diff --git a/src/Makefile.am b/src/Makefile.am index a92fdd994..86a9cdbc6 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -16,7 +16,8 @@ INCLUDEDSOURCES = \ harfbuzz-gpos.c \ harfbuzz-gsub.c \ harfbuzz-impl.c \ - harfbuzz-open.c + harfbuzz-open.c \ + harfbuzz-stream.c PUBLICHEADERS = \ harfbuzz.h \ @@ -33,7 +34,8 @@ PRIVATEHEADERS = \ harfbuzz-gdef-private.h \ harfbuzz-gpos-private.h \ harfbuzz-gsub-private.h \ - harfbuzz-open-private.h + harfbuzz-open-private.h \ + harfbuzz-stream-private.h libharfbuzz_1_la_SOURCES = \ $(MAINSOURCES) \ diff --git a/src/harfbuzz-buffer-private.h b/src/harfbuzz-buffer-private.h index 877bbe766..3037e6b9e 100644 --- a/src/harfbuzz-buffer-private.h +++ b/src/harfbuzz-buffer-private.h @@ -55,6 +55,39 @@ _hb_buffer_replace_output_glyph ( HB_Buffer buffer, HB_INTERNAL HB_UShort _hb_buffer_allocate_ligid( HB_Buffer buffer ); + +/* convenience macros */ + +#define IN_GLYPH( pos ) (buffer->in_string[(pos)].gindex) +#define IN_ITEM( pos ) (&buffer->in_string[(pos)]) +#define IN_CURGLYPH() (buffer->in_string[buffer->in_pos].gindex) +#define IN_CURITEM() (&buffer->in_string[buffer->in_pos]) +#define IN_PROPERTIES( pos ) (buffer->in_string[(pos)].properties) +#define IN_LIGID( pos ) (buffer->in_string[(pos)].ligID) +#define IN_COMPONENT( pos ) (buffer->in_string[(pos)].component) +#define POSITION( pos ) (&buffer->positions[(pos)]) +#define OUT_GLYPH( pos ) (buffer->out_string[(pos)].gindex) +#define OUT_ITEM( pos ) (&buffer->out_string[(pos)]) + +#define CHECK_Property( gdef, index, flags, property ) \ + ( ( error = _HB_GDEF_Check_Property( (gdef), (index), (flags), \ + (property) ) ) != HB_Err_Ok ) + +#define ADD_String( buffer, num_in, num_out, glyph_data, component, ligID ) \ + ( ( error = _hb_buffer_add_output_glyphs( (buffer), \ + (num_in), (num_out), \ + (glyph_data), (component), (ligID) \ + ) ) != HB_Err_Ok ) +#define ADD_Glyph( buffer, glyph_index, component, ligID ) \ + ( ( error = _hb_buffer_add_output_glyph( (buffer), \ + (glyph_index), (component), (ligID) \ + ) ) != HB_Err_Ok ) +#define REPLACE_Glyph( buffer, glyph_index, nesting_level ) \ + ( ( error = _hb_buffer_replace_output_glyph( (buffer), (glyph_index), \ + (nesting_level) == 1 ) ) != HB_Err_Ok ) +#define COPY_Glyph( buffer ) \ + ( (error = _hb_buffer_copy_output_glyph ( buffer ) ) != HB_Err_Ok ) + HB_END_HEADER #endif /* HARFBUZZ_BUFFER_PRIVATE_H */ diff --git a/src/harfbuzz-buffer.c b/src/harfbuzz-buffer.c index 9c0072a56..feb1885af 100644 --- a/src/harfbuzz-buffer.c +++ b/src/harfbuzz-buffer.c @@ -297,7 +297,7 @@ _hb_buffer_add_output_glyphs( HB_Buffer buffer, } HB_INTERNAL HB_Error -_hb_buffer_add_output_glyph( HB_Buffer buffer, +_hb_buffer_add_output_glyph( HB_Buffer buffer, HB_UInt glyph_index, HB_UShort component, HB_UShort ligID ) @@ -330,7 +330,7 @@ _hb_buffer_copy_output_glyph ( HB_Buffer buffer ) } HB_INTERNAL HB_Error -_hb_buffer_replace_output_glyph( HB_Buffer buffer, +_hb_buffer_replace_output_glyph( HB_Buffer buffer, HB_UInt glyph_index, HB_Bool inplace ) { diff --git a/src/harfbuzz-dump-main.c b/src/harfbuzz-dump-main.c index 1e8c5e5f2..5945c9d68 100644 --- a/src/harfbuzz-dump-main.c +++ b/src/harfbuzz-dump-main.c @@ -21,8 +21,7 @@ #include #include -#include "harfbuzz-open.h" - +#include "harfbuzz.h" #include "harfbuzz-dump.h" #define N_ELEMENTS(arr) (sizeof(arr)/ sizeof((arr)[0])) diff --git a/src/harfbuzz-gdef-private.h b/src/harfbuzz-gdef-private.h index dbc77e60a..b24b51383 100644 --- a/src/harfbuzz-gdef-private.h +++ b/src/harfbuzz-gdef-private.h @@ -14,8 +14,9 @@ #define HARFBUZZ_GDEF_PRIVATE_H #include "harfbuzz-impl.h" +#include "harfbuzz-stream-private.h" +#include "harfbuzz-buffer-private.h" #include "harfbuzz-gdef.h" -#include "harfbuzz-buffer.h" HB_BEGIN_HEADER @@ -99,6 +100,12 @@ _HB_GDEF_Check_Property( HB_GDEFHeader* gdef, HB_UShort flags, HB_UShort* property ); +HB_INTERNAL HB_Error +_HB_GDEF_LoadMarkAttachClassDef_From_LookupFlags( HB_GDEFHeader* gdef, + HB_Stream input, + HB_Lookup* lo, + HB_UShort num_lookups ); + HB_END_HEADER #endif /* HARFBUZZ_GDEF_PRIVATE_H */ diff --git a/src/harfbuzz-gdef.c b/src/harfbuzz-gdef.c index 041ddd5dd..bcf566e10 100644 --- a/src/harfbuzz-gdef.c +++ b/src/harfbuzz-gdef.c @@ -1200,5 +1200,44 @@ _HB_GDEF_Check_Property( HB_GDEFHeader* gdef, return HB_Err_Ok; } +HB_INTERNAL HB_Error +_HB_GDEF_LoadMarkAttachClassDef_From_LookupFlags( HB_GDEFHeader* gdef, + HB_Stream stream, + HB_Lookup* lo, + HB_UShort num_lookups) +{ + HB_Error error = HB_Err_Ok; + HB_UShort i; + + /* We now check the LookupFlags for values larger than 0xFF to find + out whether we need to load the `MarkAttachClassDef' field of the + GDEF table -- this hack is necessary for OpenType 1.2 tables since + the version field of the GDEF table hasn't been incremented. + + For constructed GDEF tables, we only load it if + `MarkAttachClassDef_offset' is not zero (nevertheless, a build of + a constructed mark attach table is not supported currently). */ + + if ( gdef && + gdef->MarkAttachClassDef_offset && !gdef->MarkAttachClassDef.loaded ) + { + for ( i = 0; i < num_lookups; i++ ) + { + + if ( lo[i].LookupFlag & HB_LOOKUP_FLAG_IGNORE_SPECIAL_MARKS ) + { + if ( FILE_Seek( gdef->MarkAttachClassDef_offset ) || + ( error = _HB_OPEN_Load_ClassDefinition( &gdef->MarkAttachClassDef, + 256, stream ) ) != HB_Err_Ok ) + goto Done; + + break; + } + } + } + +Done: + return error; +} /* END */ diff --git a/src/harfbuzz-global.h b/src/harfbuzz-global.h index bb35db07d..1484a44a1 100644 --- a/src/harfbuzz-global.h +++ b/src/harfbuzz-global.h @@ -26,6 +26,8 @@ HB_BEGIN_HEADER +#define HB_MAKE_TAG(a,b,c,d) FT_MAKE_TAG(a,b,c,d) + typedef unsigned char HB_Byte; typedef signed char HB_Char; typedef unsigned short HB_UShort; diff --git a/src/harfbuzz-gpos-private.h b/src/harfbuzz-gpos-private.h index 282924055..f7609f0ed 100644 --- a/src/harfbuzz-gpos-private.h +++ b/src/harfbuzz-gpos-private.h @@ -14,6 +14,7 @@ #define HARFBUZZ_GPOS_PRIVATE_H #include "harfbuzz-impl.h" +#include "harfbuzz-stream-private.h" #include "harfbuzz-gpos.h" HB_BEGIN_HEADER diff --git a/src/harfbuzz-gpos.c b/src/harfbuzz-gpos.c index 71dade7f1..3c36580dd 100644 --- a/src/harfbuzz-gpos.c +++ b/src/harfbuzz-gpos.c @@ -64,9 +64,7 @@ HB_Error HB_Load_GPOS_Table( FT_Face face, { HB_UInt cur_offset, new_offset, base_offset; - HB_UShort i, num_lookups; HB_GPOSHeader* gpos; - HB_Lookup* lo; HB_Stream stream = face->stream; HB_Error error; @@ -132,35 +130,11 @@ HB_Error HB_Load_GPOS_Table( FT_Face face, gpos->gdef = gdef; /* can be NULL */ - /* We now check the LookupFlags for values larger than 0xFF to find - out whether we need to load the `MarkAttachClassDef' field of the - GDEF table -- this hack is necessary for OpenType 1.2 tables since - the version field of the GDEF table hasn't been incremented. - - For constructed GDEF tables, we only load it if - `MarkAttachClassDef_offset' is not zero (nevertheless, a build of - a constructed mark attach table is not supported currently). */ - - if ( gdef && - gdef->MarkAttachClassDef_offset && !gdef->MarkAttachClassDef.loaded ) - { - lo = gpos->LookupList.Lookup; - num_lookups = gpos->LookupList.LookupCount; - - for ( i = 0; i < num_lookups; i++ ) - { - if ( lo[i].LookupFlag & HB_LOOKUP_FLAG_IGNORE_SPECIAL_MARKS ) - { - if ( FILE_Seek( gdef->MarkAttachClassDef_offset ) || - ( error = _HB_OPEN_Load_ClassDefinition( &gdef->MarkAttachClassDef, - 256, stream ) ) != HB_Err_Ok ) + if ( ( error = _HB_GDEF_LoadMarkAttachClassDef_From_LookupFlags( gdef, stream, + gpos->LookupList.Lookup, + gpos->LookupList.LookupCount ) ) ) goto Fail1; - break; - } - } - } - *retptr = gpos; return HB_Err_Ok; diff --git a/src/harfbuzz-gsub-private.h b/src/harfbuzz-gsub-private.h index 6d4be9678..ef4c9fdf5 100644 --- a/src/harfbuzz-gsub-private.h +++ b/src/harfbuzz-gsub-private.h @@ -14,6 +14,7 @@ #define HARFBUZZ_GSUB_PRIVATE_H #include "harfbuzz-impl.h" +#include "harfbuzz-stream-private.h" #include "harfbuzz-gsub.h" HB_BEGIN_HEADER diff --git a/src/harfbuzz-gsub.c b/src/harfbuzz-gsub.c index fd17a286b..558876c7b 100644 --- a/src/harfbuzz-gsub.c +++ b/src/harfbuzz-gsub.c @@ -38,9 +38,7 @@ HB_Error HB_Load_GSUB_Table( FT_Face face, HB_Error error; HB_UInt cur_offset, new_offset, base_offset; - HB_UShort i, num_lookups; HB_GSUBHeader* gsub; - HB_Lookup* lo; if ( !retptr ) return ERR(HB_Err_Invalid_Argument); @@ -100,36 +98,11 @@ HB_Error HB_Load_GSUB_Table( FT_Face face, gsub->gdef = gdef; /* can be NULL */ - /* We now check the LookupFlags for values larger than 0xFF to find - out whether we need to load the `MarkAttachClassDef' field of the - GDEF table -- this hack is necessary for OpenType 1.2 tables since - the version field of the GDEF table hasn't been incremented. - - For constructed GDEF tables, we only load it if - `MarkAttachClassDef_offset' is not zero (nevertheless, a build of - a constructed mark attach table is not supported currently). */ - - if ( gdef && - gdef->MarkAttachClassDef_offset && !gdef->MarkAttachClassDef.loaded ) - { - lo = gsub->LookupList.Lookup; - num_lookups = gsub->LookupList.LookupCount; - - for ( i = 0; i < num_lookups; i++ ) - { - - if ( lo[i].LookupFlag & HB_LOOKUP_FLAG_IGNORE_SPECIAL_MARKS ) - { - if ( FILE_Seek( gdef->MarkAttachClassDef_offset ) || - ( error = _HB_OPEN_Load_ClassDefinition( &gdef->MarkAttachClassDef, - 256, stream ) ) != HB_Err_Ok ) + if ( ( error = _HB_GDEF_LoadMarkAttachClassDef_From_LookupFlags( gdef, stream, + gsub->LookupList.Lookup, + gsub->LookupList.LookupCount ) ) ) goto Fail1; - break; - } - } - } - *retptr = gsub; return HB_Err_Ok; diff --git a/src/harfbuzz-impl.c b/src/harfbuzz-impl.c index fcdbc33af..fd8280bda 100644 --- a/src/harfbuzz-impl.c +++ b/src/harfbuzz-impl.c @@ -1,9 +1,14 @@ -/* - * By David Turner, The FreeType Project (www.freetype.org) +/******************************************************************* * - * This code is explicitely put in the public domain - */ - + * Copyright 2005 David Turner, The FreeType Project (www.freetype.org) + * Copyright 2007 Trolltech ASA + * Copyright 2007 Red Hat, Inc + * + * This is part of HarfBuzz, an OpenType Layout engine library. + * + * See the file name COPYING for licensing information. + * + ******************************************************************/ #include "harfbuzz-impl.h" #if 0 @@ -24,28 +29,6 @@ _hb_log( const char* format, ... ) #define LOG(x) do {} while (0) #endif -/* only used internally */ -static HB_Pointer -_hb_qalloc( HB_UInt size, - HB_Error *perror ) -{ - HB_Error error = 0; - HB_Pointer block = NULL; - - if ( size > 0 ) - { - block = malloc( size ); - if ( !block ) - error = ERR(HB_Err_Out_Of_Memory); - } - - *perror = error; - return block; -} - -#undef QALLOC /* just in case */ -#define QALLOC(ptr,size) ( (ptr) = _hb_qalloc( (size), &error ), error != 0 ) - HB_INTERNAL HB_Pointer _hb_alloc( HB_UInt size, @@ -96,185 +79,6 @@ _hb_free( HB_Pointer block ) } -HB_INTERNAL HB_Int -_hb_stream_pos( HB_Stream stream ) -{ - LOG(( "_hb_stream_pos() -> %ld\n", stream->pos )); - return stream->pos; -} - - -HB_INTERNAL HB_Error -_hb_stream_seek( HB_Stream stream, - HB_Int pos ) -{ - HB_Error error = 0; - - stream->pos = pos; - if ( stream->read ) - { - if ( stream->read( stream, pos, NULL, 0 ) ) - error = ERR(HB_Err_Read_Error); - } - else if ( pos > (HB_Int)stream->size ) - error = ERR(HB_Err_Read_Error); - - LOG(( "_hb_stream_seek(%ld) -> %d\n", pos, error )); - return error; -} - - -HB_INTERNAL HB_Error -_hb_stream_frame_enter( HB_Stream stream, - HB_UInt count ) -{ - HB_Error error = HB_Err_Ok; - HB_UInt read_bytes; - - if ( stream->read ) - { - /* allocate the frame in memory */ - - if ( QALLOC( stream->base, count ) ) - goto Exit; - - /* read it */ - read_bytes = stream->read( stream, stream->pos, - stream->base, count ); - if ( read_bytes < count ) - { - FREE( stream->base ); - error = ERR(HB_Err_Read_Error); - } - stream->cursor = stream->base; - stream->limit = stream->cursor + count; - stream->pos += read_bytes; - } - else - { - /* check current and new position */ - if ( stream->pos >= stream->size || - stream->pos + count > stream->size ) - { - error = ERR(HB_Err_Read_Error); - goto Exit; - } - - /* set cursor */ - stream->cursor = stream->base + stream->pos; - stream->limit = stream->cursor + count; - stream->pos += count; - } - -Exit: - LOG(( "_hb_stream_frame_enter(%ld) -> %d\n", count, error )); - return error; -} - - -HB_INTERNAL void -_hb_stream_frame_exit( HB_Stream stream ) -{ - if ( stream->read ) - { - FREE( stream->base ); - } - stream->cursor = NULL; - stream->limit = NULL; - - LOG(( "_hb_stream_frame_exit()\n" )); -} - - -HB_INTERNAL HB_Error -_hb_face_goto_table( FT_Face face, - HB_UInt the_tag, - HB_Stream stream ) -{ - HB_Error error; - - LOG(( "_hb_face_goto_table( %p, %c%c%c%c, %p )\n", - face, - (int)((the_tag >> 24) & 0xFF), - (int)((the_tag >> 16) & 0xFF), - (int)((the_tag >> 8) & 0xFF), - (int)(the_tag & 0xFF), - stream )); - - if ( !FT_IS_SFNT(face) ) - { - LOG(( "not a SFNT face !!\n" )); - error = ERR(HB_Err_Invalid_Argument); - } - else - { - /* parse the directory table directly, without using - * FreeType's built-in data structures - */ - HB_UInt offset = 0; - HB_UInt count, nn; - - if ( face->num_faces > 1 ) - { - /* deal with TrueType collections */ - LOG(( ">> This is a TrueType Collection\n" )); - - if ( FILE_Seek( 12 + face->face_index*4 ) || - ACCESS_Frame( 4 ) ) - goto Exit; - - offset = GET_ULong(); - - FORGET_Frame(); - } - - LOG(( "TrueType offset = %ld\n", offset )); - - if ( FILE_Seek( offset+4 ) || - ACCESS_Frame( 2 ) ) - goto Exit; - - count = GET_UShort(); - - FORGET_Frame(); - - if ( FILE_Seek( offset+12 ) || - ACCESS_Frame( count*16 ) ) - goto Exit; - - for ( nn = 0; nn < count; nn++ ) - { - HB_UInt tag = GET_ULong(); - HB_UInt checksum = GET_ULong(); - HB_UInt start = GET_ULong(); - HB_UInt size = GET_ULong(); - - HB_UNUSED(checksum); - HB_UNUSED(size); - - if ( tag == the_tag ) - { - LOG(( "TrueType table (start: %ld) (size: %ld)\n", start, size )); - error = _hb_stream_seek( stream, start ); - goto FoundIt; - } - } - error = HB_Err_Not_Covered; - - FoundIt: - FORGET_Frame(); - } - -Exit: - LOG(( "TrueType error=%d\n", error )); - - return error; -} - -#undef QALLOC - -/* abuse these private header/source files */ - /* helper func to set a breakpoint on */ HB_INTERNAL HB_Error _hb_err (HB_Error code) diff --git a/src/harfbuzz-impl.h b/src/harfbuzz-impl.h index 69c9ea902..098060801 100644 --- a/src/harfbuzz-impl.h +++ b/src/harfbuzz-impl.h @@ -21,17 +21,6 @@ HB_BEGIN_HEADER -/***********************************************************************/ -/************************ remaining freetype bits **********************/ -/***********************************************************************/ - -typedef FT_Stream HB_Stream; -#define HB_MAKE_TAG(a,b,c,d) FT_MAKE_TAG(a,b,c,d) - -/***********************************************************************/ -/***********************************************************************/ -/***********************************************************************/ - #ifndef HB_INTERNAL # define HB_INTERNAL #endif @@ -68,55 +57,6 @@ typedef FT_Stream HB_Stream; #define ARRAY_LEN(Array) ((int)(sizeof (Array) / sizeof (Array)[0])) -/* memory and stream management */ - -#define SET_ERR(c) ( (error = (c)) != 0 ) - -/* stream macros used by the OpenType parser */ -#define GOTO_Table(tag) SET_ERR( _hb_face_goto_table( face, tag, stream ) ) -#define FILE_Pos() _hb_stream_pos( stream ) -#define FILE_Seek(pos) SET_ERR( _hb_stream_seek( stream, pos ) ) -#define ACCESS_Frame(size) SET_ERR( _hb_stream_frame_enter( stream, size ) ) -#define FORGET_Frame() _hb_stream_frame_exit( stream ) - -#define GET_Byte() (*stream->cursor++) -#define GET_Short() (stream->cursor += 2, (HB_Short)( \ - (*(((HB_Byte*)stream->cursor)-2) << 8) | \ - *(((HB_Byte*)stream->cursor)-1) \ - )) -#define GET_Long() (stream->cursor += 4, (HB_Int)( \ - (*(((HB_Byte*)stream->cursor)-4) << 24) | \ - (*(((HB_Byte*)stream->cursor)-3) << 16) | \ - (*(((HB_Byte*)stream->cursor)-2) << 8) | \ - *(((HB_Byte*)stream->cursor)-1) \ - )) - - -#define GET_Char() ((HB_Char)GET_Byte()) -#define GET_UShort() ((HB_UShort)GET_Short()) -#define GET_ULong() ((HB_UInt)GET_Long()) -#define GET_Tag4() GET_ULong() - - -HB_INTERNAL HB_Int -_hb_stream_pos( HB_Stream stream ); - -HB_INTERNAL HB_Error -_hb_stream_seek( HB_Stream stream, - HB_Int pos ); - -HB_INTERNAL HB_Error -_hb_stream_frame_enter( HB_Stream stream, - HB_UInt size ); - -HB_INTERNAL void -_hb_stream_frame_exit( HB_Stream stream ); - -HB_INTERNAL HB_Error -_hb_face_goto_table( FT_Face face, - HB_UInt tag, - HB_Stream stream ); - #define ALLOC(_ptr,_size) \ ( (_ptr) = _hb_alloc( _size, &error ), error != 0 ) @@ -145,15 +85,15 @@ _hb_face_goto_table( FT_Face face, HB_INTERNAL HB_Pointer _hb_alloc( HB_UInt size, - HB_Error *perror_ ); + HB_Error *perror_ ); HB_INTERNAL HB_Pointer -_hb_realloc( HB_Pointer block, +_hb_realloc( HB_Pointer block, HB_UInt new_size, - HB_Error *perror_ ); + HB_Error *perror_ ); HB_INTERNAL void -_hb_free( HB_Pointer block ); +_hb_free( HB_Pointer block ); /* helper func to set a breakpoint on */ @@ -161,38 +101,6 @@ HB_INTERNAL HB_Error _hb_err (HB_Error code); -/* buffer access macros */ - -#define IN_GLYPH( pos ) (buffer->in_string[(pos)].gindex) -#define IN_ITEM( pos ) (&buffer->in_string[(pos)]) -#define IN_CURGLYPH() (buffer->in_string[buffer->in_pos].gindex) -#define IN_CURITEM() (&buffer->in_string[buffer->in_pos]) -#define IN_PROPERTIES( pos ) (buffer->in_string[(pos)].properties) -#define IN_LIGID( pos ) (buffer->in_string[(pos)].ligID) -#define IN_COMPONENT( pos ) (buffer->in_string[(pos)].component) -#define POSITION( pos ) (&buffer->positions[(pos)]) -#define OUT_GLYPH( pos ) (buffer->out_string[(pos)].gindex) -#define OUT_ITEM( pos ) (&buffer->out_string[(pos)]) - -#define CHECK_Property( gdef, index, flags, property ) \ - ( ( error = _HB_GDEF_Check_Property( (gdef), (index), (flags), \ - (property) ) ) != HB_Err_Ok ) - -#define ADD_String( buffer, num_in, num_out, glyph_data, component, ligID ) \ - ( ( error = _hb_buffer_add_output_glyphs( (buffer), \ - (num_in), (num_out), \ - (glyph_data), (component), (ligID) \ - ) ) != HB_Err_Ok ) -#define ADD_Glyph( buffer, glyph_index, component, ligID ) \ - ( ( error = _hb_buffer_add_output_glyph( (buffer), \ - (glyph_index), (component), (ligID) \ - ) ) != HB_Err_Ok ) -#define REPLACE_Glyph( buffer, glyph_index, nesting_level ) \ - ( ( error = _hb_buffer_replace_output_glyph( (buffer), (glyph_index), \ - (nesting_level) == 1 ) ) != HB_Err_Ok ) -#define COPY_Glyph( buffer ) \ - ( (error = _hb_buffer_copy_output_glyph ( buffer ) ) != HB_Err_Ok ) - HB_END_HEADER #endif /* HARFBUZZ_IMPL_H */ diff --git a/src/harfbuzz-open-private.h b/src/harfbuzz-open-private.h index 125bd0937..73fa5158d 100644 --- a/src/harfbuzz-open-private.h +++ b/src/harfbuzz-open-private.h @@ -33,7 +33,7 @@ struct HB_SubTable_ HB_INTERNAL HB_Error _HB_OPEN_Load_ScriptList( HB_ScriptList* sl, - HB_Stream stream ); + HB_Stream input ); HB_INTERNAL HB_Error _HB_OPEN_Load_FeatureList( HB_FeatureList* fl, HB_Stream input ); @@ -54,7 +54,7 @@ _HB_OPEN_Load_EmptyOrClassDefinition( HB_ClassDefinition* cd, HB_UShort limit, HB_UInt class_offset, HB_UInt base_offset, - HB_Stream stream ); + HB_Stream input ); HB_INTERNAL HB_Error _HB_OPEN_Load_Device( HB_Device* d, HB_Stream input ); diff --git a/src/harfbuzz-stream-private.h b/src/harfbuzz-stream-private.h new file mode 100644 index 000000000..eb4464c82 --- /dev/null +++ b/src/harfbuzz-stream-private.h @@ -0,0 +1,70 @@ +/******************************************************************* + * + * Copyright 1996-2000 by + * David Turner, Robert Wilhelm, and Werner Lemberg. + * + * Copyright 2006 Behdad Esfahbod + * + * This is part of HarfBuzz, an OpenType Layout engine library. + * + * See the file name COPYING for licensing information. + * + ******************************************************************/ +#ifndef HARFBUZZ_STREAM_PRIVATE_H +#define HARFBUZZ_STREAM_PRIVATE_H + +#include "harfbuzz-impl.h" + +HB_BEGIN_HEADER + +typedef FT_Stream HB_Stream; + +HB_INTERNAL HB_Int +_hb_stream_pos( HB_Stream stream ); + +HB_INTERNAL HB_Error +_hb_stream_seek( HB_Stream stream, + HB_UInt pos ); + +HB_INTERNAL HB_Error +_hb_stream_frame_enter( HB_Stream stream, + HB_UInt size ); + +HB_INTERNAL void +_hb_stream_frame_exit( HB_Stream stream ); + +HB_INTERNAL HB_Error +_hb_face_goto_table( FT_Face face, + HB_UInt tag ); + +/* convenience macros */ + +#define SET_ERR(c) ( (error = (c)) != 0 ) + +#define GOTO_Table(tag) SET_ERR( _hb_face_goto_table( face, tag ) ) +#define FILE_Pos() _hb_stream_pos( stream ) +#define FILE_Seek(pos) SET_ERR( _hb_stream_seek( stream, pos ) ) +#define ACCESS_Frame(size) SET_ERR( _hb_stream_frame_enter( stream, size ) ) +#define FORGET_Frame() _hb_stream_frame_exit( stream ) + +#define GET_Byte() (*stream->cursor++) +#define GET_Short() (stream->cursor += 2, (HB_Short)( \ + (*(((HB_Byte*)stream->cursor)-2) << 8) | \ + *(((HB_Byte*)stream->cursor)-1) \ + )) +#define GET_Long() (stream->cursor += 4, (HB_Int)( \ + (*(((HB_Byte*)stream->cursor)-4) << 24) | \ + (*(((HB_Byte*)stream->cursor)-3) << 16) | \ + (*(((HB_Byte*)stream->cursor)-2) << 8) | \ + *(((HB_Byte*)stream->cursor)-1) \ + )) + + +#define GET_Char() ((HB_Char)GET_Byte()) +#define GET_UShort() ((HB_UShort)GET_Short()) +#define GET_ULong() ((HB_UInt)GET_Long()) +#define GET_Tag4() GET_ULong() + +HB_END_HEADER + +#endif /* HARFBUZZ_STREAM_PRIVATE_H */ diff --git a/src/harfbuzz-stream.c b/src/harfbuzz-stream.c new file mode 100644 index 000000000..5746d42f7 --- /dev/null +++ b/src/harfbuzz-stream.c @@ -0,0 +1,234 @@ +/******************************************************************* + * + * Copyright 2005 David Turner, The FreeType Project (www.freetype.org) + * Copyright 2007 Trolltech ASA + * Copyright 2007 Red Hat, Inc + * + * This is part of HarfBuzz, an OpenType Layout engine library. + * + * See the file name COPYING for licensing information. + * + ******************************************************************/ +#include "harfbuzz-impl.h" +#include "harfbuzz-stream-private.h" +#include + +#if 0 +#include +#define LOG(x) _hb_log x + +static void +_hb_log( const char* format, ... ) +{ + va_list ap; + + va_start( ap, format ); + vfprintf( stderr, format, ap ); + va_end( ap ); +} + +#else +#define LOG(x) do {} while (0) +#endif + + +/* only used internally */ +static HB_Pointer +_hb_qalloc( HB_UInt size, + HB_Error *perror ) +{ + HB_Error error = 0; + HB_Pointer block = NULL; + + if ( size > 0 ) + { + block = malloc( size ); + if ( !block ) + error = ERR(HB_Err_Out_Of_Memory); + } + + *perror = error; + return block; +} + +#undef QALLOC /* just in case */ +#define QALLOC(ptr,size) ( (ptr) = _hb_qalloc( (size), &error ), error != 0 ) + +HB_INTERNAL HB_Int +_hb_stream_pos( HB_Stream stream ) +{ + LOG(( "_hb_stream_pos() -> %ld\n", stream->pos )); + return stream->pos; +} + + +HB_INTERNAL HB_Error +_hb_stream_seek( HB_Stream stream, + HB_UInt pos ) +{ + HB_Error error = 0; + + stream->pos = pos; + if ( stream->read ) + { + if ( stream->read( stream, pos, NULL, 0 ) ) + error = ERR(HB_Err_Read_Error); + } + else if ( pos > stream->size ) + error = ERR(HB_Err_Read_Error); + + LOG(( "_hb_stream_seek(%ld) -> 0x%04X\n", pos, error )); + return error; +} + + +HB_INTERNAL HB_Error +_hb_stream_frame_enter( HB_Stream stream, + HB_UInt count ) +{ + HB_Error error = HB_Err_Ok; + HB_UInt read_bytes; + + if ( stream->read ) + { + /* allocate the frame in memory */ + + if ( QALLOC( stream->base, count ) ) + goto Exit; + + /* read it */ + read_bytes = stream->read( stream, stream->pos, + stream->base, count ); + if ( read_bytes < count ) + { + FREE( stream->base ); + error = ERR(HB_Err_Read_Error); + } + stream->cursor = stream->base; + stream->limit = stream->cursor + count; + stream->pos += read_bytes; + } + else + { + /* check new position, watch for overflow */ + if (HB_UNLIKELY (stream->pos + count > stream->size || + stream->pos + count < stream->pos)) + { + error = ERR(HB_Err_Read_Error); + goto Exit; + } + + /* set cursor */ + stream->cursor = stream->base + stream->pos; + stream->limit = stream->cursor + count; + stream->pos += count; + } + +Exit: + LOG(( "_hb_stream_frame_enter(%ld) -> 0x%04X\n", count, error )); + return error; +} + + +HB_INTERNAL void +_hb_stream_frame_exit( HB_Stream stream ) +{ + if ( stream->read ) + { + FREE( stream->base ); + } + stream->cursor = NULL; + stream->limit = NULL; + + LOG(( "_hb_stream_frame_exit()\n" )); +} + + +HB_INTERNAL HB_Error +_hb_face_goto_table( FT_Face face, + HB_UInt the_tag ) +{ + HB_Stream stream = face->stream; + + HB_Error error; + + LOG(( "_hb_face_goto_table( %p, %c%c%c%c, %p )\n", + face, + (int)((the_tag >> 24) & 0xFF), + (int)((the_tag >> 16) & 0xFF), + (int)((the_tag >> 8) & 0xFF), + (int)(the_tag & 0xFF), + stream )); + + if ( !FT_IS_SFNT(face) ) + { + LOG(( "not a SFNT face !!\n" )); + error = ERR(HB_Err_Invalid_Argument); + } + else + { + /* parse the directory table directly, without using + * FreeType's built-in data structures + */ + HB_UInt offset = 0; + HB_UInt count, nn; + + if ( face->num_faces > 1 ) + { + /* deal with TrueType collections */ + LOG(( ">> This is a TrueType Collection\n" )); + + if ( FILE_Seek( 12 + face->face_index*4 ) || + ACCESS_Frame( 4 ) ) + goto Exit; + + offset = GET_ULong(); + + FORGET_Frame(); + } + + LOG(( "TrueType offset = %ld\n", offset )); + + if ( FILE_Seek( offset+4 ) || + ACCESS_Frame( 2 ) ) + goto Exit; + + count = GET_UShort(); + + FORGET_Frame(); + + if ( FILE_Seek( offset+12 ) || + ACCESS_Frame( count*16 ) ) + goto Exit; + + for ( nn = 0; nn < count; nn++ ) + { + HB_UInt tag = GET_ULong(); + HB_UInt checksum = GET_ULong(); + HB_UInt start = GET_ULong(); + HB_UInt size = GET_ULong(); + + HB_UNUSED(checksum); + HB_UNUSED(size); + + if ( tag == the_tag ) + { + LOG(( "TrueType table (start: %ld) (size: %ld)\n", start, size )); + error = _hb_stream_seek( stream, start ); + goto FoundIt; + } + } + error = HB_Err_Not_Covered; + + FoundIt: + FORGET_Frame(); + } + +Exit: + LOG(( "TrueType error=%d\n", error )); + + return error; +} + +#undef QALLOC + diff --git a/src/harfbuzz.c b/src/harfbuzz.c index 11287467a..26461638e 100644 --- a/src/harfbuzz.c +++ b/src/harfbuzz.c @@ -17,3 +17,4 @@ #include "harfbuzz-gpos.c" #include "harfbuzz-impl.c" #include "harfbuzz-open.c" +#include "harfbuzz-stream.c" diff --git a/src/harfbuzz.h b/src/harfbuzz.h index 8bf03be6f..6a1a49b39 100644 --- a/src/harfbuzz.h +++ b/src/harfbuzz.h @@ -14,11 +14,10 @@ #define HARFBUZZ_H #include "harfbuzz-global.h" -#include "harfbuzz-open.h" #include "harfbuzz-buffer.h" #include "harfbuzz-gdef.h" #include "harfbuzz-gsub.h" #include "harfbuzz-gpos.h" -#include "harfbuzz-dump.h" +#include "harfbuzz-open.h" #endif /* HARFBUZZ_OPEN_H */