Index: third_party/freetype/src/truetype/ttgload.c |
diff --git a/third_party/freetype/src/truetype/ttgload.c b/third_party/freetype/src/truetype/ttgload.c |
index c5841c301d2891f131375cc1162ffea6f03d2131..a792ad44a067d736c1ce0afc66b8f3f731166339 100644 |
--- a/third_party/freetype/src/truetype/ttgload.c |
+++ b/third_party/freetype/src/truetype/ttgload.c |
@@ -4,7 +4,7 @@ |
/* */ |
/* TrueType Glyph Loader (body). */ |
/* */ |
-/* Copyright 1996-2014 */ |
+/* Copyright 1996-2015 by */ |
/* David Turner, Robert Wilhelm, and Werner Lemberg. */ |
/* */ |
/* This file is part of the FreeType project, and may only be used, */ |
@@ -100,13 +100,15 @@ |
else if ( face->os2.version != 0xFFFFU ) |
{ |
*tsb = (FT_Short)( face->os2.sTypoAscender - yMax ); |
- *ah = face->os2.sTypoAscender - face->os2.sTypoDescender; |
+ *ah = (FT_UShort)FT_ABS( face->os2.sTypoAscender - |
+ face->os2.sTypoDescender ); |
} |
else |
{ |
*tsb = (FT_Short)( face->horizontal.Ascender - yMax ); |
- *ah = face->horizontal.Ascender - face->horizontal.Descender; |
+ *ah = (FT_UShort)FT_ABS( face->horizontal.Ascender - |
+ face->horizontal.Descender ); |
} |
FT_TRACE5(( " advance height (font units): %d\n", *ah )); |
@@ -118,7 +120,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 |
@@ -151,14 +153,16 @@ |
loader->vadvance = advance_height; |
#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING |
- if ( driver->interpreter_version == TT_INTERPRETER_VERSION_38 ) |
+ if ( driver->interpreter_version == TT_INTERPRETER_VERSION_38 && |
+ loader->exec ) |
{ |
- if ( loader->exec ) |
- loader->exec->sph_tweak_flags = 0; |
+ loader->exec->sph_tweak_flags = 0; |
- /* this may not be the right place for this, but it works */ |
- if ( loader->exec && loader->exec->ignore_x_mode ) |
- sph_set_tweaks( loader, glyph_index ); |
+ /* This may not be the right place for this, but it works... */ |
+ /* Note that we have to unconditionally load the tweaks since */ |
+ /* it is possible that glyphs individually switch ClearType's */ |
+ /* backwards compatibility mode on and off. */ |
+ sph_set_tweaks( loader, glyph_index ); |
} |
#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */ |
@@ -178,7 +182,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; |
@@ -246,29 +250,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. */ |
@@ -407,7 +388,7 @@ |
/* reading the bytecode instructions */ |
load->glyph->control_len = 0; |
- load->glyph->control_data = 0; |
+ load->glyph->control_data = NULL; |
if ( p + 2 > limit ) |
goto Invalid_Outline; |
@@ -555,8 +536,8 @@ |
*flag = (FT_Byte)( f & FT_CURVE_TAG_ON ); |
} |
- outline->n_points = (FT_UShort)n_points; |
- outline->n_contours = (FT_Short) n_contours; |
+ outline->n_points = (FT_Short)n_points; |
+ outline->n_contours = (FT_Short)n_contours; |
load->cursor = p; |
@@ -619,15 +600,31 @@ |
goto Invalid_Composite; |
/* read arguments */ |
- if ( subglyph->flags & ARGS_ARE_WORDS ) |
+ if ( subglyph->flags & ARGS_ARE_XY_VALUES ) |
{ |
- subglyph->arg1 = FT_NEXT_SHORT( p ); |
- subglyph->arg2 = FT_NEXT_SHORT( p ); |
+ if ( subglyph->flags & ARGS_ARE_WORDS ) |
+ { |
+ subglyph->arg1 = FT_NEXT_SHORT( p ); |
+ subglyph->arg2 = FT_NEXT_SHORT( p ); |
+ } |
+ else |
+ { |
+ subglyph->arg1 = FT_NEXT_CHAR( p ); |
+ subglyph->arg2 = FT_NEXT_CHAR( p ); |
+ } |
} |
else |
{ |
- subglyph->arg1 = FT_NEXT_CHAR( p ); |
- subglyph->arg2 = FT_NEXT_CHAR( p ); |
+ if ( subglyph->flags & ARGS_ARE_WORDS ) |
+ { |
+ subglyph->arg1 = (FT_Int)FT_NEXT_USHORT( p ); |
+ subglyph->arg2 = (FT_Int)FT_NEXT_USHORT( p ); |
+ } |
+ else |
+ { |
+ subglyph->arg1 = (FT_Int)FT_NEXT_BYTE( p ); |
+ subglyph->arg2 = (FT_Int)FT_NEXT_BYTE( p ); |
+ } |
} |
/* read transform */ |
@@ -636,20 +633,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; |
@@ -707,9 +704,10 @@ |
FT_UInt start_point, |
FT_UInt start_contour ) |
{ |
- zone->n_points = (FT_UShort)( load->outline.n_points - start_point ); |
- zone->n_contours = (FT_Short) ( load->outline.n_contours - |
- start_contour ); |
+ zone->n_points = (FT_UShort)load->outline.n_points - |
+ (FT_UShort)start_point; |
+ zone->n_contours = load->outline.n_contours - |
+ (FT_Short)start_contour; |
zone->org = load->extra_points + start_point; |
zone->cur = load->outline.points + start_point; |
zone->orus = load->extra_points2 + start_point; |
@@ -733,14 +731,14 @@ |
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 |
TT_GlyphZone zone = &loader->zone; |
#ifdef TT_USE_BYTECODE_INTERPRETER |
- FT_UInt n_ins; |
+ FT_Long n_ins; |
#else |
FT_UNUSED( is_composite ); |
#endif |
@@ -753,14 +751,14 @@ |
FT_TRACE1(( " (0x%lx byte) is truncated\n", |
loader->glyph->control_len )); |
} |
- n_ins = (FT_UInt)( loader->glyph->control_len ); |
+ n_ins = loader->glyph->control_len; |
/* 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; |
+ loader->exec->GS = loader->size->GS; |
/* XXX: UNDOCUMENTED! Hinting instructions of a composite glyph */ |
/* completely refer to the (already) hinted subglyphs. */ |
@@ -773,10 +771,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 |
@@ -794,7 +790,6 @@ |
if ( n_ins > 0 ) |
{ |
- FT_Bool debug; |
FT_Error error; |
FT_GlyphLoader gloader = loader->gloader; |
@@ -807,10 +802,7 @@ |
loader->exec->is_composite = is_composite; |
loader->exec->pts = *zone; |
- debug = FT_BOOL( !( loader->load_flags & FT_LOAD_NO_SCALE ) && |
- ((TT_Size)loader->size)->debug ); |
- |
- error = TT_Run_Context( loader->exec, debug ); |
+ error = TT_Run_Context( loader->exec ); |
if ( error && loader->exec->pedantic_hinting ) |
return error; |
@@ -880,28 +872,15 @@ |
#ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT |
- if ( ((TT_Face)loader->face)->doblend ) |
+ if ( loader->face->doblend ) |
{ |
/* Deltas apply to the unscaled data. */ |
- FT_Vector* deltas; |
- FT_Memory memory = loader->face->memory; |
- FT_Int i; |
- |
- |
- error = TT_Vary_Get_Glyph_Deltas( (TT_Face)(loader->face), |
- loader->glyph_index, |
- &deltas, |
- n_points ); |
+ error = TT_Vary_Apply_Glyph_Deltas( loader->face, |
+ loader->glyph_index, |
+ outline, |
+ (FT_UInt)n_points ); |
if ( error ) |
return error; |
- |
- for ( i = 0; i < n_points; ++i ) |
- { |
- outline->points[i].x += deltas[i].x; |
- outline->points[i].y += deltas[i].y; |
- } |
- |
- FT_FREE( deltas ); |
} |
#endif /* TT_CONFIG_OPTION_GX_VAR_SUPPORT */ |
@@ -916,13 +895,13 @@ |
{ |
#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; |
- FT_Int ppem = loader->size->metrics.x_ppem; |
+ FT_UInt ppem = loader->size->metrics.x_ppem; |
FT_String* style = face->root.style_name; |
- FT_Int x_scale_factor = 1000; |
+ FT_UInt x_scale_factor = 1000; |
#endif |
FT_Vector* vec = outline->points; |
@@ -949,9 +928,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_factor, 1000 ); |
- y_scale = ((TT_Size)loader->size)->metrics.y_scale; |
+ x_scale = FT_MulDiv( loader->size->metrics.x_scale, |
+ (FT_Long)x_scale_factor, 1000 ); |
+ y_scale = loader->size->metrics.y_scale; |
/* compensate for any scaling by de/emboldening; */ |
/* the amount was determined via experimentation */ |
@@ -971,8 +950,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; |
} |
@@ -1019,32 +998,31 @@ |
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 = 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 k = subglyph->arg1; |
- FT_UInt l = subglyph->arg2; |
+ 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; |
FT_Vector* p2; |
@@ -1131,8 +1109,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 ); |
@@ -1147,9 +1125,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; |
} |
@@ -1211,7 +1187,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'; */ |
@@ -1350,11 +1326,14 @@ |
#define TT_LOADER_SET_PP( loader ) \ |
do \ |
{ \ |
- FT_Bool subpixel_ = loader->exec ? loader->exec->subpixel \ |
- : 0; \ |
- FT_Bool grayscale_ = loader->exec ? loader->exec->grayscale \ |
- : 0; \ |
- FT_Bool use_aw_2_ = (FT_Bool)( subpixel_ && grayscale_ ); \ |
+ FT_Bool subpixel_hinting_ = loader->exec \ |
+ ? loader->exec->subpixel_hinting \ |
+ : 0; \ |
+ FT_Bool grayscale_ = loader->exec \ |
+ ? loader->exec->grayscale \ |
+ : 0; \ |
+ FT_Bool use_aw_2_ = (FT_Bool)( subpixel_hinting_ && \ |
+ grayscale_ ); \ |
\ |
\ |
(loader)->pp1.x = (loader)->bbox.xMin - (loader)->left_bearing; \ |
@@ -1405,14 +1384,10 @@ |
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; |
-#ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT |
- FT_Vector* deltas = NULL; |
-#endif |
- |
#ifdef FT_CONFIG_OPTION_INCREMENTAL |
FT_StreamRec inc_stream; |
FT_Data glyph_data; |
@@ -1429,19 +1404,21 @@ |
goto Exit; |
} |
+#ifndef FT_CONFIG_OPTION_INCREMENTAL |
/* check glyph index */ |
if ( glyph_index >= (FT_UInt)face->root.num_glyphs ) |
{ |
error = FT_THROW( Invalid_Glyph_Index ); |
goto Exit; |
} |
+#endif |
loader->glyph_index = glyph_index; |
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 |
{ |
@@ -1472,7 +1449,8 @@ |
FT_MEM_ZERO( &inc_stream, sizeof ( inc_stream ) ); |
FT_Stream_OpenMemory( &inc_stream, |
- glyph_data.pointer, glyph_data.length ); |
+ glyph_data.pointer, |
+ (FT_ULong)glyph_data.length ); |
loader->stream = &inc_stream; |
} |
@@ -1500,7 +1478,7 @@ |
error = face->access_glyph_frame( loader, glyph_index, |
loader->glyf_offset + offset, |
- loader->byte_len ); |
+ (FT_UInt)loader->byte_len ); |
if ( error ) |
goto Exit; |
@@ -1546,28 +1524,49 @@ |
#ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT |
- if ( ((TT_Face)(loader->face))->doblend ) |
+ if ( loader->face->doblend ) |
{ |
- /* this must be done before scaling */ |
- FT_Memory memory = loader->face->memory; |
- |
+ /* a small outline structure with four elements for */ |
+ /* communication with `TT_Vary_Apply_Glyph_Deltas' */ |
+ FT_Vector points[4]; |
+ char tags[4] = { 1, 1, 1, 1 }; |
+ short contours[4] = { 0, 1, 2, 3 }; |
+ FT_Outline outline; |
+ |
+ |
+ points[0].x = loader->pp1.x; |
+ points[0].y = loader->pp1.y; |
+ points[1].x = loader->pp2.x; |
+ points[1].y = loader->pp2.y; |
+ |
+ points[2].x = loader->pp3.x; |
+ points[2].y = loader->pp3.y; |
+ points[3].x = loader->pp4.x; |
+ points[3].y = loader->pp4.y; |
+ |
+ outline.n_points = 4; |
+ outline.n_contours = 4; |
+ outline.points = points; |
+ outline.tags = tags; |
+ outline.contours = contours; |
- error = TT_Vary_Get_Glyph_Deltas( (TT_Face)(loader->face), |
- glyph_index, &deltas, 4 ); |
+ /* this must be done before scaling */ |
+ error = TT_Vary_Apply_Glyph_Deltas( loader->face, |
+ glyph_index, |
+ &outline, |
+ (FT_UInt)outline.n_points ); |
if ( error ) |
goto Exit; |
- loader->pp1.x += deltas[0].x; |
- loader->pp1.y += deltas[0].y; |
- loader->pp2.x += deltas[1].x; |
- loader->pp2.y += deltas[1].y; |
- |
- loader->pp3.x += deltas[2].x; |
- loader->pp3.y += deltas[2].y; |
- loader->pp4.x += deltas[3].x; |
- loader->pp4.y += deltas[3].y; |
+ loader->pp1.x = points[0].x; |
+ loader->pp1.y = points[0].y; |
+ loader->pp2.x = points[1].x; |
+ loader->pp2.y = points[1].y; |
- FT_FREE( deltas ); |
+ loader->pp3.x = points[2].x; |
+ loader->pp3.y = points[2].y; |
+ loader->pp4.x = points[3].x; |
+ loader->pp4.y = points[3].y; |
} |
#endif /* TT_CONFIG_OPTION_GX_VAR_SUPPORT */ |
@@ -1633,8 +1632,8 @@ |
FT_ULong ins_pos; /* position of composite instructions, if any */ |
- start_point = gloader->base.outline.n_points; |
- start_contour = gloader->base.outline.n_contours; |
+ start_point = (FT_UInt)gloader->base.outline.n_points; |
+ start_contour = (FT_UInt)gloader->base.outline.n_contours; |
/* for each subglyph, read composite header */ |
error = face->read_composite_glyph( loader ); |
@@ -1652,47 +1651,106 @@ |
if ( face->doblend ) |
{ |
- FT_Int i, limit; |
+ short i, limit; |
FT_SubGlyph subglyph; |
- FT_Memory memory = face->root.memory; |
+ FT_Outline outline; |
+ FT_Vector* points = NULL; |
+ char* tags = NULL; |
+ short* contours = NULL; |
+ |
+ FT_Memory memory = face->root.memory; |
+ |
+ |
+ limit = (short)gloader->current.num_subglyphs; |
+ |
+ /* construct an outline structure for */ |
+ /* communication with `TT_Vary_Apply_Glyph_Deltas' */ |
+ outline.n_points = (short)( gloader->current.num_subglyphs + 4 ); |
+ outline.n_contours = outline.n_points; |
- /* this provides additional offsets */ |
- /* for each component's translation */ |
+ if ( FT_NEW_ARRAY( points, outline.n_points ) || |
+ FT_NEW_ARRAY( tags, outline.n_points ) || |
+ FT_NEW_ARRAY( contours, outline.n_points ) ) |
+ goto Exit1; |
- if ( ( error = TT_Vary_Get_Glyph_Deltas( |
+ subglyph = gloader->current.subglyphs; |
+ |
+ for ( i = 0; i < limit; i++, subglyph++ ) |
+ { |
+ /* applying deltas for anchor points doesn't make sense, */ |
+ /* but we don't have to specially check this since */ |
+ /* unused delta values are zero anyways */ |
+ points[i].x = subglyph->arg1; |
+ points[i].y = subglyph->arg2; |
+ tags[i] = 1; |
+ contours[i] = i; |
+ } |
+ |
+ points[i].x = loader->pp1.x; |
+ points[i].y = loader->pp1.y; |
+ tags[i] = 1; |
+ contours[i] = i; |
+ |
+ i++; |
+ points[i].x = loader->pp2.x; |
+ points[i].y = loader->pp2.y; |
+ tags[i] = 1; |
+ contours[i] = i; |
+ |
+ i++; |
+ points[i].x = loader->pp3.x; |
+ points[i].y = loader->pp3.y; |
+ tags[i] = 1; |
+ contours[i] = i; |
+ |
+ i++; |
+ points[i].x = loader->pp4.x; |
+ points[i].y = loader->pp4.y; |
+ tags[i] = 1; |
+ contours[i] = i; |
+ |
+ outline.points = points; |
+ outline.tags = tags; |
+ outline.contours = contours; |
+ |
+ /* this call provides additional offsets */ |
+ /* for each component's translation */ |
+ if ( ( error = TT_Vary_Apply_Glyph_Deltas( |
face, |
glyph_index, |
- &deltas, |
- gloader->current.num_subglyphs + 4 ) ) != 0 ) |
- goto Exit; |
+ &outline, |
+ (FT_UInt)outline.n_points ) ) != 0 ) |
+ goto Exit1; |
- subglyph = gloader->current.subglyphs + gloader->base.num_subglyphs; |
- limit = gloader->current.num_subglyphs; |
+ subglyph = gloader->current.subglyphs; |
- for ( i = 0; i < limit; ++i, ++subglyph ) |
+ for ( i = 0; i < limit; i++, subglyph++ ) |
{ |
- if ( subglyph->flags & ARGS_ARE_XY_VALUES ) |
- { |
- /* XXX: overflow check for subglyph->{arg1,arg2}. */ |
- /* deltas[i].{x,y} must be within signed 16-bit, */ |
- /* but the restriction of summed delta is not clear */ |
- subglyph->arg1 += (FT_Int16)deltas[i].x; |
- subglyph->arg2 += (FT_Int16)deltas[i].y; |
- } |
+ /* XXX: overflow check for subglyph->{arg1,arg2}. */ |
+ /* Deltas must be within signed 16-bit, */ |
+ /* but the restriction of summed deltas is not clear */ |
+ subglyph->arg1 = (FT_Int16)points[i].x; |
+ subglyph->arg2 = (FT_Int16)points[i].y; |
} |
- loader->pp1.x += deltas[i + 0].x; |
- loader->pp1.y += deltas[i + 0].y; |
- loader->pp2.x += deltas[i + 1].x; |
- loader->pp2.y += deltas[i + 1].y; |
+ loader->pp1.x = points[i + 0].x; |
+ loader->pp1.y = points[i + 0].y; |
+ loader->pp2.x = points[i + 1].x; |
+ loader->pp2.y = points[i + 1].y; |
+ |
+ loader->pp3.x = points[i + 2].x; |
+ loader->pp3.y = points[i + 2].y; |
+ loader->pp4.x = points[i + 3].x; |
+ loader->pp4.y = points[i + 3].y; |
- loader->pp3.x += deltas[i + 2].x; |
- loader->pp3.y += deltas[i + 2].y; |
- loader->pp4.x += deltas[i + 3].x; |
- loader->pp4.y += deltas[i + 3].y; |
+ Exit1: |
+ FT_FREE( outline.points ); |
+ FT_FREE( outline.tags ); |
+ FT_FREE( outline.contours ); |
- FT_FREE( deltas ); |
+ if ( error ) |
+ goto Exit; |
} |
#endif /* TT_CONFIG_OPTION_GX_VAR_SUPPORT */ |
@@ -1728,7 +1786,7 @@ |
{ |
FT_UInt n, num_base_points; |
- FT_SubGlyph subglyph = 0; |
+ FT_SubGlyph subglyph = NULL; |
FT_UInt num_points = start_point; |
FT_UInt num_subglyphs = gloader->current.num_subglyphs; |
@@ -1757,10 +1815,12 @@ |
pp[2] = loader->pp3; |
pp[3] = loader->pp4; |
- num_base_points = gloader->base.outline.n_points; |
+ num_base_points = (FT_UInt)gloader->base.outline.n_points; |
- error = load_truetype_glyph( loader, subglyph->index, |
- recurse_count + 1, FALSE ); |
+ error = load_truetype_glyph( loader, |
+ (FT_UInt)subglyph->index, |
+ recurse_count + 1, |
+ FALSE ); |
if ( error ) |
goto Exit; |
@@ -1776,7 +1836,7 @@ |
loader->pp4 = pp[3]; |
} |
- num_points = gloader->base.outline.n_points; |
+ num_points = (FT_UInt)gloader->base.outline.n_points; |
if ( num_points == num_base_points ) |
continue; |
@@ -1847,7 +1907,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 |
@@ -1855,7 +1915,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; |
@@ -1876,8 +1936,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; |
@@ -1900,7 +1962,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 |
@@ -1908,7 +1970,7 @@ |
{ |
if ( widthp ) |
- glyph->metrics.horiAdvance = *widthp << 6; |
+ glyph->metrics.horiAdvance = *widthp * 64; |
} |
} |
@@ -2039,7 +2101,7 @@ |
error = sfnt->load_sbit_image( face, |
size->strike_index, |
glyph_index, |
- (FT_Int)load_flags, |
+ (FT_UInt)load_flags, |
stream, |
&glyph->bitmap, |
&metrics ); |
@@ -2048,16 +2110,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; |
@@ -2111,14 +2173,16 @@ |
#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING |
TT_Driver driver = (TT_Driver)FT_FACE_DRIVER( face ); |
- FT_Bool subpixel = FALSE; |
+ FT_Bool subpixel_hinting = FALSE; |
#if 0 |
/* not used yet */ |
FT_Bool compatible_widths; |
FT_Bool symmetrical_smoothing; |
FT_Bool bgr; |
+ FT_Bool vertical_lcd; |
FT_Bool subpixel_positioned; |
+ FT_Bool gray_cleartype; |
#endif |
#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */ |
@@ -2137,8 +2201,7 @@ |
return size->cvt_ready; |
/* query new execution context */ |
- exec = size->debug ? size->context |
- : ( (TT_Driver)FT_FACE_DRIVER( face ) )->context; |
+ exec = size->context; |
if ( !exec ) |
return FT_THROW( Could_Not_Find_Context ); |
@@ -2146,33 +2209,35 @@ |
if ( driver->interpreter_version == TT_INTERPRETER_VERSION_38 ) |
{ |
- subpixel = FT_BOOL( ( FT_LOAD_TARGET_MODE( load_flags ) != |
- FT_RENDER_MODE_MONO ) && |
- SPH_OPTION_SET_SUBPIXEL ); |
+ subpixel_hinting = FT_BOOL( ( FT_LOAD_TARGET_MODE( load_flags ) != |
+ FT_RENDER_MODE_MONO ) && |
+ SPH_OPTION_SET_SUBPIXEL ); |
- if ( subpixel ) |
+ if ( subpixel_hinting ) |
grayscale = FALSE; |
else if ( SPH_OPTION_SET_GRAYSCALE ) |
{ |
- grayscale = TRUE; |
- subpixel = FALSE; |
+ grayscale = TRUE; |
+ subpixel_hinting = FALSE; |
} |
else |
grayscale = FALSE; |
if ( FT_IS_TRICKY( glyph->face ) ) |
- subpixel = FALSE; |
+ subpixel_hinting = FALSE; |
- exec->ignore_x_mode = subpixel || grayscale; |
+ exec->ignore_x_mode = subpixel_hinting || grayscale; |
exec->rasterizer_version = SPH_OPTION_SET_RASTERIZER_VERSION; |
if ( exec->sph_tweak_flags & SPH_TWEAK_RASTERIZER_35 ) |
exec->rasterizer_version = TT_INTERPRETER_VERSION_35; |
#if 1 |
exec->compatible_widths = SPH_OPTION_SET_COMPATIBLE_WIDTHS; |
- exec->symmetrical_smoothing = FALSE; |
+ exec->symmetrical_smoothing = TRUE; |
exec->bgr = FALSE; |
+ exec->vertical_lcd = FALSE; |
exec->subpixel_positioned = TRUE; |
+ exec->gray_cleartype = FALSE; |
#else /* 0 */ |
exec->compatible_widths = |
FT_BOOL( FT_LOAD_TARGET_MODE( load_flags ) != |
@@ -2183,9 +2248,15 @@ |
exec->bgr = |
FT_BOOL( FT_LOAD_TARGET_MODE( load_flags ) != |
TT_LOAD_BGR ); |
+ exec->vertical_lcd = |
+ FT_BOOL( FT_LOAD_TARGET_MODE( load_flags ) != |
+ TT_LOAD_VERTICAL_LCD ); |
exec->subpixel_positioned = |
FT_BOOL( FT_LOAD_TARGET_MODE( load_flags ) != |
TT_LOAD_SUBPIXEL_POSITIONED ); |
+ exec->gray_cleartype = |
+ FT_BOOL( FT_LOAD_TARGET_MODE( load_flags ) != |
+ TT_LOAD_GRAY_CLEARTYPE ); |
#endif /* 0 */ |
} |
@@ -2208,13 +2279,13 @@ |
{ |
/* a change from mono to subpixel rendering (and vice versa) */ |
/* requires a re-execution of the CVT program */ |
- if ( subpixel != exec->subpixel ) |
+ if ( subpixel_hinting != exec->subpixel_hinting ) |
{ |
FT_TRACE4(( "tt_loader_init: subpixel hinting change," |
" re-executing `prep' table\n" )); |
- exec->subpixel = subpixel; |
- reexecute = TRUE; |
+ exec->subpixel_hinting = subpixel_hinting; |
+ reexecute = TRUE; |
} |
/* a change from mono to grayscale rendering (and vice versa) */ |
@@ -2237,7 +2308,7 @@ |
/* requires a re-execution of the CVT program */ |
if ( grayscale != exec->grayscale ) |
{ |
- FT_TRACE4(( "tt_loader_init: grayscale change," |
+ FT_TRACE4(( "tt_loader_init: grayscale hinting change," |
" re-executing `prep' table\n" )); |
exec->grayscale = grayscale; |
@@ -2257,7 +2328,7 @@ |
return error; |
} |
- /* see whether the cvt program has disabled hinting */ |
+ /* check whether the cvt program has disabled hinting */ |
if ( exec->GS.instruct_control & 1 ) |
load_flags |= FT_LOAD_NO_HINTING; |
@@ -2265,6 +2336,13 @@ |
if ( exec->GS.instruct_control & 2 ) |
exec->GS = tt_default_graphics_state; |
+#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING |
+ /* check whether we have a font hinted for ClearType -- */ |
+ /* note that this flag can also be modified in a glyph's bytecode */ |
+ if ( exec->GS.instruct_control & 4 ) |
+ exec->ignore_x_mode = 0; |
+#endif |
+ |
exec->pedantic_hinting = FT_BOOL( load_flags & FT_LOAD_PEDANTIC ); |
loader->exec = exec; |
loader->instructions = exec->glyphIns; |
@@ -2308,10 +2386,10 @@ |
loader->gloader = gloader; |
} |
- loader->load_flags = load_flags; |
+ 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; |