| Index: third_party/freetype/src/truetype/ttgload.c
|
| diff --git a/core/src/fxge/fx_freetype/fxft2.5.01/src/truetype/ttgload.c b/third_party/freetype/src/truetype/ttgload.c
|
| similarity index 85%
|
| rename from core/src/fxge/fx_freetype/fxft2.5.01/src/truetype/ttgload.c
|
| rename to third_party/freetype/src/truetype/ttgload.c
|
| index c32419b77d9a7e80e1bcb0855f2cc27e00b87db3..c5841c301d2891f131375cc1162ffea6f03d2131 100644
|
| --- a/core/src/fxge/fx_freetype/fxft2.5.01/src/truetype/ttgload.c
|
| +++ b/third_party/freetype/src/truetype/ttgload.c
|
| @@ -4,7 +4,7 @@
|
| /* */
|
| /* TrueType Glyph Loader (body). */
|
| /* */
|
| -/* Copyright 1996-2013 */
|
| +/* Copyright 1996-2014 */
|
| /* David Turner, Robert Wilhelm, and Werner Lemberg. */
|
| /* */
|
| /* This file is part of the FreeType project, and may only be used, */
|
| @@ -16,15 +16,14 @@
|
| /***************************************************************************/
|
|
|
|
|
| -#include "../../include/ft2build.h"
|
| -#include "../../include/freetype/internal/ftdebug.h"
|
| -#include "../../include/freetype/internal/ftcalc.h"
|
| -#include "../../include/freetype/internal/ftstream.h"
|
| -#include "../../include/freetype/internal/sfnt.h"
|
| -#include "../../include/freetype/tttags.h"
|
| -#include "../../include/freetype/ftoutln.h"
|
| -#include "../../include/freetype/ftttdrv.h"
|
| -
|
| +#include <ft2build.h>
|
| +#include FT_INTERNAL_DEBUG_H
|
| +#include FT_INTERNAL_CALC_H
|
| +#include FT_INTERNAL_STREAM_H
|
| +#include FT_INTERNAL_SFNT_H
|
| +#include FT_TRUETYPE_TAGS_H
|
| +#include FT_OUTLINE_H
|
| +#include FT_TRUETYPE_DRIVER_H
|
|
|
| #include "ttgload.h"
|
| #include "ttpload.h"
|
| @@ -86,51 +85,36 @@
|
| /*************************************************************************/
|
| /* */
|
| /* Return the vertical metrics in font units for a given glyph. */
|
| - /* Greg Hitchcock from Microsoft told us that if there were no `vmtx' */
|
| - /* table, typoAscender/Descender from the `OS/2' table would be used */
|
| - /* instead, and if there were no `OS/2' table, use ascender/descender */
|
| - /* from the `hhea' table. But that is not what Microsoft's rasterizer */
|
| - /* apparently does: It uses the ppem value as the advance height, and */
|
| - /* sets the top side bearing to be zero. */
|
| + /* See macro `TT_LOADER_SET_PP' below for explanations. */
|
| /* */
|
| FT_LOCAL_DEF( void )
|
| TT_Get_VMetrics( TT_Face face,
|
| FT_UInt idx,
|
| + FT_Pos yMax,
|
| FT_Short* tsb,
|
| FT_UShort* ah )
|
| {
|
| if ( face->vertical_info )
|
| ( (SFNT_Service)face->sfnt )->get_metrics( face, 1, idx, tsb, ah );
|
|
|
| -#if 1 /* Empirically determined, at variance with what MS said */
|
| -
|
| - else
|
| - {
|
| - *tsb = 0;
|
| - *ah = face->root.units_per_EM;
|
| - }
|
| -
|
| -#else /* This is what MS said to do. It isn't what they do, however. */
|
| -
|
| else if ( face->os2.version != 0xFFFFU )
|
| {
|
| - *tsb = face->os2.sTypoAscender;
|
| + *tsb = (FT_Short)( face->os2.sTypoAscender - yMax );
|
| *ah = face->os2.sTypoAscender - face->os2.sTypoDescender;
|
| }
|
| +
|
| else
|
| {
|
| - *tsb = face->horizontal.Ascender;
|
| + *tsb = (FT_Short)( face->horizontal.Ascender - yMax );
|
| *ah = face->horizontal.Ascender - face->horizontal.Descender;
|
| }
|
|
|
| -#endif
|
| -
|
| FT_TRACE5(( " advance height (font units): %d\n", *ah ));
|
| FT_TRACE5(( " top side bearing (font units): %d\n", *tsb ));
|
| }
|
|
|
|
|
| - static void
|
| + static FT_Error
|
| tt_get_metrics( TT_Loader loader,
|
| FT_UInt glyph_index )
|
| {
|
| @@ -139,17 +123,28 @@
|
| TT_Driver driver = (TT_Driver)FT_FACE_DRIVER( face );
|
| #endif
|
|
|
| + FT_Error error;
|
| + FT_Stream stream = loader->stream;
|
| +
|
| FT_Short left_bearing = 0, top_bearing = 0;
|
| FT_UShort advance_width = 0, advance_height = 0;
|
|
|
| + /* we must preserve the stream position */
|
| + /* (which gets altered by the metrics functions) */
|
| + FT_ULong pos = FT_STREAM_POS();
|
| +
|
|
|
| TT_Get_HMetrics( face, glyph_index,
|
| &left_bearing,
|
| &advance_width );
|
| TT_Get_VMetrics( face, glyph_index,
|
| + loader->bbox.yMax,
|
| &top_bearing,
|
| &advance_height );
|
|
|
| + if ( FT_STREAM_SEEK( pos ) )
|
| + return error;
|
| +
|
| loader->left_bearing = left_bearing;
|
| loader->advance = advance_width;
|
| loader->top_bearing = top_bearing;
|
| @@ -172,6 +167,8 @@
|
| loader->linear_def = 1;
|
| loader->linear = advance_width;
|
| }
|
| +
|
| + return FT_Err_Ok;
|
| }
|
|
|
|
|
| @@ -351,9 +348,9 @@
|
| FT_GlyphLoader gloader = load->gloader;
|
| FT_Int n_contours = load->n_contours;
|
| FT_Outline* outline;
|
| - TT_Face face = (TT_Face)load->face;
|
| FT_UShort n_ins;
|
| FT_Int n_points;
|
| + FT_ULong tmp;
|
|
|
| FT_Byte *flag, *flag_limit;
|
| FT_Byte c, count;
|
| @@ -419,14 +416,7 @@
|
|
|
| FT_TRACE5(( " Instructions size: %u\n", n_ins ));
|
|
|
| - if ( n_ins > face->max_profile.maxSizeOfInstructions )
|
| - {
|
| - FT_TRACE0(( "TT_Load_Simple_Glyph: too many instructions (%d)\n",
|
| - n_ins ));
|
| - error = FT_THROW( Too_Many_Hints );
|
| - goto Fail;
|
| - }
|
| -
|
| + /* check it */
|
| if ( ( limit - p ) < n_ins )
|
| {
|
| FT_TRACE0(( "TT_Load_Simple_Glyph: instruction count mismatch\n" ));
|
| @@ -438,6 +428,20 @@
|
|
|
| if ( IS_HINTED( load->load_flags ) )
|
| {
|
| + /* we don't trust `maxSizeOfInstructions' in the `maxp' table */
|
| + /* and thus update the bytecode array size by ourselves */
|
| +
|
| + tmp = load->exec->glyphSize;
|
| + error = Update_Max( load->exec->memory,
|
| + &tmp,
|
| + sizeof ( FT_Byte ),
|
| + (void*)&load->exec->glyphIns,
|
| + n_ins );
|
| +
|
| + load->exec->glyphSize = (FT_UShort)tmp;
|
| + if ( error )
|
| + return error;
|
| +
|
| load->glyph->control_len = n_ins;
|
| load->glyph->control_data = load->exec->glyphIns;
|
|
|
| @@ -449,16 +453,12 @@
|
| p += n_ins;
|
|
|
| outline = &gloader->current.outline;
|
| - if (outline->tags == NULL) {
|
| - FT_TRACE0(( "TT_Load_Simple_Glyph: Outline->tags = NULL!\n" ));
|
| - goto Invalid_Outline;
|
| - }
|
|
|
| /* reading the point tags */
|
| flag = (FT_Byte*)outline->tags;
|
| flag_limit = flag + n_points;
|
|
|
| - //FT_ASSERT( flag != NULL );
|
| + FT_ASSERT( flag != NULL );
|
|
|
| while ( flag < flag_limit )
|
| {
|
| @@ -738,7 +738,6 @@
|
| #endif
|
|
|
| TT_GlyphZone zone = &loader->zone;
|
| - FT_Pos origin;
|
|
|
| #ifdef TT_USE_BYTECODE_INTERPRETER
|
| FT_UInt n_ins;
|
| @@ -750,19 +749,12 @@
|
| #ifdef TT_USE_BYTECODE_INTERPRETER
|
| if ( loader->glyph->control_len > 0xFFFFL )
|
| {
|
| - FT_TRACE1(( "TT_Hint_Glyph: too long instructions " ));
|
| - FT_TRACE1(( "(0x%lx byte) is truncated\n",
|
| + FT_TRACE1(( "TT_Hint_Glyph: too long instructions" ));
|
| + FT_TRACE1(( " (0x%lx byte) is truncated\n",
|
| loader->glyph->control_len ));
|
| }
|
| n_ins = (FT_UInt)( loader->glyph->control_len );
|
| -#endif
|
|
|
| - origin = zone->cur[zone->n_points - 4].x;
|
| - origin = FT_PIX_ROUND( origin ) - origin;
|
| - if ( origin )
|
| - translate_array( zone->n_points, zone->cur, origin, 0 );
|
| -
|
| -#ifdef TT_USE_BYTECODE_INTERPRETER
|
| /* save original point position in org */
|
| if ( n_ins > 0 )
|
| FT_ARRAY_COPY( zone->org, zone->cur, zone->n_points );
|
| @@ -788,9 +780,13 @@
|
| }
|
| #endif
|
|
|
| - /* round pp2 and pp4 */
|
| + /* round phantom points */
|
| + zone->cur[zone->n_points - 4].x =
|
| + FT_PIX_ROUND( zone->cur[zone->n_points - 4].x );
|
| zone->cur[zone->n_points - 3].x =
|
| FT_PIX_ROUND( zone->cur[zone->n_points - 3].x );
|
| + zone->cur[zone->n_points - 2].y =
|
| + FT_PIX_ROUND( zone->cur[zone->n_points - 2].y );
|
| zone->cur[zone->n_points - 1].y =
|
| FT_PIX_ROUND( zone->cur[zone->n_points - 1].y );
|
|
|
| @@ -805,10 +801,8 @@
|
| FT_Outline current_outline = gloader->current.outline;
|
|
|
|
|
| - error = TT_Set_CodeRange( loader->exec, tt_coderange_glyph,
|
| - loader->exec->glyphIns, n_ins );
|
| - if ( error )
|
| - return error;
|
| + TT_Set_CodeRange( loader->exec, tt_coderange_glyph,
|
| + loader->exec->glyphIns, n_ins );
|
|
|
| loader->exec->is_composite = is_composite;
|
| loader->exec->pts = *zone;
|
| @@ -828,13 +822,10 @@
|
| #endif
|
|
|
| /* save glyph phantom points */
|
| - if ( !loader->preserve_pps )
|
| - {
|
| - loader->pp1 = zone->cur[zone->n_points - 4];
|
| - loader->pp2 = zone->cur[zone->n_points - 3];
|
| - loader->pp3 = zone->cur[zone->n_points - 2];
|
| - loader->pp4 = zone->cur[zone->n_points - 1];
|
| - }
|
| + loader->pp1 = zone->cur[zone->n_points - 4];
|
| + loader->pp2 = zone->cur[zone->n_points - 3];
|
| + loader->pp3 = zone->cur[zone->n_points - 2];
|
| + loader->pp4 = zone->cur[zone->n_points - 1];
|
|
|
| #ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
|
| if ( driver->interpreter_version == TT_INTERPRETER_VERSION_38 )
|
| @@ -1002,11 +993,7 @@
|
| }
|
| }
|
|
|
| - /**We Disable HINT except tricky font, seem it looks better, #Testdoc:0000584_Open_CAC5U7WH.pdf,
|
| - 0000879_Image_MSFNUnattendedPDF.pdf,0005480_sample-barcodes print.pdf.
|
| - */
|
| -
|
| - if ( IS_HINTED( loader->load_flags ) && (loader->face->face_flags&FT_FACE_FLAG_TRICKY))
|
| + if ( IS_HINTED( loader->load_flags ) )
|
| {
|
| loader->zone.n_points += 4;
|
|
|
| @@ -1086,9 +1073,9 @@
|
| if ( !x && !y )
|
| return FT_Err_Ok;
|
|
|
| - /* Use a default value dependent on */
|
| - /* TT_CONFIG_OPTION_COMPONENT_OFFSET_SCALED. This is useful for old TT */
|
| - /* fonts which don't set the xxx_COMPONENT_OFFSET bit. */
|
| + /* Use a default value dependent on */
|
| + /* TT_CONFIG_OPTION_COMPONENT_OFFSET_SCALED. This is useful for old */
|
| + /* TT fonts which don't set the xxx_COMPONENT_OFFSET bit. */
|
|
|
| if ( have_scale &&
|
| #ifdef TT_CONFIG_OPTION_COMPONENT_OFFSET_SCALED
|
| @@ -1100,10 +1087,10 @@
|
|
|
| #if 0
|
|
|
| - /*************************************************************************/
|
| - /* */
|
| - /* This algorithm is what Apple documents. But it doesn't work. */
|
| - /* */
|
| + /*******************************************************************/
|
| + /* */
|
| + /* This algorithm is what Apple documents. But it doesn't work. */
|
| + /* */
|
| int a = subglyph->transform.xx > 0 ? subglyph->transform.xx
|
| : -subglyph->transform.xx;
|
| int b = subglyph->transform.yx > 0 ? subglyph->transform.yx
|
| @@ -1123,12 +1110,12 @@
|
| x = FT_MulFix( x, m );
|
| y = FT_MulFix( y, n );
|
|
|
| -#else /* 0 */
|
| +#else /* 1 */
|
|
|
| - /*************************************************************************/
|
| - /* */
|
| - /* This algorithm is a guess and works much better than the above. */
|
| - /* */
|
| + /*******************************************************************/
|
| + /* */
|
| + /* This algorithm is a guess and works much better than the above. */
|
| + /* */
|
| FT_Fixed mac_xscale = FT_Hypot( subglyph->transform.xx,
|
| subglyph->transform.xy );
|
| FT_Fixed mac_yscale = FT_Hypot( subglyph->transform.yy,
|
| @@ -1138,7 +1125,7 @@
|
| x = FT_MulFix( x, mac_xscale );
|
| y = FT_MulFix( y, mac_yscale );
|
|
|
| -#endif /* 0 */
|
| +#endif /* 1 */
|
|
|
| }
|
|
|
| @@ -1227,21 +1214,23 @@
|
| max_ins = ((TT_Face)loader->face)->max_profile.maxSizeOfInstructions;
|
| if ( n_ins > max_ins )
|
| {
|
| - /* acroread ignores this field, so we only do a rough safety check */
|
| + /* don't trust `maxSizeOfInstructions'; */
|
| + /* only do a rough safety check */
|
| if ( (FT_Int)n_ins > loader->byte_len )
|
| {
|
| - FT_TRACE1(( "TT_Process_Composite_Glyph: "
|
| - "too many instructions (%d) for glyph with length %d\n",
|
| + FT_TRACE1(( "TT_Process_Composite_Glyph:"
|
| + " too many instructions (%d) for glyph with length %d\n",
|
| n_ins, loader->byte_len ));
|
| return FT_THROW( Too_Many_Hints );
|
| }
|
|
|
| - tmp = loader->exec->glyphSize;
|
| + tmp = loader->exec->glyphSize;
|
| error = Update_Max( loader->exec->memory,
|
| &tmp,
|
| sizeof ( FT_Byte ),
|
| (void*)&loader->exec->glyphIns,
|
| n_ins );
|
| +
|
| loader->exec->glyphSize = (FT_UShort)tmp;
|
| if ( error )
|
| return error;
|
| @@ -1263,7 +1252,7 @@
|
|
|
| /* Some points are likely touched during execution of */
|
| /* instructions on components. So let's untouch them. */
|
| - for ( i = start_point; i < loader->zone.n_points; i++ )
|
| + for ( i = 0; i < loader->zone.n_points; i++ )
|
| loader->zone.tags[i] &= ~FT_CURVE_TAG_TOUCH_BOTH;
|
|
|
| loader->zone.n_points += 4;
|
| @@ -1272,21 +1261,131 @@
|
| }
|
|
|
|
|
| - /* Calculate the four phantom points. */
|
| - /* The first two stand for horizontal origin and advance. */
|
| - /* The last two stand for vertical origin and advance. */
|
| + /*
|
| + * Calculate the phantom points
|
| + *
|
| + * Defining the right side bearing (rsb) as
|
| + *
|
| + * rsb = aw - (lsb + xmax - xmin)
|
| + *
|
| + * (with `aw' the advance width, `lsb' the left side bearing, and `xmin'
|
| + * and `xmax' the glyph's minimum and maximum x value), the OpenType
|
| + * specification defines the initial position of horizontal phantom points
|
| + * as
|
| + *
|
| + * pp1 = (round(xmin - lsb), 0) ,
|
| + * pp2 = (round(pp1 + aw), 0) .
|
| + *
|
| + * Note that the rounding to the grid (in the device space) is not
|
| + * documented currently in the specification.
|
| + *
|
| + * However, the specification lacks the precise definition of vertical
|
| + * phantom points. Greg Hitchcock provided the following explanation.
|
| + *
|
| + * - a `vmtx' table is present
|
| + *
|
| + * For any glyph, the minimum and maximum y values (`ymin' and `ymax')
|
| + * are given in the `glyf' table, the top side bearing (tsb) and advance
|
| + * height (ah) are given in the `vmtx' table. The bottom side bearing
|
| + * (bsb) is then calculated as
|
| + *
|
| + * bsb = ah - (tsb + ymax - ymin) ,
|
| + *
|
| + * and the initial position of vertical phantom points is
|
| + *
|
| + * pp3 = (x, round(ymax + tsb)) ,
|
| + * pp4 = (x, round(pp3 - ah)) .
|
| + *
|
| + * See below for value `x'.
|
| + *
|
| + * - no `vmtx' table in the font
|
| + *
|
| + * If there is an `OS/2' table, we set
|
| + *
|
| + * DefaultAscender = sTypoAscender ,
|
| + * DefaultDescender = sTypoDescender ,
|
| + *
|
| + * otherwise we use data from the `hhea' table:
|
| + *
|
| + * DefaultAscender = Ascender ,
|
| + * DefaultDescender = Descender .
|
| + *
|
| + * With these two variables we can now set
|
| + *
|
| + * ah = DefaultAscender - sDefaultDescender ,
|
| + * tsb = DefaultAscender - yMax ,
|
| + *
|
| + * and proceed as if a `vmtx' table was present.
|
| + *
|
| + * Usually we have
|
| + *
|
| + * x = aw / 2 , (1)
|
| + *
|
| + * but there is one compatibility case where it can be set to
|
| + *
|
| + * x = -DefaultDescender -
|
| + * ((DefaultAscender - DefaultDescender - aw) / 2) . (2)
|
| + *
|
| + * and another one with
|
| + *
|
| + * x = 0 . (3)
|
| + *
|
| + * In Windows, the history of those values is quite complicated,
|
| + * depending on the hinting engine (that is, the graphics framework).
|
| + *
|
| + * framework from to formula
|
| + * ----------------------------------------------------------
|
| + * GDI Windows 98 current (1)
|
| + * (Windows 2000 for NT)
|
| + * GDI+ Windows XP Windows 7 (2)
|
| + * GDI+ Windows 8 current (3)
|
| + * DWrite Windows 7 current (3)
|
| + *
|
| + * For simplicity, FreeType uses (1) for grayscale subpixel hinting and
|
| + * (3) for everything else.
|
| + *
|
| + */
|
| +#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
|
| +
|
| +#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_ ); \
|
| + \
|
| + \
|
| + (loader)->pp1.x = (loader)->bbox.xMin - (loader)->left_bearing; \
|
| + (loader)->pp1.y = 0; \
|
| + (loader)->pp2.x = (loader)->pp1.x + (loader)->advance; \
|
| + (loader)->pp2.y = 0; \
|
| + \
|
| + (loader)->pp3.x = use_aw_2_ ? (loader)->advance / 2 : 0; \
|
| + (loader)->pp3.y = (loader)->bbox.yMax + (loader)->top_bearing; \
|
| + (loader)->pp4.x = use_aw_2_ ? (loader)->advance / 2 : 0; \
|
| + (loader)->pp4.y = (loader)->pp3.y - (loader)->vadvance; \
|
| + } while ( 0 )
|
| +
|
| +#else /* !TT_CONFIG_OPTION_SUBPIXEL_HINTING */
|
| +
|
| #define TT_LOADER_SET_PP( loader ) \
|
| - do { \
|
| + do \
|
| + { \
|
| (loader)->pp1.x = (loader)->bbox.xMin - (loader)->left_bearing; \
|
| (loader)->pp1.y = 0; \
|
| (loader)->pp2.x = (loader)->pp1.x + (loader)->advance; \
|
| (loader)->pp2.y = 0; \
|
| + \
|
| (loader)->pp3.x = 0; \
|
| - (loader)->pp3.y = (loader)->top_bearing + (loader)->bbox.yMax; \
|
| + (loader)->pp3.y = (loader)->bbox.yMax + (loader)->top_bearing; \
|
| (loader)->pp4.x = 0; \
|
| (loader)->pp4.y = (loader)->pp3.y - (loader)->vadvance; \
|
| } while ( 0 )
|
|
|
| +#endif /* !TT_CONFIG_OPTION_SUBPIXEL_HINTING */
|
| +
|
|
|
| /*************************************************************************/
|
| /* */
|
| @@ -1350,8 +1449,6 @@
|
| y_scale = 0x10000L;
|
| }
|
|
|
| - tt_get_metrics( loader, glyph_index );
|
| -
|
| /* Set `offset' to the start of the glyph relative to the start of */
|
| /* the `glyf' table, and `byte_len' to the length of the glyph in */
|
| /* bytes. */
|
| @@ -1411,7 +1508,17 @@
|
|
|
| /* read glyph header first */
|
| error = face->read_glyph_header( loader );
|
| - if ( error || header_only )
|
| + if ( error )
|
| + goto Exit;
|
| +
|
| + /* the metrics must be computed after loading the glyph header */
|
| + /* since we need the glyph's `yMax' value in case the vertical */
|
| + /* metrics must be emulated */
|
| + error = tt_get_metrics( loader, glyph_index );
|
| + if ( error )
|
| + goto Exit;
|
| +
|
| + if ( header_only )
|
| goto Exit;
|
| }
|
|
|
| @@ -1422,6 +1529,10 @@
|
| loader->bbox.yMin = 0;
|
| loader->bbox.yMax = 0;
|
|
|
| + error = tt_get_metrics( loader, glyph_index );
|
| + if ( error )
|
| + goto Exit;
|
| +
|
| if ( header_only )
|
| goto Exit;
|
|
|
| @@ -1446,21 +1557,32 @@
|
| 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 += 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;
|
|
|
| FT_FREE( deltas );
|
| }
|
|
|
| -#endif
|
| +#endif /* TT_CONFIG_OPTION_GX_VAR_SUPPORT */
|
|
|
| + /* scale phantom points, if necessary; */
|
| + /* they get rounded in `TT_Hint_Glyph' */
|
| if ( ( loader->load_flags & FT_LOAD_NO_SCALE ) == 0 )
|
| {
|
| loader->pp1.x = FT_MulFix( loader->pp1.x, x_scale );
|
| loader->pp2.x = FT_MulFix( loader->pp2.x, x_scale );
|
| + /* pp1.y and pp2.y are always zero */
|
| +
|
| + loader->pp3.x = FT_MulFix( loader->pp3.x, x_scale );
|
| loader->pp3.y = FT_MulFix( loader->pp3.y, y_scale );
|
| + loader->pp4.x = FT_MulFix( loader->pp4.x, x_scale );
|
| loader->pp4.y = FT_MulFix( loader->pp4.y, y_scale );
|
| }
|
|
|
| @@ -1468,8 +1590,8 @@
|
| goto Exit;
|
| }
|
|
|
| - /* must initialize points before (possibly) overriding */
|
| - /* glyph metrics from the incremental interface */
|
| + /* must initialize phantom points before (possibly) overriding */
|
| + /* glyph metrics from the incremental interface */
|
| TT_LOADER_SET_PP( loader );
|
|
|
| #ifdef FT_CONFIG_OPTION_INCREMENTAL
|
| @@ -1542,7 +1664,7 @@
|
| face,
|
| glyph_index,
|
| &deltas,
|
| - gloader->current.num_subglyphs + 4 )) != 0 )
|
| + gloader->current.num_subglyphs + 4 ) ) != 0 )
|
| goto Exit;
|
|
|
| subglyph = gloader->current.subglyphs + gloader->base.num_subglyphs;
|
| @@ -1560,21 +1682,32 @@
|
| }
|
| }
|
|
|
| - 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->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;
|
| + 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->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;
|
|
|
| FT_FREE( deltas );
|
| }
|
|
|
| #endif /* TT_CONFIG_OPTION_GX_VAR_SUPPORT */
|
|
|
| + /* scale phantom points, if necessary; */
|
| + /* they get rounded in `TT_Hint_Glyph' */
|
| if ( ( loader->load_flags & FT_LOAD_NO_SCALE ) == 0 )
|
| {
|
| loader->pp1.x = FT_MulFix( loader->pp1.x, x_scale );
|
| loader->pp2.x = FT_MulFix( loader->pp2.x, x_scale );
|
| + /* pp1.y and pp2.y are always zero */
|
| +
|
| + loader->pp3.x = FT_MulFix( loader->pp3.x, x_scale );
|
| loader->pp3.y = FT_MulFix( loader->pp3.y, y_scale );
|
| + loader->pp4.x = FT_MulFix( loader->pp4.x, x_scale );
|
| loader->pp4.y = FT_MulFix( loader->pp4.y, y_scale );
|
| }
|
|
|
| @@ -1634,6 +1767,7 @@
|
| /* restore subglyph pointer */
|
| subglyph = gloader->base.subglyphs + num_base_subgs + n;
|
|
|
| + /* restore phantom points if necessary */
|
| if ( !( subglyph->flags & USE_MY_METRICS ) )
|
| {
|
| loader->pp1 = pp[0];
|
| @@ -1653,8 +1787,12 @@
|
| /* (1): exists from the beginning */
|
| /* (2): components that have been loaded so far */
|
| /* (3): the newly loaded component */
|
| - TT_Process_Composite_Component( loader, subglyph, start_point,
|
| - num_base_points );
|
| + error = TT_Process_Composite_Component( loader,
|
| + subglyph,
|
| + start_point,
|
| + num_base_points );
|
| + if ( error )
|
| + goto Exit;
|
| }
|
|
|
| loader->stream = old_stream;
|
| @@ -1663,16 +1801,17 @@
|
| /* process the glyph */
|
| loader->ins_pos = ins_pos;
|
| if ( IS_HINTED( loader->load_flags ) &&
|
| -
|
| #ifdef TT_USE_BYTECODE_INTERPRETER
|
| -
|
| subglyph->flags & WE_HAVE_INSTR &&
|
| -
|
| #endif
|
| -
|
| num_points > start_point )
|
| - TT_Process_Composite_Glyph( loader, start_point, start_contour );
|
| -
|
| + {
|
| + error = TT_Process_Composite_Glyph( loader,
|
| + start_point,
|
| + start_contour );
|
| + if ( error )
|
| + goto Exit;
|
| + }
|
| }
|
| }
|
| else
|
| @@ -1947,6 +2086,8 @@
|
| FT_Int32 load_flags,
|
| FT_Bool glyf_table_only )
|
| {
|
| + FT_Error error;
|
| +
|
| TT_Face face;
|
| FT_Stream stream;
|
| #ifdef TT_USE_BYTECODE_INTERPRETER
|
| @@ -1970,8 +2111,7 @@
|
| #ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
|
| TT_Driver driver = (TT_Driver)FT_FACE_DRIVER( face );
|
|
|
| - FT_Bool subpixel_hinting = FALSE;
|
| - FT_Bool grayscale_hinting = TRUE;
|
| + FT_Bool subpixel = FALSE;
|
|
|
| #if 0
|
| /* not used yet */
|
| @@ -1985,14 +2125,16 @@
|
| FT_Bool reexecute = FALSE;
|
|
|
|
|
| - if ( !size->cvt_ready )
|
| + if ( size->bytecode_ready < 0 || size->cvt_ready < 0 )
|
| {
|
| - FT_Error error = tt_size_ready_bytecode( size, pedantic );
|
| -
|
| -
|
| + error = tt_size_ready_bytecode( size, pedantic );
|
| if ( error )
|
| return error;
|
| }
|
| + else if ( size->bytecode_ready )
|
| + return size->bytecode_ready;
|
| + else if ( size->cvt_ready )
|
| + return size->cvt_ready;
|
|
|
| /* query new execution context */
|
| exec = size->debug ? size->context
|
| @@ -2004,24 +2146,24 @@
|
|
|
| if ( driver->interpreter_version == TT_INTERPRETER_VERSION_38 )
|
| {
|
| - subpixel_hinting = FT_BOOL( ( FT_LOAD_TARGET_MODE( load_flags )
|
| - != FT_RENDER_MODE_MONO ) &&
|
| - SPH_OPTION_SET_SUBPIXEL );
|
| + subpixel = FT_BOOL( ( FT_LOAD_TARGET_MODE( load_flags ) !=
|
| + FT_RENDER_MODE_MONO ) &&
|
| + SPH_OPTION_SET_SUBPIXEL );
|
|
|
| - if ( subpixel_hinting )
|
| - grayscale = grayscale_hinting = FALSE;
|
| + if ( subpixel )
|
| + grayscale = FALSE;
|
| else if ( SPH_OPTION_SET_GRAYSCALE )
|
| {
|
| - grayscale = grayscale_hinting = TRUE;
|
| - subpixel_hinting = FALSE;
|
| + grayscale = TRUE;
|
| + subpixel = FALSE;
|
| }
|
| else
|
| - grayscale = grayscale_hinting = FALSE;
|
| + grayscale = FALSE;
|
|
|
| if ( FT_IS_TRICKY( glyph->face ) )
|
| - subpixel_hinting = grayscale_hinting = FALSE;
|
| + subpixel = FALSE;
|
|
|
| - exec->ignore_x_mode = subpixel_hinting || grayscale_hinting;
|
| + exec->ignore_x_mode = subpixel || 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;
|
| @@ -2056,7 +2198,9 @@
|
| FT_RENDER_MODE_MONO );
|
| }
|
|
|
| - TT_Load_Context( exec, face, size );
|
| + error = TT_Load_Context( exec, face, size );
|
| + if ( error )
|
| + return error;
|
|
|
| #ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
|
|
|
| @@ -2064,24 +2208,24 @@
|
| {
|
| /* a change from mono to subpixel rendering (and vice versa) */
|
| /* requires a re-execution of the CVT program */
|
| - if ( subpixel_hinting != exec->subpixel_hinting )
|
| + if ( subpixel != exec->subpixel )
|
| {
|
| FT_TRACE4(( "tt_loader_init: subpixel hinting change,"
|
| " re-executing `prep' table\n" ));
|
|
|
| - exec->subpixel_hinting = subpixel_hinting;
|
| - reexecute = TRUE;
|
| + exec->subpixel = subpixel;
|
| + reexecute = TRUE;
|
| }
|
|
|
| /* a change from mono to grayscale rendering (and vice versa) */
|
| /* requires a re-execution of the CVT program */
|
| - if ( grayscale != exec->grayscale_hinting )
|
| + if ( grayscale != exec->grayscale )
|
| {
|
| FT_TRACE4(( "tt_loader_init: grayscale hinting change,"
|
| " re-executing `prep' table\n" ));
|
|
|
| - exec->grayscale_hinting = grayscale_hinting;
|
| - reexecute = TRUE;
|
| + exec->grayscale = grayscale;
|
| + reexecute = TRUE;
|
| }
|
| }
|
| else
|
| @@ -2108,7 +2252,9 @@
|
|
|
| for ( i = 0; i < size->cvt_size; i++ )
|
| size->cvt[i] = FT_MulFix( face->cvt[i], size->ttmetrics.scale );
|
| - tt_size_run_prep( size, pedantic );
|
| + error = tt_size_run_prep( size, pedantic );
|
| + if ( error )
|
| + return error;
|
| }
|
|
|
| /* see whether the cvt program has disabled hinting */
|
| @@ -2139,8 +2285,7 @@
|
| #endif
|
|
|
| {
|
| - FT_Error error = face->goto_table( face, TTAG_glyf, stream, 0 );
|
| -
|
| + error = face->goto_table( face, TTAG_glyf, stream, 0 );
|
|
|
| if ( FT_ERR_EQ( error, Table_Missing ) )
|
| loader->glyf_offset = 0;
|
| @@ -2211,7 +2356,7 @@
|
| TT_LoaderRec loader;
|
|
|
|
|
| - error = FT_Err_Ok;
|
| + FT_TRACE1(( "TT_Load_Glyph: glyph index %d\n", glyph_index ));
|
|
|
| #ifdef TT_CONFIG_OPTION_EMBEDDED_BITMAPS
|
|
|
| @@ -2231,15 +2376,18 @@
|
| (void)tt_loader_init( &loader, size, glyph, load_flags, TRUE );
|
| (void)load_truetype_glyph( &loader, glyph_index, 0, TRUE );
|
| glyph->linearHoriAdvance = loader.linear;
|
| - glyph->linearVertAdvance = loader.top_bearing + loader.bbox.yMax -
|
| - loader.vadvance;
|
| + glyph->linearVertAdvance = loader.vadvance;
|
|
|
| - /* sanity check: if `horiAdvance' in the sbit metric */
|
| - /* structure isn't set, use `linearHoriAdvance' */
|
| + /* sanity checks: if `xxxAdvance' in the sbit metric */
|
| + /* structure isn't set, use `linearXXXAdvance' */
|
| if ( !glyph->metrics.horiAdvance && glyph->linearHoriAdvance )
|
| glyph->metrics.horiAdvance =
|
| FT_MulFix( glyph->linearHoriAdvance,
|
| size->root.metrics.x_scale );
|
| + if ( !glyph->metrics.vertAdvance && glyph->linearVertAdvance )
|
| + glyph->metrics.vertAdvance =
|
| + FT_MulFix( glyph->linearVertAdvance,
|
| + size->root.metrics.y_scale );
|
| }
|
|
|
| return FT_Err_Ok;
|
| @@ -2319,7 +2467,7 @@
|
|
|
| #endif /* TT_USE_BYTECODE_INTERPRETER */
|
|
|
| - compute_glyph_metrics( &loader, glyph_index );
|
| + error = compute_glyph_metrics( &loader, glyph_index );
|
| }
|
|
|
| /* Set the `high precision' bit flag. */
|
|
|