ref: 24d7024c4468b526996ec9f4ad83c08bb3347566
parent: 710354b8e9f7c7c44bdf1cb087625f7a16e3922a
author: David Turner <[email protected]>
date: Wed Aug 16 21:09:06 EDT 2000
added draft "psaux" code the t1 driver now reads the complete font matrix and applies it (some fonts do not work properly without hinting though...)
--- /dev/null
+++ b/include/freetype/internal/psaux.h
@@ -1,0 +1,459 @@
+#ifndef PSAUX_H
+#define PSAUX_H
+
+#include <freetype/internal/ftobjs.h>
+
+ /*************************************************************************/
+ /*************************************************************************/
+ /***** *****/
+ /***** T1_TABLE *****/
+ /***** *****/
+ /*************************************************************************/
+ /*************************************************************************/
+
+
+ /*************************************************************************/
+ /* */
+ /* <Struct> */
+ /* T1_Table */
+ /* */
+ /* <Description> */
+ /* A T1_Table is a simple object used to store an array of objects in */
+ /* a single memory block. */
+ /* */
+ /* <Fields> */
+ /* 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;
+
+
+
+ /*************************************************************************/
+ /* */
+ /* <Struct> */
+ /* T1_Table_Funcs */
+ /* */
+ /* <Description> */
+ /* A set of function pointers used to manage T1_Table objects.. */
+ /* */
+ /* <Fields> */
+ /* 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 *****/
+ /***** *****/
+ /*************************************************************************/
+ /*************************************************************************/
+
+ /*************************************************************************/
+ /* */
+ /* <Struct> */
+ /* T1_Parser */
+ /* */
+ /* <Description> */
+ /* A T1_Parser is an object used to parse a Type 1 font very */
+ /* quickly. */
+ /* */
+ /* <Fields> */
+ /* 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 *****/
+ /***** *****/
+ /*************************************************************************/
+ /*************************************************************************/
+
+
+ /*************************************************************************/
+ /* */
+ /* <Structure> */
+ /* T1_Builder */
+ /* */
+ /* <Description> */
+ /* A structure used during glyph loading to store its outline. */
+ /* */
+ /* <Fields> */
+ /* 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 */
--- 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;
--- 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 );
--- a/src/otlayout/oltypes.h
+++ b/src/otlayout/oltypes.h
@@ -1,8 +1,7 @@
#ifndef OLTYPES_H
#define OLTYPES_H
-#include <ftobjs.h>
-#include <tttypes.h>
+#include <freetype/internal/ftobjs.h>
/*************************************************************
*
@@ -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,11 +83,11 @@
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;
@@ -95,13 +94,13 @@
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;
@@ -108,35 +107,20 @@
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,7 +137,13 @@
* 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 );
+
/********************************************************
*
* - after calling OTL_Table_Set_Features:
@@ -169,7 +159,19 @@
* 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 );
+
+
/*******************************************************************
*
* - after calling OTL_Get_Languages_List(script_tag):
@@ -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,42 +261,42 @@
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 );
@@ -301,10 +303,10 @@
#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 */
--- /dev/null
+++ b/src/psaux/psobjs.c
@@ -1,0 +1,1244 @@
+#include <freetype/internal/psaux.h>
+#include <freetype/fterrors.h>
+
+ /*************************************************************************/
+ /*************************************************************************/
+ /***** *****/
+ /***** T1_TABLE *****/
+ /***** *****/
+ /*************************************************************************/
+ /*************************************************************************/
+
+ /*************************************************************************/
+ /* */
+ /* <Function> */
+ /* T1_New_Table */
+ /* */
+ /* <Description> */
+ /* Initialises a T1_Table. */
+ /* */
+ /* <InOut> */
+ /* table :: The address of the target table. */
+ /* */
+ /* <Input> */
+ /* count :: The table size = the maximum number of elements. */
+ /* */
+ /* memory :: The memory object to use for all subsequent */
+ /* reallocations. */
+ /* */
+ /* <Return> */
+ /* 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;
+ }
+
+
+ /*************************************************************************/
+ /* */
+ /* <Function> */
+ /* T1_Add_Table */
+ /* */
+ /* <Description> */
+ /* Adds an object to a T1_Table, possibly growing its memory block. */
+ /* */
+ /* <InOut> */
+ /* table :: The target table. */
+ /* */
+ /* <Input> */
+ /* 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. */
+ /* */
+ /* <Return> */
+ /* 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;
+ }
+
+
+
+ /*************************************************************************/
+ /* */
+ /* <Function> */
+ /* T1_Done_Table */
+ /* */
+ /* <Description> */
+ /* Finalizes a T1_Table (i.e., reallocate it to its current cursor). */
+ /* */
+ /* <InOut> */
+ /* table :: The target table. */
+ /* */
+ /* <Note> */
+ /* 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 *****/
+ /***** *****/
+ /*************************************************************************/
+ /*************************************************************************/
+
+ /*************************************************************************/
+ /* */
+ /* <Function> */
+ /* T1_Init_Builder */
+ /* */
+ /* <Description> */
+ /* Initializes a given glyph builder. */
+ /* */
+ /* <InOut> */
+ /* builder :: A pointer to the glyph builder to initialize. */
+ /* */
+ /* <Input> */
+ /* 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;
+ }
+
+
+ /*************************************************************************/
+ /* */
+ /* <Function> */
+ /* T1_Done_Builder */
+ /* */
+ /* <Description> */
+ /* 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. */
+ /* */
+ /* <Input> */
+ /* 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--;
+ }
+ }
+
+
+
+
--- /dev/null
+++ b/src/psaux/psobjs.h
@@ -1,0 +1,113 @@
+#ifndef PSOBJS_H
+#define PSOBJS_H
+
+#include <freetype/internal/psaux.h>
+
+
+ /*************************************************************************/
+ /*************************************************************************/
+ /***** *****/
+ /***** 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 */
+
--- 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;
--- 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;
@@ -1457,10 +1465,6 @@
metrics->vertBearingX = FT_MulFix( metrics->vertBearingX, x_scale );
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 );
--- a/src/type1z/z1load.c
+++ b/src/type1z/z1load.c
@@ -1069,7 +1069,8 @@
{
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 )
@@ -1076,11 +1077,25 @@
/* 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];
}
--- 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 */