diff --git a/Jamfile b/Jamfile index 96cfc92bd..c8467b416 100644 --- a/Jamfile +++ b/Jamfile @@ -30,6 +30,7 @@ SubDirHdr += $(FT2_INCLUDE) ; # record these definitions. # HDRMACRO [ FT2_SubDir include freetype config ftheader.h ] ; +HDRMACRO [ FT2_SubDir include freetype internal internal.h ] ; # Now include the Jamfile in "freetype2/src", used to drive the compilation # of each FreeType 2 component and/or module. diff --git a/include/freetype/config/ftmodule.h b/include/freetype/config/ftmodule.h index eb35a329a..71e668e50 100644 --- a/include/freetype/config/ftmodule.h +++ b/include/freetype/config/ftmodule.h @@ -4,9 +4,11 @@ FT_USE_MODULE(t1cid_driver_class) FT_USE_MODULE(pcf_driver_class) FT_USE_MODULE(psaux_module_class) FT_USE_MODULE(psnames_module_class) +FT_USE_MODULE(pshinter_module_class) FT_USE_MODULE(ft_raster1_renderer_class) FT_USE_MODULE(sfnt_module_class) FT_USE_MODULE(ft_smooth_renderer_class) FT_USE_MODULE(tt_driver_class) FT_USE_MODULE(t1_driver_class) FT_USE_MODULE(winfnt_driver_class) + diff --git a/include/freetype/internal/psaux.h b/include/freetype/internal/psaux.h index 85970e589..d62358113 100644 --- a/include/freetype/internal/psaux.h +++ b/include/freetype/internal/psaux.h @@ -406,7 +406,8 @@ FT_BEGIN_HEADER void (*init)( T1_Builder* builder, FT_Face face, FT_Size size, - FT_GlyphSlot slot ); + FT_GlyphSlot slot, + FT_Bool hinting ); void (*done)( T1_Builder* builder ); @@ -506,7 +507,8 @@ FT_BEGIN_HEADER FT_Error error; /* only used for memory errors */ FT_Bool metrics_only; - T1_Hints_Funcs hints_funcs; + void* hints_funcs; /* hinter-specific */ + void* hints_globals; /* hinter-specific */ T1_Builder_Funcs funcs; }; @@ -565,6 +567,7 @@ FT_BEGIN_HEADER FT_GlyphSlot slot, FT_Byte** glyph_names, T1_Blend* blend, + FT_Bool hinting, T1_Decoder_Callback callback ); void (*done) ( T1_Decoder* decoder ); diff --git a/include/freetype/internal/pshints.h b/include/freetype/internal/pshints.h index f1a12fafd..bf9814aef 100644 --- a/include/freetype/internal/pshints.h +++ b/include/freetype/internal/pshints.h @@ -21,7 +21,7 @@ #define __PSHINTS_H__ #include -#include FT_TYPES_H +#include FT_FREETYPE_H #include FT_INTERNAL_POSTSCRIPT_GLOBALS_H FT_BEGIN_HEADER @@ -287,7 +287,7 @@ FT_BEGIN_HEADER */ typedef void (*T1_Hints_SetStemFunc) ( T1_Hints hints, FT_UInt dimension, - FT_Int* coords ); + FT_Long* coords ); /************************************************************************ * @@ -311,7 +311,7 @@ FT_BEGIN_HEADER */ typedef void (*T1_Hints_SetStem3Func) ( T1_Hints hints, FT_UInt dimension, - FT_Int* coords ); + FT_Long* coords ); /************************************************************************ * diff --git a/src/base/ftobjs.c b/src/base/ftobjs.c index 01b07bfc3..18c29c2c3 100644 --- a/src/base/ftobjs.c +++ b/src/base/ftobjs.c @@ -107,6 +107,9 @@ if ( !Q ) goto Fail; + if ( size > current ) + memset( (char*)Q + current, 0, size - current ); + *P = Q; return FT_Err_Ok; diff --git a/src/cid/cidgload.c b/src/cid/cidgload.c index 05abd9cfd..79d94dacd 100644 --- a/src/cid/cidgload.c +++ b/src/cid/cidgload.c @@ -158,6 +158,7 @@ 0, /* glyph slot */ 0, /* glyph names! XXX */ 0, /* blend == 0 */ + 0, /* hinting == FALSE */ cid_load_glyph ); if ( error ) return error; @@ -237,6 +238,7 @@ (FT_GlyphSlot)glyph, 0, /* glyph names -- XXX */ 0, /* blend == 0 */ + 0, /* hinting == 0 */ cid_load_glyph ); /* set up the decoder */ diff --git a/src/cid/cidload.c b/src/cid/cidload.c index 1f45fa27e..f68bbc244 100644 --- a/src/cid/cidload.c +++ b/src/cid/cidload.c @@ -23,7 +23,6 @@ #include FT_INTERNAL_TYPE1_TYPES_H #include "cidload.h" - #include "ciderrs.h" #include diff --git a/src/psaux/psobjs.c b/src/psaux/psobjs.c index 6362618c2..f7d27d3cd 100644 --- a/src/psaux/psobjs.c +++ b/src/psaux/psobjs.c @@ -53,10 +53,10 @@ /* */ /* FreeType error code. 0 means success. */ /* */ - FT_LOCAL_DEF - FT_Error PS_Table_New( PS_Table* table, - FT_Int count, - FT_Memory memory ) + FT_LOCAL_DEF FT_Error + PS_Table_New( PS_Table* table, + FT_Int count, + FT_Memory memory ) { FT_Error error; @@ -82,9 +82,9 @@ } - static - void shift_elements( PS_Table* table, - FT_Byte* old_base ) + static void + shift_elements( PS_Table* table, + FT_Byte* old_base ) { FT_Long delta = (FT_Long)( table->block - old_base ); FT_Byte** offset = table->elements; @@ -99,9 +99,9 @@ } - static - FT_Error reallocate_t1_table( PS_Table* table, - FT_Int new_size ) + static FT_Error + reallocate_t1_table( PS_Table* table, + FT_Int new_size ) { FT_Memory memory = table->memory; FT_Byte* old_base = table->block; @@ -148,11 +148,11 @@ /* FreeType error code. 0 means success. An error is returned if a */ /* reallocation fails. */ /* */ - FT_LOCAL_DEF - FT_Error PS_Table_Add( PS_Table* table, - FT_Int index, - void* object, - FT_Int length ) + FT_LOCAL_DEF FT_Error + PS_Table_Add( PS_Table* table, + FT_Int index, + void* object, + FT_Int length ) { if ( index < 0 || index > table->max_elems ) { @@ -200,8 +200,8 @@ /* 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. */ /* */ - FT_LOCAL_DEF - void PS_Table_Done( PS_Table* table ) + FT_LOCAL_DEF void + PS_Table_Done( PS_Table* table ) { FT_Memory memory = table->memory; FT_Error error; @@ -222,8 +222,8 @@ } - FT_LOCAL_DEF - void PS_Table_Release( PS_Table* table ) + FT_LOCAL_DEF void + PS_Table_Release( PS_Table* table ) { FT_Memory memory = table->memory; @@ -253,8 +253,8 @@ #define IS_T1_SPACE( c ) ( IS_T1_WHITESPACE( c ) || IS_T1_LINESPACE( c ) ) - FT_LOCAL_DEF - void T1_Skip_Spaces( T1_Parser* parser ) + FT_LOCAL_DEF void + T1_Skip_Spaces( T1_Parser* parser ) { FT_Byte* cur = parser->cursor; FT_Byte* limit = parser->limit; @@ -273,8 +273,8 @@ } - FT_LOCAL_DEF - void T1_Skip_Alpha( T1_Parser* parser ) + FT_LOCAL_DEF void + T1_Skip_Alpha( T1_Parser* parser ) { FT_Byte* cur = parser->cursor; FT_Byte* limit = parser->limit; @@ -293,9 +293,9 @@ } - FT_LOCAL_DEF - void T1_ToToken( T1_Parser* parser, - T1_Token* token ) + FT_LOCAL_DEF void + T1_ToToken( T1_Parser* parser, + T1_Token* token ) { FT_Byte* cur; FT_Byte* limit; @@ -376,11 +376,11 @@ } - FT_LOCAL_DEF - void T1_ToTokenArray( T1_Parser* parser, - T1_Token* tokens, - FT_UInt max_tokens, - FT_Int* pnum_tokens ) + FT_LOCAL_DEF void + T1_ToTokenArray( T1_Parser* parser, + T1_Token* tokens, + FT_UInt max_tokens, + FT_Int* pnum_tokens ) { T1_Token master; @@ -422,9 +422,9 @@ } - static - FT_Long t1_toint( FT_Byte** cursor, - FT_Byte* limit ) + static FT_Long + t1_toint( FT_Byte** cursor, + FT_Byte* limit ) { FT_Long result = 0; FT_Byte* cur = *cursor; @@ -467,10 +467,10 @@ } - static - FT_Long t1_tofixed( FT_Byte** cursor, - FT_Byte* limit, - FT_Long power_ten ) + static FT_Long + t1_tofixed( FT_Byte** cursor, + FT_Byte* limit, + FT_Long power_ten ) { FT_Byte* cur = *cursor; FT_Long num, divider, result; @@ -557,11 +557,11 @@ } - static - FT_Int t1_tocoordarray( FT_Byte** cursor, - FT_Byte* limit, - FT_Int max_coords, - FT_Short* coords ) + 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; @@ -616,12 +616,12 @@ } - static - FT_Int t1_tofixedarray( FT_Byte** cursor, - FT_Byte* limit, - FT_Int max_values, - FT_Fixed* values, - FT_Int power_ten ) + 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; @@ -677,10 +677,10 @@ #if 0 - static - FT_String* t1_tostring( FT_Byte** cursor, - FT_Byte* limit, - FT_Memory memory ) + static FT_String* + t1_tostring( FT_Byte** cursor, + FT_Byte* limit, + FT_Memory memory ) { FT_Byte* cur = *cursor; FT_Int len = 0; @@ -772,12 +772,12 @@ /* Load a simple field (i.e. non-table) into the current list of objects */ - FT_LOCAL_DEF - FT_Error T1_Load_Field( T1_Parser* parser, - const T1_Field* field, - void** objects, - FT_UInt max_objects, - FT_ULong* pflags ) + FT_LOCAL_DEF 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; @@ -893,12 +893,12 @@ #define T1_MAX_TABLE_ELEMENTS 32 - FT_LOCAL_DEF - FT_Error T1_Load_Field_Table( T1_Parser* parser, - const T1_Field* field, - void** objects, - FT_UInt max_objects, - FT_ULong* pflags ) + FT_LOCAL_DEF 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; @@ -957,36 +957,36 @@ } - FT_LOCAL_DEF - FT_Long T1_ToInt( T1_Parser* parser ) + FT_LOCAL_DEF FT_Long + T1_ToInt( T1_Parser* parser ) { return t1_toint( &parser->cursor, parser->limit ); } - FT_LOCAL_DEF - FT_Fixed T1_ToFixed( T1_Parser* parser, - FT_Int power_ten ) + FT_LOCAL_DEF FT_Fixed + T1_ToFixed( T1_Parser* parser, + FT_Int power_ten ) { return t1_tofixed( &parser->cursor, parser->limit, power_ten ); } - FT_LOCAL_DEF - FT_Int T1_ToCoordArray( T1_Parser* parser, - FT_Int max_coords, - FT_Short* coords ) + FT_LOCAL_DEF FT_Int + T1_ToCoordArray( T1_Parser* parser, + FT_Int max_coords, + FT_Short* coords ) { return t1_tocoordarray( &parser->cursor, parser->limit, max_coords, coords ); } - FT_LOCAL_DEF - FT_Int T1_ToFixedArray( T1_Parser* parser, - FT_Int max_values, - FT_Fixed* values, - FT_Int power_ten ) + FT_LOCAL_DEF 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 ); @@ -995,15 +995,15 @@ #if 0 - FT_LOCAL_DEF - FT_String* T1_ToString( T1_Parser* parser ) + FT_LOCAL_DEF FT_String* + T1_ToString( T1_Parser* parser ) { return t1_tostring( &parser->cursor, parser->limit, parser->memory ); } - FT_LOCAL_DEF - FT_Bool T1_ToBool( T1_Parser* parser ) + FT_LOCAL_DEF FT_Bool + T1_ToBool( T1_Parser* parser ) { return t1_tobool( &parser->cursor, parser->limit ); } @@ -1011,11 +1011,11 @@ #endif /* 0 */ - FT_LOCAL_DEF - void T1_Init_Parser( T1_Parser* parser, - FT_Byte* base, - FT_Byte* limit, - FT_Memory memory ) + FT_LOCAL_DEF void + T1_Init_Parser( T1_Parser* parser, + FT_Byte* base, + FT_Byte* limit, + FT_Memory memory ) { parser->error = 0; parser->base = base; @@ -1026,8 +1026,8 @@ } - FT_LOCAL_DEF - void T1_Done_Parser( T1_Parser* parser ) + FT_LOCAL_DEF void + T1_Done_Parser( T1_Parser* parser ) { FT_UNUSED( parser ); } @@ -1059,11 +1059,12 @@ /* */ /* glyph :: The current glyph object. */ /* */ - FT_LOCAL_DEF - void T1_Builder_Init( T1_Builder* builder, - FT_Face face, - FT_Size size, - FT_GlyphSlot glyph ) + FT_LOCAL_DEF void + T1_Builder_Init( T1_Builder* builder, + FT_Face face, + FT_Size size, + FT_GlyphSlot glyph, + FT_Bool hinting ) { builder->path_begun = 0; builder->load_points = 1; @@ -1081,8 +1082,12 @@ builder->base = &loader->base.outline; builder->current = &loader->current.outline; FT_GlyphLoader_Rewind( loader ); - - builder->hints_func = (T1_Hints_Funcs) glyph->internal->glyph_hints; + + builder->hints_globals = size->internal; + builder->hints_funcs = 0; + + if (hinting) + builder->hints_funcs = glyph->internal->glyph_hints; } if ( size ) @@ -1116,8 +1121,8 @@ /* */ /* builder :: A pointer to the glyph builder to finalize. */ /* */ - FT_LOCAL_DEF - void T1_Builder_Done( T1_Builder* builder ) + FT_LOCAL_DEF void + T1_Builder_Done( T1_Builder* builder ) { FT_GlyphSlot glyph = builder->glyph; @@ -1128,20 +1133,20 @@ /* check that there is enough room for `count' more points */ - FT_LOCAL_DEF - FT_Error T1_Builder_Check_Points( T1_Builder* builder, - FT_Int count ) + FT_LOCAL_DEF 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 */ - FT_LOCAL_DEF - void T1_Builder_Add_Point( T1_Builder* builder, - FT_Pos x, - FT_Pos y, - FT_Byte flag ) + FT_LOCAL_DEF void + T1_Builder_Add_Point( T1_Builder* builder, + FT_Pos x, + FT_Pos y, + FT_Byte flag ) { FT_Outline* outline = builder->current; @@ -1168,10 +1173,10 @@ /* check space for a new on-curve point, then add it */ - FT_LOCAL_DEF - FT_Error T1_Builder_Add_Point1( T1_Builder* builder, - FT_Pos x, - FT_Pos y ) + FT_LOCAL_DEF FT_Error + T1_Builder_Add_Point1( T1_Builder* builder, + FT_Pos x, + FT_Pos y ) { FT_Error error; @@ -1185,8 +1190,8 @@ /* check room for a new contour, then add it */ - FT_LOCAL_DEF - FT_Error T1_Builder_Add_Contour( T1_Builder* builder ) + FT_LOCAL_DEF FT_Error + T1_Builder_Add_Contour( T1_Builder* builder ) { FT_Outline* outline = builder->current; FT_Error error; @@ -1213,10 +1218,10 @@ /* if a path was begun, add its first on-curve point */ - FT_LOCAL_DEF - FT_Error T1_Builder_Start_Point( T1_Builder* builder, - FT_Pos x, - FT_Pos y ) + FT_LOCAL_DEF FT_Error + T1_Builder_Start_Point( T1_Builder* builder, + FT_Pos x, + FT_Pos y ) { FT_Error error = 0; @@ -1234,8 +1239,8 @@ /* close the current contour */ - FT_LOCAL_DEF - void T1_Builder_Close_Contour( T1_Builder* builder ) + FT_LOCAL_DEF void + T1_Builder_Close_Contour( T1_Builder* builder ) { FT_Outline* outline = builder->current; @@ -1277,10 +1282,10 @@ /*************************************************************************/ /*************************************************************************/ - FT_LOCAL_DEF - void T1_Decrypt( FT_Byte* buffer, - FT_Int length, - FT_UShort seed ) + FT_LOCAL_DEF void + T1_Decrypt( FT_Byte* buffer, + FT_Int length, + FT_UShort seed ) { while ( length > 0 ) { diff --git a/src/psaux/psobjs.h b/src/psaux/psobjs.h index c0e482a20..9a93c2090 100644 --- a/src/psaux/psobjs.h +++ b/src/psaux/psobjs.h @@ -147,7 +147,8 @@ FT_BEGIN_HEADER void T1_Builder_Init( T1_Builder* builder, FT_Face face, FT_Size size, - FT_GlyphSlot glyph ); + FT_GlyphSlot glyph, + FT_Bool hinting ); FT_LOCAL void T1_Builder_Done( T1_Builder* builder ); diff --git a/src/psaux/t1decode.c b/src/psaux/t1decode.c index 1c0b01476..a3ec4e36a 100644 --- a/src/psaux/t1decode.c +++ b/src/psaux/t1decode.c @@ -267,6 +267,9 @@ decoder->builder.left_bearing.x = 0; decoder->builder.left_bearing.y = 0; + decoder->builder.pos_x = adx - asb; + decoder->builder.pos_y = ady; + /* Now load `achar' on top of */ /* the base outline */ error = T1_Decoder_Parse_Glyph( decoder, achar_index ); @@ -279,17 +282,8 @@ decoder->builder.left_bearing = left_bearing; decoder->builder.advance = advance; - /* Finally, move the accent */ - if ( decoder->builder.load_points ) - { - FT_Outline dummy; - - - dummy.n_points = (short)( base->n_points - n_base_points ); - dummy.points = base->points + n_base_points; - - FT_Outline_Translate( &dummy, adx - asb, ady ); - } + decoder->builder.pos_x = 0; + decoder->builder.pos_y = 0; Exit: return error; @@ -343,7 +337,7 @@ builder->path_begun = 0; - hinter = builder->hints_funcs; + hinter = (T1_Hints_Funcs) builder->hints_funcs; zone->base = charstring_base; limit = zone->limit = charstring_base + charstring_len; @@ -722,7 +716,15 @@ /* close hints recording session */ if ( hinter ) - hinter->close( hinter->hints, builder->current->n_points ); + { + if (hinter->close( hinter->hints, builder->current->n_points )) + goto Syntax_Error; + + /* apply hints to the loaded glyph outline now */ + hinter->apply( hinter->hints, + builder->current, + (PSH_Globals) builder->hints_globals ); + } /* add current outline to the glyph slot */ FT_GlyphLoader_Add( builder->loader ); @@ -738,8 +740,8 @@ builder->advance.x = top[1]; builder->advance.y = 0; - builder->last.x = x = top[0]; - builder->last.y = y = 0; + builder->last.x = x = builder->pos_x + top[0]; + builder->last.y = y = builder->pos_y; /* the `metrics_only' indicates that we only want to compute */ /* the glyph's metrics (lsb + advance width), not load the */ @@ -762,8 +764,8 @@ builder->advance.x = top[2]; builder->advance.y = top[3]; - builder->last.x = x = top[0]; - builder->last.y = y = top[1]; + builder->last.x = x = builder->pos_x + top[0]; + builder->last.y = y = builder->pos_y + top[1]; /* the `metrics_only' indicates that we only want to compute */ /* the glyph's metrics (lsb + advance width), not load the */ @@ -1057,22 +1059,25 @@ } - FT_LOCAL_DEF - FT_Error T1_Decoder_Parse_Glyph( T1_Decoder* decoder, - FT_UInt glyph ) + /* parse a single Type 1 glyph */ + FT_LOCAL_DEF FT_Error + T1_Decoder_Parse_Glyph( T1_Decoder* decoder, + FT_UInt glyph ) { return decoder->parse_callback( decoder, glyph ); } - - FT_LOCAL_DEF - FT_Error T1_Decoder_Init( T1_Decoder* decoder, - FT_Face face, - FT_Size size, - FT_GlyphSlot slot, - FT_Byte** glyph_names, - T1_Blend* blend, - T1_Decoder_Callback parse_callback ) + + /* initialise T1 decoder */ + FT_LOCAL_DEF FT_Error + T1_Decoder_Init( T1_Decoder* decoder, + FT_Face face, + FT_Size size, + FT_GlyphSlot slot, + FT_Byte** glyph_names, + T1_Blend* blend, + FT_Bool hinting, + T1_Decoder_Callback parse_callback ) { MEM_Set( decoder, 0, sizeof ( *decoder ) ); @@ -1092,7 +1097,7 @@ decoder->psnames = psnames; } - T1_Builder_Init( &decoder->builder, face, size, slot ); + T1_Builder_Init( &decoder->builder, face, size, slot, hinting ); decoder->num_glyphs = face->num_glyphs; decoder->glyph_names = glyph_names; @@ -1105,8 +1110,9 @@ } - FT_LOCAL_DEF - void T1_Decoder_Done( T1_Decoder* decoder ) + /* finalize T1 decoder */ + FT_LOCAL_DEF void + T1_Decoder_Done( T1_Decoder* decoder ) { T1_Builder_Done( &decoder->builder ); } diff --git a/src/psaux/t1decode.h b/src/psaux/t1decode.h index 7b24ee3b1..164acccb3 100644 --- a/src/psaux/t1decode.h +++ b/src/psaux/t1decode.h @@ -49,6 +49,7 @@ FT_BEGIN_HEADER FT_GlyphSlot slot, FT_Byte** glyph_names, T1_Blend* blend, + FT_Bool hinting, T1_Decoder_Callback parse_glyph ); FT_LOCAL diff --git a/src/pshinter/Jamfile b/src/pshinter/Jamfile index 1dec8d77c..081ded470 100644 --- a/src/pshinter/Jamfile +++ b/src/pshinter/Jamfile @@ -10,7 +10,7 @@ SubDirHdrs [ FT2_SubDir src pshinter ] ; if $(FT2_MULTI) { - _sources = pshrec pshglob pshfit pshmod ; + _sources = pshrec pshglob pshfit pshmod pshoptim ; } else { diff --git a/src/pshinter/pshfit.c b/src/pshinter/pshfit.c index 4a4a31b1e..2ecc8ede0 100644 --- a/src/pshinter/pshfit.c +++ b/src/pshinter/pshfit.c @@ -1,8 +1,10 @@ #include #include FT_INTERNAL_OBJECTS_H +#include FT_INTERNAL_DEBUG_H #include "pshfit.h" +#include "pshoptim.h" - /* return true iff two hints overlap */ + /* return true iff two stem hints overlap */ static FT_Int psh_hint_overlap( PSH_Hint hint1, PSH_Hint hint2 ) @@ -66,7 +68,7 @@ /* now scan the current active hint set in order to determine */ /* if we're overlapping with another segment.. */ { - PSH_Hint* sorted = table->sort; + PSH_Hint* sorted = table->sort_global; FT_UInt count = table->num_hints; PSH_Hint hint2; @@ -169,6 +171,8 @@ { FT_UInt count = hint_masks->num_masks; PS_Mask mask = hint_masks->masks; + + table->hint_masks = hint_masks; for ( ; count > 0; count--, mask++ ) psh_hint_table_record_mask( table, mask ); @@ -280,7 +284,29 @@ #define PSH_ZONE_MIN -3200000 #define PSH_ZONE_MAX +3200000 + +#define xxDEBUG_ZONES + +#ifdef DEBUG_ZONES + +#include + + static void + print_zone( PSH_Zone zone ) + { + printf( "zone [scale,delta,min,max] = [%.3f,%.3f,%d,%d]\n", + zone->scale/65536.0, + zone->delta/64.0, + zone->min, + zone->max ); + } + +#else +# define print_zone(x) do { } while (0) +#endif + /* setup interpolation zones once the hints have been grid-fitted */ + /* by the optimizer.. */ static void psh_hint_table_setup_zones( PSH_Hint_Table table, FT_Fixed scale, @@ -312,9 +338,12 @@ zone->delta = hint->cur_pos - FT_MulFix( hint->org_pos, scale ); zone->min = PSH_ZONE_MIN; zone->max = hint->org_pos; + + print_zone( zone ); + zone++; - for ( count = table->num_hints; count > 1; count-- ) + for ( count = table->num_hints; count > 0; count-- ) { FT_Fixed scale2; @@ -329,21 +358,30 @@ zone->min = hint->org_pos; zone->max = hint->org_pos + hint->org_len; zone->delta = hint->cur_pos - FT_MulFix( zone->min, scale2 ); + + print_zone( zone ); + zone++; } + if ( count == 1 ) + break; + sort++; hint2 = sort[0]; /* setup zone for inter-stem interpolation */ /* (x'-x1') = (x-x1)*(x2'-x1')/(x2-x1) */ /* x' = x*s3 + x1' - x1*s3 */ - scale2 = FT_DivFix( hint2->cur_pos - (hint->cur_pos + hint->cur_len), - hint2->org_pos - (hint2->org_pos + hint2->org_len) ); + scale2 = FT_DivFix( hint2->cur_pos - (hint->cur_pos + hint->cur_len), + hint2->org_pos - (hint->org_pos + hint->org_len) ); zone->scale = scale2; zone->min = hint->org_pos + hint->org_len; zone->max = hint2->org_pos; zone->delta = hint->cur_pos + hint->cur_len - FT_MulFix( zone->min, scale2 ); + + print_zone( zone ); + zone++; hint = hint2; @@ -353,7 +391,10 @@ zone->scale = scale; zone->min = hint->org_pos + hint->org_len; zone->max = PSH_ZONE_MAX; - zone->delta = hint->cur_pos - FT_MulFix( zone->min, scale ); + zone->delta = hint->cur_pos + hint->cur_len - FT_MulFix( zone->min, scale ); + + print_zone( zone ); + zone++; table->num_zones = zone - table->zones; @@ -395,47 +436,120 @@ table->zone = zone; } - return zone->delta + FT_MulFix( coord, zone->scale ); + return FT_MulFix( coord, zone->scale ) + zone->delta; } /* tune a given outline with current interpolation zones */ + /* the function only works in a single dimension.. */ static void psh_hint_table_tune_outline( PSH_Hint_Table table, FT_Outline* outline, - FT_Fixed scale, - FT_Fixed delta, + PSH_Globals globals, FT_Bool vertical ) { FT_UInt count, first, last; - PS_Mask_Table hint_masks; + PS_Mask_Table hint_masks = table->hint_masks; PS_Mask mask; + PSH_Dimension dim = &globals->dimension[vertical]; + FT_Fixed scale = dim->scale_mult; + FT_Fixed delta = dim->scale_delta; - first = 0; - mask = hint_masks->masks; - count = hint_masks->num_masks; - for ( ; count > 0; count--, mask++ ) + if ( hint_masks && hint_masks->num_masks > 0 ) { - FT_Vector* vec; - FT_Int count2; - - psh_hint_table_activate_mask( table, mask ); - psh_hint_table_setup_zones( table, scale, delta ); - last = mask->end_point; - - vec = outline->points + first; - count2 = last - first + 1; - for ( ; count2 > 0; count2--, vec++ ) + first = 0; + mask = hint_masks->masks; + count = hint_masks->num_masks; + for ( ; count > 0; count--, mask++ ) { - FT_Pos x, *px; + last = mask->end_point; - px = vertical ? &vec->y : &vec->y; - x = *px; - - *px = psh_hint_table_tune_coord( table, (FT_Int)x ); + if ( last > first ) + { + FT_Vector* vec; + FT_Int count2; + + psh_hint_table_activate_mask( table, mask ); + psh_hint_table_optimize( table, globals, outline, vertical ); + psh_hint_table_setup_zones( table, scale, delta ); + last = mask->end_point; + + vec = outline->points + first; + count2 = last - first; + for ( ; count2 > 0; count2--, vec++ ) + { + FT_Pos x, *px; + + px = vertical ? &vec->y : &vec->x; + x = *px; + + *px = psh_hint_table_tune_coord( table, (FT_Int)x ); + } + } + + first = last; } - - first = (FT_UInt)(last+1); } - } + else /* no hints in this glyph, simply scale the outline */ + { + FT_Vector* vec; + + vec = outline->points; + count = outline->n_points; + + if ( vertical ) + { + for ( ; count > 0; count--, vec++ ) + vec->y = FT_MulFix( vec->y, scale ) + delta; + } + else + { + for ( ; count > 0; count--, vec++ ) + vec->x = FT_MulFix( vec->x, scale ) + delta; + } + } + } + + + + + + + + + + + FT_LOCAL_DEF FT_Error + ps_hints_apply( PS_Hints ps_hints, + FT_Outline* outline, + PSH_Globals globals ) + { + PSH_Hint_TableRec hints; + FT_Error error; + FT_Int dimension; + + for ( dimension = 1; dimension >= 0; dimension-- ) + { + PS_Dimension dim = &ps_hints->dimension[dimension]; + + /* initialise hints table */ + memset( &hints, 0, sizeof(hints) ); + error = psh_hint_table_init( &hints, + &dim->hints, + &dim->masks, + &dim->counters, + ps_hints->memory ); + if (error) goto Exit; + + psh_hint_table_tune_outline( &hints, + outline, + globals, + dimension ); + + psh_hint_table_done( &hints, ps_hints->memory ); + } + + Exit: + return error; + } \ No newline at end of file diff --git a/src/pshinter/pshfit.h b/src/pshinter/pshfit.h index bc83d33ad..f51ec15d5 100644 --- a/src/pshinter/pshfit.h +++ b/src/pshinter/pshfit.h @@ -40,9 +40,9 @@ FT_BEGIN_HEADER } PSH_Hint_Flags; -#define psh_hint_is_active(x) (((x)->flags & PSH_HINT_FLAG_ACTIVE) != 0) -#define psh_hint_activate(x) (x)->flags |= PSH_HINT_FLAG_ACTIVE -#define psh_hint_deactivate(x) (x)->flags &= ~PSH_HINT_FLAG_ACTIVE +#define psh_hint_is_active(x) (((x)->flags & PSH_HINT_FLAG_ACTIVE) != 0) +#define psh_hint_activate(x) (x)->flags |= PSH_HINT_FLAG_ACTIVE +#define psh_hint_deactivate(x) (x)->flags &= ~PSH_HINT_FLAG_ACTIVE typedef struct PSH_HintRec_ { @@ -59,6 +59,9 @@ FT_BEGIN_HEADER } PSH_HintRec; + /* this is an interpolation zone used for strong points */ + /* weak points are interpolated according to their strong */ + /* neighbours.. */ typedef struct PSH_ZoneRec_ { FT_Fixed scale; @@ -85,6 +88,12 @@ FT_BEGIN_HEADER } PSH_Hint_TableRec, *PSH_Hint_Table; + FT_LOCAL FT_Error + ps_hints_apply( PS_Hints ps_hints, + FT_Outline* outline, + PSH_Globals globals ); + + FT_END_HEADER #endif /* __PS_HINTER_FITTER_H__ */ diff --git a/src/pshinter/pshglob.c b/src/pshinter/pshglob.c index 480116db4..edbcc627b 100644 --- a/src/pshinter/pshglob.c +++ b/src/pshinter/pshglob.c @@ -1,4 +1,6 @@ #include +#include FT_FREETYPE_H +#include FT_INTERNAL_OBJECTS_H #include "pshglob.h" /* "simple" ps hinter globals management, inspired from the new auto-hinter */ @@ -11,7 +13,6 @@ /*************************************************************************/ /*************************************************************************/ - /* reset the widths/heights table */ static void psh_globals_reset_widths( PSH_Globals globals, @@ -55,8 +56,9 @@ } } - + + /* org_width is is font units, result in device pixels, 26.6 format */ FT_LOCAL_DEF FT_Pos psh_dimension_snap_width( PSH_Dimension dimension, FT_Int org_width ) @@ -97,7 +99,7 @@ return width; } - + /*************************************************************************/ /*************************************************************************/ @@ -106,7 +108,10 @@ /***** *****/ /*************************************************************************/ /*************************************************************************/ - + + /* re-read blue zones from the original fonts, and store them into out */ + /* private structure. This function re-orders, sanitizes and fuzz-expands */ + /* the zones as well.. */ static void psh_blues_reset_zones( PSH_Blues target, PS_Globals_Blues source, @@ -282,7 +287,7 @@ } - /* reset the blues table */ + /* reset the blues table when the device transform changes */ static void psh_blues_scale_zones( PSH_Blues blues, FT_Fixed scale, @@ -350,7 +355,7 @@ break; } } - + /* lookup stem bottom in bottom zones table */ table = &blues->normal_bottom; count = table->count; @@ -359,7 +364,7 @@ { if ( stem_bot < zone->org_bottom ) break; - + if ( stem_bot <= zone->org_top ) { alignment->align |= PSH_BLUE_ALIGN_BOT; @@ -368,6 +373,7 @@ } } + /*************************************************************************/ /*************************************************************************/ /***** *****/ @@ -424,7 +430,7 @@ globals->dimension[0].scale_delta = 0; globals->dimension[1].scale_mult = 0; globals->dimension[1].scale_delta = 0; - + return 0; } @@ -432,8 +438,8 @@ static FT_Error psh_globals_set_scale( PSH_Globals globals, FT_Fixed x_scale, - FT_Fixed x_delta, FT_Fixed y_scale, + FT_Fixed x_delta, FT_Fixed y_delta ) { PSH_Dimension dim = &globals->dimension[0]; @@ -452,10 +458,13 @@ if ( y_scale != dim->scale_mult || y_delta != dim->scale_delta ) { + dim->scale_mult = y_scale; + dim->scale_delta = y_delta; + psh_globals_scale_widths( globals, 1 ); psh_blues_scale_zones( &globals->blues, y_scale, y_delta ); } - + return 0; } diff --git a/src/pshinter/pshglob.h b/src/pshinter/pshglob.h index 17a9633a2..ce3be476d 100644 --- a/src/pshinter/pshglob.h +++ b/src/pshinter/pshglob.h @@ -20,6 +20,7 @@ #include FT_FREETYPE_H #include FT_INTERNAL_POSTSCRIPT_GLOBALS_H +#include FT_INTERNAL_POSTSCRIPT_HINTS_H FT_BEGIN_HEADER @@ -103,7 +104,7 @@ FT_BEGIN_HEADER PSH_DimensionRec dimension[2]; PSH_BluesRec blues; - } PSH_GlobalsRec, *PSH_Globals; + } PSH_GlobalsRec; typedef enum @@ -113,6 +114,7 @@ FT_BEGIN_HEADER } PSH_Blue_Align; + typedef struct { PSH_Blue_Align align; @@ -121,10 +123,13 @@ FT_BEGIN_HEADER } PSH_Blue_AlignementRec, *PSH_Blue_Alignement; + FT_LOCAL void psh_globals_funcs_init( PSH_Globals_FuncsRec* funcs ); - /* snap a stem width to fitter coordinates */ + + /* snap a stem width to fitter coordinates. org_width is in font units */ + /* result is in device pixels (26.6 format).. */ FT_LOCAL FT_Pos psh_dimension_snap_width( PSH_Dimension dimension, FT_Int org_width ); diff --git a/src/pshinter/pshinter.c b/src/pshinter/pshinter.c index 826ed69ae..592cda3f9 100644 --- a/src/pshinter/pshinter.c +++ b/src/pshinter/pshinter.c @@ -23,5 +23,6 @@ #include "pshglob.c" #include "pshfit.c" #include "pshmod.c" +#include "pshoptim.c" /* END */ diff --git a/src/pshinter/pshmod.c b/src/pshinter/pshmod.c index f62b93cee..2838400e7 100644 --- a/src/pshinter/pshmod.c +++ b/src/pshinter/pshmod.c @@ -19,6 +19,7 @@ #include FT_INTERNAL_OBJECTS_H #include "pshrec.h" + /* the Postscript Hinter module structure */ typedef struct { FT_ModuleRec root; @@ -46,20 +47,18 @@ FT_CALLBACK_DEF FT_Error ps_hinter_init( PS_Hinter_Module module ) { - FT_Memory memory = module->root.memory; + FT_Memory memory = module->root.memory; ps_hints_init( &module->ps_hints, memory ); psh_globals_funcs_init( &module->globals_funcs ); - + t1_hints_funcs_init( &module->t1_funcs ); module->t1_funcs.hints = (T1_Hints) & module->ps_hints; - /* XXX: module->t1_funcs.apply = .... */ - + t2_hints_funcs_init( &module->t2_funcs ); module->t2_funcs.hints = (T2_Hints) & module->ps_hints; - /* XXX: module->t2_funcs.apply = .... */ - + return 0; } @@ -71,6 +70,7 @@ return &((PS_Hinter_Module)module)->globals_funcs; } + /* return Type 1 hints interface */ FT_CALLBACK_DEF T1_Hints_Funcs pshinter_get_t1_funcs( FT_Module module ) @@ -78,6 +78,7 @@ return &((PS_Hinter_Module)module)->t1_funcs; } + /* return Type 2 hints interface */ FT_CALLBACK_DEF T2_Hints_Funcs pshinter_get_t2_funcs( FT_Module module ) @@ -99,7 +100,7 @@ const FT_Module_Class pshinter_module_class = { 0, - sizeof( FT_ModuleRec ), + sizeof( PS_Hinter_ModuleRec ), "pshinter", 0x10000L, 0x20000L, diff --git a/src/pshinter/pshoptim.c b/src/pshinter/pshoptim.c new file mode 100644 index 000000000..ea8dd6037 --- /dev/null +++ b/src/pshinter/pshoptim.c @@ -0,0 +1,30 @@ +#include "pshoptim.h" + + FT_LOCAL_DEF FT_Error + psh_hint_table_optimize( PSH_Hint_Table table, + PSH_Globals globals, + FT_Outline* outline, + FT_Bool vertical ) + { + PSH_Dimension dim = &globals->dimension[vertical]; + FT_Fixed scale = dim->scale_mult; + FT_Fixed delta = dim->scale_delta; + + /* XXXX: for now, we only scale the hints to test all other aspects */ + /* of the Postscript Hinter.. */ + { + PSH_Hint hint; + FT_UInt count; + + for ( count = 0; count < table->num_hints; count++ ) + { + hint = table->sort[count]; + if ( psh_hint_is_active(hint) ) + { + hint->cur_pos = FT_MulFix( hint->org_pos, scale ) + delta; + hint->cur_len = FT_MulFix( hint->org_len, scale ); + } + } + } + return 0; + } diff --git a/src/pshinter/pshoptim.h b/src/pshinter/pshoptim.h new file mode 100644 index 000000000..eb1605e87 --- /dev/null +++ b/src/pshinter/pshoptim.h @@ -0,0 +1,41 @@ +/***************************************************************************/ +/* */ +/* pshoptim.h */ +/* */ +/* Postscript Hints optimiser and grid-fitter */ +/* */ +/* Copyright 2001 by */ +/* David Turner, Robert Wilhelm, and Werner Lemberg. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/* */ +/* process the hints provided by the fitter in order to optimize them */ +/* for the pixel grid, depending on the current glyph outline and */ +/* globals. This is where most of the PS Hinter's intelligence is */ +/* */ +/* XXXX: Until now, only a dummy implementation is provided in order */ +/* to test all other functions of the Postscript Hinter. */ +/* */ +/***************************************************************************/ + +#ifndef __PS_HINTER_OPTIMISER_H__ +#define __PS_HINTER_OPTIMISER_H__ + +#include "pshfit.h" + +FT_BEGIN_HEADER + + FT_LOCAL FT_Error + psh_hint_table_optimize( PSH_Hint_Table table, + PSH_Globals globals, + FT_Outline* outline, + FT_Bool vertical ); + +FT_END_HEADER + +#endif /* __PS_HINTER_OPTIMISER_H__ */ diff --git a/src/pshinter/pshrec.c b/src/pshinter/pshrec.c index fea4ba37a..67184e403 100644 --- a/src/pshinter/pshrec.c +++ b/src/pshinter/pshrec.c @@ -3,6 +3,7 @@ #include FT_INTERNAL_OBJECTS_H #include FT_INTERNAL_DEBUG_H #include "pshrec.h" +#include "pshfit.h" /***********************************************************************/ /***********************************************************************/ @@ -157,8 +158,10 @@ if ( (FT_UInt)index >= mask->num_bits ) { - error = ps_mask_ensure( mask, index, memory ); + error = ps_mask_ensure( mask, index+1, memory ); if (error) goto Exit; + + mask->num_bits = index+1; } p = mask->bytes + (index >> 3); @@ -219,13 +222,13 @@ count = table->num_masks; count++; - if ( count >= table->max_masks ) + if ( count > table->max_masks ) { error = ps_mask_table_ensure( table, count, memory ); if (error) goto Exit; } - mask = table->masks + count; + mask = table->masks + count - 1; mask->num_bits = 0; mask->end_point = 0; table->num_masks = count; @@ -755,7 +758,7 @@ ps_hints_stem( PS_Hints hints, FT_Int dimension, FT_UInt count, - FT_Int* stems ) + FT_Long* stems ) { if ( !hints->error ) { @@ -807,7 +810,7 @@ static void ps_hints_t1stem3( PS_Hints hints, FT_Int dimension, - FT_Int* stems ) + FT_Long* stems ) { FT_Error error = 0; @@ -1017,7 +1020,7 @@ static void t1_hints_stem( T1_Hints hints, FT_Int dimension, - FT_Int* coords ) + FT_Long* coords ) { ps_hints_stem( (PS_Hints)hints, dimension, 1, coords ); } @@ -1033,8 +1036,7 @@ funcs->stem = (T1_Hints_SetStemFunc) t1_hints_stem; funcs->stem3 = (T1_Hints_SetStem3Func) ps_hints_t1stem3; funcs->reset = (T1_Hints_ResetFunc) ps_hints_t1reset; - - /* funcs->apply = .... */ + funcs->apply = (T1_Hints_ApplyFunc) ps_hints_apply; } @@ -1059,7 +1061,7 @@ FT_Int count, FT_Fixed* coords ) { - FT_Int stems[32], n, total = count; + FT_Long stems[32], n, total = count; while (total > 0) { @@ -1085,13 +1087,12 @@ { memset( funcs, 0, sizeof(*funcs) ); - funcs->open = (T2_Hints_OpenFunc) t2_hints_open; - funcs->close = (T2_Hints_CloseFunc) ps_hints_close; - funcs->stems = (T2_Hints_StemsFunc) t2_hints_stems; - funcs->hintmask = (T2_Hints_MaskFunc) ps_hints_t2mask; - funcs->counter = ( T2_Hints_CounterFunc) ps_hints_t2counter; - - /* funcs->apply = .... */ + funcs->open = (T2_Hints_OpenFunc) t2_hints_open; + funcs->close = (T2_Hints_CloseFunc) ps_hints_close; + funcs->stems = (T2_Hints_StemsFunc) t2_hints_stems; + funcs->hintmask = (T2_Hints_MaskFunc) ps_hints_t2mask; + funcs->counter = (T2_Hints_CounterFunc) ps_hints_t2counter; + funcs->apply = (T2_Hints_ApplyFunc) ps_hints_apply; } \ No newline at end of file diff --git a/src/pshinter/pshrec.h b/src/pshinter/pshrec.h index 84c9dfdc1..ae7c2ae0e 100644 --- a/src/pshinter/pshrec.h +++ b/src/pshinter/pshrec.h @@ -2,7 +2,7 @@ /* */ /* pshrec.h */ /* */ -/* Postscript (Type 1/Type 2) hints recorder. */ +/* Postscript (Type1/Type2) hints recorder. */ /* */ /* Copyright 2001 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ @@ -14,7 +14,7 @@ /* understand and accept it fully. */ /* */ /* */ -/* The functions defined here are called from hte Type 1, CID and CFF */ +/* The functions defined here are called from the Type 1, CID and CFF */ /* font drivers to record the hints of a given character/glyph. */ /* */ /* The hints are recorded in a unified format, and are later processed */ @@ -51,6 +51,7 @@ FT_BEGIN_HEADER } PS_Hint_Type; + /* hint flags */ typedef enum { @@ -59,6 +60,7 @@ FT_BEGIN_HEADER } PS_Hint_Flags; + /* hint descriptor */ typedef struct PS_HintRec_ { @@ -132,16 +134,20 @@ FT_BEGIN_HEADER /* */ - FT_LOCAL void - ps_hints_done( PS_Hints hints ); - + /* initialise hints recorder */ FT_LOCAL FT_Error ps_hints_init( PS_Hints hints, FT_Memory memory ); + /* finalize hints recorder */ + FT_LOCAL void + ps_hints_done( PS_Hints hints ); + + /* initialise Type1 hints recorder interface */ FT_LOCAL void t1_hints_funcs_init( T1_Hints_FuncsRec* funcs ); + /* initialise Type2 hints recorder interface */ FT_LOCAL void t2_hints_funcs_init( T2_Hints_FuncsRec* funcs ); diff --git a/src/truetype/ttdriver.c b/src/truetype/ttdriver.c index 16c1ac2e3..af6f82d2f 100644 --- a/src/truetype/ttdriver.c +++ b/src/truetype/ttdriver.c @@ -207,8 +207,8 @@ if ( ( face->header.Flags & 8 ) == 0 ) { /* Compute pixel sizes in 26.6 units */ - dim_x = ( char_width * horz_resolution ) / 72; - dim_y = ( char_height * vert_resolution ) / 72; + dim_x = ( char_width * horz_resolution + 36 ) / 72; + dim_y = ( char_height * vert_resolution + 36 ) / 72; metrics->x_scale = FT_DivFix( dim_x, face->root.units_per_EM ); metrics->y_scale = FT_DivFix( dim_y, face->root.units_per_EM ); diff --git a/src/type1/t1driver.c b/src/type1/t1driver.c index 16e545ff0..12ef9492c 100644 --- a/src/type1/t1driver.c +++ b/src/type1/t1driver.c @@ -281,7 +281,10 @@ const FT_Driver_Class t1_driver_class = { { - ft_module_font_driver | ft_module_driver_scalable, + ft_module_font_driver | + ft_module_driver_scalable | + ft_module_driver_has_hinter, + sizeof( FT_DriverRec ), "type1", @@ -290,8 +293,8 @@ 0, /* format interface */ - (FT_Module_Constructor)T1_Init_Driver, - (FT_Module_Destructor) T1_Done_Driver, + (FT_Module_Constructor)T1_Driver_Init, + (FT_Module_Destructor) T1_Driver_Done, (FT_Module_Requester) Get_Interface, }, @@ -299,15 +302,15 @@ sizeof( T1_SizeRec ), sizeof( T1_GlyphSlotRec ), - (FTDriver_initFace) T1_Init_Face, - (FTDriver_doneFace) T1_Done_Face, - (FTDriver_initSize) T1_Init_Size, - (FTDriver_doneSize) T1_Done_Size, - (FTDriver_initGlyphSlot)T1_Init_GlyphSlot, - (FTDriver_doneGlyphSlot)T1_Done_GlyphSlot, + (FTDriver_initFace) T1_Face_Init, + (FTDriver_doneFace) T1_Face_Done, + (FTDriver_initSize) T1_Size_Init, + (FTDriver_doneSize) T1_Size_Done, + (FTDriver_initGlyphSlot)T1_GlyphSlot_Init, + (FTDriver_doneGlyphSlot)T1_GlyphSlot_Done, - (FTDriver_setCharSizes) 0, - (FTDriver_setPixelSizes)0, + (FTDriver_setCharSizes) T1_Size_Reset, + (FTDriver_setPixelSizes)T1_Size_Reset, (FTDriver_loadGlyph) T1_Load_Glyph, (FTDriver_getCharIndex) Get_Char_Index, diff --git a/src/type1/t1gload.c b/src/type1/t1gload.c index f6a7c7c72..4976c9708 100644 --- a/src/type1/t1gload.c +++ b/src/type1/t1gload.c @@ -93,6 +93,7 @@ 0, /* glyph slot */ (FT_Byte**)type1->glyph_names, face->blend, + 0, T1_Parse_Glyph ); if ( error ) return error; @@ -172,6 +173,7 @@ (FT_GlyphSlot)glyph, (FT_Byte**)type1->glyph_names, face->blend, + FT_BOOL(hinting), T1_Parse_Glyph ); if ( error ) goto Exit; @@ -239,20 +241,15 @@ if ( size && size->root.metrics.y_ppem < 24 ) glyph->root.outline.flags |= ft_outline_high_precision; - /* apply the font matrix */ +/* XXXX: the following needs serious work to work properly with hinting !! */ +#if 0 + /* apply the font matrix, if any.. */ FT_Outline_Transform( &glyph->root.outline, &font_matrix ); FT_Outline_Translate( &glyph->root.outline, font_offset.x, font_offset.y ); - -#if 0 - - glyph->root.outline.second_pass = TRUE; - glyph->root.outline.high_precision = size->root.metrics.y_ppem < 24; - glyph->root.outline.dropout_mode = 2; - -#endif /* 0 */ +#endif if ( ( load_flags & FT_LOAD_NO_SCALE ) == 0 ) { @@ -264,14 +261,13 @@ FT_Fixed y_scale = glyph->y_scale; - /* First of all, scale the points */ - for ( n = cur->n_points; n > 0; n--, vec++ ) - { - vec->x = FT_MulFix( vec->x, x_scale ); - vec->y = FT_MulFix( vec->y, y_scale ); - } - - FT_Outline_Get_CBox( &glyph->root.outline, &cbox ); + /* First of all, scale the points, fi we're not hinting */ + if ( !hinting ) + for ( n = cur->n_points; n > 0; n--, vec++ ) + { + vec->x = FT_MulFix( vec->x, x_scale ); + vec->y = FT_MulFix( vec->y, y_scale ); + } /* Then scale the metrics */ metrics->horiAdvance = FT_MulFix( metrics->horiAdvance, x_scale ); diff --git a/src/type1/t1objs.c b/src/type1/t1objs.c index 5c064e1e2..401c7cb96 100644 --- a/src/type1/t1objs.c +++ b/src/type1/t1objs.c @@ -49,52 +49,77 @@ /* */ /* SIZE FUNCTIONS */ /* */ + /* note that we store the global hints in the size's "internal" root */ + /* field.. */ + /* */ /*************************************************************************/ - FT_LOCAL_DEF - void T1_Done_Size( T1_Size size ) + static PSH_Globals_Funcs + T1_Size_Get_Globals( T1_Size size ) { - if ( size->size_hints ) - { - PSHinter_Interface* pshinter; - PSH_Globals_Funcs funcs; - T1_Face face; + T1_Face face = (T1_Face) size->root.face; + PSHinter_Interface* pshinter = face->pshinter; + FT_Module module; - face = (T1_Face) size->root.face; - pshinter = face->pshinter; - funcs = pshinter->get_globals_funcs( (FT_Module) face->root.driver ); - funcs->destroy( (PSH_Globals) size->size_hints ); - - size->size_hints = 0; - } + module = FT_Get_Module( size->root.face->driver->root.library, "pshinter" ); + return ( module && pshinter && pshinter->get_globals_funcs ) + ? pshinter->get_globals_funcs( module ) + : 0 ; } FT_LOCAL_DEF - FT_Error T1_Init_Size( T1_Size size ) + void T1_Size_Done( T1_Size size ) { - PSHinter_Interface* pshinter; - T1_Face face; - FT_Error error = 0; - - face = (T1_Face) size->root.face; - pshinter = face->pshinter; - if ( pshinter && pshinter->get_globals_funcs ) + if ( size->root.internal ) { - PSH_Globals_Funcs funcs; - PSH_Globals globals; - - funcs = pshinter->get_globals_funcs( (FT_Module) face->root.driver ); + PSH_Globals_Funcs funcs; + + funcs = T1_Size_Get_Globals(size); if (funcs) - { - error = funcs->create( face->root.memory, &globals ); - if (!error) - size->size_hints = globals; - } + funcs->destroy( (PSH_Globals) size->root.internal ); + + size->root.internal = 0; } + } + + + + FT_LOCAL_DEF + FT_Error T1_Size_Init( T1_Size size ) + { + FT_Error error = 0; + PSH_Globals_Funcs funcs = T1_Size_Get_Globals( size ); + + if ( funcs ) + { + PSH_Globals globals; + + error = funcs->create( size->root.face->memory, &globals ); + if (!error) + size->root.internal = (FT_Size_Internal)(void*) globals; + } + return error; } + + + FT_LOCAL_DEF + FT_Error T1_Size_Reset( T1_Size size ) + { + PSH_Globals_Funcs funcs = T1_Size_Get_Globals(size); + FT_Error error = 0; + + if (funcs) + error = funcs->set_scale( (PSH_Globals) size->root.internal, + size->root.metrics.x_scale, + size->root.metrics.y_scale, + 0, 0 ); + return error; + } + + /*************************************************************************/ /* */ /* SLOT FUNCTIONS */ @@ -102,14 +127,14 @@ /*************************************************************************/ FT_LOCAL_DEF void - T1_Done_GlyphSlot( T1_GlyphSlot slot ) + T1_GlyphSlot_Done( T1_GlyphSlot slot ) { slot->root.internal->glyph_hints = 0; } FT_LOCAL_DEF FT_Error - T1_Init_GlyphSlot( T1_GlyphSlot slot ) + T1_GlyphSlot_Init( T1_GlyphSlot slot ) { T1_Face face; PSHinter_Interface* pshinter; @@ -118,10 +143,16 @@ pshinter = face->pshinter; if (pshinter) { - T1_Hints_Funcs funcs; + FT_Module module; - funcs = pshinter->get_t1_funcs( (FT_Module)face->root.driver ); - slot->root.internal->glyph_hints = (void*)funcs; + module = FT_Get_Module( slot->root.face->driver->root.library, "pshinter" ); + if (module) + { + T1_Hints_Funcs funcs; + + funcs = pshinter->get_t1_funcs( module ); + slot->root.internal->glyph_hints = (void*)funcs; + } } return 0; } @@ -137,7 +168,7 @@ /*************************************************************************/ /* */ /* */ - /* T1_Done_Face */ + /* T1_Face_Done */ /* */ /* */ /* The face object destructor. */ @@ -146,7 +177,7 @@ /* face :: A typeless pointer to the face object to destroy. */ /* */ FT_LOCAL_DEF - void T1_Done_Face( T1_Face face ) + void T1_Face_Done( T1_Face face ) { FT_Memory memory; T1_Font* type1 = &face->type1; @@ -210,7 +241,7 @@ /*************************************************************************/ /* */ /* */ - /* T1_Init_Face */ + /* T1_Face_Init */ /* */ /* */ /* The face object constructor. */ @@ -231,7 +262,7 @@ /* FreeType error code. 0 means success. */ /* */ FT_LOCAL_DEF - FT_Error T1_Init_Face( FT_Stream stream, + FT_Error T1_Face_Init( FT_Stream stream, T1_Face face, FT_Int face_index, FT_Int num_params, @@ -267,7 +298,7 @@ face->psaux = psaux; } - + pshinter = (PSHinter_Interface*)face->pshinter; if ( !pshinter ) { @@ -289,7 +320,7 @@ /* check the face index */ if ( face_index != 0 ) { - FT_ERROR(( "T1_Init_Face: invalid face index\n" )); + FT_ERROR(( "T1_Face_Init: invalid face index\n" )); error = T1_Err_Invalid_Argument; goto Exit; } @@ -468,7 +499,7 @@ /*************************************************************************/ /* */ /* */ - /* T1_Init_Driver */ + /* T1_Driver_Init */ /* */ /* */ /* Initializes a given Type 1 driver object. */ @@ -480,7 +511,7 @@ /* FreeType error code. 0 means success. */ /* */ FT_LOCAL_DEF - FT_Error T1_Init_Driver( T1_Driver driver ) + FT_Error T1_Driver_Init( T1_Driver driver ) { FT_UNUSED( driver ); @@ -491,7 +522,7 @@ /*************************************************************************/ /* */ /* */ - /* T1_Done_Driver */ + /* T1_Driver_Done */ /* */ /* */ /* Finalizes a given Type 1 driver. */ @@ -500,7 +531,7 @@ /* driver :: A handle to the target Type 1 driver. */ /* */ FT_LOCAL_DEF - void T1_Done_Driver( T1_Driver driver ) + void T1_Driver_Done( T1_Driver driver ) { FT_UNUSED( driver ); } diff --git a/src/type1/t1objs.h b/src/type1/t1objs.h index c736868bf..59ad2df62 100644 --- a/src/type1/t1objs.h +++ b/src/type1/t1objs.h @@ -101,11 +101,19 @@ FT_BEGIN_HEADER typedef struct T1_SizeRec_ { FT_SizeRec root; - void* size_hints; /* defined for hinting engines */ } T1_SizeRec; + FT_LOCAL + void T1_Size_Done( T1_Size size ); + + FT_LOCAL + FT_Error T1_Size_Reset( T1_Size size ); + + FT_LOCAL + FT_Error T1_Size_Init( T1_Size size ); + /*************************************************************************/ /* */ /* */ @@ -131,32 +139,32 @@ FT_BEGIN_HEADER FT_LOCAL - FT_Error T1_Init_Face( FT_Stream stream, + FT_Error T1_Face_Init( FT_Stream stream, T1_Face face, FT_Int face_index, FT_Int num_params, FT_Parameter* params ); FT_LOCAL - void T1_Done_Face( T1_Face face ); + void T1_Face_Done( T1_Face face ); FT_LOCAL - FT_Error T1_Init_Size( T1_Size size ); + FT_Error T1_Size_Init( T1_Size size ); FT_LOCAL - void T1_Done_Size( T1_Size size ); + void T1_Size_Done( T1_Size size ); FT_LOCAL - FT_Error T1_Init_GlyphSlot( T1_GlyphSlot slot ); + FT_Error T1_GlyphSlot_Init( T1_GlyphSlot slot ); FT_LOCAL - void T1_Done_GlyphSlot( T1_GlyphSlot slot ); + void T1_GlyphSlot_Done( T1_GlyphSlot slot ); FT_LOCAL - FT_Error T1_Init_Driver( T1_Driver driver ); + FT_Error T1_Driver_Init( T1_Driver driver ); FT_LOCAL - void T1_Done_Driver( T1_Driver driver ); + void T1_Driver_Done( T1_Driver driver ); FT_END_HEADER