diff --git a/CHANGES b/CHANGES index 339d5b451..55cf96e9f 100644 --- a/CHANGES +++ b/CHANGES @@ -1,5 +1,7 @@ LATEST CHANGES + - changed "cid" to use "psaux" too.. + - added the cache sub-system. See as well as the sources in "src/cache". Note that it compiles but is still untested for now .. diff --git a/include/freetype/config/ftoption.h b/include/freetype/config/ftoption.h index a95c91cb2..11553a34a 100644 --- a/include/freetype/config/ftoption.h +++ b/include/freetype/config/ftoption.h @@ -349,7 +349,7 @@ /* T1_MAX_SUBRS_CALLS details the maximum number of nested sub-routine */ /* calls during glyph loading. */ /* */ -#define T1_MAX_SUBRS_CALLS 8 +#define T1_MAX_SUBRS_CALLS 16 /*************************************************************************/ @@ -357,7 +357,7 @@ /* T1_MAX_CHARSTRING_OPERANDS is the charstring stack's capacity. A */ /* minimum of 16 is required. */ /* */ -#define T1_MAX_CHARSTRINGS_OPERANDS 32 +#define T1_MAX_CHARSTRINGS_OPERANDS 64 /*************************************************************************/ diff --git a/include/freetype/internal/psaux.h b/include/freetype/internal/psaux.h index 8c8fa7ad5..eea39310e 100644 --- a/include/freetype/internal/psaux.h +++ b/include/freetype/internal/psaux.h @@ -134,6 +134,7 @@ /*************************************************************************/ /*************************************************************************/ + typedef struct T1_Parser_ T1_Parser; /* simple enumeration type used to identify token types */ typedef enum T1_Token_Type_ @@ -169,95 +170,114 @@ t1_field_string, t1_field_integer_array, t1_field_fixed_array, + t1_field_callback, /* do not remove */ t1_field_max } T1_Field_Type; + typedef enum T1_Field_Location_ + { + t1_field_cid_info, + t1_field_font_dict, + t1_field_font_info, + t1_field_private, + + /* do not remove */ + t1_field_location_max + + } T1_Field_Location; + + typedef void (*T1_Field_Parser)( FT_Face face, + FT_Pointer parser ); + /* structure type used to model object fields */ typedef struct T1_Field_ { - T1_Field_Type type; /* type of field */ - FT_UInt offset; /* offset of field in object */ - FT_Byte size; /* size of field in bytes */ - FT_UInt array_max; /* maximum number of elements for array */ - FT_UInt count_offset; /* offset of element count for arrays */ - FT_Int flag_bit; /* bit number for field flag */ - + const char* ident; /* field identifier */ + T1_Field_Location location; + T1_Field_Type type; /* type of field */ + T1_Field_Parser reader; + FT_UInt offset; /* offset of field in object */ + FT_Byte size; /* size of field in bytes */ + FT_UInt array_max; /* maximal number of elements for */ + /* array */ + FT_UInt count_offset; /* offset of element count for */ + /* arrays */ } T1_Field; -#define T1_FIELD_BOOL( _fname ) \ - { \ - t1_field_bool, \ - FT_FIELD_OFFSET( _fname ), \ - FT_FIELD_SIZE( _fname ), \ - 0, 0, 0 \ - } - -#define T1_FIELD_NUM( _fname ) \ - { \ - t1_field_integer, \ - FT_FIELD_OFFSET( _fname ), \ - FT_FIELD_SIZE( _fname ), \ - 0, 0, 0 \ - } - -#define T1_FIELD_FIXED( _fname, _power ) \ - { \ - t1_field_fixed, \ - FT_FIELD_OFFSET( _fname ), \ - FT_FIELD_SIZE( _fname ), \ - 0, 0, 0 \ - } - -#define T1_FIELD_STRING( _fname ) \ - { \ - t1_field_string, \ - FT_FIELD_OFFSET( _fname ), \ - FT_FIELD_SIZE( _fname ), \ - 0, 0, 0 \ - } - -#define T1_FIELD_NUM_ARRAY( _fname, _fcount, _fmax ) \ +#define T1_NEW_SIMPLE_FIELD( _ident, _type, _fname ) \ { \ - t1_field_integer, \ + _ident, T1CODE, _type, \ + 0, \ FT_FIELD_OFFSET( _fname ), \ - FT_FIELD_SIZE_DELTA( _fname ), \ - _fmax, \ - FT_FIELD_OFFSET( _fcount ), \ - 0 \ - } + FT_FIELD_SIZE( _fname ), \ + 0, 0 \ + }, -#define T1_FIELD_FIXED_ARRAY( _fname, _fcount, _fmax ) \ - { \ - t1_field_fixed, \ - FT_FIELD_OFFSET( _fname ), \ - FT_FIELD_SIZE_DELTA( _fname ), \ - _fmax, \ - FT_FIELD_OFFSET( _fcount ), \ - 0 \ - } +#define T1_NEW_CALLBACK_FIELD( _ident, _reader ) \ + { \ + _ident, T1CODE, t1_field_callback, \ + (T1_Field_Parser)_reader, \ + 0, 0, \ + 0, 0 \ + }, + +#define T1_NEW_TABLE_FIELD( _ident, _type, _fname, _max ) \ + { \ + _ident, T1CODE, _type, \ + 0, \ + FT_FIELD_OFFSET( _fname ), \ + FT_FIELD_SIZE_DELTA( _fname ), \ + _max, \ + FT_FIELD_OFFSET( num_ ## _fname ) \ + }, + +#define T1_NEW_TABLE_FIELD2( _ident, _type, _fname, _max ) \ + { \ + _ident, T1CODE, _type, \ + 0, \ + FT_FIELD_OFFSET( _fname ), \ + FT_FIELD_SIZE_DELTA( _fname ), \ + _max, 0 \ + }, + + +#define T1_FIELD_BOOL( _ident, _fname ) \ + T1_NEW_SIMPLE_FIELD( _ident, t1_field_bool, _fname ) + +#define T1_FIELD_NUM( _ident, _fname ) \ + T1_NEW_SIMPLE_FIELD( _ident, t1_field_integer, _fname ) + +#define T1_FIELD_FIXED( _ident, _fname ) \ + T1_NEW_SIMPLE_FIELD( _ident, t1_field_fixed, _fname ) + +#define T1_FIELD_STRING( _ident, _fname ) \ + T1_NEW_SIMPLE_FIELD( _ident, t1_field_string, _fname ) + +#define T1_FIELD_NUM_TABLE( _ident, _fname, _fmax ) \ + T1_NEW_TABLE_FIELD( _ident, t1_field_integer_array, \ + _fname, _fmax ) + +#define T1_FIELD_FIXED_TABLE( _ident, _fname, _fmax ) \ + T1_NEW_TABLE_FIELD( _ident, t1_field_fixed_array, \ + _fname, _fmax ) + +#define T1_FIELD_NUM_TABLE2( _ident, _fname, _fmax ) \ + T1_NEW_TABLE_FIELD2( _ident, t1_field_integer_array, \ + _fname, _fmax ) + +#define T1_FIELD_FIXED_TABLE2( _ident, _fname, _fmax ) \ + T1_NEW_TABLE_FIELD2( _ident, t1_field_fixed_array, \ + _fname, _fmax ) + +#define T1_FIELD_CALLBACK( _ident, _name ) \ + T1_NEW_CALLBACK_FIELD( _ident, _name ) -#define T1_FIELD_NUM_ARRAY2( _fname, _fmax ) \ - { \ - t1_field_integer, \ - FT_FIELD_OFFSET( _fname ), \ - FT_FIELD_SIZE_DELTA( _fname ), \ - _fmax, \ - 0, 0 \ - } -#define T1_FIELD_FIXED_ARRAY2( _fname, _fmax ) \ - { \ - t1_field_fixed, \ - FT_FIELD_OFFSTE( _fname ), \ - FT_FIELD_SIZE_DELTA( _fname ), \ - _fmax, \ - 0, 0 \ - } /*************************************************************************/ @@ -268,10 +288,6 @@ /*************************************************************************/ /*************************************************************************/ - - typedef struct T1_Parser_ T1_Parser; - - typedef struct T1_Parser_Funcs_ { void (*init) ( T1_Parser* parser, @@ -579,6 +595,7 @@ FT_Int* subrs_len; /* array of subrs length (optional) */ FT_Matrix font_matrix; + FT_Vector font_offset; FT_Int flex_state; FT_Int num_flex_vectors; diff --git a/include/freetype/internal/t1types.h b/include/freetype/internal/t1types.h index 8db60b05e..8bd70ac4e 100644 --- a/include/freetype/internal/t1types.h +++ b/include/freetype/internal/t1types.h @@ -181,6 +181,7 @@ { FT_FaceRec root; void* psnames; + void* psaux; CID_Info cid; void* afm_data; CID_Subrs* subrs; diff --git a/include/freetype/t1tables.h b/include/freetype/t1tables.h index 6c75f71f1..1b89df0ea 100644 --- a/include/freetype/t1tables.h +++ b/include/freetype/t1tables.h @@ -195,6 +195,7 @@ FT_Byte paint_type; FT_Byte font_type; FT_Matrix font_matrix; + FT_Vector font_offset; FT_UInt num_subrs; FT_ULong subrmap_offset; diff --git a/src/cache/ftcimage.c b/src/cache/ftcimage.c index e73b9da7a..217b11cea 100644 --- a/src/cache/ftcimage.c +++ b/src/cache/ftcimage.c @@ -426,7 +426,7 @@ FTC_Image_Cache cache = queue->cache; FT_UInt hash_index = glyph_index % queue->hash_size; FT_List bucket = queue->buckets + hash_index; - FT_ListNode node, next; + FT_ListNode node, next = 0; FT_Error error; FTC_ImageNode inode; diff --git a/src/cid/cidgload.c b/src/cid/cidgload.c index f8519d091..e9aed5c76 100644 --- a/src/cid/cidgload.c +++ b/src/cid/cidgload.c @@ -43,518 +43,73 @@ #define FT_COMPONENT trace_cidgload - /* forward */ - static - FT_Error cid_load_glyph( CID_Decoder* decoder, - FT_UInt glyph_index ); - - - typedef enum CID_Operator_ - { - op_none = 0, - - op_endchar, - op_hsbw, - op_seac, - op_sbw, - op_closepath, - - op_hlineto, - op_hmoveto, - op_hvcurveto, - op_rlineto, - op_rmoveto, - op_rrcurveto, - op_vhcurveto, - op_vlineto, - op_vmoveto, - - op_dotsection, - - op_hstem, - op_hstem3, - op_vstem, - op_vstem3, - - op_div, - op_callothersubr, - op_callsubr, - op_pop, - op_return, - op_setcurrentpoint, - - op_max /* never remove this one */ - - } CID_Operator; static - const FT_Int t1_args_count[op_max] = + FT_Error cid_load_glyph( T1_Decoder* decoder, + FT_UInt glyph_index ) { - 0, /* none */ - 0, /* endchar */ - 2, /* hsbw */ - 5, /* seac */ - 4, /* sbw */ - 0, /* closepath */ - - 1, /* hlineto */ - 1, /* hmoveto */ - 4, /* hvcurveto */ - 2, /* rlineto */ - 2, /* rmoveto */ - 6, /* rrcurveto */ - 4, /* vhcurveto */ - 1, /* vlineto */ - 1, /* vmoveto */ - - 0, /* dotsection */ - - 2, /* hstem */ - 6, /* hstem3 */ - 2, /* vstem */ - 6, /* vstem3 */ - - 2, /* div */ - -1, /* callothersubr */ - 1, /* callsubr */ - 0, /* pop */ - 0, /* return */ - 2 /* setcurrentpoint */ - }; - - - /*************************************************************************/ - /*************************************************************************/ - /*************************************************************************/ - /********** *********/ - /********** *********/ - /********** GENERIC CHARSTRING PARSING *********/ - /********** *********/ - /********** *********/ - /*************************************************************************/ - /*************************************************************************/ - /*************************************************************************/ - - - /*************************************************************************/ - /* */ - /* */ - /* CID_Init_Builder */ - /* */ - /* */ - /* Initializes a given glyph builder. */ - /* */ - /* */ - /* builder :: A pointer to the glyph builder to initialize. */ - /* */ - /* */ - /* face :: The current face object. */ - /* */ - /* size :: The current size object. */ - /* */ - /* glyph :: The current glyph object. */ - /* */ - LOCAL_FUNC - void CID_Init_Builder( CID_Builder* builder, - CID_Face face, - CID_Size size, - CID_GlyphSlot glyph ) - { - builder->path_begun = 0; - builder->load_points = 1; - - builder->face = face; - builder->glyph = glyph; - builder->memory = face->root.memory; - - if ( glyph ) - { - FT_GlyphLoader* loader = glyph->root.loader; - - - builder->loader = loader; - builder->base = &loader->base.outline; - builder->current = &loader->current.outline; - - FT_GlyphLoader_Rewind( loader ); - } - - if ( size ) - { - builder->scale_x = size->root.metrics.x_scale; - builder->scale_y = size->root.metrics.y_scale; - } - - builder->pos_x = 0; - builder->pos_y = 0; - - builder->left_bearing.x = 0; - builder->left_bearing.y = 0; - builder->advance.x = 0; - builder->advance.y = 0; - - } - - - /*************************************************************************/ - /* */ - /* */ - /* CID_Done_Builder */ - /* */ - /* */ - /* Finalizes a given glyph builder. Its contents can still be used */ - /* after the call, but the function saves important information */ - /* within the corresponding glyph slot. */ - /* */ - /* */ - /* builder :: A pointer to the glyph builder to finalize. */ - /* */ - LOCAL_FUNC - void CID_Done_Builder( CID_Builder* builder ) - { - CID_GlyphSlot glyph = builder->glyph; - - - if ( glyph ) - glyph->root.outline = *builder->base; - } - - - /*************************************************************************/ - /* */ - /* */ - /* CID_Init_Decoder */ - /* */ - /* */ - /* Initializes a given glyph decoder. */ - /* */ - /* */ - /* decoder :: A pointer to the glyph builder to initialize. */ - /* */ - LOCAL_FUNC - void CID_Init_Decoder( CID_Decoder* decoder ) - { - MEM_Set( decoder, 0, sizeof ( *decoder ) ); - - decoder->font_matrix.xx = 0x10000L; - decoder->font_matrix.yy = 0x10000L; - } - - - /* check that there is enough space for `count' more points */ - static - FT_Error check_points( CID_Builder* builder, - FT_Int count ) - { - return FT_GlyphLoader_Check_Points( builder->loader, count, 0 ); - } - - - /* add a new point, but do not check space */ - static - void add_point( CID_Builder* builder, - FT_Pos x, - FT_Pos y, - FT_Byte flag ) - { - FT_Outline* outline = builder->current; - - - if ( builder->load_points ) - { - FT_Vector* point = outline->points + outline->n_points; - FT_Byte* control = (FT_Byte*)outline->tags + outline->n_points; - - - point->x = x; - point->y = y; - *control = flag ? FT_Curve_Tag_On : FT_Curve_Tag_Cubic; - - builder->last = *point; - } - - outline->n_points++; - } - - - /* check space for a new on-curve point, then add it */ - static - FT_Error add_point1( CID_Builder* builder, - FT_Pos x, - FT_Pos y ) - { - FT_Error error; - - - error = check_points( builder, 1 ); - if ( !error ) - add_point( builder, x, y, 1 ); - - return error; - } - - - /* check room for a new contour, then add it */ - static - FT_Error add_contour( CID_Builder* builder ) - { - FT_Outline* outline = builder->current; - FT_Error error; - - - if ( !builder->load_points ) - { - outline->n_contours++; - return T1_Err_Ok; - } - - error = FT_GlyphLoader_Check_Points( builder->loader, 0, 1 ); - if ( !error ) - { - if ( outline->n_contours > 0 ) - outline->contours[outline->n_contours - 1] = outline->n_points - 1; - - outline->n_contours++; - } - return error; - } - - - /* if a path has been started, add its first on-curve point */ - static - FT_Error start_point( CID_Builder* builder, - FT_Pos x, - FT_Pos y ) - { - /* test whether we are building a new contour */ - if ( !builder->path_begun ) - { - FT_Error error; - - - builder->path_begun = 1; - error = add_contour( builder ); - if ( error ) - return error; - } - - return add_point1( builder, x, y ); - } - - - /* close the current contour */ - static - void close_contour( CID_Builder* builder ) - { - FT_Outline* outline = builder->current; - - - /* XXX: We must not include the last point in the path if it */ - /* is located on the first point. */ - if ( outline->n_points > 1 ) - { - FT_Int first = 0; - FT_Vector* p1 = outline->points + first; - FT_Vector* p2 = outline->points + outline->n_points - 1; - - - if ( outline->n_contours > 1 ) - { - first = outline->contours[outline->n_contours - 2] + 1; - p1 = outline->points + first; - } - - if ( p1->x == p2->x && p1->y == p2->y ) - outline->n_points--; - } - - if ( outline->n_contours > 0 ) - outline->contours[outline->n_contours - 1] = outline->n_points - 1; - } - - -#if 0 - - - /*************************************************************************/ - /* */ - /* */ - /* lookup_glyph_by_stdcharcode */ - /* */ - /* */ - /* Looks up a given glyph by its StandardEncoding charcode. Used */ - /* to implement the SEAC Type 1 operator. */ - /* */ - /* */ - /* face :: The current face object. */ - /* */ - /* charcode :: The character code to look for. */ - /* */ - /* */ - /* A glyph index in the font face. Returns -1 if the corresponding */ - /* glyph wasn't found. */ - /* */ - static - FT_Int lookup_glyph_by_stdcharcode( CID_Face face, - FT_Int charcode ) - { - FT_Int n; - const FT_String* glyph_name; - PSNames_Interface* psnames = (PSNames_Interface*)face->psnames; - - - /* check range of standard char code */ - if ( charcode < 0 || charcode > 255 ) - return -1; - - glyph_name = psnames->adobe_std_strings( - psnames->adobe_std_encoding[charcode]); - - for ( n = 0; n < face->cid.cid_count; n++ ) - { - FT_String* name = (FT_String*)face->type1.glyph_names[n]; - - - if ( name && strcmp( name, glyph_name ) == 0 ) - return n; - } - - return -1; - } - - -#endif /* 0 */ - - - /*************************************************************************/ - /* */ - /* */ - /* t1operator_seac */ - /* */ - /* */ - /* Implements the `seac' Type 1 operator for a Type 1 decoder. */ - /* */ - /* */ - /* decoder :: The current CID decoder. */ - /* */ - /* asb :: The accent's side bearing. */ - /* */ - /* adx :: The horizontal offset of the accent. */ - /* */ - /* ady :: The vertical offset of the accent. */ - /* */ - /* bchar :: The base character's StandardEncoding charcode. */ - /* */ - /* achar :: The accent character's StandardEncoding charcode. */ - /* */ - /* */ - /* FreeType error code. 0 means success. */ - /* */ - static - FT_Error t1operator_seac( CID_Decoder* decoder, - FT_Pos asb, - FT_Pos adx, - FT_Pos ady, - FT_Int bchar, - FT_Int achar ) - { - FT_Error error; - FT_Int bchar_index, achar_index, n_base_points; - FT_Outline* base = decoder->builder.base; - FT_Vector left_bearing, advance; - - - bchar_index = bchar; - achar_index = achar; - - if ( bchar_index < 0 || achar_index < 0 ) - { - FT_ERROR(( "t1operator_seac:" )); - FT_ERROR(( " invalid seac character code arguments\n" )); - return T1_Err_Syntax_Error; - } - - /* if we are trying to load a composite glyph, do not load the */ - /* accent character and return the array of subglyphs. */ - if ( decoder->builder.no_recurse ) - { - FT_GlyphSlot glyph = (FT_GlyphSlot)decoder->builder.glyph; - FT_GlyphLoader* loader = glyph->loader; - FT_SubGlyph* subg; - - - /* reallocate subglyph array if necessary */ - error = FT_GlyphLoader_Check_Subglyphs( loader, 2 ); - if ( error ) - goto Exit; - - subg = loader->current.subglyphs; - - /* subglyph 0 = base character */ - subg->index = bchar_index; - subg->flags = FT_SUBGLYPH_FLAG_ARGS_ARE_XY_VALUES | - FT_SUBGLYPH_FLAG_USE_MY_METRICS; - subg->arg1 = 0; - subg->arg2 = 0; - subg++; - - /* subglyph 1 = accent character */ - subg->index = achar_index; - subg->flags = FT_SUBGLYPH_FLAG_ARGS_ARE_XY_VALUES; - subg->arg1 = adx - asb; - subg->arg2 = ady; - - /* set up remaining glyph fields */ - glyph->num_subglyphs = 2; - glyph->subglyphs = loader->current.subglyphs; - glyph->format = ft_glyph_format_composite; - - loader->current.num_subglyphs = 2; - } - - /* First load `bchar' in builder */ - /* now load the unscaled outline */ - if ( decoder->builder.loader ) - FT_GlyphLoader_Prepare( decoder->builder.loader ); - - error = cid_load_glyph( decoder, bchar_index ); /* load one glyph */ - if ( error ) + CID_Face face = (CID_Face)decoder->builder.face; + CID_Info* cid = &face->cid; + FT_Byte* p; + FT_UInt entry_len = cid->fd_bytes + cid->gd_bytes; + FT_UInt fd_select; + FT_ULong off1, glyph_len; + FT_Stream stream = face->root.stream; + FT_Error error = 0; + + + /* read the CID font dict index and charstring offset from the CIDMap */ + if ( FILE_Seek( cid->data_offset + cid->cidmap_offset + + glyph_index * entry_len) || + ACCESS_Frame( 2 * entry_len ) ) goto Exit; - n_base_points = base->n_points; + p = (FT_Byte*)stream->cursor; + fd_select = (FT_UInt) cid_get_offset( &p, (FT_Byte)cid->fd_bytes ); + off1 = (FT_ULong)cid_get_offset( &p, (FT_Byte)cid->gd_bytes ); + p += cid->fd_bytes; + glyph_len = cid_get_offset( &p, (FT_Byte)cid->gd_bytes ) - off1; + FORGET_Frame(); + + /* now, if the glyph is not empty, set up the subrs array, and parse */ + /* the charstrings */ + if ( glyph_len > 0 ) { - /* save the left bearing and width of the base character */ - /* as they will be erased by the next load. */ + CID_FontDict* dict; + CID_Subrs* cid_subrs = face->subrs + fd_select; + FT_Byte* charstring; + FT_UInt lenIV; + FT_Memory memory = face->root.memory; - left_bearing = decoder->builder.left_bearing; - advance = decoder->builder.advance; - decoder->builder.left_bearing.x = 0; - decoder->builder.left_bearing.y = 0; + /* setup subrs */ + decoder->num_subrs = cid_subrs->num_subrs; + decoder->subrs = cid_subrs->code; + decoder->subrs_len = 0; - /* Now load `achar' on top of */ - /* the base outline */ - error = cid_load_glyph( decoder, achar_index ); - if ( error ) - return error; + /* setup font matrix */ + dict = cid->font_dicts + fd_select; + lenIV = dict->private_dict.lenIV; - /* restore the left side bearing and */ - /* advance width of the base character */ + decoder->font_matrix = dict->font_matrix; + decoder->font_offset = dict->font_offset; - decoder->builder.left_bearing = left_bearing; - decoder->builder.advance = advance; + /* the charstrings are encoded (stupid!) */ + /* load the charstrings, then execute it */ - /* Finally, move the accent */ - if ( decoder->builder.load_points ) + if ( ALLOC( charstring, glyph_len ) ) + goto Exit; + + if ( !FILE_Read_At( cid->data_offset + off1, charstring, glyph_len ) ) { - FT_Outline dummy; - - - dummy.n_points = base->n_points - n_base_points; - dummy.points = base->points + n_base_points; - FT_Outline_Translate( &dummy, adx - asb, ady ); + cid_decrypt( charstring, glyph_len, 4330 ); + error = decoder->funcs.parse_charstrings( decoder, + charstring + lenIV, + glyph_len - lenIV ); } + + FREE( charstring ); } Exit: @@ -562,720 +117,8 @@ } -#define USE_ARGS( n ) do \ - { \ - top -= n; \ - if ( top < decoder->stack ) \ - goto Stack_Underflow; \ - } while ( 0 ) - /*************************************************************************/ - /* */ - /* */ - /* CID_Parse_CharStrings */ - /* */ - /* */ - /* Parses a given CID charstrings program. */ - /* */ - /* */ - /* decoder :: The current CID decoder. */ - /* */ - /* */ - /* charstring_base :: The base of the charstring stream. */ - /* */ - /* charstring_len :: The length in bytes of the charstring stream. */ - /* */ - /* */ - /* FreeType error code. 0 means success. */ - /* */ - LOCAL_FUNC - FT_Error CID_Parse_CharStrings( CID_Decoder* decoder, - FT_Byte* charstring_base, - FT_Int charstring_len ) - { - FT_Error error; - CID_Decoder_Zone* zone; - FT_Byte* ip; - FT_Byte* limit; - CID_Builder* builder = &decoder->builder; - FT_Outline* outline; - FT_Pos x, y; - - - /* First of all, initialize the decoder */ - decoder->top = decoder->stack; - decoder->zone = decoder->zones; - zone = decoder->zones; - - builder->path_begun = 0; - - zone->base = charstring_base; - limit = zone->limit = charstring_base + charstring_len; - ip = zone->cursor = zone->base; - - error = T1_Err_Ok; - outline = builder->current; - - x = builder->pos_x; - y = builder->pos_y; - - /* now, execute loop */ - while ( ip < limit ) - { - FT_Int* top = decoder->top; - CID_Operator op = op_none; - FT_Long value = 0; - - - /********************************************************************/ - /* */ - /* Decode operator or operand */ - /* */ - - /* First of all, decompress operator or value */ - switch ( *ip++ ) - { - case 1: - op = op_hstem; - break; - - case 3: - op = op_vstem; - break; - case 4: - op = op_vmoveto; - break; - case 5: - op = op_rlineto; - break; - case 6: - op = op_hlineto; - break; - case 7: - op = op_vlineto; - break; - case 8: - op = op_rrcurveto; - break; - case 9: - op = op_closepath; - break; - case 10: - op = op_callsubr; - break; - case 11: - op = op_return; - break; - - case 13: - op = op_hsbw; - break; - case 14: - op = op_endchar; - break; - - case 21: - op = op_rmoveto; - break; - case 22: - op = op_hmoveto; - break; - - case 30: - op = op_vhcurveto; - break; - case 31: - op = op_hvcurveto; - break; - - case 12: - if ( ip > limit ) - { - FT_ERROR(( "CID_Parse_CharStrings: invalid escape (12+EOF)\n" )); - goto Syntax_Error; - } - - switch ( *ip++ ) - { - case 0: - op = op_dotsection; - break; - case 1: - op = op_vstem3; - break; - case 2: - op = op_hstem3; - break; - case 6: - op = op_seac; - break; - case 7: - op = op_sbw; - break; - case 12: - op = op_div; - break; - case 16: - op = op_callothersubr; - break; - case 17: - op = op_pop; - break; - case 33: - op = op_setcurrentpoint; - break; - - default: - FT_ERROR(( "CID_Parse_CharStrings: invalid escape (12+%d)\n", - ip[-1] )); - goto Syntax_Error; - } - break; - - case 255: /* four bytes integer */ - if ( ip + 4 > limit ) - { - FT_ERROR(( "CID_Parse_CharStrings: unexpected EOF in integer\n" )); - goto Syntax_Error; - } - - value = ( (long)ip[0] << 24 ) | - ( (long)ip[1] << 16 ) | - ( (long)ip[2] << 8 ) | - ip[3]; - ip += 4; - break; - - default: - if ( ip[-1] >= 32 ) - { - if ( ip[-1] < 247 ) - value = (long)ip[-1] - 139; - else - { - if ( ++ip > limit ) - { - FT_ERROR(( "CID_Parse_CharStrings:" )); - FT_ERROR(( " unexpected EOF in integer\n" )); - goto Syntax_Error; - } - - if ( ip[-2] < 251 ) - value = ( (long)( ip[-2] - 247 ) << 8 ) + ip[-1] + 108; - else - value = -( ( ( (long)ip[-2] - 251 ) << 8 ) + ip[-1] + 108 ); - } - } - else - { - FT_ERROR(( "CID_Parse_CharStrings: invalid byte (%d)\n", - ip[-1] )); - goto Syntax_Error; - } - } - - /********************************************************************/ - /* */ - /* Push value on stack, or process operator */ - /* */ - if ( op == op_none ) - { - if ( top - decoder->stack >= T1_MAX_CHARSTRINGS_OPERANDS ) - { - FT_ERROR(( "CID_Parse_CharStrings: Stack overflow!\n" )); - goto Syntax_Error; - } - - FT_TRACE4(( " %ld", value )); - *top++ = value; - decoder->top = top; - } - else if ( op == op_callothersubr ) /* callothersubr */ - { - FT_TRACE4(( " callothersubr" )); - - if ( top - decoder->stack < 2 ) - goto Stack_Underflow; - - top -= 2; - switch ( top[1] ) - { - case 1: /* start flex feature ---------------------- */ - if ( top[0] != 0 ) - goto Unexpected_OtherSubr; - - decoder->flex_state = 1; - decoder->num_flex_vectors = 0; - if ( start_point( builder, x, y ) || - check_points( builder, 6 ) ) - goto Memory_Error; - break; - - case 2: /* add flex vectors ------------------------ */ - { - FT_Int index; - - - if ( top[0] != 0 ) - goto Unexpected_OtherSubr; - - /* note that we should not add a point for index 0. */ - /* this will move our current position to the flex */ - /* point without adding any point to the outline */ - index = decoder->num_flex_vectors++; - if ( index > 0 && index < 7 ) - add_point( builder, - x, - y, - (FT_Byte)( index==3 || index==6 ) ); - } - break; - - case 0: /* end flex feature ------------------------- */ - if ( top[0] != 3 ) - goto Unexpected_OtherSubr; - - if ( decoder->flex_state == 0 || - decoder->num_flex_vectors != 7 ) - { - FT_ERROR(( "CID_Parse_CharStrings: unexpected flex end\n" )); - goto Syntax_Error; - } - - /* now consume the remaining `pop pop setcurpoint' */ - if ( ip + 6 > limit || - ip[0] != 12 || ip[1] != 17 || /* pop */ - ip[2] != 12 || ip[3] != 17 || /* pop */ - ip[4] != 12 || ip[5] != 33 ) /* setcurpoint */ - { - FT_ERROR(( "CID_Parse_CharStrings: invalid flex charstring\n" )); - goto Syntax_Error; - } - - ip += 6; - decoder->flex_state = 0; - break; - - case 3: /* change hints ---------------------------- */ - if ( top[0] != 1 ) - goto Unexpected_OtherSubr; - - /* eat the following `pop' */ - if ( ip + 2 > limit ) - { - FT_ERROR(( "CID_Parse_CharStrings: invalid escape (12+%d)\n", - ip[-1] )); - goto Syntax_Error; - } - - if ( ip[0] != 12 || ip[1] != 17 ) - { - FT_ERROR(( "CID_Parse_CharStrings:" )); - FT_ERROR(( " `pop' expected, found (%d %d)\n", - ip[0], ip[1] )); - goto Syntax_Error; - } - ip += 2; - break; - - case 12: - case 13: - /* counter control hints, clear stack */ - top = decoder->stack; - break; - -#if 0 - - case 14: - case 15: - case 16: - case 17: - case 18: /* multiple masters */ - { - T1_Blend* blend = decoder->blend; - FT_UInt num_points, nn, mm; - FT_Int* delta; - FT_Int* values; - - - if ( !blend ) - { - FT_ERROR(( "CID_Parse_CharStrings:" )); - FT_ERROR(( " unexpected multiple masters operator!\n" )); - goto Syntax_Error; - } - - num_points = top[1] - 13 + ( top[1] == 18 ); - if ( top[0] != num_points * blend->num_designs ) - { - FT_ERROR(( "CID_Parse_CharStrings:" )); - FT_ERROR(( " incorrect number of mm arguments\n" )); - goto Syntax_Error; - } - - top -= blend->num_designs * num_points; - if ( top < decoder->stack ) - goto Stack_Underflow; - - /* We want to compute: */ - /* */ - /* a0*w0 + a1*w1 + ... + ak*wk */ - /* */ - /* but we only have the a0, a1-a0, a2-a0, .. ak-a0. */ - /* However, given that w0 + w1 + ... + wk == 1, we can */ - /* rewrite it easily as: */ - /* */ - /* a0 + (a1-a0)*w1 + (a2-a0)*w2 + .. + (ak-a0)*wk */ - /* */ - /* where k == num_designs-1 */ - /* */ - /* I guess that's why it's written in this `compact' */ - /* form... */ - /* */ - delta = top + num_points; - values = top; - for ( nn = 0; nn < num_points; nn++ ) - { - FT_Int x = values[0]; - - - for ( mm = 1; mm < blend->num_designs; mm++ ) - x += FT_MulFix( *delta++, blend->weight_vector[mm] ); - - *values++ = x; - } - /* note that `top' will be incremented later by calls to `pop' */ - } - break; - -#endif - - default: - Unexpected_OtherSubr: - FT_ERROR(( "CID_Parse_CharStrings: invalid othersubr [%d %d]!\n", - top[0], top[1] )); - goto Syntax_Error; - } - decoder->top = top; - } - else /* general operator */ - { - FT_Int num_args = t1_args_count[op]; - - - if ( top - decoder->stack < num_args ) - goto Stack_Underflow; - - top -= num_args; - - switch ( op ) - { - case op_endchar: - FT_TRACE4(( " endchar" )); - - close_contour( builder ); - - /* add current outline to the glyph slot */ - FT_GlyphLoader_Add( builder->loader ); - - /* return now! */ - FT_TRACE4(( "\n\n" )); - return T1_Err_Ok; - - case op_hsbw: - FT_TRACE4(( " hsbw" )); - - builder->left_bearing.x += top[0]; - builder->advance.x = top[1]; - builder->advance.y = 0; - - builder->last.x = x = top[0]; - builder->last.y = y = 0; - - /* The `metrics_only' indicates that we only want to compute */ - /* the glyph's metrics (lsb + advance width), not load the */ - /* rest of it. So exit immediately. */ - if ( builder->metrics_only ) - return T1_Err_Ok; - - break; - - case op_seac: - /* return immediately after processing */ - return t1operator_seac( decoder, top[0], top[1], - top[2], top[3], top[4] ); - - case op_sbw: - FT_TRACE4(( " sbw" )); - - builder->left_bearing.x += top[0]; - builder->left_bearing.y += top[1]; - builder->advance.x = top[2]; - builder->advance.y = top[3]; - - builder->last.x = x = top[0]; - builder->last.y = y = top[1]; - - /* The `metrics_only' indicates that we only want to compute */ - /* the glyph's metrics (lsb + advance width), not load the */ - /* rest of it. So exit immediately. */ - if ( builder->metrics_only ) - return T1_Err_Ok; - - break; - - case op_closepath: - FT_TRACE4(( " closepath" )); - - close_contour( builder ); - builder->path_begun = 0; - break; - - case op_hlineto: - FT_TRACE4(( " hlineto" )); - - if ( start_point( builder, x, y ) ) - goto Memory_Error; - - x += top[0]; - goto Add_Line; - - case op_hmoveto: - FT_TRACE4(( " hmoveto" )); - - x += top[0]; - break; - - case op_hvcurveto: - FT_TRACE4(( " hvcurveto" )); - - if ( start_point( builder, x, y ) || - check_points( builder, 3 ) ) - goto Memory_Error; - - x += top[0]; - add_point( builder, x, y, 0 ); - - x += top[1]; - y += top[2]; - add_point( builder, x, y, 0 ); - - y += top[3]; - add_point( builder, x, y, 1 ); - - break; - - case op_rlineto: - FT_TRACE4(( " rlineto" )); - - if ( start_point( builder, x, y ) ) - goto Memory_Error; - - x += top[0]; - y += top[1]; - - Add_Line: - if ( add_point1( builder, x, y ) ) - goto Memory_Error; - break; - - case op_rmoveto: - FT_TRACE4(( " rmoveto" )); - - x += top[0]; - y += top[1]; - break; - - case op_rrcurveto: - FT_TRACE4(( " rcurveto" )); - - if ( start_point( builder, x, y ) || - check_points( builder, 3 ) ) - goto Memory_Error; - - x += top[0]; - y += top[1]; - add_point( builder, x, y, 0 ); - - x += top[2]; - y += top[3]; - add_point( builder, x, y, 0 ); - - x += top[4]; - y += top[5]; - add_point( builder, x, y, 1 ); - - break; - - case op_vhcurveto: - FT_TRACE4(( " vhcurveto" )); - - if ( start_point( builder, x, y ) || - check_points( builder, 3 ) ) - goto Memory_Error; - - y += top[0]; - add_point( builder, x, y, 0 ); - - x += top[1]; - y += top[2]; - add_point( builder, x, y, 0 ); - - x += top[3]; - add_point( builder, x, y, 1 ); - - break; - - case op_vlineto: - FT_TRACE4(( " vlineto" )); - - if ( start_point( builder, x, y ) ) - goto Memory_Error; - - y += top[0]; - goto Add_Line; - - case op_vmoveto: - FT_TRACE4(( " vmoveto" )); - - y += top[0]; - break; - - case op_div: - FT_TRACE4(( " div" )); - - if ( top[1] ) - { - *top = top[0] / top[1]; - top++; - } - else - { - FT_ERROR(( "CID_Parse_CharStrings: division by 0\n" )); - goto Syntax_Error; - } - break; - - case op_callsubr: - { - FT_Int index; - - - FT_TRACE4(( " callsubr" )); - - index = top[0]; - if ( index < 0 || index >= (FT_Int)decoder->subrs->num_subrs ) - { - FT_ERROR(( "CID_Parse_CharStrings: invalid subrs index\n" )); - goto Syntax_Error; - } - - if ( zone - decoder->zones >= T1_MAX_SUBRS_CALLS ) - { - FT_ERROR(( "CID_Parse_CharStrings: too many nested subrs\n" )); - goto Syntax_Error; - } - - zone->cursor = ip; /* save current instruction pointer */ - - zone++; - zone->base = decoder->subrs->code[index] + decoder->lenIV; - zone->limit = decoder->subrs->code[index + 1]; - zone->cursor = zone->base; - - if ( !zone->base ) - { - FT_ERROR(( "CID_Parse_CharStrings: invoking empty subrs!\n" )); - goto Syntax_Error; - } - - decoder->zone = zone; - ip = zone->base; - limit = zone->limit; - } - break; - - case op_pop: - FT_TRACE4(( " pop" )); - - /* theoretically, the arguments are already on the stack */ - top++; - break; - - case op_return: - FT_TRACE4(( " return" )); - - if ( zone <= decoder->zones ) - { - FT_ERROR(( "CID_Parse_CharStrings: unexpected return\n" )); - goto Syntax_Error; - } - - zone--; - ip = zone->cursor; - limit = zone->limit; - decoder->zone = zone; - - break; - - case op_dotsection: - FT_TRACE4(( " dotsection" )); - - break; - - case op_hstem: - FT_TRACE4(( " hstem" )); - - break; - - case op_hstem3: - FT_TRACE4(( " hstem3" )); - - break; - - case op_vstem: - FT_TRACE4(( " vstem" )); - - break; - - case op_vstem3: - FT_TRACE4(( " vstem3" )); - - break; - - case op_setcurrentpoint: - FT_TRACE4(( " setcurrentpoint" )); - - FT_ERROR(( "CID_Parse_CharStrings:" )); - FT_ERROR(( " unexpected `setcurrentpoint'\n" )); - goto Syntax_Error; - - default: - FT_ERROR(( "CID_Parse_CharStrings: unhandled opcode %d\n", op )); - goto Syntax_Error; - } - - decoder->top = top; - - } /* general operator processing */ - - } /* while ip < limit */ - - FT_TRACE4(( "..end..\n\n" )); - - return error; - - Syntax_Error: - return T1_Err_Syntax_Error; - - Stack_Underflow: - return T1_Err_Stack_Underflow; - - Memory_Error: - return builder->error; - } - #if 0 @@ -1302,17 +145,25 @@ FT_Error CID_Compute_Max_Advance( CID_Face face, FT_Int* max_advance ) { - FT_Error error; - CID_Decoder decoder; - FT_Int glyph_index; - + FT_Error error; + T1_Decoder decoder; + FT_Int glyph_index; + + PSAux_Interface* psaux = (PSAux_Interface*)face->psaux; *max_advance = 0; /* Initialize load decoder */ - CID_Init_Decoder( &decoder ); - CID_Init_Builder( &decoder.builder, face, 0, 0 ); - + error = psaux->t1_decoder_funcs->init( &decoder, + (FT_Face)face, + 0, /* size */ + 0, /* glyph slot */ + 0, /* glyph names !!!! XXXXX */ + 0, /* blend == 0 */ + cid_load_glyph ); + if (error) + return error; + decoder.builder.metrics_only = 1; decoder.builder.load_points = 0; @@ -1351,74 +202,6 @@ /*************************************************************************/ - static - FT_Error cid_load_glyph( CID_Decoder* decoder, - FT_UInt glyph_index ) - { - CID_Face face = decoder->builder.face; - CID_Info* cid = &face->cid; - FT_Byte* p; - FT_UInt entry_len = cid->fd_bytes + cid->gd_bytes; - FT_UInt fd_select; - FT_ULong off1, glyph_len; - FT_Stream stream = face->root.stream; - FT_Error error = 0; - - - /* read the CID font dict index and charstring offset from the CIDMap */ - if ( FILE_Seek( cid->data_offset + cid->cidmap_offset + - glyph_index * entry_len) || - ACCESS_Frame( 2 * entry_len ) ) - goto Exit; - - p = (FT_Byte*)stream->cursor; - fd_select = (FT_UInt) cid_get_offset( &p, (FT_Byte)cid->fd_bytes ); - off1 = (FT_ULong)cid_get_offset( &p, (FT_Byte)cid->gd_bytes ); - p += cid->fd_bytes; - glyph_len = cid_get_offset( &p, (FT_Byte)cid->gd_bytes ) - off1; - - FORGET_Frame(); - - /* now, if the glyph is not empty, set up the subrs array, and parse */ - /* the charstrings */ - if ( glyph_len > 0 ) - { - CID_FontDict* dict; - FT_Byte* charstring; - FT_UInt lenIV; - FT_Memory memory = face->root.memory; - - - /* setup subrs */ - decoder->subrs = face->subrs + fd_select; - - /* setup font matrix */ - dict = cid->font_dicts + fd_select; - decoder->font_matrix = dict->font_matrix; - lenIV = dict->private_dict.lenIV; - decoder->lenIV = lenIV; - - /* the charstrings are encoded (stupid!) */ - /* load the charstrings, then execute it */ - - if ( ALLOC( charstring, glyph_len ) ) - goto Exit; - - if ( !FILE_Read_At( cid->data_offset + off1, charstring, glyph_len ) ) - { - cid_decrypt( charstring, glyph_len, 4330 ); - error = CID_Parse_CharStrings( decoder, - charstring + lenIV, - glyph_len - lenIV ); - } - - FREE( charstring ); - } - - Exit: - return error; - } - LOCAL_FUNC FT_Error CID_Load_Glyph( CID_GlyphSlot glyph, @@ -1426,11 +209,14 @@ FT_Int glyph_index, FT_Int load_flags ) { - FT_Error error; - CID_Decoder decoder; - CID_Face face = (CID_Face)glyph->root.face; - FT_Bool hinting; + FT_Error error; + T1_Decoder decoder; + CID_Face face = (CID_Face)glyph->root.face; + FT_Bool hinting; + PSAux_Interface* psaux = (PSAux_Interface*)face->psaux; + FT_Matrix font_matrix; + FT_Vector font_offset; if ( load_flags & FT_LOAD_NO_RECURSE ) load_flags |= FT_LOAD_NO_SCALE | FT_LOAD_NO_HINTING; @@ -1447,26 +233,36 @@ glyph->root.format = ft_glyph_format_outline; { - CID_Init_Decoder( &decoder ); - CID_Init_Builder( &decoder.builder, face, size, glyph ); + error = psaux->t1_decoder_funcs->init( &decoder, + (FT_Face)face, + (FT_Size)size, + (FT_GlyphSlot)glyph, + 0, /* glyph names -- XXXX */ + 0, /* blend == 0 */ + cid_load_glyph ); /* set up the decoder */ - decoder.builder.no_recurse = - (FT_Bool)( load_flags & FT_LOAD_NO_RECURSE ); + decoder.builder.no_recurse = (load_flags & FT_LOAD_NO_RECURSE) != 0; error = cid_load_glyph( &decoder, glyph_index ); + font_matrix = decoder.font_matrix; + font_offset = decoder.font_offset; + /* save new glyph tables */ - CID_Done_Builder( &decoder.builder ); + psaux->t1_decoder_funcs->done( &decoder ); } - /* Now, set the metrics - this is rather simple, as */ + /* now, set the metrics -- this is rather simple, as */ /* the left side bearing is the xMin, and the top side */ - /* bearing the yMax. */ + /* bearing the yMax */ if ( !error ) { - /* for composite glyphs, return only the left side bearing and the */ - /* advance width */ + glyph->root.outline.flags &= ft_outline_owner; + glyph->root.outline.flags |= ft_outline_reverse_fill; + + /* for composite glyphs, return only left side bearing and */ + /* advance width */ if ( load_flags & FT_LOAD_NO_RECURSE ) { glyph->root.metrics.horiBearingX = decoder.builder.left_bearing.x; @@ -1474,8 +270,8 @@ } else { - FT_BBox cbox; - FT_Glyph_Metrics* metrics = &glyph->root.metrics; + FT_BBox cbox; + FT_Glyph_Metrics* metrics = &glyph->root.metrics; /* copy the _unscaled_ advance width */ @@ -1488,24 +284,22 @@ glyph->root.format = ft_glyph_format_outline; - glyph->root.outline.flags &= ft_outline_owner; if ( size && size->root.metrics.y_ppem < 24 ) glyph->root.outline.flags |= ft_outline_high_precision; - glyph->root.outline.flags |= ft_outline_reverse_fill; + /* apply the font matrix */ + FT_Outline_Transform( &glyph->root.outline, &font_matrix ); -#if 0 - glyph->root.outline.second_pass = TRUE; - glyph->root.outline.high_precision = size->root.metrics.y_ppem < 24; - glyph->root.outline.dropout_mode = 2; -#endif + FT_Outline_Translate( &glyph->root.outline, + font_offset.x, + font_offset.y ); if ( ( load_flags & FT_LOAD_NO_SCALE ) == 0 ) { /* scale the outline and the metrics */ FT_Int n; - FT_Outline* cur = &glyph->root.outline; - FT_Vector* vec = cur->points; + FT_Outline* cur = decoder.builder.base; + FT_Vector* vec = cur->points; FT_Fixed x_scale = glyph->x_scale; FT_Fixed y_scale = glyph->y_scale; @@ -1527,9 +321,6 @@ metrics->vertBearingY = FT_MulFix( metrics->vertBearingY, y_scale ); } - /* apply the font matrix */ - FT_Outline_Transform( &glyph->root.outline, &decoder.font_matrix ); - /* compute the other metrics */ FT_Outline_Get_CBox( &glyph->root.outline, &cbox ); @@ -1538,8 +329,8 @@ { cbox.xMin &= -64; cbox.yMin &= -64; - cbox.xMax = ( cbox.xMax + 63 ) & -64; - cbox.yMax = ( cbox.yMax + 63 ) & -64; + cbox.xMax = ( cbox.xMax+63 ) & -64; + cbox.yMax = ( cbox.yMax+63 ) & -64; } metrics->width = cbox.xMax - cbox.xMin; @@ -1549,7 +340,6 @@ metrics->horiBearingY = cbox.yMax; } } - return error; } diff --git a/src/cid/cidgload.h b/src/cid/cidgload.h index 5f3913d52..a73548664 100644 --- a/src/cid/cidgload.h +++ b/src/cid/cidgload.h @@ -36,133 +36,6 @@ #endif - /*************************************************************************/ - /* */ - /* */ - /* CID_Builder */ - /* */ - /* */ - /* A structure used during glyph loading to store its outline. */ - /* */ - /* */ - /* memory :: The current memory object. */ - /* */ - /* face :: The current face object. */ - /* */ - /* glyph :: The current glyph slot. */ - /* */ - /* current :: The current glyph outline. */ - /* */ - /* base :: The base glyph outline. */ - /* */ - /* max_points :: maximum points in builder outline */ - /* */ - /* max_contours :: Maximal number of contours in builder outline. */ - /* */ - /* last :: The last point position. */ - /* */ - /* scale_x :: The horizontal scale (FUnits to sub-pixels). */ - /* */ - /* scale_y :: The vertical scale (FUnits to sub-pixels). */ - /* */ - /* pos_x :: The horizontal translation (if composite glyph). */ - /* */ - /* pos_y :: The vertical translation (if composite glyph). */ - /* */ - /* left_bearing :: The left side bearing point. */ - /* */ - /* advance :: The horizontal advance vector. */ - /* */ - /* bbox :: Unused. */ - /* */ - /* path_begun :: A flag which indicates that a new path has begun. */ - /* */ - /* load_points :: If this flag is not set, no points are loaded. */ - /* */ - /* no_recurse :: Set but not used. */ - /* */ - /* error :: An error code that is only used to report memory */ - /* allocation problems. */ - /* */ - /* metrics_only :: A boolean indicating that we only want to compute */ - /* the metrics of a given glyph, not load all of its */ - /* points. */ - /* */ - typedef struct CID_Builder_ - { - FT_Memory memory; - CID_Face face; - CID_GlyphSlot glyph; - FT_GlyphLoader* loader; - FT_Outline* base; - FT_Outline* current; - - FT_Vector last; - - FT_Fixed scale_x; - FT_Fixed scale_y; - - FT_Pos pos_x; - FT_Pos pos_y; - - FT_Vector left_bearing; - FT_Vector advance; - - FT_BBox bbox; /* bounding box */ - FT_Bool path_begun; - FT_Bool load_points; - FT_Bool no_recurse; - - FT_Error error; /* only used for memory errors */ - FT_Bool metrics_only; - - } CID_Builder; - - - /* execution context charstring zone */ - - typedef struct CID_Decoder_Zone_ - { - FT_Byte* base; - FT_Byte* limit; - FT_Byte* cursor; - - } CID_Decoder_Zone; - - - typedef struct CID_Decoder_ - { - CID_Builder builder; - - FT_Int stack[T1_MAX_CHARSTRINGS_OPERANDS]; - FT_Int* top; - - CID_Decoder_Zone zones[T1_MAX_SUBRS_CALLS + 1]; - CID_Decoder_Zone* zone; - - FT_Matrix font_matrix; - CID_Subrs* subrs; - FT_UInt lenIV; - - FT_Int flex_state; - FT_Int num_flex_vectors; - FT_Vector flex_vectors[7]; - - } CID_Decoder; - - - LOCAL_DEF - void CID_Init_Builder( CID_Builder* builder, - CID_Face face, - CID_Size size, - CID_GlyphSlot glyph ); - - LOCAL_DEF - void CID_Done_Builder( CID_Builder* builder ); - - - LOCAL_DEF - void CID_Init_Decoder( CID_Decoder* decoder ); #if 0 @@ -174,12 +47,6 @@ #endif - /* This function is exported, because it is used by the T1Dump utility */ - LOCAL_DEF - FT_Error CID_Parse_CharStrings( CID_Decoder* decoder, - FT_Byte* charstring_base, - FT_Int charstring_len ); - LOCAL_DEF FT_Error CID_Load_Glyph( CID_GlyphSlot glyph, CID_Size size, diff --git a/src/cid/cidload.c b/src/cid/cidload.c index b512bef03..cd43f6571 100644 --- a/src/cid/cidload.c +++ b/src/cid/cidload.c @@ -97,20 +97,22 @@ static - FT_Error cid_load_keyword( CID_Face face, - CID_Loader* loader, - const CID_Field_Rec* keyword ) + FT_Error cid_load_keyword( CID_Face face, + CID_Loader* loader, + const T1_Field* keyword ) { FT_Error error; CID_Parser* parser = &loader->parser; FT_Byte* object; + void* dummy_object; CID_Info* cid = &face->cid; /* if the keyword has a dedicated callback, call it */ if ( keyword->type == t1_field_callback ) { - error = keyword->reader( face, parser ); + keyword->reader( (FT_Face)face, parser ); + error = parser->root.error; goto Exit; } @@ -151,13 +153,15 @@ } } + dummy_object = object; + /* now, load the keyword data in the object's field(s) */ if ( keyword->type == t1_field_integer_array || keyword->type == t1_field_fixed_array ) - error = CID_Load_Field_Table( parser, keyword, object ); + error = CID_Load_Field_Table( &loader->parser, keyword, + &dummy_object ); else - error = CID_Load_Field( parser, keyword, object ); - + error = CID_Load_Field( &loader->parser, keyword, &dummy_object ); Exit: return error; } @@ -187,20 +191,36 @@ CID_Parser* parser ) { FT_Matrix* matrix; + FT_Vector* offset; CID_FontDict* dict; - FT_Fixed temp[4]; + FT_Fixed temp[6]; if ( parser->num_dict >= 0 ) { dict = face->cid.font_dicts + parser->num_dict; matrix = &dict->font_matrix; + offset = &dict->font_offset; + + (void)CID_ToFixedArray( parser, 6, temp, 3 ); + + /* we need to scale the values by 1.0/temp[3] */ + if ( temp[3] != 0x10000L ) + { + temp[0] = FT_DivFix( temp[0], temp[3] ); + temp[1] = FT_DivFix( temp[1], temp[3] ); + temp[2] = FT_DivFix( temp[2], temp[3] ); + temp[4] = FT_DivFix( temp[4], temp[3] ); + temp[5] = FT_DivFix( temp[5], temp[3] ); + temp[3] = 0x10000L; + } - (void)CID_ToFixedArray( parser, 4, temp, 3 ); matrix->xx = temp[0]; matrix->yx = temp[1]; matrix->xy = temp[2]; matrix->yy = temp[3]; + offset->x = temp[4]; + offset->y = temp[5]; } return T1_Err_Ok; /* this is a callback function; */ @@ -247,7 +267,7 @@ static - const CID_Field_Rec t1_field_records[] = + const T1_Field cid_field_records[] = { #ifdef FT_FLAT_COMPILE @@ -260,7 +280,10 @@ #endif - { 0, t1_field_cid_info, t1_field_none, 0, 0, 0, 0, 0 } + T1_FIELD_CALLBACK( "FontBBox", parse_font_bbox ) + T1_FIELD_CALLBACK( "FDArray", parse_fd_array ) + T1_FIELD_CALLBACK( "FontMatrix", parse_font_matrix ) + { 0, 0, 0, 0, 0, 0, 0, 0 } }; @@ -273,31 +296,19 @@ } - static - void skip_whitespace( CID_Parser* parser ) - { - FT_Byte* cur = parser->cursor; - - - while ( cur < parser->limit && isspace( *cur ) ) - cur++; - - parser->cursor = cur; - } - static - FT_Error parse_dict( CID_Face face, - CID_Loader* loader, - FT_Byte* base, - FT_Long size ) + FT_Error cid_parse_dict( CID_Face face, + CID_Loader* loader, + FT_Byte* base, + FT_Long size ) { CID_Parser* parser = &loader->parser; - parser->cursor = base; - parser->limit = base + size; - parser->error = 0; + parser->root.cursor = base; + parser->root.limit = base + size; + parser->root.error = 0; { FT_Byte* cur = base; @@ -334,7 +345,7 @@ if ( len > 0 && len < 22 ) { /* now compare the immediate name to the keyword table */ - const CID_Field_Rec* keyword = t1_field_records; + const T1_Field* keyword = cid_field_records; for (;;) @@ -359,13 +370,13 @@ if ( n >= len ) { /* we found it - run the parsing callback */ - parser->cursor = cur2; - skip_whitespace( parser ); - parser->error = cid_load_keyword( face, loader, keyword ); - if ( parser->error ) - return parser->error; + parser->root.cursor = cur2; + CID_Skip_Spaces( parser ); + parser->root.error = cid_load_keyword( face, loader, keyword ); + if ( parser->root.error ) + return parser->root.error; - cur = parser->cursor; + cur = parser->root.cursor; break; } } @@ -375,7 +386,7 @@ } } } - return parser->error; + return parser->root.error; } @@ -515,13 +526,14 @@ t1_init_loader( &loader, face ); parser = &loader.parser; - error = CID_New_Parser( parser, face->root.stream, face->root.memory ); + error = CID_New_Parser( parser, face->root.stream, face->root.memory, + (PSAux_Interface*)face->psaux ); if ( error ) goto Exit; - error = parse_dict( face, &loader, - parser->postscript, - parser->postscript_len ); + error = cid_parse_dict( face, &loader, + parser->postscript, + parser->postscript_len ); if ( error ) goto Exit; diff --git a/src/cid/cidload.h b/src/cid/cidload.h index 7495da0dc..388589637 100644 --- a/src/cid/cidload.h +++ b/src/cid/cidload.h @@ -21,7 +21,6 @@ #include - #ifdef FT_FLAT_COMPILE #include "cidparse.h" diff --git a/src/cid/cidobjs.c b/src/cid/cidobjs.c index 588e5f1a9..334d14b79 100644 --- a/src/cid/cidobjs.c +++ b/src/cid/cidobjs.c @@ -34,6 +34,7 @@ #include +#include /*************************************************************************/ @@ -132,6 +133,7 @@ { FT_Error error; PSNames_Interface* psnames; + PSAux_Interface* psaux; FT_UNUSED( num_params ); FT_UNUSED( params ); @@ -150,6 +152,15 @@ face->psnames = psnames; } + psaux = (PSAux_Interface*)face->psaux; + if ( !psaux ) + { + psaux = (PSAux_Interface*)FT_Get_Module_Interface( + FT_FACE_LIBRARY( face ), "psaux" ); + + face->psaux = psaux; + } + /* open the tokenizer; this will also check the font format */ if ( FILE_Seek( 0 ) ) goto Exit; diff --git a/src/cid/cidparse.c b/src/cid/cidparse.c index 9c4c4aa0e..fb5dcc7b7 100644 --- a/src/cid/cidparse.c +++ b/src/cid/cidparse.c @@ -43,226 +43,10 @@ /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log */ /* messages during execution. */ /* */ -#undef FT_COMPONENT +#undef FT_COMPONENT #define FT_COMPONENT trace_cidparse -#if 0 - - /*************************************************************************/ - /*************************************************************************/ - /*************************************************************************/ - /***** *****/ - /***** IMPLEMENTATION OF CID_TABLE OBJECT *****/ - /***** *****/ - /*************************************************************************/ - /*************************************************************************/ - /*************************************************************************/ - - - /*************************************************************************/ - /* */ - /* */ - /* CID_New_Table */ - /* */ - /* */ - /* Initializes a CID_Table. */ - /* */ - /* */ - /* table :: The address of the target table. */ - /* */ - /* */ - /* count :: The table size, i.e., the maximal number of elements. */ - /* */ - /* memory :: The memory object to be used for all subsequent */ - /* reallocations. */ - /* */ - /* */ - /* FreeType error code. 0 means success. */ - /* */ - LOCAL_FUNC - FT_Error CID_New_Table( CID_Table* table, - FT_Int count, - FT_Memory memory ) - { - FT_Error error; - - - table->memory = memory; - if ( ALLOC_ARRAY( table->elements, count, FT_Byte* ) || - ALLOC_ARRAY( table->lengths, count, FT_Byte* ) ) - goto Exit; - - table->max_elems = count; - table->init = 0xDEADBEEFL; - table->num_elems = 0; - table->block = 0; - table->capacity = 0; - table->cursor = 0; - - Exit: - if ( error ) - FREE( table->elements ); - - return error; - } - - - static - void shift_elements( CID_Table* table, - FT_Byte* old_base ) - { - FT_Long delta = table->block - old_base; - FT_Byte** offset = table->elements; - FT_Byte** limit = offset + table->max_elems; - - - if ( delta ) - for ( ; offset < limit; offset++ ) - { - if ( offset[0] ) - offset[0] += delta; - } - } - - - static - FT_Error reallocate_t1_table( CID_Table* table, - FT_Int new_size ) - { - FT_Memory memory = table->memory; - FT_Byte* old_base = table->block; - FT_Error error; - - - /* realloc the base block */ - if ( REALLOC( table->block, table->capacity, new_size ) ) - return error; - - table->capacity = new_size; - - /* shift all offsets when needed */ - if ( old_base ) - shift_elements( table, old_base ); - - return T1_Err_Ok; - } - - - /*************************************************************************/ - /* */ - /* */ - /* CID_Add_Table */ - /* */ - /* */ - /* Adds an object to a CID_Table, possibly growing its memory block. */ - /* */ - /* */ - /* table :: The target table. */ - /* */ - /* */ - /* index :: The index of the object in the table. */ - /* */ - /* object :: The address of the object to copy in the memory. */ - /* */ - /* length :: The length in bytes of the source object. */ - /* */ - /* */ - /* FreeType error code. 0 means success. An error is returned if */ - /* reallocation fails. */ - /* */ - LOCAL_FUNC - FT_Error CID_Add_Table( CID_Table* table, - FT_Int index, - void* object, - FT_Int length ) - { - if ( index < 0 || index > table->max_elems ) - { - FT_ERROR(( "CID_Add_Table: invalid index\n" )); - return T1_Err_Syntax_Error; - } - - /* grow the base block if needed */ - if ( table->cursor + length > table->capacity ) - { - FT_Error error; - FT_Int new_size = table->capacity; - - - while ( new_size < table->cursor + length ) - new_size += 1024; - - error = reallocate_t1_table( table, new_size ); - if ( error ) - return error; - } - - /* add the object to the base block and adjust offset */ - table->elements[index] = table->block + table->cursor; - table->lengths [index] = length; - - MEM_Copy( table->block + table->cursor, object, length ); - - table->cursor += length; - - return T1_Err_Ok; - } - - - /*************************************************************************/ - /* */ - /* */ - /* CID_Done_Table */ - /* */ - /* */ - /* Finalizes a CID_Table (reallocate it to its current cursor). */ - /* */ - /* */ - /* table :: The target table. */ - /* */ - /* */ - /* This function does NOT release the heap's memory block. It is up */ - /* to the caller to clean it, or reference it in its own structures. */ - /* */ - LOCAL_FUNC - void CID_Done_Table( CID_Table* table ) - { - FT_Memory memory = table->memory; - FT_Error error; - FT_Byte* old_base; - - - /* should never fail, as rec.cursor <= rec.size */ - old_base = table->block; - if ( !old_base ) - return; - - (void)REALLOC( table->block, table->capacity, table->cursor ); - table->capacity = table->cursor; - - if ( old_base != table->block ) - shift_elements( table, old_base ); - } - - - LOCAL_FUNC - void CID_Release_Table( CID_Table* table ) - { - FT_Memory memory = table->memory; - - - if ( table->init == 0xDEADBEEFL ) - { - FREE( table->block ); - FREE( table->elements ); - FREE( table->lengths ); - table->init = 0; - } - } - -#endif /* 0 */ - /*************************************************************************/ /*************************************************************************/ @@ -275,671 +59,21 @@ /*************************************************************************/ -#define IS_CID_WHITESPACE( c ) ( (c) == ' ' || (c) == '\t' ) -#define IS_CID_LINESPACE( c ) ( (c) == '\r' || (c) == '\n' ) - -#define IS_CID_SPACE( c ) ( IS_CID_WHITESPACE( c ) || IS_CID_LINESPACE( c ) ) - - LOCAL_FUNC - void CID_Skip_Spaces( CID_Parser* parser ) - { - FT_Byte* cur = parser->cursor; - FT_Byte* limit = parser->limit; - - - while ( cur < limit ) - { - FT_Byte c = *cur; - - - if ( !IS_CID_SPACE( c ) ) - break; - cur++; - } - - parser->cursor = cur; - } - - - LOCAL_FUNC - void CID_ToToken( CID_Parser* parser, - CID_Token_Rec* token ) - { - FT_Byte* cur; - FT_Byte* limit; - FT_Byte starter, ender; - FT_Int embed; - - - token->type = t1_token_none; - token->start = 0; - token->limit = 0; - - /* first of all, skip space */ - CID_Skip_Spaces( parser ); - - cur = parser->cursor; - limit = parser->limit; - - if ( cur < limit ) - { - switch ( *cur ) - { - /************* check for strings ***********************/ - case '(': - token->type = t1_token_string; - ender = ')'; - goto Lookup_Ender; - - /************* check for programs/array ****************/ - case '{': - token->type = t1_token_array; - ender = '}'; - goto Lookup_Ender; - - /************* check for table/array ******************/ - case '[': - token->type = t1_token_array; - ender = ']'; - - Lookup_Ender: - embed = 1; - starter = *cur++; - token->start = cur; - - while ( cur < limit ) - { - if ( *cur == starter ) - embed++; - else if ( *cur == ender ) - { - embed--; - if ( embed <= 0 ) - { - token->limit = cur++; - break; - } - } - cur++; - } - break; - - /* **************** otherwise, it is any token **********/ - default: - token->start = cur++; - token->type = t1_token_any; - while ( cur < limit && !IS_CID_SPACE( *cur ) ) - cur++; - - token->limit = cur; - } - - if ( !token->limit ) - { - token->start = 0; - token->type = t1_token_none; - } - - parser->cursor = cur; - } - } - - - LOCAL_FUNC - void CID_ToTokenArray( CID_Parser* parser, - CID_Token_Rec* tokens, - FT_UInt max_tokens, - FT_Int* pnum_tokens ) - { - CID_Token_Rec master; - - - *pnum_tokens = -1; - - CID_ToToken( parser, &master ); - - if ( master.type == t1_token_array ) - { - FT_Byte* old_cursor = parser->cursor; - FT_Byte* old_limit = parser->limit; - CID_Token_Rec* cur = tokens; - CID_Token_Rec* limit = cur + max_tokens; - - - parser->cursor = master.start; - parser->limit = master.limit; - - while ( parser->cursor < parser->limit ) - { - CID_Token_Rec token; - - - CID_ToToken( parser, &token ); - if ( !token.type ) - break; - - if ( cur < limit ) - *cur = token; - - cur++; - } - - *pnum_tokens = cur - tokens; - - parser->cursor = old_cursor; - parser->limit = old_limit; - } - } - - - static - FT_Long t1_toint( FT_Byte** cursor, - FT_Byte* limit ) - { - FT_Long result = 0; - FT_Byte* cur = *cursor; - FT_Byte c = '\0', d; - - - for ( ; cur < limit; cur++ ) - { - c = *cur; - d = (FT_Byte)( c - '0' ); - if ( d < 10 ) - break; - - if ( c == '-' ) - { - cur++; - break; - } - } - - if ( cur < limit ) - { - do - { - d = (FT_Byte)( cur[0] - '0' ); - if ( d >= 10 ) - break; - - result = result * 10 + d; - cur++; - - } while ( cur < limit ); - - if ( c == '-' ) - result = -result; - } - - *cursor = cur; - - return result; - } - - - static - FT_Long t1_tofixed( FT_Byte** cursor, - FT_Byte* limit, - FT_Long power_ten ) - { - FT_Byte* cur = *cursor; - FT_Long num, divider, result; - FT_Int sign = 0; - FT_Byte d; - - - if ( cur >= limit ) - return 0; - - /* first of all, read the integer part */ - result = t1_toint( &cur, limit ) << 16; - num = 0; - divider = 1; - - if ( result < 0 ) - { - sign = 1; - result = -result; - } - - if ( cur >= limit ) - goto Exit; - - /* read decimal part, if any */ - if ( *cur == '.' && cur + 1 < limit ) - { - cur++; - - for (;;) - { - d = (FT_Byte)( *cur - '0' ); - if ( d >= 10 ) - break; - - if ( divider < 10000000L ) - { - num = num * 10 + d; - divider *= 10; - } - - cur++; - if ( cur >= limit ) - break; - } - } - - /* read exponent, if any */ - if ( cur + 1 < limit && ( *cur == 'e' || *cur == 'E' ) ) - { - cur++; - power_ten += t1_toint( &cur, limit ); - } - - Exit: - /* raise to power of ten if needed */ - while ( power_ten > 0 ) - { - result = result * 10; - num = num * 10; - power_ten--; - } - - while ( power_ten < 0 ) - { - result = result / 10; - divider = divider * 10; - power_ten++; - } - - if ( num ) - result += FT_DivFix( num, divider ); - - if ( sign ) - result = -result; - - *cursor = cur; - - return result; - } - - - static - int t1_tobool( FT_Byte** cursor, - FT_Byte* limit ) - { - FT_Byte* cur = *cursor; - FT_Bool result = 0; - - - /* return 1 if we find a "true", 0 otherwise */ - if ( cur + 3 < limit && - cur[0] == 't' && - cur[1] == 'r' && - cur[2] == 'u' && - cur[3] == 'e' ) - { - result = 1; - cur += 5; - } - else if ( cur + 4 < limit && - cur[0] == 'f' && - cur[1] == 'a' && - cur[2] == 'l' && - cur[3] == 's' && - cur[4] == 'e' ) - { - result = 0; - cur += 6; - } - *cursor = cur; - return result; - } - - - static - FT_Int t1_tocoordarray( FT_Byte** cursor, - FT_Byte* limit, - FT_Int max_coords, - FT_Short* coords ) - { - FT_Byte* cur = *cursor; - FT_Int count = 0; - FT_Byte c, ender; - - - if ( cur >= limit ) - goto Exit; - - /* check for the beginning of an array. */ - /* If not, only one number will be read */ - c = *cur; - ender = 0; - - if ( c == '[' ) - ender = ']'; - - if ( c == '{' ) - ender = '}'; - - if ( ender ) - cur++; - - /* now, read the coordinates */ - for ( ; cur < limit; ) - { - /* skip whitespace in front of data */ - for (;;) - { - c = *cur; - if ( c != ' ' && c != '\t' ) - break; - - cur++; - if ( cur >= limit ) - goto Exit; - } - - if ( count >= max_coords || c == ender ) - break; - - coords[count] = (FT_Short)( t1_tofixed( &cur, limit, 0 ) >> 16 ); - count++; - - if ( !ender ) - break; - } - - Exit: - *cursor = cur; - return count; - } - - - static - FT_Int t1_tofixedarray( FT_Byte** cursor, - FT_Byte* limit, - FT_Int max_values, - FT_Fixed* values, - FT_Int power_ten ) - { - FT_Byte* cur = *cursor; - FT_Int count = 0; - FT_Byte c, ender; - - - if ( cur >= limit ) - goto Exit; - - /* check for the beginning of an array. */ - /* If not, only one number will be read */ - c = *cur; - ender = 0; - - if ( c == '[' ) - ender = ']'; - - if ( c == '{' ) - ender = '}'; - - if ( ender ) - cur++; - - /* now, read the values */ - for ( ; cur < limit; ) - { - /* skip whitespace in front of data */ - for (;;) - { - c = *cur; - if ( c != ' ' && c != '\t' ) - break; - - cur++; - if ( cur >= limit ) - goto Exit; - } - - if ( count >= max_values || c == ender ) - break; - - values[count] = t1_tofixed( &cur, limit, power_ten ); - count++; - - if ( !ender ) - break; - } - - Exit: - *cursor = cur; - - return count; - } - - - /* Loads a simple field (i.e. non-table) into the current */ - /* list of objects */ - LOCAL_FUNC - FT_Error CID_Load_Field( CID_Parser* parser, - const CID_Field_Rec* field, - void* object ) - { - CID_Token_Rec token; - FT_Byte* cur; - FT_Byte* limit; - FT_UInt count; - FT_UInt index; - FT_Error error; - - - CID_ToToken( parser, &token ); - if ( !token.type ) - goto Fail; - - count = 1; - index = 0; - cur = token.start; - limit = token.limit; - - { - FT_Byte* q = (FT_Byte*)object + field->offset; - FT_Long val; - FT_String* string; - - - switch ( field->type ) - { - case t1_field_bool: - val = t1_tobool( &cur, limit ); - goto Store_Integer; - - case t1_field_fixed: - val = t1_tofixed( &cur, limit, 0 ); - goto Store_Integer; - - case t1_field_integer: - val = t1_toint( &cur, limit ); - - Store_Integer: - switch ( field->size ) - { - case 1: - *(FT_Byte*)q = (FT_Byte)val; - break; - - case 2: - *(FT_UShort*)q = (FT_UShort)val; - break; - - case 4: - *(FT_Int32*)q = (FT_Int)val; - break; - - default: /* for 64-bit systems */ - *(FT_Long*)q = val; - } - break; - - case t1_field_string: - { - FT_Memory memory = parser->memory; - FT_UInt len = limit-cur; - - - if ( ALLOC( string, len + 1 ) ) - goto Exit; - - MEM_Copy( string, cur, len ); - string[len] = 0; - - *(FT_String**)q = string; - } - break; - - default: - /* an error occurred */ - goto Fail; - } - } - - error = 0; - - Exit: - return error; - - Fail: - error = T1_Err_Invalid_File_Format; - goto Exit; - } - - -#define T1_MAX_TABLE_ELEMENTS 32 - - - LOCAL_FUNC - FT_Error CID_Load_Field_Table( CID_Parser* parser, - const CID_Field_Rec* field, - void* object ) - { - CID_Token_Rec elements[T1_MAX_TABLE_ELEMENTS]; - CID_Token_Rec* token; - FT_Int num_elements; - FT_Error error = 0; - FT_Byte* old_cursor; - FT_Byte* old_limit; - CID_Field_Rec fieldrec = *(CID_Field_Rec*)field; - - - fieldrec.type = t1_field_integer; - if ( field->type == t1_field_fixed_array ) - fieldrec.type = t1_field_fixed; - - CID_ToTokenArray( parser, elements, 32, &num_elements ); - if ( num_elements < 0 ) - goto Fail; - - if ( num_elements > T1_MAX_TABLE_ELEMENTS ) - num_elements = T1_MAX_TABLE_ELEMENTS; - - old_cursor = parser->cursor; - old_limit = parser->limit; - - /* we store the elements count */ - if ( field->count_offset ) - *(FT_Byte*)( (FT_Byte*)object + field->count_offset ) = num_elements; - - /* we now load each element, adjusting the field.offset on each one */ - token = elements; - for ( ; num_elements > 0; num_elements--, token++ ) - { - parser->cursor = token->start; - parser->limit = token->limit; - CID_Load_Field( parser, &fieldrec, object ); - fieldrec.offset += fieldrec.size; - } - - parser->cursor = old_cursor; - parser->limit = old_limit; - - Exit: - return error; - - Fail: - error = T1_Err_Invalid_File_Format; - goto Exit; - } - - - LOCAL_FUNC - FT_Long CID_ToInt( CID_Parser* parser ) - { - return t1_toint( &parser->cursor, parser->limit ); - } - - - LOCAL_FUNC - FT_Int CID_ToCoordArray( CID_Parser* parser, - FT_Int max_coords, - FT_Short* coords ) - { - return t1_tocoordarray( &parser->cursor, parser->limit, - max_coords, coords ); - } - - - LOCAL_FUNC - FT_Int CID_ToFixedArray( CID_Parser* parser, - FT_Int max_values, - FT_Fixed* values, - FT_Int power_ten ) - { - return t1_tofixedarray( &parser->cursor, parser->limit, - max_values, values, power_ten ); - } - - -#if 0 - - /* return the value of an hexadecimal digit */ - static - int hexa_value( char c ) - { - unsigned int d; - - - d = (unsigned int)( c - '0' ); - if ( d <= 9 ) - return (int)d; - - d = (unsigned int)( c - 'a' ); - if ( d <= 5 ) - return (int)( d + 10 ); - - d = (unsigned int)( c - 'A' ); - if ( d <= 5 ) - return (int)( d + 10 ); - - return -1; - } - -#endif /* 0 */ - - - LOCAL_FUNC - FT_Error CID_New_Parser( CID_Parser* parser, - FT_Stream stream, - FT_Memory memory ) + FT_Error CID_New_Parser( CID_Parser* parser, + FT_Stream stream, + FT_Memory memory, + PSAux_Interface* psaux ) { FT_Error error; FT_ULong base_offset, offset, ps_len; FT_Byte buffer[256 + 10]; FT_Int buff_len; - MEM_Set( parser, 0, sizeof ( *parser ) ); + psaux->t1_parser_funcs->init( &parser->root, 0, 0, memory ); + parser->stream = stream; - parser->memory = memory; base_offset = FILE_Pos(); @@ -998,8 +132,9 @@ parser->data_offset = offset; parser->postscript_len = ps_len; - parser->cursor = parser->postscript; - parser->limit = parser->cursor + ps_len; + parser->root.base = parser->postscript; + parser->root.cursor = parser->postscript; + parser->root.limit = parser->root.cursor + ps_len; parser->num_dict = -1; Exit: @@ -1018,6 +153,7 @@ RELEASE_Frame( parser->postscript ); } + parser->root.funcs.done( &parser->root ); } diff --git a/src/cid/cidparse.h b/src/cid/cidparse.h index e325845c7..ea23bfe2c 100644 --- a/src/cid/cidparse.h +++ b/src/cid/cidparse.h @@ -21,81 +21,13 @@ #include #include - +#include #ifdef __cplusplus extern "C" { #endif -#if 0 - - /*************************************************************************/ - /* */ - /* */ - /* CID_Table */ - /* */ - /* */ - /* A CID_Table is a simple object used to store an array of objects */ - /* in a single memory block. */ - /* */ - /* */ - /* block :: The address in memory of the growheap's block. This */ - /* can change between two object adds, due to the use */ - /* of `realloc()'. */ - /* */ - /* cursor :: The current top of the growheap within its block. */ - /* */ - /* capacity :: The current size of the heap block. Increments by */ - /* blocks of 1 kByte. */ - /* */ - /* init :: A boolean. Set when the table has been initialized */ - /* (the table user should set this field). */ - /* */ - /* max_elems :: The maximal number of elements in the table. */ - /* */ - /* num_elems :: The current number of elements (in use) in the table. */ - /* */ - /* elements :: A table of element addresses within the block. */ - /* */ - /* lengths :: A table of element sizes within the block. */ - /* */ - /* memory :: The memory object used for memory operations */ - /* (allocation resp. reallocation). */ - /* */ - typedef struct CID_Table_ - { - FT_Byte* block; /* current memory block */ - FT_Int cursor; /* current cursor in memory block */ - FT_Int capacity; /* current size of memory block */ - FT_Long init; - - FT_Int max_elems; - FT_Int num_elems; - FT_Byte** elements; /* addresses of table elements */ - FT_Int* lengths; /* lengths of table elements */ - - FT_Memory memory; - - } CID_Table; - - - LOCAL_DEF - FT_Error CID_New_Table( CID_Table* table, - FT_Int count, - CID_Memory memory ); - - LOCAL_DEF - FT_Error CID_Add_Table( CID_Table* table, - FT_Int index, - void* object, - FT_Int length ); - - LOCAL_DEF - void CID_Release_Table( CID_Table* table ); - -#endif /* 0 */ - /*************************************************************************/ /* */ @@ -107,9 +39,9 @@ /* quickly. */ /* */ /* */ - /* stream :: The current input stream. */ + /* root :: the root T1_Parser fields */ /* */ - /* memory :: The current memory object. */ + /* stream :: The current input stream. */ /* */ /* postscript :: A pointer to the data to be parsed. */ /* */ @@ -118,13 +50,6 @@ /* data_offset :: The start position of the binary data (i.e., the */ /* end of the data to be parsed. */ /* */ - /* cursor :: The current parser cursor. */ - /* */ - /* limit :: The current parser limit (i.e., the first byte */ - /* after the current dictionary). */ - /* */ - /* error :: The current parsing error. */ - /* */ /* cid :: A structure which holds the information about */ /* the current font. */ /* */ @@ -132,18 +57,14 @@ /* */ typedef struct CID_Parser_ { + T1_Parser root; FT_Stream stream; - FT_Memory memory; FT_Byte* postscript; FT_Int postscript_len; FT_ULong data_offset; - FT_Byte* cursor; - FT_Byte* limit; - FT_Error error; - CID_Info* cid; FT_Int num_dict; @@ -151,9 +72,10 @@ LOCAL_DEF - FT_Error CID_New_Parser( CID_Parser* parser, - FT_Stream stream, - FT_Memory memory ); + FT_Error CID_New_Parser( CID_Parser* parser, + FT_Stream stream, + FT_Memory memory, + PSAux_Interface* psaux ); LOCAL_DEF void CID_Done_Parser( CID_Parser* parser ); @@ -165,181 +87,21 @@ /* */ /*************************************************************************/ - LOCAL_DEF - FT_Long CID_ToInt( CID_Parser* parser ); +#define CID_Skip_Spaces(p) (p)->root.funcs.skip_spaces( &(p)->root ) +#define CID_Skip_Alpha(p) (p)->root.funcs.skip_alpha ( &(p)->root ) - LOCAL_DEF - FT_Int CID_ToCoordArray( CID_Parser* parser, - FT_Int max_coords, - FT_Short* coords ); +#define CID_ToInt(p) (p)->root.funcs.to_int( &(p)->root ) +#define CID_ToFixed(p,t) (p)->root.funcs.to_fixed( &(p)->root, t ) - LOCAL_DEF - FT_Int CID_ToFixedArray( CID_Parser* parser, - FT_Int max_values, - FT_Fixed* values, - FT_Int power_ten ); +#define CID_ToCoordArray(p,m,c) (p)->root.funcs.to_coord_array( &(p)->root, m, c ) +#define CID_ToFixedArray(p,m,f,t) (p)->root.funcs.to_fixed_array( &(p)->root, m, f, t ) +#define CID_ToToken(p,t) (p)->root.funcs.to_token( &(p)->root, t ) +#define CID_ToTokenArray(p,t,m,c) (p)->root.funcs.to_token_array( &(p)->root, t, m, c ) - LOCAL_DEF - void CID_Skip_Spaces( CID_Parser* parser ); +#define CID_Load_Field(p,f,o) (p)->root.funcs.load_field( &(p)->root, f, o, 0, 0 ) +#define CID_Load_Field_Table(p,f,o) (p)->root.funcs.load_field_table( &(p)->root, f, o, 0, 0 ) - /* simple enumeration type used to identify token types */ - typedef enum CID_Token_Type_ - { - t1_token_none = 0, - t1_token_any, - t1_token_string, - t1_token_array, - - /* do not remove */ - t1_token_max - - } CID_Token_Type; - - - /* a simple structure used to identify tokens */ - typedef struct CID_Token_Rec_ - { - FT_Byte* start; /* first character of token in input stream */ - FT_Byte* limit; /* first character after the token */ - CID_Token_Type type; /* type of token */ - - } CID_Token_Rec; - - - LOCAL_DEF - void CID_ToToken( CID_Parser* parser, - CID_Token_Rec* token ); - - - /* enumeration type used to identify object fields */ - typedef enum CID_Field_Type_ - { - t1_field_none = 0, - t1_field_bool, - t1_field_integer, - t1_field_fixed, - t1_field_string, - t1_field_integer_array, - t1_field_fixed_array, - t1_field_callback, - - /* do not remove */ - t1_field_max - - } CID_Field_Type; - - typedef enum CID_Field_Location_ - { - t1_field_cid_info, - t1_field_font_dict, - t1_field_font_info, - t1_field_private, - - /* do not remove */ - t1_field_location_max - - } CID_Field_Location; - - - typedef FT_Error (*CID_Field_Parser)( CID_Face face, - CID_Parser* parser ); - - /* structure type used to model object fields */ - typedef struct CID_Field_Rec_ - { - const char* ident; /* field identifier */ - CID_Field_Location location; - CID_Field_Type type; /* type of field */ - CID_Field_Parser reader; - FT_UInt offset; /* offset of field in object */ - FT_Byte size; /* size of field in bytes */ - FT_UInt array_max; /* maximal number of elements for */ - /* array */ - FT_UInt count_offset; /* offset of element count for */ - /* arrays */ - } CID_Field_Rec; - - -#define CID_NEW_SIMPLE_FIELD( _ident, _type, _fname ) \ - { \ - _ident, T1CODE, _type, \ - 0, \ - FT_FIELD_OFFSET( _fname ), \ - FT_FIELD_SIZE( _fname ), \ - 0, 0 \ - }, - -#define CID_NEW_CALLBACK_FIELD( _ident, _reader ) \ - { \ - _ident, T1CODE, t1_field_callback, \ - _reader, \ - 0, 0, \ - 0, 0 \ - }, - -#define CID_NEW_TABLE_FIELD( _ident, _type, _fname, _max ) \ - { \ - _ident, T1CODE, _type, \ - 0, \ - FT_FIELD_OFFSET( _fname ), \ - FT_FIELD_SIZE_DELTA( _fname ), \ - _max, \ - FT_FIELD_OFFSET( num_ ## _fname ) \ - }, - -#define CID_NEW_TABLE_FIELD2( _ident, _type, _fname, _max ) \ - { \ - _ident, T1CODE, _type, \ - 0, \ - FT_FIELD_OFFSET( _fname ), \ - FT_FIELD_SIZE_DELTA( _fname ), \ - _max, 0 \ - }, - - -#define CID_FIELD_BOOL( _ident, _fname ) \ - CID_NEW_SIMPLE_FIELD( _ident, t1_field_bool, _fname ) - -#define CID_FIELD_NUM( _ident, _fname ) \ - CID_NEW_SIMPLE_FIELD( _ident, t1_field_integer, _fname ) - -#define CID_FIELD_FIXED( _ident, _fname ) \ - CID_NEW_SIMPLE_FIELD( _ident, t1_field_fixed, _fname ) - -#define CID_FIELD_STRING( _ident, _fname ) \ - CID_NEW_SIMPLE_FIELD( _ident, t1_field_string, _fname ) - -#define CID_FIELD_NUM_TABLE( _ident, _fname, _fmax ) \ - CID_NEW_TABLE_FIELD( _ident, t1_field_integer_array, \ - _fname, _fmax ) - -#define CID_FIELD_FIXED_TABLE( _ident, _fname, _fmax ) \ - CID_NEW_TABLE_FIELD( _ident, t1_field_fixed_array, \ - _fname, _fmax ) - -#define CID_FIELD_NUM_TABLE2( _ident, _fname, _fmax ) \ - CID_NEW_TABLE_FIELD2( _ident, t1_field_integer_array, \ - _fname, _fmax ) - -#define CID_FIELD_FIXED_TABLE2( _ident, _fname, _fmax ) \ - CID_NEW_TABLE_FIELD2( _ident, t1_field_fixed_array, \ - _fname, _fmax ) - -#define CID_FIELD_CALLBACK( _ident, _name ) \ - CID_NEW_CALLBACK_FIELD( _ident, parse_ ## _name ) - - - LOCAL_DEF - FT_Error CID_Load_Field( CID_Parser* parser, - const CID_Field_Rec* field, - void* object ); - - LOCAL_DEF - FT_Error CID_Load_Field_Table( CID_Parser* parser, - const CID_Field_Rec* field, - void* object ); - #ifdef __cplusplus } diff --git a/src/cid/cidtokens.h b/src/cid/cidtokens.h index 465afaf5b..39cd5005a 100644 --- a/src/cid/cidtokens.h +++ b/src/cid/cidtokens.h @@ -21,19 +21,17 @@ #undef T1CODE #define T1CODE t1_field_cid_info - CID_FIELD_STRING ( "CIDFontName", cid_font_name ) - CID_FIELD_NUM ( "CIDFontVersion", cid_version ) - CID_FIELD_NUM ( "CIDFontType", cid_font_type ) - CID_FIELD_STRING ( "Registry", registry ) - CID_FIELD_STRING ( "Ordering", ordering ) - CID_FIELD_NUM ( "Supplement", supplement ) - CID_FIELD_CALLBACK( "FontBBox", font_bbox ) - CID_FIELD_NUM ( "UIDBase", uid_base ) - CID_FIELD_CALLBACK( "FDArray", fd_array ) - CID_FIELD_NUM ( "CIDMapOffset", cidmap_offset ) - CID_FIELD_NUM ( "FDBytes", fd_bytes ) - CID_FIELD_NUM ( "GDBytes", gd_bytes ) - CID_FIELD_NUM ( "CIDCount", cid_count ) + T1_FIELD_STRING ( "CIDFontName", cid_font_name ) + T1_FIELD_NUM ( "CIDFontVersion", cid_version ) + T1_FIELD_NUM ( "CIDFontType", cid_font_type ) + T1_FIELD_STRING ( "Registry", registry ) + T1_FIELD_STRING ( "Ordering", ordering ) + T1_FIELD_NUM ( "Supplement", supplement ) + T1_FIELD_NUM ( "UIDBase", uid_base ) + T1_FIELD_NUM ( "CIDMapOffset", cidmap_offset ) + T1_FIELD_NUM ( "FDBytes", fd_bytes ) + T1_FIELD_NUM ( "GDBytes", gd_bytes ) + T1_FIELD_NUM ( "CIDCount", cid_count ) #undef FT_STRUCTURE @@ -41,15 +39,15 @@ #undef T1CODE #define T1CODE t1_field_font_info - CID_FIELD_STRING( "version", version ) - CID_FIELD_STRING( "Notice", notice ) - CID_FIELD_STRING( "FullName", full_name ) - CID_FIELD_STRING( "FamilyName", family_name ) - CID_FIELD_STRING( "Weight", weight ) - CID_FIELD_FIXED ( "ItalicAngle", italic_angle ) - CID_FIELD_BOOL ( "isFixedPitch", is_fixed_pitch ) - CID_FIELD_NUM ( "UnderlinePosition", underline_position ) - CID_FIELD_NUM ( "UnderlineThickness", underline_thickness ) + T1_FIELD_STRING( "version", version ) + T1_FIELD_STRING( "Notice", notice ) + T1_FIELD_STRING( "FullName", full_name ) + T1_FIELD_STRING( "FamilyName", family_name ) + T1_FIELD_STRING( "Weight", weight ) + T1_FIELD_FIXED ( "ItalicAngle", italic_angle ) + T1_FIELD_BOOL ( "isFixedPitch", is_fixed_pitch ) + T1_FIELD_NUM ( "UnderlinePosition", underline_position ) + T1_FIELD_NUM ( "UnderlineThickness", underline_thickness ) #undef FT_STRUCTURE @@ -57,16 +55,15 @@ #undef T1CODE #define T1CODE t1_field_font_dict - CID_FIELD_CALLBACK( "FontMatrix", font_matrix ) - CID_FIELD_NUM ( "PaintType", paint_type ) - CID_FIELD_NUM ( "FontType", font_type ) - CID_FIELD_NUM ( "SubrMapOffset", subrmap_offset ) - CID_FIELD_NUM ( "SDBytes", sd_bytes ) - CID_FIELD_NUM ( "SubrCount", num_subrs ) - CID_FIELD_NUM ( "lenBuildCharArray", len_buildchar ) - CID_FIELD_FIXED ( "ForceBoldThreshold", forcebold_threshold ) - CID_FIELD_FIXED ( "ExpansionFactor", expansion_factor ) - CID_FIELD_NUM ( "StrokeWidth", stroke_width ) + T1_FIELD_NUM ( "PaintType", paint_type ) + T1_FIELD_NUM ( "FontType", font_type ) + T1_FIELD_NUM ( "SubrMapOffset", subrmap_offset ) + T1_FIELD_NUM ( "SDBytes", sd_bytes ) + T1_FIELD_NUM ( "SubrCount", num_subrs ) + T1_FIELD_NUM ( "lenBuildCharArray", len_buildchar ) + T1_FIELD_FIXED ( "ForceBoldThreshold", forcebold_threshold ) + T1_FIELD_FIXED ( "ExpansionFactor", expansion_factor ) + T1_FIELD_NUM ( "StrokeWidth", stroke_width ) #undef FT_STRUCTURE @@ -74,26 +71,27 @@ #undef T1CODE #define T1CODE t1_field_private - CID_FIELD_NUM ( "UniqueID", unique_id ) - CID_FIELD_NUM ( "lenIV", lenIV ) - CID_FIELD_NUM ( "LanguageGroup", language_group ) - CID_FIELD_NUM ( "password", password ) + T1_FIELD_NUM ( "UniqueID", unique_id ) + T1_FIELD_NUM ( "lenIV", lenIV ) + T1_FIELD_NUM ( "LanguageGroup", language_group ) + T1_FIELD_NUM ( "password", password ) - CID_FIELD_FIXED ( "BlueScale", blue_scale ) - CID_FIELD_NUM ( "BlueShift", blue_shift ) - CID_FIELD_NUM ( "BlueFuzz", blue_fuzz ) + T1_FIELD_FIXED ( "BlueScale", blue_scale ) + T1_FIELD_NUM ( "BlueShift", blue_shift ) + T1_FIELD_NUM ( "BlueFuzz", blue_fuzz ) - CID_FIELD_NUM_TABLE ( "BlueValues", blue_values, 14 ) - CID_FIELD_NUM_TABLE ( "OtherBlues", other_blues, 10 ) - CID_FIELD_NUM_TABLE ( "FamilyBlues", family_blues, 14 ) - CID_FIELD_NUM_TABLE ( "FamilyOtherBlues", family_other_blues, 10 ) + T1_FIELD_NUM_TABLE ( "BlueValues", blue_values, 14 ) + T1_FIELD_NUM_TABLE ( "OtherBlues", other_blues, 10 ) + T1_FIELD_NUM_TABLE ( "FamilyBlues", family_blues, 14 ) + T1_FIELD_NUM_TABLE ( "FamilyOtherBlues", family_other_blues, 10 ) - CID_FIELD_NUM_TABLE2( "StdHW", standard_width, 1 ) - CID_FIELD_NUM_TABLE2( "StdVW", standard_height, 1 ) - CID_FIELD_NUM_TABLE2( "MinFeature", min_feature, 2 ) + T1_FIELD_NUM_TABLE2( "StdHW", standard_width, 1 ) + T1_FIELD_NUM_TABLE2( "StdVW", standard_height, 1 ) + T1_FIELD_NUM_TABLE2( "MinFeature", min_feature, 2 ) + + T1_FIELD_NUM_TABLE ( "StemSnapH", snap_widths, 12 ) + T1_FIELD_NUM_TABLE ( "StemSnapV", snap_heights, 12 ) - CID_FIELD_NUM_TABLE ( "StemSnapH", snap_widths, 12 ) - CID_FIELD_NUM_TABLE ( "StemSnapV", snap_heights, 12 ) /* END */ diff --git a/src/psaux/psobjs.c b/src/psaux/psobjs.c index 1c47af067..6e73db5c9 100644 --- a/src/psaux/psobjs.c +++ b/src/psaux/psobjs.c @@ -874,8 +874,12 @@ } } +#if 0 /* obsolete - keep for reference */ if ( pflags ) *pflags |= 1L << field->flag_bit; +#else + FT_UNUSED(pflags); +#endif error = FT_Err_Ok; @@ -906,6 +910,11 @@ FT_Byte* old_limit; T1_Field fieldrec = *(T1_Field*)field; +#if 1 + fieldrec.type = t1_field_integer; + if ( field->type == t1_field_fixed_array ) + fieldrec.type = t1_field_fixed; +#endif T1_ToTokenArray( parser, elements, 32, &num_elements ); if ( num_elements < 0 ) @@ -930,8 +939,12 @@ fieldrec.offset += fieldrec.size; } +#if 0 /* obsolete -- keep for reference */ if ( pflags ) *pflags |= 1L << field->flag_bit; +#else + FT_UNUSED(pflags); +#endif parser->cursor = old_cursor; parser->limit = old_limit; diff --git a/src/psaux/t1decode.c b/src/psaux/t1decode.c index 0aa7cc649..e364ba47e 100644 --- a/src/psaux/t1decode.c +++ b/src/psaux/t1decode.c @@ -185,6 +185,15 @@ /* seac weirdness */ adx += decoder->builder.left_bearing.x; + /* glyph_names is set to 0 for CID fonts which do not */ + /* include an encoding.. How can we deal with these ?? */ + if (decoder->glyph_names == 0) + { + FT_ERROR(( "t1operator_seac:" )); + FT_ERROR(( " glyph names table not available in this font !!\n" )); + return T1_Err_Syntax_Error; + } + bchar_index = t1_lookup_glyph_by_stdcharcode( decoder, bchar ); achar_index = t1_lookup_glyph_by_stdcharcode( decoder, achar ); diff --git a/src/type1z/z1gload.c b/src/type1z/z1gload.c index 59072bac6..15ca3b900 100644 --- a/src/type1z/z1gload.c +++ b/src/type1z/z1gload.c @@ -67,9 +67,11 @@ FT_Error Z1_Parse_Glyph( T1_Decoder* decoder, FT_UInt glyph_index ) { - T1_Face face = (T1_Face)decoder->builder.face; - T1_Font* type1 = &face->type1; - + T1_Face face = (T1_Face)decoder->builder.face; + T1_Font* type1 = &face->type1; + + decoder->font_matrix = type1->font_matrix; + decoder->font_offset = type1->font_offset; return decoder->funcs.parse_charstrings( decoder, @@ -99,7 +101,9 @@ (FT_Byte**)type1->glyph_names, face->blend, Z1_Parse_Glyph ); - + if (error) + return error; + decoder.builder.metrics_only = 1; decoder.builder.load_points = 0; @@ -117,7 +121,7 @@ } *max_advance = decoder.builder.advance.x; - return T1_Err_Ok; + return FT_Err_Ok; } @@ -152,6 +156,8 @@ PSAux_Interface* psaux = (PSAux_Interface*)face->psaux; const T1_Decoder_Funcs* decoder_funcs = psaux->t1_decoder_funcs; + FT_Matrix font_matrix; + FT_Vector font_offset; if ( load_flags & FT_LOAD_NO_RECURSE ) load_flags |= FT_LOAD_NO_SCALE | FT_LOAD_NO_HINTING; @@ -189,6 +195,9 @@ if ( error ) goto Exit; + font_matrix = decoder.font_matrix; + font_offset = decoder.font_offset; + /* save new glyph tables */ decoder_funcs->done( &decoder ); @@ -227,12 +236,11 @@ glyph->root.outline.flags |= ft_outline_high_precision; /* apply the font matrix */ - FT_Outline_Transform( &glyph->root.outline, - &face->type1.font_matrix ); + FT_Outline_Transform( &glyph->root.outline, &font_matrix ); FT_Outline_Translate( &glyph->root.outline, - face->type1.font_offset.x, - face->type1.font_offset.y ); + font_offset.x, + font_offset.y ); #if 0 diff --git a/src/type1z/z1load.c b/src/type1z/z1load.c index 98f76cf38..71c1537b9 100644 --- a/src/type1z/z1load.c +++ b/src/type1z/z1load.c @@ -697,168 +697,11 @@ /* */ /*************************************************************************/ -#define Z1_NEW_STRING( _name, _field ) \ - static \ - const T1_Field z1_field_ ## _field = \ - T1_FIELD_STRING( _field ); - -#define Z1_NEW_BOOL( _name, _field ) \ - static \ - const T1_Field z1_field_ ## _field = \ - T1_FIELD_BOOL( _field ); - -#define Z1_NEW_NUM( _name, _field ) \ - static \ - const T1_Field z1_field_ ## _field = \ - T1_FIELD_NUM( _field ); - -#define Z1_NEW_FIXED( _name, _field ) \ - static \ - const T1_Field z1_field_ ## _field = \ - T1_FIELD_FIXED( _field, _power ); - -#define Z1_NEW_NUM_TABLE( _name, _field, _max, _count ) \ - static \ - const T1_Field z1_field_ ## _field = \ - T1_FIELD_NUM_ARRAY( _field, _count, _max ); - -#define Z1_NEW_FIXED_TABLE( _name, _field, _max, _count ) \ - static \ - const T1_Field z1_field_ ## _field = \ - T1_FIELD_FIXED_ARRAY( _field, _count, _max ); - -#define Z1_NEW_NUM_TABLE2( _name, _field, _max ) \ - static \ - const T1_Field z1_field_ ## _field = \ - T1_FIELD_NUM_ARRAY2( _field, _max ); - -#define Z1_NEW_FIXED_TABLE2( _name, _field, _max ) \ - static \ - const T1_Field z1_field_ ## _field = \ - T1_FIELD_FIXED_ARRAY2( _field, _max ); - - -#define Z1_FONTINFO_STRING( n, f ) Z1_NEW_STRING( n, f ) -#define Z1_FONTINFO_NUM( n, f ) Z1_NEW_NUM( n, f ) -#define Z1_FONTINFO_BOOL( n, f ) Z1_NEW_BOOL( n, f ) -#define Z1_PRIVATE_NUM( n, f ) Z1_NEW_NUM( n, f ) -#define Z1_PRIVATE_FIXED( n, f ) Z1_NEW_FIXED( n, f ) -#define Z1_PRIVATE_NUM_TABLE( n, f, m, c ) Z1_NEW_NUM_TABLE( n, f, m, c ) -#define Z1_PRIVATE_NUM_TABLE2( n, f, m ) Z1_NEW_NUM_TABLE2( n, f, m ) -#define Z1_TOPDICT_NUM( n, f ) Z1_NEW_NUM( n, f ) -#define Z1_TOPDICT_NUM_FIXED2( n, f, m ) Z1_NEW_FIXED_TABLE2( n, f, m ) - - - /* including this file defines all field variables */ -#ifdef FT_FLAT_COMPILE - -#include "z1tokens.h" - -#else - -#include - -#endif - - - /*************************************************************************/ - /* */ - /* Second, define the keyword variables. This is a set of Z1_KeyWord */ - /* structures used to model the way each keyword is `loaded'. */ - /* */ - /*************************************************************************/ - - typedef void (*Z1_Parse_Func)( T1_Face face, - Z1_Loader* loader ); - - - typedef enum Z1_KeyWord_Type_ - { - t1_keyword_callback = 0, - t1_keyword_field, - t1_keyword_field_table - - } Z1_KeyWord_Type; - - - typedef enum Z1_KeyWord_Location_ - { - t1_keyword_type1 = 0, - t1_keyword_font_info, - t1_keyword_private - - } Z1_KeyWord_Location; - - - typedef struct Z1_KeyWord_ - { - const char* name; - Z1_KeyWord_Type type; - Z1_KeyWord_Location location; - Z1_Parse_Func parsing; - const T1_Field* field; - - } Z1_KeyWord; - - -#define Z1_KEYWORD_CALLBACK( name, callback ) \ - { \ - name, t1_keyword_callback, t1_keyword_type1, callback, 0 \ - } - -#define Z1_KEYWORD_TYPE1( name, f ) \ - { \ - name, t1_keyword_field, t1_keyword_type1, 0, &z1_field_ ## f \ - } - -#define Z1_KEYWORD_FONTINFO( name, f ) \ - { \ - name, t1_keyword_field, t1_keyword_font_info, 0, &z1_field_ ## f \ - } - -#define Z1_KEYWORD_PRIVATE( name, f ) \ - { \ - name, t1_keyword_field, t1_keyword_private, 0, &z1_field_ ## f \ - } - -#define Z1_KEYWORD_FONTINFO_TABLE( name, f ) \ - { \ - name, t1_keyword_field_table, t1_keyword_font_info, 0, \ - &z1_field_ ## f \ - } - -#define Z1_KEYWORD_PRIVATE_TABLE( name, f ) \ - { \ - name, t1_keyword_field_table, t1_keyword_private, 0, \ - &z1_field_ ## f \ - } - - -#undef Z1_FONTINFO_STRING -#undef Z1_FONTINFO_NUM -#undef Z1_FONTINFO_BOOL -#undef Z1_PRIVATE_NUM -#undef Z1_PRIVATE_FIXED -#undef Z1_PRIVATE_NUM_TABLE -#undef Z1_PRIVATE_NUM_TABLE2 -#undef Z1_TOPDICT_NUM -#undef Z1_TOPDICT_NUM_FIXED2 - -#define Z1_FONTINFO_STRING( n, f ) Z1_KEYWORD_FONTINFO( n, f ), -#define Z1_FONTINFO_NUM( n, f ) Z1_KEYWORD_FONTINFO( n, f ), -#define Z1_FONTINFO_BOOL( n, f ) Z1_KEYWORD_FONTINFO( n, f ), -#define Z1_PRIVATE_NUM( n, f ) Z1_KEYWORD_PRIVATE( n, f ), -#define Z1_PRIVATE_FIXED( n, f ) Z1_KEYWORD_PRIVATE( n, f ), -#define Z1_PRIVATE_NUM_TABLE( n, f, m, c ) Z1_KEYWORD_PRIVATE_TABLE( n, f ), -#define Z1_PRIVATE_NUM_TABLE2( n, f, m ) Z1_KEYWORD_PRIVATE_TABLE( n, f ), -#define Z1_TOPDICT_NUM( n, f ) Z1_KEYWORD_TYPE1( n, f ), -#define Z1_TOPDICT_NUM_FIXED2( n, f, m ) Z1_KEYWORD_TYPE1( n, f ), - static - FT_Error t1_load_keyword( T1_Face face, - Z1_Loader* loader, - Z1_KeyWord* keyword ) + FT_Error t1_load_keyword( T1_Face face, + Z1_Loader* loader, + T1_Field* field ) { FT_Error error; void* dummy_object; @@ -868,18 +711,18 @@ /* if the keyword has a dedicated callback, call it */ - if ( keyword->type == t1_keyword_callback ) + if ( field->type == t1_field_callback ) { - keyword->parsing( face, loader ); + field->reader( (FT_Face)face, loader ); error = loader->parser.root.error; goto Exit; } /* now, the keyword is either a simple field, or a table of fields; */ /* we are now going to take care of it */ - switch ( keyword->location ) + switch ( field->location ) { - case t1_keyword_font_info: + case t1_field_font_info: dummy_object = &face->type1.font_info; objects = &dummy_object; max_objects = 0; @@ -891,7 +734,7 @@ } break; - case t1_keyword_private: + case t1_field_private: dummy_object = &face->type1.private_dict; objects = &dummy_object; max_objects = 0; @@ -909,11 +752,12 @@ max_objects = 0; } - if ( keyword->type == t1_keyword_field_table ) - error = Z1_Load_Field_Table( &loader->parser, keyword->field, + if ( field->type == t1_field_integer_array || + field->type == t1_field_fixed_array ) + error = Z1_Load_Field_Table( &loader->parser, field, objects, max_objects, 0 ); else - error = Z1_Load_Field( &loader->parser, keyword->field, + error = Z1_Load_Field( &loader->parser, field, objects, max_objects, 0 ); Exit: @@ -1426,7 +1270,7 @@ static - const Z1_KeyWord t1_keywords[] = + const T1_Field t1_keywords[] = { #ifdef FT_FLAT_COMPILE @@ -1440,22 +1284,22 @@ #endif /* now add the special functions... */ - Z1_KEYWORD_CALLBACK( "FontName", parse_font_name ), - Z1_KEYWORD_CALLBACK( "FontBBox", parse_font_bbox ), - Z1_KEYWORD_CALLBACK( "FontMatrix", parse_font_matrix ), - Z1_KEYWORD_CALLBACK( "Encoding", parse_encoding ), - Z1_KEYWORD_CALLBACK( "Subrs", parse_subrs ), - Z1_KEYWORD_CALLBACK( "CharStrings", parse_charstrings ), + T1_FIELD_CALLBACK( "FontName", parse_font_name ) + T1_FIELD_CALLBACK( "FontBBox", parse_font_bbox ) + T1_FIELD_CALLBACK( "FontMatrix", parse_font_matrix ) + T1_FIELD_CALLBACK( "Encoding", parse_encoding ) + T1_FIELD_CALLBACK( "Subrs", parse_subrs ) + T1_FIELD_CALLBACK( "CharStrings", parse_charstrings ) #ifndef Z1_CONFIG_OPTION_NO_MM_SUPPORT - Z1_KEYWORD_CALLBACK( "BlendDesignPositions", parse_blend_design_positions ), - Z1_KEYWORD_CALLBACK( "BlendDesignMap", parse_blend_design_map ), - Z1_KEYWORD_CALLBACK( "BlendAxisTypes", parse_blend_axis_types ), - Z1_KEYWORD_CALLBACK( "WeightVector", parse_weight_vector ), - Z1_KEYWORD_CALLBACK( "shareddict", parse_shared_dict ), + T1_FIELD_CALLBACK( "BlendDesignPositions", parse_blend_design_positions ) + T1_FIELD_CALLBACK( "BlendDesignMap", parse_blend_design_map ) + T1_FIELD_CALLBACK( "BlendAxisTypes", parse_blend_axis_types ) + T1_FIELD_CALLBACK( "WeightVector", parse_weight_vector ) + T1_FIELD_CALLBACK( "shareddict", parse_shared_dict ) #endif - Z1_KEYWORD_CALLBACK( 0, 0 ) + { 0,0,0,0, 0,0,0,0 } }; @@ -1534,7 +1378,7 @@ else { /* now, compare the immediate name to the keyword table */ - Z1_KeyWord* keyword = (Z1_KeyWord*)t1_keywords; + T1_Field* keyword = (T1_Field*)t1_keywords; for (;;) @@ -1542,7 +1386,7 @@ FT_Byte* name; - name = (FT_Byte*)keyword->name; + name = (FT_Byte*)keyword->ident; if ( !name ) break; diff --git a/src/type1z/z1tokens.h b/src/type1z/z1tokens.h index 65ef0479d..04e25a512 100644 --- a/src/type1z/z1tokens.h +++ b/src/type1z/z1tokens.h @@ -18,50 +18,55 @@ #undef FT_STRUCTURE #define FT_STRUCTURE T1_FontInfo +#undef T1CODE +#define T1CODE t1_field_font_info - Z1_FONTINFO_STRING( "version", version ) - Z1_FONTINFO_STRING( "Notice", notice ) - Z1_FONTINFO_STRING( "FullName", full_name ) - Z1_FONTINFO_STRING( "FamilyName", family_name ) - Z1_FONTINFO_STRING( "Weight", weight ) + T1_FIELD_STRING( "version", version ) + T1_FIELD_STRING( "Notice", notice ) + T1_FIELD_STRING( "FullName", full_name ) + T1_FIELD_STRING( "FamilyName", family_name ) + T1_FIELD_STRING( "Weight", weight ) - Z1_FONTINFO_NUM ( "ItalicAngle", italic_angle ) - Z1_FONTINFO_BOOL ( "isFixedPitch", is_fixed_pitch ) - Z1_FONTINFO_NUM ( "UnderlinePosition", underline_position ) - Z1_FONTINFO_NUM ( "UnderlineThickness", underline_thickness ) + T1_FIELD_NUM ( "ItalicAngle", italic_angle ) + T1_FIELD_BOOL ( "isFixedPitch", is_fixed_pitch ) + T1_FIELD_NUM ( "UnderlinePosition", underline_position ) + T1_FIELD_NUM ( "UnderlineThickness", underline_thickness ) #undef FT_STRUCTURE #define FT_STRUCTURE T1_Private +#undef T1CODE +#define T1CODE t1_field_private - Z1_PRIVATE_NUM ( "UniqueID", unique_id ) - Z1_PRIVATE_NUM ( "lenIV", lenIV ) - Z1_PRIVATE_NUM ( "LanguageGroup", language_group ) - Z1_PRIVATE_NUM ( "password", password ) + T1_FIELD_NUM ( "UniqueID", unique_id ) + T1_FIELD_NUM ( "lenIV", lenIV ) + T1_FIELD_NUM ( "LanguageGroup", language_group ) + T1_FIELD_NUM ( "password", password ) - Z1_PRIVATE_FIXED ( "BlueScale", blue_scale ) - Z1_PRIVATE_NUM ( "BlueShift", blue_shift ) - Z1_PRIVATE_NUM ( "BlueFuzz", blue_fuzz ) + T1_FIELD_FIXED ( "BlueScale", blue_scale ) + T1_FIELD_NUM ( "BlueShift", blue_shift ) + T1_FIELD_NUM ( "BlueFuzz", blue_fuzz ) - Z1_PRIVATE_NUM_TABLE ( "BlueValues", blue_values, 14, num_blue_values ) - Z1_PRIVATE_NUM_TABLE ( "OtherBlues", other_blues, 10, num_other_blues ) - Z1_PRIVATE_NUM_TABLE ( "FamilyBlues", family_blues, 14, num_family_blues ) - Z1_PRIVATE_NUM_TABLE ( "FamilyOtherBlues", family_other_blues, 10, \ - num_family_other_blues ) + T1_FIELD_NUM_TABLE ( "BlueValues", blue_values, 14 ) + T1_FIELD_NUM_TABLE ( "OtherBlues", other_blues, 10 ) + T1_FIELD_NUM_TABLE ( "FamilyBlues", family_blues, 14 ) + T1_FIELD_NUM_TABLE ( "FamilyOtherBlues", family_other_blues, 10 ) - Z1_PRIVATE_NUM_TABLE2( "StdHW", standard_width, 1 ) - Z1_PRIVATE_NUM_TABLE2( "StdVW", standard_height, 1 ) - Z1_PRIVATE_NUM_TABLE2( "MinFeature", min_feature, 2 ) + T1_FIELD_NUM_TABLE2( "StdHW", standard_width, 1 ) + T1_FIELD_NUM_TABLE2( "StdVW", standard_height, 1 ) + T1_FIELD_NUM_TABLE2( "MinFeature", min_feature, 2 ) - Z1_PRIVATE_NUM_TABLE ( "StemSnapH", snap_widths, 12, num_snap_widths ) - Z1_PRIVATE_NUM_TABLE ( "StemSnapV", snap_heights, 12, num_snap_heights ) + T1_FIELD_NUM_TABLE ( "StemSnapH", snap_widths, 12 ) + T1_FIELD_NUM_TABLE ( "StemSnapV", snap_heights, 12 ) #undef FT_STRUCTURE #define FT_STRUCTURE T1_Font +#undef T1CODE +#define T1CODE t1_field_font_dict - Z1_TOPDICT_NUM( "PaintType", paint_type ) - Z1_TOPDICT_NUM( "FontType", font_type ) - Z1_TOPDICT_NUM( "StrokeWidth", stroke_width ) + T1_FIELD_NUM( "PaintType", paint_type ) + T1_FIELD_NUM( "FontType", font_type ) + T1_FIELD_NUM( "StrokeWidth", stroke_width ) /* END */