diff options
author | Jungshik Shin <jungshik@google.com> | 2016-01-15 16:18:25 -0800 |
---|---|---|
committer | The Android Automerger <android-build@google.com> | 2016-02-24 13:20:13 -0800 |
commit | f720f0dbcf012d6c984dbbefa0875ef9840458c6 (patch) | |
tree | bdb1068e64623c623100071dc586117aba4a2417 /src/truetype | |
parent | ec62c527eb34ee4481a0153ceb42dfd35d7e1d26 (diff) | |
download | android_external_freetype-f720f0dbcf012d6c984dbbefa0875ef9840458c6.tar.gz android_external_freetype-f720f0dbcf012d6c984dbbefa0875ef9840458c6.tar.bz2 android_external_freetype-f720f0dbcf012d6c984dbbefa0875ef9840458c6.zip |
[DO NOT MERGE] Update FreeType to 2.6.2 + update from 2.6.0
1. Update to a512b0fe7a (several patches past 2.6.2).
Major changes include
- stem-darkening is OFF for CFF fonts by default
- general code tightening
- header file location is back to include/freetype (used be include/)
2. A bit more details are added to README.android for the reference.
This CL requires a pdfium change (the way it includes FT header
files : https://googleplex-android-review.git.corp.google.com/#/c/846889
An AOSP master CL
(https://android-review.googlesource.com/#/c/196504/) is ported
to mnc-dev.
Bug: 24296662
Change-Id: Iec6784838d89098f332e6d1ed79663efd91a8441
Signed-off-by: Jungshik Shin <jungshik@google.com>
Diffstat (limited to 'src/truetype')
-rw-r--r-- | src/truetype/ttdriver.c | 51 | ||||
-rw-r--r-- | src/truetype/ttgload.c | 216 | ||||
-rw-r--r-- | src/truetype/ttgxvar.c | 147 | ||||
-rw-r--r-- | src/truetype/ttgxvar.h | 2 | ||||
-rw-r--r-- | src/truetype/ttinterp.c | 55 | ||||
-rw-r--r-- | src/truetype/ttobjs.c | 69 | ||||
-rw-r--r-- | src/truetype/ttobjs.h | 11 | ||||
-rw-r--r-- | src/truetype/ttpic.h | 10 | ||||
-rw-r--r-- | src/truetype/ttpload.c | 26 | ||||
-rw-r--r-- | src/truetype/ttsubpix.c | 2 |
10 files changed, 372 insertions, 217 deletions
diff --git a/src/truetype/ttdriver.c b/src/truetype/ttdriver.c index 08b30c9..1ba71f0 100644 --- a/src/truetype/ttdriver.c +++ b/src/truetype/ttdriver.c @@ -117,8 +117,8 @@ FT_DEFINE_SERVICE_PROPERTIESREC( tt_service_properties, - (FT_Properties_SetFunc)tt_property_set, - (FT_Properties_GetFunc)tt_property_get ) + (FT_Properties_SetFunc)tt_property_set, /* set_property */ + (FT_Properties_GetFunc)tt_property_get ) /* get_property */ /*************************************************************************/ @@ -417,13 +417,14 @@ #ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT FT_DEFINE_SERVICE_MULTIMASTERSREC( tt_service_gx_multi_masters, - (FT_Get_MM_Func) NULL, - (FT_Set_MM_Design_Func) NULL, - (FT_Set_MM_Blend_Func) TT_Set_MM_Blend, - (FT_Get_MM_Var_Func) TT_Get_MM_Var, - (FT_Set_Var_Design_Func)TT_Set_Var_Design ) + (FT_Get_MM_Func) NULL, /* get_mm */ + (FT_Set_MM_Design_Func) NULL, /* set_mm_design */ + (FT_Set_MM_Blend_Func) TT_Set_MM_Blend, /* set_mm_blend */ + (FT_Get_MM_Var_Func) TT_Get_MM_Var, /* get_mm_var */ + (FT_Set_Var_Design_Func)TT_Set_Var_Design ) /* set_var_design */ #endif + static const FT_Service_TrueTypeEngineRec tt_service_truetype_engine = { #ifdef TT_USE_BYTECODE_INTERPRETER @@ -441,9 +442,11 @@ #endif /* TT_USE_BYTECODE_INTERPRETER */ }; + FT_DEFINE_SERVICE_TTGLYFREC( tt_service_truetype_glyf, - (TT_Glyf_GetLocationFunc)tt_face_get_location ) + (TT_Glyf_GetLocationFunc)tt_face_get_location ) /* get_location */ + #ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT FT_DEFINE_SERVICEDESCREC5( @@ -534,31 +537,31 @@ 0x10000L, /* driver version == 1.0 */ 0x20000L, /* driver requires FreeType 2.0 or above */ - (void*)0, /* driver specific interface */ + 0, /* module-specific interface */ - tt_driver_init, - tt_driver_done, - tt_get_interface, + tt_driver_init, /* FT_Module_Constructor module_init */ + tt_driver_done, /* FT_Module_Destructor module_done */ + tt_get_interface, /* FT_Module_Requester get_interface */ sizeof ( TT_FaceRec ), sizeof ( TT_SizeRec ), sizeof ( FT_GlyphSlotRec ), - tt_face_init, - tt_face_done, - tt_size_init, - tt_size_done, - tt_slot_init, - 0, /* FT_Slot_DoneFunc */ + tt_face_init, /* FT_Face_InitFunc init_face */ + tt_face_done, /* FT_Face_DoneFunc done_face */ + tt_size_init, /* FT_Size_InitFunc init_size */ + tt_size_done, /* FT_Size_DoneFunc done_size */ + tt_slot_init, /* FT_Slot_InitFunc init_slot */ + 0, /* FT_Slot_DoneFunc done_slot */ - tt_glyph_load, + tt_glyph_load, /* FT_Slot_LoadFunc load_glyph */ - tt_get_kerning, - 0, /* FT_Face_AttachFunc */ - tt_get_advances, + tt_get_kerning, /* FT_Face_GetKerningFunc get_kerning */ + 0, /* FT_Face_AttachFunc attach_file */ + tt_get_advances, /* FT_Face_GetAdvancesFunc get_advances */ - tt_size_request, - TT_SIZE_SELECT + tt_size_request, /* FT_Size_RequestFunc request_size */ + TT_SIZE_SELECT /* FT_Size_SelectFunc select_size */ ) diff --git a/src/truetype/ttgload.c b/src/truetype/ttgload.c index e1acd69..d94fc92 100644 --- a/src/truetype/ttgload.c +++ b/src/truetype/ttgload.c @@ -24,6 +24,7 @@ #include FT_TRUETYPE_TAGS_H #include FT_OUTLINE_H #include FT_TRUETYPE_DRIVER_H +#include FT_LIST_H #include "ttgload.h" #include "ttpload.h" @@ -120,7 +121,7 @@ tt_get_metrics( TT_Loader loader, FT_UInt glyph_index ) { - TT_Face face = (TT_Face)loader->face; + TT_Face face = loader->face; #ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING TT_Driver driver = (TT_Driver)FT_FACE_DRIVER( face ); #endif @@ -182,7 +183,7 @@ tt_get_metrics_incr_overrides( TT_Loader loader, FT_UInt glyph_index ) { - TT_Face face = (TT_Face)loader->face; + TT_Face face = loader->face; FT_Short left_bearing = 0, top_bearing = 0; FT_UShort advance_width = 0, advance_height = 0; @@ -250,29 +251,6 @@ /*************************************************************************/ /* */ - /* Translates an array of coordinates. */ - /* */ - static void - translate_array( FT_UInt n, - FT_Vector* coords, - FT_Pos delta_x, - FT_Pos delta_y ) - { - FT_UInt k; - - - if ( delta_x ) - for ( k = 0; k < n; k++ ) - coords[k].x += delta_x; - - if ( delta_y ) - for ( k = 0; k < n; k++ ) - coords[k].y += delta_y; - } - - - /*************************************************************************/ - /* */ /* The following functions are used by default with TrueType fonts. */ /* However, they can be replaced by alternatives if we need to support */ /* TrueType-compressed formats (like MicroType) in the future. */ @@ -656,20 +634,20 @@ if ( subglyph->flags & WE_HAVE_A_SCALE ) { - xx = (FT_Fixed)FT_NEXT_SHORT( p ) << 2; + xx = (FT_Fixed)FT_NEXT_SHORT( p ) * 4; yy = xx; } else if ( subglyph->flags & WE_HAVE_AN_XY_SCALE ) { - xx = (FT_Fixed)FT_NEXT_SHORT( p ) << 2; - yy = (FT_Fixed)FT_NEXT_SHORT( p ) << 2; + xx = (FT_Fixed)FT_NEXT_SHORT( p ) * 4; + yy = (FT_Fixed)FT_NEXT_SHORT( p ) * 4; } else if ( subglyph->flags & WE_HAVE_A_2X2 ) { - xx = (FT_Fixed)FT_NEXT_SHORT( p ) << 2; - yx = (FT_Fixed)FT_NEXT_SHORT( p ) << 2; - xy = (FT_Fixed)FT_NEXT_SHORT( p ) << 2; - yy = (FT_Fixed)FT_NEXT_SHORT( p ) << 2; + xx = (FT_Fixed)FT_NEXT_SHORT( p ) * 4; + yx = (FT_Fixed)FT_NEXT_SHORT( p ) * 4; + xy = (FT_Fixed)FT_NEXT_SHORT( p ) * 4; + yy = (FT_Fixed)FT_NEXT_SHORT( p ) * 4; } subglyph->transform.xx = xx; @@ -682,6 +660,7 @@ } while ( subglyph->flags & MORE_COMPONENTS ); gloader->current.num_subglyphs = num_subglyphs; + FT_TRACE5(( " %d components\n", num_subglyphs )); #ifdef TT_USE_BYTECODE_INTERPRETER @@ -754,7 +733,7 @@ FT_Bool is_composite ) { #ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING - TT_Face face = (TT_Face)loader->face; + TT_Face face = loader->face; TT_Driver driver = (TT_Driver)FT_FACE_DRIVER( face ); #endif @@ -781,7 +760,7 @@ FT_ARRAY_COPY( zone->org, zone->cur, zone->n_points ); /* Reset graphics state. */ - loader->exec->GS = ((TT_Size)loader->size)->GS; + loader->exec->GS = loader->size->GS; /* XXX: UNDOCUMENTED! Hinting instructions of a composite glyph */ /* completely refer to the (already) hinted subglyphs. */ @@ -794,10 +773,8 @@ } 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; + loader->exec->metrics.x_scale = loader->size->metrics.x_scale; + loader->exec->metrics.y_scale = loader->size->metrics.y_scale; } #endif @@ -897,13 +874,13 @@ #ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT - if ( ((TT_Face)loader->face)->doblend ) + if ( loader->face->doblend ) { /* Deltas apply to the unscaled data. */ - error = TT_Vary_Apply_Glyph_Deltas( (TT_Face)(loader->face), - loader->glyph_index, - outline, - (FT_UInt)n_points ); + error = TT_Vary_Apply_Glyph_Deltas( loader->face, + loader->glyph_index, + outline, + (FT_UInt)n_points ); if ( error ) return error; } @@ -920,7 +897,7 @@ { #ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING - TT_Face face = (TT_Face)loader->face; + TT_Face face = loader->face; TT_Driver driver = (TT_Driver)FT_FACE_DRIVER( face ); FT_String* family = face->root.family_name; @@ -953,9 +930,9 @@ if ( ( loader->load_flags & FT_LOAD_NO_SCALE ) == 0 || x_scale_factor != 1000 ) { - x_scale = FT_MulDiv( ((TT_Size)loader->size)->metrics.x_scale, + x_scale = FT_MulDiv( loader->size->metrics.x_scale, (FT_Long)x_scale_factor, 1000 ); - y_scale = ((TT_Size)loader->size)->metrics.y_scale; + y_scale = loader->size->metrics.y_scale; /* compensate for any scaling by de/emboldening; */ /* the amount was determined via experimentation */ @@ -975,8 +952,8 @@ /* scale the glyph */ if ( ( loader->load_flags & FT_LOAD_NO_SCALE ) == 0 ) { - x_scale = ((TT_Size)loader->size)->metrics.x_scale; - y_scale = ((TT_Size)loader->size)->metrics.y_scale; + x_scale = loader->size->metrics.x_scale; + y_scale = loader->size->metrics.y_scale; do_scale = TRUE; } @@ -1023,30 +1000,29 @@ FT_UInt start_point, FT_UInt num_base_points ) { - FT_GlyphLoader gloader = loader->gloader; - FT_Vector* base_vec = gloader->base.outline.points; - FT_UInt num_points = (FT_UInt)gloader->base.outline.n_points; + FT_GlyphLoader gloader = loader->gloader; + FT_Outline current; FT_Bool have_scale; FT_Pos x, y; + current.points = gloader->base.outline.points + + num_base_points; + current.n_points = gloader->base.outline.n_points - + (short)num_base_points; + have_scale = FT_BOOL( subglyph->flags & ( WE_HAVE_A_SCALE | WE_HAVE_AN_XY_SCALE | WE_HAVE_A_2X2 ) ); /* perform the transform required for this subglyph */ if ( have_scale ) - { - FT_UInt i; - - - for ( i = num_base_points; i < num_points; i++ ) - FT_Vector_Transform( base_vec + i, &subglyph->transform ); - } + FT_Outline_Transform( ¤t, &subglyph->transform ); /* get offset */ if ( !( subglyph->flags & ARGS_ARE_XY_VALUES ) ) { + FT_UInt num_points = (FT_UInt)gloader->base.outline.n_points; FT_UInt k = (FT_UInt)subglyph->arg1; FT_UInt l = (FT_UInt)subglyph->arg2; FT_Vector* p1; @@ -1135,8 +1111,8 @@ if ( !( loader->load_flags & FT_LOAD_NO_SCALE ) ) { - FT_Fixed x_scale = ((TT_Size)loader->size)->metrics.x_scale; - FT_Fixed y_scale = ((TT_Size)loader->size)->metrics.y_scale; + FT_Fixed x_scale = loader->size->metrics.x_scale; + FT_Fixed y_scale = loader->size->metrics.y_scale; x = FT_MulFix( x, x_scale ); @@ -1151,9 +1127,7 @@ } if ( x || y ) - translate_array( num_points - num_base_points, - base_vec + num_base_points, - x, y ); + FT_Outline_Translate( ¤t, x, y ); return FT_Err_Ok; } @@ -1215,7 +1189,7 @@ FT_TRACE5(( " Instructions size = %d\n", n_ins )); /* check it */ - max_ins = ((TT_Face)loader->face)->max_profile.maxSizeOfInstructions; + max_ins = loader->face->max_profile.maxSizeOfInstructions; if ( n_ins > max_ins ) { /* don't trust `maxSizeOfInstructions'; */ @@ -1412,7 +1386,7 @@ FT_Error error = FT_Err_Ok; FT_Fixed x_scale, y_scale; FT_ULong offset; - TT_Face face = (TT_Face)loader->face; + TT_Face face = loader->face; FT_GlyphLoader gloader = loader->gloader; FT_Bool opened_frame = 0; @@ -1423,6 +1397,11 @@ #endif +#ifdef FT_DEBUG_LEVEL_TRACE + if ( recurse_count ) + FT_TRACE5(( " nesting level: %d\n", recurse_count )); +#endif + /* some fonts have an incorrect value of `maxComponentDepth', */ /* thus we allow depth 1 to catch the majority of them */ if ( recurse_count > 1 && @@ -1445,8 +1424,8 @@ if ( ( loader->load_flags & FT_LOAD_NO_SCALE ) == 0 ) { - x_scale = ((TT_Size)loader->size)->metrics.x_scale; - y_scale = ((TT_Size)loader->size)->metrics.y_scale; + x_scale = loader->size->metrics.x_scale; + y_scale = loader->size->metrics.y_scale; } else { @@ -1552,7 +1531,7 @@ #ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT - if ( ((TT_Face)(loader->face))->doblend ) + if ( loader->face->doblend ) { /* a small outline structure with four elements for */ /* communication with `TT_Vary_Apply_Glyph_Deltas' */ @@ -1579,10 +1558,10 @@ outline.contours = contours; /* this must be done before scaling */ - error = TT_Vary_Apply_Glyph_Deltas( (TT_Face)(loader->face), - glyph_index, - &outline, - outline.n_points ); + error = TT_Vary_Apply_Glyph_Deltas( loader->face, + glyph_index, + &outline, + (FT_UInt)outline.n_points ); if ( error ) goto Exit; @@ -1655,11 +1634,40 @@ /* otherwise, load a composite! */ else if ( loader->n_contours == -1 ) { + FT_Memory memory = face->root.memory; + FT_UInt start_point; FT_UInt start_contour; FT_ULong ins_pos; /* position of composite instructions, if any */ + /* + * We store the glyph index directly in the `node->data' pointer, + * following the glib solution (cf. macro `GUINT_TO_POINTER') with a + * double cast to make this portable. Note, however, that this needs + * pointers with a width of at least 32 bits. + */ + + /* check whether we already have a composite glyph with this index */ + if ( FT_List_Find( &loader->composites, + (void*)(unsigned long)glyph_index ) ) + { + FT_TRACE1(( "TT_Load_Composite_Glyph:" + " infinite recursion detected\n" )); + error = FT_THROW( Invalid_Composite ); + goto Exit; + } + else + { + FT_ListNode node = NULL; + + + if ( FT_NEW( node ) ) + goto Exit; + node->data = (void*)(unsigned long)glyph_index; + FT_List_Add( &loader->composites, node ); + } + start_point = (FT_UInt)gloader->base.outline.n_points; start_contour = (FT_UInt)gloader->base.outline.n_contours; @@ -1679,7 +1687,7 @@ if ( face->doblend ) { - FT_UInt i, limit; + short i, limit; FT_SubGlyph subglyph; FT_Outline outline; @@ -1687,14 +1695,12 @@ char* tags = NULL; short* contours = NULL; - FT_Memory memory = face->root.memory; - - limit = gloader->current.num_subglyphs; + limit = (short)gloader->current.num_subglyphs; /* construct an outline structure for */ /* communication with `TT_Vary_Apply_Glyph_Deltas' */ - outline.n_points = gloader->current.num_subglyphs + 4; + outline.n_points = (short)( gloader->current.num_subglyphs + 4 ); outline.n_contours = outline.n_points; if ( FT_NEW_ARRAY( points, outline.n_points ) || @@ -1702,7 +1708,7 @@ FT_NEW_ARRAY( contours, outline.n_points ) ) goto Exit1; - subglyph = gloader->current.subglyphs + gloader->base.num_subglyphs; + subglyph = gloader->current.subglyphs; for ( i = 0; i < limit; i++, subglyph++ ) { @@ -1748,10 +1754,10 @@ face, glyph_index, &outline, - outline.n_points ) ) != 0 ) + (FT_UInt)outline.n_points ) ) != 0 ) goto Exit1; - subglyph = gloader->current.subglyphs + gloader->base.num_subglyphs; + subglyph = gloader->current.subglyphs; for ( i = 0; i < limit; i++, subglyph++ ) { @@ -1935,7 +1941,7 @@ compute_glyph_metrics( TT_Loader loader, FT_UInt glyph_index ) { - TT_Face face = (TT_Face)loader->face; + TT_Face face = loader->face; #ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING TT_Driver driver = (TT_Driver)FT_FACE_DRIVER( face ); #endif @@ -1943,7 +1949,7 @@ FT_BBox bbox; FT_Fixed y_scale; TT_GlyphSlot glyph = loader->glyph; - TT_Size size = (TT_Size)loader->size; + TT_Size size = loader->size; y_scale = 0x10000L; @@ -1964,8 +1970,10 @@ glyph->metrics.horiAdvance = loader->pp2.x - loader->pp1.x; /* adjust advance width to the value contained in the hdmx table */ - if ( !face->postscript.isFixedPitch && - IS_HINTED( loader->load_flags ) ) + /* unless FT_LOAD_COMPUTE_METRICS is set */ + if ( !face->postscript.isFixedPitch && + IS_HINTED( loader->load_flags ) && + !( loader->load_flags & FT_LOAD_COMPUTE_METRICS ) ) { FT_Byte* widthp; @@ -1988,7 +1996,7 @@ ( ( ignore_x_mode && loader->exec->compatible_widths ) || !ignore_x_mode || SPH_OPTION_BITMAP_WIDTHS ) ) - glyph->metrics.horiAdvance = *widthp << 6; + glyph->metrics.horiAdvance = *widthp * 64; } else @@ -1996,7 +2004,7 @@ { if ( widthp ) - glyph->metrics.horiAdvance = *widthp << 6; + glyph->metrics.horiAdvance = *widthp * 64; } } @@ -2136,16 +2144,16 @@ glyph->outline.n_points = 0; glyph->outline.n_contours = 0; - glyph->metrics.width = (FT_Pos)metrics.width << 6; - glyph->metrics.height = (FT_Pos)metrics.height << 6; + glyph->metrics.width = (FT_Pos)metrics.width * 64; + glyph->metrics.height = (FT_Pos)metrics.height * 64; - glyph->metrics.horiBearingX = (FT_Pos)metrics.horiBearingX << 6; - glyph->metrics.horiBearingY = (FT_Pos)metrics.horiBearingY << 6; - glyph->metrics.horiAdvance = (FT_Pos)metrics.horiAdvance << 6; + glyph->metrics.horiBearingX = (FT_Pos)metrics.horiBearingX * 64; + glyph->metrics.horiBearingY = (FT_Pos)metrics.horiBearingY * 64; + glyph->metrics.horiAdvance = (FT_Pos)metrics.horiAdvance * 64; - glyph->metrics.vertBearingX = (FT_Pos)metrics.vertBearingX << 6; - glyph->metrics.vertBearingY = (FT_Pos)metrics.vertBearingY << 6; - glyph->metrics.vertAdvance = (FT_Pos)metrics.vertAdvance << 6; + glyph->metrics.vertBearingX = (FT_Pos)metrics.vertBearingX * 64; + glyph->metrics.vertBearingY = (FT_Pos)metrics.vertBearingY * 64; + glyph->metrics.vertAdvance = (FT_Pos)metrics.vertAdvance * 64; glyph->format = FT_GLYPH_FORMAT_BITMAP; @@ -2414,15 +2422,28 @@ loader->load_flags = (FT_ULong)load_flags; - loader->face = (FT_Face)face; - loader->size = (FT_Size)size; + loader->face = face; + loader->size = size; loader->glyph = (FT_GlyphSlot)glyph; loader->stream = stream; + loader->composites.head = NULL; + loader->composites.tail = NULL; + return FT_Err_Ok; } + static void + tt_loader_done( TT_Loader loader ) + { + FT_List_Finalize( &loader->composites, + NULL, + loader->face->root.memory, + NULL ); + } + + /*************************************************************************/ /* */ /* <Function> */ @@ -2479,6 +2500,7 @@ /* for the bbox we need the header only */ (void)tt_loader_init( &loader, size, glyph, load_flags, TRUE ); (void)load_truetype_glyph( &loader, glyph_index, 0, TRUE ); + tt_loader_done( &loader ); glyph->linearHoriAdvance = loader.linear; glyph->linearVertAdvance = loader.vadvance; @@ -2574,6 +2596,8 @@ error = compute_glyph_metrics( &loader, glyph_index ); } + tt_loader_done( &loader ); + /* Set the `high precision' bit flag. */ /* This is _critical_ to get correct output for monochrome */ /* TrueType glyphs at all sizes using the bytecode interpreter. */ diff --git a/src/truetype/ttgxvar.c b/src/truetype/ttgxvar.c index 2b12483..5d4384e 100644 --- a/src/truetype/ttgxvar.c +++ b/src/truetype/ttgxvar.c @@ -112,6 +112,8 @@ /* <Input> */ /* stream :: The data stream. */ /* */ + /* size :: The size of the table holding the data. */ + /* */ /* <Output> */ /* point_cnt :: The number of points read. A zero value means that */ /* all points in the glyph will be affected, without */ @@ -123,6 +125,7 @@ /* */ static FT_UShort* ft_var_readpackedpoints( FT_Stream stream, + FT_ULong size, FT_UInt *point_cnt ) { FT_UShort *points = NULL; @@ -149,6 +152,12 @@ n |= FT_GET_BYTE(); } + if ( n > size ) + { + FT_TRACE1(( "ft_var_readpackedpoints: number of points too large\n" )); + return NULL; + } + if ( FT_NEW_ARRAY( points, n ) ) return NULL; @@ -212,6 +221,8 @@ /* <Input> */ /* stream :: The data stream. */ /* */ + /* size :: The size of the table holding the data. */ + /* */ /* delta_cnt :: The number of deltas to be read. */ /* */ /* <Return> */ @@ -222,6 +233,7 @@ /* */ static FT_Short* ft_var_readpackeddeltas( FT_Stream stream, + FT_ULong size, FT_UInt delta_cnt ) { FT_Short *deltas = NULL; @@ -233,6 +245,12 @@ FT_UNUSED( error ); + if ( delta_cnt > size ) + { + FT_TRACE1(( "ft_var_readpackeddeltas: number of points too large\n" )); + return NULL; + } + if ( FT_NEW_ARRAY( deltas, delta_cnt ) ) return NULL; @@ -341,7 +359,8 @@ FT_TRACE5(( " axis %d:\n", i )); segment->pairCount = FT_GET_USHORT(); - if ( FT_NEW_ARRAY( segment->correspondence, segment->pairCount ) ) + if ( (FT_ULong)segment->pairCount * 4 > table_len || + FT_NEW_ARRAY( segment->correspondence, segment->pairCount ) ) { /* Failure. Free everything we have done so far. We must do */ /* it right now since loading the `avar' table is optional. */ @@ -357,8 +376,8 @@ for ( j = 0; j < segment->pairCount; j++ ) { /* convert to Fixed */ - segment->correspondence[j].fromCoord = FT_GET_SHORT() << 2; - segment->correspondence[j].toCoord = FT_GET_SHORT() << 2; + segment->correspondence[j].fromCoord = FT_GET_SHORT() * 4; + segment->correspondence[j].toCoord = FT_GET_SHORT() * 4; FT_TRACE5(( " mapping %.4f to %.4f\n", segment->correspondence[j].fromCoord / 65536.0, @@ -447,10 +466,6 @@ if ( FT_STREAM_READ_FIELDS( gvar_fields, &gvar_head ) ) goto Exit; - blend->tuplecount = gvar_head.globalCoordCount; - blend->gv_glyphcnt = gvar_head.glyphCount; - offsetToData = gvar_start + gvar_head.offsetToData; - if ( gvar_head.version != 0x00010000L ) { FT_TRACE1(( "bad table version\n" )); @@ -458,8 +473,6 @@ goto Exit; } - FT_TRACE2(( "loaded\n" )); - if ( gvar_head.axisCount != (FT_UShort)blend->mmvar->num_axis ) { FT_TRACE1(( "ft_var_load_gvar: number of axes in `gvar' and `cvar'\n" @@ -468,6 +481,33 @@ goto Exit; } + /* rough sanity check, ignoring offsets */ + if ( (FT_ULong)gvar_head.globalCoordCount * gvar_head.axisCount > + table_len / 2 ) + { + FT_TRACE1(( "ft_var_load_gvar:" + " invalid number of global coordinates\n" )); + error = FT_THROW( Invalid_Table ); + goto Exit; + } + + /* rough sanity check: offsets can be either 2 or 4 bytes, */ + /* and a single variation needs at least 4 bytes per glyph */ + if ( (FT_ULong)gvar_head.glyphCount * + ( ( gvar_head.flags & 1 ) ? 8 : 6 ) > table_len ) + { + FT_TRACE1(( "ft_var_load_gvar: invalid number of glyphs\n" )); + error = FT_THROW( Invalid_Table ); + goto Exit; + } + + FT_TRACE2(( "loaded\n" )); + + blend->gvar_size = table_len; + blend->tuplecount = gvar_head.globalCoordCount; + blend->gv_glyphcnt = gvar_head.glyphCount; + offsetToData = gvar_start + gvar_head.offsetToData; + FT_TRACE5(( "gvar: there are %d shared coordinates:\n", blend->tuplecount )); @@ -514,7 +554,7 @@ for ( j = 0 ; j < (FT_UInt)gvar_head.axisCount; j++ ) { blend->tuplecoords[i * gvar_head.axisCount + j] = - FT_GET_SHORT() << 2; /* convert to FT_Fixed */ + FT_GET_SHORT() * 4; /* convert to FT_Fixed */ FT_TRACE5(( "%.4f ", blend->tuplecoords[i * gvar_head.axisCount + j] / 65536.0 )); } @@ -698,7 +738,8 @@ /* TT_Get_MM_Var initializes the blend structure. */ /* */ /* <Output> */ - /* master :: The `fvar' data (must be freed by caller). */ + /* master :: The `fvar' data (must be freed by caller). Can be NULL, */ + /* which makes this function simply load MM support. */ /* */ /* <Return> */ /* FreeType error code. 0 means success. */ @@ -1352,13 +1393,25 @@ goto FExit; tupleCount = FT_GET_USHORT(); - offsetToData = table_start + FT_GET_USHORT(); + offsetToData = FT_GET_USHORT(); + + /* rough sanity test */ + if ( offsetToData + tupleCount * 4 > table_len ) + { + FT_TRACE2(( "tt_face_vary_cvt:" + " invalid CVT variation array header\n" )); + + error = FT_THROW( Invalid_Table ); + goto FExit; + } - /* The documentation implies there are flags packed into the */ - /* tuplecount, but John Jenkins says that shared points don't apply */ - /* to `cvar', and no other flags are defined. */ + offsetToData += table_start; - FT_TRACE5(( "cvar: there are %d tuples:\n", tupleCount )); + /* The documentation implies there are flags packed into */ + /* `tupleCount', but John Jenkins says that shared points don't apply */ + /* to `cvar', and no other flags are defined. */ + + FT_TRACE5(( "cvar: there are %d tuples:\n", tupleCount & 0xFFF )); for ( i = 0; i < ( tupleCount & 0xFFF ); i++ ) { @@ -1378,7 +1431,7 @@ if ( tupleIndex & GX_TI_EMBEDDED_TUPLE_COORD ) { for ( j = 0; j < blend->num_axis; j++ ) - tuple_coords[j] = FT_GET_SHORT() << 2; /* convert from */ + tuple_coords[j] = FT_GET_SHORT() * 4; /* convert from */ /* short frac to fixed */ } else @@ -1396,9 +1449,9 @@ if ( tupleIndex & GX_TI_INTERMEDIATE_TUPLE ) { for ( j = 0; j < blend->num_axis; j++ ) - im_start_coords[j] = FT_GET_SHORT() << 2; + im_start_coords[j] = FT_GET_SHORT() * 4; for ( j = 0; j < blend->num_axis; j++ ) - im_end_coords[j] = FT_GET_SHORT() << 2; + im_end_coords[j] = FT_GET_SHORT() * 4; } apply = ft_var_apply_tuple( blend, @@ -1420,8 +1473,11 @@ FT_Stream_SeekSet( stream, offsetToData ); - localpoints = ft_var_readpackedpoints( stream, &point_count ); + localpoints = ft_var_readpackedpoints( stream, + table_len, + &point_count ); deltas = ft_var_readpackeddeltas( stream, + table_len, point_count == 0 ? face->cvt_size : point_count ); if ( localpoints == NULL || deltas == NULL ) @@ -1649,13 +1705,13 @@ { FT_Vector* out_points; - FT_UInt first_point; - FT_UInt end_point; + FT_Int first_point; + FT_Int end_point; - FT_UInt first_delta; - FT_UInt cur_delta; + FT_Int first_delta; + FT_Int cur_delta; - FT_UInt point; + FT_Int point; FT_Short contour; @@ -1818,7 +1874,19 @@ goto Fail2; tupleCount = FT_GET_USHORT(); - offsetToData = glyph_start + FT_GET_USHORT(); + offsetToData = FT_GET_USHORT(); + + /* rough sanity test */ + if ( offsetToData + tupleCount * 4 > blend->gvar_size ) + { + FT_TRACE2(( "TT_Vary_Apply_Glyph_Deltas:" + " invalid glyph variation array header\n" )); + + error = FT_THROW( Invalid_Table ); + goto Fail2; + } + + offsetToData += glyph_start; if ( tupleCount & GX_TC_TUPLES_SHARE_POINT_NUMBERS ) { @@ -1826,13 +1894,16 @@ FT_Stream_SeekSet( stream, offsetToData ); - sharedpoints = ft_var_readpackedpoints( stream, &spoint_count ); + sharedpoints = ft_var_readpackedpoints( stream, + blend->gvar_size, + &spoint_count ); offsetToData = FT_Stream_FTell( stream ); FT_Stream_SeekSet( stream, here ); } - FT_TRACE5(( "gvar: there are %d tuples:\n", tupleCount )); + FT_TRACE5(( "gvar: there are %d tuples:\n", + tupleCount & GX_TC_TUPLE_COUNT_MASK )); for ( i = 0; i < ( tupleCount & GX_TC_TUPLE_COUNT_MASK ); i++ ) { @@ -1849,11 +1920,14 @@ if ( tupleIndex & GX_TI_EMBEDDED_TUPLE_COORD ) { for ( j = 0; j < blend->num_axis; j++ ) - tuple_coords[j] = FT_GET_SHORT() << 2; /* convert from */ + tuple_coords[j] = FT_GET_SHORT() * 4; /* convert from */ /* short frac to fixed */ } else if ( ( tupleIndex & GX_TI_TUPLE_INDEX_MASK ) >= blend->tuplecount ) { + FT_TRACE2(( "TT_Vary_Apply_Glyph_Deltas:" + " invalid tuple index\n" )); + error = FT_THROW( Invalid_Table ); goto Fail2; } @@ -1866,9 +1940,9 @@ if ( tupleIndex & GX_TI_INTERMEDIATE_TUPLE ) { for ( j = 0; j < blend->num_axis; j++ ) - im_start_coords[j] = FT_GET_SHORT() << 2; + im_start_coords[j] = FT_GET_SHORT() * 4; for ( j = 0; j < blend->num_axis; j++ ) - im_end_coords[j] = FT_GET_SHORT() << 2; + im_end_coords[j] = FT_GET_SHORT() * 4; } apply = ft_var_apply_tuple( blend, @@ -1889,7 +1963,9 @@ { FT_Stream_SeekSet( stream, offsetToData ); - localpoints = ft_var_readpackedpoints( stream, &point_count ); + localpoints = ft_var_readpackedpoints( stream, + blend->gvar_size, + &point_count ); points = localpoints; } else @@ -1899,9 +1975,11 @@ } deltas_x = ft_var_readpackeddeltas( stream, + blend->gvar_size, point_count == 0 ? n_points : point_count ); deltas_y = ft_var_readpackeddeltas( stream, + blend->gvar_size, point_count == 0 ? n_points : point_count ); @@ -1949,6 +2027,9 @@ #endif } + else if ( localpoints == NULL ) + ; /* failure, ignore it */ + else { #ifdef FT_DEBUG_LEVEL_TRACE @@ -2020,6 +2101,8 @@ FT_TRACE5(( "\n" )); Fail2: + if ( sharedpoints != ALL_POINTS ) + FT_FREE( sharedpoints ); FT_FREE( tuple_coords ); FT_FREE( im_start_coords ); FT_FREE( im_end_coords ); diff --git a/src/truetype/ttgxvar.h b/src/truetype/ttgxvar.h index 060d4d6..dd1411f 100644 --- a/src/truetype/ttgxvar.h +++ b/src/truetype/ttgxvar.h @@ -95,6 +95,8 @@ FT_BEGIN_HEADER FT_UInt gv_glyphcnt; FT_ULong* glyphoffsets; + FT_ULong gvar_size; + } GX_BlendRec; diff --git a/src/truetype/ttinterp.c b/src/truetype/ttinterp.c index 089f604..1c1d7de 100644 --- a/src/truetype/ttinterp.c +++ b/src/truetype/ttinterp.c @@ -45,15 +45,6 @@ #define FT_COMPONENT trace_ttinterp - /*************************************************************************/ - /* */ - /* In order to detect infinite loops in the code, we set up a counter */ - /* within the run loop. A single stroke of interpretation is now */ - /* limited to a maximum number of opcodes defined below. */ - /* */ -#define MAX_RUNNABLE_OPCODES 1000000L - - #define SUBPIXEL_HINTING \ ( ((TT_Driver)FT_FACE_DRIVER( exc->face ))->interpreter_version == \ TT_INTERPRETER_VERSION_38 ) @@ -88,13 +79,6 @@ #define BOUNDSL( x, n ) ( (FT_ULong)(x) >= (FT_ULong)(n) ) - /*************************************************************************/ - /* */ - /* This macro computes (a*2^14)/b and complements TT_MulFix14. */ - /* */ -#define TT_DivFix14( a, b ) FT_DivFix( a, (b) << 2 ) - - #undef SUCCESS #define SUCCESS 0 @@ -2580,26 +2564,23 @@ FT_F26Dot6 Vy, FT_UnitVector* R ) { - FT_F26Dot6 W; + FT_Vector V; - if ( FT_ABS( Vx ) < 0x4000L && FT_ABS( Vy ) < 0x4000L ) + if ( Vx == 0 && Vy == 0 ) { - if ( Vx == 0 && Vy == 0 ) - { - /* XXX: UNDOCUMENTED! It seems that it is possible to try */ - /* to normalize the vector (0,0). Return immediately. */ - return SUCCESS; - } - - Vx *= 0x4000; - Vy *= 0x4000; + /* XXX: UNDOCUMENTED! It seems that it is possible to try */ + /* to normalize the vector (0,0). Return immediately. */ + return SUCCESS; } - W = FT_Hypot( Vx, Vy ); + V.x = Vx; + V.y = Vy; - R->x = (FT_F2Dot14)TT_DivFix14( Vx, W ); - R->y = (FT_F2Dot14)TT_DivFix14( Vy, W ); + FT_Vector_NormLen( &V ); + + R->x = (FT_F2Dot14)( V.x / 4 ); + R->y = (FT_F2Dot14)( V.y / 4 ); return SUCCESS; } @@ -5157,11 +5138,11 @@ Ins_INSTCTRL( TT_ExecContext exc, FT_Long* args ) { - FT_Long K, L, Kf; + FT_ULong K, L, Kf; - K = args[1]; - L = args[0]; + K = (FT_ULong)args[1]; + L = (FT_ULong)args[0]; /* selector values cannot be `OR'ed; */ /* they are indices starting with index 1, not flags */ @@ -6505,8 +6486,6 @@ dx = exc->zp0.cur[b0].x - exc->zp1.cur[a0].x; dy = exc->zp0.cur[b0].y - exc->zp1.cur[a0].y; - exc->zp2.tags[point] |= FT_CURVE_TAG_TOUCH_BOTH; - discriminant = FT_MulDiv( dax, -dby, 0x40 ) + FT_MulDiv( day, dbx, 0x40 ); dotproduct = FT_MulDiv( dax, dbx, 0x40 ) + @@ -6543,6 +6522,8 @@ exc->zp0.cur[b0].y + exc->zp0.cur[b1].y ) / 4; } + + exc->zp2.tags[point] |= FT_CURVE_TAG_TOUCH_BOTH; } @@ -7575,7 +7556,7 @@ ? 2 : 12 - ( *opcode_name[exc->opcode] - '0' ), "#" )); - for ( n = 0; n < cnt; n++ ) + for ( n = 1; n <= cnt; n++ ) FT_TRACE7(( " %d", exc->stack[exc->top - n] )); FT_TRACE6(( "\n" )); } @@ -8240,7 +8221,7 @@ /* increment instruction counter and check if we didn't */ /* run this program for too long (e.g. infinite loops). */ - if ( ++ins_counter > MAX_RUNNABLE_OPCODES ) + if ( ++ins_counter > TT_CONFIG_OPTION_MAX_RUNNABLE_OPCODES ) return FT_THROW( Execution_Too_Long ); LSuiteLabel_: diff --git a/src/truetype/ttobjs.c b/src/truetype/ttobjs.c index 202aa04..b0d9f28 100644 --- a/src/truetype/ttobjs.c +++ b/src/truetype/ttobjs.c @@ -191,7 +191,7 @@ { FT_Error error; FT_UInt32 checksum = 0; - int i; + FT_UInt i; if ( FT_FRAME_ENTER( length ) ) @@ -200,8 +200,8 @@ for ( ; length > 3; length -= 4 ) checksum += (FT_UInt32)FT_GET_ULONG(); - for ( i = 3; length > 0; length --, i-- ) - checksum += (FT_UInt32)( FT_GET_BYTE() << ( i * 8 ) ); + for ( i = 3; length > 0; length--, i-- ) + checksum += (FT_UInt32)FT_GET_BYTE() << ( i * 8 ); FT_FRAME_EXIT(); @@ -490,7 +490,10 @@ /* <Input> */ /* stream :: The source font stream. */ /* */ - /* face_index :: The index of the font face in the resource. */ + /* face_index :: The index of the TrueType font, if we are opening a */ + /* collection, in bits 0-15. The numbered instance */ + /* index~+~1 of a GX (sub)font, if applicable, in bits */ + /* 16-30. */ /* */ /* num_params :: Number of additional generic parameters. Ignored. */ /* */ @@ -599,7 +602,7 @@ ttface->face_flags &= ~FT_FACE_FLAG_SCALABLE; } -#else +#else /* !FT_CONFIG_OPTION_INCREMENTAL */ if ( !error ) error = tt_face_load_loca( face, stream ); @@ -623,10 +626,56 @@ ttface->face_flags &= ~FT_FACE_FLAG_SCALABLE; } -#endif +#endif /* !FT_CONFIG_OPTION_INCREMENTAL */ } +#ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT + + { + FT_Int instance_index = face_index >> 16; + + + if ( FT_HAS_MULTIPLE_MASTERS( ttface ) && + instance_index > 0 ) + { + error = TT_Get_MM_Var( face, NULL ); + if ( error ) + goto Exit; + + if ( face->blend->mmvar->namedstyle ) + { + FT_Memory memory = ttface->memory; + + FT_Var_Named_Style* named_style; + FT_String* style_name; + + + /* in `face_index', the instance index starts with value 1 */ + named_style = face->blend->mmvar->namedstyle + instance_index - 1; + error = sfnt->get_name( face, + (FT_UShort)named_style->strid, + &style_name ); + if ( error ) + goto Exit; + + /* set style name; if already set, replace it */ + if ( face->root.style_name ) + FT_FREE( face->root.style_name ); + face->root.style_name = style_name; + + /* finally, select the named instance */ + error = TT_Set_Var_Design( face, + face->blend->mmvar->num_axis, + named_style->coords ); + if ( error ) + goto Exit; + } + } + } + +#endif /* TT_CONFIG_OPTION_GX_VAR_SUPPORT */ + #if defined( TT_CONFIG_OPTION_UNPATENTED_HINTING ) && \ !defined( TT_CONFIG_OPTION_BYTECODE_INTERPRETER ) @@ -1029,7 +1078,15 @@ } /* Fine, now run the font program! */ + + /* In case of an error while executing `fpgm', we intentionally don't */ + /* clean up immediately – bugs in the `fpgm' are so fundamental that */ + /* all following hinting calls should fail. Additionally, `fpgm' is */ + /* to be executed just once; calling it again is completely useless */ + /* and might even lead to extremely slow behaviour if it is malformed */ + /* (containing an infinite loop, for example). */ error = tt_size_run_fpgm( size, pedantic ); + return error; Exit: if ( error ) diff --git a/src/truetype/ttobjs.h b/src/truetype/ttobjs.h index 7ac4123..9396089 100644 --- a/src/truetype/ttobjs.h +++ b/src/truetype/ttobjs.h @@ -42,17 +42,6 @@ FT_BEGIN_HEADER /*************************************************************************/ /* */ /* <Type> */ - /* TT_Instance */ - /* */ - /* <Description> */ - /* A handle to a TrueType size object. */ - /* */ - typedef struct TT_SizeRec_* TT_Size; - - - /*************************************************************************/ - /* */ - /* <Type> */ /* TT_GlyphSlot */ /* */ /* <Description> */ diff --git a/src/truetype/ttpic.h b/src/truetype/ttpic.h index 48ba4aa..076ae56 100644 --- a/src/truetype/ttpic.h +++ b/src/truetype/ttpic.h @@ -20,7 +20,8 @@ #define __TTPIC_H__ -FT_BEGIN_HEADER +#include FT_INTERNAL_PIC_H + #ifndef FT_CONFIG_OPTION_PIC @@ -37,6 +38,8 @@ FT_BEGIN_HEADER #include FT_SERVICE_PROPERTIES_H +FT_BEGIN_HEADER + typedef struct TTModulePIC_ { FT_ServiceDescRec* tt_services; @@ -68,13 +71,12 @@ FT_BEGIN_HEADER FT_Error tt_driver_class_pic_init( FT_Library library ); +FT_END_HEADER + #endif /* FT_CONFIG_OPTION_PIC */ /* */ - -FT_END_HEADER - #endif /* __TTPIC_H__ */ diff --git a/src/truetype/ttpload.c b/src/truetype/ttpload.c index fb338bd..9bf67f9 100644 --- a/src/truetype/ttpload.c +++ b/src/truetype/ttpload.c @@ -124,8 +124,9 @@ TT_Table entry = face->dir_tables; TT_Table limit = entry + face->num_tables; - FT_Long pos = (FT_Long)FT_STREAM_POS(); - FT_Long dist = 0x7FFFFFFFL; + FT_Long pos = (FT_Long)FT_STREAM_POS(); + FT_Long dist = 0x7FFFFFFFL; + FT_Bool found = 0; /* compute the distance to next table in font file */ @@ -135,10 +136,13 @@ if ( diff > 0 && diff < dist ) - dist = diff; + { + dist = diff; + found = 1; + } } - if ( entry == limit ) + if ( !found ) { /* `loca' is the last table */ dist = (FT_Long)stream->size - pos; @@ -152,6 +156,14 @@ FT_TRACE2(( "adjusting num_locations to %d\n", face->num_locations )); } + else + { + face->root.num_glyphs = face->num_locations + ? (FT_Long)face->num_locations - 1 : 0; + + FT_TRACE2(( "adjusting num_glyphs to %d\n", + face->root.num_glyphs )); + } } } @@ -214,7 +226,8 @@ if ( pos1 > face->glyf_len ) { FT_TRACE1(( "tt_face_get_location:" - " too large offset=0x%08lx found for gid=0x%04lx," + " too large offset=0x%08lx found for gid=0x%04lx,\n" + " " " exceeding the end of glyf table (0x%08lx)\n", pos1, gindex, face->glyf_len )); *asize = 0; @@ -224,7 +237,8 @@ if ( pos2 > face->glyf_len ) { FT_TRACE1(( "tt_face_get_location:" - " too large offset=0x%08lx found for gid=0x%04lx," + " too large offset=0x%08lx found for gid=0x%04lx,\n" + " " " truncate at the end of glyf table (0x%08lx)\n", pos2, gindex + 1, face->glyf_len )); pos2 = face->glyf_len; diff --git a/src/truetype/ttsubpix.c b/src/truetype/ttsubpix.c index dbda4d9..0d391e9 100644 --- a/src/truetype/ttsubpix.c +++ b/src/truetype/ttsubpix.c @@ -903,7 +903,7 @@ sph_set_tweaks( TT_Loader loader, FT_UInt glyph_index ) { - TT_Face face = (TT_Face)loader->face; + TT_Face face = loader->face; FT_String* family = face->root.family_name; FT_UInt ppem = loader->size->metrics.x_ppem; FT_String* style = face->root.style_name; |