diff options
Diffstat (limited to 'src/truetype/ttgload.c')
-rw-r--r-- | src/truetype/ttgload.c | 135 |
1 files changed, 77 insertions, 58 deletions
diff --git a/src/truetype/ttgload.c b/src/truetype/ttgload.c index ae476a4..ddcea97 100644 --- a/src/truetype/ttgload.c +++ b/src/truetype/ttgload.c @@ -4,7 +4,7 @@ /* */ /* TrueType Glyph Loader (body). */ /* */ -/* Copyright 1996-2001, 2002, 2003, 2004, 2005, 2006, 2007 by */ +/* Copyright 1996-2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -69,12 +69,12 @@ /* `check' is true, take care of monospaced fonts by returning the */ /* advance width maximum. */ /* */ - static void - Get_HMetrics( TT_Face face, - FT_UInt idx, - FT_Bool check, - FT_Short* lsb, - FT_UShort* aw ) + FT_LOCAL_DEF(void) + TT_Get_HMetrics( TT_Face face, + FT_UInt idx, + FT_Bool check, + FT_Short* lsb, + FT_UShort* aw ) { ( (SFNT_Service)face->sfnt )->get_metrics( face, 0, idx, lsb, aw ); @@ -96,12 +96,12 @@ /* The monospace `check' is probably not meaningful here, but we leave */ /* it in for a consistent interface. */ /* */ - static void - Get_VMetrics( TT_Face face, - FT_UInt idx, - FT_Bool check, - FT_Short* tsb, - FT_UShort* ah ) + FT_LOCAL_DEF(void) + TT_Get_VMetrics( TT_Face face, + FT_UInt idx, + FT_Bool check, + FT_Short* tsb, + FT_UShort* ah ) { FT_UNUSED( check ); @@ -267,7 +267,11 @@ if ( n_contours >= 0xFFF || p + ( n_contours + 1 ) * 2 > limit ) goto Invalid_Outline; - cont[0] = prev_cont = FT_NEXT_USHORT( p ); + prev_cont = FT_NEXT_USHORT( p ); + + if ( n_contours > 0 ) + cont[0] = prev_cont; + for ( cont++; cont < cont_limit; cont++ ) { cont[0] = FT_NEXT_USHORT( p ); @@ -639,6 +643,25 @@ /* save original point position in org */ if ( n_ins > 0 ) FT_ARRAY_COPY( zone->org, zone->cur, zone->n_points ); + /* Reset graphics state. */ + loader->exec->GS = ((TT_Size)loader->size)->GS; + + /* XXX: UNDOCUMENTED! Hinting instructions of a composite glyph */ + /* completely refer to the (already) hinted subglyphs. */ + if ( is_composite ) + { + loader->exec->metrics.x_scale = 1 << 16; + loader->exec->metrics.y_scale = 1 << 16; + + FT_ARRAY_COPY( zone->orus, zone->cur, zone->n_points ); + } + else + { + loader->exec->metrics.x_scale = + ((TT_Size)loader->size)->metrics.x_scale; + loader->exec->metrics.y_scale = + ((TT_Size)loader->size)->metrics.y_scale; + } #endif /* round pp2 and pp4 */ @@ -702,7 +725,7 @@ FT_GlyphLoader gloader = loader->gloader; FT_Error error = TT_Err_Ok; FT_Outline* outline; - FT_UInt n_points; + FT_Int n_points; outline = &gloader->current.outline; @@ -729,7 +752,7 @@ /* Deltas apply to the unscaled data. */ FT_Vector* deltas; FT_Memory memory = loader->face->memory; - FT_UInt i; + FT_Int i; error = TT_Vary_Get_Glyph_Deltas( (TT_Face)(loader->face), @@ -1084,7 +1107,10 @@ #endif - if ( recurse_count > face->max_profile.maxComponentDepth ) + /* some fonts have an incorrect value of `maxComponentDepth', */ + /* thus we allow depth 1 to catch the majority of them */ + if ( recurse_count > 1 && + recurse_count > face->max_profile.maxComponentDepth ) { error = TT_Err_Invalid_Composite; goto Exit; @@ -1116,16 +1142,16 @@ FT_UShort advance_width = 0, advance_height = 0; - Get_HMetrics( face, glyph_index, - (FT_Bool)!( loader->load_flags & - FT_LOAD_IGNORE_GLOBAL_ADVANCE_WIDTH ), - &left_bearing, - &advance_width ); - Get_VMetrics( face, glyph_index, - (FT_Bool)!( loader->load_flags & - FT_LOAD_IGNORE_GLOBAL_ADVANCE_WIDTH ), - &top_bearing, - &advance_height ); + TT_Get_HMetrics( face, glyph_index, + (FT_Bool)!( loader->load_flags & + FT_LOAD_IGNORE_GLOBAL_ADVANCE_WIDTH ), + &left_bearing, + &advance_width ); + TT_Get_VMetrics( face, glyph_index, + (FT_Bool)!( loader->load_flags & + FT_LOAD_IGNORE_GLOBAL_ADVANCE_WIDTH ), + &top_bearing, + &advance_height ); #ifdef FT_CONFIG_OPTION_INCREMENTAL @@ -1214,10 +1240,24 @@ offset = tt_face_get_location( face, glyph_index, (FT_UInt*)&loader->byte_len ); - if ( loader->byte_len == 0 ) + if ( loader->byte_len > 0 ) + { + error = face->access_glyph_frame( loader, glyph_index, + loader->glyf_offset + offset, + loader->byte_len ); + if ( error ) + goto Exit; + + opened_frame = 1; + + /* read first glyph header */ + error = face->read_glyph_header( loader ); + if ( error ) + goto Exit; + } + + if ( loader->byte_len == 0 || loader->n_contours == 0 ) { - /* as described by Frederic Loyer, these are spaces or */ - /* the unknown glyph. */ loader->bbox.xMin = 0; loader->bbox.xMax = 0; loader->bbox.yMin = 0; @@ -1260,19 +1300,6 @@ goto Exit; } - error = face->access_glyph_frame( loader, glyph_index, - loader->glyf_offset + offset, - loader->byte_len ); - if ( error ) - goto Exit; - - opened_frame = 1; - - /* read first glyph header */ - error = face->read_glyph_header( loader ); - if ( error ) - goto Exit; - TT_LOADER_SET_PP( loader ); /***********************************************************************/ @@ -1281,7 +1308,7 @@ /* if it is a simple glyph, load it */ - if ( loader->n_contours >= 0 ) + if ( loader->n_contours > 0 ) { error = face->read_simple_glyph( loader ); if ( error ) @@ -1390,20 +1417,15 @@ /*********************************************************************/ { - FT_UInt n, num_base_points; - FT_SubGlyph subglyph = 0; - - FT_UInt num_points = start_point; - FT_UInt num_subglyphs = gloader->current.num_subglyphs; - FT_UInt num_base_subgs = gloader->base.num_subglyphs; - - FT_Stream old_stream = loader->stream; + FT_UInt n, num_base_points; + FT_SubGlyph subglyph = 0; - TT_GraphicsState saved_GS; + FT_UInt num_points = start_point; + FT_UInt num_subglyphs = gloader->current.num_subglyphs; + FT_UInt num_base_subgs = gloader->base.num_subglyphs; + FT_Stream old_stream = loader->stream; - if ( loader->exec ) - saved_GS = loader->exec->GS; FT_GlyphLoader_Add( gloader ); @@ -1413,9 +1435,6 @@ FT_Vector pp[4]; - /* reinitialize graphics state */ - if ( loader->exec ) - loader->exec->GS = saved_GS; /* Each time we call load_truetype_glyph in this loop, the */ /* value of `gloader.base.subglyphs' can change due to table */ |