summaryrefslogtreecommitdiffstats
path: root/src/3rdparty/freetype/src/truetype
diff options
context:
space:
mode:
Diffstat (limited to 'src/3rdparty/freetype/src/truetype')
-rw-r--r--src/3rdparty/freetype/src/truetype/Jamfile12
-rw-r--r--src/3rdparty/freetype/src/truetype/module.mk2
-rw-r--r--src/3rdparty/freetype/src/truetype/rules.mk7
-rw-r--r--src/3rdparty/freetype/src/truetype/truetype.c2
-rw-r--r--src/3rdparty/freetype/src/truetype/ttdriver.c16
-rw-r--r--src/3rdparty/freetype/src/truetype/ttdriver.h2
-rw-r--r--src/3rdparty/freetype/src/truetype/tterrors.h2
-rw-r--r--src/3rdparty/freetype/src/truetype/ttgload.c496
-rw-r--r--src/3rdparty/freetype/src/truetype/ttgload.h2
-rw-r--r--src/3rdparty/freetype/src/truetype/ttgxvar.c948
-rw-r--r--src/3rdparty/freetype/src/truetype/ttgxvar.h10
-rw-r--r--src/3rdparty/freetype/src/truetype/ttinterp.c5994
-rw-r--r--src/3rdparty/freetype/src/truetype/ttinterp.h64
-rw-r--r--src/3rdparty/freetype/src/truetype/ttobjs.c127
-rw-r--r--src/3rdparty/freetype/src/truetype/ttobjs.h23
-rw-r--r--src/3rdparty/freetype/src/truetype/ttpic.c2
-rw-r--r--src/3rdparty/freetype/src/truetype/ttpic.h12
-rw-r--r--src/3rdparty/freetype/src/truetype/ttpload.c24
-rw-r--r--src/3rdparty/freetype/src/truetype/ttpload.h2
-rw-r--r--src/3rdparty/freetype/src/truetype/ttsubpix.c86
-rw-r--r--src/3rdparty/freetype/src/truetype/ttsubpix.h42
21 files changed, 3879 insertions, 3996 deletions
diff --git a/src/3rdparty/freetype/src/truetype/Jamfile b/src/3rdparty/freetype/src/truetype/Jamfile
index a8cccfe137..88cc26f2b1 100644
--- a/src/3rdparty/freetype/src/truetype/Jamfile
+++ b/src/3rdparty/freetype/src/truetype/Jamfile
@@ -1,6 +1,6 @@
# FreeType 2 src/truetype Jamfile
#
-# Copyright 2001, 2004 by
+# Copyright 2001-2015 by
# David Turner, Robert Wilhelm, and Werner Lemberg.
#
# This file is part of the FreeType project, and may only be used, modified,
@@ -16,7 +16,15 @@ SubDir FT2_TOP $(FT2_SRC_DIR) truetype ;
if $(FT2_MULTI)
{
- _sources = ttdriver ttobjs ttpload ttgload ttinterp ttgxvar ttpic ;
+ _sources = ttdriver
+ ttgload
+ ttgxvar
+ ttinterp
+ ttobjs
+ ttpic
+ ttpload
+ ttsubpix
+ ;
}
else
{
diff --git a/src/3rdparty/freetype/src/truetype/module.mk b/src/3rdparty/freetype/src/truetype/module.mk
index baee81a773..c6dc6fa6e7 100644
--- a/src/3rdparty/freetype/src/truetype/module.mk
+++ b/src/3rdparty/freetype/src/truetype/module.mk
@@ -3,7 +3,7 @@
#
-# Copyright 1996-2000, 2006 by
+# Copyright 1996-2015 by
# David Turner, Robert Wilhelm, and Werner Lemberg.
#
# This file is part of the FreeType project, and may only be used, modified,
diff --git a/src/3rdparty/freetype/src/truetype/rules.mk b/src/3rdparty/freetype/src/truetype/rules.mk
index d4b69f578b..1db16ba35f 100644
--- a/src/3rdparty/freetype/src/truetype/rules.mk
+++ b/src/3rdparty/freetype/src/truetype/rules.mk
@@ -3,7 +3,7 @@
#
-# Copyright 1996-2001, 2003-2004, 2011-2012 by
+# Copyright 1996-2015 by
# David Turner, Robert Wilhelm, and Werner Lemberg.
#
# This file is part of the FreeType project, and may only be used, modified,
@@ -20,7 +20,10 @@ TT_DIR := $(SRC_DIR)/truetype
# compilation flags for the driver
#
-TT_COMPILE := $(FT_COMPILE) $I$(subst /,$(COMPILER_SEP),$(TT_DIR))
+TT_COMPILE := $(CC) $(ANSIFLAGS) \
+ $I$(subst /,$(COMPILER_SEP),$(TT_DIR)) \
+ $(INCLUDE_FLAGS) \
+ $(FT_CFLAGS)
# TrueType driver sources (i.e., C files)
diff --git a/src/3rdparty/freetype/src/truetype/truetype.c b/src/3rdparty/freetype/src/truetype/truetype.c
index 576912b219..f929437dc1 100644
--- a/src/3rdparty/freetype/src/truetype/truetype.c
+++ b/src/3rdparty/freetype/src/truetype/truetype.c
@@ -4,7 +4,7 @@
/* */
/* FreeType TrueType driver component (body only). */
/* */
-/* Copyright 1996-2001, 2004, 2006, 2012 by */
+/* Copyright 1996-2015 by */
/* David Turner, Robert Wilhelm, and Werner Lemberg. */
/* */
/* This file is part of the FreeType project, and may only be used, */
diff --git a/src/3rdparty/freetype/src/truetype/ttdriver.c b/src/3rdparty/freetype/src/truetype/ttdriver.c
index ecf4cdcb41..08b30c95ad 100644
--- a/src/3rdparty/freetype/src/truetype/ttdriver.c
+++ b/src/3rdparty/freetype/src/truetype/ttdriver.c
@@ -4,7 +4,7 @@
/* */
/* TrueType font driver implementation (body). */
/* */
-/* Copyright 1996-2014 by */
+/* Copyright 1996-2015 by */
/* David Turner, Robert Wilhelm, and Werner Lemberg. */
/* */
/* This file is part of the FreeType project, and may only be used, */
@@ -20,7 +20,7 @@
#include FT_INTERNAL_DEBUG_H
#include FT_INTERNAL_STREAM_H
#include FT_INTERNAL_SFNT_H
-#include FT_SERVICE_XFREE86_NAME_H
+#include FT_SERVICE_FONT_FORMAT_H
#ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT
#include FT_MULTIPLE_MASTERS_H
@@ -134,11 +134,6 @@
/*************************************************************************/
-#undef PAIR_TAG
-#define PAIR_TAG( left, right ) ( ( (FT_ULong)left << 16 ) | \
- (FT_ULong)right )
-
-
/*************************************************************************/
/* */
/* <Function> */
@@ -191,9 +186,6 @@
}
-#undef PAIR_TAG
-
-
static FT_Error
tt_get_advances( FT_Face ttface,
FT_UInt start,
@@ -456,7 +448,7 @@
#ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT
FT_DEFINE_SERVICEDESCREC5(
tt_services,
- FT_SERVICE_ID_XF86_NAME, FT_XF86_FORMAT_TRUETYPE,
+ FT_SERVICE_ID_FONT_FORMAT, FT_FONT_FORMAT_TRUETYPE,
FT_SERVICE_ID_MULTI_MASTERS, &TT_SERVICE_GX_MULTI_MASTERS_GET,
FT_SERVICE_ID_TRUETYPE_ENGINE, &tt_service_truetype_engine,
FT_SERVICE_ID_TT_GLYF, &TT_SERVICE_TRUETYPE_GLYF_GET,
@@ -464,7 +456,7 @@
#else
FT_DEFINE_SERVICEDESCREC4(
tt_services,
- FT_SERVICE_ID_XF86_NAME, FT_XF86_FORMAT_TRUETYPE,
+ FT_SERVICE_ID_FONT_FORMAT, FT_FONT_FORMAT_TRUETYPE,
FT_SERVICE_ID_TRUETYPE_ENGINE, &tt_service_truetype_engine,
FT_SERVICE_ID_TT_GLYF, &TT_SERVICE_TRUETYPE_GLYF_GET,
FT_SERVICE_ID_PROPERTIES, &TT_SERVICE_PROPERTIES_GET )
diff --git a/src/3rdparty/freetype/src/truetype/ttdriver.h b/src/3rdparty/freetype/src/truetype/ttdriver.h
index aae00f2617..6cacd60966 100644
--- a/src/3rdparty/freetype/src/truetype/ttdriver.h
+++ b/src/3rdparty/freetype/src/truetype/ttdriver.h
@@ -4,7 +4,7 @@
/* */
/* High-level TrueType driver interface (specification). */
/* */
-/* Copyright 1996-2001, 2002 by */
+/* Copyright 1996-2015 by */
/* David Turner, Robert Wilhelm, and Werner Lemberg. */
/* */
/* This file is part of the FreeType project, and may only be used, */
diff --git a/src/3rdparty/freetype/src/truetype/tterrors.h b/src/3rdparty/freetype/src/truetype/tterrors.h
index 78d138fab2..ba32cf744c 100644
--- a/src/3rdparty/freetype/src/truetype/tterrors.h
+++ b/src/3rdparty/freetype/src/truetype/tterrors.h
@@ -4,7 +4,7 @@
/* */
/* TrueType error codes (specification only). */
/* */
-/* Copyright 2001, 2012 by */
+/* Copyright 2001-2015 by */
/* David Turner, Robert Wilhelm, and Werner Lemberg. */
/* */
/* This file is part of the FreeType project, and may only be used, */
diff --git a/src/3rdparty/freetype/src/truetype/ttgload.c b/src/3rdparty/freetype/src/truetype/ttgload.c
index c5841c301d..a792ad44a0 100644
--- a/src/3rdparty/freetype/src/truetype/ttgload.c
+++ b/src/3rdparty/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( &current, &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( &current, 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;
diff --git a/src/3rdparty/freetype/src/truetype/ttgload.h b/src/3rdparty/freetype/src/truetype/ttgload.h
index 3f1699e686..8e3255e106 100644
--- a/src/3rdparty/freetype/src/truetype/ttgload.h
+++ b/src/3rdparty/freetype/src/truetype/ttgload.h
@@ -4,7 +4,7 @@
/* */
/* TrueType Glyph Loader (specification). */
/* */
-/* Copyright 1996-2006, 2008, 2011 by */
+/* Copyright 1996-2015 by */
/* David Turner, Robert Wilhelm, and Werner Lemberg. */
/* */
/* This file is part of the FreeType project, and may only be used, */
diff --git a/src/3rdparty/freetype/src/truetype/ttgxvar.c b/src/3rdparty/freetype/src/truetype/ttgxvar.c
index 1b35539fe1..dd9e250c94 100644
--- a/src/3rdparty/freetype/src/truetype/ttgxvar.c
+++ b/src/3rdparty/freetype/src/truetype/ttgxvar.c
@@ -4,7 +4,7 @@
/* */
/* TrueType GX Font Variation loader */
/* */
-/* Copyright 2004-2014 by */
+/* Copyright 2004-2015 by */
/* David Turner, Robert Wilhelm, Werner Lemberg, and George Williams. */
/* */
/* This file is part of the FreeType project, and may only be used, */
@@ -20,7 +20,7 @@
/* */
/* Apple documents the `fvar', `gvar', `cvar', and `avar' tables at */
/* */
- /* http://developer.apple.com/fonts/TTRefMan/RM06/Chap6[fgca]var.html */
+ /* https://developer.apple.com/fonts/TrueType-Reference-Manual/RM06/Chap6[fgca]var.html */
/* */
/* The documentation for `fvar' is inconsistent. At one point it says */
/* that `countSizePairs' should be 3, at another point 2. It should */
@@ -60,9 +60,9 @@
#ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT
-#define FT_Stream_FTell( stream ) \
+#define FT_Stream_FTell( stream ) \
(FT_ULong)( (stream)->cursor - (stream)->base )
-#define FT_Stream_SeekSet( stream, off ) \
+#define FT_Stream_SeekSet( stream, off ) \
( (stream)->cursor = (stream)->base + (off) )
@@ -96,8 +96,8 @@
#define ALL_POINTS (FT_UShort*)~(FT_PtrDist)0
-#define GX_PT_POINTS_ARE_WORDS 0x80
-#define GX_PT_POINT_RUN_COUNT_MASK 0x7F
+#define GX_PT_POINTS_ARE_WORDS 0x80U
+#define GX_PT_POINT_RUN_COUNT_MASK 0x7FU
/*************************************************************************/
@@ -126,52 +126,67 @@
FT_UInt *point_cnt )
{
FT_UShort *points = NULL;
- FT_Int n;
- FT_Int runcnt;
- FT_Int i;
- FT_Int j;
- FT_Int first;
+ FT_UInt n;
+ FT_UInt runcnt;
+ FT_UInt i, j;
+ FT_UShort first;
FT_Memory memory = stream->memory;
FT_Error error = FT_Err_Ok;
FT_UNUSED( error );
- *point_cnt = n = FT_GET_BYTE();
+ *point_cnt = 0;
+
+ n = FT_GET_BYTE();
if ( n == 0 )
return ALL_POINTS;
if ( n & GX_PT_POINTS_ARE_WORDS )
- n = FT_GET_BYTE() | ( ( n & GX_PT_POINT_RUN_COUNT_MASK ) << 8 );
+ {
+ n &= GX_PT_POINT_RUN_COUNT_MASK;
+ n <<= 8;
+ n |= FT_GET_BYTE();
+ }
if ( FT_NEW_ARRAY( points, n ) )
return NULL;
+ *point_cnt = n;
+
i = 0;
while ( i < n )
{
runcnt = FT_GET_BYTE();
if ( runcnt & GX_PT_POINTS_ARE_WORDS )
{
- runcnt = runcnt & GX_PT_POINT_RUN_COUNT_MASK;
- first = points[i++] = FT_GET_USHORT();
+ runcnt &= GX_PT_POINT_RUN_COUNT_MASK;
+ first = FT_GET_USHORT();
+ points[i++] = first;
- if ( runcnt < 1 || i + runcnt >= n )
+ if ( runcnt < 1 || i + runcnt > n )
goto Exit;
- /* first point not included in runcount */
- for ( j = 0; j < runcnt; ++j )
- points[i++] = (FT_UShort)( first += FT_GET_USHORT() );
+ /* first point not included in run count */
+ for ( j = 0; j < runcnt; j++ )
+ {
+ first += FT_GET_USHORT();
+ points[i++] = first;
+ }
}
else
{
- first = points[i++] = FT_GET_BYTE();
+ first = FT_GET_BYTE();
+ points[i++] = first;
- if ( runcnt < 1 || i + runcnt >= n )
+ if ( runcnt < 1 || i + runcnt > n )
goto Exit;
- for ( j = 0; j < runcnt; ++j )
- points[i++] = (FT_UShort)( first += FT_GET_BYTE() );
+ for ( j = 0; j < runcnt; j++ )
+ {
+ first += FT_GET_BYTE();
+ points[i++] = first;
+ }
}
}
@@ -180,12 +195,9 @@
}
- enum
- {
- GX_DT_DELTAS_ARE_ZERO = 0x80,
- GX_DT_DELTAS_ARE_WORDS = 0x40,
- GX_DT_DELTA_RUN_COUNT_MASK = 0x3F
- };
+#define GX_DT_DELTAS_ARE_ZERO 0x80U
+#define GX_DT_DELTAS_ARE_WORDS 0x40U
+#define GX_DT_DELTA_RUN_COUNT_MASK 0x3FU
/*************************************************************************/
@@ -200,7 +212,7 @@
/* <Input> */
/* stream :: The data stream. */
/* */
- /* delta_cnt :: The number of to be read. */
+ /* delta_cnt :: The number of deltas to be read. */
/* */
/* <Return> */
/* An array of FT_Short containing the deltas for the affected */
@@ -210,12 +222,11 @@
/* */
static FT_Short*
ft_var_readpackeddeltas( FT_Stream stream,
- FT_Offset delta_cnt )
+ FT_UInt delta_cnt )
{
FT_Short *deltas = NULL;
- FT_UInt runcnt;
- FT_Offset i;
- FT_UInt j;
+ FT_UInt runcnt, cnt;
+ FT_UInt i, j;
FT_Memory memory = stream->memory;
FT_Error error = FT_Err_Ok;
@@ -229,34 +240,30 @@
while ( i < delta_cnt )
{
runcnt = FT_GET_BYTE();
+ cnt = runcnt & GX_DT_DELTA_RUN_COUNT_MASK;
+
if ( runcnt & GX_DT_DELTAS_ARE_ZERO )
{
- /* runcnt zeroes get added */
- for ( j = 0;
- j <= ( runcnt & GX_DT_DELTA_RUN_COUNT_MASK ) && i < delta_cnt;
- ++j )
+ /* `runcnt' zeroes get added */
+ for ( j = 0; j <= cnt && i < delta_cnt; j++ )
deltas[i++] = 0;
}
else if ( runcnt & GX_DT_DELTAS_ARE_WORDS )
{
- /* runcnt shorts from the stack */
- for ( j = 0;
- j <= ( runcnt & GX_DT_DELTA_RUN_COUNT_MASK ) && i < delta_cnt;
- ++j )
+ /* `runcnt' shorts from the stack */
+ for ( j = 0; j <= cnt && i < delta_cnt; j++ )
deltas[i++] = FT_GET_SHORT();
}
else
{
- /* runcnt signed bytes from the stack */
- for ( j = 0;
- j <= ( runcnt & GX_DT_DELTA_RUN_COUNT_MASK ) && i < delta_cnt;
- ++j )
+ /* `runcnt' signed bytes from the stack */
+ for ( j = 0; j <= cnt && i < delta_cnt; j++ )
deltas[i++] = FT_GET_CHAR();
}
- if ( j <= ( runcnt & GX_DT_DELTA_RUN_COUNT_MASK ) )
+ if ( j <= cnt )
{
- /* Bad format */
+ /* bad format */
FT_FREE( deltas );
return NULL;
}
@@ -281,12 +288,12 @@
static void
ft_var_load_avar( TT_Face face )
{
- FT_Stream stream = FT_FACE_STREAM(face);
+ FT_Stream stream = FT_FACE_STREAM( face );
FT_Memory memory = stream->memory;
GX_Blend blend = face->blend;
GX_AVarSegment segment;
FT_Error error = FT_Err_Ok;
- FT_ULong version;
+ FT_Long version;
FT_Long axisCount;
FT_Int i, j;
FT_ULong table_len;
@@ -294,9 +301,15 @@
FT_UNUSED( error );
+ FT_TRACE2(( "AVAR " ));
+
blend->avar_checked = TRUE;
- if ( (error = face->goto_table( face, TTAG_avar, stream, &table_len )) != 0 )
+ error = face->goto_table( face, TTAG_avar, stream, &table_len );
+ if ( error )
+ {
+ FT_TRACE2(( "is missing\n" ));
return;
+ }
if ( FT_FRAME_ENTER( table_len ) )
return;
@@ -304,23 +317,36 @@
version = FT_GET_LONG();
axisCount = FT_GET_LONG();
- if ( version != 0x00010000L ||
- axisCount != (FT_Long)blend->mmvar->num_axis )
+ if ( version != 0x00010000L )
+ {
+ FT_TRACE2(( "bad table version\n" ));
+ goto Exit;
+ }
+
+ FT_TRACE2(( "loaded\n" ));
+
+ if ( axisCount != (FT_Long)blend->mmvar->num_axis )
+ {
+ FT_TRACE2(( "ft_var_load_avar: number of axes in `avar' and `cvar'\n"
+ " table are different\n" ));
goto Exit;
+ }
if ( FT_NEW_ARRAY( blend->avar_segment, axisCount ) )
goto Exit;
segment = &blend->avar_segment[0];
- for ( i = 0; i < axisCount; ++i, ++segment )
+ for ( i = 0; i < axisCount; i++, segment++ )
{
+ FT_TRACE5(( " axis %d:\n", i ));
+
segment->pairCount = FT_GET_USHORT();
if ( 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. */
- for ( j = i - 1; j >= 0; --j )
+ for ( j = i - 1; j >= 0; j-- )
FT_FREE( blend->avar_segment[j].correspondence );
FT_FREE( blend->avar_segment );
@@ -328,13 +354,18 @@
goto Exit;
}
- for ( j = 0; j < segment->pairCount; ++j )
+ for ( j = 0; j < segment->pairCount; j++ )
{
- segment->correspondence[j].fromCoord =
- FT_GET_SHORT() << 2; /* convert to Fixed */
- segment->correspondence[j].toCoord =
- FT_GET_SHORT()<<2; /* convert to Fixed */
+ /* convert to Fixed */
+ 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,
+ segment->correspondence[j].toCoord / 65536.0 ));
}
+
+ FT_TRACE5(( "\n" ));
}
Exit:
@@ -361,8 +392,8 @@
/* ft_var_load_gvar */
/* */
/* <Description> */
- /* Parses the `gvar' table if present. If `fvar' is there, `gvar' */
- /* had better be there too. */
+ /* Parse the `gvar' table if present. If `fvar' is there, `gvar' had */
+ /* better be there too. */
/* */
/* <InOut> */
/* face :: The font face. */
@@ -373,7 +404,7 @@
static FT_Error
ft_var_load_gvar( TT_Face face )
{
- FT_Stream stream = FT_FACE_STREAM(face);
+ FT_Stream stream = FT_FACE_STREAM( face );
FT_Memory memory = stream->memory;
GX_Blend blend = face->blend;
FT_Error error;
@@ -400,8 +431,17 @@
FT_FRAME_END
};
- if ( (error = face->goto_table( face, TTAG_gvar, stream, &table_len )) != 0 )
+
+ FT_TRACE2(( "GVAR " ));
+
+ if ( ( error = face->goto_table( face,
+ TTAG_gvar,
+ stream,
+ &table_len ) ) != 0 )
+ {
+ FT_TRACE2(( "is missing\n" ));
goto Exit;
+ }
gvar_start = FT_STREAM_POS( );
if ( FT_STREAM_READ_FIELDS( gvar_fields, &gvar_head ) )
@@ -411,13 +451,26 @@
blend->gv_glyphcnt = gvar_head.glyphCount;
offsetToData = gvar_start + gvar_head.offsetToData;
- if ( gvar_head.version != (FT_Long)0x00010000L ||
- gvar_head.axisCount != (FT_UShort)blend->mmvar->num_axis )
+ if ( gvar_head.version != 0x00010000L )
+ {
+ FT_TRACE1(( "bad table version\n" ));
+ error = FT_THROW( Invalid_Table );
+ 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"
+ " table are different\n" ));
error = FT_THROW( Invalid_Table );
goto Exit;
}
+ FT_TRACE5(( "gvar: there are %d shared coordinates:\n",
+ blend->tuplecount ));
+
if ( FT_NEW_ARRAY( blend->glyphoffsets, blend->gv_glyphcnt + 1 ) )
goto Exit;
@@ -427,8 +480,8 @@
if ( FT_FRAME_ENTER( ( blend->gv_glyphcnt + 1 ) * 4L ) )
goto Exit;
- for ( i = 0; i <= blend->gv_glyphcnt; ++i )
- blend->glyphoffsets[i] = offsetToData + FT_GET_LONG();
+ for ( i = 0; i <= blend->gv_glyphcnt; i++ )
+ blend->glyphoffsets[i] = offsetToData + FT_GET_ULONG();
FT_FRAME_EXIT();
}
@@ -438,9 +491,9 @@
if ( FT_FRAME_ENTER( ( blend->gv_glyphcnt + 1 ) * 2L ) )
goto Exit;
- for ( i = 0; i <= blend->gv_glyphcnt; ++i )
+ for ( i = 0; i <= blend->gv_glyphcnt; i++ )
blend->glyphoffsets[i] = offsetToData + FT_GET_USHORT() * 2;
- /* XXX: Undocumented: `*2'! */
+ /* XXX: Undocumented: `*2'! */
FT_FRAME_EXIT();
}
@@ -451,14 +504,24 @@
gvar_head.axisCount * blend->tuplecount ) )
goto Exit;
- if ( FT_STREAM_SEEK( gvar_start + gvar_head.offsetToCoord ) ||
- FT_FRAME_ENTER( blend->tuplecount * gvar_head.axisCount * 2L ) )
+ if ( FT_STREAM_SEEK( gvar_start + gvar_head.offsetToCoord ) ||
+ FT_FRAME_ENTER( blend->tuplecount * gvar_head.axisCount * 2L ) )
goto Exit;
- for ( i = 0; i < blend->tuplecount; ++i )
- for ( j = 0 ; j < (FT_UInt)gvar_head.axisCount; ++j )
+ for ( i = 0; i < blend->tuplecount; i++ )
+ {
+ FT_TRACE5(( " [ " ));
+ 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 ));
+ }
+ FT_TRACE5(( "]\n" ));
+ }
+
+ FT_TRACE5(( "\n" ));
FT_FRAME_EXIT();
}
@@ -506,48 +569,83 @@
FT_Fixed apply = 0x10000L;
- for ( i = 0; i < blend->num_axis; ++i )
+ for ( i = 0; i < blend->num_axis; i++ )
{
+ FT_TRACE6(( " axis coordinate %d (%.4f):\n",
+ i, blend->normalizedcoords[i] / 65536.0 ));
+
+ /* It's not clear why (for intermediate tuples) we don't need */
+ /* to check against start/end -- the documentation says we don't. */
+ /* Similarly, it's unclear why we don't need to scale along the */
+ /* axis. */
+
if ( tuple_coords[i] == 0 )
- /* It's not clear why (for intermediate tuples) we don't need */
- /* to check against start/end -- the documentation says we don't. */
- /* Similarly, it's unclear why we don't need to scale along the */
- /* axis. */
+ {
+ FT_TRACE6(( " tuple coordinate is zero, ignored\n", i ));
continue;
+ }
+
+ else if ( blend->normalizedcoords[i] == 0 )
+ {
+ FT_TRACE6(( " axis coordinate is zero, stop\n" ));
+ apply = 0;
+ break;
+ }
- else if ( blend->normalizedcoords[i] == 0 ||
- ( blend->normalizedcoords[i] < 0 && tuple_coords[i] > 0 ) ||
+ else if ( ( blend->normalizedcoords[i] < 0 && tuple_coords[i] > 0 ) ||
( blend->normalizedcoords[i] > 0 && tuple_coords[i] < 0 ) )
{
+ FT_TRACE6(( " tuple coordinate value %.4f is exceeded, stop\n",
+ tuple_coords[i] / 65536.0 ));
apply = 0;
break;
}
else if ( !( tupleIndex & GX_TI_INTERMEDIATE_TUPLE ) )
+ {
+ FT_TRACE6(( " tuple coordinate value %.4f fits\n",
+ tuple_coords[i] / 65536.0 ));
/* not an intermediate tuple */
apply = FT_MulFix( apply,
blend->normalizedcoords[i] > 0
? blend->normalizedcoords[i]
: -blend->normalizedcoords[i] );
+ }
- else if ( blend->normalizedcoords[i] <= im_start_coords[i] ||
- blend->normalizedcoords[i] >= im_end_coords[i] )
+ else if ( blend->normalizedcoords[i] < im_start_coords[i] ||
+ blend->normalizedcoords[i] > im_end_coords[i] )
{
+ FT_TRACE6(( " intermediate tuple range [%.4f;%.4f] is exceeded,"
+ " stop\n",
+ im_start_coords[i] / 65536.0,
+ im_end_coords[i] / 65536.0 ));
apply = 0;
break;
}
else if ( blend->normalizedcoords[i] < tuple_coords[i] )
+ {
+ FT_TRACE6(( " intermediate tuple range [%.4f;%.4f] fits\n",
+ im_start_coords[i] / 65536.0,
+ im_end_coords[i] / 65536.0 ));
apply = FT_MulDiv( apply,
blend->normalizedcoords[i] - im_start_coords[i],
tuple_coords[i] - im_start_coords[i] );
+ }
else
+ {
+ FT_TRACE6(( " intermediate tuple range [%.4f;%.4f] fits\n",
+ im_start_coords[i] / 65536.0,
+ im_end_coords[i] / 65536.0 ));
apply = FT_MulDiv( apply,
im_end_coords[i] - blend->normalizedcoords[i],
im_end_coords[i] - tuple_coords[i] );
+ }
}
+ FT_TRACE6(( " apply factor is %.4f\n", apply / 65536.0 ));
+
return apply;
}
@@ -577,9 +675,9 @@
typedef struct fvar_axis_
{
FT_ULong axisTag;
- FT_ULong minValue;
- FT_ULong defaultValue;
- FT_ULong maxValue;
+ FT_Fixed minValue;
+ FT_Fixed defaultValue;
+ FT_Fixed maxValue;
FT_UShort flags;
FT_UShort nameID;
@@ -600,7 +698,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. */
@@ -647,25 +746,37 @@
FT_FRAME_START( 20 ),
FT_FRAME_ULONG ( axisTag ),
- FT_FRAME_ULONG ( minValue ),
- FT_FRAME_ULONG ( defaultValue ),
- FT_FRAME_ULONG ( maxValue ),
+ FT_FRAME_LONG ( minValue ),
+ FT_FRAME_LONG ( defaultValue ),
+ FT_FRAME_LONG ( maxValue ),
FT_FRAME_USHORT( flags ),
FT_FRAME_USHORT( nameID ),
FT_FRAME_END
};
+ /* read the font data and set up the internal representation */
+ /* if not already done */
+
if ( face->blend == NULL )
{
+ FT_TRACE2(( "FVAR " ));
+
/* both `fvar' and `gvar' must be present */
- if ( (error = face->goto_table( face, TTAG_gvar,
- stream, &table_len )) != 0 )
+ if ( ( error = face->goto_table( face, TTAG_gvar,
+ stream, &table_len ) ) != 0 )
+ {
+ FT_TRACE1(( "\n"
+ "TT_Get_MM_Var: `gvar' table is missing\n" ));
goto Exit;
+ }
- if ( (error = face->goto_table( face, TTAG_fvar,
- stream, &table_len )) != 0 )
+ if ( ( error = face->goto_table( face, TTAG_fvar,
+ stream, &table_len ) ) != 0 )
+ {
+ FT_TRACE1(( "is missing\n" ));
goto Exit;
+ }
fvar_start = FT_STREAM_POS( );
@@ -673,7 +784,12 @@
goto Exit;
if ( fvar_head.version != (FT_Long)0x00010000L ||
+#if 0
+ /* fonts like `JamRegular.ttf' have an incorrect value for */
+ /* `countSizePairs'; since value 2 is hard-coded in `fvar' */
+ /* version 1.0, we simply ignore it */
fvar_head.countSizePairs != 2 ||
+#endif
fvar_head.axisSize != 20 ||
/* axisCount limit implied by 16-bit instanceSize */
fvar_head.axisCount > 0x3FFE ||
@@ -683,10 +799,16 @@
fvar_head.offsetToData + fvar_head.axisCount * 20U +
fvar_head.instanceCount * fvar_head.instanceSize > table_len )
{
+ FT_TRACE1(( "\n"
+ "TT_Get_MM_Var: invalid `fvar' header\n" ));
error = FT_THROW( Invalid_Table );
goto Exit;
}
+ FT_TRACE2(( "loaded\n" ));
+
+ FT_TRACE5(( "number of GX style axes: %d\n", fvar_head.axisCount ));
+
if ( FT_NEW( face->blend ) )
goto Exit;
@@ -702,6 +824,9 @@
goto Exit;
face->blend->mmvar = mmvar;
+ /* set up pointers and offsets into the `mmvar' array; */
+ /* the data gets filled in later on */
+
mmvar->num_axis =
fvar_head.axisCount;
mmvar->num_designs =
@@ -711,30 +836,32 @@
mmvar->num_namedstyles =
fvar_head.instanceCount;
mmvar->axis =
- (FT_Var_Axis*)&(mmvar[1]);
+ (FT_Var_Axis*)&( mmvar[1] );
mmvar->namedstyle =
- (FT_Var_Named_Style*)&(mmvar->axis[fvar_head.axisCount]);
+ (FT_Var_Named_Style*)&( mmvar->axis[fvar_head.axisCount] );
next_coords =
- (FT_Fixed*)&(mmvar->namedstyle[fvar_head.instanceCount]);
- for ( i = 0; i < fvar_head.instanceCount; ++i )
+ (FT_Fixed*)&( mmvar->namedstyle[fvar_head.instanceCount] );
+ for ( i = 0; i < fvar_head.instanceCount; i++ )
{
mmvar->namedstyle[i].coords = next_coords;
next_coords += fvar_head.axisCount;
}
next_name = (FT_String*)next_coords;
- for ( i = 0; i < fvar_head.axisCount; ++i )
+ for ( i = 0; i < fvar_head.axisCount; i++ )
{
mmvar->axis[i].name = next_name;
next_name += 5;
}
+ /* now fill in the data */
+
if ( FT_STREAM_SEEK( fvar_start + fvar_head.offsetToData ) )
goto Exit;
a = mmvar->axis;
- for ( i = 0; i < fvar_head.axisCount; ++i )
+ for ( i = 0; i < fvar_head.axisCount; i++ )
{
GX_FVar_Axis axis_rec;
@@ -742,22 +869,30 @@
if ( FT_STREAM_READ_FIELDS( fvaraxis_fields, &axis_rec ) )
goto Exit;
a->tag = axis_rec.axisTag;
- a->minimum = axis_rec.minValue; /* A Fixed */
- a->def = axis_rec.defaultValue; /* A Fixed */
- a->maximum = axis_rec.maxValue; /* A Fixed */
+ a->minimum = axis_rec.minValue;
+ a->def = axis_rec.defaultValue;
+ a->maximum = axis_rec.maxValue;
a->strid = axis_rec.nameID;
a->name[0] = (FT_String)( a->tag >> 24 );
a->name[1] = (FT_String)( ( a->tag >> 16 ) & 0xFF );
a->name[2] = (FT_String)( ( a->tag >> 8 ) & 0xFF );
a->name[3] = (FT_String)( ( a->tag ) & 0xFF );
- a->name[4] = 0;
+ a->name[4] = '\0';
- ++a;
+ FT_TRACE5(( " \"%s\": minimum=%.4f, default=%.4f, maximum=%.4f\n",
+ a->name,
+ a->minimum / 65536.0,
+ a->def / 65536.0,
+ a->maximum / 65536.0 ));
+
+ a++;
}
+ FT_TRACE5(( "\n" ));
+
ns = mmvar->namedstyle;
- for ( i = 0; i < fvar_head.instanceCount; ++i, ++ns )
+ for ( i = 0; i < fvar_head.instanceCount; i++, ns++ )
{
if ( FT_FRAME_ENTER( 4L + 4L * fvar_head.axisCount ) )
goto Exit;
@@ -765,13 +900,15 @@
ns->strid = FT_GET_USHORT();
(void) /* flags = */ FT_GET_USHORT();
- for ( j = 0; j < fvar_head.axisCount; ++j )
- ns->coords[j] = FT_GET_ULONG(); /* A Fixed */
+ for ( j = 0; j < fvar_head.axisCount; j++ )
+ ns->coords[j] = FT_GET_LONG();
FT_FRAME_EXIT();
}
}
+ /* fill the output array if requested */
+
if ( master != NULL )
{
FT_UInt n;
@@ -782,36 +919,36 @@
FT_MEM_COPY( mmvar, face->blend->mmvar, face->blend->mmvar_len );
mmvar->axis =
- (FT_Var_Axis*)&(mmvar[1]);
+ (FT_Var_Axis*)&( mmvar[1] );
mmvar->namedstyle =
- (FT_Var_Named_Style*)&(mmvar->axis[mmvar->num_axis]);
+ (FT_Var_Named_Style*)&( mmvar->axis[mmvar->num_axis] );
next_coords =
- (FT_Fixed*)&(mmvar->namedstyle[mmvar->num_namedstyles]);
+ (FT_Fixed*)&( mmvar->namedstyle[mmvar->num_namedstyles] );
- for ( n = 0; n < mmvar->num_namedstyles; ++n )
+ for ( n = 0; n < mmvar->num_namedstyles; n++ )
{
mmvar->namedstyle[n].coords = next_coords;
next_coords += mmvar->num_axis;
}
- a = mmvar->axis;
+ a = mmvar->axis;
next_name = (FT_String*)next_coords;
- for ( n = 0; n < mmvar->num_axis; ++n )
+ for ( n = 0; n < mmvar->num_axis; n++ )
{
a->name = next_name;
/* standard PostScript names for some standard apple tags */
if ( a->tag == TTAG_wght )
- a->name = (char *)"Weight";
+ a->name = (char*)"Weight";
else if ( a->tag == TTAG_wdth )
- a->name = (char *)"Width";
+ a->name = (char*)"Width";
else if ( a->tag == TTAG_opsz )
- a->name = (char *)"OpticalSize";
+ a->name = (char*)"OpticalSize";
else if ( a->tag == TTAG_slnt )
- a->name = (char *)"Slant";
+ a->name = (char*)"Slant";
next_name += 5;
- ++a;
+ a++;
}
*master = mmvar;
@@ -837,9 +974,12 @@
/* Initialize the blend structure with `gvar' data. */
/* */
/* <Input> */
- /* num_coords :: Must be the axis count of the font. */
+ /* num_coords :: The number of available coordinates. If it is */
+ /* larger than the number of axes, ignore the excess */
+ /* values. If it is smaller than the number of axes, */
+ /* use the default value (0) for the remaining axes. */
/* */
- /* coords :: An array of num_coords, each between [-1,1]. */
+ /* coords :: An array of `num_coords', each between [-1,1]. */
/* */
/* <Return> */
/* FreeType error code. 0 means success. */
@@ -868,33 +1008,44 @@
if ( face->blend == NULL )
{
- if ( (error = TT_Get_MM_Var( face, NULL)) != 0 )
+ if ( ( error = TT_Get_MM_Var( face, NULL ) ) != 0 )
goto Exit;
}
blend = face->blend;
mmvar = blend->mmvar;
- if ( num_coords != mmvar->num_axis )
+ if ( num_coords > mmvar->num_axis )
{
- error = FT_THROW( Invalid_Argument );
- goto Exit;
+ FT_TRACE2(( "TT_Set_MM_Blend: only using first %d of %d coordinates\n",
+ mmvar->num_axis, num_coords ));
+ num_coords = mmvar->num_axis;
}
- for ( i = 0; i < num_coords; ++i )
+ FT_TRACE5(( "normalized design coordinates:\n" ));
+
+ for ( i = 0; i < num_coords; i++ )
+ {
+ FT_TRACE5(( " %.4f\n", coords[i] / 65536.0 ));
if ( coords[i] < -0x00010000L || coords[i] > 0x00010000L )
{
+ FT_TRACE1(( "TT_Set_MM_Blend: normalized design coordinate %.4f\n"
+ " is out of range [-1;1]\n",
+ coords[i] / 65536.0 ));
error = FT_THROW( Invalid_Argument );
goto Exit;
}
+ }
+
+ FT_TRACE5(( "\n" ));
if ( blend->glyphoffsets == NULL )
- if ( (error = ft_var_load_gvar( face )) != 0 )
+ if ( ( error = ft_var_load_gvar( face ) ) != 0 )
goto Exit;
if ( blend->normalizedcoords == NULL )
{
- if ( FT_NEW_ARRAY( blend->normalizedcoords, num_coords ) )
+ if ( FT_NEW_ARRAY( blend->normalizedcoords, mmvar->num_axis ) )
goto Exit;
manageCvt = mcvt_modify;
@@ -906,7 +1057,8 @@
else
{
manageCvt = mcvt_retain;
- for ( i = 0; i < num_coords; ++i )
+
+ for ( i = 0; i < num_coords; i++ )
{
if ( blend->normalizedcoords[i] != coords[i] )
{
@@ -915,13 +1067,22 @@
}
}
+ for ( ; i < mmvar->num_axis; i++ )
+ {
+ if ( blend->normalizedcoords[i] != 0 )
+ {
+ manageCvt = mcvt_load;
+ break;
+ }
+ }
+
/* If we don't change the blend coords then we don't need to do */
/* anything to the cvt table. It will be correct. Otherwise we */
/* no longer have the original cvt (it was modified when we set */
/* the blend last time), so we must reload and then modify it. */
}
- blend->num_axis = num_coords;
+ blend->num_axis = mmvar->num_axis;
FT_MEM_COPY( blend->normalizedcoords,
coords,
num_coords * sizeof ( FT_Fixed ) );
@@ -973,7 +1134,10 @@
/* Initialize the blend struct with `gvar' data. */
/* */
/* <Input> */
- /* num_coords :: This must be the axis count of the font. */
+ /* num_coords :: The number of available coordinates. If it is */
+ /* larger than the number of axes, ignore the excess */
+ /* values. If it is smaller than the number of axes, */
+ /* use the default values for the remaining axes. */
/* */
/* coords :: A coordinate array with `num_coords' elements. */
/* */
@@ -997,17 +1161,19 @@
if ( face->blend == NULL )
{
- if ( (error = TT_Get_MM_Var( face, NULL )) != 0 )
+ if ( ( error = TT_Get_MM_Var( face, NULL ) ) != 0 )
goto Exit;
}
blend = face->blend;
mmvar = blend->mmvar;
- if ( num_coords != mmvar->num_axis )
+ if ( num_coords > mmvar->num_axis )
{
- error = FT_THROW( Invalid_Argument );
- goto Exit;
+ FT_TRACE2(( "TT_Set_Var_Design:"
+ " only using first %d of %d coordinates\n",
+ mmvar->num_axis, num_coords ));
+ num_coords = mmvar->num_axis;
}
/* Axis normalization is a two stage process. First we normalize */
@@ -1017,32 +1183,52 @@
if ( FT_NEW_ARRAY( normalized, mmvar->num_axis ) )
goto Exit;
+ FT_TRACE5(( "design coordinates:\n" ));
+
a = mmvar->axis;
- for ( i = 0; i < mmvar->num_axis; ++i, ++a )
+ for ( i = 0; i < num_coords; i++, a++ )
{
+ FT_TRACE5(( " %.4f\n", coords[i] / 65536.0 ));
if ( coords[i] > a->maximum || coords[i] < a->minimum )
{
+ FT_TRACE1(( "TT_Set_Var_Design: normalized design coordinate %.4f\n"
+ " is out of range [%.4f;%.4f]\n",
+ coords[i] / 65536.0,
+ a->minimum / 65536.0,
+ a->maximum / 65536.0 ));
error = FT_THROW( Invalid_Argument );
goto Exit;
}
if ( coords[i] < a->def )
- normalized[i] = -FT_DivFix( coords[i] - a->def, a->minimum - a->def );
+ normalized[i] = -FT_DivFix( coords[i] - a->def,
+ a->minimum - a->def );
else if ( a->maximum == a->def )
normalized[i] = 0;
else
- normalized[i] = FT_DivFix( coords[i] - a->def, a->maximum - a->def );
+ normalized[i] = FT_DivFix( coords[i] - a->def,
+ a->maximum - a->def );
}
+ FT_TRACE5(( "\n" ));
+
+ for ( ; i < mmvar->num_axis; i++ )
+ normalized[i] = 0;
+
if ( !blend->avar_checked )
ft_var_load_avar( face );
if ( blend->avar_segment != NULL )
{
+ FT_TRACE5(( "normalized design coordinates"
+ " before applying `avar' data:\n" ));
+
av = blend->avar_segment;
- for ( i = 0; i < mmvar->num_axis; ++i, ++av )
+ for ( i = 0; i < mmvar->num_axis; i++, av++ )
{
- for ( j = 1; j < (FT_UInt)av->pairCount; ++j )
+ for ( j = 1; j < (FT_UInt)av->pairCount; j++ )
+ {
+ FT_TRACE5(( " %.4f\n", normalized[i] / 65536.0 ));
if ( normalized[i] < av->correspondence[j].fromCoord )
{
normalized[i] =
@@ -1054,10 +1240,11 @@
av->correspondence[j - 1].toCoord;
break;
}
+ }
}
}
- error = TT_Set_MM_Blend( face, num_coords, normalized );
+ error = TT_Set_MM_Blend( face, mmvar->num_axis, normalized );
Exit:
FT_FREE( normalized );
@@ -1120,16 +1307,16 @@
if ( blend == NULL )
{
- FT_TRACE2(( "tt_face_vary_cvt: no blend specified\n" ));
-
+ FT_TRACE2(( "\n"
+ "tt_face_vary_cvt: no blend specified\n" ));
error = FT_Err_Ok;
goto Exit;
}
if ( face->cvt == NULL )
{
- FT_TRACE2(( "tt_face_vary_cvt: no `cvt ' table\n" ));
-
+ FT_TRACE2(( "\n"
+ "tt_face_vary_cvt: no `cvt ' table\n" ));
error = FT_Err_Ok;
goto Exit;
}
@@ -1158,6 +1345,8 @@
goto FExit;
}
+ FT_TRACE2(( "loaded\n" ));
+
if ( FT_NEW_ARRAY( tuple_coords, blend->num_axis ) ||
FT_NEW_ARRAY( im_start_coords, blend->num_axis ) ||
FT_NEW_ARRAY( im_end_coords, blend->num_axis ) )
@@ -1170,13 +1359,17 @@
/* tuplecount, but John Jenkins says that shared points don't apply */
/* to `cvar', and no other flags are defined. */
- for ( i = 0; i < ( tupleCount & 0xFFF ); ++i )
+ FT_TRACE5(( "cvar: there are %d tuples:\n", tupleCount ));
+
+ for ( i = 0; i < ( tupleCount & 0xFFF ); i++ )
{
FT_UInt tupleDataSize;
FT_UInt tupleIndex;
FT_Fixed apply;
+ FT_TRACE6(( " tuple %d:\n", i ));
+
tupleDataSize = FT_GET_USHORT();
tupleIndex = FT_GET_USHORT();
@@ -1185,8 +1378,8 @@
if ( tupleIndex & GX_TI_EMBEDDED_TUPLE_COORD )
{
- for ( j = 0; j < blend->num_axis; ++j )
- tuple_coords[j] = FT_GET_SHORT() << 2; /* convert from */
+ for ( j = 0; j < blend->num_axis; j++ )
+ tuple_coords[j] = FT_GET_SHORT() * 4; /* convert from */
/* short frac to fixed */
}
else
@@ -1194,7 +1387,7 @@
/* skip this tuple; it makes no sense */
if ( tupleIndex & GX_TI_INTERMEDIATE_TUPLE )
- for ( j = 0; j < 2 * blend->num_axis; ++j )
+ for ( j = 0; j < 2 * blend->num_axis; j++ )
(void)FT_GET_SHORT();
offsetToData += tupleDataSize;
@@ -1203,10 +1396,10 @@
if ( tupleIndex & GX_TI_INTERMEDIATE_TUPLE )
{
- for ( j = 0; j < blend->num_axis; ++j )
- im_start_coords[j] = FT_GET_SHORT() << 2;
- for ( j = 0; j < blend->num_axis; ++j )
- im_end_coords[j] = FT_GET_SHORT() << 2;
+ for ( j = 0; j < blend->num_axis; j++ )
+ im_start_coords[j] = FT_GET_SHORT() * 4;
+ for ( j = 0; j < blend->num_axis; j++ )
+ im_end_coords[j] = FT_GET_SHORT() * 4;
}
apply = ft_var_apply_tuple( blend,
@@ -1233,25 +1426,74 @@
point_count == 0 ? face->cvt_size
: point_count );
if ( localpoints == NULL || deltas == NULL )
- /* failure, ignore it */;
+ ; /* failure, ignore it */
else if ( localpoints == ALL_POINTS )
{
+#ifdef FT_DEBUG_LEVEL_TRACE
+ int count = 0;
+#endif
+
+
+ FT_TRACE7(( " CVT deltas:\n" ));
+
/* this means that there are deltas for every entry in cvt */
- for ( j = 0; j < face->cvt_size; ++j )
- face->cvt[j] = (FT_Short)( face->cvt[j] +
+ for ( j = 0; j < face->cvt_size; j++ )
+ {
+ FT_Long orig_cvt = face->cvt[j];
+
+
+ face->cvt[j] = (FT_Short)( orig_cvt +
FT_MulFix( deltas[j], apply ) );
+
+#ifdef FT_DEBUG_LEVEL_TRACE
+ if ( orig_cvt != face->cvt[j] )
+ {
+ FT_TRACE7(( " %d: %d -> %d\n",
+ j, orig_cvt, face->cvt[j] ));
+ count++;
+ }
+#endif
+ }
+
+#ifdef FT_DEBUG_LEVEL_TRACE
+ if ( !count )
+ FT_TRACE7(( " none\n" ));
+#endif
}
else
{
- for ( j = 0; j < point_count; ++j )
+#ifdef FT_DEBUG_LEVEL_TRACE
+ int count = 0;
+#endif
+
+
+ FT_TRACE7(( " CVT deltas:\n" ));
+
+ for ( j = 0; j < point_count; j++ )
{
- int pindex = localpoints[j];
+ int pindex = localpoints[j];
+ FT_Long orig_cvt = face->cvt[pindex];
+
- face->cvt[pindex] = (FT_Short)( face->cvt[pindex] +
+ face->cvt[pindex] = (FT_Short)( orig_cvt +
FT_MulFix( deltas[j], apply ) );
+
+#ifdef FT_DEBUG_LEVEL_TRACE
+ if ( orig_cvt != face->cvt[pindex] )
+ {
+ FT_TRACE7(( " %d: %d -> %d\n",
+ pindex, orig_cvt, face->cvt[pindex] ));
+ count++;
+ }
+#endif
}
+
+#ifdef FT_DEBUG_LEVEL_TRACE
+ if ( !count )
+ FT_TRACE7(( " none\n" ));
+#endif
}
if ( localpoints != ALL_POINTS )
@@ -1263,6 +1505,8 @@
FT_Stream_SeekSet( stream, here );
}
+ FT_TRACE5(( "\n" ));
+
FExit:
FT_FRAME_EXIT();
@@ -1275,13 +1519,230 @@
}
+ /* Shift the original coordinates of all points between indices `p1' */
+ /* and `p2', using the same difference as given by index `ref'. */
+
+ /* modeled after `af_iup_shift' */
+
+ static void
+ tt_delta_shift( int p1,
+ int p2,
+ int ref,
+ FT_Vector* in_points,
+ FT_Vector* out_points )
+ {
+ int p;
+ FT_Vector delta;
+
+
+ delta.x = out_points[ref].x - in_points[ref].x;
+ delta.y = out_points[ref].y - in_points[ref].y;
+
+ if ( delta.x == 0 && delta.y == 0 )
+ return;
+
+ for ( p = p1; p < ref; p++ )
+ {
+ out_points[p].x += delta.x;
+ out_points[p].y += delta.y;
+ }
+
+ for ( p = ref + 1; p <= p2; p++ )
+ {
+ out_points[p].x += delta.x;
+ out_points[p].y += delta.y;
+ }
+ }
+
+
+ /* Interpolate the original coordinates of all points with indices */
+ /* between `p1' and `p2', using `ref1' and `ref2' as the reference */
+ /* point indices. */
+
+ /* modeled after `af_iup_interp', `_iup_worker_interpolate', and */
+ /* `Ins_IUP' */
+
+ static void
+ tt_delta_interpolate( int p1,
+ int p2,
+ int ref1,
+ int ref2,
+ FT_Vector* in_points,
+ FT_Vector* out_points )
+ {
+ int p, i;
+
+ FT_Pos out, in1, in2, out1, out2, d1, d2;
+
+
+ if ( p1 > p2 )
+ return;
+
+ /* handle both horizontal and vertical coordinates */
+ for ( i = 0; i <= 1; i++ )
+ {
+ /* shift array pointers so that we can access `foo.y' as `foo.x' */
+ in_points = (FT_Vector*)( (FT_Pos*)in_points + i );
+ out_points = (FT_Vector*)( (FT_Pos*)out_points + i );
+
+ if ( in_points[ref1].x > in_points[ref2].x )
+ {
+ p = ref1;
+ ref1 = ref2;
+ ref2 = p;
+ }
+
+ in1 = in_points[ref1].x;
+ in2 = in_points[ref2].x;
+ out1 = out_points[ref1].x;
+ out2 = out_points[ref2].x;
+ d1 = out1 - in1;
+ d2 = out2 - in2;
+
+ if ( out1 == out2 || in1 == in2 )
+ {
+ for ( p = p1; p <= p2; p++ )
+ {
+ out = in_points[p].x;
+
+ if ( out <= in1 )
+ out += d1;
+ else if ( out >= in2 )
+ out += d2;
+ else
+ out = out1;
+
+ out_points[p].x = out;
+ }
+ }
+ else
+ {
+ FT_Fixed scale = FT_DivFix( out2 - out1, in2 - in1 );
+
+
+ for ( p = p1; p <= p2; p++ )
+ {
+ out = in_points[p].x;
+
+ if ( out <= in1 )
+ out += d1;
+ else if ( out >= in2 )
+ out += d2;
+ else
+ out = out1 + FT_MulFix( out - in1, scale );
+
+ out_points[p].x = out;
+ }
+ }
+ }
+ }
+
+
+ /* Interpolate points without delta values, similar to */
+ /* the `IUP' hinting instruction. */
+
+ /* modeled after `Ins_IUP */
+
+ static void
+ tt_handle_deltas( FT_Outline* outline,
+ FT_Vector* in_points,
+ FT_Bool* has_delta )
+ {
+ FT_Vector* out_points;
+
+ FT_Int first_point;
+ FT_Int end_point;
+
+ FT_Int first_delta;
+ FT_Int cur_delta;
+
+ FT_Int point;
+ FT_Short contour;
+
+
+ /* ignore empty outlines */
+ if ( !outline->n_contours )
+ return;
+
+ out_points = outline->points;
+
+ contour = 0;
+ point = 0;
+
+ do
+ {
+ end_point = outline->contours[contour];
+ first_point = point;
+
+ /* search first point that has a delta */
+ while ( point <= end_point && !has_delta[point] )
+ point++;
+
+ if ( point <= end_point )
+ {
+ first_delta = point;
+ cur_delta = point;
+
+ point++;
+
+ while ( point <= end_point )
+ {
+ /* search next point that has a delta */
+ /* and interpolate intermediate points */
+ if ( has_delta[point] )
+ {
+ tt_delta_interpolate( cur_delta + 1,
+ point - 1,
+ cur_delta,
+ point,
+ in_points,
+ out_points );
+ cur_delta = point;
+ }
+
+ point++;
+ }
+
+ /* shift contour if we only have a single delta */
+ if ( cur_delta == first_delta )
+ tt_delta_shift( first_point,
+ end_point,
+ cur_delta,
+ in_points,
+ out_points );
+ else
+ {
+ /* otherwise handle remaining points */
+ /* at the end and beginning of the contour */
+ tt_delta_interpolate( cur_delta + 1,
+ end_point,
+ cur_delta,
+ first_delta,
+ in_points,
+ out_points );
+
+ if ( first_delta > 0 )
+ tt_delta_interpolate( first_point,
+ first_delta - 1,
+ cur_delta,
+ first_delta,
+ in_points,
+ out_points );
+ }
+ }
+ contour++;
+
+ } while ( contour < outline->n_contours );
+ }
+
+
/*************************************************************************/
/* */
/* <Function> */
- /* TT_Vary_Get_Glyph_Deltas */
+ /* TT_Vary_Apply_Glyph_Deltas */
/* */
/* <Description> */
- /* Load the appropriate deltas for the current glyph. */
+ /* Apply the appropriate deltas to the current glyph. */
/* */
/* <Input> */
/* face :: A handle to the target face object. */
@@ -1291,22 +1752,24 @@
/* n_points :: The number of the points in the glyph, including */
/* phantom points. */
/* */
- /* <Output> */
- /* deltas :: The array of points to change. */
+ /* <InOut> */
+ /* outline :: The outline to change. */
/* */
/* <Return> */
/* FreeType error code. 0 means success. */
/* */
FT_LOCAL_DEF( FT_Error )
- TT_Vary_Get_Glyph_Deltas( TT_Face face,
- FT_UInt glyph_index,
- FT_Vector* *deltas,
- FT_UInt n_points )
+ TT_Vary_Apply_Glyph_Deltas( TT_Face face,
+ FT_UInt glyph_index,
+ FT_Outline* outline,
+ FT_UInt n_points )
{
FT_Stream stream = face->root.stream;
FT_Memory memory = stream->memory;
GX_Blend blend = face->blend;
- FT_Vector* delta_xy = NULL;
+
+ FT_Vector* points_org = NULL;
+ FT_Bool* has_delta = NULL;
FT_Error error;
FT_ULong glyph_start;
@@ -1327,15 +1790,18 @@
if ( !face->doblend || blend == NULL )
return FT_THROW( Invalid_Argument );
- /* to be freed by the caller */
- if ( FT_NEW_ARRAY( delta_xy, n_points ) )
- goto Exit;
- *deltas = delta_xy;
-
if ( glyph_index >= blend->gv_glyphcnt ||
blend->glyphoffsets[glyph_index] ==
blend->glyphoffsets[glyph_index + 1] )
- return FT_Err_Ok; /* no variation data for this glyph */
+ {
+ FT_TRACE2(( "TT_Vary_Apply_Glyph_Deltas:"
+ " no variation data for this glyph\n" ));
+ return FT_Err_Ok;
+ }
+
+ if ( FT_NEW_ARRAY( points_org, n_points ) ||
+ FT_NEW_ARRAY( has_delta, n_points ) )
+ goto Fail1;
if ( FT_STREAM_SEEK( blend->glyphoffsets[glyph_index] ) ||
FT_FRAME_ENTER( blend->glyphoffsets[glyph_index + 1] -
@@ -1367,41 +1833,43 @@
FT_Stream_SeekSet( stream, here );
}
- for ( i = 0; i < ( tupleCount & GX_TC_TUPLE_COUNT_MASK ); ++i )
+ FT_TRACE5(( "gvar: there are %d tuples:\n", tupleCount ));
+
+ for ( i = 0; i < ( tupleCount & GX_TC_TUPLE_COUNT_MASK ); i++ )
{
FT_UInt tupleDataSize;
FT_UInt tupleIndex;
FT_Fixed apply;
+ FT_TRACE6(( " tuple %d:\n", i ));
+
tupleDataSize = FT_GET_USHORT();
tupleIndex = FT_GET_USHORT();
if ( tupleIndex & GX_TI_EMBEDDED_TUPLE_COORD )
{
- for ( j = 0; j < blend->num_axis; ++j )
- tuple_coords[j] = FT_GET_SHORT() << 2; /* convert from */
+ for ( j = 0; j < blend->num_axis; j++ )
+ tuple_coords[j] = FT_GET_SHORT() * 4; /* convert from */
/* short frac to fixed */
}
else if ( ( tupleIndex & GX_TI_TUPLE_INDEX_MASK ) >= blend->tuplecount )
{
error = FT_THROW( Invalid_Table );
- goto Fail3;
+ goto Fail2;
}
else
- {
FT_MEM_COPY(
tuple_coords,
- &blend->tuplecoords[(tupleIndex & 0xFFF) * blend->num_axis],
+ &blend->tuplecoords[( tupleIndex & 0xFFF ) * blend->num_axis],
blend->num_axis * sizeof ( FT_Fixed ) );
- }
if ( tupleIndex & GX_TI_INTERMEDIATE_TUPLE )
{
- for ( j = 0; j < blend->num_axis; ++j )
- im_start_coords[j] = FT_GET_SHORT() << 2;
- for ( j = 0; j < blend->num_axis; ++j )
- im_end_coords[j] = FT_GET_SHORT() << 2;
+ for ( j = 0; j < blend->num_axis; j++ )
+ im_start_coords[j] = FT_GET_SHORT() * 4;
+ for ( j = 0; j < blend->num_axis; j++ )
+ im_end_coords[j] = FT_GET_SHORT() * 4;
}
apply = ft_var_apply_tuple( blend,
@@ -1443,24 +1911,101 @@
else if ( points == ALL_POINTS )
{
+#ifdef FT_DEBUG_LEVEL_TRACE
+ int count = 0;
+#endif
+
+
+ FT_TRACE7(( " point deltas:\n" ));
+
/* this means that there are deltas for every point in the glyph */
- for ( j = 0; j < n_points; ++j )
+ for ( j = 0; j < n_points; j++ )
{
- delta_xy[j].x += FT_MulFix( deltas_x[j], apply );
- delta_xy[j].y += FT_MulFix( deltas_y[j], apply );
+#ifdef FT_DEBUG_LEVEL_TRACE
+ FT_Vector point_org = outline->points[j];
+#endif
+
+
+ outline->points[j].x += FT_MulFix( deltas_x[j], apply );
+ outline->points[j].y += FT_MulFix( deltas_y[j], apply );
+
+#ifdef FT_DEBUG_LEVEL_TRACE
+ if ( ( point_org.x != outline->points[j].x ) ||
+ ( point_org.y != outline->points[j].y ) )
+ {
+ FT_TRACE7(( " %d: (%d, %d) -> (%d, %d)\n",
+ j,
+ point_org.x,
+ point_org.y,
+ outline->points[j].x,
+ outline->points[j].y ));
+ count++;
+ }
+#endif
}
+
+#ifdef FT_DEBUG_LEVEL_TRACE
+ if ( !count )
+ FT_TRACE7(( " none\n" ));
+#endif
}
else
{
- for ( j = 0; j < point_count; ++j )
+#ifdef FT_DEBUG_LEVEL_TRACE
+ int count = 0;
+#endif
+
+
+ /* we have to interpolate the missing deltas similar to the */
+ /* IUP bytecode instruction */
+ for ( j = 0; j < n_points; j++ )
+ {
+ points_org[j] = outline->points[j];
+ has_delta[j] = FALSE;
+ }
+
+ for ( j = 0; j < point_count; j++ )
{
- if ( localpoints[j] >= n_points )
+ FT_UShort idx = localpoints[j];
+
+
+ if ( idx >= n_points )
continue;
- delta_xy[localpoints[j]].x += FT_MulFix( deltas_x[j], apply );
- delta_xy[localpoints[j]].y += FT_MulFix( deltas_y[j], apply );
+ has_delta[idx] = TRUE;
+
+ outline->points[idx].x += FT_MulFix( deltas_x[j], apply );
+ outline->points[idx].y += FT_MulFix( deltas_y[j], apply );
}
+
+ /* no need to handle phantom points here, */
+ /* since solitary points can't be interpolated */
+ tt_handle_deltas( outline,
+ points_org,
+ has_delta );
+
+#ifdef FT_DEBUG_LEVEL_TRACE
+ FT_TRACE7(( " point deltas:\n" ));
+
+ for ( j = 0; j < n_points; j++)
+ {
+ if ( ( points_org[j].x != outline->points[j].x ) ||
+ ( points_org[j].y != outline->points[j].y ) )
+ {
+ FT_TRACE7(( " %d: (%d, %d) -> (%d, %d)\n",
+ j,
+ points_org[j].x,
+ points_org[j].y,
+ outline->points[j].x,
+ outline->points[j].y ));
+ count++;
+ }
+ }
+
+ if ( !count )
+ FT_TRACE7(( " none\n" ));
+#endif
}
if ( localpoints != ALL_POINTS )
@@ -1473,22 +2018,19 @@
FT_Stream_SeekSet( stream, here );
}
- Fail3:
+ FT_TRACE5(( "\n" ));
+
+ Fail2:
FT_FREE( tuple_coords );
FT_FREE( im_start_coords );
FT_FREE( im_end_coords );
- Fail2:
FT_FRAME_EXIT();
Fail1:
- if ( error )
- {
- FT_FREE( delta_xy );
- *deltas = NULL;
- }
+ FT_FREE( points_org );
+ FT_FREE( has_delta );
- Exit:
return error;
}
@@ -1499,7 +2041,7 @@
/* tt_done_blend */
/* */
/* <Description> */
- /* Frees the blend internal data structure. */
+ /* Free the blend internal data structure. */
/* */
FT_LOCAL_DEF( void )
tt_done_blend( FT_Memory memory,
@@ -1515,7 +2057,7 @@
if ( blend->avar_segment != NULL )
{
- for ( i = 0; i < blend->num_axis; ++i )
+ for ( i = 0; i < blend->num_axis; i++ )
FT_FREE( blend->avar_segment[i].correspondence );
FT_FREE( blend->avar_segment );
}
diff --git a/src/3rdparty/freetype/src/truetype/ttgxvar.h b/src/3rdparty/freetype/src/truetype/ttgxvar.h
index 82dfc4431f..060d4d60ea 100644
--- a/src/3rdparty/freetype/src/truetype/ttgxvar.h
+++ b/src/3rdparty/freetype/src/truetype/ttgxvar.h
@@ -4,7 +4,7 @@
/* */
/* TrueType GX Font Variation loader (specification) */
/* */
-/* Copyright 2004 by */
+/* Copyright 2004-2015 by */
/* David Turner, Robert Wilhelm, Werner Lemberg and George Williams. */
/* */
/* This file is part of the FreeType project, and may only be used, */
@@ -162,10 +162,10 @@ FT_BEGIN_HEADER
FT_LOCAL( FT_Error )
- TT_Vary_Get_Glyph_Deltas( TT_Face face,
- FT_UInt glyph_index,
- FT_Vector* *deltas,
- FT_UInt n_points );
+ TT_Vary_Apply_Glyph_Deltas( TT_Face face,
+ FT_UInt glyph_index,
+ FT_Outline* outline,
+ FT_UInt n_points );
FT_LOCAL( void )
diff --git a/src/3rdparty/freetype/src/truetype/ttinterp.c b/src/3rdparty/freetype/src/truetype/ttinterp.c
index eccd4aaccb..ae2a82adc5 100644
--- a/src/3rdparty/freetype/src/truetype/ttinterp.c
+++ b/src/3rdparty/freetype/src/truetype/ttinterp.c
@@ -4,8 +4,8 @@
/* */
/* TrueType bytecode interpreter (body). */
/* */
-/* Copyright 1996-2014 */
-/* by David Turner, Robert Wilhelm, and Werner Lemberg. */
+/* Copyright 1996-2015 by */
+/* David Turner, Robert Wilhelm, and Werner Lemberg. */
/* */
/* This file is part of the FreeType project, and may only be used, */
/* modified, and distributed under the terms of the FreeType project */
@@ -44,6 +44,7 @@
#undef FT_COMPONENT
#define FT_COMPONENT trace_ttinterp
+
/*************************************************************************/
/* */
/* In order to detect infinite loops in the code, we set up a counter */
@@ -53,174 +54,30 @@
#define MAX_RUNNABLE_OPCODES 1000000L
- /*************************************************************************/
- /* */
- /* There are two kinds of implementations: */
- /* */
- /* a. static implementation */
- /* */
- /* The current execution context is a static variable, which fields */
- /* are accessed directly by the interpreter during execution. The */
- /* context is named `cur'. */
- /* */
- /* This version is non-reentrant, of course. */
- /* */
- /* b. indirect implementation */
- /* */
- /* The current execution context is passed to _each_ function as its */
- /* first argument, and each field is thus accessed indirectly. */
- /* */
- /* This version is fully re-entrant. */
- /* */
- /* The idea is that an indirect implementation may be slower to execute */
- /* on low-end processors that are used in some systems (like 386s or */
- /* even 486s). */
- /* */
- /* As a consequence, the indirect implementation is now the default, as */
- /* its performance costs can be considered negligible in our context. */
- /* Note, however, that we kept the same source with macros because: */
- /* */
- /* - The code is kept very close in design to the Pascal code used for */
- /* development. */
- /* */
- /* - It's much more readable that way! */
- /* */
- /* - It's still open to experimentation and tuning. */
- /* */
- /*************************************************************************/
-
-
-#ifndef TT_CONFIG_OPTION_STATIC_INTERPRETER /* indirect implementation */
-
-#define CUR (*exc) /* see ttobjs.h */
-
- /*************************************************************************/
- /* */
- /* This macro is used whenever `exec' is unused in a function, to avoid */
- /* stupid warnings from pedantic compilers. */
- /* */
-#define FT_UNUSED_EXEC FT_UNUSED( exc )
-
-#else /* static implementation */
-
-#define CUR cur
-
-#define FT_UNUSED_EXEC int __dummy = __dummy
-
- static
- TT_ExecContextRec cur; /* static exec. context variable */
-
- /* apparently, we have a _lot_ of direct indexing when accessing */
- /* the static `cur', which makes the code bigger (due to all the */
- /* four bytes addresses). */
-
-#endif /* TT_CONFIG_OPTION_STATIC_INTERPRETER */
-
-
- /*************************************************************************/
- /* */
- /* The instruction argument stack. */
- /* */
-#define INS_ARG EXEC_OP_ FT_Long* args /* see ttobjs.h for EXEC_OP_ */
-
-
- /*************************************************************************/
- /* */
- /* This macro is used whenever `args' is unused in a function, to avoid */
- /* stupid warnings from pedantic compilers. */
- /* */
-#define FT_UNUSED_ARG FT_UNUSED_EXEC; FT_UNUSED( args )
-
-
-#define SUBPIXEL_HINTING \
- ( ((TT_Driver)FT_FACE_DRIVER( CUR.face ))->interpreter_version == \
+#define SUBPIXEL_HINTING \
+ ( ((TT_Driver)FT_FACE_DRIVER( exc->face ))->interpreter_version == \
TT_INTERPRETER_VERSION_38 )
- /*************************************************************************/
- /* */
- /* The following macros hide the use of EXEC_ARG and EXEC_ARG_ to */
- /* increase readability of the code. */
- /* */
- /*************************************************************************/
-
-
-#define SKIP_Code() \
- SkipCode( EXEC_ARG )
-
-#define GET_ShortIns() \
- GetShortIns( EXEC_ARG )
-
-#define NORMalize( x, y, v ) \
- Normalize( EXEC_ARG_ x, y, v )
-
-#define SET_SuperRound( scale, flags ) \
- SetSuperRound( EXEC_ARG_ scale, flags )
-
-#define ROUND_None( d, c ) \
- Round_None( EXEC_ARG_ d, c )
-
-#define INS_Goto_CodeRange( range, ip ) \
- Ins_Goto_CodeRange( EXEC_ARG_ range, ip )
-
-#define CUR_Func_move( z, p, d ) \
- CUR.func_move( EXEC_ARG_ z, p, d )
-
-#define CUR_Func_move_orig( z, p, d ) \
- CUR.func_move_orig( EXEC_ARG_ z, p, d )
-
-#define CUR_Func_round( d, c ) \
- CUR.func_round( EXEC_ARG_ d, c )
-
-#define CUR_Func_cur_ppem() \
- CUR.func_cur_ppem( EXEC_ARG )
-
-#define CUR_Func_read_cvt( index ) \
- CUR.func_read_cvt( EXEC_ARG_ index )
-
-#define CUR_Func_write_cvt( index, val ) \
- CUR.func_write_cvt( EXEC_ARG_ index, val )
-
-#define CUR_Func_move_cvt( index, val ) \
- CUR.func_move_cvt( EXEC_ARG_ index, val )
-
-#define CURRENT_Ratio() \
- Current_Ratio( EXEC_ARG )
-
-#define INS_SxVTL( a, b, c, d ) \
- Ins_SxVTL( EXEC_ARG_ a, b, c, d )
-
-#define COMPUTE_Funcs() \
- Compute_Funcs( EXEC_ARG )
+#define PROJECT( v1, v2 ) \
+ exc->func_project( exc, (v1)->x - (v2)->x, (v1)->y - (v2)->y )
-#define COMPUTE_Round( a ) \
- Compute_Round( EXEC_ARG_ a )
+#define DUALPROJ( v1, v2 ) \
+ exc->func_dualproj( exc, (v1)->x - (v2)->x, (v1)->y - (v2)->y )
-#define COMPUTE_Point_Displacement( a, b, c, d ) \
- Compute_Point_Displacement( EXEC_ARG_ a, b, c, d )
+#define FAST_PROJECT( v ) \
+ exc->func_project( exc, (v)->x, (v)->y )
-#define MOVE_Zp2_Point( a, b, c, t ) \
- Move_Zp2_Point( EXEC_ARG_ a, b, c, t )
-
-
-#define CUR_Func_project( v1, v2 ) \
- CUR.func_project( EXEC_ARG_ (v1)->x - (v2)->x, (v1)->y - (v2)->y )
-
-#define CUR_Func_dualproj( v1, v2 ) \
- CUR.func_dualproj( EXEC_ARG_ (v1)->x - (v2)->x, (v1)->y - (v2)->y )
-
-#define CUR_fast_project( v ) \
- CUR.func_project( EXEC_ARG_ (v)->x, (v)->y )
-
-#define CUR_fast_dualproj( v ) \
- CUR.func_dualproj( EXEC_ARG_ (v)->x, (v)->y )
+#define FAST_DUALPROJ( v ) \
+ exc->func_dualproj( exc, (v)->x, (v)->y )
/*************************************************************************/
/* */
/* Instruction dispatch function, as used by the interpreter. */
/* */
- typedef void (*TInstruction_Function)( INS_ARG );
+ typedef void (*TInstruction_Function)( TT_ExecContext exc,
+ FT_Long* args );
/*************************************************************************/
@@ -230,13 +87,6 @@
#define BOUNDS( x, n ) ( (FT_UInt)(x) >= (FT_UInt)(n) )
#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
@@ -245,16 +95,20 @@
#define FAILURE 1
#ifdef TT_CONFIG_OPTION_UNPATENTED_HINTING
-#define GUESS_VECTOR( V ) \
- if ( CUR.face->unpatented_hinting ) \
- { \
- CUR.GS.V.x = (FT_F2Dot14)( CUR.GS.both_x_axis ? 0x4000 : 0 ); \
- CUR.GS.V.y = (FT_F2Dot14)( CUR.GS.both_x_axis ? 0 : 0x4000 ); \
- }
+#define GUESS_VECTOR( V ) \
+ do \
+ { \
+ if ( exc->face->unpatented_hinting ) \
+ { \
+ exc->GS.V.x = (FT_F2Dot14)( exc->GS.both_x_axis ? 0x4000 : 0 ); \
+ exc->GS.V.y = (FT_F2Dot14)( exc->GS.both_x_axis ? 0 : 0x4000 ); \
+ } \
+ } while (0)
#else
-#define GUESS_VECTOR( V )
+#define GUESS_VECTOR( V ) do { } while (0)
#endif
+
/*************************************************************************/
/* */
/* CODERANGE FUNCTIONS */
@@ -297,7 +151,7 @@
/* which will return to the first byte *after* the code */
/* range, we test for IP <= Size instead of IP < Size. */
/* */
- FT_ASSERT( (FT_ULong)IP <= coderange->size );
+ FT_ASSERT( IP <= coderange->size );
exec->code = coderange->base;
exec->codeSize = coderange->size;
@@ -498,7 +352,7 @@
FT_LOCAL_DEF( FT_Error )
Update_Max( FT_Memory memory,
FT_ULong* size,
- FT_Long multiplier,
+ FT_ULong multiplier,
void* _pbuff,
FT_ULong new_max )
{
@@ -591,13 +445,13 @@
/* XXX: We reserve a little more elements on the stack to deal safely */
/* with broken fonts like arialbs, courbs, timesbs, etc. */
- tmp = exec->stackSize;
+ tmp = (FT_ULong)exec->stackSize;
error = Update_Max( exec->memory,
&tmp,
sizeof ( FT_F26Dot6 ),
(void*)&exec->stack,
maxp->maxStackElements + 32 );
- exec->stackSize = (FT_UInt)tmp;
+ exec->stackSize = (FT_Long)tmp;
if ( error )
return error;
@@ -683,12 +537,8 @@
/* <Return> */
/* TrueType error code. 0 means success. */
/* */
- /* <Note> */
- /* Only the glyph loader and debugger should call this function. */
- /* */
FT_LOCAL_DEF( FT_Error )
- TT_Run_Context( TT_ExecContext exec,
- FT_Bool debug )
+ TT_Run_Context( TT_ExecContext exec )
{
TT_Goto_CodeRange( exec, tt_coderange_glyph, 0 );
@@ -718,16 +568,7 @@
exec->top = 0;
exec->callTop = 0;
-#if 1
- FT_UNUSED( debug );
-
return exec->face->interpreter( exec );
-#else
- if ( !debug )
- return TT_RunIns( exec );
- else
- return FT_Err_Ok;
-#endif
}
@@ -761,6 +602,9 @@
TT_New_Context( TT_Driver driver )
{
FT_Memory memory;
+ FT_Error error;
+
+ TT_ExecContext exec = NULL;
if ( !driver )
@@ -768,26 +612,16 @@
memory = driver->root.root.memory;
- if ( !driver->context )
- {
- FT_Error error;
- TT_ExecContext exec;
-
-
- /* allocate object */
- if ( FT_NEW( exec ) )
- goto Fail;
-
- /* initialize it; in case of error this deallocates `exec' too */
- error = Init_Context( exec, memory );
- if ( error )
- goto Fail;
+ /* allocate object */
+ if ( FT_NEW( exec ) )
+ goto Fail;
- /* store it into the driver */
- driver->context = exec;
- }
+ /* initialize it; in case of error this deallocates `exec' too */
+ error = Init_Context( exec, memory );
+ if ( error )
+ goto Fail;
- return driver->context;
+ return exec;
Fail:
return NULL;
@@ -834,8 +668,8 @@
/* SFvTL + */ PACK( 2, 0 ),
/* SPvFS */ PACK( 2, 0 ),
/* SFvFS */ PACK( 2, 0 ),
- /* GPV */ PACK( 0, 2 ),
- /* GFV */ PACK( 0, 2 ),
+ /* GPv */ PACK( 0, 2 ),
+ /* GFv */ PACK( 0, 2 ),
/* SFvTPv */ PACK( 0, 0 ),
/* ISECT */ PACK( 5, 0 ),
@@ -964,8 +798,8 @@
/* INS_$83 */ PACK( 0, 0 ),
/* INS_$84 */ PACK( 0, 0 ),
/* ScanCTRL */ PACK( 1, 0 ),
- /* SDPVTL[0] */ PACK( 2, 0 ),
- /* SDPVTL[1] */ PACK( 2, 0 ),
+ /* SDPvTL[0] */ PACK( 2, 0 ),
+ /* SDPvTL[1] */ PACK( 2, 0 ),
/* GetINFO */ PACK( 1, 1 ),
/* IDEF */ PACK( 1, 0 ),
/* ROLL */ PACK( 3, 3 ),
@@ -1098,280 +932,284 @@
#ifdef FT_DEBUG_LEVEL_TRACE
+ /* the first hex digit gives the length of the opcode name; the space */
+ /* after the digit is here just to increase readability of the source */
+ /* code */
+
static
const char* const opcode_name[256] =
{
- "SVTCA y",
- "SVTCA x",
- "SPvTCA y",
- "SPvTCA x",
- "SFvTCA y",
- "SFvTCA x",
- "SPvTL ||",
- "SPvTL +",
- "SFvTL ||",
- "SFvTL +",
- "SPvFS",
- "SFvFS",
- "GPV",
- "GFV",
- "SFvTPv",
- "ISECT",
-
- "SRP0",
- "SRP1",
- "SRP2",
- "SZP0",
- "SZP1",
- "SZP2",
- "SZPS",
- "SLOOP",
- "RTG",
- "RTHG",
- "SMD",
- "ELSE",
- "JMPR",
- "SCvTCi",
- "SSwCi",
- "SSW",
-
- "DUP",
- "POP",
- "CLEAR",
- "SWAP",
- "DEPTH",
- "CINDEX",
- "MINDEX",
- "AlignPTS",
- "INS_$28",
- "UTP",
- "LOOPCALL",
- "CALL",
- "FDEF",
- "ENDF",
- "MDAP[0]",
- "MDAP[1]",
-
- "IUP[0]",
- "IUP[1]",
- "SHP[0]",
- "SHP[1]",
- "SHC[0]",
- "SHC[1]",
- "SHZ[0]",
- "SHZ[1]",
- "SHPIX",
- "IP",
- "MSIRP[0]",
- "MSIRP[1]",
- "AlignRP",
- "RTDG",
- "MIAP[0]",
- "MIAP[1]",
-
- "NPushB",
- "NPushW",
- "WS",
- "RS",
- "WCvtP",
- "RCvt",
- "GC[0]",
- "GC[1]",
- "SCFS",
- "MD[0]",
- "MD[1]",
- "MPPEM",
- "MPS",
- "FlipON",
- "FlipOFF",
- "DEBUG",
-
- "LT",
- "LTEQ",
- "GT",
- "GTEQ",
- "EQ",
- "NEQ",
- "ODD",
- "EVEN",
- "IF",
- "EIF",
- "AND",
- "OR",
- "NOT",
- "DeltaP1",
- "SDB",
- "SDS",
-
- "ADD",
- "SUB",
- "DIV",
- "MUL",
- "ABS",
- "NEG",
- "FLOOR",
- "CEILING",
- "ROUND[0]",
- "ROUND[1]",
- "ROUND[2]",
- "ROUND[3]",
- "NROUND[0]",
- "NROUND[1]",
- "NROUND[2]",
- "NROUND[3]",
-
- "WCvtF",
- "DeltaP2",
- "DeltaP3",
- "DeltaCn[0]",
- "DeltaCn[1]",
- "DeltaCn[2]",
- "SROUND",
- "S45Round",
- "JROT",
- "JROF",
- "ROFF",
- "INS_$7B",
- "RUTG",
- "RDTG",
- "SANGW",
- "AA",
-
- "FlipPT",
- "FlipRgON",
- "FlipRgOFF",
- "INS_$83",
- "INS_$84",
- "ScanCTRL",
- "SDVPTL[0]",
- "SDVPTL[1]",
- "GetINFO",
- "IDEF",
- "ROLL",
- "MAX",
- "MIN",
- "ScanTYPE",
- "InstCTRL",
- "INS_$8F",
-
- "INS_$90",
- "INS_$91",
- "INS_$92",
- "INS_$93",
- "INS_$94",
- "INS_$95",
- "INS_$96",
- "INS_$97",
- "INS_$98",
- "INS_$99",
- "INS_$9A",
- "INS_$9B",
- "INS_$9C",
- "INS_$9D",
- "INS_$9E",
- "INS_$9F",
-
- "INS_$A0",
- "INS_$A1",
- "INS_$A2",
- "INS_$A3",
- "INS_$A4",
- "INS_$A5",
- "INS_$A6",
- "INS_$A7",
- "INS_$A8",
- "INS_$A9",
- "INS_$AA",
- "INS_$AB",
- "INS_$AC",
- "INS_$AD",
- "INS_$AE",
- "INS_$AF",
-
- "PushB[0]",
- "PushB[1]",
- "PushB[2]",
- "PushB[3]",
- "PushB[4]",
- "PushB[5]",
- "PushB[6]",
- "PushB[7]",
- "PushW[0]",
- "PushW[1]",
- "PushW[2]",
- "PushW[3]",
- "PushW[4]",
- "PushW[5]",
- "PushW[6]",
- "PushW[7]",
-
- "MDRP[00]",
- "MDRP[01]",
- "MDRP[02]",
- "MDRP[03]",
- "MDRP[04]",
- "MDRP[05]",
- "MDRP[06]",
- "MDRP[07]",
- "MDRP[08]",
- "MDRP[09]",
- "MDRP[10]",
- "MDRP[11]",
- "MDRP[12]",
- "MDRP[13]",
- "MDRP[14]",
- "MDRP[15]",
-
- "MDRP[16]",
- "MDRP[17]",
- "MDRP[18]",
- "MDRP[19]",
- "MDRP[20]",
- "MDRP[21]",
- "MDRP[22]",
- "MDRP[23]",
- "MDRP[24]",
- "MDRP[25]",
- "MDRP[26]",
- "MDRP[27]",
- "MDRP[28]",
- "MDRP[29]",
- "MDRP[30]",
- "MDRP[31]",
-
- "MIRP[00]",
- "MIRP[01]",
- "MIRP[02]",
- "MIRP[03]",
- "MIRP[04]",
- "MIRP[05]",
- "MIRP[06]",
- "MIRP[07]",
- "MIRP[08]",
- "MIRP[09]",
- "MIRP[10]",
- "MIRP[11]",
- "MIRP[12]",
- "MIRP[13]",
- "MIRP[14]",
- "MIRP[15]",
-
- "MIRP[16]",
- "MIRP[17]",
- "MIRP[18]",
- "MIRP[19]",
- "MIRP[20]",
- "MIRP[21]",
- "MIRP[22]",
- "MIRP[23]",
- "MIRP[24]",
- "MIRP[25]",
- "MIRP[26]",
- "MIRP[27]",
- "MIRP[28]",
- "MIRP[29]",
- "MIRP[30]",
- "MIRP[31]"
+ "7 SVTCA y",
+ "7 SVTCA x",
+ "8 SPvTCA y",
+ "8 SPvTCA x",
+ "8 SFvTCA y",
+ "8 SFvTCA x",
+ "8 SPvTL ||",
+ "7 SPvTL +",
+ "8 SFvTL ||",
+ "7 SFvTL +",
+ "5 SPvFS",
+ "5 SFvFS",
+ "3 GPv",
+ "3 GFv",
+ "6 SFvTPv",
+ "5 ISECT",
+
+ "4 SRP0",
+ "4 SRP1",
+ "4 SRP2",
+ "4 SZP0",
+ "4 SZP1",
+ "4 SZP2",
+ "4 SZPS",
+ "5 SLOOP",
+ "3 RTG",
+ "4 RTHG",
+ "3 SMD",
+ "4 ELSE",
+ "4 JMPR",
+ "6 SCvTCi",
+ "5 SSwCi",
+ "3 SSW",
+
+ "3 DUP",
+ "3 POP",
+ "5 CLEAR",
+ "4 SWAP",
+ "5 DEPTH",
+ "6 CINDEX",
+ "6 MINDEX",
+ "8 AlignPTS",
+ "7 INS_$28",
+ "3 UTP",
+ "8 LOOPCALL",
+ "4 CALL",
+ "4 FDEF",
+ "4 ENDF",
+ "7 MDAP[0]",
+ "7 MDAP[1]",
+
+ "6 IUP[0]",
+ "6 IUP[1]",
+ "6 SHP[0]",
+ "6 SHP[1]",
+ "6 SHC[0]",
+ "6 SHC[1]",
+ "6 SHZ[0]",
+ "6 SHZ[1]",
+ "5 SHPIX",
+ "2 IP",
+ "8 MSIRP[0]",
+ "8 MSIRP[1]",
+ "7 AlignRP",
+ "4 RTDG",
+ "7 MIAP[0]",
+ "7 MIAP[1]",
+
+ "6 NPushB",
+ "6 NPushW",
+ "2 WS",
+ "2 RS",
+ "5 WCvtP",
+ "4 RCvt",
+ "5 GC[0]",
+ "5 GC[1]",
+ "4 SCFS",
+ "5 MD[0]",
+ "5 MD[1]",
+ "5 MPPEM",
+ "3 MPS",
+ "6 FlipON",
+ "7 FlipOFF",
+ "5 DEBUG",
+
+ "2 LT",
+ "4 LTEQ",
+ "2 GT",
+ "4 GTEQ",
+ "2 EQ",
+ "3 NEQ",
+ "3 ODD",
+ "4 EVEN",
+ "2 IF",
+ "3 EIF",
+ "3 AND",
+ "2 OR",
+ "3 NOT",
+ "7 DeltaP1",
+ "3 SDB",
+ "3 SDS",
+
+ "3 ADD",
+ "3 SUB",
+ "3 DIV",
+ "3 MUL",
+ "3 ABS",
+ "3 NEG",
+ "5 FLOOR",
+ "7 CEILING",
+ "8 ROUND[0]",
+ "8 ROUND[1]",
+ "8 ROUND[2]",
+ "8 ROUND[3]",
+ "9 NROUND[0]",
+ "9 NROUND[1]",
+ "9 NROUND[2]",
+ "9 NROUND[3]",
+
+ "5 WCvtF",
+ "7 DeltaP2",
+ "7 DeltaP3",
+ "A DeltaCn[0]",
+ "A DeltaCn[1]",
+ "A DeltaCn[2]",
+ "6 SROUND",
+ "8 S45Round",
+ "4 JROT",
+ "4 JROF",
+ "4 ROFF",
+ "7 INS_$7B",
+ "4 RUTG",
+ "4 RDTG",
+ "5 SANGW",
+ "2 AA",
+
+ "6 FlipPT",
+ "8 FlipRgON",
+ "9 FlipRgOFF",
+ "7 INS_$83",
+ "7 INS_$84",
+ "8 ScanCTRL",
+ "9 SDPvTL[0]",
+ "9 SDPvTL[1]",
+ "7 GetINFO",
+ "4 IDEF",
+ "4 ROLL",
+ "3 MAX",
+ "3 MIN",
+ "8 ScanTYPE",
+ "8 InstCTRL",
+ "7 INS_$8F",
+
+ "7 INS_$90",
+ "7 INS_$91",
+ "7 INS_$92",
+ "7 INS_$93",
+ "7 INS_$94",
+ "7 INS_$95",
+ "7 INS_$96",
+ "7 INS_$97",
+ "7 INS_$98",
+ "7 INS_$99",
+ "7 INS_$9A",
+ "7 INS_$9B",
+ "7 INS_$9C",
+ "7 INS_$9D",
+ "7 INS_$9E",
+ "7 INS_$9F",
+
+ "7 INS_$A0",
+ "7 INS_$A1",
+ "7 INS_$A2",
+ "7 INS_$A3",
+ "7 INS_$A4",
+ "7 INS_$A5",
+ "7 INS_$A6",
+ "7 INS_$A7",
+ "7 INS_$A8",
+ "7 INS_$A9",
+ "7 INS_$AA",
+ "7 INS_$AB",
+ "7 INS_$AC",
+ "7 INS_$AD",
+ "7 INS_$AE",
+ "7 INS_$AF",
+
+ "8 PushB[0]",
+ "8 PushB[1]",
+ "8 PushB[2]",
+ "8 PushB[3]",
+ "8 PushB[4]",
+ "8 PushB[5]",
+ "8 PushB[6]",
+ "8 PushB[7]",
+ "8 PushW[0]",
+ "8 PushW[1]",
+ "8 PushW[2]",
+ "8 PushW[3]",
+ "8 PushW[4]",
+ "8 PushW[5]",
+ "8 PushW[6]",
+ "8 PushW[7]",
+
+ "8 MDRP[00]",
+ "8 MDRP[01]",
+ "8 MDRP[02]",
+ "8 MDRP[03]",
+ "8 MDRP[04]",
+ "8 MDRP[05]",
+ "8 MDRP[06]",
+ "8 MDRP[07]",
+ "8 MDRP[08]",
+ "8 MDRP[09]",
+ "8 MDRP[10]",
+ "8 MDRP[11]",
+ "8 MDRP[12]",
+ "8 MDRP[13]",
+ "8 MDRP[14]",
+ "8 MDRP[15]",
+
+ "8 MDRP[16]",
+ "8 MDRP[17]",
+ "8 MDRP[18]",
+ "8 MDRP[19]",
+ "8 MDRP[20]",
+ "8 MDRP[21]",
+ "8 MDRP[22]",
+ "8 MDRP[23]",
+ "8 MDRP[24]",
+ "8 MDRP[25]",
+ "8 MDRP[26]",
+ "8 MDRP[27]",
+ "8 MDRP[28]",
+ "8 MDRP[29]",
+ "8 MDRP[30]",
+ "8 MDRP[31]",
+
+ "8 MIRP[00]",
+ "8 MIRP[01]",
+ "8 MIRP[02]",
+ "8 MIRP[03]",
+ "8 MIRP[04]",
+ "8 MIRP[05]",
+ "8 MIRP[06]",
+ "8 MIRP[07]",
+ "8 MIRP[08]",
+ "8 MIRP[09]",
+ "8 MIRP[10]",
+ "8 MIRP[11]",
+ "8 MIRP[12]",
+ "8 MIRP[13]",
+ "8 MIRP[14]",
+ "8 MIRP[15]",
+
+ "8 MIRP[16]",
+ "8 MIRP[17]",
+ "8 MIRP[18]",
+ "8 MIRP[19]",
+ "8 MIRP[20]",
+ "8 MIRP[21]",
+ "8 MIRP[22]",
+ "8 MIRP[23]",
+ "8 MIRP[24]",
+ "8 MIRP[25]",
+ "8 MIRP[26]",
+ "8 MIRP[27]",
+ "8 MIRP[28]",
+ "8 MIRP[29]",
+ "8 MIRP[30]",
+ "8 MIRP[31]"
};
#endif /* FT_DEBUG_LEVEL_TRACE */
@@ -1637,55 +1475,55 @@
/* The aspect ratio in 16.16 format, always <= 1.0 . */
/* */
static FT_Long
- Current_Ratio( EXEC_OP )
+ Current_Ratio( TT_ExecContext exc )
{
- if ( !CUR.tt_metrics.ratio )
+ if ( !exc->tt_metrics.ratio )
{
#ifdef TT_CONFIG_OPTION_UNPATENTED_HINTING
- if ( CUR.face->unpatented_hinting )
+ if ( exc->face->unpatented_hinting )
{
- if ( CUR.GS.both_x_axis )
- CUR.tt_metrics.ratio = CUR.tt_metrics.x_ratio;
+ if ( exc->GS.both_x_axis )
+ exc->tt_metrics.ratio = exc->tt_metrics.x_ratio;
else
- CUR.tt_metrics.ratio = CUR.tt_metrics.y_ratio;
+ exc->tt_metrics.ratio = exc->tt_metrics.y_ratio;
}
else
#endif
{
- if ( CUR.GS.projVector.y == 0 )
- CUR.tt_metrics.ratio = CUR.tt_metrics.x_ratio;
+ if ( exc->GS.projVector.y == 0 )
+ exc->tt_metrics.ratio = exc->tt_metrics.x_ratio;
- else if ( CUR.GS.projVector.x == 0 )
- CUR.tt_metrics.ratio = CUR.tt_metrics.y_ratio;
+ else if ( exc->GS.projVector.x == 0 )
+ exc->tt_metrics.ratio = exc->tt_metrics.y_ratio;
else
{
FT_F26Dot6 x, y;
- x = TT_MulFix14( CUR.tt_metrics.x_ratio,
- CUR.GS.projVector.x );
- y = TT_MulFix14( CUR.tt_metrics.y_ratio,
- CUR.GS.projVector.y );
- CUR.tt_metrics.ratio = FT_Hypot( x, y );
+ x = TT_MulFix14( exc->tt_metrics.x_ratio,
+ exc->GS.projVector.x );
+ y = TT_MulFix14( exc->tt_metrics.y_ratio,
+ exc->GS.projVector.y );
+ exc->tt_metrics.ratio = FT_Hypot( x, y );
}
}
}
- return CUR.tt_metrics.ratio;
+ return exc->tt_metrics.ratio;
}
FT_CALLBACK_DEF( FT_Long )
- Current_Ppem( EXEC_OP )
+ Current_Ppem( TT_ExecContext exc )
{
- return CUR.tt_metrics.ppem;
+ return exc->tt_metrics.ppem;
}
FT_CALLBACK_DEF( FT_Long )
- Current_Ppem_Stretched( EXEC_OP )
+ Current_Ppem_Stretched( TT_ExecContext exc )
{
- return FT_MulFix( CUR.tt_metrics.ppem, CURRENT_Ratio() );
+ return FT_MulFix( exc->tt_metrics.ppem, Current_Ratio( exc ) );
}
@@ -1697,48 +1535,54 @@
FT_CALLBACK_DEF( FT_F26Dot6 )
- Read_CVT( EXEC_OP_ FT_ULong idx )
+ Read_CVT( TT_ExecContext exc,
+ FT_ULong idx )
{
- return CUR.cvt[idx];
+ return exc->cvt[idx];
}
FT_CALLBACK_DEF( FT_F26Dot6 )
- Read_CVT_Stretched( EXEC_OP_ FT_ULong idx )
+ Read_CVT_Stretched( TT_ExecContext exc,
+ FT_ULong idx )
{
- return FT_MulFix( CUR.cvt[idx], CURRENT_Ratio() );
+ return FT_MulFix( exc->cvt[idx], Current_Ratio( exc ) );
}
FT_CALLBACK_DEF( void )
- Write_CVT( EXEC_OP_ FT_ULong idx,
- FT_F26Dot6 value )
+ Write_CVT( TT_ExecContext exc,
+ FT_ULong idx,
+ FT_F26Dot6 value )
{
- CUR.cvt[idx] = value;
+ exc->cvt[idx] = value;
}
FT_CALLBACK_DEF( void )
- Write_CVT_Stretched( EXEC_OP_ FT_ULong idx,
- FT_F26Dot6 value )
+ Write_CVT_Stretched( TT_ExecContext exc,
+ FT_ULong idx,
+ FT_F26Dot6 value )
{
- CUR.cvt[idx] = FT_DivFix( value, CURRENT_Ratio() );
+ exc->cvt[idx] = FT_DivFix( value, Current_Ratio( exc ) );
}
FT_CALLBACK_DEF( void )
- Move_CVT( EXEC_OP_ FT_ULong idx,
- FT_F26Dot6 value )
+ Move_CVT( TT_ExecContext exc,
+ FT_ULong idx,
+ FT_F26Dot6 value )
{
- CUR.cvt[idx] += value;
+ exc->cvt[idx] += value;
}
FT_CALLBACK_DEF( void )
- Move_CVT_Stretched( EXEC_OP_ FT_ULong idx,
- FT_F26Dot6 value )
+ Move_CVT_Stretched( TT_ExecContext exc,
+ FT_ULong idx,
+ FT_F26Dot6 value )
{
- CUR.cvt[idx] += FT_DivFix( value, CURRENT_Ratio() );
+ exc->cvt[idx] += FT_DivFix( value, Current_Ratio( exc ) );
}
@@ -1758,12 +1602,12 @@
/* This one could become a macro. */
/* */
static FT_Short
- GetShortIns( EXEC_OP )
+ GetShortIns( TT_ExecContext exc )
{
/* Reading a byte stream so there is no endianess (DaveP) */
- CUR.IP += 2;
- return (FT_Short)( ( CUR.code[CUR.IP - 2] << 8 ) +
- CUR.code[CUR.IP - 1] );
+ exc->IP += 2;
+ return (FT_Short)( ( exc->code[exc->IP - 2] << 8 ) +
+ exc->code[exc->IP - 1] );
}
@@ -1784,23 +1628,24 @@
/* SUCCESS or FAILURE. */
/* */
static FT_Bool
- Ins_Goto_CodeRange( EXEC_OP_ FT_Int aRange,
- FT_ULong aIP )
+ Ins_Goto_CodeRange( TT_ExecContext exc,
+ FT_Int aRange,
+ FT_Long aIP )
{
TT_CodeRange* range;
if ( aRange < 1 || aRange > 3 )
{
- CUR.error = FT_THROW( Bad_Argument );
+ exc->error = FT_THROW( Bad_Argument );
return FAILURE;
}
- range = &CUR.codeRangeTable[aRange - 1];
+ range = &exc->codeRangeTable[aRange - 1];
if ( range->base == NULL ) /* invalid coderange */
{
- CUR.error = FT_THROW( Invalid_CodeRange );
+ exc->error = FT_THROW( Invalid_CodeRange );
return FAILURE;
}
@@ -1810,14 +1655,14 @@
if ( aIP > range->size )
{
- CUR.error = FT_THROW( Code_Overflow );
+ exc->error = FT_THROW( Code_Overflow );
return FAILURE;
}
- CUR.code = range->base;
- CUR.codeSize = range->size;
- CUR.IP = aIP;
- CUR.curRange = aRange;
+ exc->code = range->base;
+ exc->codeSize = range->size;
+ exc->IP = aIP;
+ exc->curRange = aRange;
return SUCCESS;
}
@@ -1841,36 +1686,37 @@
/* zone :: The affected glyph zone. */
/* */
static void
- Direct_Move( EXEC_OP_ TT_GlyphZone zone,
- FT_UShort point,
- FT_F26Dot6 distance )
+ Direct_Move( TT_ExecContext exc,
+ TT_GlyphZone zone,
+ FT_UShort point,
+ FT_F26Dot6 distance )
{
FT_F26Dot6 v;
#ifdef TT_CONFIG_OPTION_UNPATENTED_HINTING
- FT_ASSERT( !CUR.face->unpatented_hinting );
+ FT_ASSERT( !exc->face->unpatented_hinting );
#endif
- v = CUR.GS.freeVector.x;
+ v = exc->GS.freeVector.x;
if ( v != 0 )
{
#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
- if ( !SUBPIXEL_HINTING ||
- ( !CUR.ignore_x_mode ||
- ( CUR.sph_tweak_flags & SPH_TWEAK_ALLOW_X_DMOVE ) ) )
+ if ( !SUBPIXEL_HINTING ||
+ ( !exc->ignore_x_mode ||
+ ( exc->sph_tweak_flags & SPH_TWEAK_ALLOW_X_DMOVE ) ) )
#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */
- zone->cur[point].x += FT_MulDiv( distance, v, CUR.F_dot_P );
+ zone->cur[point].x += FT_MulDiv( distance, v, exc->F_dot_P );
zone->tags[point] |= FT_CURVE_TAG_TOUCH_X;
}
- v = CUR.GS.freeVector.y;
+ v = exc->GS.freeVector.y;
if ( v != 0 )
{
- zone->cur[point].y += FT_MulDiv( distance, v, CUR.F_dot_P );
+ zone->cur[point].y += FT_MulDiv( distance, v, exc->F_dot_P );
zone->tags[point] |= FT_CURVE_TAG_TOUCH_Y;
}
@@ -1895,26 +1741,27 @@
/* zone :: The affected glyph zone. */
/* */
static void
- Direct_Move_Orig( EXEC_OP_ TT_GlyphZone zone,
- FT_UShort point,
- FT_F26Dot6 distance )
+ Direct_Move_Orig( TT_ExecContext exc,
+ TT_GlyphZone zone,
+ FT_UShort point,
+ FT_F26Dot6 distance )
{
FT_F26Dot6 v;
#ifdef TT_CONFIG_OPTION_UNPATENTED_HINTING
- FT_ASSERT( !CUR.face->unpatented_hinting );
+ FT_ASSERT( !exc->face->unpatented_hinting );
#endif
- v = CUR.GS.freeVector.x;
+ v = exc->GS.freeVector.x;
if ( v != 0 )
- zone->org[point].x += FT_MulDiv( distance, v, CUR.F_dot_P );
+ zone->org[point].x += FT_MulDiv( distance, v, exc->F_dot_P );
- v = CUR.GS.freeVector.y;
+ v = exc->GS.freeVector.y;
if ( v != 0 )
- zone->org[point].y += FT_MulDiv( distance, v, CUR.F_dot_P );
+ zone->org[point].y += FT_MulDiv( distance, v, exc->F_dot_P );
}
@@ -1929,15 +1776,16 @@
static void
- Direct_Move_X( EXEC_OP_ TT_GlyphZone zone,
- FT_UShort point,
- FT_F26Dot6 distance )
+ Direct_Move_X( TT_ExecContext exc,
+ TT_GlyphZone zone,
+ FT_UShort point,
+ FT_F26Dot6 distance )
{
- FT_UNUSED_EXEC;
+ FT_UNUSED( exc );
#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
- if ( !SUBPIXEL_HINTING ||
- !CUR.ignore_x_mode )
+ if ( !SUBPIXEL_HINTING ||
+ !exc->ignore_x_mode )
#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */
zone->cur[point].x += distance;
@@ -1946,11 +1794,12 @@
static void
- Direct_Move_Y( EXEC_OP_ TT_GlyphZone zone,
- FT_UShort point,
- FT_F26Dot6 distance )
+ Direct_Move_Y( TT_ExecContext exc,
+ TT_GlyphZone zone,
+ FT_UShort point,
+ FT_F26Dot6 distance )
{
- FT_UNUSED_EXEC;
+ FT_UNUSED( exc );
zone->cur[point].y += distance;
zone->tags[point] |= FT_CURVE_TAG_TOUCH_Y;
@@ -1968,22 +1817,24 @@
static void
- Direct_Move_Orig_X( EXEC_OP_ TT_GlyphZone zone,
- FT_UShort point,
- FT_F26Dot6 distance )
+ Direct_Move_Orig_X( TT_ExecContext exc,
+ TT_GlyphZone zone,
+ FT_UShort point,
+ FT_F26Dot6 distance )
{
- FT_UNUSED_EXEC;
+ FT_UNUSED( exc );
zone->org[point].x += distance;
}
static void
- Direct_Move_Orig_Y( EXEC_OP_ TT_GlyphZone zone,
- FT_UShort point,
- FT_F26Dot6 distance )
+ Direct_Move_Orig_Y( TT_ExecContext exc,
+ TT_GlyphZone zone,
+ FT_UShort point,
+ FT_F26Dot6 distance )
{
- FT_UNUSED_EXEC;
+ FT_UNUSED( exc );
zone->org[point].y += distance;
}
@@ -2012,12 +1863,13 @@
/* before rounding. */
/* */
static FT_F26Dot6
- Round_None( EXEC_OP_ FT_F26Dot6 distance,
- FT_F26Dot6 compensation )
+ Round_None( TT_ExecContext exc,
+ FT_F26Dot6 distance,
+ FT_F26Dot6 compensation )
{
FT_F26Dot6 val;
- FT_UNUSED_EXEC;
+ FT_UNUSED( exc );
if ( distance >= 0 )
@@ -2053,12 +1905,13 @@
/* Rounded distance. */
/* */
static FT_F26Dot6
- Round_To_Grid( EXEC_OP_ FT_F26Dot6 distance,
- FT_F26Dot6 compensation )
+ Round_To_Grid( TT_ExecContext exc,
+ FT_F26Dot6 distance,
+ FT_F26Dot6 compensation )
{
FT_F26Dot6 val;
- FT_UNUSED_EXEC;
+ FT_UNUSED( exc );
if ( distance >= 0 )
@@ -2074,7 +1927,7 @@
val = 0;
}
- return val;
+ return val;
}
@@ -2095,12 +1948,13 @@
/* Rounded distance. */
/* */
static FT_F26Dot6
- Round_To_Half_Grid( EXEC_OP_ FT_F26Dot6 distance,
- FT_F26Dot6 compensation )
+ Round_To_Half_Grid( TT_ExecContext exc,
+ FT_F26Dot6 distance,
+ FT_F26Dot6 compensation )
{
FT_F26Dot6 val;
- FT_UNUSED_EXEC;
+ FT_UNUSED( exc );
if ( distance >= 0 )
@@ -2137,12 +1991,13 @@
/* Rounded distance. */
/* */
static FT_F26Dot6
- Round_Down_To_Grid( EXEC_OP_ FT_F26Dot6 distance,
- FT_F26Dot6 compensation )
+ Round_Down_To_Grid( TT_ExecContext exc,
+ FT_F26Dot6 distance,
+ FT_F26Dot6 compensation )
{
FT_F26Dot6 val;
- FT_UNUSED_EXEC;
+ FT_UNUSED( exc );
if ( distance >= 0 )
@@ -2179,12 +2034,13 @@
/* Rounded distance. */
/* */
static FT_F26Dot6
- Round_Up_To_Grid( EXEC_OP_ FT_F26Dot6 distance,
- FT_F26Dot6 compensation )
+ Round_Up_To_Grid( TT_ExecContext exc,
+ FT_F26Dot6 distance,
+ FT_F26Dot6 compensation )
{
FT_F26Dot6 val;
- FT_UNUSED_EXEC;
+ FT_UNUSED( exc );
if ( distance >= 0 )
@@ -2221,12 +2077,13 @@
/* Rounded distance. */
/* */
static FT_F26Dot6
- Round_To_Double_Grid( EXEC_OP_ FT_F26Dot6 distance,
- FT_F26Dot6 compensation )
+ Round_To_Double_Grid( TT_ExecContext exc,
+ FT_F26Dot6 distance,
+ FT_F26Dot6 compensation )
{
FT_F26Dot6 val;
- FT_UNUSED_EXEC;
+ FT_UNUSED( exc );
if ( distance >= 0 )
@@ -2269,27 +2126,28 @@
/* before rounding. */
/* */
static FT_F26Dot6
- Round_Super( EXEC_OP_ FT_F26Dot6 distance,
- FT_F26Dot6 compensation )
+ Round_Super( TT_ExecContext exc,
+ FT_F26Dot6 distance,
+ FT_F26Dot6 compensation )
{
FT_F26Dot6 val;
if ( distance >= 0 )
{
- val = ( distance - CUR.phase + CUR.threshold + compensation ) &
- -CUR.period;
- val += CUR.phase;
+ val = ( distance - exc->phase + exc->threshold + compensation ) &
+ -exc->period;
+ val += exc->phase;
if ( val < 0 )
- val = CUR.phase;
+ val = exc->phase;
}
else
{
- val = -( ( CUR.threshold - CUR.phase - distance + compensation ) &
- -CUR.period );
- val -= CUR.phase;
+ val = -( ( exc->threshold - exc->phase - distance + compensation ) &
+ -exc->period );
+ val -= exc->phase;
if ( val > 0 )
- val = -CUR.phase;
+ val = -exc->phase;
}
return val;
@@ -2317,27 +2175,28 @@
/* greater precision. */
/* */
static FT_F26Dot6
- Round_Super_45( EXEC_OP_ FT_F26Dot6 distance,
- FT_F26Dot6 compensation )
+ Round_Super_45( TT_ExecContext exc,
+ FT_F26Dot6 distance,
+ FT_F26Dot6 compensation )
{
FT_F26Dot6 val;
if ( distance >= 0 )
{
- val = ( ( distance - CUR.phase + CUR.threshold + compensation ) /
- CUR.period ) * CUR.period;
- val += CUR.phase;
+ val = ( ( distance - exc->phase + exc->threshold + compensation ) /
+ exc->period ) * exc->period;
+ val += exc->phase;
if ( val < 0 )
- val = CUR.phase;
+ val = exc->phase;
}
else
{
- val = -( ( ( CUR.threshold - CUR.phase - distance + compensation ) /
- CUR.period ) * CUR.period );
- val -= CUR.phase;
+ val = -( ( ( exc->threshold - exc->phase - distance + compensation ) /
+ exc->period ) * exc->period );
+ val -= exc->phase;
if ( val > 0 )
- val = -CUR.phase;
+ val = -exc->phase;
}
return val;
@@ -2356,40 +2215,41 @@
/* round_mode :: The rounding mode to be used. */
/* */
static void
- Compute_Round( EXEC_OP_ FT_Byte round_mode )
+ Compute_Round( TT_ExecContext exc,
+ FT_Byte round_mode )
{
switch ( round_mode )
{
case TT_Round_Off:
- CUR.func_round = (TT_Round_Func)Round_None;
+ exc->func_round = (TT_Round_Func)Round_None;
break;
case TT_Round_To_Grid:
- CUR.func_round = (TT_Round_Func)Round_To_Grid;
+ exc->func_round = (TT_Round_Func)Round_To_Grid;
break;
case TT_Round_Up_To_Grid:
- CUR.func_round = (TT_Round_Func)Round_Up_To_Grid;
+ exc->func_round = (TT_Round_Func)Round_Up_To_Grid;
break;
case TT_Round_Down_To_Grid:
- CUR.func_round = (TT_Round_Func)Round_Down_To_Grid;
+ exc->func_round = (TT_Round_Func)Round_Down_To_Grid;
break;
case TT_Round_To_Half_Grid:
- CUR.func_round = (TT_Round_Func)Round_To_Half_Grid;
+ exc->func_round = (TT_Round_Func)Round_To_Half_Grid;
break;
case TT_Round_To_Double_Grid:
- CUR.func_round = (TT_Round_Func)Round_To_Double_Grid;
+ exc->func_round = (TT_Round_Func)Round_To_Double_Grid;
break;
case TT_Round_Super:
- CUR.func_round = (TT_Round_Func)Round_Super;
+ exc->func_round = (TT_Round_Func)Round_Super;
break;
case TT_Round_Super_45:
- CUR.func_round = (TT_Round_Func)Round_Super_45;
+ exc->func_round = (TT_Round_Func)Round_Super_45;
break;
}
}
@@ -2409,57 +2269,58 @@
/* selector :: The SROUND opcode. */
/* */
static void
- SetSuperRound( EXEC_OP_ FT_F26Dot6 GridPeriod,
- FT_Long selector )
+ SetSuperRound( TT_ExecContext exc,
+ FT_F2Dot14 GridPeriod,
+ FT_Long selector )
{
switch ( (FT_Int)( selector & 0xC0 ) )
{
case 0:
- CUR.period = GridPeriod / 2;
+ exc->period = GridPeriod / 2;
break;
case 0x40:
- CUR.period = GridPeriod;
+ exc->period = GridPeriod;
break;
case 0x80:
- CUR.period = GridPeriod * 2;
+ exc->period = GridPeriod * 2;
break;
/* This opcode is reserved, but... */
-
case 0xC0:
- CUR.period = GridPeriod;
+ exc->period = GridPeriod;
break;
}
switch ( (FT_Int)( selector & 0x30 ) )
{
case 0:
- CUR.phase = 0;
+ exc->phase = 0;
break;
case 0x10:
- CUR.phase = CUR.period / 4;
+ exc->phase = exc->period / 4;
break;
case 0x20:
- CUR.phase = CUR.period / 2;
+ exc->phase = exc->period / 2;
break;
case 0x30:
- CUR.phase = CUR.period * 3 / 4;
+ exc->phase = exc->period * 3 / 4;
break;
}
if ( ( selector & 0x0F ) == 0 )
- CUR.threshold = CUR.period - 1;
+ exc->threshold = exc->period - 1;
else
- CUR.threshold = ( (FT_Int)( selector & 0x0F ) - 4 ) * CUR.period / 8;
+ exc->threshold = ( (FT_Int)( selector & 0x0F ) - 4 ) * exc->period / 8;
- CUR.period /= 256;
- CUR.phase /= 256;
- CUR.threshold /= 256;
+ /* convert to F26Dot6 format */
+ exc->period >>= 8;
+ exc->phase >>= 8;
+ exc->threshold >>= 8;
}
@@ -2480,16 +2341,17 @@
/* The distance in F26dot6 format. */
/* */
static FT_F26Dot6
- Project( EXEC_OP_ FT_Pos dx,
- FT_Pos dy )
+ Project( TT_ExecContext exc,
+ FT_Pos dx,
+ FT_Pos dy )
{
#ifdef TT_CONFIG_OPTION_UNPATENTED_HINTING
- FT_ASSERT( !CUR.face->unpatented_hinting );
+ FT_ASSERT( !exc->face->unpatented_hinting );
#endif
- return TT_DotFix14( (FT_UInt32)dx, (FT_UInt32)dy,
- CUR.GS.projVector.x,
- CUR.GS.projVector.y );
+ return TT_DotFix14( dx, dy,
+ exc->GS.projVector.x,
+ exc->GS.projVector.y );
}
@@ -2510,12 +2372,13 @@
/* The distance in F26dot6 format. */
/* */
static FT_F26Dot6
- Dual_Project( EXEC_OP_ FT_Pos dx,
- FT_Pos dy )
+ Dual_Project( TT_ExecContext exc,
+ FT_Pos dx,
+ FT_Pos dy )
{
- return TT_DotFix14( (FT_UInt32)dx, (FT_UInt32)dy,
- CUR.GS.dualVector.x,
- CUR.GS.dualVector.y );
+ return TT_DotFix14( dx, dy,
+ exc->GS.dualVector.x,
+ exc->GS.dualVector.y );
}
@@ -2536,10 +2399,11 @@
/* The distance in F26dot6 format. */
/* */
static FT_F26Dot6
- Project_x( EXEC_OP_ FT_Pos dx,
- FT_Pos dy )
+ Project_x( TT_ExecContext exc,
+ FT_Pos dx,
+ FT_Pos dy )
{
- FT_UNUSED_EXEC;
+ FT_UNUSED( exc );
FT_UNUSED( dy );
return dx;
@@ -2563,10 +2427,11 @@
/* The distance in F26dot6 format. */
/* */
static FT_F26Dot6
- Project_y( EXEC_OP_ FT_Pos dx,
- FT_Pos dy )
+ Project_y( TT_ExecContext exc,
+ FT_Pos dx,
+ FT_Pos dy )
{
- FT_UNUSED_EXEC;
+ FT_UNUSED( exc );
FT_UNUSED( dx );
return dy;
@@ -2583,101 +2448,101 @@
/* to the current graphics state. */
/* */
static void
- Compute_Funcs( EXEC_OP )
+ Compute_Funcs( TT_ExecContext exc )
{
#ifdef TT_CONFIG_OPTION_UNPATENTED_HINTING
- if ( CUR.face->unpatented_hinting )
+ if ( exc->face->unpatented_hinting )
{
- /* If both vectors point rightwards along the x axis, set */
- /* `both-x-axis' true, otherwise set it false. The x values only */
- /* need be tested because the vector has been normalised to a unit */
- /* vector of length 0x4000 = unity. */
- CUR.GS.both_x_axis = (FT_Bool)( CUR.GS.projVector.x == 0x4000 &&
- CUR.GS.freeVector.x == 0x4000 );
+ /* If both vectors point rightwards along the x axis, set */
+ /* `both-x-axis' true, otherwise set it false. The x values only */
+ /* need be tested because the vector has been normalised to a unit */
+ /* vector of length 0x4000 = unity. */
+ exc->GS.both_x_axis = (FT_Bool)( exc->GS.projVector.x == 0x4000 &&
+ exc->GS.freeVector.x == 0x4000 );
/* Throw away projection and freedom vector information */
/* because the patents don't allow them to be stored. */
/* The relevant US Patents are 5155805 and 5325479. */
- CUR.GS.projVector.x = 0;
- CUR.GS.projVector.y = 0;
- CUR.GS.freeVector.x = 0;
- CUR.GS.freeVector.y = 0;
+ exc->GS.projVector.x = 0;
+ exc->GS.projVector.y = 0;
+ exc->GS.freeVector.x = 0;
+ exc->GS.freeVector.y = 0;
- if ( CUR.GS.both_x_axis )
+ if ( exc->GS.both_x_axis )
{
- CUR.func_project = Project_x;
- CUR.func_move = Direct_Move_X;
- CUR.func_move_orig = Direct_Move_Orig_X;
+ exc->func_project = Project_x;
+ exc->func_move = Direct_Move_X;
+ exc->func_move_orig = Direct_Move_Orig_X;
}
else
{
- CUR.func_project = Project_y;
- CUR.func_move = Direct_Move_Y;
- CUR.func_move_orig = Direct_Move_Orig_Y;
+ exc->func_project = Project_y;
+ exc->func_move = Direct_Move_Y;
+ exc->func_move_orig = Direct_Move_Orig_Y;
}
- if ( CUR.GS.dualVector.x == 0x4000 )
- CUR.func_dualproj = Project_x;
- else if ( CUR.GS.dualVector.y == 0x4000 )
- CUR.func_dualproj = Project_y;
+ if ( exc->GS.dualVector.x == 0x4000 )
+ exc->func_dualproj = Project_x;
+ else if ( exc->GS.dualVector.y == 0x4000 )
+ exc->func_dualproj = Project_y;
else
- CUR.func_dualproj = Dual_Project;
+ exc->func_dualproj = Dual_Project;
/* Force recalculation of cached aspect ratio */
- CUR.tt_metrics.ratio = 0;
+ exc->tt_metrics.ratio = 0;
return;
}
#endif /* TT_CONFIG_OPTION_UNPATENTED_HINTING */
- if ( CUR.GS.freeVector.x == 0x4000 )
- CUR.F_dot_P = CUR.GS.projVector.x;
- else if ( CUR.GS.freeVector.y == 0x4000 )
- CUR.F_dot_P = CUR.GS.projVector.y;
+ if ( exc->GS.freeVector.x == 0x4000 )
+ exc->F_dot_P = exc->GS.projVector.x;
+ else if ( exc->GS.freeVector.y == 0x4000 )
+ exc->F_dot_P = exc->GS.projVector.y;
else
- CUR.F_dot_P = ( (FT_Long)CUR.GS.projVector.x * CUR.GS.freeVector.x +
- (FT_Long)CUR.GS.projVector.y * CUR.GS.freeVector.y ) >>
- 14;
-
- if ( CUR.GS.projVector.x == 0x4000 )
- CUR.func_project = (TT_Project_Func)Project_x;
- else if ( CUR.GS.projVector.y == 0x4000 )
- CUR.func_project = (TT_Project_Func)Project_y;
+ exc->F_dot_P =
+ ( (FT_Long)exc->GS.projVector.x * exc->GS.freeVector.x +
+ (FT_Long)exc->GS.projVector.y * exc->GS.freeVector.y ) >> 14;
+
+ if ( exc->GS.projVector.x == 0x4000 )
+ exc->func_project = (TT_Project_Func)Project_x;
+ else if ( exc->GS.projVector.y == 0x4000 )
+ exc->func_project = (TT_Project_Func)Project_y;
else
- CUR.func_project = (TT_Project_Func)Project;
+ exc->func_project = (TT_Project_Func)Project;
- if ( CUR.GS.dualVector.x == 0x4000 )
- CUR.func_dualproj = (TT_Project_Func)Project_x;
- else if ( CUR.GS.dualVector.y == 0x4000 )
- CUR.func_dualproj = (TT_Project_Func)Project_y;
+ if ( exc->GS.dualVector.x == 0x4000 )
+ exc->func_dualproj = (TT_Project_Func)Project_x;
+ else if ( exc->GS.dualVector.y == 0x4000 )
+ exc->func_dualproj = (TT_Project_Func)Project_y;
else
- CUR.func_dualproj = (TT_Project_Func)Dual_Project;
+ exc->func_dualproj = (TT_Project_Func)Dual_Project;
- CUR.func_move = (TT_Move_Func)Direct_Move;
- CUR.func_move_orig = (TT_Move_Func)Direct_Move_Orig;
+ exc->func_move = (TT_Move_Func)Direct_Move;
+ exc->func_move_orig = (TT_Move_Func)Direct_Move_Orig;
- if ( CUR.F_dot_P == 0x4000L )
+ if ( exc->F_dot_P == 0x4000L )
{
- if ( CUR.GS.freeVector.x == 0x4000 )
+ if ( exc->GS.freeVector.x == 0x4000 )
{
- CUR.func_move = (TT_Move_Func)Direct_Move_X;
- CUR.func_move_orig = (TT_Move_Func)Direct_Move_Orig_X;
+ exc->func_move = (TT_Move_Func)Direct_Move_X;
+ exc->func_move_orig = (TT_Move_Func)Direct_Move_Orig_X;
}
- else if ( CUR.GS.freeVector.y == 0x4000 )
+ else if ( exc->GS.freeVector.y == 0x4000 )
{
- CUR.func_move = (TT_Move_Func)Direct_Move_Y;
- CUR.func_move_orig = (TT_Move_Func)Direct_Move_Orig_Y;
+ exc->func_move = (TT_Move_Func)Direct_Move_Y;
+ exc->func_move_orig = (TT_Move_Func)Direct_Move_Orig_Y;
}
}
/* at small sizes, F_dot_P can become too small, resulting */
/* in overflows and `spikes' in a number of glyphs like `w'. */
- if ( FT_ABS( CUR.F_dot_P ) < 0x400L )
- CUR.F_dot_P = 0x4000L;
+ if ( FT_ABS( exc->F_dot_P ) < 0x400L )
+ exc->F_dot_P = 0x4000L;
/* Disable cached aspect ratio */
- CUR.tt_metrics.ratio = 0;
+ exc->tt_metrics.ratio = 0;
}
@@ -2700,1107 +2565,49 @@
/* Returns FAILURE if a vector parameter is zero. */
/* */
/* <Note> */
- /* In case Vx and Vy are both zero, Normalize() returns SUCCESS, and */
+ /* In case Vx and Vy are both zero, `Normalize' returns SUCCESS, and */
/* R is undefined. */
/* */
static FT_Bool
- Normalize( EXEC_OP_ FT_F26Dot6 Vx,
- FT_F26Dot6 Vy,
- FT_UnitVector* R )
+ Normalize( FT_F26Dot6 Vx,
+ FT_F26Dot6 Vy,
+ FT_UnitVector* R )
{
- FT_F26Dot6 W;
-
- FT_UNUSED_EXEC;
+ 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 );
-
- R->x = (FT_F2Dot14)TT_DivFix14( Vx, W );
- R->y = (FT_F2Dot14)TT_DivFix14( Vy, W );
-
- return SUCCESS;
- }
-
+ V.x = Vx;
+ V.y = Vy;
- /*************************************************************************/
- /* */
- /* Here we start with the implementation of the various opcodes. */
- /* */
- /*************************************************************************/
+ FT_Vector_NormLen( &V );
-
- static FT_Bool
- Ins_SxVTL( EXEC_OP_ FT_UShort aIdx1,
- FT_UShort aIdx2,
- FT_Int aOpc,
- FT_UnitVector* Vec )
- {
- FT_Long A, B, C;
- FT_Vector* p1;
- FT_Vector* p2;
-
-
- if ( BOUNDS( aIdx1, CUR.zp2.n_points ) ||
- BOUNDS( aIdx2, CUR.zp1.n_points ) )
- {
- if ( CUR.pedantic_hinting )
- CUR.error = FT_THROW( Invalid_Reference );
- return FAILURE;
- }
-
- p1 = CUR.zp1.cur + aIdx2;
- p2 = CUR.zp2.cur + aIdx1;
-
- A = p1->x - p2->x;
- B = p1->y - p2->y;
-
- /* If p1 == p2, SPVTL and SFVTL behave the same as */
- /* SPVTCA[X] and SFVTCA[X], respectively. */
- /* */
- /* Confirmed by Greg Hitchcock. */
-
- if ( A == 0 && B == 0 )
- {
- A = 0x4000;
- aOpc = 0;
- }
-
- if ( ( aOpc & 1 ) != 0 )
- {
- C = B; /* counter clockwise rotation */
- B = A;
- A = -C;
- }
-
- NORMalize( A, B, Vec );
+ R->x = (FT_F2Dot14)( V.x / 4 );
+ R->y = (FT_F2Dot14)( V.y / 4 );
return SUCCESS;
}
- /* When not using the big switch statements, the interpreter uses a */
- /* call table defined later below in this source. Each opcode must */
- /* thus have a corresponding function, even trivial ones. */
- /* */
- /* They are all defined there. */
-
-#define DO_SVTCA \
- { \
- FT_Short A, B; \
- \
- \
- A = (FT_Short)( CUR.opcode & 1 ) << 14; \
- B = A ^ (FT_Short)0x4000; \
- \
- CUR.GS.freeVector.x = A; \
- CUR.GS.projVector.x = A; \
- CUR.GS.dualVector.x = A; \
- \
- CUR.GS.freeVector.y = B; \
- CUR.GS.projVector.y = B; \
- CUR.GS.dualVector.y = B; \
- \
- COMPUTE_Funcs(); \
- }
-
-
-#define DO_SPVTCA \
- { \
- FT_Short A, B; \
- \
- \
- A = (FT_Short)( CUR.opcode & 1 ) << 14; \
- B = A ^ (FT_Short)0x4000; \
- \
- CUR.GS.projVector.x = A; \
- CUR.GS.dualVector.x = A; \
- \
- CUR.GS.projVector.y = B; \
- CUR.GS.dualVector.y = B; \
- \
- GUESS_VECTOR( freeVector ); \
- \
- COMPUTE_Funcs(); \
- }
-
-
-#define DO_SFVTCA \
- { \
- FT_Short A, B; \
- \
- \
- A = (FT_Short)( CUR.opcode & 1 ) << 14; \
- B = A ^ (FT_Short)0x4000; \
- \
- CUR.GS.freeVector.x = A; \
- CUR.GS.freeVector.y = B; \
- \
- GUESS_VECTOR( projVector ); \
- \
- COMPUTE_Funcs(); \
- }
-
-
-#define DO_SPVTL \
- if ( INS_SxVTL( (FT_UShort)args[1], \
- (FT_UShort)args[0], \
- CUR.opcode, \
- &CUR.GS.projVector ) == SUCCESS ) \
- { \
- CUR.GS.dualVector = CUR.GS.projVector; \
- GUESS_VECTOR( freeVector ); \
- COMPUTE_Funcs(); \
- }
-
-
-#define DO_SFVTL \
- if ( INS_SxVTL( (FT_UShort)args[1], \
- (FT_UShort)args[0], \
- CUR.opcode, \
- &CUR.GS.freeVector ) == SUCCESS ) \
- { \
- GUESS_VECTOR( projVector ); \
- COMPUTE_Funcs(); \
- }
-
-
-#define DO_SFVTPV \
- GUESS_VECTOR( projVector ); \
- CUR.GS.freeVector = CUR.GS.projVector; \
- COMPUTE_Funcs();
-
-
-#define DO_SPVFS \
- { \
- FT_Short S; \
- FT_Long X, Y; \
- \
- \
- /* Only use low 16bits, then sign extend */ \
- S = (FT_Short)args[1]; \
- Y = (FT_Long)S; \
- S = (FT_Short)args[0]; \
- X = (FT_Long)S; \
- \
- NORMalize( X, Y, &CUR.GS.projVector ); \
- \
- CUR.GS.dualVector = CUR.GS.projVector; \
- GUESS_VECTOR( freeVector ); \
- COMPUTE_Funcs(); \
- }
-
-
-#define DO_SFVFS \
- { \
- FT_Short S; \
- FT_Long X, Y; \
- \
- \
- /* Only use low 16bits, then sign extend */ \
- S = (FT_Short)args[1]; \
- Y = (FT_Long)S; \
- S = (FT_Short)args[0]; \
- X = S; \
- \
- NORMalize( X, Y, &CUR.GS.freeVector ); \
- GUESS_VECTOR( projVector ); \
- COMPUTE_Funcs(); \
- }
-
-
-#ifdef TT_CONFIG_OPTION_UNPATENTED_HINTING
-#define DO_GPV \
- if ( CUR.face->unpatented_hinting ) \
- { \
- args[0] = CUR.GS.both_x_axis ? 0x4000 : 0; \
- args[1] = CUR.GS.both_x_axis ? 0 : 0x4000; \
- } \
- else \
- { \
- args[0] = CUR.GS.projVector.x; \
- args[1] = CUR.GS.projVector.y; \
- }
-#else
-#define DO_GPV \
- args[0] = CUR.GS.projVector.x; \
- args[1] = CUR.GS.projVector.y;
-#endif
-
-
-#ifdef TT_CONFIG_OPTION_UNPATENTED_HINTING
-#define DO_GFV \
- if ( CUR.face->unpatented_hinting ) \
- { \
- args[0] = CUR.GS.both_x_axis ? 0x4000 : 0; \
- args[1] = CUR.GS.both_x_axis ? 0 : 0x4000; \
- } \
- else \
- { \
- args[0] = CUR.GS.freeVector.x; \
- args[1] = CUR.GS.freeVector.y; \
- }
-#else
-#define DO_GFV \
- args[0] = CUR.GS.freeVector.x; \
- args[1] = CUR.GS.freeVector.y;
-#endif
-
-
-#define DO_SRP0 \
- CUR.GS.rp0 = (FT_UShort)args[0];
-
-
-#define DO_SRP1 \
- CUR.GS.rp1 = (FT_UShort)args[0];
-
-
-#define DO_SRP2 \
- CUR.GS.rp2 = (FT_UShort)args[0];
-
-
-#define DO_RTHG \
- CUR.GS.round_state = TT_Round_To_Half_Grid; \
- CUR.func_round = (TT_Round_Func)Round_To_Half_Grid;
-
-
-#define DO_RTG \
- CUR.GS.round_state = TT_Round_To_Grid; \
- CUR.func_round = (TT_Round_Func)Round_To_Grid;
-
-
-#define DO_RTDG \
- CUR.GS.round_state = TT_Round_To_Double_Grid; \
- CUR.func_round = (TT_Round_Func)Round_To_Double_Grid;
-
-
-#define DO_RUTG \
- CUR.GS.round_state = TT_Round_Up_To_Grid; \
- CUR.func_round = (TT_Round_Func)Round_Up_To_Grid;
-
-
-#define DO_RDTG \
- CUR.GS.round_state = TT_Round_Down_To_Grid; \
- CUR.func_round = (TT_Round_Func)Round_Down_To_Grid;
-
-
-#define DO_ROFF \
- CUR.GS.round_state = TT_Round_Off; \
- CUR.func_round = (TT_Round_Func)Round_None;
-
-
-#define DO_SROUND \
- SET_SuperRound( 0x4000, args[0] ); \
- CUR.GS.round_state = TT_Round_Super; \
- CUR.func_round = (TT_Round_Func)Round_Super;
-
-
-#define DO_S45ROUND \
- SET_SuperRound( 0x2D41, args[0] ); \
- CUR.GS.round_state = TT_Round_Super_45; \
- CUR.func_round = (TT_Round_Func)Round_Super_45;
-
-
-#define DO_SLOOP \
- if ( args[0] < 0 ) \
- CUR.error = FT_THROW( Bad_Argument ); \
- else \
- CUR.GS.loop = args[0];
-
-
-#define DO_SMD \
- CUR.GS.minimum_distance = args[0];
-
-
-#define DO_SCVTCI \
- CUR.GS.control_value_cutin = (FT_F26Dot6)args[0];
-
-
-#define DO_SSWCI \
- CUR.GS.single_width_cutin = (FT_F26Dot6)args[0];
-
-
-#define DO_SSW \
- CUR.GS.single_width_value = FT_MulFix( args[0], \
- CUR.tt_metrics.scale );
-
-
-#define DO_FLIPON \
- CUR.GS.auto_flip = TRUE;
-
-
-#define DO_FLIPOFF \
- CUR.GS.auto_flip = FALSE;
-
-
-#define DO_SDB \
- CUR.GS.delta_base = (FT_UShort)args[0];
-
-
-#define DO_SDS \
- if ( (FT_ULong)args[0] > 6UL ) \
- CUR.error = FT_THROW( Bad_Argument ); \
- else \
- CUR.GS.delta_shift = (FT_UShort)args[0];
-
-
-#define DO_MD /* nothing */
-
-
-#define DO_MPPEM \
- args[0] = CUR_Func_cur_ppem();
-
-
- /* Note: The pointSize should be irrelevant in a given font program; */
- /* we thus decide to return only the ppem. */
-#if 0
-
-#define DO_MPS \
- args[0] = CUR.metrics.pointSize;
-
-#else
-
-#define DO_MPS \
- args[0] = CUR_Func_cur_ppem();
-
-#endif /* 0 */
-
-
-#define DO_DUP \
- args[1] = args[0];
-
-
-#define DO_CLEAR \
- CUR.new_top = 0;
-
-
-#define DO_SWAP \
- { \
- FT_Long L; \
- \
- \
- L = args[0]; \
- args[0] = args[1]; \
- args[1] = L; \
- }
-
-
-#define DO_DEPTH \
- args[0] = CUR.top;
-
-
-#define DO_CINDEX \
- { \
- FT_Long L; \
- \
- \
- L = args[0]; \
- \
- if ( L <= 0 || L > CUR.args ) \
- { \
- if ( CUR.pedantic_hinting ) \
- CUR.error = FT_THROW( Invalid_Reference ); \
- args[0] = 0; \
- } \
- else \
- args[0] = CUR.stack[CUR.args - L]; \
- }
-
-
-#define DO_JROT \
- if ( args[1] != 0 ) \
- { \
- if ( args[0] == 0 && CUR.args == 0 ) \
- CUR.error = FT_THROW( Bad_Argument ); \
- CUR.IP += args[0]; \
- if ( CUR.IP < 0 || \
- ( CUR.callTop > 0 && \
- CUR.IP > CUR.callStack[CUR.callTop - 1].Def->end ) ) \
- CUR.error = FT_THROW( Bad_Argument ); \
- CUR.step_ins = FALSE; \
- }
-
-
-#define DO_JMPR \
- if ( args[0] == 0 && CUR.args == 0 ) \
- CUR.error = FT_THROW( Bad_Argument ); \
- CUR.IP += args[0]; \
- if ( CUR.IP < 0 || \
- ( CUR.callTop > 0 && \
- CUR.IP > CUR.callStack[CUR.callTop - 1].Def->end ) ) \
- CUR.error = FT_THROW( Bad_Argument ); \
- CUR.step_ins = FALSE;
-
-
-#define DO_JROF \
- if ( args[1] == 0 ) \
- { \
- if ( args[0] == 0 && CUR.args == 0 ) \
- CUR.error = FT_THROW( Bad_Argument ); \
- CUR.IP += args[0]; \
- if ( CUR.IP < 0 || \
- ( CUR.callTop > 0 && \
- CUR.IP > CUR.callStack[CUR.callTop - 1].Def->end ) ) \
- CUR.error = FT_THROW( Bad_Argument ); \
- CUR.step_ins = FALSE; \
- }
-
-
-#define DO_LT \
- args[0] = ( args[0] < args[1] );
-
-
-#define DO_LTEQ \
- args[0] = ( args[0] <= args[1] );
-
-
-#define DO_GT \
- args[0] = ( args[0] > args[1] );
-
-
-#define DO_GTEQ \
- args[0] = ( args[0] >= args[1] );
-
-
-#define DO_EQ \
- args[0] = ( args[0] == args[1] );
-
-
-#define DO_NEQ \
- args[0] = ( args[0] != args[1] );
-
-
-#define DO_ODD \
- args[0] = ( ( CUR_Func_round( args[0], 0 ) & 127 ) == 64 );
-
-
-#define DO_EVEN \
- args[0] = ( ( CUR_Func_round( args[0], 0 ) & 127 ) == 0 );
-
-
-#define DO_AND \
- args[0] = ( args[0] && args[1] );
-
-
-#define DO_OR \
- args[0] = ( args[0] || args[1] );
-
-
-#define DO_NOT \
- args[0] = !args[0];
-
-
-#define DO_ADD \
- args[0] += args[1];
-
-
-#define DO_SUB \
- args[0] -= args[1];
-
-
-#define DO_DIV \
- if ( args[1] == 0 ) \
- CUR.error = FT_THROW( Divide_By_Zero ); \
- else \
- args[0] = FT_MulDiv_No_Round( args[0], 64L, args[1] );
-
-
-#define DO_MUL \
- args[0] = FT_MulDiv( args[0], args[1], 64L );
-
-
-#define DO_ABS \
- args[0] = FT_ABS( args[0] );
-
-
-#define DO_NEG \
- args[0] = -args[0];
-
-
-#define DO_FLOOR \
- args[0] = FT_PIX_FLOOR( args[0] );
-
-
-#define DO_CEILING \
- args[0] = FT_PIX_CEIL( args[0] );
-
-#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
-
-#define DO_RS \
- { \
- FT_ULong I = (FT_ULong)args[0]; \
- \
- \
- if ( BOUNDSL( I, CUR.storeSize ) ) \
- { \
- if ( CUR.pedantic_hinting ) \
- ARRAY_BOUND_ERROR; \
- else \
- args[0] = 0; \
- } \
- else \
- { \
- /* subpixel hinting - avoid Typeman Dstroke and */ \
- /* IStroke and Vacuform rounds */ \
- \
- if ( SUBPIXEL_HINTING && \
- CUR.ignore_x_mode && \
- ( ( I == 24 && \
- ( CUR.face->sph_found_func_flags & \
- ( SPH_FDEF_SPACING_1 | \
- SPH_FDEF_SPACING_2 ) ) ) || \
- ( I == 22 && \
- ( CUR.sph_in_func_flags & \
- SPH_FDEF_TYPEMAN_STROKES ) ) || \
- ( I == 8 && \
- ( CUR.face->sph_found_func_flags & \
- SPH_FDEF_VACUFORM_ROUND_1 ) && \
- CUR.iup_called ) ) ) \
- args[0] = 0; \
- else \
- args[0] = CUR.storage[I]; \
- } \
- }
-
-#else /* !TT_CONFIG_OPTION_SUBPIXEL_HINTING */
-
-#define DO_RS \
- { \
- FT_ULong I = (FT_ULong)args[0]; \
- \
- \
- if ( BOUNDSL( I, CUR.storeSize ) ) \
- { \
- if ( CUR.pedantic_hinting ) \
- { \
- ARRAY_BOUND_ERROR; \
- } \
- else \
- args[0] = 0; \
- } \
- else \
- args[0] = CUR.storage[I]; \
- }
-
-#endif /* !TT_CONFIG_OPTION_SUBPIXEL_HINTING */
-
-
-#define DO_WS \
- { \
- FT_ULong I = (FT_ULong)args[0]; \
- \
- \
- if ( BOUNDSL( I, CUR.storeSize ) ) \
- { \
- if ( CUR.pedantic_hinting ) \
- { \
- ARRAY_BOUND_ERROR; \
- } \
- } \
- else \
- CUR.storage[I] = args[1]; \
- }
-
-
-#define DO_RCVT \
- { \
- FT_ULong I = (FT_ULong)args[0]; \
- \
- \
- if ( BOUNDSL( I, CUR.cvtSize ) ) \
- { \
- if ( CUR.pedantic_hinting ) \
- { \
- ARRAY_BOUND_ERROR; \
- } \
- else \
- args[0] = 0; \
- } \
- else \
- args[0] = CUR_Func_read_cvt( I ); \
- }
-
-
-#define DO_WCVTP \
- { \
- FT_ULong I = (FT_ULong)args[0]; \
- \
- \
- if ( BOUNDSL( I, CUR.cvtSize ) ) \
- { \
- if ( CUR.pedantic_hinting ) \
- { \
- ARRAY_BOUND_ERROR; \
- } \
- } \
- else \
- CUR_Func_write_cvt( I, args[1] ); \
- }
-
-
-#define DO_WCVTF \
- { \
- FT_ULong I = (FT_ULong)args[0]; \
- \
- \
- if ( BOUNDSL( I, CUR.cvtSize ) ) \
- { \
- if ( CUR.pedantic_hinting ) \
- { \
- ARRAY_BOUND_ERROR; \
- } \
- } \
- else \
- CUR.cvt[I] = FT_MulFix( args[1], CUR.tt_metrics.scale ); \
- }
-
-
-#define DO_DEBUG \
- CUR.error = FT_THROW( Debug_OpCode );
-
-
-#define DO_ROUND \
- args[0] = CUR_Func_round( \
- args[0], \
- CUR.tt_metrics.compensations[CUR.opcode - 0x68] );
-
-
-#define DO_NROUND \
- args[0] = ROUND_None( args[0], \
- CUR.tt_metrics.compensations[CUR.opcode - 0x6C] );
-
-
-#define DO_MAX \
- if ( args[1] > args[0] ) \
- args[0] = args[1];
-
-
-#define DO_MIN \
- if ( args[1] < args[0] ) \
- args[0] = args[1];
-
-
-#ifndef TT_CONFIG_OPTION_INTERPRETER_SWITCH
-
-
-#undef ARRAY_BOUND_ERROR
-#define ARRAY_BOUND_ERROR \
- { \
- CUR.error = FT_THROW( Invalid_Reference ); \
- return; \
- }
-
-
/*************************************************************************/
/* */
- /* SVTCA[a]: Set (F and P) Vectors to Coordinate Axis */
- /* Opcode range: 0x00-0x01 */
- /* Stack: --> */
- /* */
- static void
- Ins_SVTCA( INS_ARG )
- {
- DO_SVTCA
- }
-
-
- /*************************************************************************/
- /* */
- /* SPVTCA[a]: Set PVector to Coordinate Axis */
- /* Opcode range: 0x02-0x03 */
- /* Stack: --> */
- /* */
- static void
- Ins_SPVTCA( INS_ARG )
- {
- DO_SPVTCA
- }
-
-
- /*************************************************************************/
- /* */
- /* SFVTCA[a]: Set FVector to Coordinate Axis */
- /* Opcode range: 0x04-0x05 */
- /* Stack: --> */
- /* */
- static void
- Ins_SFVTCA( INS_ARG )
- {
- DO_SFVTCA
- }
-
-
- /*************************************************************************/
- /* */
- /* SPVTL[a]: Set PVector To Line */
- /* Opcode range: 0x06-0x07 */
- /* Stack: uint32 uint32 --> */
- /* */
- static void
- Ins_SPVTL( INS_ARG )
- {
- DO_SPVTL
- }
-
-
- /*************************************************************************/
- /* */
- /* SFVTL[a]: Set FVector To Line */
- /* Opcode range: 0x08-0x09 */
- /* Stack: uint32 uint32 --> */
- /* */
- static void
- Ins_SFVTL( INS_ARG )
- {
- DO_SFVTL
- }
-
-
- /*************************************************************************/
- /* */
- /* SFVTPV[]: Set FVector To PVector */
- /* Opcode range: 0x0E */
- /* Stack: --> */
- /* */
- static void
- Ins_SFVTPV( INS_ARG )
- {
- DO_SFVTPV
- }
-
-
- /*************************************************************************/
- /* */
- /* SPVFS[]: Set PVector From Stack */
- /* Opcode range: 0x0A */
- /* Stack: f2.14 f2.14 --> */
- /* */
- static void
- Ins_SPVFS( INS_ARG )
- {
- DO_SPVFS
- }
-
-
- /*************************************************************************/
- /* */
- /* SFVFS[]: Set FVector From Stack */
- /* Opcode range: 0x0B */
- /* Stack: f2.14 f2.14 --> */
- /* */
- static void
- Ins_SFVFS( INS_ARG )
- {
- DO_SFVFS
- }
-
-
- /*************************************************************************/
- /* */
- /* GPV[]: Get Projection Vector */
- /* Opcode range: 0x0C */
- /* Stack: ef2.14 --> ef2.14 */
- /* */
- static void
- Ins_GPV( INS_ARG )
- {
- DO_GPV
- }
-
-
- /*************************************************************************/
- /* GFV[]: Get Freedom Vector */
- /* Opcode range: 0x0D */
- /* Stack: ef2.14 --> ef2.14 */
- /* */
- static void
- Ins_GFV( INS_ARG )
- {
- DO_GFV
- }
-
-
- /*************************************************************************/
- /* */
- /* SRP0[]: Set Reference Point 0 */
- /* Opcode range: 0x10 */
- /* Stack: uint32 --> */
- /* */
- static void
- Ins_SRP0( INS_ARG )
- {
- DO_SRP0
- }
-
-
- /*************************************************************************/
- /* */
- /* SRP1[]: Set Reference Point 1 */
- /* Opcode range: 0x11 */
- /* Stack: uint32 --> */
- /* */
- static void
- Ins_SRP1( INS_ARG )
- {
- DO_SRP1
- }
-
-
- /*************************************************************************/
- /* */
- /* SRP2[]: Set Reference Point 2 */
- /* Opcode range: 0x12 */
- /* Stack: uint32 --> */
- /* */
- static void
- Ins_SRP2( INS_ARG )
- {
- DO_SRP2
- }
-
-
- /*************************************************************************/
- /* */
- /* RTHG[]: Round To Half Grid */
- /* Opcode range: 0x19 */
- /* Stack: --> */
- /* */
- static void
- Ins_RTHG( INS_ARG )
- {
- DO_RTHG
- }
-
-
- /*************************************************************************/
- /* */
- /* RTG[]: Round To Grid */
- /* Opcode range: 0x18 */
- /* Stack: --> */
- /* */
- static void
- Ins_RTG( INS_ARG )
- {
- DO_RTG
- }
-
-
- /*************************************************************************/
- /* RTDG[]: Round To Double Grid */
- /* Opcode range: 0x3D */
- /* Stack: --> */
- /* */
- static void
- Ins_RTDG( INS_ARG )
- {
- DO_RTDG
- }
-
-
- /*************************************************************************/
- /* RUTG[]: Round Up To Grid */
- /* Opcode range: 0x7C */
- /* Stack: --> */
- /* */
- static void
- Ins_RUTG( INS_ARG )
- {
- DO_RUTG
- }
-
-
- /*************************************************************************/
- /* */
- /* RDTG[]: Round Down To Grid */
- /* Opcode range: 0x7D */
- /* Stack: --> */
- /* */
- static void
- Ins_RDTG( INS_ARG )
- {
- DO_RDTG
- }
-
-
- /*************************************************************************/
- /* */
- /* ROFF[]: Round OFF */
- /* Opcode range: 0x7A */
- /* Stack: --> */
- /* */
- static void
- Ins_ROFF( INS_ARG )
- {
- DO_ROFF
- }
-
-
- /*************************************************************************/
- /* */
- /* SROUND[]: Super ROUND */
- /* Opcode range: 0x76 */
- /* Stack: Eint8 --> */
- /* */
- static void
- Ins_SROUND( INS_ARG )
- {
- DO_SROUND
- }
-
-
- /*************************************************************************/
- /* */
- /* S45ROUND[]: Super ROUND 45 degrees */
- /* Opcode range: 0x77 */
- /* Stack: uint32 --> */
- /* */
- static void
- Ins_S45ROUND( INS_ARG )
- {
- DO_S45ROUND
- }
-
-
- /*************************************************************************/
- /* */
- /* SLOOP[]: Set LOOP variable */
- /* Opcode range: 0x17 */
- /* Stack: int32? --> */
- /* */
- static void
- Ins_SLOOP( INS_ARG )
- {
- DO_SLOOP
- }
-
-
- /*************************************************************************/
- /* */
- /* SMD[]: Set Minimum Distance */
- /* Opcode range: 0x1A */
- /* Stack: f26.6 --> */
- /* */
- static void
- Ins_SMD( INS_ARG )
- {
- DO_SMD
- }
-
-
- /*************************************************************************/
- /* */
- /* SCVTCI[]: Set Control Value Table Cut In */
- /* Opcode range: 0x1D */
- /* Stack: f26.6 --> */
- /* */
- static void
- Ins_SCVTCI( INS_ARG )
- {
- DO_SCVTCI
- }
-
-
- /*************************************************************************/
- /* */
- /* SSWCI[]: Set Single Width Cut In */
- /* Opcode range: 0x1E */
- /* Stack: f26.6 --> */
- /* */
- static void
- Ins_SSWCI( INS_ARG )
- {
- DO_SSWCI
- }
-
-
- /*************************************************************************/
- /* */
- /* SSW[]: Set Single Width */
- /* Opcode range: 0x1F */
- /* Stack: int32? --> */
- /* */
- static void
- Ins_SSW( INS_ARG )
- {
- DO_SSW
- }
-
-
- /*************************************************************************/
- /* */
- /* FLIPON[]: Set auto-FLIP to ON */
- /* Opcode range: 0x4D */
- /* Stack: --> */
- /* */
- static void
- Ins_FLIPON( INS_ARG )
- {
- DO_FLIPON
- }
-
-
- /*************************************************************************/
- /* */
- /* FLIPOFF[]: Set auto-FLIP to OFF */
- /* Opcode range: 0x4E */
- /* Stack: --> */
- /* */
- static void
- Ins_FLIPOFF( INS_ARG )
- {
- DO_FLIPOFF
- }
-
-
- /*************************************************************************/
- /* */
- /* SANGW[]: Set ANGle Weight */
- /* Opcode range: 0x7E */
- /* Stack: uint32 --> */
+ /* Here we start with the implementation of the various opcodes. */
/* */
- static void
- Ins_SANGW( INS_ARG )
- {
- /* instruction not supported anymore */
- }
-
-
/*************************************************************************/
- /* */
- /* SDB[]: Set Delta Base */
- /* Opcode range: 0x5E */
- /* Stack: uint32 --> */
- /* */
- static void
- Ins_SDB( INS_ARG )
- {
- DO_SDB
- }
- /*************************************************************************/
- /* */
- /* SDS[]: Set Delta Shift */
- /* Opcode range: 0x5F */
- /* Stack: uint32 --> */
- /* */
- static void
- Ins_SDS( INS_ARG )
- {
- DO_SDS
- }
+#define ARRAY_BOUND_ERROR \
+ do \
+ { \
+ exc->error = FT_THROW( Invalid_Reference ); \
+ return; \
+ } while (0)
/*************************************************************************/
@@ -3810,9 +2617,10 @@
/* Stack: --> Euint16 */
/* */
static void
- Ins_MPPEM( INS_ARG )
+ Ins_MPPEM( TT_ExecContext exc,
+ FT_Long* args )
{
- DO_MPPEM
+ args[0] = exc->func_cur_ppem( exc );
}
@@ -3823,22 +2631,29 @@
/* Stack: --> Euint16 */
/* */
static void
- Ins_MPS( INS_ARG )
+ Ins_MPS( TT_ExecContext exc,
+ FT_Long* args )
{
- DO_MPS
+ /* Note: The point size should be irrelevant in a given font program; */
+ /* we thus decide to return only the PPEM value. */
+#if 0
+ args[0] = exc->metrics.pointSize;
+#else
+ args[0] = exc->func_cur_ppem( exc );
+#endif
}
/*************************************************************************/
/* */
- /* DUP[]: DUPlicate the top stack's element */
+ /* DUP[]: DUPlicate the stack's top element */
/* Opcode range: 0x20 */
/* Stack: StkElt --> StkElt StkElt */
/* */
static void
- Ins_DUP( INS_ARG )
+ Ins_DUP( FT_Long* args )
{
- DO_DUP
+ args[1] = args[0];
}
@@ -3849,7 +2664,7 @@
/* Stack: StkElt --> */
/* */
static void
- Ins_POP( INS_ARG )
+ Ins_POP( void )
{
/* nothing to do */
}
@@ -3862,9 +2677,9 @@
/* Stack: StkElt... --> */
/* */
static void
- Ins_CLEAR( INS_ARG )
+ Ins_CLEAR( TT_ExecContext exc )
{
- DO_CLEAR
+ exc->new_top = 0;
}
@@ -3875,9 +2690,14 @@
/* Stack: 2 * StkElt --> 2 * StkElt */
/* */
static void
- Ins_SWAP( INS_ARG )
+ Ins_SWAP( FT_Long* args )
{
- DO_SWAP
+ FT_Long L;
+
+
+ L = args[0];
+ args[0] = args[1];
+ args[1] = L;
}
@@ -3888,74 +2708,10 @@
/* Stack: --> uint32 */
/* */
static void
- Ins_DEPTH( INS_ARG )
- {
- DO_DEPTH
- }
-
-
- /*************************************************************************/
- /* */
- /* CINDEX[]: Copy INDEXed element */
- /* Opcode range: 0x25 */
- /* Stack: int32 --> StkElt */
- /* */
- static void
- Ins_CINDEX( INS_ARG )
- {
- DO_CINDEX
- }
-
-
- /*************************************************************************/
- /* */
- /* EIF[]: End IF */
- /* Opcode range: 0x59 */
- /* Stack: --> */
- /* */
- static void
- Ins_EIF( INS_ARG )
- {
- /* nothing to do */
- }
-
-
- /*************************************************************************/
- /* */
- /* JROT[]: Jump Relative On True */
- /* Opcode range: 0x78 */
- /* Stack: StkElt int32 --> */
- /* */
- static void
- Ins_JROT( INS_ARG )
- {
- DO_JROT
- }
-
-
- /*************************************************************************/
- /* */
- /* JMPR[]: JuMP Relative */
- /* Opcode range: 0x1C */
- /* Stack: int32 --> */
- /* */
- static void
- Ins_JMPR( INS_ARG )
- {
- DO_JMPR
- }
-
-
- /*************************************************************************/
- /* */
- /* JROF[]: Jump Relative On False */
- /* Opcode range: 0x79 */
- /* Stack: StkElt int32 --> */
- /* */
- static void
- Ins_JROF( INS_ARG )
+ Ins_DEPTH( TT_ExecContext exc,
+ FT_Long* args )
{
- DO_JROF
+ args[0] = exc->top;
}
@@ -3966,9 +2722,9 @@
/* Stack: int32? int32? --> bool */
/* */
static void
- Ins_LT( INS_ARG )
+ Ins_LT( FT_Long* args )
{
- DO_LT
+ args[0] = ( args[0] < args[1] );
}
@@ -3979,9 +2735,9 @@
/* Stack: int32? int32? --> bool */
/* */
static void
- Ins_LTEQ( INS_ARG )
+ Ins_LTEQ( FT_Long* args )
{
- DO_LTEQ
+ args[0] = ( args[0] <= args[1] );
}
@@ -3992,9 +2748,9 @@
/* Stack: int32? int32? --> bool */
/* */
static void
- Ins_GT( INS_ARG )
+ Ins_GT( FT_Long* args )
{
- DO_GT
+ args[0] = ( args[0] > args[1] );
}
@@ -4005,9 +2761,9 @@
/* Stack: int32? int32? --> bool */
/* */
static void
- Ins_GTEQ( INS_ARG )
+ Ins_GTEQ( FT_Long* args )
{
- DO_GTEQ
+ args[0] = ( args[0] >= args[1] );
}
@@ -4018,9 +2774,9 @@
/* Stack: StkElt StkElt --> bool */
/* */
static void
- Ins_EQ( INS_ARG )
+ Ins_EQ( FT_Long* args )
{
- DO_EQ
+ args[0] = ( args[0] == args[1] );
}
@@ -4031,9 +2787,9 @@
/* Stack: StkElt StkElt --> bool */
/* */
static void
- Ins_NEQ( INS_ARG )
+ Ins_NEQ( FT_Long* args )
{
- DO_NEQ
+ args[0] = ( args[0] != args[1] );
}
@@ -4044,9 +2800,10 @@
/* Stack: f26.6 --> bool */
/* */
static void
- Ins_ODD( INS_ARG )
+ Ins_ODD( TT_ExecContext exc,
+ FT_Long* args )
{
- DO_ODD
+ args[0] = ( ( exc->func_round( exc, args[0], 0 ) & 127 ) == 64 );
}
@@ -4057,9 +2814,10 @@
/* Stack: f26.6 --> bool */
/* */
static void
- Ins_EVEN( INS_ARG )
+ Ins_EVEN( TT_ExecContext exc,
+ FT_Long* args )
{
- DO_EVEN
+ args[0] = ( ( exc->func_round( exc, args[0], 0 ) & 127 ) == 0 );
}
@@ -4070,9 +2828,9 @@
/* Stack: uint32 uint32 --> uint32 */
/* */
static void
- Ins_AND( INS_ARG )
+ Ins_AND( FT_Long* args )
{
- DO_AND
+ args[0] = ( args[0] && args[1] );
}
@@ -4083,9 +2841,9 @@
/* Stack: uint32 uint32 --> uint32 */
/* */
static void
- Ins_OR( INS_ARG )
+ Ins_OR( FT_Long* args )
{
- DO_OR
+ args[0] = ( args[0] || args[1] );
}
@@ -4096,9 +2854,9 @@
/* Stack: StkElt --> uint32 */
/* */
static void
- Ins_NOT( INS_ARG )
+ Ins_NOT( FT_Long* args )
{
- DO_NOT
+ args[0] = !args[0];
}
@@ -4109,9 +2867,9 @@
/* Stack: f26.6 f26.6 --> f26.6 */
/* */
static void
- Ins_ADD( INS_ARG )
+ Ins_ADD( FT_Long* args )
{
- DO_ADD
+ args[0] += args[1];
}
@@ -4122,9 +2880,9 @@
/* Stack: f26.6 f26.6 --> f26.6 */
/* */
static void
- Ins_SUB( INS_ARG )
+ Ins_SUB( FT_Long* args )
{
- DO_SUB
+ args[0] -= args[1];
}
@@ -4135,9 +2893,13 @@
/* Stack: f26.6 f26.6 --> f26.6 */
/* */
static void
- Ins_DIV( INS_ARG )
+ Ins_DIV( TT_ExecContext exc,
+ FT_Long* args )
{
- DO_DIV
+ if ( args[1] == 0 )
+ exc->error = FT_THROW( Divide_By_Zero );
+ else
+ args[0] = FT_MulDiv_No_Round( args[0], 64L, args[1] );
}
@@ -4148,9 +2910,9 @@
/* Stack: f26.6 f26.6 --> f26.6 */
/* */
static void
- Ins_MUL( INS_ARG )
+ Ins_MUL( FT_Long* args )
{
- DO_MUL
+ args[0] = FT_MulDiv( args[0], args[1], 64L );
}
@@ -4161,9 +2923,9 @@
/* Stack: f26.6 --> f26.6 */
/* */
static void
- Ins_ABS( INS_ARG )
+ Ins_ABS( FT_Long* args )
{
- DO_ABS
+ args[0] = FT_ABS( args[0] );
}
@@ -4174,9 +2936,9 @@
/* Stack: f26.6 --> f26.6 */
/* */
static void
- Ins_NEG( INS_ARG )
+ Ins_NEG( FT_Long* args )
{
- DO_NEG
+ args[0] = -args[0];
}
@@ -4187,9 +2949,9 @@
/* Stack: f26.6 --> f26.6 */
/* */
static void
- Ins_FLOOR( INS_ARG )
+ Ins_FLOOR( FT_Long* args )
{
- DO_FLOOR
+ args[0] = FT_PIX_FLOOR( args[0] );
}
@@ -4200,9 +2962,9 @@
/* Stack: f26.6 --> f26.6 */
/* */
static void
- Ins_CEILING( INS_ARG )
+ Ins_CEILING( FT_Long* args )
{
- DO_CEILING
+ args[0] = FT_PIX_CEIL( args[0] );
}
@@ -4213,9 +2975,59 @@
/* Stack: uint32 --> uint32 */
/* */
static void
- Ins_RS( INS_ARG )
+ Ins_RS( TT_ExecContext exc,
+ FT_Long* args )
{
- DO_RS
+#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
+
+ FT_ULong I = (FT_ULong)args[0];
+
+
+ if ( BOUNDSL( I, exc->storeSize ) )
+ {
+ if ( exc->pedantic_hinting )
+ ARRAY_BOUND_ERROR;
+ else
+ args[0] = 0;
+ }
+ else
+ {
+ /* subpixel hinting - avoid Typeman Dstroke and */
+ /* IStroke and Vacuform rounds */
+ if ( SUBPIXEL_HINTING &&
+ exc->ignore_x_mode &&
+ ( ( I == 24 &&
+ ( exc->face->sph_found_func_flags &
+ ( SPH_FDEF_SPACING_1 |
+ SPH_FDEF_SPACING_2 ) ) ) ||
+ ( I == 22 &&
+ ( exc->sph_in_func_flags &
+ SPH_FDEF_TYPEMAN_STROKES ) ) ||
+ ( I == 8 &&
+ ( exc->face->sph_found_func_flags &
+ SPH_FDEF_VACUFORM_ROUND_1 ) &&
+ exc->iup_called ) ) )
+ args[0] = 0;
+ else
+ args[0] = exc->storage[I];
+ }
+
+#else /* !TT_CONFIG_OPTION_SUBPIXEL_HINTING */
+
+ FT_ULong I = (FT_ULong)args[0];
+
+
+ if ( BOUNDSL( I, exc->storeSize ) )
+ {
+ if ( exc->pedantic_hinting )
+ ARRAY_BOUND_ERROR;
+ else
+ args[0] = 0;
+ }
+ else
+ args[0] = exc->storage[I];
+
+#endif /* !TT_CONFIG_OPTION_SUBPIXEL_HINTING */
}
@@ -4226,9 +3038,19 @@
/* Stack: uint32 uint32 --> */
/* */
static void
- Ins_WS( INS_ARG )
+ Ins_WS( TT_ExecContext exc,
+ FT_Long* args )
{
- DO_WS
+ FT_ULong I = (FT_ULong)args[0];
+
+
+ if ( BOUNDSL( I, exc->storeSize ) )
+ {
+ if ( exc->pedantic_hinting )
+ ARRAY_BOUND_ERROR;
+ }
+ else
+ exc->storage[I] = args[1];
}
@@ -4239,9 +3061,19 @@
/* Stack: f26.6 uint32 --> */
/* */
static void
- Ins_WCVTP( INS_ARG )
+ Ins_WCVTP( TT_ExecContext exc,
+ FT_Long* args )
{
- DO_WCVTP
+ FT_ULong I = (FT_ULong)args[0];
+
+
+ if ( BOUNDSL( I, exc->cvtSize ) )
+ {
+ if ( exc->pedantic_hinting )
+ ARRAY_BOUND_ERROR;
+ }
+ else
+ exc->func_write_cvt( exc, I, args[1] );
}
@@ -4252,9 +3084,19 @@
/* Stack: uint32 uint32 --> */
/* */
static void
- Ins_WCVTF( INS_ARG )
+ Ins_WCVTF( TT_ExecContext exc,
+ FT_Long* args )
{
- DO_WCVTF
+ FT_ULong I = (FT_ULong)args[0];
+
+
+ if ( BOUNDSL( I, exc->cvtSize ) )
+ {
+ if ( exc->pedantic_hinting )
+ ARRAY_BOUND_ERROR;
+ }
+ else
+ exc->cvt[I] = FT_MulFix( args[1], exc->tt_metrics.scale );
}
@@ -4265,9 +3107,21 @@
/* Stack: uint32 --> f26.6 */
/* */
static void
- Ins_RCVT( INS_ARG )
+ Ins_RCVT( TT_ExecContext exc,
+ FT_Long* args )
{
- DO_RCVT
+ FT_ULong I = (FT_ULong)args[0];
+
+
+ if ( BOUNDSL( I, exc->cvtSize ) )
+ {
+ if ( exc->pedantic_hinting )
+ ARRAY_BOUND_ERROR;
+ else
+ args[0] = 0;
+ }
+ else
+ args[0] = exc->func_read_cvt( exc, I );
}
@@ -4278,7 +3132,7 @@
/* Stack: uint32 --> */
/* */
static void
- Ins_AA( INS_ARG )
+ Ins_AA( void )
{
/* intentionally no longer supported */
}
@@ -4293,9 +3147,9 @@
/* Note: The original instruction pops a value from the stack. */
/* */
static void
- Ins_DEBUG( INS_ARG )
+ Ins_DEBUG( TT_ExecContext exc )
{
- DO_DEBUG
+ exc->error = FT_THROW( Debug_OpCode );
}
@@ -4306,9 +3160,13 @@
/* Stack: f26.6 --> f26.6 */
/* */
static void
- Ins_ROUND( INS_ARG )
+ Ins_ROUND( TT_ExecContext exc,
+ FT_Long* args )
{
- DO_ROUND
+ args[0] = exc->func_round(
+ exc,
+ args[0],
+ exc->tt_metrics.compensations[exc->opcode - 0x68] );
}
@@ -4319,9 +3177,13 @@
/* Stack: f26.6 --> f26.6 */
/* */
static void
- Ins_NROUND( INS_ARG )
+ Ins_NROUND( TT_ExecContext exc,
+ FT_Long* args )
{
- DO_NROUND
+ args[0] = Round_None(
+ exc,
+ args[0],
+ exc->tt_metrics.compensations[exc->opcode - 0x6C] );
}
@@ -4332,9 +3194,10 @@
/* Stack: int32? int32? --> int32 */
/* */
static void
- Ins_MAX( INS_ARG )
+ Ins_MAX( FT_Long* args )
{
- DO_MAX
+ if ( args[1] > args[0] )
+ args[0] = args[1];
}
@@ -4345,22 +3208,13 @@
/* Stack: int32? int32? --> int32 */
/* */
static void
- Ins_MIN( INS_ARG )
+ Ins_MIN( FT_Long* args )
{
- DO_MIN
+ if ( args[1] < args[0] )
+ args[0] = args[1];
}
-#endif /* !TT_CONFIG_OPTION_INTERPRETER_SWITCH */
-
-
- /*************************************************************************/
- /* */
- /* The following functions are called as is within the switch statement. */
- /* */
- /*************************************************************************/
-
-
/*************************************************************************/
/* */
/* MINDEX[]: Move INDEXed element */
@@ -4368,28 +3222,55 @@
/* Stack: int32? --> StkElt */
/* */
static void
- Ins_MINDEX( INS_ARG )
+ Ins_MINDEX( TT_ExecContext exc,
+ FT_Long* args )
{
FT_Long L, K;
L = args[0];
- if ( L <= 0 || L > CUR.args )
+ if ( L <= 0 || L > exc->args )
{
- if ( CUR.pedantic_hinting )
- CUR.error = FT_THROW( Invalid_Reference );
+ if ( exc->pedantic_hinting )
+ exc->error = FT_THROW( Invalid_Reference );
}
else
{
- K = CUR.stack[CUR.args - L];
+ K = exc->stack[exc->args - L];
- FT_ARRAY_MOVE( &CUR.stack[CUR.args - L ],
- &CUR.stack[CUR.args - L + 1],
+ FT_ARRAY_MOVE( &exc->stack[exc->args - L ],
+ &exc->stack[exc->args - L + 1],
( L - 1 ) );
- CUR.stack[CUR.args - 1] = K;
+ exc->stack[exc->args - 1] = K;
+ }
+ }
+
+
+ /*************************************************************************/
+ /* */
+ /* CINDEX[]: Copy INDEXed element */
+ /* Opcode range: 0x25 */
+ /* Stack: int32 --> StkElt */
+ /* */
+ static void
+ Ins_CINDEX( TT_ExecContext exc,
+ FT_Long* args )
+ {
+ FT_Long L;
+
+
+ L = args[0];
+
+ if ( L <= 0 || L > exc->args )
+ {
+ if ( exc->pedantic_hinting )
+ exc->error = FT_THROW( Invalid_Reference );
+ args[0] = 0;
}
+ else
+ args[0] = exc->stack[exc->args - L];
}
@@ -4400,12 +3281,10 @@
/* Stack: 3 * StkElt --> 3 * StkElt */
/* */
static void
- Ins_ROLL( INS_ARG )
+ Ins_ROLL( FT_Long* args )
{
FT_Long A, B, C;
- FT_UNUSED_EXEC;
-
A = args[2];
B = args[1];
@@ -4421,34 +3300,49 @@
/* */
/* MANAGING THE FLOW OF CONTROL */
/* */
- /* Instructions appear in the specification's order. */
- /* */
/*************************************************************************/
+ /*************************************************************************/
+ /* */
+ /* SLOOP[]: Set LOOP variable */
+ /* Opcode range: 0x17 */
+ /* Stack: int32? --> */
+ /* */
+ static void
+ Ins_SLOOP( TT_ExecContext exc,
+ FT_Long* args )
+ {
+ if ( args[0] < 0 )
+ exc->error = FT_THROW( Bad_Argument );
+ else
+ exc->GS.loop = args[0];
+ }
+
+
static FT_Bool
- SkipCode( EXEC_OP )
+ SkipCode( TT_ExecContext exc )
{
- CUR.IP += CUR.length;
+ exc->IP += exc->length;
- if ( CUR.IP < CUR.codeSize )
+ if ( exc->IP < exc->codeSize )
{
- CUR.opcode = CUR.code[CUR.IP];
+ exc->opcode = exc->code[exc->IP];
- CUR.length = opcode_length[CUR.opcode];
- if ( CUR.length < 0 )
+ exc->length = opcode_length[exc->opcode];
+ if ( exc->length < 0 )
{
- if ( CUR.IP + 1 >= CUR.codeSize )
+ if ( exc->IP + 1 >= exc->codeSize )
goto Fail_Overflow;
- CUR.length = 2 - CUR.length * CUR.code[CUR.IP + 1];
+ exc->length = 2 - exc->length * exc->code[exc->IP + 1];
}
- if ( CUR.IP + CUR.length <= CUR.codeSize )
+ if ( exc->IP + exc->length <= exc->codeSize )
return SUCCESS;
}
Fail_Overflow:
- CUR.error = FT_THROW( Code_Overflow );
+ exc->error = FT_THROW( Code_Overflow );
return FAILURE;
}
@@ -4460,7 +3354,8 @@
/* Stack: StkElt --> */
/* */
static void
- Ins_IF( INS_ARG )
+ Ins_IF( TT_ExecContext exc,
+ FT_Long* args )
{
FT_Int nIfs;
FT_Bool Out;
@@ -4474,10 +3369,10 @@
do
{
- if ( SKIP_Code() == FAILURE )
+ if ( SkipCode( exc ) == FAILURE )
return;
- switch ( CUR.opcode )
+ switch ( exc->opcode )
{
case 0x58: /* IF */
nIfs++;
@@ -4503,21 +3398,19 @@
/* Stack: --> */
/* */
static void
- Ins_ELSE( INS_ARG )
+ Ins_ELSE( TT_ExecContext exc )
{
FT_Int nIfs;
- FT_UNUSED_ARG;
-
nIfs = 1;
do
{
- if ( SKIP_Code() == FAILURE )
+ if ( SkipCode( exc ) == FAILURE )
return;
- switch ( CUR.opcode )
+ switch ( exc->opcode )
{
case 0x58: /* IF */
nIfs++;
@@ -4533,9 +3426,71 @@
/*************************************************************************/
/* */
- /* DEFINING AND USING FUNCTIONS AND INSTRUCTIONS */
+ /* EIF[]: End IF */
+ /* Opcode range: 0x59 */
+ /* Stack: --> */
/* */
- /* Instructions appear in the specification's order. */
+ static void
+ Ins_EIF( void )
+ {
+ /* nothing to do */
+ }
+
+
+ /*************************************************************************/
+ /* */
+ /* JMPR[]: JuMP Relative */
+ /* Opcode range: 0x1C */
+ /* Stack: int32 --> */
+ /* */
+ static void
+ Ins_JMPR( TT_ExecContext exc,
+ FT_Long* args )
+ {
+ if ( args[0] == 0 && exc->args == 0 )
+ exc->error = FT_THROW( Bad_Argument );
+ exc->IP += args[0];
+ if ( exc->IP < 0 ||
+ ( exc->callTop > 0 &&
+ exc->IP > exc->callStack[exc->callTop - 1].Def->end ) )
+ exc->error = FT_THROW( Bad_Argument );
+ exc->step_ins = FALSE;
+ }
+
+
+ /*************************************************************************/
+ /* */
+ /* JROT[]: Jump Relative On True */
+ /* Opcode range: 0x78 */
+ /* Stack: StkElt int32 --> */
+ /* */
+ static void
+ Ins_JROT( TT_ExecContext exc,
+ FT_Long* args )
+ {
+ if ( args[1] != 0 )
+ Ins_JMPR( exc, args );
+ }
+
+
+ /*************************************************************************/
+ /* */
+ /* JROF[]: Jump Relative On False */
+ /* Opcode range: 0x79 */
+ /* Stack: StkElt int32 --> */
+ /* */
+ static void
+ Ins_JROF( TT_ExecContext exc,
+ FT_Long* args )
+ {
+ if ( args[1] == 0 )
+ Ins_JMPR( exc, args );
+ }
+
+
+ /*************************************************************************/
+ /* */
+ /* DEFINING AND USING FUNCTIONS AND INSTRUCTIONS */
/* */
/*************************************************************************/
@@ -4547,7 +3502,8 @@
/* Stack: uint32 --> */
/* */
static void
- Ins_FDEF( INS_ARG )
+ Ins_FDEF( TT_ExecContext exc,
+ FT_Long* args )
{
FT_ULong n;
TT_DefRecord* rec;
@@ -4657,9 +3613,9 @@
/* some font programs are broken enough to redefine functions! */
/* We will then parse the current table. */
- rec = CUR.FDefs;
- limit = rec + CUR.numFDefs;
- n = args[0];
+ rec = exc->FDefs;
+ limit = rec + exc->numFDefs;
+ n = (FT_ULong)args[0];
for ( ; rec < limit; rec++ )
{
@@ -4670,31 +3626,31 @@
if ( rec == limit )
{
/* check that there is enough room for new functions */
- if ( CUR.numFDefs >= CUR.maxFDefs )
+ if ( exc->numFDefs >= exc->maxFDefs )
{
- CUR.error = FT_THROW( Too_Many_Function_Defs );
+ exc->error = FT_THROW( Too_Many_Function_Defs );
return;
}
- CUR.numFDefs++;
+ exc->numFDefs++;
}
/* Although FDEF takes unsigned 32-bit integer, */
/* func # must be within unsigned 16-bit integer */
if ( n > 0xFFFFU )
{
- CUR.error = FT_THROW( Too_Many_Function_Defs );
+ exc->error = FT_THROW( Too_Many_Function_Defs );
return;
}
- rec->range = CUR.curRange;
+ rec->range = exc->curRange;
rec->opc = (FT_UInt16)n;
- rec->start = CUR.IP + 1;
+ rec->start = exc->IP + 1;
rec->active = TRUE;
rec->inline_delta = FALSE;
rec->sph_fdef_flags = 0x0000;
- if ( n > CUR.maxFunc )
- CUR.maxFunc = (FT_UInt16)n;
+ if ( n > exc->maxFunc )
+ exc->maxFunc = (FT_UInt16)n;
#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
/* We don't know for sure these are typeman functions, */
@@ -4706,7 +3662,7 @@
/* Now skip the whole function definition. */
/* We don't allow nested IDEFS & FDEFs. */
- while ( SKIP_Code() == SUCCESS )
+ while ( SkipCode( exc ) == SUCCESS )
{
#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
@@ -4715,28 +3671,28 @@
{
for ( i = 0; i < opcode_patterns; i++ )
{
- if ( opcode_pointer[i] < opcode_size[i] &&
- CUR.opcode == opcode_pattern[i][opcode_pointer[i]] )
+ if ( opcode_pointer[i] < opcode_size[i] &&
+ exc->opcode == opcode_pattern[i][opcode_pointer[i]] )
{
opcode_pointer[i] += 1;
if ( opcode_pointer[i] == opcode_size[i] )
{
- FT_TRACE7(( "sph: Function %d, opcode ptrn: %d, %s %s\n",
+ FT_TRACE6(( "sph: Function %d, opcode ptrn: %d, %s %s\n",
i, n,
- CUR.face->root.family_name,
- CUR.face->root.style_name ));
+ exc->face->root.family_name,
+ exc->face->root.style_name ));
switch ( i )
{
case 0:
- rec->sph_fdef_flags |= SPH_FDEF_INLINE_DELTA_1;
- CUR.face->sph_found_func_flags |= SPH_FDEF_INLINE_DELTA_1;
+ rec->sph_fdef_flags |= SPH_FDEF_INLINE_DELTA_1;
+ exc->face->sph_found_func_flags |= SPH_FDEF_INLINE_DELTA_1;
break;
case 1:
- rec->sph_fdef_flags |= SPH_FDEF_INLINE_DELTA_2;
- CUR.face->sph_found_func_flags |= SPH_FDEF_INLINE_DELTA_2;
+ rec->sph_fdef_flags |= SPH_FDEF_INLINE_DELTA_2;
+ exc->face->sph_found_func_flags |= SPH_FDEF_INLINE_DELTA_2;
break;
case 2:
@@ -4744,8 +3700,8 @@
{
/* needs to be implemented still */
case 58:
- rec->sph_fdef_flags |= SPH_FDEF_DIAGONAL_STROKE;
- CUR.face->sph_found_func_flags |= SPH_FDEF_DIAGONAL_STROKE;
+ rec->sph_fdef_flags |= SPH_FDEF_DIAGONAL_STROKE;
+ exc->face->sph_found_func_flags |= SPH_FDEF_DIAGONAL_STROKE;
}
break;
@@ -4753,15 +3709,15 @@
switch ( n )
{
case 0:
- rec->sph_fdef_flags |= SPH_FDEF_VACUFORM_ROUND_1;
- CUR.face->sph_found_func_flags |= SPH_FDEF_VACUFORM_ROUND_1;
+ rec->sph_fdef_flags |= SPH_FDEF_VACUFORM_ROUND_1;
+ exc->face->sph_found_func_flags |= SPH_FDEF_VACUFORM_ROUND_1;
}
break;
case 4:
/* probably not necessary to detect anymore */
- rec->sph_fdef_flags |= SPH_FDEF_TTFAUTOHINT_1;
- CUR.face->sph_found_func_flags |= SPH_FDEF_TTFAUTOHINT_1;
+ rec->sph_fdef_flags |= SPH_FDEF_TTFAUTOHINT_1;
+ exc->face->sph_found_func_flags |= SPH_FDEF_TTFAUTOHINT_1;
break;
case 5:
@@ -4773,8 +3729,8 @@
case 4:
case 7:
case 8:
- rec->sph_fdef_flags |= SPH_FDEF_SPACING_1;
- CUR.face->sph_found_func_flags |= SPH_FDEF_SPACING_1;
+ rec->sph_fdef_flags |= SPH_FDEF_SPACING_1;
+ exc->face->sph_found_func_flags |= SPH_FDEF_SPACING_1;
}
break;
@@ -4787,20 +3743,20 @@
case 4:
case 7:
case 8:
- rec->sph_fdef_flags |= SPH_FDEF_SPACING_2;
- CUR.face->sph_found_func_flags |= SPH_FDEF_SPACING_2;
+ rec->sph_fdef_flags |= SPH_FDEF_SPACING_2;
+ exc->face->sph_found_func_flags |= SPH_FDEF_SPACING_2;
}
break;
case 7:
- rec->sph_fdef_flags |= SPH_FDEF_TYPEMAN_DIAGENDCTRL;
- CUR.face->sph_found_func_flags |= SPH_FDEF_TYPEMAN_DIAGENDCTRL;
+ rec->sph_fdef_flags |= SPH_FDEF_TYPEMAN_DIAGENDCTRL;
+ exc->face->sph_found_func_flags |= SPH_FDEF_TYPEMAN_DIAGENDCTRL;
break;
case 8:
#if 0
- rec->sph_fdef_flags |= SPH_FDEF_TYPEMAN_DIAGENDCTRL;
- CUR.face->sph_found_func_flags |= SPH_FDEF_TYPEMAN_DIAGENDCTRL;
+ rec->sph_fdef_flags |= SPH_FDEF_TYPEMAN_DIAGENDCTRL;
+ exc->face->sph_found_func_flags |= SPH_FDEF_TYPEMAN_DIAGENDCTRL;
#endif
break;
}
@@ -4813,22 +3769,22 @@
}
/* Set sph_compatibility_mode only when deltas are detected */
- CUR.face->sph_compatibility_mode =
- ( ( CUR.face->sph_found_func_flags & SPH_FDEF_INLINE_DELTA_1 ) |
- ( CUR.face->sph_found_func_flags & SPH_FDEF_INLINE_DELTA_2 ) );
+ exc->face->sph_compatibility_mode =
+ ( ( exc->face->sph_found_func_flags & SPH_FDEF_INLINE_DELTA_1 ) |
+ ( exc->face->sph_found_func_flags & SPH_FDEF_INLINE_DELTA_2 ) );
}
#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */
- switch ( CUR.opcode )
+ switch ( exc->opcode )
{
case 0x89: /* IDEF */
case 0x2C: /* FDEF */
- CUR.error = FT_THROW( Nested_DEFS );
+ exc->error = FT_THROW( Nested_DEFS );
return;
case 0x2D: /* ENDF */
- rec->end = CUR.IP;
+ rec->end = exc->IP;
return;
}
}
@@ -4842,40 +3798,37 @@
/* Stack: --> */
/* */
static void
- Ins_ENDF( INS_ARG )
+ Ins_ENDF( TT_ExecContext exc )
{
TT_CallRec* pRec;
- FT_UNUSED_ARG;
-
#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
- CUR.sph_in_func_flags = 0x0000;
+ exc->sph_in_func_flags = 0x0000;
#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */
- if ( CUR.callTop <= 0 ) /* We encountered an ENDF without a call */
+ if ( exc->callTop <= 0 ) /* We encountered an ENDF without a call */
{
- CUR.error = FT_THROW( ENDF_In_Exec_Stream );
+ exc->error = FT_THROW( ENDF_In_Exec_Stream );
return;
}
- CUR.callTop--;
+ exc->callTop--;
- pRec = &CUR.callStack[CUR.callTop];
+ pRec = &exc->callStack[exc->callTop];
pRec->Cur_Count--;
- CUR.step_ins = FALSE;
+ exc->step_ins = FALSE;
if ( pRec->Cur_Count > 0 )
{
- CUR.callTop++;
- CUR.IP = pRec->Def->start;
+ exc->callTop++;
+ exc->IP = pRec->Def->start;
}
else
/* Loop through the current function */
- INS_Goto_CodeRange( pRec->Caller_Range,
- pRec->Caller_IP );
+ Ins_Goto_CodeRange( exc, pRec->Caller_Range, pRec->Caller_IP );
/* Exit the current call frame. */
@@ -4894,7 +3847,8 @@
/* Stack: uint32? --> */
/* */
static void
- Ins_CALL( INS_ARG )
+ Ins_CALL( TT_ExecContext exc,
+ FT_Long* args )
{
FT_ULong F;
TT_CallRec* pCrec;
@@ -4903,28 +3857,28 @@
/* first of all, check the index */
- F = args[0];
- if ( BOUNDSL( F, CUR.maxFunc + 1 ) )
+ F = (FT_ULong)args[0];
+ if ( BOUNDSL( F, exc->maxFunc + 1 ) )
goto Fail;
/* Except for some old Apple fonts, all functions in a TrueType */
/* font are defined in increasing order, starting from 0. This */
/* means that we normally have */
/* */
- /* CUR.maxFunc+1 == CUR.numFDefs */
- /* CUR.FDefs[n].opc == n for n in 0..CUR.maxFunc */
+ /* exc->maxFunc+1 == exc->numFDefs */
+ /* exc->FDefs[n].opc == n for n in 0..exc->maxFunc */
/* */
/* If this isn't true, we need to look up the function table. */
- def = CUR.FDefs + F;
- if ( CUR.maxFunc + 1 != CUR.numFDefs || def->opc != F )
+ def = exc->FDefs + F;
+ if ( exc->maxFunc + 1 != exc->numFDefs || def->opc != F )
{
/* look up the FDefs table */
TT_DefRecord* limit;
- def = CUR.FDefs;
- limit = def + CUR.numFDefs;
+ def = exc->FDefs;
+ limit = def + exc->numFDefs;
while ( def < limit && def->opc != F )
def++;
@@ -4938,41 +3892,40 @@
goto Fail;
#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
- if ( SUBPIXEL_HINTING &&
- CUR.ignore_x_mode &&
- ( ( CUR.iup_called &&
- ( CUR.sph_tweak_flags & SPH_TWEAK_NO_CALL_AFTER_IUP ) ) ||
- ( def->sph_fdef_flags & SPH_FDEF_VACUFORM_ROUND_1 ) ) )
+ if ( SUBPIXEL_HINTING &&
+ exc->ignore_x_mode &&
+ ( ( exc->iup_called &&
+ ( exc->sph_tweak_flags & SPH_TWEAK_NO_CALL_AFTER_IUP ) ) ||
+ ( def->sph_fdef_flags & SPH_FDEF_VACUFORM_ROUND_1 ) ) )
goto Fail;
else
- CUR.sph_in_func_flags = def->sph_fdef_flags;
+ exc->sph_in_func_flags = def->sph_fdef_flags;
#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */
/* check the call stack */
- if ( CUR.callTop >= CUR.callSize )
+ if ( exc->callTop >= exc->callSize )
{
- CUR.error = FT_THROW( Stack_Overflow );
+ exc->error = FT_THROW( Stack_Overflow );
return;
}
- pCrec = CUR.callStack + CUR.callTop;
+ pCrec = exc->callStack + exc->callTop;
- pCrec->Caller_Range = CUR.curRange;
- pCrec->Caller_IP = CUR.IP + 1;
+ pCrec->Caller_Range = exc->curRange;
+ pCrec->Caller_IP = exc->IP + 1;
pCrec->Cur_Count = 1;
pCrec->Def = def;
- CUR.callTop++;
+ exc->callTop++;
- INS_Goto_CodeRange( def->range,
- def->start );
+ Ins_Goto_CodeRange( exc, def->range, def->start );
- CUR.step_ins = FALSE;
+ exc->step_ins = FALSE;
return;
Fail:
- CUR.error = FT_THROW( Invalid_Reference );
+ exc->error = FT_THROW( Invalid_Reference );
}
@@ -4983,7 +3936,8 @@
/* Stack: uint32? Eint16? --> */
/* */
static void
- Ins_LOOPCALL( INS_ARG )
+ Ins_LOOPCALL( TT_ExecContext exc,
+ FT_Long* args )
{
FT_ULong F;
TT_CallRec* pCrec;
@@ -4991,28 +3945,28 @@
/* first of all, check the index */
- F = args[1];
- if ( BOUNDSL( F, CUR.maxFunc + 1 ) )
+ F = (FT_ULong)args[1];
+ if ( BOUNDSL( F, exc->maxFunc + 1 ) )
goto Fail;
/* Except for some old Apple fonts, all functions in a TrueType */
/* font are defined in increasing order, starting from 0. This */
/* means that we normally have */
/* */
- /* CUR.maxFunc+1 == CUR.numFDefs */
- /* CUR.FDefs[n].opc == n for n in 0..CUR.maxFunc */
+ /* exc->maxFunc+1 == exc->numFDefs */
+ /* exc->FDefs[n].opc == n for n in 0..exc->maxFunc */
/* */
/* If this isn't true, we need to look up the function table. */
- def = CUR.FDefs + F;
- if ( CUR.maxFunc + 1 != CUR.numFDefs || def->opc != F )
+ def = exc->FDefs + F;
+ if ( exc->maxFunc + 1 != exc->numFDefs || def->opc != F )
{
/* look up the FDefs table */
TT_DefRecord* limit;
- def = CUR.FDefs;
- limit = def + CUR.numFDefs;
+ def = exc->FDefs;
+ limit = def + exc->numFDefs;
while ( def < limit && def->opc != F )
def++;
@@ -5027,40 +3981,40 @@
#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
if ( SUBPIXEL_HINTING &&
- CUR.ignore_x_mode &&
+ exc->ignore_x_mode &&
( def->sph_fdef_flags & SPH_FDEF_VACUFORM_ROUND_1 ) )
goto Fail;
else
- CUR.sph_in_func_flags = def->sph_fdef_flags;
+ exc->sph_in_func_flags = def->sph_fdef_flags;
#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */
/* check stack */
- if ( CUR.callTop >= CUR.callSize )
+ if ( exc->callTop >= exc->callSize )
{
- CUR.error = FT_THROW( Stack_Overflow );
+ exc->error = FT_THROW( Stack_Overflow );
return;
}
if ( args[0] > 0 )
{
- pCrec = CUR.callStack + CUR.callTop;
+ pCrec = exc->callStack + exc->callTop;
- pCrec->Caller_Range = CUR.curRange;
- pCrec->Caller_IP = CUR.IP + 1;
+ pCrec->Caller_Range = exc->curRange;
+ pCrec->Caller_IP = exc->IP + 1;
pCrec->Cur_Count = (FT_Int)args[0];
pCrec->Def = def;
- CUR.callTop++;
+ exc->callTop++;
- INS_Goto_CodeRange( def->range, def->start );
+ Ins_Goto_CodeRange( exc, def->range, def->start );
- CUR.step_ins = FALSE;
+ exc->step_ins = FALSE;
}
return;
Fail:
- CUR.error = FT_THROW( Invalid_Reference );
+ exc->error = FT_THROW( Invalid_Reference );
}
@@ -5071,7 +4025,8 @@
/* Stack: Eint8 --> */
/* */
static void
- Ins_IDEF( INS_ARG )
+ Ins_IDEF( TT_ExecContext exc,
+ FT_Long* args )
{
TT_DefRecord* def;
TT_DefRecord* limit;
@@ -5079,8 +4034,8 @@
/* First of all, look for the same function in our table */
- def = CUR.IDefs;
- limit = def + CUR.numIDefs;
+ def = exc->IDefs;
+ limit = def + exc->numIDefs;
for ( ; def < limit; def++ )
if ( def->opc == (FT_ULong)args[0] )
@@ -5089,39 +4044,39 @@
if ( def == limit )
{
/* check that there is enough room for a new instruction */
- if ( CUR.numIDefs >= CUR.maxIDefs )
+ if ( exc->numIDefs >= exc->maxIDefs )
{
- CUR.error = FT_THROW( Too_Many_Instruction_Defs );
+ exc->error = FT_THROW( Too_Many_Instruction_Defs );
return;
}
- CUR.numIDefs++;
+ exc->numIDefs++;
}
/* opcode must be unsigned 8-bit integer */
if ( 0 > args[0] || args[0] > 0x00FF )
{
- CUR.error = FT_THROW( Too_Many_Instruction_Defs );
+ exc->error = FT_THROW( Too_Many_Instruction_Defs );
return;
}
def->opc = (FT_Byte)args[0];
- def->start = CUR.IP + 1;
- def->range = CUR.curRange;
+ def->start = exc->IP + 1;
+ def->range = exc->curRange;
def->active = TRUE;
- if ( (FT_ULong)args[0] > CUR.maxIns )
- CUR.maxIns = (FT_Byte)args[0];
+ if ( (FT_ULong)args[0] > exc->maxIns )
+ exc->maxIns = (FT_Byte)args[0];
/* Now skip the whole function definition. */
/* We don't allow nested IDEFs & FDEFs. */
- while ( SKIP_Code() == SUCCESS )
+ while ( SkipCode( exc ) == SUCCESS )
{
- switch ( CUR.opcode )
+ switch ( exc->opcode )
{
case 0x89: /* IDEF */
case 0x2C: /* FDEF */
- CUR.error = FT_THROW( Nested_DEFS );
+ exc->error = FT_THROW( Nested_DEFS );
return;
case 0x2D: /* ENDF */
return;
@@ -5134,8 +4089,6 @@
/* */
/* PUSHING DATA ONTO THE INTERPRETER STACK */
/* */
- /* Instructions appear in the specification's order. */
- /* */
/*************************************************************************/
@@ -5146,23 +4099,24 @@
/* Stack: --> uint32... */
/* */
static void
- Ins_NPUSHB( INS_ARG )
+ Ins_NPUSHB( TT_ExecContext exc,
+ FT_Long* args )
{
FT_UShort L, K;
- L = (FT_UShort)CUR.code[CUR.IP + 1];
+ L = (FT_UShort)exc->code[exc->IP + 1];
- if ( BOUNDS( L, CUR.stackSize + 1 - CUR.top ) )
+ if ( BOUNDS( L, exc->stackSize + 1 - exc->top ) )
{
- CUR.error = FT_THROW( Stack_Overflow );
+ exc->error = FT_THROW( Stack_Overflow );
return;
}
for ( K = 1; K <= L; K++ )
- args[K - 1] = CUR.code[CUR.IP + K + 1];
+ args[K - 1] = exc->code[exc->IP + K + 1];
- CUR.new_top += L;
+ exc->new_top += L;
}
@@ -5173,26 +4127,27 @@
/* Stack: --> int32... */
/* */
static void
- Ins_NPUSHW( INS_ARG )
+ Ins_NPUSHW( TT_ExecContext exc,
+ FT_Long* args )
{
FT_UShort L, K;
- L = (FT_UShort)CUR.code[CUR.IP + 1];
+ L = (FT_UShort)exc->code[exc->IP + 1];
- if ( BOUNDS( L, CUR.stackSize + 1 - CUR.top ) )
+ if ( BOUNDS( L, exc->stackSize + 1 - exc->top ) )
{
- CUR.error = FT_THROW( Stack_Overflow );
+ exc->error = FT_THROW( Stack_Overflow );
return;
}
- CUR.IP += 2;
+ exc->IP += 2;
for ( K = 0; K < L; K++ )
- args[K] = GET_ShortIns();
+ args[K] = GetShortIns( exc );
- CUR.step_ins = FALSE;
- CUR.new_top += L;
+ exc->step_ins = FALSE;
+ exc->new_top += L;
}
@@ -5203,21 +4158,22 @@
/* Stack: --> uint32... */
/* */
static void
- Ins_PUSHB( INS_ARG )
+ Ins_PUSHB( TT_ExecContext exc,
+ FT_Long* args )
{
FT_UShort L, K;
- L = (FT_UShort)( CUR.opcode - 0xB0 + 1 );
+ L = (FT_UShort)( exc->opcode - 0xB0 + 1 );
- if ( BOUNDS( L, CUR.stackSize + 1 - CUR.top ) )
+ if ( BOUNDS( L, exc->stackSize + 1 - exc->top ) )
{
- CUR.error = FT_THROW( Stack_Overflow );
+ exc->error = FT_THROW( Stack_Overflow );
return;
}
for ( K = 1; K <= L; K++ )
- args[K - 1] = CUR.code[CUR.IP + K];
+ args[K - 1] = exc->code[exc->IP + K];
}
@@ -5228,25 +4184,26 @@
/* Stack: --> int32... */
/* */
static void
- Ins_PUSHW( INS_ARG )
+ Ins_PUSHW( TT_ExecContext exc,
+ FT_Long* args )
{
FT_UShort L, K;
- L = (FT_UShort)( CUR.opcode - 0xB8 + 1 );
+ L = (FT_UShort)( exc->opcode - 0xB8 + 1 );
- if ( BOUNDS( L, CUR.stackSize + 1 - CUR.top ) )
+ if ( BOUNDS( L, exc->stackSize + 1 - exc->top ) )
{
- CUR.error = FT_THROW( Stack_Overflow );
+ exc->error = FT_THROW( Stack_Overflow );
return;
}
- CUR.IP++;
+ exc->IP++;
for ( K = 0; K < L; K++ )
- args[K] = GET_ShortIns();
+ args[K] = GetShortIns( exc );
- CUR.step_ins = FALSE;
+ exc->step_ins = FALSE;
}
@@ -5254,9 +4211,559 @@
/* */
/* MANAGING THE GRAPHICS STATE */
/* */
- /* Instructions appear in the specs' order. */
+ /*************************************************************************/
+
+
+ static FT_Bool
+ Ins_SxVTL( TT_ExecContext exc,
+ FT_UShort aIdx1,
+ FT_UShort aIdx2,
+ FT_UnitVector* Vec )
+ {
+ FT_Long A, B, C;
+ FT_Vector* p1;
+ FT_Vector* p2;
+
+ FT_Byte opcode = exc->opcode;
+
+
+ if ( BOUNDS( aIdx1, exc->zp2.n_points ) ||
+ BOUNDS( aIdx2, exc->zp1.n_points ) )
+ {
+ if ( exc->pedantic_hinting )
+ exc->error = FT_THROW( Invalid_Reference );
+ return FAILURE;
+ }
+
+ p1 = exc->zp1.cur + aIdx2;
+ p2 = exc->zp2.cur + aIdx1;
+
+ A = p1->x - p2->x;
+ B = p1->y - p2->y;
+
+ /* If p1 == p2, SPvTL and SFvTL behave the same as */
+ /* SPvTCA[X] and SFvTCA[X], respectively. */
+ /* */
+ /* Confirmed by Greg Hitchcock. */
+
+ if ( A == 0 && B == 0 )
+ {
+ A = 0x4000;
+ opcode = 0;
+ }
+
+ if ( ( opcode & 1 ) != 0 )
+ {
+ C = B; /* counter clockwise rotation */
+ B = A;
+ A = -C;
+ }
+
+ Normalize( A, B, Vec );
+
+ return SUCCESS;
+ }
+
+
+ /*************************************************************************/
+ /* */
+ /* SVTCA[a]: Set (F and P) Vectors to Coordinate Axis */
+ /* Opcode range: 0x00-0x01 */
+ /* Stack: --> */
/* */
+ /* SPvTCA[a]: Set PVector to Coordinate Axis */
+ /* Opcode range: 0x02-0x03 */
+ /* Stack: --> */
+ /* */
+ /* SFvTCA[a]: Set FVector to Coordinate Axis */
+ /* Opcode range: 0x04-0x05 */
+ /* Stack: --> */
+ /* */
+ static void
+ Ins_SxyTCA( TT_ExecContext exc )
+ {
+ FT_Short AA, BB;
+
+ FT_Byte opcode = exc->opcode;
+
+
+ AA = (FT_Short)( ( opcode & 1 ) << 14 );
+ BB = (FT_Short)( AA ^ 0x4000 );
+
+ if ( opcode < 4 )
+ {
+ exc->GS.projVector.x = AA;
+ exc->GS.projVector.y = BB;
+
+ exc->GS.dualVector.x = AA;
+ exc->GS.dualVector.y = BB;
+ }
+ else
+ GUESS_VECTOR( projVector );
+
+ if ( ( opcode & 2 ) == 0 )
+ {
+ exc->GS.freeVector.x = AA;
+ exc->GS.freeVector.y = BB;
+ }
+ else
+ GUESS_VECTOR( freeVector );
+
+ Compute_Funcs( exc );
+ }
+
+
/*************************************************************************/
+ /* */
+ /* SPvTL[a]: Set PVector To Line */
+ /* Opcode range: 0x06-0x07 */
+ /* Stack: uint32 uint32 --> */
+ /* */
+ static void
+ Ins_SPVTL( TT_ExecContext exc,
+ FT_Long* args )
+ {
+ if ( Ins_SxVTL( exc,
+ (FT_UShort)args[1],
+ (FT_UShort)args[0],
+ &exc->GS.projVector ) == SUCCESS )
+ {
+ exc->GS.dualVector = exc->GS.projVector;
+ GUESS_VECTOR( freeVector );
+ Compute_Funcs( exc );
+ }
+ }
+
+
+ /*************************************************************************/
+ /* */
+ /* SFvTL[a]: Set FVector To Line */
+ /* Opcode range: 0x08-0x09 */
+ /* Stack: uint32 uint32 --> */
+ /* */
+ static void
+ Ins_SFVTL( TT_ExecContext exc,
+ FT_Long* args )
+ {
+ if ( Ins_SxVTL( exc,
+ (FT_UShort)args[1],
+ (FT_UShort)args[0],
+ &exc->GS.freeVector ) == SUCCESS )
+ {
+ GUESS_VECTOR( projVector );
+ Compute_Funcs( exc );
+ }
+ }
+
+
+ /*************************************************************************/
+ /* */
+ /* SFvTPv[]: Set FVector To PVector */
+ /* Opcode range: 0x0E */
+ /* Stack: --> */
+ /* */
+ static void
+ Ins_SFVTPV( TT_ExecContext exc )
+ {
+ GUESS_VECTOR( projVector );
+ exc->GS.freeVector = exc->GS.projVector;
+ Compute_Funcs( exc );
+ }
+
+
+ /*************************************************************************/
+ /* */
+ /* SPvFS[]: Set PVector From Stack */
+ /* Opcode range: 0x0A */
+ /* Stack: f2.14 f2.14 --> */
+ /* */
+ static void
+ Ins_SPVFS( TT_ExecContext exc,
+ FT_Long* args )
+ {
+ FT_Short S;
+ FT_Long X, Y;
+
+
+ /* Only use low 16bits, then sign extend */
+ S = (FT_Short)args[1];
+ Y = (FT_Long)S;
+ S = (FT_Short)args[0];
+ X = (FT_Long)S;
+
+ Normalize( X, Y, &exc->GS.projVector );
+
+ exc->GS.dualVector = exc->GS.projVector;
+ GUESS_VECTOR( freeVector );
+ Compute_Funcs( exc );
+ }
+
+
+ /*************************************************************************/
+ /* */
+ /* SFvFS[]: Set FVector From Stack */
+ /* Opcode range: 0x0B */
+ /* Stack: f2.14 f2.14 --> */
+ /* */
+ static void
+ Ins_SFVFS( TT_ExecContext exc,
+ FT_Long* args )
+ {
+ FT_Short S;
+ FT_Long X, Y;
+
+
+ /* Only use low 16bits, then sign extend */
+ S = (FT_Short)args[1];
+ Y = (FT_Long)S;
+ S = (FT_Short)args[0];
+ X = S;
+
+ Normalize( X, Y, &exc->GS.freeVector );
+ GUESS_VECTOR( projVector );
+ Compute_Funcs( exc );
+ }
+
+
+ /*************************************************************************/
+ /* */
+ /* GPv[]: Get Projection Vector */
+ /* Opcode range: 0x0C */
+ /* Stack: ef2.14 --> ef2.14 */
+ /* */
+ static void
+ Ins_GPV( TT_ExecContext exc,
+ FT_Long* args )
+ {
+#ifdef TT_CONFIG_OPTION_UNPATENTED_HINTING
+ if ( exc->face->unpatented_hinting )
+ {
+ args[0] = exc->GS.both_x_axis ? 0x4000 : 0;
+ args[1] = exc->GS.both_x_axis ? 0 : 0x4000;
+ }
+ else
+ {
+ args[0] = exc->GS.projVector.x;
+ args[1] = exc->GS.projVector.y;
+ }
+#else
+ args[0] = exc->GS.projVector.x;
+ args[1] = exc->GS.projVector.y;
+#endif
+ }
+
+
+ /*************************************************************************/
+ /* */
+ /* GFv[]: Get Freedom Vector */
+ /* Opcode range: 0x0D */
+ /* Stack: ef2.14 --> ef2.14 */
+ /* */
+ static void
+ Ins_GFV( TT_ExecContext exc,
+ FT_Long* args )
+ {
+#ifdef TT_CONFIG_OPTION_UNPATENTED_HINTING
+ if ( exc->face->unpatented_hinting )
+ {
+ args[0] = exc->GS.both_x_axis ? 0x4000 : 0;
+ args[1] = exc->GS.both_x_axis ? 0 : 0x4000;
+ }
+ else
+ {
+ args[0] = exc->GS.freeVector.x;
+ args[1] = exc->GS.freeVector.y;
+ }
+#else
+ args[0] = exc->GS.freeVector.x;
+ args[1] = exc->GS.freeVector.y;
+#endif
+ }
+
+
+ /*************************************************************************/
+ /* */
+ /* SRP0[]: Set Reference Point 0 */
+ /* Opcode range: 0x10 */
+ /* Stack: uint32 --> */
+ /* */
+ static void
+ Ins_SRP0( TT_ExecContext exc,
+ FT_Long* args )
+ {
+ exc->GS.rp0 = (FT_UShort)args[0];
+ }
+
+
+ /*************************************************************************/
+ /* */
+ /* SRP1[]: Set Reference Point 1 */
+ /* Opcode range: 0x11 */
+ /* Stack: uint32 --> */
+ /* */
+ static void
+ Ins_SRP1( TT_ExecContext exc,
+ FT_Long* args )
+ {
+ exc->GS.rp1 = (FT_UShort)args[0];
+ }
+
+
+ /*************************************************************************/
+ /* */
+ /* SRP2[]: Set Reference Point 2 */
+ /* Opcode range: 0x12 */
+ /* Stack: uint32 --> */
+ /* */
+ static void
+ Ins_SRP2( TT_ExecContext exc,
+ FT_Long* args )
+ {
+ exc->GS.rp2 = (FT_UShort)args[0];
+ }
+
+
+ /*************************************************************************/
+ /* */
+ /* SMD[]: Set Minimum Distance */
+ /* Opcode range: 0x1A */
+ /* Stack: f26.6 --> */
+ /* */
+ static void
+ Ins_SMD( TT_ExecContext exc,
+ FT_Long* args )
+ {
+ exc->GS.minimum_distance = args[0];
+ }
+
+
+ /*************************************************************************/
+ /* */
+ /* SCVTCI[]: Set Control Value Table Cut In */
+ /* Opcode range: 0x1D */
+ /* Stack: f26.6 --> */
+ /* */
+ static void
+ Ins_SCVTCI( TT_ExecContext exc,
+ FT_Long* args )
+ {
+ exc->GS.control_value_cutin = (FT_F26Dot6)args[0];
+ }
+
+
+ /*************************************************************************/
+ /* */
+ /* SSWCI[]: Set Single Width Cut In */
+ /* Opcode range: 0x1E */
+ /* Stack: f26.6 --> */
+ /* */
+ static void
+ Ins_SSWCI( TT_ExecContext exc,
+ FT_Long* args )
+ {
+ exc->GS.single_width_cutin = (FT_F26Dot6)args[0];
+ }
+
+
+ /*************************************************************************/
+ /* */
+ /* SSW[]: Set Single Width */
+ /* Opcode range: 0x1F */
+ /* Stack: int32? --> */
+ /* */
+ static void
+ Ins_SSW( TT_ExecContext exc,
+ FT_Long* args )
+ {
+ exc->GS.single_width_value = FT_MulFix( args[0],
+ exc->tt_metrics.scale );
+ }
+
+
+ /*************************************************************************/
+ /* */
+ /* FLIPON[]: Set auto-FLIP to ON */
+ /* Opcode range: 0x4D */
+ /* Stack: --> */
+ /* */
+ static void
+ Ins_FLIPON( TT_ExecContext exc )
+ {
+ exc->GS.auto_flip = TRUE;
+ }
+
+
+ /*************************************************************************/
+ /* */
+ /* FLIPOFF[]: Set auto-FLIP to OFF */
+ /* Opcode range: 0x4E */
+ /* Stack: --> */
+ /* */
+ static void
+ Ins_FLIPOFF( TT_ExecContext exc )
+ {
+ exc->GS.auto_flip = FALSE;
+ }
+
+
+ /*************************************************************************/
+ /* */
+ /* SANGW[]: Set ANGle Weight */
+ /* Opcode range: 0x7E */
+ /* Stack: uint32 --> */
+ /* */
+ static void
+ Ins_SANGW( void )
+ {
+ /* instruction not supported anymore */
+ }
+
+
+ /*************************************************************************/
+ /* */
+ /* SDB[]: Set Delta Base */
+ /* Opcode range: 0x5E */
+ /* Stack: uint32 --> */
+ /* */
+ static void
+ Ins_SDB( TT_ExecContext exc,
+ FT_Long* args )
+ {
+ exc->GS.delta_base = (FT_UShort)args[0];
+ }
+
+
+ /*************************************************************************/
+ /* */
+ /* SDS[]: Set Delta Shift */
+ /* Opcode range: 0x5F */
+ /* Stack: uint32 --> */
+ /* */
+ static void
+ Ins_SDS( TT_ExecContext exc,
+ FT_Long* args )
+ {
+ if ( (FT_ULong)args[0] > 6UL )
+ exc->error = FT_THROW( Bad_Argument );
+ else
+ exc->GS.delta_shift = (FT_UShort)args[0];
+ }
+
+
+ /*************************************************************************/
+ /* */
+ /* RTHG[]: Round To Half Grid */
+ /* Opcode range: 0x19 */
+ /* Stack: --> */
+ /* */
+ static void
+ Ins_RTHG( TT_ExecContext exc )
+ {
+ exc->GS.round_state = TT_Round_To_Half_Grid;
+ exc->func_round = (TT_Round_Func)Round_To_Half_Grid;
+ }
+
+
+ /*************************************************************************/
+ /* */
+ /* RTG[]: Round To Grid */
+ /* Opcode range: 0x18 */
+ /* Stack: --> */
+ /* */
+ static void
+ Ins_RTG( TT_ExecContext exc )
+ {
+ exc->GS.round_state = TT_Round_To_Grid;
+ exc->func_round = (TT_Round_Func)Round_To_Grid;
+ }
+
+
+ /*************************************************************************/
+ /* RTDG[]: Round To Double Grid */
+ /* Opcode range: 0x3D */
+ /* Stack: --> */
+ /* */
+ static void
+ Ins_RTDG( TT_ExecContext exc )
+ {
+ exc->GS.round_state = TT_Round_To_Double_Grid;
+ exc->func_round = (TT_Round_Func)Round_To_Double_Grid;
+ }
+
+
+ /*************************************************************************/
+ /* RUTG[]: Round Up To Grid */
+ /* Opcode range: 0x7C */
+ /* Stack: --> */
+ /* */
+ static void
+ Ins_RUTG( TT_ExecContext exc )
+ {
+ exc->GS.round_state = TT_Round_Up_To_Grid;
+ exc->func_round = (TT_Round_Func)Round_Up_To_Grid;
+ }
+
+
+ /*************************************************************************/
+ /* */
+ /* RDTG[]: Round Down To Grid */
+ /* Opcode range: 0x7D */
+ /* Stack: --> */
+ /* */
+ static void
+ Ins_RDTG( TT_ExecContext exc )
+ {
+ exc->GS.round_state = TT_Round_Down_To_Grid;
+ exc->func_round = (TT_Round_Func)Round_Down_To_Grid;
+ }
+
+
+ /*************************************************************************/
+ /* */
+ /* ROFF[]: Round OFF */
+ /* Opcode range: 0x7A */
+ /* Stack: --> */
+ /* */
+ static void
+ Ins_ROFF( TT_ExecContext exc )
+ {
+ exc->GS.round_state = TT_Round_Off;
+ exc->func_round = (TT_Round_Func)Round_None;
+ }
+
+
+ /*************************************************************************/
+ /* */
+ /* SROUND[]: Super ROUND */
+ /* Opcode range: 0x76 */
+ /* Stack: Eint8 --> */
+ /* */
+ static void
+ Ins_SROUND( TT_ExecContext exc,
+ FT_Long* args )
+ {
+ SetSuperRound( exc, 0x4000, args[0] );
+
+ exc->GS.round_state = TT_Round_Super;
+ exc->func_round = (TT_Round_Func)Round_Super;
+ }
+
+
+ /*************************************************************************/
+ /* */
+ /* S45ROUND[]: Super ROUND 45 degrees */
+ /* Opcode range: 0x77 */
+ /* Stack: uint32 --> */
+ /* */
+ static void
+ Ins_S45ROUND( TT_ExecContext exc,
+ FT_Long* args )
+ {
+ SetSuperRound( exc, 0x2D41, args[0] );
+
+ exc->GS.round_state = TT_Round_Super_45;
+ exc->func_round = (TT_Round_Func)Round_Super_45;
+ }
/*************************************************************************/
@@ -5269,7 +4776,8 @@
/* along the dual projection vector! */
/* */
static void
- Ins_GC( INS_ARG )
+ Ins_GC( TT_ExecContext exc,
+ FT_Long* args )
{
FT_ULong L;
FT_F26Dot6 R;
@@ -5277,18 +4785,18 @@
L = (FT_ULong)args[0];
- if ( BOUNDSL( L, CUR.zp2.n_points ) )
+ if ( BOUNDSL( L, exc->zp2.n_points ) )
{
- if ( CUR.pedantic_hinting )
- CUR.error = FT_THROW( Invalid_Reference );
+ if ( exc->pedantic_hinting )
+ exc->error = FT_THROW( Invalid_Reference );
R = 0;
}
else
{
- if ( CUR.opcode & 1 )
- R = CUR_fast_dualproj( &CUR.zp2.org[L] );
+ if ( exc->opcode & 1 )
+ R = FAST_DUALPROJ( &exc->zp2.org[L] );
else
- R = CUR_fast_project( &CUR.zp2.cur[L] );
+ R = FAST_PROJECT( &exc->zp2.cur[L] );
}
args[0] = R;
@@ -5306,7 +4814,8 @@
/* OA := OA + ( value - OA.p )/( f.p ) * f */
/* */
static void
- Ins_SCFS( INS_ARG )
+ Ins_SCFS( TT_ExecContext exc,
+ FT_Long* args )
{
FT_Long K;
FT_UShort L;
@@ -5314,21 +4823,21 @@
L = (FT_UShort)args[0];
- if ( BOUNDS( L, CUR.zp2.n_points ) )
+ if ( BOUNDS( L, exc->zp2.n_points ) )
{
- if ( CUR.pedantic_hinting )
- CUR.error = FT_THROW( Invalid_Reference );
+ if ( exc->pedantic_hinting )
+ exc->error = FT_THROW( Invalid_Reference );
return;
}
- K = CUR_fast_project( &CUR.zp2.cur[L] );
+ K = FAST_PROJECT( &exc->zp2.cur[L] );
- CUR_Func_move( &CUR.zp2, L, args[1] - K );
+ exc->func_move( exc, &exc->zp2, L, args[1] - K );
/* UNDOCUMENTED! The MS rasterizer does that with */
/* twilight points (confirmed by Greg Hitchcock) */
- if ( CUR.GS.gep2 == 0 )
- CUR.zp2.org[L] = CUR.zp2.cur[L];
+ if ( exc->GS.gep2 == 0 )
+ exc->zp2.org[L] = exc->zp2.cur[L];
}
@@ -5348,7 +4857,8 @@
/* XXX: UNDOCUMENTED: `zp0 - zp1', and not `zp2 - zp1! */
/* */
static void
- Ins_MD( INS_ARG )
+ Ins_MD( TT_ExecContext exc,
+ FT_Long* args )
{
FT_UShort K, L;
FT_F26Dot6 D;
@@ -5357,50 +4867,50 @@
K = (FT_UShort)args[1];
L = (FT_UShort)args[0];
- if ( BOUNDS( L, CUR.zp0.n_points ) ||
- BOUNDS( K, CUR.zp1.n_points ) )
+ if ( BOUNDS( L, exc->zp0.n_points ) ||
+ BOUNDS( K, exc->zp1.n_points ) )
{
- if ( CUR.pedantic_hinting )
- CUR.error = FT_THROW( Invalid_Reference );
+ if ( exc->pedantic_hinting )
+ exc->error = FT_THROW( Invalid_Reference );
D = 0;
}
else
{
- if ( CUR.opcode & 1 )
- D = CUR_Func_project( CUR.zp0.cur + L, CUR.zp1.cur + K );
+ if ( exc->opcode & 1 )
+ D = PROJECT( exc->zp0.cur + L, exc->zp1.cur + K );
else
{
/* XXX: UNDOCUMENTED: twilight zone special case */
- if ( CUR.GS.gep0 == 0 || CUR.GS.gep1 == 0 )
+ if ( exc->GS.gep0 == 0 || exc->GS.gep1 == 0 )
{
- FT_Vector* vec1 = CUR.zp0.org + L;
- FT_Vector* vec2 = CUR.zp1.org + K;
+ FT_Vector* vec1 = exc->zp0.org + L;
+ FT_Vector* vec2 = exc->zp1.org + K;
- D = CUR_Func_dualproj( vec1, vec2 );
+ D = DUALPROJ( vec1, vec2 );
}
else
{
- FT_Vector* vec1 = CUR.zp0.orus + L;
- FT_Vector* vec2 = CUR.zp1.orus + K;
+ FT_Vector* vec1 = exc->zp0.orus + L;
+ FT_Vector* vec2 = exc->zp1.orus + K;
- if ( CUR.metrics.x_scale == CUR.metrics.y_scale )
+ if ( exc->metrics.x_scale == exc->metrics.y_scale )
{
/* this should be faster */
- D = CUR_Func_dualproj( vec1, vec2 );
- D = FT_MulFix( D, CUR.metrics.x_scale );
+ D = DUALPROJ( vec1, vec2 );
+ D = FT_MulFix( D, exc->metrics.x_scale );
}
else
{
FT_Vector vec;
- vec.x = FT_MulFix( vec1->x - vec2->x, CUR.metrics.x_scale );
- vec.y = FT_MulFix( vec1->y - vec2->y, CUR.metrics.y_scale );
+ vec.x = FT_MulFix( vec1->x - vec2->x, exc->metrics.x_scale );
+ vec.y = FT_MulFix( vec1->y - vec2->y, exc->metrics.y_scale );
- D = CUR_fast_dualproj( &vec );
+ D = FAST_DUALPROJ( &vec );
}
}
}
@@ -5408,8 +4918,9 @@
#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
/* Disable Type 2 Vacuform Rounds - e.g. Arial Narrow */
- if ( SUBPIXEL_HINTING &&
- CUR.ignore_x_mode && FT_ABS( D ) == 64 )
+ if ( SUBPIXEL_HINTING &&
+ exc->ignore_x_mode &&
+ FT_ABS( D ) == 64 )
D += 1;
#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */
@@ -5419,61 +4930,63 @@
/*************************************************************************/
/* */
- /* SDPVTL[a]: Set Dual PVector to Line */
+ /* SDPvTL[a]: Set Dual PVector to Line */
/* Opcode range: 0x86-0x87 */
/* Stack: uint32 uint32 --> */
/* */
static void
- Ins_SDPVTL( INS_ARG )
+ Ins_SDPVTL( TT_ExecContext exc,
+ FT_Long* args )
{
FT_Long A, B, C;
FT_UShort p1, p2; /* was FT_Int in pas type ERROR */
- FT_Int aOpc = CUR.opcode;
+
+ FT_Byte opcode = exc->opcode;
p1 = (FT_UShort)args[1];
p2 = (FT_UShort)args[0];
- if ( BOUNDS( p2, CUR.zp1.n_points ) ||
- BOUNDS( p1, CUR.zp2.n_points ) )
+ if ( BOUNDS( p2, exc->zp1.n_points ) ||
+ BOUNDS( p1, exc->zp2.n_points ) )
{
- if ( CUR.pedantic_hinting )
- CUR.error = FT_THROW( Invalid_Reference );
+ if ( exc->pedantic_hinting )
+ exc->error = FT_THROW( Invalid_Reference );
return;
}
{
- FT_Vector* v1 = CUR.zp1.org + p2;
- FT_Vector* v2 = CUR.zp2.org + p1;
+ FT_Vector* v1 = exc->zp1.org + p2;
+ FT_Vector* v2 = exc->zp2.org + p1;
A = v1->x - v2->x;
B = v1->y - v2->y;
- /* If v1 == v2, SDPVTL behaves the same as */
+ /* If v1 == v2, SDPvTL behaves the same as */
/* SVTCA[X], respectively. */
/* */
/* Confirmed by Greg Hitchcock. */
if ( A == 0 && B == 0 )
{
- A = 0x4000;
- aOpc = 0;
+ A = 0x4000;
+ opcode = 0;
}
}
- if ( ( aOpc & 1 ) != 0 )
+ if ( ( opcode & 1 ) != 0 )
{
C = B; /* counter clockwise rotation */
B = A;
A = -C;
}
- NORMalize( A, B, &CUR.GS.dualVector );
+ Normalize( A, B, &exc->GS.dualVector );
{
- FT_Vector* v1 = CUR.zp1.cur + p2;
- FT_Vector* v2 = CUR.zp2.cur + p1;
+ FT_Vector* v1 = exc->zp1.cur + p2;
+ FT_Vector* v2 = exc->zp2.cur + p1;
A = v1->x - v2->x;
@@ -5481,23 +4994,21 @@
if ( A == 0 && B == 0 )
{
- A = 0x4000;
- aOpc = 0;
+ A = 0x4000;
+ opcode = 0;
}
}
- if ( ( aOpc & 1 ) != 0 )
+ if ( ( opcode & 1 ) != 0 )
{
C = B; /* counter clockwise rotation */
B = A;
A = -C;
}
- NORMalize( A, B, &CUR.GS.projVector );
-
+ Normalize( A, B, &exc->GS.projVector );
GUESS_VECTOR( freeVector );
-
- COMPUTE_Funcs();
+ Compute_Funcs( exc );
}
@@ -5508,25 +5019,26 @@
/* Stack: uint32 --> */
/* */
static void
- Ins_SZP0( INS_ARG )
+ Ins_SZP0( TT_ExecContext exc,
+ FT_Long* args )
{
switch ( (FT_Int)args[0] )
{
case 0:
- CUR.zp0 = CUR.twilight;
+ exc->zp0 = exc->twilight;
break;
case 1:
- CUR.zp0 = CUR.pts;
+ exc->zp0 = exc->pts;
break;
default:
- if ( CUR.pedantic_hinting )
- CUR.error = FT_THROW( Invalid_Reference );
+ if ( exc->pedantic_hinting )
+ exc->error = FT_THROW( Invalid_Reference );
return;
}
- CUR.GS.gep0 = (FT_UShort)args[0];
+ exc->GS.gep0 = (FT_UShort)args[0];
}
@@ -5537,25 +5049,26 @@
/* Stack: uint32 --> */
/* */
static void
- Ins_SZP1( INS_ARG )
+ Ins_SZP1( TT_ExecContext exc,
+ FT_Long* args )
{
switch ( (FT_Int)args[0] )
{
case 0:
- CUR.zp1 = CUR.twilight;
+ exc->zp1 = exc->twilight;
break;
case 1:
- CUR.zp1 = CUR.pts;
+ exc->zp1 = exc->pts;
break;
default:
- if ( CUR.pedantic_hinting )
- CUR.error = FT_THROW( Invalid_Reference );
+ if ( exc->pedantic_hinting )
+ exc->error = FT_THROW( Invalid_Reference );
return;
}
- CUR.GS.gep1 = (FT_UShort)args[0];
+ exc->GS.gep1 = (FT_UShort)args[0];
}
@@ -5566,25 +5079,26 @@
/* Stack: uint32 --> */
/* */
static void
- Ins_SZP2( INS_ARG )
+ Ins_SZP2( TT_ExecContext exc,
+ FT_Long* args )
{
switch ( (FT_Int)args[0] )
{
case 0:
- CUR.zp2 = CUR.twilight;
+ exc->zp2 = exc->twilight;
break;
case 1:
- CUR.zp2 = CUR.pts;
+ exc->zp2 = exc->pts;
break;
default:
- if ( CUR.pedantic_hinting )
- CUR.error = FT_THROW( Invalid_Reference );
+ if ( exc->pedantic_hinting )
+ exc->error = FT_THROW( Invalid_Reference );
return;
}
- CUR.GS.gep2 = (FT_UShort)args[0];
+ exc->GS.gep2 = (FT_UShort)args[0];
}
@@ -5595,30 +5109,31 @@
/* Stack: uint32 --> */
/* */
static void
- Ins_SZPS( INS_ARG )
+ Ins_SZPS( TT_ExecContext exc,
+ FT_Long* args )
{
switch ( (FT_Int)args[0] )
{
case 0:
- CUR.zp0 = CUR.twilight;
+ exc->zp0 = exc->twilight;
break;
case 1:
- CUR.zp0 = CUR.pts;
+ exc->zp0 = exc->pts;
break;
default:
- if ( CUR.pedantic_hinting )
- CUR.error = FT_THROW( Invalid_Reference );
+ if ( exc->pedantic_hinting )
+ exc->error = FT_THROW( Invalid_Reference );
return;
}
- CUR.zp1 = CUR.zp0;
- CUR.zp2 = CUR.zp0;
+ exc->zp1 = exc->zp0;
+ exc->zp2 = exc->zp0;
- CUR.GS.gep0 = (FT_UShort)args[0];
- CUR.GS.gep1 = (FT_UShort)args[0];
- CUR.GS.gep2 = (FT_UShort)args[0];
+ exc->GS.gep0 = (FT_UShort)args[0];
+ exc->GS.gep1 = (FT_UShort)args[0];
+ exc->GS.gep2 = (FT_UShort)args[0];
}
@@ -5629,26 +5144,47 @@
/* Stack: int32 int32 --> */
/* */
static void
- Ins_INSTCTRL( INS_ARG )
+ Ins_INSTCTRL( TT_ExecContext exc,
+ FT_Long* args )
{
- FT_Long K, L;
+ FT_ULong K, L, Kf;
- K = args[1];
- L = args[0];
+ K = (FT_ULong)args[1];
+ L = (FT_ULong)args[0];
- if ( K < 1 || K > 2 )
+ /* selector values cannot be `OR'ed; */
+ /* they are indices starting with index 1, not flags */
+ if ( K < 1 || K > 3 )
{
- if ( CUR.pedantic_hinting )
- CUR.error = FT_THROW( Invalid_Reference );
+ if ( exc->pedantic_hinting )
+ exc->error = FT_THROW( Invalid_Reference );
return;
}
+ /* convert index to flag value */
+ Kf = 1 << ( K - 1 );
+
if ( L != 0 )
- L = K;
+ {
+ /* arguments to selectors look like flag values */
+ if ( L != Kf )
+ {
+ if ( exc->pedantic_hinting )
+ exc->error = FT_THROW( Invalid_Reference );
+ return;
+ }
+ }
+
+ exc->GS.instruct_control &= ~(FT_Byte)Kf;
+ exc->GS.instruct_control |= (FT_Byte)L;
- CUR.GS.instruct_control = FT_BOOL(
- ( (FT_Byte)CUR.GS.instruct_control & ~(FT_Byte)K ) | (FT_Byte)L );
+#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
+ /* INSTCTRL modifying flag 3 also has an effect */
+ /* outside of the CVT program */
+ if ( K == 3 )
+ exc->ignore_x_mode = FT_BOOL( L == 4 );
+#endif
}
@@ -5659,7 +5195,8 @@
/* Stack: uint32? --> */
/* */
static void
- Ins_SCANCTRL( INS_ARG )
+ Ins_SCANCTRL( TT_ExecContext exc,
+ FT_Long* args )
{
FT_Int A;
@@ -5669,32 +5206,32 @@
if ( A == 0xFF )
{
- CUR.GS.scan_control = TRUE;
+ exc->GS.scan_control = TRUE;
return;
}
else if ( A == 0 )
{
- CUR.GS.scan_control = FALSE;
+ exc->GS.scan_control = FALSE;
return;
}
- if ( ( args[0] & 0x100 ) != 0 && CUR.tt_metrics.ppem <= A )
- CUR.GS.scan_control = TRUE;
+ if ( ( args[0] & 0x100 ) != 0 && exc->tt_metrics.ppem <= A )
+ exc->GS.scan_control = TRUE;
- if ( ( args[0] & 0x200 ) != 0 && CUR.tt_metrics.rotated )
- CUR.GS.scan_control = TRUE;
+ if ( ( args[0] & 0x200 ) != 0 && exc->tt_metrics.rotated )
+ exc->GS.scan_control = TRUE;
- if ( ( args[0] & 0x400 ) != 0 && CUR.tt_metrics.stretched )
- CUR.GS.scan_control = TRUE;
+ if ( ( args[0] & 0x400 ) != 0 && exc->tt_metrics.stretched )
+ exc->GS.scan_control = TRUE;
- if ( ( args[0] & 0x800 ) != 0 && CUR.tt_metrics.ppem > A )
- CUR.GS.scan_control = FALSE;
+ if ( ( args[0] & 0x800 ) != 0 && exc->tt_metrics.ppem > A )
+ exc->GS.scan_control = FALSE;
- if ( ( args[0] & 0x1000 ) != 0 && CUR.tt_metrics.rotated )
- CUR.GS.scan_control = FALSE;
+ if ( ( args[0] & 0x1000 ) != 0 && exc->tt_metrics.rotated )
+ exc->GS.scan_control = FALSE;
- if ( ( args[0] & 0x2000 ) != 0 && CUR.tt_metrics.stretched )
- CUR.GS.scan_control = FALSE;
+ if ( ( args[0] & 0x2000 ) != 0 && exc->tt_metrics.stretched )
+ exc->GS.scan_control = FALSE;
}
@@ -5705,10 +5242,11 @@
/* Stack: uint32? --> */
/* */
static void
- Ins_SCANTYPE( INS_ARG )
+ Ins_SCANTYPE( TT_ExecContext exc,
+ FT_Long* args )
{
if ( args[0] >= 0 )
- CUR.GS.scan_type = (FT_Int)args[0];
+ exc->GS.scan_type = (FT_Int)args[0];
}
@@ -5716,8 +5254,6 @@
/* */
/* MANAGING OUTLINES */
/* */
- /* Instructions appear in the specification's order. */
- /* */
/*************************************************************************/
@@ -5728,43 +5264,41 @@
/* Stack: uint32... --> */
/* */
static void
- Ins_FLIPPT( INS_ARG )
+ Ins_FLIPPT( TT_ExecContext exc )
{
FT_UShort point;
- FT_UNUSED_ARG;
-
- if ( CUR.top < CUR.GS.loop )
+ if ( exc->top < exc->GS.loop )
{
- if ( CUR.pedantic_hinting )
- CUR.error = FT_THROW( Too_Few_Arguments );
+ if ( exc->pedantic_hinting )
+ exc->error = FT_THROW( Too_Few_Arguments );
goto Fail;
}
- while ( CUR.GS.loop > 0 )
+ while ( exc->GS.loop > 0 )
{
- CUR.args--;
+ exc->args--;
- point = (FT_UShort)CUR.stack[CUR.args];
+ point = (FT_UShort)exc->stack[exc->args];
- if ( BOUNDS( point, CUR.pts.n_points ) )
+ if ( BOUNDS( point, exc->pts.n_points ) )
{
- if ( CUR.pedantic_hinting )
+ if ( exc->pedantic_hinting )
{
- CUR.error = FT_THROW( Invalid_Reference );
+ exc->error = FT_THROW( Invalid_Reference );
return;
}
}
else
- CUR.pts.tags[point] ^= FT_CURVE_TAG_ON;
+ exc->pts.tags[point] ^= FT_CURVE_TAG_ON;
- CUR.GS.loop--;
+ exc->GS.loop--;
}
Fail:
- CUR.GS.loop = 1;
- CUR.new_top = CUR.args;
+ exc->GS.loop = 1;
+ exc->new_top = exc->args;
}
@@ -5775,7 +5309,8 @@
/* Stack: uint32 uint32 --> */
/* */
static void
- Ins_FLIPRGON( INS_ARG )
+ Ins_FLIPRGON( TT_ExecContext exc,
+ FT_Long* args )
{
FT_UShort I, K, L;
@@ -5783,16 +5318,16 @@
K = (FT_UShort)args[1];
L = (FT_UShort)args[0];
- if ( BOUNDS( K, CUR.pts.n_points ) ||
- BOUNDS( L, CUR.pts.n_points ) )
+ if ( BOUNDS( K, exc->pts.n_points ) ||
+ BOUNDS( L, exc->pts.n_points ) )
{
- if ( CUR.pedantic_hinting )
- CUR.error = FT_THROW( Invalid_Reference );
+ if ( exc->pedantic_hinting )
+ exc->error = FT_THROW( Invalid_Reference );
return;
}
for ( I = L; I <= K; I++ )
- CUR.pts.tags[I] |= FT_CURVE_TAG_ON;
+ exc->pts.tags[I] |= FT_CURVE_TAG_ON;
}
@@ -5803,7 +5338,8 @@
/* Stack: uint32 uint32 --> */
/* */
static void
- Ins_FLIPRGOFF( INS_ARG )
+ Ins_FLIPRGOFF( TT_ExecContext exc,
+ FT_Long* args )
{
FT_UShort I, K, L;
@@ -5811,45 +5347,46 @@
K = (FT_UShort)args[1];
L = (FT_UShort)args[0];
- if ( BOUNDS( K, CUR.pts.n_points ) ||
- BOUNDS( L, CUR.pts.n_points ) )
+ if ( BOUNDS( K, exc->pts.n_points ) ||
+ BOUNDS( L, exc->pts.n_points ) )
{
- if ( CUR.pedantic_hinting )
- CUR.error = FT_THROW( Invalid_Reference );
+ if ( exc->pedantic_hinting )
+ exc->error = FT_THROW( Invalid_Reference );
return;
}
for ( I = L; I <= K; I++ )
- CUR.pts.tags[I] &= ~FT_CURVE_TAG_ON;
+ exc->pts.tags[I] &= ~FT_CURVE_TAG_ON;
}
static FT_Bool
- Compute_Point_Displacement( EXEC_OP_ FT_F26Dot6* x,
- FT_F26Dot6* y,
- TT_GlyphZone zone,
- FT_UShort* refp )
+ Compute_Point_Displacement( TT_ExecContext exc,
+ FT_F26Dot6* x,
+ FT_F26Dot6* y,
+ TT_GlyphZone zone,
+ FT_UShort* refp )
{
TT_GlyphZoneRec zp;
FT_UShort p;
FT_F26Dot6 d;
- if ( CUR.opcode & 1 )
+ if ( exc->opcode & 1 )
{
- zp = CUR.zp0;
- p = CUR.GS.rp1;
+ zp = exc->zp0;
+ p = exc->GS.rp1;
}
else
{
- zp = CUR.zp1;
- p = CUR.GS.rp2;
+ zp = exc->zp1;
+ p = exc->GS.rp2;
}
if ( BOUNDS( p, zp.n_points ) )
{
- if ( CUR.pedantic_hinting )
- CUR.error = FT_THROW( Invalid_Reference );
+ if ( exc->pedantic_hinting )
+ exc->error = FT_THROW( Invalid_Reference );
*refp = 0;
return FAILURE;
}
@@ -5857,12 +5394,12 @@
*zone = zp;
*refp = p;
- d = CUR_Func_project( zp.cur + p, zp.org + p );
+ d = PROJECT( zp.cur + p, zp.org + p );
#ifdef TT_CONFIG_OPTION_UNPATENTED_HINTING
- if ( CUR.face->unpatented_hinting )
+ if ( exc->face->unpatented_hinting )
{
- if ( CUR.GS.both_x_axis )
+ if ( exc->GS.both_x_axis )
{
*x = d;
*y = 0;
@@ -5876,8 +5413,8 @@
else
#endif
{
- *x = FT_MulDiv( d, (FT_Long)CUR.GS.freeVector.x, CUR.F_dot_P );
- *y = FT_MulDiv( d, (FT_Long)CUR.GS.freeVector.y, CUR.F_dot_P );
+ *x = FT_MulDiv( d, (FT_Long)exc->GS.freeVector.x, exc->F_dot_P );
+ *y = FT_MulDiv( d, (FT_Long)exc->GS.freeVector.y, exc->F_dot_P );
}
return SUCCESS;
@@ -5885,42 +5422,43 @@
static void
- Move_Zp2_Point( EXEC_OP_ FT_UShort point,
- FT_F26Dot6 dx,
- FT_F26Dot6 dy,
- FT_Bool touch )
+ Move_Zp2_Point( TT_ExecContext exc,
+ FT_UShort point,
+ FT_F26Dot6 dx,
+ FT_F26Dot6 dy,
+ FT_Bool touch )
{
#ifdef TT_CONFIG_OPTION_UNPATENTED_HINTING
- if ( CUR.face->unpatented_hinting )
+ if ( exc->face->unpatented_hinting )
{
- if ( CUR.GS.both_x_axis )
+ if ( exc->GS.both_x_axis )
{
- CUR.zp2.cur[point].x += dx;
+ exc->zp2.cur[point].x += dx;
if ( touch )
- CUR.zp2.tags[point] |= FT_CURVE_TAG_TOUCH_X;
+ exc->zp2.tags[point] |= FT_CURVE_TAG_TOUCH_X;
}
else
{
- CUR.zp2.cur[point].y += dy;
+ exc->zp2.cur[point].y += dy;
if ( touch )
- CUR.zp2.tags[point] |= FT_CURVE_TAG_TOUCH_Y;
+ exc->zp2.tags[point] |= FT_CURVE_TAG_TOUCH_Y;
}
return;
}
#endif
- if ( CUR.GS.freeVector.x != 0 )
+ if ( exc->GS.freeVector.x != 0 )
{
- CUR.zp2.cur[point].x += dx;
+ exc->zp2.cur[point].x += dx;
if ( touch )
- CUR.zp2.tags[point] |= FT_CURVE_TAG_TOUCH_X;
+ exc->zp2.tags[point] |= FT_CURVE_TAG_TOUCH_X;
}
- if ( CUR.GS.freeVector.y != 0 )
+ if ( exc->GS.freeVector.y != 0 )
{
- CUR.zp2.cur[point].y += dy;
+ exc->zp2.cur[point].y += dy;
if ( touch )
- CUR.zp2.tags[point] |= FT_CURVE_TAG_TOUCH_Y;
+ exc->zp2.tags[point] |= FT_CURVE_TAG_TOUCH_Y;
}
}
@@ -5932,57 +5470,54 @@
/* Stack: uint32... --> */
/* */
static void
- Ins_SHP( INS_ARG )
+ Ins_SHP( TT_ExecContext exc )
{
TT_GlyphZoneRec zp;
FT_UShort refp;
- FT_F26Dot6 dx,
- dy;
+ FT_F26Dot6 dx, dy;
FT_UShort point;
- FT_UNUSED_ARG;
-
- if ( CUR.top < CUR.GS.loop )
+ if ( exc->top < exc->GS.loop )
{
- if ( CUR.pedantic_hinting )
- CUR.error = FT_THROW( Invalid_Reference );
+ if ( exc->pedantic_hinting )
+ exc->error = FT_THROW( Invalid_Reference );
goto Fail;
}
- if ( COMPUTE_Point_Displacement( &dx, &dy, &zp, &refp ) )
+ if ( Compute_Point_Displacement( exc, &dx, &dy, &zp, &refp ) )
return;
- while ( CUR.GS.loop > 0 )
+ while ( exc->GS.loop > 0 )
{
- CUR.args--;
- point = (FT_UShort)CUR.stack[CUR.args];
+ exc->args--;
+ point = (FT_UShort)exc->stack[exc->args];
- if ( BOUNDS( point, CUR.zp2.n_points ) )
+ if ( BOUNDS( point, exc->zp2.n_points ) )
{
- if ( CUR.pedantic_hinting )
+ if ( exc->pedantic_hinting )
{
- CUR.error = FT_THROW( Invalid_Reference );
+ exc->error = FT_THROW( Invalid_Reference );
return;
}
}
else
#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
/* doesn't follow Cleartype spec but produces better result */
- if ( SUBPIXEL_HINTING &&
- CUR.ignore_x_mode )
- MOVE_Zp2_Point( point, 0, dy, TRUE );
+ if ( SUBPIXEL_HINTING &&
+ exc->ignore_x_mode )
+ Move_Zp2_Point( exc, point, 0, dy, TRUE );
else
#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */
- MOVE_Zp2_Point( point, dx, dy, TRUE );
+ Move_Zp2_Point( exc, point, dx, dy, TRUE );
- CUR.GS.loop--;
+ exc->GS.loop--;
}
Fail:
- CUR.GS.loop = 1;
- CUR.new_top = CUR.args;
+ exc->GS.loop = 1;
+ exc->new_top = exc->args;
}
@@ -5997,7 +5532,8 @@
/* zero which includes all points of it. */
/* */
static void
- Ins_SHC( INS_ARG )
+ Ins_SHC( TT_ExecContext exc,
+ FT_Long* args )
{
TT_GlyphZoneRec zp;
FT_UShort refp;
@@ -6007,36 +5543,36 @@
FT_UShort start, limit, i;
- contour = (FT_UShort)args[0];
- bounds = ( CUR.GS.gep2 == 0 ) ? 1 : CUR.zp2.n_contours;
+ contour = (FT_Short)args[0];
+ bounds = ( exc->GS.gep2 == 0 ) ? 1 : exc->zp2.n_contours;
if ( BOUNDS( contour, bounds ) )
{
- if ( CUR.pedantic_hinting )
- CUR.error = FT_THROW( Invalid_Reference );
+ if ( exc->pedantic_hinting )
+ exc->error = FT_THROW( Invalid_Reference );
return;
}
- if ( COMPUTE_Point_Displacement( &dx, &dy, &zp, &refp ) )
+ if ( Compute_Point_Displacement( exc, &dx, &dy, &zp, &refp ) )
return;
if ( contour == 0 )
start = 0;
else
- start = (FT_UShort)( CUR.zp2.contours[contour - 1] + 1 -
- CUR.zp2.first_point );
+ start = (FT_UShort)( exc->zp2.contours[contour - 1] + 1 -
+ exc->zp2.first_point );
/* we use the number of points if in the twilight zone */
- if ( CUR.GS.gep2 == 0 )
- limit = CUR.zp2.n_points;
+ if ( exc->GS.gep2 == 0 )
+ limit = exc->zp2.n_points;
else
- limit = (FT_UShort)( CUR.zp2.contours[contour] -
- CUR.zp2.first_point + 1 );
+ limit = (FT_UShort)( exc->zp2.contours[contour] -
+ exc->zp2.first_point + 1 );
for ( i = start; i < limit; i++ )
{
- if ( zp.cur != CUR.zp2.cur || refp != i )
- MOVE_Zp2_Point( i, dx, dy, TRUE );
+ if ( zp.cur != exc->zp2.cur || refp != i )
+ Move_Zp2_Point( exc, i, dx, dy, TRUE );
}
}
@@ -6048,7 +5584,8 @@
/* Stack: uint32 --> */
/* */
static void
- Ins_SHZ( INS_ARG )
+ Ins_SHZ( TT_ExecContext exc,
+ FT_Long* args )
{
TT_GlyphZoneRec zp;
FT_UShort refp;
@@ -6060,30 +5597,30 @@
if ( BOUNDS( args[0], 2 ) )
{
- if ( CUR.pedantic_hinting )
- CUR.error = FT_THROW( Invalid_Reference );
+ if ( exc->pedantic_hinting )
+ exc->error = FT_THROW( Invalid_Reference );
return;
}
- if ( COMPUTE_Point_Displacement( &dx, &dy, &zp, &refp ) )
+ if ( Compute_Point_Displacement( exc, &dx, &dy, &zp, &refp ) )
return;
/* XXX: UNDOCUMENTED! SHZ doesn't move the phantom points. */
/* Twilight zone has no real contours, so use `n_points'. */
/* Normal zone's `n_points' includes phantoms, so must */
/* use end of last contour. */
- if ( CUR.GS.gep2 == 0 )
- limit = (FT_UShort)CUR.zp2.n_points;
- else if ( CUR.GS.gep2 == 1 && CUR.zp2.n_contours > 0 )
- limit = (FT_UShort)( CUR.zp2.contours[CUR.zp2.n_contours - 1] + 1 );
+ if ( exc->GS.gep2 == 0 )
+ limit = (FT_UShort)exc->zp2.n_points;
+ else if ( exc->GS.gep2 == 1 && exc->zp2.n_contours > 0 )
+ limit = (FT_UShort)( exc->zp2.contours[exc->zp2.n_contours - 1] + 1 );
else
limit = 0;
/* XXX: UNDOCUMENTED! SHZ doesn't touch the points */
for ( i = 0; i < limit; i++ )
{
- if ( zp.cur != CUR.zp2.cur || refp != i )
- MOVE_Zp2_Point( i, dx, dy, FALSE );
+ if ( zp.cur != exc->zp2.cur || refp != i )
+ Move_Zp2_Point( exc, i, dx, dy, FALSE );
}
}
@@ -6095,7 +5632,8 @@
/* Stack: f26.6 uint32... --> */
/* */
static void
- Ins_SHPIX( INS_ARG )
+ Ins_SHPIX( TT_ExecContext exc,
+ FT_Long* args )
{
FT_F26Dot6 dx, dy;
FT_UShort point;
@@ -6104,17 +5642,17 @@
#endif
- if ( CUR.top < CUR.GS.loop + 1 )
+ if ( exc->top < exc->GS.loop + 1 )
{
- if ( CUR.pedantic_hinting )
- CUR.error = FT_THROW( Invalid_Reference );
+ if ( exc->pedantic_hinting )
+ exc->error = FT_THROW( Invalid_Reference );
goto Fail;
}
#ifdef TT_CONFIG_OPTION_UNPATENTED_HINTING
- if ( CUR.face->unpatented_hinting )
+ if ( exc->face->unpatented_hinting )
{
- if ( CUR.GS.both_x_axis )
+ if ( exc->GS.both_x_axis )
{
dx = (FT_UInt32)args[0];
dy = 0;
@@ -6128,115 +5666,115 @@
else
#endif
{
- dx = TT_MulFix14( (FT_UInt32)args[0], CUR.GS.freeVector.x );
- dy = TT_MulFix14( (FT_UInt32)args[0], CUR.GS.freeVector.y );
+ dx = TT_MulFix14( args[0], exc->GS.freeVector.x );
+ dy = TT_MulFix14( args[0], exc->GS.freeVector.y );
}
- while ( CUR.GS.loop > 0 )
+ while ( exc->GS.loop > 0 )
{
- CUR.args--;
+ exc->args--;
- point = (FT_UShort)CUR.stack[CUR.args];
+ point = (FT_UShort)exc->stack[exc->args];
- if ( BOUNDS( point, CUR.zp2.n_points ) )
+ if ( BOUNDS( point, exc->zp2.n_points ) )
{
- if ( CUR.pedantic_hinting )
+ if ( exc->pedantic_hinting )
{
- CUR.error = FT_THROW( Invalid_Reference );
+ exc->error = FT_THROW( Invalid_Reference );
return;
}
}
else
#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
{
- /* If not using ignore_x_mode rendering, allow ZP2 move. */
- /* If inline deltas aren't allowed, skip ZP2 move. */
- /* If using ignore_x_mode rendering, allow ZP2 point move if: */
- /* - freedom vector is y and sph_compatibility_mode is off */
- /* - the glyph is composite and the move is in the Y direction */
- /* - the glyph is specifically set to allow SHPIX moves */
- /* - the move is on a previously Y-touched point */
-
- if ( SUBPIXEL_HINTING &&
- CUR.ignore_x_mode )
+ /* If not using ignore_x_mode rendering, allow ZP2 move. */
+ /* If inline deltas aren't allowed, skip ZP2 move. */
+ /* If using ignore_x_mode rendering, allow ZP2 point move if: */
+ /* - freedom vector is y and sph_compatibility_mode is off */
+ /* - the glyph is composite and the move is in the Y direction */
+ /* - the glyph is specifically set to allow SHPIX moves */
+ /* - the move is on a previously Y-touched point */
+
+ if ( SUBPIXEL_HINTING &&
+ exc->ignore_x_mode )
{
/* save point for later comparison */
- if ( CUR.GS.freeVector.y != 0 )
- B1 = CUR.zp2.cur[point].y;
+ if ( exc->GS.freeVector.y != 0 )
+ B1 = exc->zp2.cur[point].y;
else
- B1 = CUR.zp2.cur[point].x;
+ B1 = exc->zp2.cur[point].x;
- if ( !CUR.face->sph_compatibility_mode &&
- CUR.GS.freeVector.y != 0 )
+ if ( !exc->face->sph_compatibility_mode &&
+ exc->GS.freeVector.y != 0 )
{
- MOVE_Zp2_Point( point, dx, dy, TRUE );
+ Move_Zp2_Point( exc, point, dx, dy, TRUE );
/* save new point */
- if ( CUR.GS.freeVector.y != 0 )
+ if ( exc->GS.freeVector.y != 0 )
{
- B2 = CUR.zp2.cur[point].y;
+ B2 = exc->zp2.cur[point].y;
/* reverse any disallowed moves */
- if ( ( CUR.sph_tweak_flags & SPH_TWEAK_SKIP_NONPIXEL_Y_MOVES ) &&
- ( B1 & 63 ) != 0 &&
- ( B2 & 63 ) != 0 &&
- B1 != B2 )
- MOVE_Zp2_Point( point, -dx, -dy, TRUE );
+ if ( ( exc->sph_tweak_flags & SPH_TWEAK_SKIP_NONPIXEL_Y_MOVES ) &&
+ ( B1 & 63 ) != 0 &&
+ ( B2 & 63 ) != 0 &&
+ B1 != B2 )
+ Move_Zp2_Point( exc, point, -dx, -dy, TRUE );
}
}
- else if ( CUR.face->sph_compatibility_mode )
+ else if ( exc->face->sph_compatibility_mode )
{
- if ( CUR.sph_tweak_flags & SPH_TWEAK_ROUND_NONPIXEL_Y_MOVES )
+ if ( exc->sph_tweak_flags & SPH_TWEAK_ROUND_NONPIXEL_Y_MOVES )
{
dx = FT_PIX_ROUND( B1 + dx ) - B1;
dy = FT_PIX_ROUND( B1 + dy ) - B1;
}
/* skip post-iup deltas */
- if ( CUR.iup_called &&
- ( ( CUR.sph_in_func_flags & SPH_FDEF_INLINE_DELTA_1 ) ||
- ( CUR.sph_in_func_flags & SPH_FDEF_INLINE_DELTA_2 ) ) )
+ if ( exc->iup_called &&
+ ( ( exc->sph_in_func_flags & SPH_FDEF_INLINE_DELTA_1 ) ||
+ ( exc->sph_in_func_flags & SPH_FDEF_INLINE_DELTA_2 ) ) )
goto Skip;
- if ( !( CUR.sph_tweak_flags & SPH_TWEAK_ALWAYS_SKIP_DELTAP ) &&
- ( ( CUR.is_composite && CUR.GS.freeVector.y != 0 ) ||
- ( CUR.zp2.tags[point] & FT_CURVE_TAG_TOUCH_Y ) ||
- ( CUR.sph_tweak_flags & SPH_TWEAK_DO_SHPIX ) ) )
- MOVE_Zp2_Point( point, 0, dy, TRUE );
+ if ( !( exc->sph_tweak_flags & SPH_TWEAK_ALWAYS_SKIP_DELTAP ) &&
+ ( ( exc->is_composite && exc->GS.freeVector.y != 0 ) ||
+ ( exc->zp2.tags[point] & FT_CURVE_TAG_TOUCH_Y ) ||
+ ( exc->sph_tweak_flags & SPH_TWEAK_DO_SHPIX ) ) )
+ Move_Zp2_Point( exc, point, 0, dy, TRUE );
/* save new point */
- if ( CUR.GS.freeVector.y != 0 )
+ if ( exc->GS.freeVector.y != 0 )
{
- B2 = CUR.zp2.cur[point].y;
+ B2 = exc->zp2.cur[point].y;
/* reverse any disallowed moves */
if ( ( B1 & 63 ) == 0 &&
( B2 & 63 ) != 0 &&
B1 != B2 )
- MOVE_Zp2_Point( point, 0, -dy, TRUE );
+ Move_Zp2_Point( exc, point, 0, -dy, TRUE );
}
}
- else if ( CUR.sph_in_func_flags & SPH_FDEF_TYPEMAN_DIAGENDCTRL )
- MOVE_Zp2_Point( point, dx, dy, TRUE );
+ else if ( exc->sph_in_func_flags & SPH_FDEF_TYPEMAN_DIAGENDCTRL )
+ Move_Zp2_Point( exc, point, dx, dy, TRUE );
}
else
- MOVE_Zp2_Point( point, dx, dy, TRUE );
+ Move_Zp2_Point( exc, point, dx, dy, TRUE );
}
Skip:
#else /* !TT_CONFIG_OPTION_SUBPIXEL_HINTING */
- MOVE_Zp2_Point( point, dx, dy, TRUE );
+ Move_Zp2_Point( exc, point, dx, dy, TRUE );
#endif /* !TT_CONFIG_OPTION_SUBPIXEL_HINTING */
- CUR.GS.loop--;
+ exc->GS.loop--;
}
Fail:
- CUR.GS.loop = 1;
- CUR.new_top = CUR.args;
+ exc->GS.loop = 1;
+ exc->new_top = exc->args;
}
@@ -6247,7 +5785,8 @@
/* Stack: f26.6 uint32 --> */
/* */
static void
- Ins_MSIRP( INS_ARG )
+ Ins_MSIRP( TT_ExecContext exc,
+ FT_Long* args )
{
FT_UShort point;
FT_F26Dot6 distance;
@@ -6258,11 +5797,11 @@
if ( SUBPIXEL_HINTING )
{
- control_value_cutin = CUR.GS.control_value_cutin;
+ control_value_cutin = exc->GS.control_value_cutin;
- if ( CUR.ignore_x_mode &&
- CUR.GS.freeVector.x != 0 &&
- !( CUR.sph_tweak_flags & SPH_TWEAK_NORMAL_ROUND ) )
+ if ( exc->ignore_x_mode &&
+ exc->GS.freeVector.x != 0 &&
+ !( exc->sph_tweak_flags & SPH_TWEAK_NORMAL_ROUND ) )
control_value_cutin = 0;
}
@@ -6270,42 +5809,41 @@
point = (FT_UShort)args[0];
- if ( BOUNDS( point, CUR.zp1.n_points ) ||
- BOUNDS( CUR.GS.rp0, CUR.zp0.n_points ) )
+ if ( BOUNDS( point, exc->zp1.n_points ) ||
+ BOUNDS( exc->GS.rp0, exc->zp0.n_points ) )
{
- if ( CUR.pedantic_hinting )
- CUR.error = FT_THROW( Invalid_Reference );
+ if ( exc->pedantic_hinting )
+ exc->error = FT_THROW( Invalid_Reference );
return;
}
/* UNDOCUMENTED! The MS rasterizer does that with */
/* twilight points (confirmed by Greg Hitchcock) */
- if ( CUR.GS.gep1 == 0 )
+ if ( exc->GS.gep1 == 0 )
{
- CUR.zp1.org[point] = CUR.zp0.org[CUR.GS.rp0];
- CUR_Func_move_orig( &CUR.zp1, point, args[1] );
- CUR.zp1.cur[point] = CUR.zp1.org[point];
+ exc->zp1.org[point] = exc->zp0.org[exc->GS.rp0];
+ exc->func_move_orig( exc, &exc->zp1, point, args[1] );
+ exc->zp1.cur[point] = exc->zp1.org[point];
}
- distance = CUR_Func_project( CUR.zp1.cur + point,
- CUR.zp0.cur + CUR.GS.rp0 );
+ distance = PROJECT( exc->zp1.cur + point, exc->zp0.cur + exc->GS.rp0 );
#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
/* subpixel hinting - make MSIRP respect CVT cut-in; */
if ( SUBPIXEL_HINTING &&
- CUR.ignore_x_mode &&
- CUR.GS.freeVector.x != 0 &&
+ exc->ignore_x_mode &&
+ exc->GS.freeVector.x != 0 &&
FT_ABS( distance - args[1] ) >= control_value_cutin )
distance = args[1];
#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */
- CUR_Func_move( &CUR.zp1, point, args[1] - distance );
+ exc->func_move( exc, &exc->zp1, point, args[1] - distance );
- CUR.GS.rp1 = CUR.GS.rp0;
- CUR.GS.rp2 = point;
+ exc->GS.rp1 = exc->GS.rp0;
+ exc->GS.rp2 = point;
- if ( ( CUR.opcode & 1 ) != 0 )
- CUR.GS.rp0 = point;
+ if ( ( exc->opcode & 1 ) != 0 )
+ exc->GS.rp0 = point;
}
@@ -6316,7 +5854,8 @@
/* Stack: uint32 --> */
/* */
static void
- Ins_MDAP( INS_ARG )
+ Ins_MDAP( TT_ExecContext exc,
+ FT_Long* args )
{
FT_UShort point;
FT_F26Dot6 cur_dist;
@@ -6325,36 +5864,38 @@
point = (FT_UShort)args[0];
- if ( BOUNDS( point, CUR.zp0.n_points ) )
+ if ( BOUNDS( point, exc->zp0.n_points ) )
{
- if ( CUR.pedantic_hinting )
- CUR.error = FT_THROW( Invalid_Reference );
+ if ( exc->pedantic_hinting )
+ exc->error = FT_THROW( Invalid_Reference );
return;
}
- if ( ( CUR.opcode & 1 ) != 0 )
+ if ( ( exc->opcode & 1 ) != 0 )
{
- cur_dist = CUR_fast_project( &CUR.zp0.cur[point] );
+ cur_dist = FAST_PROJECT( &exc->zp0.cur[point] );
#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
- if ( SUBPIXEL_HINTING &&
- CUR.ignore_x_mode &&
- CUR.GS.freeVector.x != 0 )
- distance = ROUND_None(
+ if ( SUBPIXEL_HINTING &&
+ exc->ignore_x_mode &&
+ exc->GS.freeVector.x != 0 )
+ distance = Round_None(
+ exc,
cur_dist,
- CUR.tt_metrics.compensations[0] ) - cur_dist;
+ exc->tt_metrics.compensations[0] ) - cur_dist;
else
#endif
- distance = CUR_Func_round(
+ distance = exc->func_round(
+ exc,
cur_dist,
- CUR.tt_metrics.compensations[0] ) - cur_dist;
+ exc->tt_metrics.compensations[0] ) - cur_dist;
}
else
distance = 0;
- CUR_Func_move( &CUR.zp0, point, distance );
+ exc->func_move( exc, &exc->zp0, point, distance );
- CUR.GS.rp0 = point;
- CUR.GS.rp1 = point;
+ exc->GS.rp0 = point;
+ exc->GS.rp1 = point;
}
@@ -6365,7 +5906,8 @@
/* Stack: uint32 uint32 --> */
/* */
static void
- Ins_MIAP( INS_ARG )
+ Ins_MIAP( TT_ExecContext exc,
+ FT_Long* args )
{
FT_ULong cvtEntry;
FT_UShort point;
@@ -6374,24 +5916,24 @@
FT_F26Dot6 control_value_cutin;
- control_value_cutin = CUR.GS.control_value_cutin;
+ control_value_cutin = exc->GS.control_value_cutin;
cvtEntry = (FT_ULong)args[1];
point = (FT_UShort)args[0];
#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
- if ( SUBPIXEL_HINTING &&
- CUR.ignore_x_mode &&
- CUR.GS.freeVector.x != 0 &&
- CUR.GS.freeVector.y == 0 &&
- !( CUR.sph_tweak_flags & SPH_TWEAK_NORMAL_ROUND ) )
+ if ( SUBPIXEL_HINTING &&
+ exc->ignore_x_mode &&
+ exc->GS.freeVector.x != 0 &&
+ exc->GS.freeVector.y == 0 &&
+ !( exc->sph_tweak_flags & SPH_TWEAK_NORMAL_ROUND ) )
control_value_cutin = 0;
#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */
- if ( BOUNDS( point, CUR.zp0.n_points ) ||
- BOUNDSL( cvtEntry, CUR.cvtSize ) )
+ if ( BOUNDS( point, exc->zp0.n_points ) ||
+ BOUNDSL( cvtEntry, exc->cvtSize ) )
{
- if ( CUR.pedantic_hinting )
- CUR.error = FT_THROW( Invalid_Reference );
+ if ( exc->pedantic_hinting )
+ exc->error = FT_THROW( Invalid_Reference );
goto Fail;
}
@@ -6415,56 +5957,58 @@
/* */
/* Confirmed by Greg Hitchcock. */
- distance = CUR_Func_read_cvt( cvtEntry );
+ distance = exc->func_read_cvt( exc, cvtEntry );
- if ( CUR.GS.gep0 == 0 ) /* If in twilight zone */
+ if ( exc->GS.gep0 == 0 ) /* If in twilight zone */
{
#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
/* Only adjust if not in sph_compatibility_mode or ignore_x_mode. */
/* Determined via experimentation and may be incorrect... */
- if ( !SUBPIXEL_HINTING ||
- ( !CUR.ignore_x_mode ||
- !CUR.face->sph_compatibility_mode ) )
+ if ( !SUBPIXEL_HINTING ||
+ ( !exc->ignore_x_mode ||
+ !exc->face->sph_compatibility_mode ) )
#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */
- CUR.zp0.org[point].x = TT_MulFix14( (FT_UInt32)distance,
- CUR.GS.freeVector.x );
- CUR.zp0.org[point].y = TT_MulFix14( (FT_UInt32)distance,
- CUR.GS.freeVector.y ),
- CUR.zp0.cur[point] = CUR.zp0.org[point];
+ exc->zp0.org[point].x = TT_MulFix14( distance,
+ exc->GS.freeVector.x );
+ exc->zp0.org[point].y = TT_MulFix14( distance,
+ exc->GS.freeVector.y ),
+ exc->zp0.cur[point] = exc->zp0.org[point];
}
#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
- if ( SUBPIXEL_HINTING &&
- CUR.ignore_x_mode &&
- ( CUR.sph_tweak_flags & SPH_TWEAK_MIAP_HACK ) &&
- distance > 0 &&
- CUR.GS.freeVector.y != 0 )
+ if ( SUBPIXEL_HINTING &&
+ exc->ignore_x_mode &&
+ ( exc->sph_tweak_flags & SPH_TWEAK_MIAP_HACK ) &&
+ distance > 0 &&
+ exc->GS.freeVector.y != 0 )
distance = 0;
#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */
- org_dist = CUR_fast_project( &CUR.zp0.cur[point] );
+ org_dist = FAST_PROJECT( &exc->zp0.cur[point] );
- if ( ( CUR.opcode & 1 ) != 0 ) /* rounding and control cut-in flag */
+ if ( ( exc->opcode & 1 ) != 0 ) /* rounding and control cut-in flag */
{
if ( FT_ABS( distance - org_dist ) > control_value_cutin )
distance = org_dist;
#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
- if ( SUBPIXEL_HINTING &&
- CUR.ignore_x_mode &&
- CUR.GS.freeVector.x != 0 )
- distance = ROUND_None( distance,
- CUR.tt_metrics.compensations[0] );
+ if ( SUBPIXEL_HINTING &&
+ exc->ignore_x_mode &&
+ exc->GS.freeVector.x != 0 )
+ distance = Round_None( exc,
+ distance,
+ exc->tt_metrics.compensations[0] );
else
#endif
- distance = CUR_Func_round( distance,
- CUR.tt_metrics.compensations[0] );
+ distance = exc->func_round( exc,
+ distance,
+ exc->tt_metrics.compensations[0] );
}
- CUR_Func_move( &CUR.zp0, point, distance - org_dist );
+ exc->func_move( exc, &exc->zp0, point, distance - org_dist );
Fail:
- CUR.GS.rp0 = point;
- CUR.GS.rp1 = point;
+ exc->GS.rp0 = point;
+ exc->GS.rp1 = point;
}
@@ -6475,29 +6019,30 @@
/* Stack: uint32 --> */
/* */
static void
- Ins_MDRP( INS_ARG )
+ Ins_MDRP( TT_ExecContext exc,
+ FT_Long* args )
{
FT_UShort point;
FT_F26Dot6 org_dist, distance, minimum_distance;
- minimum_distance = CUR.GS.minimum_distance;
+ minimum_distance = exc->GS.minimum_distance;
#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
- if ( SUBPIXEL_HINTING &&
- CUR.ignore_x_mode &&
- CUR.GS.freeVector.x != 0 &&
- !( CUR.sph_tweak_flags & SPH_TWEAK_NORMAL_ROUND ) )
+ if ( SUBPIXEL_HINTING &&
+ exc->ignore_x_mode &&
+ exc->GS.freeVector.x != 0 &&
+ !( exc->sph_tweak_flags & SPH_TWEAK_NORMAL_ROUND ) )
minimum_distance = 0;
#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */
point = (FT_UShort)args[0];
- if ( BOUNDS( point, CUR.zp1.n_points ) ||
- BOUNDS( CUR.GS.rp0, CUR.zp0.n_points ) )
+ if ( BOUNDS( point, exc->zp1.n_points ) ||
+ BOUNDS( exc->GS.rp0, exc->zp0.n_points ) )
{
- if ( CUR.pedantic_hinting )
- CUR.error = FT_THROW( Invalid_Reference );
+ if ( exc->pedantic_hinting )
+ exc->error = FT_THROW( Invalid_Reference );
goto Fail;
}
@@ -6506,74 +6051,77 @@
/* XXX: UNDOCUMENTED: twilight zone special case */
- if ( CUR.GS.gep0 == 0 || CUR.GS.gep1 == 0 )
+ if ( exc->GS.gep0 == 0 || exc->GS.gep1 == 0 )
{
- FT_Vector* vec1 = &CUR.zp1.org[point];
- FT_Vector* vec2 = &CUR.zp0.org[CUR.GS.rp0];
+ FT_Vector* vec1 = &exc->zp1.org[point];
+ FT_Vector* vec2 = &exc->zp0.org[exc->GS.rp0];
- org_dist = CUR_Func_dualproj( vec1, vec2 );
+ org_dist = DUALPROJ( vec1, vec2 );
}
else
{
- FT_Vector* vec1 = &CUR.zp1.orus[point];
- FT_Vector* vec2 = &CUR.zp0.orus[CUR.GS.rp0];
+ FT_Vector* vec1 = &exc->zp1.orus[point];
+ FT_Vector* vec2 = &exc->zp0.orus[exc->GS.rp0];
- if ( CUR.metrics.x_scale == CUR.metrics.y_scale )
+ if ( exc->metrics.x_scale == exc->metrics.y_scale )
{
/* this should be faster */
- org_dist = CUR_Func_dualproj( vec1, vec2 );
- org_dist = FT_MulFix( org_dist, CUR.metrics.x_scale );
+ org_dist = DUALPROJ( vec1, vec2 );
+ org_dist = FT_MulFix( org_dist, exc->metrics.x_scale );
}
else
{
FT_Vector vec;
- vec.x = FT_MulFix( vec1->x - vec2->x, CUR.metrics.x_scale );
- vec.y = FT_MulFix( vec1->y - vec2->y, CUR.metrics.y_scale );
+ vec.x = FT_MulFix( vec1->x - vec2->x, exc->metrics.x_scale );
+ vec.y = FT_MulFix( vec1->y - vec2->y, exc->metrics.y_scale );
- org_dist = CUR_fast_dualproj( &vec );
+ org_dist = FAST_DUALPROJ( &vec );
}
}
/* single width cut-in test */
- if ( FT_ABS( org_dist - CUR.GS.single_width_value ) <
- CUR.GS.single_width_cutin )
+ if ( FT_ABS( org_dist - exc->GS.single_width_value ) <
+ exc->GS.single_width_cutin )
{
if ( org_dist >= 0 )
- org_dist = CUR.GS.single_width_value;
+ org_dist = exc->GS.single_width_value;
else
- org_dist = -CUR.GS.single_width_value;
+ org_dist = -exc->GS.single_width_value;
}
/* round flag */
- if ( ( CUR.opcode & 4 ) != 0 )
+ if ( ( exc->opcode & 4 ) != 0 )
{
#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
- if ( SUBPIXEL_HINTING &&
- CUR.ignore_x_mode &&
- CUR.GS.freeVector.x != 0 )
- distance = ROUND_None(
+ if ( SUBPIXEL_HINTING &&
+ exc->ignore_x_mode &&
+ exc->GS.freeVector.x != 0 )
+ distance = Round_None(
+ exc,
org_dist,
- CUR.tt_metrics.compensations[CUR.opcode & 3] );
+ exc->tt_metrics.compensations[exc->opcode & 3] );
else
#endif
- distance = CUR_Func_round(
- org_dist,
- CUR.tt_metrics.compensations[CUR.opcode & 3] );
+ distance = exc->func_round(
+ exc,
+ org_dist,
+ exc->tt_metrics.compensations[exc->opcode & 3] );
}
else
- distance = ROUND_None(
+ distance = Round_None(
+ exc,
org_dist,
- CUR.tt_metrics.compensations[CUR.opcode & 3] );
+ exc->tt_metrics.compensations[exc->opcode & 3] );
/* minimum distance flag */
- if ( ( CUR.opcode & 8 ) != 0 )
+ if ( ( exc->opcode & 8 ) != 0 )
{
if ( org_dist >= 0 )
{
@@ -6589,17 +6137,16 @@
/* now move the point */
- org_dist = CUR_Func_project( CUR.zp1.cur + point,
- CUR.zp0.cur + CUR.GS.rp0 );
+ org_dist = PROJECT( exc->zp1.cur + point, exc->zp0.cur + exc->GS.rp0 );
- CUR_Func_move( &CUR.zp1, point, distance - org_dist );
+ exc->func_move( exc, &exc->zp1, point, distance - org_dist );
Fail:
- CUR.GS.rp1 = CUR.GS.rp0;
- CUR.GS.rp2 = point;
+ exc->GS.rp1 = exc->GS.rp0;
+ exc->GS.rp2 = point;
- if ( ( CUR.opcode & 16 ) != 0 )
- CUR.GS.rp0 = point;
+ if ( ( exc->opcode & 16 ) != 0 )
+ exc->GS.rp0 = point;
}
@@ -6610,7 +6157,8 @@
/* Stack: int32? uint32 --> */
/* */
static void
- Ins_MIRP( INS_ARG )
+ Ins_MIRP( TT_ExecContext exc,
+ FT_Long* args )
{
FT_UShort point;
FT_ULong cvtEntry;
@@ -6628,77 +6176,75 @@
#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */
- minimum_distance = CUR.GS.minimum_distance;
- control_value_cutin = CUR.GS.control_value_cutin;
+ minimum_distance = exc->GS.minimum_distance;
+ control_value_cutin = exc->GS.control_value_cutin;
point = (FT_UShort)args[0];
cvtEntry = (FT_ULong)( args[1] + 1 );
#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
- if ( SUBPIXEL_HINTING &&
- CUR.ignore_x_mode &&
- CUR.GS.freeVector.x != 0 &&
- !( CUR.sph_tweak_flags & SPH_TWEAK_NORMAL_ROUND ) )
+ if ( SUBPIXEL_HINTING &&
+ exc->ignore_x_mode &&
+ exc->GS.freeVector.x != 0 &&
+ !( exc->sph_tweak_flags & SPH_TWEAK_NORMAL_ROUND ) )
control_value_cutin = minimum_distance = 0;
#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */
/* XXX: UNDOCUMENTED! cvt[-1] = 0 always */
- if ( BOUNDS( point, CUR.zp1.n_points ) ||
- BOUNDSL( cvtEntry, CUR.cvtSize + 1 ) ||
- BOUNDS( CUR.GS.rp0, CUR.zp0.n_points ) )
+ if ( BOUNDS( point, exc->zp1.n_points ) ||
+ BOUNDSL( cvtEntry, exc->cvtSize + 1 ) ||
+ BOUNDS( exc->GS.rp0, exc->zp0.n_points ) )
{
- if ( CUR.pedantic_hinting )
- CUR.error = FT_THROW( Invalid_Reference );
+ if ( exc->pedantic_hinting )
+ exc->error = FT_THROW( Invalid_Reference );
goto Fail;
}
if ( !cvtEntry )
cvt_dist = 0;
else
- cvt_dist = CUR_Func_read_cvt( cvtEntry - 1 );
+ cvt_dist = exc->func_read_cvt( exc, cvtEntry - 1 );
/* single width test */
- if ( FT_ABS( cvt_dist - CUR.GS.single_width_value ) <
- CUR.GS.single_width_cutin )
+ if ( FT_ABS( cvt_dist - exc->GS.single_width_value ) <
+ exc->GS.single_width_cutin )
{
if ( cvt_dist >= 0 )
- cvt_dist = CUR.GS.single_width_value;
+ cvt_dist = exc->GS.single_width_value;
else
- cvt_dist = -CUR.GS.single_width_value;
+ cvt_dist = -exc->GS.single_width_value;
}
/* UNDOCUMENTED! The MS rasterizer does that with */
/* twilight points (confirmed by Greg Hitchcock) */
- if ( CUR.GS.gep1 == 0 )
+ if ( exc->GS.gep1 == 0 )
{
- CUR.zp1.org[point].x = CUR.zp0.org[CUR.GS.rp0].x +
- TT_MulFix14( (FT_UInt32)cvt_dist,
- CUR.GS.freeVector.x );
- CUR.zp1.org[point].y = CUR.zp0.org[CUR.GS.rp0].y +
- TT_MulFix14( (FT_UInt32)cvt_dist,
- CUR.GS.freeVector.y );
- CUR.zp1.cur[point] = CUR.zp1.org[point];
+ exc->zp1.org[point].x = exc->zp0.org[exc->GS.rp0].x +
+ TT_MulFix14( cvt_dist,
+ exc->GS.freeVector.x );
+ exc->zp1.org[point].y = exc->zp0.org[exc->GS.rp0].y +
+ TT_MulFix14( cvt_dist,
+ exc->GS.freeVector.y );
+ exc->zp1.cur[point] = exc->zp1.org[point];
}
- org_dist = CUR_Func_dualproj( &CUR.zp1.org[point],
- &CUR.zp0.org[CUR.GS.rp0] );
- cur_dist = CUR_Func_project ( &CUR.zp1.cur[point],
- &CUR.zp0.cur[CUR.GS.rp0] );
+ org_dist = DUALPROJ( &exc->zp1.org[point], &exc->zp0.org[exc->GS.rp0] );
+ cur_dist = PROJECT ( &exc->zp1.cur[point], &exc->zp0.cur[exc->GS.rp0] );
/* auto-flip test */
- if ( CUR.GS.auto_flip )
+ if ( exc->GS.auto_flip )
{
if ( ( org_dist ^ cvt_dist ) < 0 )
cvt_dist = -cvt_dist;
}
#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
- if ( SUBPIXEL_HINTING &&
- CUR.ignore_x_mode &&
- CUR.GS.freeVector.y != 0 &&
- ( CUR.sph_tweak_flags & SPH_TWEAK_TIMES_NEW_ROMAN_HACK ) )
+ if ( SUBPIXEL_HINTING &&
+ exc->ignore_x_mode &&
+ exc->GS.freeVector.y != 0 &&
+ ( exc->sph_tweak_flags & SPH_TWEAK_TIMES_NEW_ROMAN_HACK ) )
{
if ( cur_dist < -64 )
cvt_dist -= 16;
@@ -6709,12 +6255,12 @@
/* control value cut-in and round */
- if ( ( CUR.opcode & 4 ) != 0 )
+ if ( ( exc->opcode & 4 ) != 0 )
{
/* XXX: UNDOCUMENTED! Only perform cut-in test when both points */
/* refer to the same zone. */
- if ( CUR.GS.gep0 == CUR.GS.gep1 )
+ if ( exc->GS.gep0 == exc->GS.gep1 )
{
/* XXX: According to Greg Hitchcock, the following wording is */
/* the right one: */
@@ -6732,32 +6278,34 @@
cvt_dist = org_dist;
}
- distance = CUR_Func_round(
+ distance = exc->func_round(
+ exc,
cvt_dist,
- CUR.tt_metrics.compensations[CUR.opcode & 3] );
+ exc->tt_metrics.compensations[exc->opcode & 3] );
}
else
{
#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
/* do cvt cut-in always in MIRP for sph */
- if ( SUBPIXEL_HINTING &&
- CUR.ignore_x_mode &&
- CUR.GS.gep0 == CUR.GS.gep1 )
+ if ( SUBPIXEL_HINTING &&
+ exc->ignore_x_mode &&
+ exc->GS.gep0 == exc->GS.gep1 )
{
if ( FT_ABS( cvt_dist - org_dist ) > control_value_cutin )
cvt_dist = org_dist;
}
#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */
- distance = ROUND_None(
+ distance = Round_None(
+ exc,
cvt_dist,
- CUR.tt_metrics.compensations[CUR.opcode & 3] );
+ exc->tt_metrics.compensations[exc->opcode & 3] );
}
/* minimum distance test */
- if ( ( CUR.opcode & 8 ) != 0 )
+ if ( ( exc->opcode & 8 ) != 0 )
{
if ( org_dist >= 0 )
{
@@ -6774,59 +6322,59 @@
#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
if ( SUBPIXEL_HINTING )
{
- B1 = CUR.zp1.cur[point].y;
+ B1 = exc->zp1.cur[point].y;
/* Round moves if necessary */
- if ( CUR.ignore_x_mode &&
- CUR.GS.freeVector.y != 0 &&
- ( CUR.sph_tweak_flags & SPH_TWEAK_ROUND_NONPIXEL_Y_MOVES ) )
+ if ( exc->ignore_x_mode &&
+ exc->GS.freeVector.y != 0 &&
+ ( exc->sph_tweak_flags & SPH_TWEAK_ROUND_NONPIXEL_Y_MOVES ) )
distance = FT_PIX_ROUND( B1 + distance - cur_dist ) - B1 + cur_dist;
- if ( CUR.ignore_x_mode &&
- CUR.GS.freeVector.y != 0 &&
- ( CUR.opcode & 16 ) == 0 &&
- ( CUR.opcode & 8 ) == 0 &&
- ( CUR.sph_tweak_flags & SPH_TWEAK_COURIER_NEW_2_HACK ) )
+ if ( exc->ignore_x_mode &&
+ exc->GS.freeVector.y != 0 &&
+ ( exc->opcode & 16 ) == 0 &&
+ ( exc->opcode & 8 ) == 0 &&
+ ( exc->sph_tweak_flags & SPH_TWEAK_COURIER_NEW_2_HACK ) )
distance += 64;
}
#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */
- CUR_Func_move( &CUR.zp1, point, distance - cur_dist );
+ exc->func_move( exc, &exc->zp1, point, distance - cur_dist );
#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
if ( SUBPIXEL_HINTING )
{
- B2 = CUR.zp1.cur[point].y;
+ B2 = exc->zp1.cur[point].y;
/* Reverse move if necessary */
- if ( CUR.ignore_x_mode )
+ if ( exc->ignore_x_mode )
{
- if ( CUR.face->sph_compatibility_mode &&
- CUR.GS.freeVector.y != 0 &&
- ( B1 & 63 ) == 0 &&
- ( B2 & 63 ) != 0 )
+ if ( exc->face->sph_compatibility_mode &&
+ exc->GS.freeVector.y != 0 &&
+ ( B1 & 63 ) == 0 &&
+ ( B2 & 63 ) != 0 )
reverse_move = TRUE;
- if ( ( CUR.sph_tweak_flags & SPH_TWEAK_SKIP_NONPIXEL_Y_MOVES ) &&
- CUR.GS.freeVector.y != 0 &&
- ( B2 & 63 ) != 0 &&
- ( B1 & 63 ) != 0 )
+ if ( ( exc->sph_tweak_flags & SPH_TWEAK_SKIP_NONPIXEL_Y_MOVES ) &&
+ exc->GS.freeVector.y != 0 &&
+ ( B2 & 63 ) != 0 &&
+ ( B1 & 63 ) != 0 )
reverse_move = TRUE;
}
if ( reverse_move )
- CUR_Func_move( &CUR.zp1, point, -( distance - cur_dist ) );
+ exc->func_move( exc, &exc->zp1, point, -( distance - cur_dist ) );
}
#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */
Fail:
- CUR.GS.rp1 = CUR.GS.rp0;
+ exc->GS.rp1 = exc->GS.rp0;
- if ( ( CUR.opcode & 16 ) != 0 )
- CUR.GS.rp0 = point;
+ if ( ( exc->opcode & 16 ) != 0 )
+ exc->GS.rp0 = point;
- CUR.GS.rp2 = point;
+ exc->GS.rp2 = point;
}
@@ -6837,61 +6385,59 @@
/* Stack: uint32 uint32... --> */
/* */
static void
- Ins_ALIGNRP( INS_ARG )
+ Ins_ALIGNRP( TT_ExecContext exc )
{
FT_UShort point;
FT_F26Dot6 distance;
- FT_UNUSED_ARG;
-
#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
- if ( SUBPIXEL_HINTING &&
- CUR.ignore_x_mode &&
- CUR.iup_called &&
- ( CUR.sph_tweak_flags & SPH_TWEAK_NO_ALIGNRP_AFTER_IUP ) )
+ if ( SUBPIXEL_HINTING &&
+ exc->ignore_x_mode &&
+ exc->iup_called &&
+ ( exc->sph_tweak_flags & SPH_TWEAK_NO_ALIGNRP_AFTER_IUP ) )
{
- CUR.error = FT_THROW( Invalid_Reference );
+ exc->error = FT_THROW( Invalid_Reference );
goto Fail;
}
#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */
- if ( CUR.top < CUR.GS.loop ||
- BOUNDS( CUR.GS.rp0, CUR.zp0.n_points ) )
+ if ( exc->top < exc->GS.loop ||
+ BOUNDS( exc->GS.rp0, exc->zp0.n_points ) )
{
- if ( CUR.pedantic_hinting )
- CUR.error = FT_THROW( Invalid_Reference );
+ if ( exc->pedantic_hinting )
+ exc->error = FT_THROW( Invalid_Reference );
goto Fail;
}
- while ( CUR.GS.loop > 0 )
+ while ( exc->GS.loop > 0 )
{
- CUR.args--;
+ exc->args--;
- point = (FT_UShort)CUR.stack[CUR.args];
+ point = (FT_UShort)exc->stack[exc->args];
- if ( BOUNDS( point, CUR.zp1.n_points ) )
+ if ( BOUNDS( point, exc->zp1.n_points ) )
{
- if ( CUR.pedantic_hinting )
+ if ( exc->pedantic_hinting )
{
- CUR.error = FT_THROW( Invalid_Reference );
+ exc->error = FT_THROW( Invalid_Reference );
return;
}
}
else
{
- distance = CUR_Func_project( CUR.zp1.cur + point,
- CUR.zp0.cur + CUR.GS.rp0 );
+ distance = PROJECT( exc->zp1.cur + point,
+ exc->zp0.cur + exc->GS.rp0 );
- CUR_Func_move( &CUR.zp1, point, -distance );
+ exc->func_move( exc, &exc->zp1, point, -distance );
}
- CUR.GS.loop--;
+ exc->GS.loop--;
}
Fail:
- CUR.GS.loop = 1;
- CUR.new_top = CUR.args;
+ exc->GS.loop = 1;
+ exc->new_top = exc->args;
}
@@ -6902,7 +6448,8 @@
/* Stack: 5 * uint32 --> */
/* */
static void
- Ins_ISECT( INS_ARG )
+ Ins_ISECT( TT_ExecContext exc,
+ FT_Long* args )
{
FT_UShort point,
a0, a1,
@@ -6926,29 +6473,27 @@
b0 = (FT_UShort)args[3];
b1 = (FT_UShort)args[4];
- if ( BOUNDS( b0, CUR.zp0.n_points ) ||
- BOUNDS( b1, CUR.zp0.n_points ) ||
- BOUNDS( a0, CUR.zp1.n_points ) ||
- BOUNDS( a1, CUR.zp1.n_points ) ||
- BOUNDS( point, CUR.zp2.n_points ) )
+ if ( BOUNDS( b0, exc->zp0.n_points ) ||
+ BOUNDS( b1, exc->zp0.n_points ) ||
+ BOUNDS( a0, exc->zp1.n_points ) ||
+ BOUNDS( a1, exc->zp1.n_points ) ||
+ BOUNDS( point, exc->zp2.n_points ) )
{
- if ( CUR.pedantic_hinting )
- CUR.error = FT_THROW( Invalid_Reference );
+ if ( exc->pedantic_hinting )
+ exc->error = FT_THROW( Invalid_Reference );
return;
}
/* Cramer's rule */
- dbx = CUR.zp0.cur[b1].x - CUR.zp0.cur[b0].x;
- dby = CUR.zp0.cur[b1].y - CUR.zp0.cur[b0].y;
+ dbx = exc->zp0.cur[b1].x - exc->zp0.cur[b0].x;
+ dby = exc->zp0.cur[b1].y - exc->zp0.cur[b0].y;
- dax = CUR.zp1.cur[a1].x - CUR.zp1.cur[a0].x;
- day = CUR.zp1.cur[a1].y - CUR.zp1.cur[a0].y;
+ dax = exc->zp1.cur[a1].x - exc->zp1.cur[a0].x;
+ day = exc->zp1.cur[a1].y - exc->zp1.cur[a0].y;
- dx = CUR.zp0.cur[b0].x - CUR.zp1.cur[a0].x;
- dy = CUR.zp0.cur[b0].y - CUR.zp1.cur[a0].y;
-
- CUR.zp2.tags[point] |= FT_CURVE_TAG_TOUCH_BOTH;
+ dx = exc->zp0.cur[b0].x - exc->zp1.cur[a0].x;
+ dy = exc->zp0.cur[b0].y - exc->zp1.cur[a0].y;
discriminant = FT_MulDiv( dax, -dby, 0x40 ) +
FT_MulDiv( day, dbx, 0x40 );
@@ -6970,22 +6515,24 @@
R.x = FT_MulDiv( val, dax, discriminant );
R.y = FT_MulDiv( val, day, discriminant );
- CUR.zp2.cur[point].x = CUR.zp1.cur[a0].x + R.x;
- CUR.zp2.cur[point].y = CUR.zp1.cur[a0].y + R.y;
+ exc->zp2.cur[point].x = exc->zp1.cur[a0].x + R.x;
+ exc->zp2.cur[point].y = exc->zp1.cur[a0].y + R.y;
}
else
{
/* else, take the middle of the middles of A and B */
- CUR.zp2.cur[point].x = ( CUR.zp1.cur[a0].x +
- CUR.zp1.cur[a1].x +
- CUR.zp0.cur[b0].x +
- CUR.zp0.cur[b1].x ) / 4;
- CUR.zp2.cur[point].y = ( CUR.zp1.cur[a0].y +
- CUR.zp1.cur[a1].y +
- CUR.zp0.cur[b0].y +
- CUR.zp0.cur[b1].y ) / 4;
+ exc->zp2.cur[point].x = ( exc->zp1.cur[a0].x +
+ exc->zp1.cur[a1].x +
+ exc->zp0.cur[b0].x +
+ exc->zp0.cur[b1].x ) / 4;
+ exc->zp2.cur[point].y = ( exc->zp1.cur[a0].y +
+ exc->zp1.cur[a1].y +
+ exc->zp0.cur[b0].y +
+ exc->zp0.cur[b1].y ) / 4;
}
+
+ exc->zp2.tags[point] |= FT_CURVE_TAG_TOUCH_BOTH;
}
@@ -6996,7 +6543,8 @@
/* Stack: uint32 uint32 --> */
/* */
static void
- Ins_ALIGNPTS( INS_ARG )
+ Ins_ALIGNPTS( TT_ExecContext exc,
+ FT_Long* args )
{
FT_UShort p1, p2;
FT_F26Dot6 distance;
@@ -7005,19 +6553,18 @@
p1 = (FT_UShort)args[0];
p2 = (FT_UShort)args[1];
- if ( BOUNDS( p1, CUR.zp1.n_points ) ||
- BOUNDS( p2, CUR.zp0.n_points ) )
+ if ( BOUNDS( p1, exc->zp1.n_points ) ||
+ BOUNDS( p2, exc->zp0.n_points ) )
{
- if ( CUR.pedantic_hinting )
- CUR.error = FT_THROW( Invalid_Reference );
+ if ( exc->pedantic_hinting )
+ exc->error = FT_THROW( Invalid_Reference );
return;
}
- distance = CUR_Func_project( CUR.zp0.cur + p2,
- CUR.zp1.cur + p1 ) / 2;
+ distance = PROJECT( exc->zp0.cur + p2, exc->zp1.cur + p1 ) / 2;
- CUR_Func_move( &CUR.zp1, p1, distance );
- CUR_Func_move( &CUR.zp0, p2, -distance );
+ exc->func_move( exc, &exc->zp1, p1, distance );
+ exc->func_move( exc, &exc->zp0, p2, -distance );
}
@@ -7031,50 +6578,48 @@
/* SOMETIMES, DUMBER CODE IS BETTER CODE */
static void
- Ins_IP( INS_ARG )
+ Ins_IP( TT_ExecContext exc )
{
FT_F26Dot6 old_range, cur_range;
FT_Vector* orus_base;
FT_Vector* cur_base;
FT_Int twilight;
- FT_UNUSED_ARG;
-
- if ( CUR.top < CUR.GS.loop )
+ if ( exc->top < exc->GS.loop )
{
- if ( CUR.pedantic_hinting )
- CUR.error = FT_THROW( Invalid_Reference );
+ if ( exc->pedantic_hinting )
+ exc->error = FT_THROW( Invalid_Reference );
goto Fail;
}
/*
* We need to deal in a special way with the twilight zone.
- * Otherwise, by definition, the value of CUR.twilight.orus[n] is (0,0),
+ * Otherwise, by definition, the value of exc->twilight.orus[n] is (0,0),
* for every n.
*/
- twilight = CUR.GS.gep0 == 0 || CUR.GS.gep1 == 0 || CUR.GS.gep2 == 0;
+ twilight = exc->GS.gep0 == 0 || exc->GS.gep1 == 0 || exc->GS.gep2 == 0;
- if ( BOUNDS( CUR.GS.rp1, CUR.zp0.n_points ) )
+ if ( BOUNDS( exc->GS.rp1, exc->zp0.n_points ) )
{
- if ( CUR.pedantic_hinting )
- CUR.error = FT_THROW( Invalid_Reference );
+ if ( exc->pedantic_hinting )
+ exc->error = FT_THROW( Invalid_Reference );
goto Fail;
}
if ( twilight )
- orus_base = &CUR.zp0.org[CUR.GS.rp1];
+ orus_base = &exc->zp0.org[exc->GS.rp1];
else
- orus_base = &CUR.zp0.orus[CUR.GS.rp1];
+ orus_base = &exc->zp0.orus[exc->GS.rp1];
- cur_base = &CUR.zp0.cur[CUR.GS.rp1];
+ cur_base = &exc->zp0.cur[exc->GS.rp1];
/* XXX: There are some glyphs in some braindead but popular */
/* fonts out there (e.g. [aeu]grave in monotype.ttf) */
/* calling IP[] with bad values of rp[12]. */
/* Do something sane when this odd thing happens. */
- if ( BOUNDS( CUR.GS.rp1, CUR.zp0.n_points ) ||
- BOUNDS( CUR.GS.rp2, CUR.zp1.n_points ) )
+ if ( BOUNDS( exc->GS.rp1, exc->zp0.n_points ) ||
+ BOUNDS( exc->GS.rp2, exc->zp1.n_points ) )
{
old_range = 0;
cur_range = 0;
@@ -7082,62 +6627,60 @@
else
{
if ( twilight )
- old_range = CUR_Func_dualproj( &CUR.zp1.org[CUR.GS.rp2],
- orus_base );
- else if ( CUR.metrics.x_scale == CUR.metrics.y_scale )
- old_range = CUR_Func_dualproj( &CUR.zp1.orus[CUR.GS.rp2],
- orus_base );
+ old_range = DUALPROJ( &exc->zp1.org[exc->GS.rp2], orus_base );
+ else if ( exc->metrics.x_scale == exc->metrics.y_scale )
+ old_range = DUALPROJ( &exc->zp1.orus[exc->GS.rp2], orus_base );
else
{
FT_Vector vec;
- vec.x = FT_MulFix( CUR.zp1.orus[CUR.GS.rp2].x - orus_base->x,
- CUR.metrics.x_scale );
- vec.y = FT_MulFix( CUR.zp1.orus[CUR.GS.rp2].y - orus_base->y,
- CUR.metrics.y_scale );
+ vec.x = FT_MulFix( exc->zp1.orus[exc->GS.rp2].x - orus_base->x,
+ exc->metrics.x_scale );
+ vec.y = FT_MulFix( exc->zp1.orus[exc->GS.rp2].y - orus_base->y,
+ exc->metrics.y_scale );
- old_range = CUR_fast_dualproj( &vec );
+ old_range = FAST_DUALPROJ( &vec );
}
- cur_range = CUR_Func_project ( &CUR.zp1.cur[CUR.GS.rp2], cur_base );
+ cur_range = PROJECT( &exc->zp1.cur[exc->GS.rp2], cur_base );
}
- for ( ; CUR.GS.loop > 0; --CUR.GS.loop )
+ for ( ; exc->GS.loop > 0; --exc->GS.loop )
{
- FT_UInt point = (FT_UInt)CUR.stack[--CUR.args];
+ FT_UInt point = (FT_UInt)exc->stack[--exc->args];
FT_F26Dot6 org_dist, cur_dist, new_dist;
/* check point bounds */
- if ( BOUNDS( point, CUR.zp2.n_points ) )
+ if ( BOUNDS( point, exc->zp2.n_points ) )
{
- if ( CUR.pedantic_hinting )
+ if ( exc->pedantic_hinting )
{
- CUR.error = FT_THROW( Invalid_Reference );
+ exc->error = FT_THROW( Invalid_Reference );
return;
}
continue;
}
if ( twilight )
- org_dist = CUR_Func_dualproj( &CUR.zp2.org[point], orus_base );
- else if ( CUR.metrics.x_scale == CUR.metrics.y_scale )
- org_dist = CUR_Func_dualproj( &CUR.zp2.orus[point], orus_base );
+ org_dist = DUALPROJ( &exc->zp2.org[point], orus_base );
+ else if ( exc->metrics.x_scale == exc->metrics.y_scale )
+ org_dist = DUALPROJ( &exc->zp2.orus[point], orus_base );
else
{
FT_Vector vec;
- vec.x = FT_MulFix( CUR.zp2.orus[point].x - orus_base->x,
- CUR.metrics.x_scale );
- vec.y = FT_MulFix( CUR.zp2.orus[point].y - orus_base->y,
- CUR.metrics.y_scale );
+ vec.x = FT_MulFix( exc->zp2.orus[point].x - orus_base->x,
+ exc->metrics.x_scale );
+ vec.y = FT_MulFix( exc->zp2.orus[point].y - orus_base->y,
+ exc->metrics.y_scale );
- org_dist = CUR_fast_dualproj( &vec );
+ org_dist = FAST_DUALPROJ( &vec );
}
- cur_dist = CUR_Func_project( &CUR.zp2.cur[point], cur_base );
+ cur_dist = PROJECT( &exc->zp2.cur[point], cur_base );
if ( org_dist )
{
@@ -7167,12 +6710,15 @@
else
new_dist = 0;
- CUR_Func_move( &CUR.zp2, (FT_UShort)point, new_dist - cur_dist );
+ exc->func_move( exc,
+ &exc->zp2,
+ (FT_UShort)point,
+ new_dist - cur_dist );
}
Fail:
- CUR.GS.loop = 1;
- CUR.new_top = CUR.args;
+ exc->GS.loop = 1;
+ exc->new_top = exc->args;
}
@@ -7183,7 +6729,8 @@
/* Stack: uint32 --> */
/* */
static void
- Ins_UTP( INS_ARG )
+ Ins_UTP( TT_ExecContext exc,
+ FT_Long* args )
{
FT_UShort point;
FT_Byte mask;
@@ -7191,22 +6738,22 @@
point = (FT_UShort)args[0];
- if ( BOUNDS( point, CUR.zp0.n_points ) )
+ if ( BOUNDS( point, exc->zp0.n_points ) )
{
- if ( CUR.pedantic_hinting )
- CUR.error = FT_THROW( Invalid_Reference );
+ if ( exc->pedantic_hinting )
+ exc->error = FT_THROW( Invalid_Reference );
return;
}
mask = 0xFF;
- if ( CUR.GS.freeVector.x != 0 )
+ if ( exc->GS.freeVector.x != 0 )
mask &= ~FT_CURVE_TAG_TOUCH_X;
- if ( CUR.GS.freeVector.y != 0 )
+ if ( exc->GS.freeVector.y != 0 )
mask &= ~FT_CURVE_TAG_TOUCH_Y;
- CUR.zp0.tags[point] &= mask;
+ exc->zp0.tags[point] &= mask;
}
@@ -7251,7 +6798,7 @@
FT_UInt ref2 )
{
FT_UInt i;
- FT_F26Dot6 orus1, orus2, org1, org2, delta1, delta2;
+ FT_F26Dot6 orus1, orus2, org1, org2, cur1, cur2, delta1, delta2;
if ( p1 > p2 )
@@ -7281,12 +6828,15 @@
org1 = worker->orgs[ref1].x;
org2 = worker->orgs[ref2].x;
- delta1 = worker->curs[ref1].x - org1;
- delta2 = worker->curs[ref2].x - org2;
+ cur1 = worker->curs[ref1].x;
+ cur2 = worker->curs[ref2].x;
+ delta1 = cur1 - org1;
+ delta2 = cur2 - org2;
- if ( orus1 == orus2 )
+ if ( cur1 == cur2 || orus1 == orus2 )
{
- /* simple shift of untouched points */
+
+ /* trivial snap or shift of untouched points */
for ( i = p1; i <= p2; i++ )
{
FT_F26Dot6 x = worker->orgs[i].x;
@@ -7294,9 +6844,13 @@
if ( x <= org1 )
x += delta1;
- else
+
+ else if ( x >= org2 )
x += delta2;
+ else
+ x = cur1;
+
worker->curs[i].x = x;
}
}
@@ -7323,12 +6877,10 @@
if ( !scale_valid )
{
scale_valid = 1;
- scale = FT_DivFix( org2 + delta2 - ( org1 + delta1 ),
- orus2 - orus1 );
+ scale = FT_DivFix( cur2 - cur1, orus2 - orus1 );
}
- x = ( org1 + delta1 ) +
- FT_MulFix( worker->orus[i].x - orus1, scale );
+ x = cur1 + FT_MulFix( worker->orus[i].x - orus1, scale );
}
worker->curs[i].x = x;
}
@@ -7343,7 +6895,7 @@
/* Stack: --> */
/* */
static void
- Ins_IUP( INS_ARG )
+ Ins_IUP( TT_ExecContext exc )
{
IUP_WorkerRec V;
FT_Byte mask;
@@ -7357,51 +6909,49 @@
FT_UInt point; /* current point */
FT_Short contour; /* current contour */
- FT_UNUSED_ARG;
-
/* ignore empty outlines */
- if ( CUR.pts.n_contours == 0 )
+ if ( exc->pts.n_contours == 0 )
return;
- if ( CUR.opcode & 1 )
+ if ( exc->opcode & 1 )
{
mask = FT_CURVE_TAG_TOUCH_X;
- V.orgs = CUR.pts.org;
- V.curs = CUR.pts.cur;
- V.orus = CUR.pts.orus;
+ V.orgs = exc->pts.org;
+ V.curs = exc->pts.cur;
+ V.orus = exc->pts.orus;
}
else
{
mask = FT_CURVE_TAG_TOUCH_Y;
- V.orgs = (FT_Vector*)( (FT_Pos*)CUR.pts.org + 1 );
- V.curs = (FT_Vector*)( (FT_Pos*)CUR.pts.cur + 1 );
- V.orus = (FT_Vector*)( (FT_Pos*)CUR.pts.orus + 1 );
+ V.orgs = (FT_Vector*)( (FT_Pos*)exc->pts.org + 1 );
+ V.curs = (FT_Vector*)( (FT_Pos*)exc->pts.cur + 1 );
+ V.orus = (FT_Vector*)( (FT_Pos*)exc->pts.orus + 1 );
}
- V.max_points = CUR.pts.n_points;
+ V.max_points = exc->pts.n_points;
contour = 0;
point = 0;
#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
- if ( SUBPIXEL_HINTING &&
- CUR.ignore_x_mode )
+ if ( SUBPIXEL_HINTING &&
+ exc->ignore_x_mode )
{
- CUR.iup_called = TRUE;
- if ( CUR.sph_tweak_flags & SPH_TWEAK_SKIP_IUP )
+ exc->iup_called = TRUE;
+ if ( exc->sph_tweak_flags & SPH_TWEAK_SKIP_IUP )
return;
}
#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */
do
{
- end_point = CUR.pts.contours[contour] - CUR.pts.first_point;
+ end_point = exc->pts.contours[contour] - exc->pts.first_point;
first_point = point;
- if ( BOUNDS ( end_point, CUR.pts.n_points ) )
- end_point = CUR.pts.n_points - 1;
+ if ( BOUNDS( end_point, exc->pts.n_points ) )
+ end_point = exc->pts.n_points - 1;
- while ( point <= end_point && ( CUR.pts.tags[point] & mask ) == 0 )
+ while ( point <= end_point && ( exc->pts.tags[point] & mask ) == 0 )
point++;
if ( point <= end_point )
@@ -7413,7 +6963,7 @@
while ( point <= end_point )
{
- if ( ( CUR.pts.tags[point] & mask ) != 0 )
+ if ( ( exc->pts.tags[point] & mask ) != 0 )
{
_iup_worker_interpolate( &V,
cur_touched + 1,
@@ -7445,7 +6995,7 @@
}
}
contour++;
- } while ( contour < CUR.pts.n_contours );
+ } while ( contour < exc->pts.n_contours );
}
@@ -7456,7 +7006,8 @@
/* Stack: uint32 (2 * uint32)... --> */
/* */
static void
- Ins_DELTAP( INS_ARG )
+ Ins_DELTAP( TT_ExecContext exc,
+ FT_Long* args )
{
FT_ULong nump, k;
FT_UShort A;
@@ -7466,52 +7017,52 @@
FT_UShort B1, B2;
- if ( SUBPIXEL_HINTING &&
- CUR.ignore_x_mode &&
- CUR.iup_called &&
- ( CUR.sph_tweak_flags & SPH_TWEAK_NO_DELTAP_AFTER_IUP ) )
+ if ( SUBPIXEL_HINTING &&
+ exc->ignore_x_mode &&
+ exc->iup_called &&
+ ( exc->sph_tweak_flags & SPH_TWEAK_NO_DELTAP_AFTER_IUP ) )
goto Fail;
#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */
#ifdef TT_CONFIG_OPTION_UNPATENTED_HINTING
/* Delta hinting is covered by US Patent 5159668. */
- if ( CUR.face->unpatented_hinting )
+ if ( exc->face->unpatented_hinting )
{
FT_Long n = args[0] * 2;
- if ( CUR.args < n )
+ if ( exc->args < n )
{
- if ( CUR.pedantic_hinting )
- CUR.error = FT_THROW( Too_Few_Arguments );
- n = CUR.args;
+ if ( exc->pedantic_hinting )
+ exc->error = FT_THROW( Too_Few_Arguments );
+ n = exc->args;
}
- CUR.args -= n;
- CUR.new_top = CUR.args;
+ exc->args -= n;
+ exc->new_top = exc->args;
return;
}
#endif
- P = (FT_ULong)CUR_Func_cur_ppem();
+ P = (FT_ULong)exc->func_cur_ppem( exc );
nump = (FT_ULong)args[0]; /* some points theoretically may occur more
than once, thus UShort isn't enough */
for ( k = 1; k <= nump; k++ )
{
- if ( CUR.args < 2 )
+ if ( exc->args < 2 )
{
- if ( CUR.pedantic_hinting )
- CUR.error = FT_THROW( Too_Few_Arguments );
- CUR.args = 0;
+ if ( exc->pedantic_hinting )
+ exc->error = FT_THROW( Too_Few_Arguments );
+ exc->args = 0;
goto Fail;
}
- CUR.args -= 2;
+ exc->args -= 2;
- A = (FT_UShort)CUR.stack[CUR.args + 1];
- B = CUR.stack[CUR.args];
+ A = (FT_UShort)exc->stack[exc->args + 1];
+ B = exc->stack[exc->args];
/* XXX: Because some popular fonts contain some invalid DeltaP */
/* instructions, we simply ignore them when the stacked */
@@ -7519,11 +7070,11 @@
/* error. As a delta instruction doesn't change a glyph */
/* in great ways, this shouldn't be a problem. */
- if ( !BOUNDS( A, CUR.zp0.n_points ) )
+ if ( !BOUNDS( A, exc->zp0.n_points ) )
{
C = ( (FT_ULong)B & 0xF0 ) >> 4;
- switch ( CUR.opcode )
+ switch ( exc->opcode )
{
case 0x5D:
break;
@@ -7537,14 +7088,14 @@
break;
}
- C += CUR.GS.delta_base;
+ C += exc->GS.delta_base;
if ( P == C )
{
B = ( (FT_ULong)B & 0xF ) - 8;
if ( B >= 0 )
B++;
- B *= 1L << ( 6 - CUR.GS.delta_shift );
+ B *= 1L << ( 6 - exc->GS.delta_shift );
#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
@@ -7558,65 +7109,65 @@
* - glyph is composite and freedom vector is not in subpixel
* direction.
*/
- if ( !CUR.ignore_x_mode ||
- ( CUR.sph_tweak_flags & SPH_TWEAK_ALWAYS_DO_DELTAP ) ||
- ( CUR.is_composite && CUR.GS.freeVector.y != 0 ) )
- CUR_Func_move( &CUR.zp0, A, B );
+ if ( !exc->ignore_x_mode ||
+ ( exc->sph_tweak_flags & SPH_TWEAK_ALWAYS_DO_DELTAP ) ||
+ ( exc->is_composite && exc->GS.freeVector.y != 0 ) )
+ exc->func_move( exc, &exc->zp0, A, B );
/* Otherwise, apply subpixel hinting and compatibility mode */
/* rules, always skipping deltas in subpixel direction. */
- else if ( CUR.ignore_x_mode && CUR.GS.freeVector.y != 0 )
+ else if ( exc->ignore_x_mode && exc->GS.freeVector.y != 0 )
{
/* save the y value of the point now; compare after move */
- B1 = (FT_UShort)CUR.zp0.cur[A].y;
+ B1 = (FT_UShort)exc->zp0.cur[A].y;
/* Standard subpixel hinting: Allow y move for y-touched */
/* points. This messes up DejaVu ... */
- if ( !CUR.face->sph_compatibility_mode &&
- ( CUR.zp0.tags[A] & FT_CURVE_TAG_TOUCH_Y ) )
- CUR_Func_move( &CUR.zp0, A, B );
+ if ( !exc->face->sph_compatibility_mode &&
+ ( exc->zp0.tags[A] & FT_CURVE_TAG_TOUCH_Y ) )
+ exc->func_move( exc, &exc->zp0, A, B );
/* compatibility mode */
- else if ( CUR.face->sph_compatibility_mode &&
- !( CUR.sph_tweak_flags & SPH_TWEAK_ALWAYS_SKIP_DELTAP ) )
+ else if ( exc->face->sph_compatibility_mode &&
+ !( exc->sph_tweak_flags & SPH_TWEAK_ALWAYS_SKIP_DELTAP ) )
{
- if ( CUR.sph_tweak_flags & SPH_TWEAK_ROUND_NONPIXEL_Y_MOVES )
+ if ( exc->sph_tweak_flags & SPH_TWEAK_ROUND_NONPIXEL_Y_MOVES )
B = FT_PIX_ROUND( B1 + B ) - B1;
/* Allow delta move if using sph_compatibility_mode, */
/* IUP has not been called, and point is touched on Y. */
- if ( !CUR.iup_called &&
- ( CUR.zp0.tags[A] & FT_CURVE_TAG_TOUCH_Y ) )
- CUR_Func_move( &CUR.zp0, A, B );
+ if ( !exc->iup_called &&
+ ( exc->zp0.tags[A] & FT_CURVE_TAG_TOUCH_Y ) )
+ exc->func_move( exc, &exc->zp0, A, B );
}
- B2 = (FT_UShort)CUR.zp0.cur[A].y;
+ B2 = (FT_UShort)exc->zp0.cur[A].y;
/* Reverse this move if it results in a disallowed move */
- if ( CUR.GS.freeVector.y != 0 &&
- ( ( CUR.face->sph_compatibility_mode &&
+ if ( exc->GS.freeVector.y != 0 &&
+ ( ( exc->face->sph_compatibility_mode &&
( B1 & 63 ) == 0 &&
( B2 & 63 ) != 0 ) ||
- ( ( CUR.sph_tweak_flags &
+ ( ( exc->sph_tweak_flags &
SPH_TWEAK_SKIP_NONPIXEL_Y_MOVES_DELTAP ) &&
( B1 & 63 ) != 0 &&
( B2 & 63 ) != 0 ) ) )
- CUR_Func_move( &CUR.zp0, A, -B );
+ exc->func_move( exc, &exc->zp0, A, -B );
}
}
else
#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */
- CUR_Func_move( &CUR.zp0, A, B );
+ exc->func_move( exc, &exc->zp0, A, B );
}
}
else
- if ( CUR.pedantic_hinting )
- CUR.error = FT_THROW( Invalid_Reference );
+ if ( exc->pedantic_hinting )
+ exc->error = FT_THROW( Invalid_Reference );
}
Fail:
- CUR.new_top = CUR.args;
+ exc->new_top = exc->args;
}
@@ -7627,7 +7178,8 @@
/* Stack: uint32 (2 * uint32)... --> */
/* */
static void
- Ins_DELTAC( INS_ARG )
+ Ins_DELTAC( TT_ExecContext exc,
+ FT_Long* args )
{
FT_ULong nump, k;
FT_ULong A, C, P;
@@ -7636,47 +7188,47 @@
#ifdef TT_CONFIG_OPTION_UNPATENTED_HINTING
/* Delta hinting is covered by US Patent 5159668. */
- if ( CUR.face->unpatented_hinting )
+ if ( exc->face->unpatented_hinting )
{
FT_Long n = args[0] * 2;
- if ( CUR.args < n )
+ if ( exc->args < n )
{
- if ( CUR.pedantic_hinting )
- CUR.error = FT_THROW( Too_Few_Arguments );
- n = CUR.args;
+ if ( exc->pedantic_hinting )
+ exc->error = FT_THROW( Too_Few_Arguments );
+ n = exc->args;
}
- CUR.args -= n;
- CUR.new_top = CUR.args;
+ exc->args -= n;
+ exc->new_top = exc->args;
return;
}
#endif
- P = (FT_ULong)CUR_Func_cur_ppem();
+ P = (FT_ULong)exc->func_cur_ppem( exc );
nump = (FT_ULong)args[0];
for ( k = 1; k <= nump; k++ )
{
- if ( CUR.args < 2 )
+ if ( exc->args < 2 )
{
- if ( CUR.pedantic_hinting )
- CUR.error = FT_THROW( Too_Few_Arguments );
- CUR.args = 0;
+ if ( exc->pedantic_hinting )
+ exc->error = FT_THROW( Too_Few_Arguments );
+ exc->args = 0;
goto Fail;
}
- CUR.args -= 2;
+ exc->args -= 2;
- A = (FT_ULong)CUR.stack[CUR.args + 1];
- B = CUR.stack[CUR.args];
+ A = (FT_ULong)exc->stack[exc->args + 1];
+ B = exc->stack[exc->args];
- if ( BOUNDSL( A, CUR.cvtSize ) )
+ if ( BOUNDSL( A, exc->cvtSize ) )
{
- if ( CUR.pedantic_hinting )
+ if ( exc->pedantic_hinting )
{
- CUR.error = FT_THROW( Invalid_Reference );
+ exc->error = FT_THROW( Invalid_Reference );
return;
}
}
@@ -7684,7 +7236,7 @@
{
C = ( (FT_ULong)B & 0xF0 ) >> 4;
- switch ( CUR.opcode )
+ switch ( exc->opcode )
{
case 0x73:
break;
@@ -7698,22 +7250,22 @@
break;
}
- C += CUR.GS.delta_base;
+ C += exc->GS.delta_base;
if ( P == C )
{
B = ( (FT_ULong)B & 0xF ) - 8;
if ( B >= 0 )
B++;
- B *= 1L << ( 6 - CUR.GS.delta_shift );
+ B *= 1L << ( 6 - exc->GS.delta_shift );
- CUR_Func_move_cvt( A, B );
+ exc->func_move_cvt( exc, A, B );
}
}
}
Fail:
- CUR.new_top = CUR.args;
+ exc->new_top = exc->args;
}
@@ -7730,8 +7282,17 @@
/* Opcode range: 0x88 */
/* Stack: uint32 --> uint32 */
/* */
+ /* XXX: UNDOCUMENTED: Selector bits higher than 9 are currently (May */
+ /* 2015) not documented in the OpenType specification. */
+ /* */
+ /* Selector bit 11 is incorrectly described as bit 8, while the */
+ /* real meaning of bit 8 (vertical LCD subpixels) stays */
+ /* undocumented. The same mistake can be found in Greg Hitchcock's */
+ /* whitepaper. */
+ /* */
static void
- Ins_GETINFO( INS_ARG )
+ Ins_GETINFO( TT_ExecContext exc,
+ FT_Long* args )
{
FT_Long K;
@@ -7744,13 +7305,20 @@
/* Selector Bit: 0 */
/* Return Bit(s): 0-7 */
/* */
- if ( SUBPIXEL_HINTING &&
- ( args[0] & 1 ) != 0 &&
- CUR.ignore_x_mode )
+ if ( SUBPIXEL_HINTING &&
+ ( args[0] & 1 ) != 0 &&
+ exc->subpixel_hinting )
{
- K = CUR.rasterizer_version;
- FT_TRACE7(( "Setting rasterizer version %d\n",
- CUR.rasterizer_version ));
+ if ( exc->ignore_x_mode )
+ {
+ /* if in ClearType backwards compatibility mode, */
+ /* we sometimes change the TrueType version dynamically */
+ K = exc->rasterizer_version;
+ FT_TRACE6(( "Setting rasterizer version %d\n",
+ exc->rasterizer_version ));
+ }
+ else
+ K = TT_INTERPRETER_VERSION_38;
}
else
#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */
@@ -7762,7 +7330,7 @@
/* Selector Bit: 1 */
/* Return Bit(s): 8 */
/* */
- if ( ( args[0] & 2 ) != 0 && CUR.tt_metrics.rotated )
+ if ( ( args[0] & 2 ) != 0 && exc->tt_metrics.rotated )
K |= 0x80;
/********************************/
@@ -7770,7 +7338,7 @@
/* Selector Bit: 2 */
/* Return Bit(s): 9 */
/* */
- if ( ( args[0] & 4 ) != 0 && CUR.tt_metrics.stretched )
+ if ( ( args[0] & 4 ) != 0 && exc->tt_metrics.stretched )
K |= 1 << 8;
/********************************/
@@ -7778,24 +7346,23 @@
/* Selector Bit: 5 */
/* Return Bit(s): 12 */
/* */
- if ( ( args[0] & 32 ) != 0 && CUR.grayscale )
+ if ( ( args[0] & 32 ) != 0 && exc->grayscale )
K |= 1 << 12;
#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
- if ( SUBPIXEL_HINTING &&
- CUR.ignore_x_mode &&
- CUR.rasterizer_version >= TT_INTERPRETER_VERSION_35 )
+ if ( SUBPIXEL_HINTING &&
+ exc->rasterizer_version >= TT_INTERPRETER_VERSION_35 )
{
- if ( CUR.rasterizer_version >= 37 )
+ if ( exc->rasterizer_version >= 37 )
{
/********************************/
/* HINTING FOR SUBPIXEL */
/* Selector Bit: 6 */
/* Return Bit(s): 13 */
/* */
- if ( ( args[0] & 64 ) != 0 && CUR.subpixel )
+ if ( ( args[0] & 64 ) != 0 && exc->subpixel_hinting )
K |= 1 << 13;
/********************************/
@@ -7804,16 +7371,16 @@
/* Return Bit(s): 14 */
/* */
/* Functionality still needs to be added */
- if ( ( args[0] & 128 ) != 0 && CUR.compatible_widths )
+ if ( ( args[0] & 128 ) != 0 && exc->compatible_widths )
K |= 1 << 14;
/********************************/
- /* SYMMETRICAL SMOOTHING */
+ /* VERTICAL LCD SUBPIXELS? */
/* Selector Bit: 8 */
/* Return Bit(s): 15 */
/* */
/* Functionality still needs to be added */
- if ( ( args[0] & 256 ) != 0 && CUR.symmetrical_smoothing )
+ if ( ( args[0] & 256 ) != 0 && exc->vertical_lcd )
K |= 1 << 15;
/********************************/
@@ -7822,10 +7389,10 @@
/* Return Bit(s): 16 */
/* */
/* Functionality still needs to be added */
- if ( ( args[0] & 512 ) != 0 && CUR.bgr )
+ if ( ( args[0] & 512 ) != 0 && exc->bgr )
K |= 1 << 16;
- if ( CUR.rasterizer_version >= 38 )
+ if ( exc->rasterizer_version >= 38 )
{
/********************************/
/* SUBPIXEL POSITIONED? */
@@ -7833,8 +7400,26 @@
/* Return Bit(s): 17 */
/* */
/* Functionality still needs to be added */
- if ( ( args[0] & 1024 ) != 0 && CUR.subpixel_positioned )
+ if ( ( args[0] & 1024 ) != 0 && exc->subpixel_positioned )
K |= 1 << 17;
+
+ /********************************/
+ /* SYMMETRICAL SMOOTHING */
+ /* Selector Bit: 11 */
+ /* Return Bit(s): 18 */
+ /* */
+ /* Functionality still needs to be added */
+ if ( ( args[0] & 2048 ) != 0 && exc->symmetrical_smoothing )
+ K |= 1 << 18;
+
+ /********************************/
+ /* GRAY CLEARTYPE */
+ /* Selector Bit: 12 */
+ /* Return Bit(s): 19 */
+ /* */
+ /* Functionality still needs to be added */
+ if ( ( args[0] & 4096 ) != 0 && exc->gray_cleartype )
+ K |= 1 << 19;
}
}
}
@@ -7846,331 +7431,43 @@
static void
- Ins_UNKNOWN( INS_ARG )
+ Ins_UNKNOWN( TT_ExecContext exc )
{
- TT_DefRecord* def = CUR.IDefs;
- TT_DefRecord* limit = def + CUR.numIDefs;
-
- FT_UNUSED_ARG;
+ TT_DefRecord* def = exc->IDefs;
+ TT_DefRecord* limit = def + exc->numIDefs;
for ( ; def < limit; def++ )
{
- if ( (FT_Byte)def->opc == CUR.opcode && def->active )
+ if ( (FT_Byte)def->opc == exc->opcode && def->active )
{
TT_CallRec* call;
- if ( CUR.callTop >= CUR.callSize )
+ if ( exc->callTop >= exc->callSize )
{
- CUR.error = FT_THROW( Stack_Overflow );
+ exc->error = FT_THROW( Stack_Overflow );
return;
}
- call = CUR.callStack + CUR.callTop++;
+ call = exc->callStack + exc->callTop++;
- call->Caller_Range = CUR.curRange;
- call->Caller_IP = CUR.IP + 1;
+ call->Caller_Range = exc->curRange;
+ call->Caller_IP = exc->IP + 1;
call->Cur_Count = 1;
call->Def = def;
- INS_Goto_CodeRange( def->range, def->start );
+ Ins_Goto_CodeRange( exc, def->range, def->start );
- CUR.step_ins = FALSE;
+ exc->step_ins = FALSE;
return;
}
}
- CUR.error = FT_THROW( Invalid_Opcode );
+ exc->error = FT_THROW( Invalid_Opcode );
}
-#ifndef TT_CONFIG_OPTION_INTERPRETER_SWITCH
-
-
- static
- TInstruction_Function Instruct_Dispatch[256] =
- {
- /* Opcodes are gathered in groups of 16. */
- /* Please keep the spaces as they are. */
-
- /* SVTCA y */ Ins_SVTCA,
- /* SVTCA x */ Ins_SVTCA,
- /* SPvTCA y */ Ins_SPVTCA,
- /* SPvTCA x */ Ins_SPVTCA,
- /* SFvTCA y */ Ins_SFVTCA,
- /* SFvTCA x */ Ins_SFVTCA,
- /* SPvTL // */ Ins_SPVTL,
- /* SPvTL + */ Ins_SPVTL,
- /* SFvTL // */ Ins_SFVTL,
- /* SFvTL + */ Ins_SFVTL,
- /* SPvFS */ Ins_SPVFS,
- /* SFvFS */ Ins_SFVFS,
- /* GPV */ Ins_GPV,
- /* GFV */ Ins_GFV,
- /* SFvTPv */ Ins_SFVTPV,
- /* ISECT */ Ins_ISECT,
-
- /* SRP0 */ Ins_SRP0,
- /* SRP1 */ Ins_SRP1,
- /* SRP2 */ Ins_SRP2,
- /* SZP0 */ Ins_SZP0,
- /* SZP1 */ Ins_SZP1,
- /* SZP2 */ Ins_SZP2,
- /* SZPS */ Ins_SZPS,
- /* SLOOP */ Ins_SLOOP,
- /* RTG */ Ins_RTG,
- /* RTHG */ Ins_RTHG,
- /* SMD */ Ins_SMD,
- /* ELSE */ Ins_ELSE,
- /* JMPR */ Ins_JMPR,
- /* SCvTCi */ Ins_SCVTCI,
- /* SSwCi */ Ins_SSWCI,
- /* SSW */ Ins_SSW,
-
- /* DUP */ Ins_DUP,
- /* POP */ Ins_POP,
- /* CLEAR */ Ins_CLEAR,
- /* SWAP */ Ins_SWAP,
- /* DEPTH */ Ins_DEPTH,
- /* CINDEX */ Ins_CINDEX,
- /* MINDEX */ Ins_MINDEX,
- /* AlignPTS */ Ins_ALIGNPTS,
- /* INS_0x28 */ Ins_UNKNOWN,
- /* UTP */ Ins_UTP,
- /* LOOPCALL */ Ins_LOOPCALL,
- /* CALL */ Ins_CALL,
- /* FDEF */ Ins_FDEF,
- /* ENDF */ Ins_ENDF,
- /* MDAP[0] */ Ins_MDAP,
- /* MDAP[1] */ Ins_MDAP,
-
- /* IUP[0] */ Ins_IUP,
- /* IUP[1] */ Ins_IUP,
- /* SHP[0] */ Ins_SHP,
- /* SHP[1] */ Ins_SHP,
- /* SHC[0] */ Ins_SHC,
- /* SHC[1] */ Ins_SHC,
- /* SHZ[0] */ Ins_SHZ,
- /* SHZ[1] */ Ins_SHZ,
- /* SHPIX */ Ins_SHPIX,
- /* IP */ Ins_IP,
- /* MSIRP[0] */ Ins_MSIRP,
- /* MSIRP[1] */ Ins_MSIRP,
- /* AlignRP */ Ins_ALIGNRP,
- /* RTDG */ Ins_RTDG,
- /* MIAP[0] */ Ins_MIAP,
- /* MIAP[1] */ Ins_MIAP,
-
- /* NPushB */ Ins_NPUSHB,
- /* NPushW */ Ins_NPUSHW,
- /* WS */ Ins_WS,
- /* RS */ Ins_RS,
- /* WCvtP */ Ins_WCVTP,
- /* RCvt */ Ins_RCVT,
- /* GC[0] */ Ins_GC,
- /* GC[1] */ Ins_GC,
- /* SCFS */ Ins_SCFS,
- /* MD[0] */ Ins_MD,
- /* MD[1] */ Ins_MD,
- /* MPPEM */ Ins_MPPEM,
- /* MPS */ Ins_MPS,
- /* FlipON */ Ins_FLIPON,
- /* FlipOFF */ Ins_FLIPOFF,
- /* DEBUG */ Ins_DEBUG,
-
- /* LT */ Ins_LT,
- /* LTEQ */ Ins_LTEQ,
- /* GT */ Ins_GT,
- /* GTEQ */ Ins_GTEQ,
- /* EQ */ Ins_EQ,
- /* NEQ */ Ins_NEQ,
- /* ODD */ Ins_ODD,
- /* EVEN */ Ins_EVEN,
- /* IF */ Ins_IF,
- /* EIF */ Ins_EIF,
- /* AND */ Ins_AND,
- /* OR */ Ins_OR,
- /* NOT */ Ins_NOT,
- /* DeltaP1 */ Ins_DELTAP,
- /* SDB */ Ins_SDB,
- /* SDS */ Ins_SDS,
-
- /* ADD */ Ins_ADD,
- /* SUB */ Ins_SUB,
- /* DIV */ Ins_DIV,
- /* MUL */ Ins_MUL,
- /* ABS */ Ins_ABS,
- /* NEG */ Ins_NEG,
- /* FLOOR */ Ins_FLOOR,
- /* CEILING */ Ins_CEILING,
- /* ROUND[0] */ Ins_ROUND,
- /* ROUND[1] */ Ins_ROUND,
- /* ROUND[2] */ Ins_ROUND,
- /* ROUND[3] */ Ins_ROUND,
- /* NROUND[0] */ Ins_NROUND,
- /* NROUND[1] */ Ins_NROUND,
- /* NROUND[2] */ Ins_NROUND,
- /* NROUND[3] */ Ins_NROUND,
-
- /* WCvtF */ Ins_WCVTF,
- /* DeltaP2 */ Ins_DELTAP,
- /* DeltaP3 */ Ins_DELTAP,
- /* DeltaCn[0] */ Ins_DELTAC,
- /* DeltaCn[1] */ Ins_DELTAC,
- /* DeltaCn[2] */ Ins_DELTAC,
- /* SROUND */ Ins_SROUND,
- /* S45Round */ Ins_S45ROUND,
- /* JROT */ Ins_JROT,
- /* JROF */ Ins_JROF,
- /* ROFF */ Ins_ROFF,
- /* INS_0x7B */ Ins_UNKNOWN,
- /* RUTG */ Ins_RUTG,
- /* RDTG */ Ins_RDTG,
- /* SANGW */ Ins_SANGW,
- /* AA */ Ins_AA,
-
- /* FlipPT */ Ins_FLIPPT,
- /* FlipRgON */ Ins_FLIPRGON,
- /* FlipRgOFF */ Ins_FLIPRGOFF,
- /* INS_0x83 */ Ins_UNKNOWN,
- /* INS_0x84 */ Ins_UNKNOWN,
- /* ScanCTRL */ Ins_SCANCTRL,
- /* SDPVTL[0] */ Ins_SDPVTL,
- /* SDPVTL[1] */ Ins_SDPVTL,
- /* GetINFO */ Ins_GETINFO,
- /* IDEF */ Ins_IDEF,
- /* ROLL */ Ins_ROLL,
- /* MAX */ Ins_MAX,
- /* MIN */ Ins_MIN,
- /* ScanTYPE */ Ins_SCANTYPE,
- /* InstCTRL */ Ins_INSTCTRL,
- /* INS_0x8F */ Ins_UNKNOWN,
-
- /* INS_0x90 */ Ins_UNKNOWN,
- /* INS_0x91 */ Ins_UNKNOWN,
- /* INS_0x92 */ Ins_UNKNOWN,
- /* INS_0x93 */ Ins_UNKNOWN,
- /* INS_0x94 */ Ins_UNKNOWN,
- /* INS_0x95 */ Ins_UNKNOWN,
- /* INS_0x96 */ Ins_UNKNOWN,
- /* INS_0x97 */ Ins_UNKNOWN,
- /* INS_0x98 */ Ins_UNKNOWN,
- /* INS_0x99 */ Ins_UNKNOWN,
- /* INS_0x9A */ Ins_UNKNOWN,
- /* INS_0x9B */ Ins_UNKNOWN,
- /* INS_0x9C */ Ins_UNKNOWN,
- /* INS_0x9D */ Ins_UNKNOWN,
- /* INS_0x9E */ Ins_UNKNOWN,
- /* INS_0x9F */ Ins_UNKNOWN,
-
- /* INS_0xA0 */ Ins_UNKNOWN,
- /* INS_0xA1 */ Ins_UNKNOWN,
- /* INS_0xA2 */ Ins_UNKNOWN,
- /* INS_0xA3 */ Ins_UNKNOWN,
- /* INS_0xA4 */ Ins_UNKNOWN,
- /* INS_0xA5 */ Ins_UNKNOWN,
- /* INS_0xA6 */ Ins_UNKNOWN,
- /* INS_0xA7 */ Ins_UNKNOWN,
- /* INS_0xA8 */ Ins_UNKNOWN,
- /* INS_0xA9 */ Ins_UNKNOWN,
- /* INS_0xAA */ Ins_UNKNOWN,
- /* INS_0xAB */ Ins_UNKNOWN,
- /* INS_0xAC */ Ins_UNKNOWN,
- /* INS_0xAD */ Ins_UNKNOWN,
- /* INS_0xAE */ Ins_UNKNOWN,
- /* INS_0xAF */ Ins_UNKNOWN,
-
- /* PushB[0] */ Ins_PUSHB,
- /* PushB[1] */ Ins_PUSHB,
- /* PushB[2] */ Ins_PUSHB,
- /* PushB[3] */ Ins_PUSHB,
- /* PushB[4] */ Ins_PUSHB,
- /* PushB[5] */ Ins_PUSHB,
- /* PushB[6] */ Ins_PUSHB,
- /* PushB[7] */ Ins_PUSHB,
- /* PushW[0] */ Ins_PUSHW,
- /* PushW[1] */ Ins_PUSHW,
- /* PushW[2] */ Ins_PUSHW,
- /* PushW[3] */ Ins_PUSHW,
- /* PushW[4] */ Ins_PUSHW,
- /* PushW[5] */ Ins_PUSHW,
- /* PushW[6] */ Ins_PUSHW,
- /* PushW[7] */ Ins_PUSHW,
-
- /* MDRP[00] */ Ins_MDRP,
- /* MDRP[01] */ Ins_MDRP,
- /* MDRP[02] */ Ins_MDRP,
- /* MDRP[03] */ Ins_MDRP,
- /* MDRP[04] */ Ins_MDRP,
- /* MDRP[05] */ Ins_MDRP,
- /* MDRP[06] */ Ins_MDRP,
- /* MDRP[07] */ Ins_MDRP,
- /* MDRP[08] */ Ins_MDRP,
- /* MDRP[09] */ Ins_MDRP,
- /* MDRP[10] */ Ins_MDRP,
- /* MDRP[11] */ Ins_MDRP,
- /* MDRP[12] */ Ins_MDRP,
- /* MDRP[13] */ Ins_MDRP,
- /* MDRP[14] */ Ins_MDRP,
- /* MDRP[15] */ Ins_MDRP,
-
- /* MDRP[16] */ Ins_MDRP,
- /* MDRP[17] */ Ins_MDRP,
- /* MDRP[18] */ Ins_MDRP,
- /* MDRP[19] */ Ins_MDRP,
- /* MDRP[20] */ Ins_MDRP,
- /* MDRP[21] */ Ins_MDRP,
- /* MDRP[22] */ Ins_MDRP,
- /* MDRP[23] */ Ins_MDRP,
- /* MDRP[24] */ Ins_MDRP,
- /* MDRP[25] */ Ins_MDRP,
- /* MDRP[26] */ Ins_MDRP,
- /* MDRP[27] */ Ins_MDRP,
- /* MDRP[28] */ Ins_MDRP,
- /* MDRP[29] */ Ins_MDRP,
- /* MDRP[30] */ Ins_MDRP,
- /* MDRP[31] */ Ins_MDRP,
-
- /* MIRP[00] */ Ins_MIRP,
- /* MIRP[01] */ Ins_MIRP,
- /* MIRP[02] */ Ins_MIRP,
- /* MIRP[03] */ Ins_MIRP,
- /* MIRP[04] */ Ins_MIRP,
- /* MIRP[05] */ Ins_MIRP,
- /* MIRP[06] */ Ins_MIRP,
- /* MIRP[07] */ Ins_MIRP,
- /* MIRP[08] */ Ins_MIRP,
- /* MIRP[09] */ Ins_MIRP,
- /* MIRP[10] */ Ins_MIRP,
- /* MIRP[11] */ Ins_MIRP,
- /* MIRP[12] */ Ins_MIRP,
- /* MIRP[13] */ Ins_MIRP,
- /* MIRP[14] */ Ins_MIRP,
- /* MIRP[15] */ Ins_MIRP,
-
- /* MIRP[16] */ Ins_MIRP,
- /* MIRP[17] */ Ins_MIRP,
- /* MIRP[18] */ Ins_MIRP,
- /* MIRP[19] */ Ins_MIRP,
- /* MIRP[20] */ Ins_MIRP,
- /* MIRP[21] */ Ins_MIRP,
- /* MIRP[22] */ Ins_MIRP,
- /* MIRP[23] */ Ins_MIRP,
- /* MIRP[24] */ Ins_MIRP,
- /* MIRP[25] */ Ins_MIRP,
- /* MIRP[26] */ Ins_MIRP,
- /* MIRP[27] */ Ins_MIRP,
- /* MIRP[28] */ Ins_MIRP,
- /* MIRP[29] */ Ins_MIRP,
- /* MIRP[30] */ Ins_MIRP,
- /* MIRP[31] */ Ins_MIRP
- };
-
-
-#endif /* !TT_CONFIG_OPTION_INTERPRETER_SWITCH */
-
-
/*************************************************************************/
/* */
/* RUN */
@@ -8198,8 +7495,6 @@
/* */
/* THIS IS THE INTERPRETER'S MAIN LOOP. */
/* */
- /* Instructions appear in the specification's order. */
- /* */
/*************************************************************************/
@@ -8225,90 +7520,100 @@
#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */
-#ifdef TT_CONFIG_OPTION_STATIC_RASTER
- if ( !exc )
- return FT_THROW( Invalid_Argument );
-
- cur = *exc;
-#endif
-
#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
- CUR.iup_called = FALSE;
+ exc->iup_called = FALSE;
#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */
/* set PPEM and CVT functions */
- CUR.tt_metrics.ratio = 0;
- if ( CUR.metrics.x_ppem != CUR.metrics.y_ppem )
+ exc->tt_metrics.ratio = 0;
+ if ( exc->metrics.x_ppem != exc->metrics.y_ppem )
{
/* non-square pixels, use the stretched routines */
- CUR.func_cur_ppem = Current_Ppem_Stretched;
- CUR.func_read_cvt = Read_CVT_Stretched;
- CUR.func_write_cvt = Write_CVT_Stretched;
- CUR.func_move_cvt = Move_CVT_Stretched;
+ exc->func_cur_ppem = Current_Ppem_Stretched;
+ exc->func_read_cvt = Read_CVT_Stretched;
+ exc->func_write_cvt = Write_CVT_Stretched;
+ exc->func_move_cvt = Move_CVT_Stretched;
}
else
{
/* square pixels, use normal routines */
- CUR.func_cur_ppem = Current_Ppem;
- CUR.func_read_cvt = Read_CVT;
- CUR.func_write_cvt = Write_CVT;
- CUR.func_move_cvt = Move_CVT;
+ exc->func_cur_ppem = Current_Ppem;
+ exc->func_read_cvt = Read_CVT;
+ exc->func_write_cvt = Write_CVT;
+ exc->func_move_cvt = Move_CVT;
}
- COMPUTE_Funcs();
- COMPUTE_Round( (FT_Byte)exc->GS.round_state );
+ Compute_Funcs( exc );
+ Compute_Round( exc, (FT_Byte)exc->GS.round_state );
do
{
- CUR.opcode = CUR.code[CUR.IP];
+ exc->opcode = exc->code[exc->IP];
- FT_TRACE7(( " " ));
- FT_TRACE7(( opcode_name[CUR.opcode] ));
- FT_TRACE7(( "\n" ));
+#ifdef FT_DEBUG_LEVEL_TRACE
+ {
+ FT_Long cnt = FT_MIN( 8, exc->top );
+ FT_Long n;
+
+
+ /* if tracing level is 7, show current code position */
+ /* and the first few stack elements also */
+ FT_TRACE6(( " " ));
+ FT_TRACE7(( "%06d ", exc->IP ));
+ FT_TRACE6(( opcode_name[exc->opcode] + 2 ));
+ FT_TRACE7(( "%*s", *opcode_name[exc->opcode] == 'A'
+ ? 2
+ : 12 - ( *opcode_name[exc->opcode] - '0' ),
+ "#" ));
+ for ( n = 0; n < cnt; n++ )
+ FT_TRACE7(( " %d", exc->stack[exc->top - n] ));
+ FT_TRACE6(( "\n" ));
+ }
+#endif /* FT_DEBUG_LEVEL_TRACE */
- if ( ( CUR.length = opcode_length[CUR.opcode] ) < 0 )
+ if ( ( exc->length = opcode_length[exc->opcode] ) < 0 )
{
- if ( CUR.IP + 1 >= CUR.codeSize )
+ if ( exc->IP + 1 >= exc->codeSize )
goto LErrorCodeOverflow_;
- CUR.length = 2 - CUR.length * CUR.code[CUR.IP + 1];
+ exc->length = 2 - exc->length * exc->code[exc->IP + 1];
}
- if ( CUR.IP + CUR.length > CUR.codeSize )
+ if ( exc->IP + exc->length > exc->codeSize )
goto LErrorCodeOverflow_;
/* First, let's check for empty stack and overflow */
- CUR.args = CUR.top - ( Pop_Push_Count[CUR.opcode] >> 4 );
+ exc->args = exc->top - ( Pop_Push_Count[exc->opcode] >> 4 );
/* `args' is the top of the stack once arguments have been popped. */
/* One can also interpret it as the index of the last argument. */
- if ( CUR.args < 0 )
+ if ( exc->args < 0 )
{
- if ( CUR.pedantic_hinting )
+ if ( exc->pedantic_hinting )
{
- CUR.error = FT_THROW( Too_Few_Arguments );
+ exc->error = FT_THROW( Too_Few_Arguments );
goto LErrorLabel_;
}
/* push zeroes onto the stack */
- for ( i = 0; i < Pop_Push_Count[CUR.opcode] >> 4; i++ )
- CUR.stack[i] = 0;
- CUR.args = 0;
+ for ( i = 0; i < Pop_Push_Count[exc->opcode] >> 4; i++ )
+ exc->stack[i] = 0;
+ exc->args = 0;
}
- CUR.new_top = CUR.args + ( Pop_Push_Count[CUR.opcode] & 15 );
+ exc->new_top = exc->args + ( Pop_Push_Count[exc->opcode] & 15 );
/* `new_top' is the new top of the stack, after the instruction's */
/* execution. `top' will be set to `new_top' after the `switch' */
/* statement. */
- if ( CUR.new_top > CUR.stackSize )
+ if ( exc->new_top > exc->stackSize )
{
- CUR.error = FT_THROW( Stack_Overflow );
+ exc->error = FT_THROW( Stack_Overflow );
goto LErrorLabel_;
}
- CUR.step_ins = TRUE;
- CUR.error = FT_Err_Ok;
+ exc->step_ins = TRUE;
+ exc->error = FT_Err_Ok;
#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
@@ -8316,17 +7621,17 @@
{
for ( i = 0; i < opcode_patterns; i++ )
{
- if ( opcode_pointer[i] < opcode_size[i] &&
- CUR.opcode == opcode_pattern[i][opcode_pointer[i]] )
+ if ( opcode_pointer[i] < opcode_size[i] &&
+ exc->opcode == opcode_pattern[i][opcode_pointer[i]] )
{
opcode_pointer[i] += 1;
if ( opcode_pointer[i] == opcode_size[i] )
{
- FT_TRACE7(( "sph: opcode ptrn: %d, %s %s\n",
+ FT_TRACE6(( "sph: opcode ptrn: %d, %s %s\n",
i,
- CUR.face->root.family_name,
- CUR.face->root.style_name ));
+ exc->face->root.family_name,
+ exc->face->root.style_name ));
switch ( i )
{
@@ -8343,15 +7648,9 @@
#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */
-#ifdef TT_CONFIG_OPTION_INTERPRETER_SWITCH
-
{
- FT_Long* args = CUR.stack + CUR.args;
- FT_Byte opcode = CUR.opcode;
-
-
-#undef ARRAY_BOUND_ERROR
-#define ARRAY_BOUND_ERROR goto Set_Invalid_Ref
+ FT_Long* args = exc->stack + exc->args;
+ FT_Byte opcode = exc->opcode;
switch ( opcode )
@@ -8362,580 +7661,543 @@
case 0x03: /* SPvTCA x */
case 0x04: /* SFvTCA y */
case 0x05: /* SFvTCA x */
- {
- FT_Short AA, BB;
-
-
- AA = (FT_Short)( ( opcode & 1 ) << 14 );
- BB = (FT_Short)( AA ^ 0x4000 );
-
- if ( opcode < 4 )
- {
- CUR.GS.projVector.x = AA;
- CUR.GS.projVector.y = BB;
-
- CUR.GS.dualVector.x = AA;
- CUR.GS.dualVector.y = BB;
- }
- else
- {
- GUESS_VECTOR( projVector );
- }
-
- if ( ( opcode & 2 ) == 0 )
- {
- CUR.GS.freeVector.x = AA;
- CUR.GS.freeVector.y = BB;
- }
- else
- {
- GUESS_VECTOR( freeVector );
- }
-
- COMPUTE_Funcs();
- }
+ Ins_SxyTCA( exc );
break;
case 0x06: /* SPvTL // */
case 0x07: /* SPvTL + */
- DO_SPVTL
+ Ins_SPVTL( exc, args );
break;
case 0x08: /* SFvTL // */
case 0x09: /* SFvTL + */
- DO_SFVTL
+ Ins_SFVTL( exc, args );
break;
case 0x0A: /* SPvFS */
- DO_SPVFS
+ Ins_SPVFS( exc, args );
break;
case 0x0B: /* SFvFS */
- DO_SFVFS
+ Ins_SFVFS( exc, args );
break;
- case 0x0C: /* GPV */
- DO_GPV
+ case 0x0C: /* GPv */
+ Ins_GPV( exc, args );
break;
- case 0x0D: /* GFV */
- DO_GFV
+ case 0x0D: /* GFv */
+ Ins_GFV( exc, args );
break;
case 0x0E: /* SFvTPv */
- DO_SFVTPV
+ Ins_SFVTPV( exc );
break;
case 0x0F: /* ISECT */
- Ins_ISECT( EXEC_ARG_ args );
+ Ins_ISECT( exc, args );
break;
case 0x10: /* SRP0 */
- DO_SRP0
+ Ins_SRP0( exc, args );
break;
case 0x11: /* SRP1 */
- DO_SRP1
+ Ins_SRP1( exc, args );
break;
case 0x12: /* SRP2 */
- DO_SRP2
+ Ins_SRP2( exc, args );
break;
case 0x13: /* SZP0 */
- Ins_SZP0( EXEC_ARG_ args );
+ Ins_SZP0( exc, args );
break;
case 0x14: /* SZP1 */
- Ins_SZP1( EXEC_ARG_ args );
+ Ins_SZP1( exc, args );
break;
case 0x15: /* SZP2 */
- Ins_SZP2( EXEC_ARG_ args );
+ Ins_SZP2( exc, args );
break;
case 0x16: /* SZPS */
- Ins_SZPS( EXEC_ARG_ args );
+ Ins_SZPS( exc, args );
break;
case 0x17: /* SLOOP */
- DO_SLOOP
+ Ins_SLOOP( exc, args );
break;
case 0x18: /* RTG */
- DO_RTG
+ Ins_RTG( exc );
break;
case 0x19: /* RTHG */
- DO_RTHG
+ Ins_RTHG( exc );
break;
case 0x1A: /* SMD */
- DO_SMD
+ Ins_SMD( exc, args );
break;
case 0x1B: /* ELSE */
- Ins_ELSE( EXEC_ARG_ args );
+ Ins_ELSE( exc );
break;
case 0x1C: /* JMPR */
- DO_JMPR
+ Ins_JMPR( exc, args );
break;
case 0x1D: /* SCVTCI */
- DO_SCVTCI
+ Ins_SCVTCI( exc, args );
break;
case 0x1E: /* SSWCI */
- DO_SSWCI
+ Ins_SSWCI( exc, args );
break;
case 0x1F: /* SSW */
- DO_SSW
+ Ins_SSW( exc, args );
break;
case 0x20: /* DUP */
- DO_DUP
+ Ins_DUP( args );
break;
case 0x21: /* POP */
- /* nothing :-) */
+ Ins_POP();
break;
case 0x22: /* CLEAR */
- DO_CLEAR
+ Ins_CLEAR( exc );
break;
case 0x23: /* SWAP */
- DO_SWAP
+ Ins_SWAP( args );
break;
case 0x24: /* DEPTH */
- DO_DEPTH
+ Ins_DEPTH( exc, args );
break;
case 0x25: /* CINDEX */
- DO_CINDEX
+ Ins_CINDEX( exc, args );
break;
case 0x26: /* MINDEX */
- Ins_MINDEX( EXEC_ARG_ args );
+ Ins_MINDEX( exc, args );
break;
case 0x27: /* ALIGNPTS */
- Ins_ALIGNPTS( EXEC_ARG_ args );
+ Ins_ALIGNPTS( exc, args );
break;
case 0x28: /* ???? */
- Ins_UNKNOWN( EXEC_ARG_ args );
+ Ins_UNKNOWN( exc );
break;
case 0x29: /* UTP */
- Ins_UTP( EXEC_ARG_ args );
+ Ins_UTP( exc, args );
break;
case 0x2A: /* LOOPCALL */
- Ins_LOOPCALL( EXEC_ARG_ args );
+ Ins_LOOPCALL( exc, args );
break;
case 0x2B: /* CALL */
- Ins_CALL( EXEC_ARG_ args );
+ Ins_CALL( exc, args );
break;
case 0x2C: /* FDEF */
- Ins_FDEF( EXEC_ARG_ args );
+ Ins_FDEF( exc, args );
break;
case 0x2D: /* ENDF */
- Ins_ENDF( EXEC_ARG_ args );
+ Ins_ENDF( exc );
break;
case 0x2E: /* MDAP */
case 0x2F: /* MDAP */
- Ins_MDAP( EXEC_ARG_ args );
+ Ins_MDAP( exc, args );
break;
case 0x30: /* IUP */
case 0x31: /* IUP */
- Ins_IUP( EXEC_ARG_ args );
+ Ins_IUP( exc );
break;
case 0x32: /* SHP */
case 0x33: /* SHP */
- Ins_SHP( EXEC_ARG_ args );
+ Ins_SHP( exc );
break;
case 0x34: /* SHC */
case 0x35: /* SHC */
- Ins_SHC( EXEC_ARG_ args );
+ Ins_SHC( exc, args );
break;
case 0x36: /* SHZ */
case 0x37: /* SHZ */
- Ins_SHZ( EXEC_ARG_ args );
+ Ins_SHZ( exc, args );
break;
case 0x38: /* SHPIX */
- Ins_SHPIX( EXEC_ARG_ args );
+ Ins_SHPIX( exc, args );
break;
case 0x39: /* IP */
- Ins_IP( EXEC_ARG_ args );
+ Ins_IP( exc );
break;
case 0x3A: /* MSIRP */
case 0x3B: /* MSIRP */
- Ins_MSIRP( EXEC_ARG_ args );
+ Ins_MSIRP( exc, args );
break;
case 0x3C: /* AlignRP */
- Ins_ALIGNRP( EXEC_ARG_ args );
+ Ins_ALIGNRP( exc );
break;
case 0x3D: /* RTDG */
- DO_RTDG
+ Ins_RTDG( exc );
break;
case 0x3E: /* MIAP */
case 0x3F: /* MIAP */
- Ins_MIAP( EXEC_ARG_ args );
+ Ins_MIAP( exc, args );
break;
case 0x40: /* NPUSHB */
- Ins_NPUSHB( EXEC_ARG_ args );
+ Ins_NPUSHB( exc, args );
break;
case 0x41: /* NPUSHW */
- Ins_NPUSHW( EXEC_ARG_ args );
+ Ins_NPUSHW( exc, args );
break;
case 0x42: /* WS */
- DO_WS
- break;
-
- Set_Invalid_Ref:
- CUR.error = FT_THROW( Invalid_Reference );
+ Ins_WS( exc, args );
break;
case 0x43: /* RS */
- DO_RS
+ Ins_RS( exc, args );
break;
case 0x44: /* WCVTP */
- DO_WCVTP
+ Ins_WCVTP( exc, args );
break;
case 0x45: /* RCVT */
- DO_RCVT
+ Ins_RCVT( exc, args );
break;
case 0x46: /* GC */
case 0x47: /* GC */
- Ins_GC( EXEC_ARG_ args );
+ Ins_GC( exc, args );
break;
case 0x48: /* SCFS */
- Ins_SCFS( EXEC_ARG_ args );
+ Ins_SCFS( exc, args );
break;
case 0x49: /* MD */
case 0x4A: /* MD */
- Ins_MD( EXEC_ARG_ args );
+ Ins_MD( exc, args );
break;
case 0x4B: /* MPPEM */
- DO_MPPEM
+ Ins_MPPEM( exc, args );
break;
case 0x4C: /* MPS */
- DO_MPS
+ Ins_MPS( exc, args );
break;
case 0x4D: /* FLIPON */
- DO_FLIPON
+ Ins_FLIPON( exc );
break;
case 0x4E: /* FLIPOFF */
- DO_FLIPOFF
+ Ins_FLIPOFF( exc );
break;
case 0x4F: /* DEBUG */
- DO_DEBUG
+ Ins_DEBUG( exc );
break;
case 0x50: /* LT */
- DO_LT
+ Ins_LT( args );
break;
case 0x51: /* LTEQ */
- DO_LTEQ
+ Ins_LTEQ( args );
break;
case 0x52: /* GT */
- DO_GT
+ Ins_GT( args );
break;
case 0x53: /* GTEQ */
- DO_GTEQ
+ Ins_GTEQ( args );
break;
case 0x54: /* EQ */
- DO_EQ
+ Ins_EQ( args );
break;
case 0x55: /* NEQ */
- DO_NEQ
+ Ins_NEQ( args );
break;
case 0x56: /* ODD */
- DO_ODD
+ Ins_ODD( exc, args );
break;
case 0x57: /* EVEN */
- DO_EVEN
+ Ins_EVEN( exc, args );
break;
case 0x58: /* IF */
- Ins_IF( EXEC_ARG_ args );
+ Ins_IF( exc, args );
break;
case 0x59: /* EIF */
- /* do nothing */
+ Ins_EIF();
break;
case 0x5A: /* AND */
- DO_AND
+ Ins_AND( args );
break;
case 0x5B: /* OR */
- DO_OR
+ Ins_OR( args );
break;
case 0x5C: /* NOT */
- DO_NOT
+ Ins_NOT( args );
break;
case 0x5D: /* DELTAP1 */
- Ins_DELTAP( EXEC_ARG_ args );
+ Ins_DELTAP( exc, args );
break;
case 0x5E: /* SDB */
- DO_SDB
+ Ins_SDB( exc, args );
break;
case 0x5F: /* SDS */
- DO_SDS
+ Ins_SDS( exc, args );
break;
case 0x60: /* ADD */
- DO_ADD
+ Ins_ADD( args );
break;
case 0x61: /* SUB */
- DO_SUB
+ Ins_SUB( args );
break;
case 0x62: /* DIV */
- DO_DIV
+ Ins_DIV( exc, args );
break;
case 0x63: /* MUL */
- DO_MUL
+ Ins_MUL( args );
break;
case 0x64: /* ABS */
- DO_ABS
+ Ins_ABS( args );
break;
case 0x65: /* NEG */
- DO_NEG
+ Ins_NEG( args );
break;
case 0x66: /* FLOOR */
- DO_FLOOR
+ Ins_FLOOR( args );
break;
case 0x67: /* CEILING */
- DO_CEILING
+ Ins_CEILING( args );
break;
case 0x68: /* ROUND */
case 0x69: /* ROUND */
case 0x6A: /* ROUND */
case 0x6B: /* ROUND */
- DO_ROUND
+ Ins_ROUND( exc, args );
break;
case 0x6C: /* NROUND */
case 0x6D: /* NROUND */
case 0x6E: /* NRRUND */
case 0x6F: /* NROUND */
- DO_NROUND
+ Ins_NROUND( exc, args );
break;
case 0x70: /* WCVTF */
- DO_WCVTF
+ Ins_WCVTF( exc, args );
break;
case 0x71: /* DELTAP2 */
case 0x72: /* DELTAP3 */
- Ins_DELTAP( EXEC_ARG_ args );
+ Ins_DELTAP( exc, args );
break;
case 0x73: /* DELTAC0 */
case 0x74: /* DELTAC1 */
case 0x75: /* DELTAC2 */
- Ins_DELTAC( EXEC_ARG_ args );
+ Ins_DELTAC( exc, args );
break;
case 0x76: /* SROUND */
- DO_SROUND
+ Ins_SROUND( exc, args );
break;
case 0x77: /* S45Round */
- DO_S45ROUND
+ Ins_S45ROUND( exc, args );
break;
case 0x78: /* JROT */
- DO_JROT
+ Ins_JROT( exc, args );
break;
case 0x79: /* JROF */
- DO_JROF
+ Ins_JROF( exc, args );
break;
case 0x7A: /* ROFF */
- DO_ROFF
+ Ins_ROFF( exc );
break;
case 0x7B: /* ???? */
- Ins_UNKNOWN( EXEC_ARG_ args );
+ Ins_UNKNOWN( exc );
break;
case 0x7C: /* RUTG */
- DO_RUTG
+ Ins_RUTG( exc );
break;
case 0x7D: /* RDTG */
- DO_RDTG
+ Ins_RDTG( exc );
break;
case 0x7E: /* SANGW */
- case 0x7F: /* AA */
- /* nothing - obsolete */
+ Ins_SANGW();
+ break;
+
+ case 0x7F: /* AA */
+ Ins_AA();
break;
case 0x80: /* FLIPPT */
- Ins_FLIPPT( EXEC_ARG_ args );
+ Ins_FLIPPT( exc );
break;
case 0x81: /* FLIPRGON */
- Ins_FLIPRGON( EXEC_ARG_ args );
+ Ins_FLIPRGON( exc, args );
break;
case 0x82: /* FLIPRGOFF */
- Ins_FLIPRGOFF( EXEC_ARG_ args );
+ Ins_FLIPRGOFF( exc, args );
break;
case 0x83: /* UNKNOWN */
case 0x84: /* UNKNOWN */
- Ins_UNKNOWN( EXEC_ARG_ args );
+ Ins_UNKNOWN( exc );
break;
case 0x85: /* SCANCTRL */
- Ins_SCANCTRL( EXEC_ARG_ args );
+ Ins_SCANCTRL( exc, args );
break;
- case 0x86: /* SDPVTL */
- case 0x87: /* SDPVTL */
- Ins_SDPVTL( EXEC_ARG_ args );
+ case 0x86: /* SDPvTL */
+ case 0x87: /* SDPvTL */
+ Ins_SDPVTL( exc, args );
break;
case 0x88: /* GETINFO */
- Ins_GETINFO( EXEC_ARG_ args );
+ Ins_GETINFO( exc, args );
break;
case 0x89: /* IDEF */
- Ins_IDEF( EXEC_ARG_ args );
+ Ins_IDEF( exc, args );
break;
case 0x8A: /* ROLL */
- Ins_ROLL( EXEC_ARG_ args );
+ Ins_ROLL( args );
break;
case 0x8B: /* MAX */
- DO_MAX
+ Ins_MAX( args );
break;
case 0x8C: /* MIN */
- DO_MIN
+ Ins_MIN( args );
break;
case 0x8D: /* SCANTYPE */
- Ins_SCANTYPE( EXEC_ARG_ args );
+ Ins_SCANTYPE( exc, args );
break;
case 0x8E: /* INSTCTRL */
- Ins_INSTCTRL( EXEC_ARG_ args );
+ Ins_INSTCTRL( exc, args );
break;
case 0x8F:
- Ins_UNKNOWN( EXEC_ARG_ args );
+ Ins_UNKNOWN( exc );
break;
default:
if ( opcode >= 0xE0 )
- Ins_MIRP( EXEC_ARG_ args );
+ Ins_MIRP( exc, args );
else if ( opcode >= 0xC0 )
- Ins_MDRP( EXEC_ARG_ args );
+ Ins_MDRP( exc, args );
else if ( opcode >= 0xB8 )
- Ins_PUSHW( EXEC_ARG_ args );
+ Ins_PUSHW( exc, args );
else if ( opcode >= 0xB0 )
- Ins_PUSHB( EXEC_ARG_ args );
+ Ins_PUSHB( exc, args );
else
- Ins_UNKNOWN( EXEC_ARG_ args );
+ Ins_UNKNOWN( exc );
}
-
}
-#else
-
- Instruct_Dispatch[CUR.opcode]( EXEC_ARG_ &CUR.stack[CUR.args] );
-
-#endif /* TT_CONFIG_OPTION_INTERPRETER_SWITCH */
-
- if ( CUR.error )
+ if ( exc->error )
{
- switch ( CUR.error )
+ switch ( exc->error )
{
/* looking for redefined instructions */
case FT_ERR( Invalid_Opcode ):
{
- TT_DefRecord* def = CUR.IDefs;
- TT_DefRecord* limit = def + CUR.numIDefs;
+ TT_DefRecord* def = exc->IDefs;
+ TT_DefRecord* limit = def + exc->numIDefs;
for ( ; def < limit; def++ )
{
- if ( def->active && CUR.opcode == (FT_Byte)def->opc )
+ if ( def->active && exc->opcode == (FT_Byte)def->opc )
{
TT_CallRec* callrec;
- if ( CUR.callTop >= CUR.callSize )
+ if ( exc->callTop >= exc->callSize )
{
- CUR.error = FT_THROW( Invalid_Reference );
+ exc->error = FT_THROW( Invalid_Reference );
goto LErrorLabel_;
}
- callrec = &CUR.callStack[CUR.callTop];
+ callrec = &exc->callStack[exc->callTop];
- callrec->Caller_Range = CUR.curRange;
- callrec->Caller_IP = CUR.IP + 1;
+ callrec->Caller_Range = exc->curRange;
+ callrec->Caller_IP = exc->IP + 1;
callrec->Cur_Count = 1;
callrec->Def = def;
- if ( INS_Goto_CodeRange( def->range, def->start ) == FAILURE )
+ if ( Ins_Goto_CodeRange( exc,
+ def->range,
+ def->start ) == FAILURE )
goto LErrorLabel_;
goto LSuiteLabel_;
@@ -8943,7 +8205,7 @@
}
}
- CUR.error = FT_THROW( Invalid_Opcode );
+ exc->error = FT_THROW( Invalid_Opcode );
goto LErrorLabel_;
#if 0
@@ -8961,10 +8223,10 @@
}
}
- CUR.top = CUR.new_top;
+ exc->top = exc->new_top;
- if ( CUR.step_ins )
- CUR.IP += CUR.length;
+ if ( exc->step_ins )
+ exc->IP += exc->length;
/* increment instruction counter and check if we didn't */
/* run this program for too long (e.g. infinite loops). */
@@ -8972,48 +8234,38 @@
return FT_THROW( Execution_Too_Long );
LSuiteLabel_:
- if ( CUR.IP >= CUR.codeSize )
+ if ( exc->IP >= exc->codeSize )
{
- if ( CUR.callTop > 0 )
+ if ( exc->callTop > 0 )
{
- CUR.error = FT_THROW( Code_Overflow );
+ exc->error = FT_THROW( Code_Overflow );
goto LErrorLabel_;
}
else
goto LNo_Error_;
}
- } while ( !CUR.instruction_trap );
+ } while ( !exc->instruction_trap );
LNo_Error_:
-
-#ifdef TT_CONFIG_OPTION_STATIC_RASTER
- *exc = cur;
-#endif
-
return FT_Err_Ok;
LErrorCodeOverflow_:
- CUR.error = FT_THROW( Code_Overflow );
+ exc->error = FT_THROW( Code_Overflow );
LErrorLabel_:
-
-#ifdef TT_CONFIG_OPTION_STATIC_RASTER
- *exc = cur;
-#endif
-
/* If any errors have occurred, function tables may be broken. */
/* Force a re-execution of `prep' and `fpgm' tables if no */
/* bytecode debugger is run. */
- if ( CUR.error &&
- !CUR.instruction_trap &&
- CUR.curRange == tt_coderange_glyph )
+ if ( exc->error &&
+ !exc->instruction_trap &&
+ exc->curRange == tt_coderange_glyph )
{
- FT_TRACE1(( " The interpreter returned error 0x%x\n", CUR.error ));
+ FT_TRACE1(( " The interpreter returned error 0x%x\n", exc->error ));
exc->size->bytecode_ready = -1;
exc->size->cvt_ready = -1;
}
- return CUR.error;
+ return exc->error;
}
diff --git a/src/3rdparty/freetype/src/truetype/ttinterp.h b/src/3rdparty/freetype/src/truetype/ttinterp.h
index 333decc6a6..32706d0760 100644
--- a/src/3rdparty/freetype/src/truetype/ttinterp.h
+++ b/src/3rdparty/freetype/src/truetype/ttinterp.h
@@ -4,7 +4,7 @@
/* */
/* TrueType bytecode interpreter (specification). */
/* */
-/* Copyright 1996-2007, 2010, 2012-2014 by */
+/* Copyright 1996-2015 by */
/* David Turner, Robert Wilhelm, and Werner Lemberg. */
/* */
/* This file is part of the FreeType project, and may only be used, */
@@ -26,23 +26,6 @@
FT_BEGIN_HEADER
-#ifndef TT_CONFIG_OPTION_STATIC_INTERPRETER /* indirect implementation */
-
-#define EXEC_OP_ TT_ExecContext exc,
-#define EXEC_OP TT_ExecContext exc
-#define EXEC_ARG_ exc,
-#define EXEC_ARG exc
-
-#else /* static implementation */
-
-#define EXEC_OP_ /* void */
-#define EXEC_OP /* void */
-#define EXEC_ARG_ /* void */
-#define EXEC_ARG /* void */
-
-#endif /* TT_CONFIG_OPTION_STATIC_INTERPRETER */
-
-
/*************************************************************************/
/* */
/* Rounding mode constants. */
@@ -67,33 +50,38 @@ FT_BEGIN_HEADER
/* Rounding function */
typedef FT_F26Dot6
- (*TT_Round_Func)( EXEC_OP_ FT_F26Dot6 distance,
- FT_F26Dot6 compensation );
+ (*TT_Round_Func)( TT_ExecContext exc,
+ FT_F26Dot6 distance,
+ FT_F26Dot6 compensation );
/* Point displacement along the freedom vector routine */
typedef void
- (*TT_Move_Func)( EXEC_OP_ TT_GlyphZone zone,
- FT_UShort point,
- FT_F26Dot6 distance );
+ (*TT_Move_Func)( TT_ExecContext exc,
+ TT_GlyphZone zone,
+ FT_UShort point,
+ FT_F26Dot6 distance );
/* Distance projection along one of the projection vectors */
typedef FT_F26Dot6
- (*TT_Project_Func)( EXEC_OP_ FT_Pos dx,
- FT_Pos dy );
+ (*TT_Project_Func)( TT_ExecContext exc,
+ FT_Pos dx,
+ FT_Pos dy );
/* getting current ppem. Take care of non-square pixels if necessary */
typedef FT_Long
- (*TT_Cur_Ppem_Func)( EXEC_OP );
+ (*TT_Cur_Ppem_Func)( TT_ExecContext exc );
/* reading a cvt value. Take care of non-square pixels if necessary */
typedef FT_F26Dot6
- (*TT_Get_CVT_Func)( EXEC_OP_ FT_ULong idx );
+ (*TT_Get_CVT_Func)( TT_ExecContext exc,
+ FT_ULong idx );
/* setting or moving a cvt value. Take care of non-square pixels */
/* if necessary */
typedef void
- (*TT_Set_CVT_Func)( EXEC_OP_ FT_ULong idx,
- FT_F26Dot6 value );
+ (*TT_Set_CVT_Func)( TT_ExecContext exc,
+ FT_ULong idx,
+ FT_F26Dot6 value );
/*************************************************************************/
@@ -170,11 +158,11 @@ FT_BEGIN_HEADER
FT_Long top; /* top of exec. stack */
- FT_UInt stackSize; /* size of exec. stack */
+ FT_Long stackSize; /* size of exec. stack */
FT_Long* stack; /* current exec. stack */
FT_Long args;
- FT_UInt new_top; /* new top after exec. */
+ FT_Long new_top; /* new top after exec. */
TT_GlyphZoneRec zp0, /* zone records */
zp1,
@@ -264,18 +252,22 @@ FT_BEGIN_HEADER
#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
TT_Round_Func func_round_sphn; /* subpixel rounding function */
- FT_Bool subpixel; /* Using subpixel hinting? */
+ FT_Bool subpixel_hinting; /* Using subpixel hinting? */
FT_Bool ignore_x_mode; /* Standard rendering mode for */
/* subpixel hinting. On if gray */
/* or subpixel hinting is on. */
- /* The following 4 aren't fully implemented but here for MS rasterizer */
+ /* The following 6 aren't fully implemented but here for MS rasterizer */
/* compatibility. */
FT_Bool compatible_widths; /* compatible widths? */
FT_Bool symmetrical_smoothing; /* symmetrical_smoothing? */
FT_Bool bgr; /* bgr instead of rgb? */
+ FT_Bool vertical_lcd; /* long side of LCD subpixel */
+ /* rectangles is horizontal */
FT_Bool subpixel_positioned; /* subpixel positioned */
/* (DirectWrite ClearType)? */
+ FT_Bool gray_cleartype; /* ClearType hinting but */
+ /* grayscale rendering */
FT_Int rasterizer_version; /* MS rasterizer version */
@@ -315,7 +307,7 @@ FT_BEGIN_HEADER
FT_LOCAL( FT_Error )
Update_Max( FT_Memory memory,
FT_ULong* size,
- FT_Long multiplier,
+ FT_ULong multiplier,
void* _pbuff,
FT_ULong new_max );
#endif /* TT_USE_BYTECODE_INTERPRETER */
@@ -339,6 +331,7 @@ FT_BEGIN_HEADER
/* */
/* <Note> */
/* Only the glyph loader and debugger should call this function. */
+ /* (And right now only the glyph loader uses it.) */
/* */
FT_EXPORT( TT_ExecContext )
TT_New_Context( TT_Driver driver );
@@ -358,8 +351,7 @@ FT_BEGIN_HEADER
TT_Size ins );
FT_LOCAL( FT_Error )
- TT_Run_Context( TT_ExecContext exec,
- FT_Bool debug );
+ TT_Run_Context( TT_ExecContext exec );
#endif /* TT_USE_BYTECODE_INTERPRETER */
diff --git a/src/3rdparty/freetype/src/truetype/ttobjs.c b/src/3rdparty/freetype/src/truetype/ttobjs.c
index 4707dfe159..6060d6f5d1 100644
--- a/src/3rdparty/freetype/src/truetype/ttobjs.c
+++ b/src/3rdparty/freetype/src/truetype/ttobjs.c
@@ -4,7 +4,7 @@
/* */
/* Objects manager (body). */
/* */
-/* Copyright 1996-2013 */
+/* Copyright 1996-2015 by */
/* David Turner, Robert Wilhelm, and Werner Lemberg. */
/* */
/* This file is part of the FreeType project, and may only be used, */
@@ -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 )
@@ -751,14 +800,7 @@
FT_Error error;
- /* debugging instances have their own context */
- if ( size->debug )
- exec = size->context;
- else
- exec = ( (TT_Driver)FT_FACE_DRIVER( face ) )->context;
-
- if ( !exec )
- return FT_THROW( Could_Not_Find_Context );
+ exec = size->context;
error = TT_Load_Context( exec, face, size );
if ( error )
@@ -795,7 +837,7 @@
TT_Set_CodeRange( exec,
tt_coderange_font,
face->font_program,
- face->font_program_size );
+ (FT_Long)face->font_program_size );
/* disable CVT and glyph programs coderange */
TT_Clear_CodeRange( exec, tt_coderange_cvt );
@@ -845,14 +887,7 @@
FT_Error error;
- /* debugging instances have their own context */
- if ( size->debug )
- exec = size->context;
- else
- exec = ( (TT_Driver)FT_FACE_DRIVER( face ) )->context;
-
- if ( !exec )
- return FT_THROW( Could_Not_Find_Context );
+ exec = size->context;
error = TT_Load_Context( exec, face, size );
if ( error )
@@ -868,7 +903,7 @@
TT_Set_CodeRange( exec,
tt_coderange_cvt,
face->cvt_program,
- face->cvt_program_size );
+ (FT_Long)face->cvt_program_size );
TT_Clear_CodeRange( exec, tt_coderange_glyph );
@@ -876,12 +911,9 @@
{
TT_Goto_CodeRange( exec, tt_coderange_cvt, 0 );
- if ( !size->debug )
- {
- FT_TRACE4(( "Executing `prep' table.\n" ));
+ FT_TRACE4(( "Executing `prep' table.\n" ));
- error = face->interpreter( exec );
- }
+ error = face->interpreter( exec );
}
else
error = FT_Err_Ok;
@@ -924,12 +956,10 @@
TT_Face face = (TT_Face)ftsize->face;
FT_Memory memory = face->root.memory;
-
- if ( size->debug )
+ if ( size->context )
{
- /* the debug context must be deleted by the debugger itself */
+ TT_Done_Context( size->context );
size->context = NULL;
- size->debug = FALSE;
}
FT_FREE( size->cvt );
@@ -973,9 +1003,21 @@
TT_MaxProfile* maxp = &face->max_profile;
+ /* clean up bytecode related data */
+ FT_FREE( size->function_defs );
+ FT_FREE( size->instruction_defs );
+ FT_FREE( size->cvt );
+ FT_FREE( size->storage );
+
+ if ( size->context )
+ TT_Done_Context( size->context );
+ tt_glyphzone_done( &size->twilight );
+
size->bytecode_ready = -1;
size->cvt_ready = -1;
+ size->context = TT_New_Context( (TT_Driver)face->root.driver );
+
size->max_function_defs = maxp->maxFunctionDefs;
size->max_instruction_defs = maxp->maxInstructionDefs;
@@ -1259,10 +1301,6 @@
TT_Driver driver = (TT_Driver)ttdriver;
-
- if ( !TT_New_Context( driver ) )
- return FT_THROW( Could_Not_Find_Context );
-
#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
driver->interpreter_version = TT_INTERPRETER_VERSION_38;
#else
@@ -1293,20 +1331,7 @@
FT_LOCAL_DEF( void )
tt_driver_done( FT_Module ttdriver ) /* TT_Driver */
{
-#ifdef TT_USE_BYTECODE_INTERPRETER
- TT_Driver driver = (TT_Driver)ttdriver;
-
-
- /* destroy the execution context */
- if ( driver->context )
- {
- TT_Done_Context( driver->context );
- driver->context = NULL;
- }
-#else
FT_UNUSED( ttdriver );
-#endif
-
}
diff --git a/src/3rdparty/freetype/src/truetype/ttobjs.h b/src/3rdparty/freetype/src/truetype/ttobjs.h
index 859164f86b..9396089a99 100644
--- a/src/3rdparty/freetype/src/truetype/ttobjs.h
+++ b/src/3rdparty/freetype/src/truetype/ttobjs.h
@@ -4,7 +4,7 @@
/* */
/* Objects manager (specification). */
/* */
-/* Copyright 1996-2009, 2011-2014 by */
+/* Copyright 1996-2015 by */
/* David Turner, Robert Wilhelm, and Werner Lemberg. */
/* */
/* This file is part of the FreeType project, and may only be used, */
@@ -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> */
@@ -160,7 +149,7 @@ FT_BEGIN_HEADER
typedef struct TT_CodeRange_
{
FT_Byte* base;
- FT_ULong size;
+ FT_Long size;
} TT_CodeRange;
@@ -324,13 +313,6 @@ FT_BEGIN_HEADER
TT_GlyphZoneRec twilight; /* The instance's twilight zone */
- /* debugging variables */
-
- /* When using the debugger, we must keep the */
- /* execution context tied to the instance */
- /* object rather than asking it on demand. */
-
- FT_Bool debug;
TT_ExecContext context;
/* if negative, `fpgm' (resp. `prep'), wasn't executed yet; */
@@ -351,7 +333,6 @@ FT_BEGIN_HEADER
{
FT_DriverRec root;
- TT_ExecContext context; /* execution context */
TT_GlyphZoneRec zone; /* glyph loader points zone */
FT_UInt interpreter_version;
diff --git a/src/3rdparty/freetype/src/truetype/ttpic.c b/src/3rdparty/freetype/src/truetype/ttpic.c
index edefae72c5..242a6b76dd 100644
--- a/src/3rdparty/freetype/src/truetype/ttpic.c
+++ b/src/3rdparty/freetype/src/truetype/ttpic.c
@@ -4,7 +4,7 @@
/* */
/* The FreeType position independent code services for truetype module. */
/* */
-/* Copyright 2009, 2010, 2012, 2013 by */
+/* Copyright 2009-2015 by */
/* Oran Agra and Mickey Gabel. */
/* */
/* This file is part of the FreeType project, and may only be used, */
diff --git a/src/3rdparty/freetype/src/truetype/ttpic.h b/src/3rdparty/freetype/src/truetype/ttpic.h
index cfb4ee6281..076ae56efa 100644
--- a/src/3rdparty/freetype/src/truetype/ttpic.h
+++ b/src/3rdparty/freetype/src/truetype/ttpic.h
@@ -4,7 +4,7 @@
/* */
/* The FreeType position independent code services for truetype module. */
/* */
-/* Copyright 2009, 2012, 2013 by */
+/* Copyright 2009-2015 by */
/* Oran Agra and Mickey Gabel. */
/* */
/* This file is part of the FreeType project, and may only be used, */
@@ -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/3rdparty/freetype/src/truetype/ttpload.c b/src/3rdparty/freetype/src/truetype/ttpload.c
index 9991925425..4647c938ae 100644
--- a/src/3rdparty/freetype/src/truetype/ttpload.c
+++ b/src/3rdparty/freetype/src/truetype/ttpload.c
@@ -4,7 +4,7 @@
/* */
/* TrueType-specific tables loader (body). */
/* */
-/* Copyright 1996-2002, 2004-2013 by */
+/* Copyright 1996-2015 by */
/* David Turner, Robert Wilhelm, and Werner Lemberg. */
/* */
/* This file is part of the FreeType project, and may only be used, */
@@ -118,20 +118,20 @@
/* we only handle the case where `maxp' gives a larger value */
if ( face->num_locations <= (FT_ULong)face->root.num_glyphs )
{
- FT_Long new_loca_len =
- ( (FT_Long)( face->root.num_glyphs ) + 1 ) << shift;
+ FT_ULong new_loca_len =
+ ( (FT_ULong)face->root.num_glyphs + 1 ) << shift;
TT_Table entry = face->dir_tables;
TT_Table limit = entry + face->num_tables;
- FT_Long pos = FT_Stream_Pos( stream );
+ FT_Long pos = (FT_Long)FT_STREAM_POS();
FT_Long dist = 0x7FFFFFFFL;
/* compute the distance to next table in font file */
for ( ; entry < limit; entry++ )
{
- FT_Long diff = entry->Offset - pos;
+ FT_Long diff = (FT_Long)entry->Offset - pos;
if ( diff > 0 && diff < dist )
@@ -141,17 +141,25 @@
if ( entry == limit )
{
/* `loca' is the last table */
- dist = stream->size - pos;
+ dist = (FT_Long)stream->size - pos;
}
- if ( new_loca_len <= dist )
+ if ( new_loca_len <= (FT_ULong)dist )
{
- face->num_locations = face->root.num_glyphs + 1;
+ face->num_locations = (FT_ULong)face->root.num_glyphs + 1;
table_len = new_loca_len;
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 ));
+ }
}
}
diff --git a/src/3rdparty/freetype/src/truetype/ttpload.h b/src/3rdparty/freetype/src/truetype/ttpload.h
index f61ac079ce..bc92369827 100644
--- a/src/3rdparty/freetype/src/truetype/ttpload.h
+++ b/src/3rdparty/freetype/src/truetype/ttpload.h
@@ -4,7 +4,7 @@
/* */
/* TrueType-specific tables loader (specification). */
/* */
-/* Copyright 1996-2001, 2002, 2005, 2006 by */
+/* Copyright 1996-2015 by */
/* David Turner, Robert Wilhelm, and Werner Lemberg. */
/* */
/* This file is part of the FreeType project, and may only be used, */
diff --git a/src/3rdparty/freetype/src/truetype/ttsubpix.c b/src/3rdparty/freetype/src/truetype/ttsubpix.c
index ca604518cf..0d391e95a0 100644
--- a/src/3rdparty/freetype/src/truetype/ttsubpix.c
+++ b/src/3rdparty/freetype/src/truetype/ttsubpix.c
@@ -4,7 +4,7 @@
/* */
/* TrueType Subpixel Hinting. */
/* */
-/* Copyright 2010-2013 by */
+/* Copyright 2010-2015 by */
/* David Turner, Robert Wilhelm, and Werner Lemberg. */
/* */
/* This file is part of the FreeType project, and may only be used, */
@@ -63,8 +63,8 @@
/* rules below. A blank entry "" is required at the end of these! */
#define FAMILY_CLASS_RULES_SIZE 7
- static const SPH_Font_Class FAMILY_CLASS_Rules
- [FAMILY_CLASS_RULES_SIZE] =
+ static const SPH_Font_Class FAMILY_CLASS_Rules
+ [FAMILY_CLASS_RULES_SIZE] =
{
{ "MS Legacy Fonts",
{ "Aharoni",
@@ -223,8 +223,8 @@
/* rules below. A blank entry "" is required at the end of these! */
#define STYLE_CLASS_RULES_SIZE 5
- const SPH_Font_Class STYLE_CLASS_Rules
- [STYLE_CLASS_RULES_SIZE] =
+ static const SPH_Font_Class STYLE_CLASS_Rules
+ [STYLE_CLASS_RULES_SIZE] =
{
{ "Regular Class",
{ "Regular",
@@ -279,8 +279,8 @@
/* Force special legacy fixes for fonts. */
#define COMPATIBILITY_MODE_RULES_SIZE 1
- const SPH_TweakRule COMPATIBILITY_MODE_Rules
- [COMPATIBILITY_MODE_RULES_SIZE] =
+ static const SPH_TweakRule COMPATIBILITY_MODE_Rules
+ [COMPATIBILITY_MODE_RULES_SIZE] =
{
{ "Verdana Clones", 0, "", 0 },
};
@@ -289,8 +289,8 @@
/* Don't do subpixel (ignore_x_mode) hinting; do normal hinting. */
#define PIXEL_HINTING_RULES_SIZE 2
- const SPH_TweakRule PIXEL_HINTING_Rules
- [PIXEL_HINTING_RULES_SIZE] =
+ static const SPH_TweakRule PIXEL_HINTING_Rules
+ [PIXEL_HINTING_RULES_SIZE] =
{
/* these characters are almost always safe */
{ "Courier New", 12, "Italic", 'z' },
@@ -301,8 +301,8 @@
/* Subpixel hinting ignores SHPIX rules on X. Force SHPIX for these. */
#define DO_SHPIX_RULES_SIZE 1
- const SPH_TweakRule DO_SHPIX_Rules
- [DO_SHPIX_RULES_SIZE] =
+ static const SPH_TweakRule DO_SHPIX_Rules
+ [DO_SHPIX_RULES_SIZE] =
{
{ "-", 0, "", 0 },
};
@@ -312,8 +312,8 @@
/* boundary and don't move that point to a Y pixel boundary. */
#define SKIP_NONPIXEL_Y_MOVES_RULES_SIZE 4
- const SPH_TweakRule SKIP_NONPIXEL_Y_MOVES_Rules
- [SKIP_NONPIXEL_Y_MOVES_RULES_SIZE] =
+ static const SPH_TweakRule SKIP_NONPIXEL_Y_MOVES_Rules
+ [SKIP_NONPIXEL_Y_MOVES_RULES_SIZE] =
{
/* fix vwxyz thinness*/
{ "Consolas", 0, "", 0 },
@@ -328,8 +328,8 @@
#define SKIP_NONPIXEL_Y_MOVES_RULES_EXCEPTIONS_SIZE 1
- const SPH_TweakRule SKIP_NONPIXEL_Y_MOVES_Rules_Exceptions
- [SKIP_NONPIXEL_Y_MOVES_RULES_EXCEPTIONS_SIZE] =
+ static const SPH_TweakRule SKIP_NONPIXEL_Y_MOVES_Rules_Exceptions
+ [SKIP_NONPIXEL_Y_MOVES_RULES_EXCEPTIONS_SIZE] =
{
/* Fixes < and > */
{ "Courier New", 0, "Regular", 0 },
@@ -340,8 +340,8 @@
/* boundary and don't move that point to a Y pixel boundary. */
#define SKIP_NONPIXEL_Y_MOVES_DELTAP_RULES_SIZE 2
- const SPH_TweakRule SKIP_NONPIXEL_Y_MOVES_DELTAP_Rules
- [SKIP_NONPIXEL_Y_MOVES_DELTAP_RULES_SIZE] =
+ static const SPH_TweakRule SKIP_NONPIXEL_Y_MOVES_DELTAP_Rules
+ [SKIP_NONPIXEL_Y_MOVES_DELTAP_RULES_SIZE] =
{
/* Maintain thickness of diagonal in 'N' */
{ "Times New Roman", 0, "Regular/Bold Class", 'N' },
@@ -352,8 +352,8 @@
/* Skip Y moves that move a point off a Y pixel boundary. */
#define SKIP_OFFPIXEL_Y_MOVES_RULES_SIZE 1
- const SPH_TweakRule SKIP_OFFPIXEL_Y_MOVES_Rules
- [SKIP_OFFPIXEL_Y_MOVES_RULES_SIZE] =
+ static const SPH_TweakRule SKIP_OFFPIXEL_Y_MOVES_Rules
+ [SKIP_OFFPIXEL_Y_MOVES_RULES_SIZE] =
{
{ "-", 0, "", 0 },
};
@@ -361,8 +361,8 @@
#define SKIP_OFFPIXEL_Y_MOVES_RULES_EXCEPTIONS_SIZE 1
- const SPH_TweakRule SKIP_OFFPIXEL_Y_MOVES_Rules_Exceptions
- [SKIP_OFFPIXEL_Y_MOVES_RULES_EXCEPTIONS_SIZE] =
+ static const SPH_TweakRule SKIP_OFFPIXEL_Y_MOVES_Rules_Exceptions
+ [SKIP_OFFPIXEL_Y_MOVES_RULES_EXCEPTIONS_SIZE] =
{
{ "-", 0, "", 0 },
};
@@ -371,8 +371,8 @@
/* Round moves that don't move a point to a Y pixel boundary. */
#define ROUND_NONPIXEL_Y_MOVES_RULES_SIZE 2
- const SPH_TweakRule ROUND_NONPIXEL_Y_MOVES_Rules
- [ROUND_NONPIXEL_Y_MOVES_RULES_SIZE] =
+ static const SPH_TweakRule ROUND_NONPIXEL_Y_MOVES_Rules
+ [ROUND_NONPIXEL_Y_MOVES_RULES_SIZE] =
{
/* Droid font instructions don't snap Y to pixels */
{ "Droid Sans", 0, "Regular/Italic Class", 0 },
@@ -382,8 +382,8 @@
#define ROUND_NONPIXEL_Y_MOVES_RULES_EXCEPTIONS_SIZE 1
- const SPH_TweakRule ROUND_NONPIXEL_Y_MOVES_Rules_Exceptions
- [ROUND_NONPIXEL_Y_MOVES_RULES_EXCEPTIONS_SIZE] =
+ static const SPH_TweakRule ROUND_NONPIXEL_Y_MOVES_Rules_Exceptions
+ [ROUND_NONPIXEL_Y_MOVES_RULES_EXCEPTIONS_SIZE] =
{
{ "-", 0, "", 0 },
};
@@ -392,8 +392,8 @@
/* Allow a Direct_Move along X freedom vector if matched. */
#define ALLOW_X_DMOVE_RULES_SIZE 1
- const SPH_TweakRule ALLOW_X_DMOVE_Rules
- [ALLOW_X_DMOVE_RULES_SIZE] =
+ static const SPH_TweakRule ALLOW_X_DMOVE_Rules
+ [ALLOW_X_DMOVE_RULES_SIZE] =
{
/* Fixes vanishing diagonal in 4 */
{ "Verdana", 0, "Regular", '4' },
@@ -403,8 +403,8 @@
/* Return MS rasterizer version 35 if matched. */
#define RASTERIZER_35_RULES_SIZE 8
- const SPH_TweakRule RASTERIZER_35_Rules
- [RASTERIZER_35_RULES_SIZE] =
+ static const SPH_TweakRule RASTERIZER_35_Rules
+ [RASTERIZER_35_RULES_SIZE] =
{
/* This seems to be the only way to make these look good */
{ "Times New Roman", 0, "Regular", 'i' },
@@ -421,8 +421,8 @@
/* Don't round to the subpixel grid. Round to pixel grid. */
#define NORMAL_ROUND_RULES_SIZE 1
- const SPH_TweakRule NORMAL_ROUND_Rules
- [NORMAL_ROUND_RULES_SIZE] =
+ static const SPH_TweakRule NORMAL_ROUND_Rules
+ [NORMAL_ROUND_RULES_SIZE] =
{
/* Fix serif thickness for certain ppems */
/* Can probably be generalized somehow */
@@ -433,8 +433,8 @@
/* Skip IUP instructions if matched. */
#define SKIP_IUP_RULES_SIZE 1
- const SPH_TweakRule SKIP_IUP_Rules
- [SKIP_IUP_RULES_SIZE] =
+ static const SPH_TweakRule SKIP_IUP_Rules
+ [SKIP_IUP_RULES_SIZE] =
{
{ "Arial", 13, "Regular", 'a' },
};
@@ -443,8 +443,8 @@
/* Skip MIAP Twilight hack if matched. */
#define MIAP_HACK_RULES_SIZE 1
- const SPH_TweakRule MIAP_HACK_Rules
- [MIAP_HACK_RULES_SIZE] =
+ static const SPH_TweakRule MIAP_HACK_Rules
+ [MIAP_HACK_RULES_SIZE] =
{
{ "Geneva", 12, "", 0 },
};
@@ -453,8 +453,8 @@
/* Skip DELTAP instructions if matched. */
#define ALWAYS_SKIP_DELTAP_RULES_SIZE 23
- const SPH_TweakRule ALWAYS_SKIP_DELTAP_Rules
- [ALWAYS_SKIP_DELTAP_RULES_SIZE] =
+ static const SPH_TweakRule ALWAYS_SKIP_DELTAP_Rules
+ [ALWAYS_SKIP_DELTAP_RULES_SIZE] =
{
{ "Georgia", 0, "Regular", 'k' },
/* fix various problems with e in different versions */
@@ -489,8 +489,8 @@
/* Always do DELTAP instructions if matched. */
#define ALWAYS_DO_DELTAP_RULES_SIZE 1
- const SPH_TweakRule ALWAYS_DO_DELTAP_Rules
- [ALWAYS_DO_DELTAP_RULES_SIZE] =
+ static const SPH_TweakRule ALWAYS_DO_DELTAP_Rules
+ [ALWAYS_DO_DELTAP_RULES_SIZE] =
{
{ "-", 0, "", 0 },
};
@@ -744,7 +744,7 @@
#endif /* FORCE_NATURAL_WIDTHS */
- FT_LOCAL_DEF( FT_Bool )
+ static FT_Bool
is_member_of_family_class( const FT_String* detected_font_name,
const FT_String* rule_font_name )
{
@@ -779,7 +779,7 @@
}
- FT_LOCAL_DEF( FT_Bool )
+ static FT_Bool
is_member_of_style_class( const FT_String* detected_font_style,
const FT_String* rule_font_style )
{
@@ -903,9 +903,9 @@
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;
- int ppem = loader->size->metrics.x_ppem;
+ FT_UInt ppem = loader->size->metrics.x_ppem;
FT_String* style = face->root.style_name;
diff --git a/src/3rdparty/freetype/src/truetype/ttsubpix.h b/src/3rdparty/freetype/src/truetype/ttsubpix.h
index 8a54fc7cc7..9151aa3250 100644
--- a/src/3rdparty/freetype/src/truetype/ttsubpix.h
+++ b/src/3rdparty/freetype/src/truetype/ttsubpix.h
@@ -4,7 +4,7 @@
/* */
/* TrueType Subpixel Hinting. */
/* */
-/* Copyright 2010-2013 by */
+/* Copyright 2010-2015 by */
/* David Turner, Robert Wilhelm, and Werner Lemberg. */
/* */
/* This file is part of the FreeType project, and may only be used, */
@@ -50,26 +50,26 @@ FT_BEGIN_HEADER
/* Tweak flags that are set for each glyph by the below rules. */
/* */
/* */
-#define SPH_TWEAK_ALLOW_X_DMOVE 0x0000001
-#define SPH_TWEAK_ALWAYS_DO_DELTAP 0x0000002
-#define SPH_TWEAK_ALWAYS_SKIP_DELTAP 0x0000004
-#define SPH_TWEAK_COURIER_NEW_2_HACK 0x0000008
-#define SPH_TWEAK_DEEMBOLDEN 0x0000010
-#define SPH_TWEAK_DO_SHPIX 0x0000020
-#define SPH_TWEAK_EMBOLDEN 0x0000040
-#define SPH_TWEAK_MIAP_HACK 0x0000080
-#define SPH_TWEAK_NORMAL_ROUND 0x0000100
-#define SPH_TWEAK_NO_ALIGNRP_AFTER_IUP 0x0000200
-#define SPH_TWEAK_NO_CALL_AFTER_IUP 0x0000400
-#define SPH_TWEAK_NO_DELTAP_AFTER_IUP 0x0000800
-#define SPH_TWEAK_PIXEL_HINTING 0x0001000
-#define SPH_TWEAK_RASTERIZER_35 0x0002000
-#define SPH_TWEAK_ROUND_NONPIXEL_Y_MOVES 0x0004000
-#define SPH_TWEAK_SKIP_IUP 0x0008000
-#define SPH_TWEAK_SKIP_NONPIXEL_Y_MOVES 0x0010000
-#define SPH_TWEAK_SKIP_OFFPIXEL_Y_MOVES 0x0020000
-#define SPH_TWEAK_TIMES_NEW_ROMAN_HACK 0x0040000
-#define SPH_TWEAK_SKIP_NONPIXEL_Y_MOVES_DELTAP 0x0080000
+#define SPH_TWEAK_ALLOW_X_DMOVE 0x0000001UL
+#define SPH_TWEAK_ALWAYS_DO_DELTAP 0x0000002UL
+#define SPH_TWEAK_ALWAYS_SKIP_DELTAP 0x0000004UL
+#define SPH_TWEAK_COURIER_NEW_2_HACK 0x0000008UL
+#define SPH_TWEAK_DEEMBOLDEN 0x0000010UL
+#define SPH_TWEAK_DO_SHPIX 0x0000020UL
+#define SPH_TWEAK_EMBOLDEN 0x0000040UL
+#define SPH_TWEAK_MIAP_HACK 0x0000080UL
+#define SPH_TWEAK_NORMAL_ROUND 0x0000100UL
+#define SPH_TWEAK_NO_ALIGNRP_AFTER_IUP 0x0000200UL
+#define SPH_TWEAK_NO_CALL_AFTER_IUP 0x0000400UL
+#define SPH_TWEAK_NO_DELTAP_AFTER_IUP 0x0000800UL
+#define SPH_TWEAK_PIXEL_HINTING 0x0001000UL
+#define SPH_TWEAK_RASTERIZER_35 0x0002000UL
+#define SPH_TWEAK_ROUND_NONPIXEL_Y_MOVES 0x0004000UL
+#define SPH_TWEAK_SKIP_IUP 0x0008000UL
+#define SPH_TWEAK_SKIP_NONPIXEL_Y_MOVES 0x0010000UL
+#define SPH_TWEAK_SKIP_OFFPIXEL_Y_MOVES 0x0020000UL
+#define SPH_TWEAK_TIMES_NEW_ROMAN_HACK 0x0040000UL
+#define SPH_TWEAK_SKIP_NONPIXEL_Y_MOVES_DELTAP 0x0080000UL
FT_LOCAL( FT_Bool )