diff --git a/include/freetype/internal/psaux.h b/include/freetype/internal/psaux.h new file mode 100644 index 000000000..d840992d5 --- /dev/null +++ b/include/freetype/internal/psaux.h @@ -0,0 +1,459 @@ +#ifndef PSAUX_H +#define PSAUX_H + +#include + + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** T1_TABLE *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + + + /*************************************************************************/ + /* */ + /* */ + /* T1_Table */ + /* */ + /* */ + /* A T1_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 */ + /* reallocation. */ + /* */ + /* cursor :: The current top of the grow heap within its block. */ + /* */ + /* capacity :: The current size of the heap block. Increments by */ + /* 1kByte chunks. */ + /* */ + /* max_elems :: The maximum number of elements in table. */ + /* */ + /* num_elems :: The current number of elements in table. */ + /* */ + /* elements :: A table of element addresses within the block. */ + /* */ + /* lengths :: A table of element sizes within the block. */ + /* */ + /* memory :: The object used for memory operations */ + /* (alloc/realloc). */ + /* */ + typedef struct T1_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; + + } T1_Table; + + + + /*************************************************************************/ + /* */ + /* */ + /* T1_Table_Funcs */ + /* */ + /* */ + /* A set of function pointers used to manage T1_Table objects.. */ + /* */ + /* */ + /* table_init :: used to initialise a a table */ + /* table_done :: finalize/destroy a given table */ + /* table_add :: add one new object to a table */ + /* table_release :: release table data, then finalize it */ + /* */ + typedef struct T1_Table_Funcs_ + { + FT_Error (*init) ( T1_Table* table, + FT_Int count, + FT_Memory memory ); + + void (*done) ( T1_Table* table ); + + FT_Error (*add) ( T1_Table* table, + FT_Int index, + void* object, + FT_Int length ); + + void (*release)( T1_Table* table ); + + } T1_Table_Funcs; + + + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** T1 FIELDS & TOKENS *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + + /* simple enumeration type used to identify token types */ + typedef enum T1_Token_Type_ + { + t1_token_none = 0, + t1_token_any, + t1_token_string, + t1_token_array, + + /* do not remove */ + t1_token_max + + } T1_Token_Type; + + + /* a simple structure used to identify tokens */ + typedef struct T1_Token_ + { + FT_Byte* start; /* first character of token in input stream */ + FT_Byte* limit; /* first character after the token */ + T1_Token_Type type; /* type of token.. */ + + } T1_Token; + + + /* enumeration type used to identify object fields */ + typedef enum T1_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, + + /* do not remove */ + t1_field_max + + } T1_Field_Type; + + + /* 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 */ + + } 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 ) \ + { \ + t1_field_integer, \ + FT_FIELD_OFFSET( _fname ), \ + FT_FIELD_SIZE_DELTA( _fname ), \ + _fmax, \ + FT_FIELD_OFFSET( _fcount ), \ + 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_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 \ + } + + + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** T1 PARSER *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + + /*************************************************************************/ + /* */ + /* */ + /* T1_Parser */ + /* */ + /* */ + /* A T1_Parser is an object used to parse a Type 1 font very */ + /* quickly. */ + /* */ + /* */ + /* cursor :: current position in text. */ + /* base :: start of processed text. */ + /* limit :: end of processed text. */ + /* error :: last error returned. */ + /* */ + + typedef struct T1_Parser_ + { + FT_Byte* cursor; + FT_Byte* base; + FT_Byte* limit; + FT_Error error; + FT_Memory memory; + + } T1_Parser; + + + typedef struct T1_Parser_Funcs_ + { + void (*init) ( T1_Parser* parser, + FT_Byte* base, + FT_Byte* limit, + FT_Memory memory ); + + void (*done) ( T1_Parser* parser ); + + void (*skip_spaces) ( T1_Parser* parser ); + void (*skip_alpha) ( T1_Parser* parser ); + + FT_Long (*to_int) ( T1_Parser* parser ); + FT_Fixed (*to_fixed) ( T1_Parser* parser, + FT_Int power_ten ); + FT_Int (*to_coord_array)( T1_Parser* parser, + FT_Int max_coords, + FT_Short* coords ); + FT_Int (*to_fixed_array)( T1_Parser* parser, + FT_Int max_values, + FT_Fixed* values, + FT_Int power_ten ); + + void (*to_token) ( T1_Parser* parser, + T1_Token *token ); + void (*to_token_array)( T1_Parser* parser, + T1_Token* tokens, + FT_UInt max_tokens, + FT_Int *pnum_tokens ); + + FT_Error (*load_field) ( T1_Parser* parser, + const T1_Field* field, + void** objects, + FT_UInt max_objects, + FT_ULong* pflags ); + + FT_Error (*load_field_table)( T1_Parser* parser, + const T1_Field* field, + void** objects, + FT_UInt max_objects, + FT_ULong* pflags ); + + } T1_Parser_Funcs; + + + + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** T1 BUILDER *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + + + /*************************************************************************/ + /* */ + /* */ + /* T1_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 T2_Builder_ + { + FT_Memory memory; + FT_Face face; + FT_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; + + } T1_Builder; + + + typedef FT_Error (*T1_Builder_Check_Points_Func)( T1_Builder* builder, + FT_Int count ); + + typedef void (*T1_Builder_Add_Point_Func) ( T1_Builder* builder, + FT_Pos x, + FT_Pos y, + FT_Byte flag ); + + typedef void (*T1_Builder_Add_Point1_Func)( T1_Builder* builder, + FT_Pos x, + FT_Pos y ); + + typedef FT_Error (*T1_Builder_Add_Contour_Func)( T1_Builder* builder ); + + typedef FT_Error (*T1_Builder_Start_Point_Func)( T1_Builder* builder, + FT_Pos x, + FT_Pos y ); + + typedef void (*T1_Builder_Close_Contour_Func)( T1_Builder* builder ); + + + typedef struct T1_Builder_Funcs_ + { + FT_Error (*init)( T1_Builder* builder, + FT_Face face, + FT_Size size, + FT_GlyphSlot slot ); + + void (*done)( T1_Builder* builder ); + + T1_Builder_Check_Points_Func check_points; + T1_Builder_Add_Points_Func add_point; + T1_Builder_Add_Point1_Func add_point1; + T1_Builder_Add_Contour_Func add_contour; + T1_Builder_Start_Point_Func start_point; + T1_Builder_Close_Contour_Func close_contour; + + } T1_Builder_Funcs; + + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** PSAux Module Interface *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + + + + typedef struct PSAux_Interface_ + { + const T1_Table_Funcs* t1_table_funcs; + const T1_Parser_Funcs* t1_parser_funcs; + const T1_Builder_Funcs* t1_builder_funcs; + + } PSAux_Interface; + + +#endif /* PSAUX_H */ diff --git a/include/freetype/internal/t1types.h b/include/freetype/internal/t1types.h index 0fa385556..c5afb7c21 100644 --- a/include/freetype/internal/t1types.h +++ b/include/freetype/internal/t1types.h @@ -116,6 +116,7 @@ FT_Byte paint_type; FT_Byte font_type; FT_Matrix font_matrix; + FT_Vector font_offset; FT_BBox font_bbox; FT_Long font_id; diff --git a/src/base/ftobjs.c b/src/base/ftobjs.c index ab2fe89f7..acc7fc76e 100644 --- a/src/base/ftobjs.c +++ b/src/base/ftobjs.c @@ -1020,7 +1020,7 @@ } /* now, transform the glyph image when needed */ - if ( face->transform_flags ) + if ( face->transform_flags && !(load_flags & FT_LOAD_NO_RECURSE)) { /* get renderer */ FT_Renderer renderer = ft_lookup_glyph_renderer( slot ); diff --git a/src/otlayout/oltypes.h b/src/otlayout/oltypes.h index b4a4d802e..68d025709 100644 --- a/src/otlayout/oltypes.h +++ b/src/otlayout/oltypes.h @@ -1,8 +1,7 @@ #ifndef OLTYPES_H #define OLTYPES_H -#include -#include +#include /************************************************************* * @@ -48,34 +47,34 @@ { FT_Memory memory; - TT_Int num_scripts; - TT_Tag* script_tags; + FT_Int num_scripts; + FT_Tag* script_tags; - TT_Int max_languages; - TT_Int num_languages; - TT_Tag* language_tags; + FT_Int max_languages; + FT_Int num_languages; + FT_Tag* language_tags; - TT_Int max_features; - TT_Tag* feature_tags; - TT_Bool* features; + FT_Int max_features; + FT_Tag* feature_tags; + FT_Bool* features; - TT_Int max_lookups; - TT_Bool* lookups; + FT_Int max_lookups; + FT_Bool* lookups; - TT_Byte* scripts_table; - TT_Long scripts_len; + FT_Byte* scripts_table; + FT_Long scripts_len; - TT_Byte* features_table; - TT_Long* features_len; + FT_Byte* features_table; + FT_Long* features_len; - TT_Byte* lookups_table; - TT_Byte* lookups_len; + FT_Byte* lookups_table; + FT_Byte* lookups_len; - TT_Byte* cur_script; /* current script */ - TT_Byte* cur_language; /* current language */ + FT_Byte* cur_script; /* current script */ + FT_Byte* cur_language; /* current language */ - TT_Byte* cur_base_values; - TT_Byte* cur_min_max; + FT_Byte* cur_base_values; + FT_Byte* cur_min_max; OTL_Type otl_type; @@ -84,58 +83,43 @@ typedef struct OTL_BaseCoord_ { - TT_UShort format; - TT_Short coordinate; - TT_UShort ref_glyph; - TT_UShort ref_point; - TT_Byte* device; + FT_UShort format; + FT_Short coordinate; + FT_UShort ref_glyph; + FT_UShort ref_point; + FT_Byte* device; } OTL_BaseCoord; typedef struct OTL_ValueRecord_ { - TT_Vector placement; - TT_Vector advance; + FT_Vector placement; + FT_Vector advance; - TT_Byte* device_pla_x; - TT_Byte* device_pla_y; - TT_Byte* device_adv_x; - TT_Byte* device_adv_y; + FT_Byte* device_pla_x; + FT_Byte* device_pla_y; + FT_Byte* device_adv_x; + FT_Byte* device_adv_y; } OTL_ValueRecord; typedef struct OTL_Anchor_ { - TT_UInt format; - TT_Vector coord; - TT_UInt anchor_point; - TT_Byte* device_x; - TT_Byte* device_y; + FT_UInt format; + FT_Vector coord; + FT_UInt anchor_point; + FT_Byte* device_x; + FT_Byte* device_y; } OTL_Anchor; + LOCAL_DEF - TT_Error OTL_Table_Init( OTL_Table* table, + FT_Error OTL_Table_Init( OTL_Table* table, FT_Memory memory ); - LOCAL_DEF - TT_Error OTL_Table_Set_Scripts( OTL_Table* table, - TT_Byte* bytes, - TT_Long len, - OTL_Type otl_type ); - - LOCAL_DEF - TT_Error OTL_Table_Set_Features( OTL_Table* table, - TT_Byte* bytes, - TT_Long len ); - - LOCAL_DEF - TT_Error OTL_Table_Set_Lookups( OTL_Table* table, - TT_Byte* bytes, - TT_Long len ); - LOCAL_DEF void OTL_Table_Done( OTL_Table* table ); @@ -153,6 +137,12 @@ * table->num_scripts is the number of scripts * */ + LOCAL_DEF + FT_Error OTL_Table_Set_Scripts( OTL_Table* table, + FT_Byte* bytes, + FT_Long len, + OTL_Type otl_type ); + /******************************************************** * @@ -169,6 +159,18 @@ * it is empty (zero-filled) by default. * */ + LOCAL_DEF + FT_Error OTL_Table_Set_Features( OTL_Table* table, + FT_Byte* bytes, + FT_Long len ); + + + + LOCAL_DEF + FT_Error OTL_Table_Set_Lookups( OTL_Table* table, + FT_Byte* bytes, + FT_Long len ); + /******************************************************************* * @@ -187,7 +189,7 @@ */ LOCAL_DEF void OTL_Get_Languages_List( OTL_Table* table, - TT_ULong script_tag ); + FT_ULong script_tag ); /******************************************************************* @@ -208,15 +210,15 @@ */ LOCAL_DEF void OTL_Get_Features_List( OTL_Table* table, - TT_ULong language_tag ); + FT_ULong language_tag ); LOCAL_DEF void OTL_Get_Baseline_Values( OTL_Table* table, - TT_ULong language_tag ); + FT_ULong language_tag ); LOCAL_DEF void OTL_Get_Justification( OTL_Table* table, - TT_ULong language_tag ); + FT_ULong language_tag ); /******************************************************************* * @@ -259,52 +261,52 @@ LOCAL_DEF - TT_Long OTL_Get_Coverage_Index( TT_Byte* coverage, - TT_UInt glyph_id ); + FT_Long OTL_Get_Coverage_Index( FT_Byte* coverage, + FT_UInt glyph_id ); LOCAL_DEF - TT_UInt OTL_Get_Glyph_Class( TT_Byte* class_def, - TT_UInt glyph_id ); + FT_UInt OTL_Get_Glyph_Class( FT_Byte* class_def, + FT_UInt glyph_id ); LOCAL_DEF - TT_Int OTL_Get_Device_Adjustment( TT_Byte* device, - TT_UInt size ); + FT_Int OTL_Get_Device_Adjustment( FT_Byte* device, + FT_UInt size ); LOCAL_DEF - void OTL_Get_Base_Coordinate( TT_Byte* base_coord, + void OTL_Get_Base_Coordinate( FT_Byte* base_coord, OTL_BaseCoord* coord ); LOCAL_DEF - TT_Int OTL_ValueRecord_Size( TT_UShort value_format ); + FT_Int OTL_ValueRecord_Size( FT_UShort value_format ); LOCAL_DEF - void OTL_Get_ValueRecord( TT_Byte* value_record, - TT_UShort value_format, - TT_Byte* pos_table, + void OTL_Get_ValueRecord( FT_Byte* value_record, + FT_UShort value_format, + FT_Byte* pos_table, OTL_ValueRecord* record ); LOCAL_DEF - void OTL_Get_Anchor( TT_Byte* anchor_table, + void OTL_Get_Anchor( FT_Byte* anchor_table, OTL_Anchor* anchor ); LOCAL_DEF - void OTL_Get_Mark( TT_Byte* mark_array, - TT_UInt index, - TT_UShort* clazz, + void OTL_Get_Mark( FT_Byte* mark_array, + FT_UInt index, + FT_UShort* clazz, OTL_Anchor* anchor ); #define OTL_Byte(p) (p++, p[-1]) -#define OTL_UShort(p) (p+=2, ((TT_UShort)p[-2] << 8) | p[-1]) +#define OTL_UShort(p) (p+=2, ((FT_UShort)p[-2] << 8) | p[-1]) -#define OTL_ULong(p) (p+=4, ((TT_ULong)p[-4] << 24) | \ - ((TT_ULong)p[-3] << 16) | \ - ((TT_ULong)p[-2] << 8 ) | p[-1] ) +#define OTL_ULong(p) (p+=4, ((FT_ULong)p[-4] << 24) | \ + ((FT_ULong)p[-3] << 16) | \ + ((FT_ULong)p[-2] << 8 ) | p[-1] ) #endif /* OLTYPES_H */ diff --git a/src/psaux/psobjs.c b/src/psaux/psobjs.c new file mode 100644 index 000000000..af4ca1b63 --- /dev/null +++ b/src/psaux/psobjs.c @@ -0,0 +1,1244 @@ +#include +#include + + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** T1_TABLE *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + + /*************************************************************************/ + /* */ + /* */ + /* T1_New_Table */ + /* */ + /* */ + /* Initialises a T1_Table. */ + /* */ + /* */ + /* table :: The address of the target table. */ + /* */ + /* */ + /* count :: The table size = the maximum number of elements. */ + /* */ + /* memory :: The memory object to use for all subsequent */ + /* reallocations. */ + /* */ + /* */ + /* FreeType error code. 0 means success. */ + /* */ + LOCAL_FUNC + FT_Error T1_New_Table( T1_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 = 0xDEADBEEF; + 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( T1_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( T1_Table* table, + FT_Int new_size ) + { + FT_Memory memory = table->memory; + FT_Byte* old_base = table->block; + FT_Error error; + + + /* reallocate the base block */ + if ( REALLOC( table->block, table->capacity, new_size ) ) + return error; + + table->capacity = new_size; + + /* shift all offsets if necessary */ + if ( old_base ) + shift_elements( table, old_base ); + + return FT_Err_Ok; + } + + + /*************************************************************************/ + /* */ + /* */ + /* T1_Add_Table */ + /* */ + /* */ + /* Adds an object to a T1_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 memory. */ + /* */ + /* length :: The length in bytes of the source object. */ + /* */ + /* */ + /* FreeType error code. 0 means success. An error is returned if a */ + /* reallocation fails. */ + /* */ + LOCAL_DEF + FT_Error T1_Add_Table( T1_Table* table, + FT_Int index, + void* object, + FT_Int length ) + { + if ( index < 0 || index > table->max_elems ) + { + FT_ERROR(( "T1_Add_Table: invalid index\n" )); + return FT_Err_Invalid_Argument; + } + + /* 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 FT_Err_Ok; + } + + + + /*************************************************************************/ + /* */ + /* */ + /* T1_Done_Table */ + /* */ + /* */ + /* Finalizes a T1_Table (i.e., 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 T1_Done_Table( T1_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 T1_Release_Table( T1_Table* table ) + { + FT_Memory memory = table->memory; + + + if ( table->init == (FT_Long)0xDEADBEEF ) + { + FREE( table->block ); + FREE( table->elements ); + FREE( table->lengths ); + table->init = 0; + } + } + + + + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** T1 PARSER *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + +#define IS_T1_WHITESPACE( c ) ( (c) == ' ' || (c) == '\t' ) +#define IS_T1_LINESPACE( c ) ( (c) == '\r' || (c) == '\n' ) + +#define IS_T1_SPACE( c ) ( IS_T1_WHITESPACE( c ) || IS_T1_LINESPACE( c ) ) + + + LOCAL_FUNC + void T1_Skip_Spaces( T1_Parser* parser ) + { + FT_Byte* cur = parser->cursor; + FT_Byte* limit = parser->limit; + + + while ( cur < limit ) + { + FT_Byte c = *cur; + + + if ( !IS_T1_SPACE( c ) ) + break; + cur++; + } + parser->cursor = cur; + } + + + LOCAL_FUNC + void T1_Skip_Alpha( T1_Parser* parser ) + { + FT_Byte* cur = parser->cursor; + FT_Byte* limit = parser->limit; + + + while ( cur < limit ) + { + FT_Byte c = *cur; + + + if ( IS_T1_SPACE( c ) ) + break; + cur++; + } + parser->cursor = cur; + } + + + + LOCAL_FUNC + void T1_ToToken( T1_Parser* parser, + T1_Token* 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 */ + T1_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's any token **********/ + default: + token->start = cur++; + token->type = t1_token_any; + while ( cur < limit && !IS_T1_SPACE( *cur ) ) + cur++; + + token->limit = cur; + } + + if ( !token->limit ) + { + token->start = 0; + token->type = t1_token_none; + } + + parser->cursor = cur; + } + } + + + LOCAL_FUNC + void T1_ToTokenArray( T1_Parser* parser, + T1_Token* tokens, + FT_UInt max_tokens, + FT_Int* pnum_tokens ) + { + T1_Token master; + + + *pnum_tokens = -1; + + T1_ToToken( parser, &master ); + if ( master.type == t1_token_array ) + { + FT_Byte* old_cursor = parser->cursor; + FT_Byte* old_limit = parser->limit; + T1_Token* cur = tokens; + T1_Token* limit = cur + max_tokens; + + + parser->cursor = master.start; + parser->limit = master.limit; + + while ( parser->cursor < parser->limit ) + { + T1_Token token; + + + T1_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, check the sign */ + if ( *cur == '-' ) + { + sign = 1; + cur++; + } + + /* then, read the integer part, if any */ + if ( *cur != '.' ) + result = t1_toint( &cur, limit ) << 16; + else + result = 0; + + num = 0; + divider = 1; + + 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 + 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; + } + + +#if 0 + + static + FT_String* t1_tostring( FT_Byte** cursor, + FT_Byte* limit, + FT_Memory memory ) + { + FT_Byte* cur = *cursor; + FT_Int len = 0; + FT_Int count; + FT_String* result; + FT_Error error; + + + /* XXX: some stupid fonts have a `Notice' or `Copyright' string */ + /* that simply doesn't begin with an opening parenthesis, even */ + /* though they have a closing one! E.g. "amuncial.pfb" */ + /* */ + /* We must deal with these ill-fated cases there. Note that */ + /* these fonts didn't work with the old Type 1 driver as the */ + /* notice/copyright was not recognized as a valid string token */ + /* and made the old token parser commit errors. */ + + while ( cur < limit && ( *cur == ' ' || *cur == '\t' ) ) + cur++; + if ( cur + 1 >= limit ) + return 0; + + if ( *cur == '(' ) + cur++; /* skip the opening parenthesis, if there is one */ + + *cursor = cur; + count = 0; + + /* then, count its length */ + for ( ; cur < limit; cur++ ) + { + if ( *cur == '(' ) + count++; + + else if ( *cur == ')' ) + { + count--; + if ( count < 0 ) + break; + } + } + + len = cur - *cursor; + if ( cur >= limit || ALLOC( result, len + 1 ) ) + return 0; + + /* now copy the string */ + MEM_Copy( result, *cursor, len ); + result[len] = '\0'; + *cursor = cur; + return result; + } + +#endif /* 0 */ + + + static + int t1_tobool( FT_Byte** cursor, + FT_Byte* limit ) + { + FT_Byte* cur = *cursor; + FT_Bool result = 0; + + + /* return 1 if we find `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; + } + + + /* Load a simple field (i.e. non-table) into the current list of objects */ + LOCAL_FUNC + FT_Error T1_Load_Field( T1_Parser* parser, + const T1_Field* field, + void** objects, + FT_UInt max_objects, + FT_ULong* pflags ) + { + T1_Token token; + FT_Byte* cur; + FT_Byte* limit; + FT_UInt count; + FT_UInt index; + FT_Error error; + + + T1_ToToken( parser, &token ); + if ( !token.type ) + goto Fail; + + count = 1; + index = 0; + cur = token.start; + limit = token.limit; + + if ( token.type == t1_token_array ) + { + /* if this is an array, and we have no blend, an error occurs */ + if ( max_objects == 0 ) + goto Fail; + + count = max_objects; + index = 1; + } + + for ( ; count > 0; count--, index++ ) + { + FT_Byte* q = (FT_Byte*)objects[index] + 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, 3 ); + 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_UInt32*)q = (FT_UInt32)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 ( *(FT_String**)q ) + /* with synthetic fonts, it's possible to find a field twice */ + break; + + if ( ALLOC( string, len + 1 ) ) + goto Exit; + + MEM_Copy( string, cur, len ); + string[len] = 0; + + *(FT_String**)q = string; + } + break; + + default: + /* an error occured */ + goto Fail; + } + } + + if ( pflags ) + *pflags |= 1L << field->flag_bit; + + error = FT_Err_Ok; + + Exit: + return error; + + Fail: + error = FT_Err_Invalid_File_Format; + goto Exit; + } + + +#define T1_MAX_TABLE_ELEMENTS 32 + + + LOCAL_FUNC + FT_Error T1_Load_Field_Table( T1_Parser* parser, + const T1_Field* field, + void** objects, + FT_UInt max_objects, + FT_ULong* pflags ) + { + T1_Token elements[T1_MAX_TABLE_ELEMENTS]; + T1_Token* token; + FT_Int num_elements; + FT_Error error = 0; + FT_Byte* old_cursor; + FT_Byte* old_limit; + T1_Field fieldrec = *(T1_Field*)field; + + + T1_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 */ + *(FT_Byte*)( (FT_Byte*)objects[0] + 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; + T1_Load_Field( parser, &fieldrec, objects, max_objects, 0 ); + fieldrec.offset += fieldrec.size; + } + + if ( pflags ) + *pflags |= 1L << field->flag_bit; + + parser->cursor = old_cursor; + parser->limit = old_limit; + + Exit: + return error; + + Fail: + error = FT_Err_Invalid_File_Format; + goto Exit; + } + + + LOCAL_FUNC + FT_Long T1_ToInt ( T1_Parser* parser ) + { + return t1_toint( &parser->cursor, parser->limit ); + } + + + LOCAL_FUNC + FT_Fixed T1_ToFixed( T1_Parser* parser, + FT_Int power_ten ) + { + return t1_tofixed( &parser->cursor, parser->limit, power_ten ); + } + + + LOCAL_FUNC + FT_Int T1_ToCoordArray( T1_Parser* parser, + FT_Int max_coords, + FT_Short* coords ) + { + return t1_tocoordarray( &parser->cursor, parser->limit, + max_coords, coords ); + } + + + LOCAL_FUNC + FT_Int T1_ToFixedArray( T1_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 + + LOCAL_FUNC + FT_String* T1_ToString( T1_Parser* parser ) + { + return t1_tostring( &parser->cursor, parser->limit, parser->memory ); + } + + + LOCAL_FUNC + FT_Bool T1_ToBool( T1_Parser* parser ) + { + return t1_tobool( &parser->cursor, parser->limit ); + } + +#endif /* 0 */ + + + LOCAL_FUNC + void T1_Init_Parser( T1_Parser* parser, + FT_Byte* base, + FT_Byte* limit, + FT_Memory memory ) + { + parser->error = 0; + parser->base = base; + parser->limit = base; + parser->cursor = base; + parser->memory = memory; + } + + + LOCAL_FUNC + void T1_Done_Parser( T1_Parser* parser ) + { + FT_UNUSED(parser); + } + + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** T1 BUILDER *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + + /*************************************************************************/ + /* */ + /* */ + /* T1_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. */ + /* */ + LOCALFUNC + void T1_Init_Builder( T1_Builder* builder, + FT_Face face, + FT_Size size, + FT_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->metrics.x_scale; + builder->scale_y = size->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; + } + + + /*************************************************************************/ + /* */ + /* */ + /* T1_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. */ + /* */ + LOCALFUNC + void T1_Done_Builder( T1_Builder* builder ) + { + T1_GlyphSlot glyph = builder->glyph; + + + if ( glyph ) + glyph->root.outline = *builder->base; + } + + + /* check that there is enough room for `count' more points */ + LOCAL_FUNC + FT_Error T1_Builder_Check_Points( T1_Builder* builder, + FT_Int count ) + { + return FT_GlyphLoader_Check_Points( builder->loader, count, 0 ); + } + + + /* add a new point, do not check space */ + LOCAL_FUNC + void T1_Builder_Add_Point( T1_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 >> 16; + point->y = y >> 16; + *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 */ + LOCAL_FUNC + FT_Error T1_Builder_Add_Point1( T1_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 */ + LOCAL_FUNC + FT_Error T1_Builder_Add_Contour( T1_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 was begun, add its first on-curve point */ + LOCAL_FUNC + FT_Error T1_Builder_Start_Point( T1_Builder* builder, + FT_Pos x, + FT_Pos y ) + { + FT_Error error = 0; + + + /* test whether we are building a new contour */ + if ( !builder->path_begun ) + { + builder->path_begun = 1; + error = add_contour( builder ); + if ( !error ) + error = add_point1( builder, x, y ); + } + return error; + } + + + /* close the current contour */ + LOCAL_FUNC + void T1_Builder_Close_Contour( T1_Builder* builder ) + { + FT_Outline* outline = builder->current; + + /* XXXX: 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; + } + + + + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** OTHER *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + + + + + + + LOCAL_FUNC + void T1_Decrypt( FT_Byte* buffer, + FT_Int length, + FT_UShort seed ) + { + while ( length > 0 ) + { + FT_Byte plain; + + + plain = ( *buffer ^ ( seed >> 8 ) ); + seed = ( *buffer + seed ) * 52845 + 22719; + *buffer++ = plain; + length--; + } + } + + + + diff --git a/src/psaux/psobjs.h b/src/psaux/psobjs.h new file mode 100644 index 000000000..84c4359b5 --- /dev/null +++ b/src/psaux/psobjs.h @@ -0,0 +1,113 @@ +#ifndef PSOBJS_H +#define PSOBJS_H + +#include + + + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** T1_TABLE *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + + + LOCAL_DEF + FT_Error T1_New_Table( T1_Table* table, + FT_Int count, + FT_Memory memory ); + + LOCAL_DEF + FT_Error T1_Add_Table( T1_Table* table, + FT_Int index, + void* object, + FT_Int length ); + + LOCAL_DEF + void T1_Done_Table( T1_Table* table ); + + LOCAL_DEF + void T1_Release_Table( T1_Table* table ); + + + + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** T1 PARSER *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + + + LOCAL_DEF + void T1_Skip_Spaces( T1_Parser* parser ); + + LOCAL_DEF + void T1_Skip_Alpha( T1_Parser* parser ); + + LOCAL_DEF + void T1_ToToken( T1_Parser* parser, + T1_Token* token ); + + LOCAL_DEF + void T1_ToTokenArray( T1_Parser* parser, + T1_Token* tokens, + FT_UInt max_tokens, + FT_Int* pnum_tokens ); + + LOCAL_DEF + FT_Error T1_Load_Field( T1_Parser* parser, + const T1_Field* field, + void** objects, + FT_UInt max_objects, + FT_ULong* pflags ); + + LOCAL_DEF + FT_Error T1_Load_Field_Table( T1_Parser* parser, + const T1_Field* field, + void** objects, + FT_UInt max_objects, + FT_ULong* pflags ); + + LOCAL_DEF + FT_Long T1_ToInt ( T1_Parser* parser ); + + + LOCAL_DEF + FT_Fixed T1_ToFixed( T1_Parser* parser, + FT_Int power_ten ); + + + LOCAL_DEF + FT_Int T1_ToCoordArray( T1_Parser* parser, + FT_Int max_coords, + FT_Short* coords ); + + LOCAL_DEF + FT_Int T1_ToFixedArray( T1_Parser* parser, + FT_Int max_values, + FT_Fixed* values, + FT_Int power_ten ); + + + LOCAL_DEF + void T1_Init_Parser( T1_Parser* parser, + FT_Byte* base, + FT_Byte* limit, + FT_Memory memory ); + + LOCAL_DEF + void T1_Done_Parser( T1_Parser* parser ) + + + + LOCAL_DEF + void T1_Decrypt( FT_Byte* buffer, + FT_Int length, + FT_UShort seed ); + + +#endif /* PSOBJS_H */ + diff --git a/src/sfnt/ttload.c b/src/sfnt/ttload.c index 32338d548..fc9da24a6 100644 --- a/src/sfnt/ttload.c +++ b/src/sfnt/ttload.c @@ -436,7 +436,7 @@ stream = face->root.stream; /* the `if' is syntactic sugar for picky compilers */ if ( FILE_Read_At( offset, buffer, size ) ) - ; + goto Exit; Exit: return error; diff --git a/src/type1z/z1gload.c b/src/type1z/z1gload.c index 0a881c655..15999cb9c 100644 --- a/src/type1z/z1gload.c +++ b/src/type1z/z1gload.c @@ -1425,6 +1425,14 @@ if ( size && size->root.metrics.y_ppem < 24 ) glyph->root.outline.flags |= ft_outline_high_precision; + /* apply the font matrix */ + FT_Outline_Transform( &glyph->root.outline, + &face->type1.font_matrix ); + + FT_Outline_Translate( &glyph->root.outline, + face->type1.font_offset.x, + face->type1.font_offset.y ); + #if 0 glyph->root.outline.second_pass = TRUE; glyph->root.outline.high_precision = size->root.metrics.y_ppem < 24; @@ -1458,10 +1466,6 @@ metrics->vertBearingY = FT_MulFix( metrics->vertBearingY, y_scale ); } - /* apply the font matrix */ - FT_Outline_Transform( &glyph->root.outline, - &face->type1.font_matrix ); - /* compute the other metrics */ FT_Outline_Get_CBox( &glyph->root.outline, &cbox ); diff --git a/src/type1z/z1load.c b/src/type1z/z1load.c index 7d63a34e3..4a19402dd 100644 --- a/src/type1z/z1load.c +++ b/src/type1z/z1load.c @@ -1069,18 +1069,33 @@ { Z1_Parser* parser = &loader->parser; FT_Matrix* matrix = &face->type1.font_matrix; - FT_Fixed temp[4]; + FT_Vector* offset = &face->type1.font_offset; + FT_Fixed temp[6]; if ( matrix->xx || matrix->yx ) /* with synthetic fonts, it's possible we get here twice */ return; - (void)Z1_ToFixedArray( parser, 4, temp, 3 ); + (void)Z1_ToFixedArray( parser, 6, temp, 3 ); + + /* we need to scale the values by 1.0/temp[3] */ + if ( temp[3] != 0x10000 ) + { + 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] = 0x10000; + } + matrix->xx = temp[0]; matrix->yx = temp[1]; matrix->xy = temp[2]; matrix->yy = temp[3]; + offset->x = temp[4]; + offset->y = temp[5]; } diff --git a/src/type1z/z1tokens.h b/src/type1z/z1tokens.h index 96288139f..65ef0479d 100644 --- a/src/type1z/z1tokens.h +++ b/src/type1z/z1tokens.h @@ -64,69 +64,4 @@ Z1_TOPDICT_NUM( "FontType", font_type ) Z1_TOPDICT_NUM( "StrokeWidth", stroke_width ) - -#if 0 - - /* define the font info dictionary parsing callbacks */ -#undef FACE -#define FACE (face->type1.font_info) - - PARSE_STRING( "version", version ) - PARSE_STRING( "Notice", notice ) - PARSE_STRING( "FullName", full_name ) - PARSE_STRING( "FamilyName", family_name ) - PARSE_STRING( "Weight", weight ) - - PARSE_INT ( "ItalicAngle", italic_angle ) - PARSE_BOOL ( "isFixedPitch", is_fixed_pitch ) - PARSE_NUM ( "UnderlinePosition", underline_position, FT_Short ) - PARSE_NUM ( "UnderlineThickness", underline_thickness, FT_UShort ) - - - /* define the private dict parsing callbacks */ -#undef FACE -#define FACE (face->type1.private_dict) - - PARSE_INT ("UniqueID", unique_id ) - PARSE_INT ("lenIV", lenIV ) - - PARSE_COORDS ( "BlueValues", num_blues, 14, blue_values) - PARSE_COORDS ( "OtherBlues", num_other_blues, 10, other_blues) - - PARSE_COORDS ( "FamilyBlues", num_family_blues, 14, family_blues ) - PARSE_COORDS ( "FamilyOtherBlues", num_family_other_blues, 10, - family_other_blues ) - - PARSE_FIXED ( "BlueScale", blue_scale ) - PARSE_INT ( "BlueShift", blue_shift ) - - PARSE_INT ( "BlueFuzz", blue_fuzz ) - - PARSE_COORDS2( "StdHW", 1, standard_width ) - PARSE_COORDS2( "StdVW", 1, standard_height ) - - PARSE_COORDS ( "StemSnapH", num_snap_widths, 12, stem_snap_widths ) - PARSE_COORDS ( "StemSnapV", num_snap_heights, 12, stem_snap_heights ) - - PARSE_INT ( "LanguageGroup", language_group ) - PARSE_INT ( "password", password ) - PARSE_COORDS2( "MinFeature", 2, min_feature ) - - - /* define the top-level dictionary parsing callbacks */ -#undef FACE -#define FACE (face->type1) - -/*PARSE_STRING ( "FontName", font_name ) -- handled by special routine */ - PARSE_NUM ( "PaintType", paint_type, FT_Byte ) - PARSE_NUM ( "FontType", font_type, FT_Byte ) - PARSE_FIXEDS2( "FontMatrix", 4, font_matrix ) -/*PARSE_COORDS2( "FontBBox", 4, font_bbox ) -- handled by special routine */ - PARSE_INT ( "StrokeWidth", stroke_width ) - -#undef FACE - -#endif /* 0 */ - - /* END */