summaryrefslogtreecommitdiffstats
path: root/src/truetype
diff options
context:
space:
mode:
authorJungshik Shin <jungshik@google.com>2016-09-18 03:50:36 -0700
committerSean McCreary <mccreary@mcwest.org>2017-04-07 16:53:42 -0600
commit3ff870b9dbbd88173df82269d3c1cffb1eba2eda (patch)
tree0e443679e800bb442b2cbb2f7ae086b787ca65ff /src/truetype
parentf720f0dbcf012d6c984dbbefa0875ef9840458c6 (diff)
downloadandroid_external_freetype-cm-13.0.tar.gz
android_external_freetype-cm-13.0.tar.bz2
android_external_freetype-cm-13.0.zip
Update FreeType from 2.6.2 to c38be52bf8de (2.7 + a few post-2.7 CLs)HEADreplicant-6.0-0002replicant-6.0-0001cm-13.0
http://git.savannah.gnu.org/cgit/freetype/freetype2.git/commit/?id=c38be52b Keep all the configuration options as before. Likewise, exclude unused files (Jamfiles, various mk files, builds/, docs/, ChangeLog*, directories under src/ for disabled modules, etc). Update README.android to record the configurations. Besides, disable a new option (TT_CONFIG_OPTION_SUBPIXEL_HINTING) for branches. Note that a bulk of changes in this CL come from the code to implement this option. BUG: 31470908 AOSP-Change-Id: I1ca90aec171d9580415b8531e2b767e9dd31164c CVE-2016-10244 Change-Id: I4485d2ea543c52f8145ab23372cf3e5c7345879b (cherry picked from commit 055aee28cedc3631434b2636fc6093c0d4d818ab)
Diffstat (limited to 'src/truetype')
-rw-r--r--src/truetype/truetype.c2
-rw-r--r--src/truetype/ttdriver.c71
-rw-r--r--src/truetype/ttdriver.h8
-rw-r--r--src/truetype/tterrors.h11
-rw-r--r--src/truetype/ttgload.c305
-rw-r--r--src/truetype/ttgload.h8
-rw-r--r--src/truetype/ttgxvar.c198
-rw-r--r--src/truetype/ttgxvar.h8
-rw-r--r--src/truetype/ttinterp.c958
-rw-r--r--src/truetype/ttinterp.h147
-rw-r--r--src/truetype/ttobjs.c50
-rw-r--r--src/truetype/ttobjs.h14
-rw-r--r--src/truetype/ttpic.c2
-rw-r--r--src/truetype/ttpic.h8
-rw-r--r--src/truetype/ttpload.c2
-rw-r--r--src/truetype/ttpload.h8
-rw-r--r--src/truetype/ttsubpix.c8
-rw-r--r--src/truetype/ttsubpix.h13
18 files changed, 1100 insertions, 721 deletions
diff --git a/src/truetype/truetype.c b/src/truetype/truetype.c
index f929437..23e2ea0 100644
--- a/src/truetype/truetype.c
+++ b/src/truetype/truetype.c
@@ -4,7 +4,7 @@
/* */
/* FreeType TrueType driver component (body only). */
/* */
-/* Copyright 1996-2015 by */
+/* Copyright 1996-2016 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/truetype/ttdriver.c b/src/truetype/ttdriver.c
index 1ba71f0..b96a227 100644
--- a/src/truetype/ttdriver.c
+++ b/src/truetype/ttdriver.c
@@ -4,7 +4,7 @@
/* */
/* TrueType font driver implementation (body). */
/* */
-/* Copyright 1996-2015 by */
+/* Copyright 1996-2016 by */
/* David Turner, Robert Wilhelm, and Werner Lemberg. */
/* */
/* This file is part of the FreeType project, and may only be used, */
@@ -61,23 +61,50 @@
static FT_Error
tt_property_set( FT_Module module, /* TT_Driver */
const char* property_name,
- const void* value )
+ const void* value,
+ FT_Bool value_is_string )
{
FT_Error error = FT_Err_Ok;
TT_Driver driver = (TT_Driver)module;
+#ifndef FT_CONFIG_OPTION_ENVIRONMENT_PROPERTIES
+ FT_UNUSED( value_is_string );
+#endif
+
if ( !ft_strcmp( property_name, "interpreter-version" ) )
{
- FT_UInt* interpreter_version = (FT_UInt*)value;
+ FT_UInt interpreter_version;
-#ifndef TT_CONFIG_OPTION_SUBPIXEL_HINTING
- if ( *interpreter_version != TT_INTERPRETER_VERSION_35 )
- error = FT_ERR( Unimplemented_Feature );
+#ifdef FT_CONFIG_OPTION_ENVIRONMENT_PROPERTIES
+ if ( value_is_string )
+ {
+ const char* s = (const char*)value;
+
+
+ interpreter_version = (FT_UInt)ft_strtol( s, NULL, 10 );
+ }
else
#endif
- driver->interpreter_version = *interpreter_version;
+ {
+ FT_UInt* iv = (FT_UInt*)value;
+
+
+ interpreter_version = *iv;
+ }
+
+ if ( interpreter_version == TT_INTERPRETER_VERSION_35
+#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY
+ || interpreter_version == TT_INTERPRETER_VERSION_38
+#endif
+#ifdef TT_SUPPORT_SUBPIXEL_HINTING_MINIMAL
+ || interpreter_version == TT_INTERPRETER_VERSION_40
+#endif
+ )
+ driver->interpreter_version = interpreter_version;
+ else
+ error = FT_ERR( Unimplemented_Feature );
return error;
}
@@ -194,7 +221,7 @@
FT_Fixed *advances )
{
FT_UInt nn;
- TT_Face face = (TT_Face) ttface;
+ TT_Face face = (TT_Face) ttface;
/* XXX: TODO: check for sbits */
@@ -228,6 +255,7 @@
return FT_Err_Ok;
}
+
/*************************************************************************/
/*************************************************************************/
/*************************************************************************/
@@ -263,7 +291,7 @@
}
else
{
- SFNT_Service sfnt = (SFNT_Service) ttface->sfnt;
+ SFNT_Service sfnt = (SFNT_Service)ttface->sfnt;
FT_Size_Metrics* metrics = &size->metrics;
@@ -291,7 +319,7 @@
if ( FT_HAS_FIXED_SIZES( size->face ) )
{
TT_Face ttface = (TT_Face)size->face;
- SFNT_Service sfnt = (SFNT_Service) ttface->sfnt;
+ SFNT_Service sfnt = (SFNT_Service)ttface->sfnt;
FT_ULong strike_index;
@@ -311,6 +339,25 @@
{
error = tt_size_reset( ttsize );
ttsize->root.metrics = ttsize->metrics;
+
+#ifdef TT_USE_BYTECODE_INTERPRETER
+ /* for the `MPS' bytecode instruction we need the point size */
+ {
+ FT_UInt resolution = ttsize->metrics.x_ppem > ttsize->metrics.y_ppem
+ ? req->horiResolution
+ : req->vertResolution;
+
+
+ /* if we don't have a resolution value, assume 72dpi */
+ if ( req->type == FT_SIZE_REQUEST_TYPE_SCALES ||
+ !resolution )
+ resolution = 72;
+
+ ttsize->point_size = FT_MulDiv( ttsize->ttmetrics.ppem,
+ 64 * 72,
+ resolution );
+ }
+#endif
}
return error;
@@ -429,11 +476,7 @@
{
#ifdef TT_USE_BYTECODE_INTERPRETER
-#ifdef TT_CONFIG_OPTION_UNPATENTED_HINTING
- FT_TRUETYPE_ENGINE_TYPE_UNPATENTED
-#else
FT_TRUETYPE_ENGINE_TYPE_PATENTED
-#endif
#else /* !TT_USE_BYTECODE_INTERPRETER */
diff --git a/src/truetype/ttdriver.h b/src/truetype/ttdriver.h
index 6cacd60..74392bb 100644
--- a/src/truetype/ttdriver.h
+++ b/src/truetype/ttdriver.h
@@ -4,7 +4,7 @@
/* */
/* High-level TrueType driver interface (specification). */
/* */
-/* Copyright 1996-2015 by */
+/* Copyright 1996-2016 by */
/* David Turner, Robert Wilhelm, and Werner Lemberg. */
/* */
/* This file is part of the FreeType project, and may only be used, */
@@ -16,8 +16,8 @@
/***************************************************************************/
-#ifndef __TTDRIVER_H__
-#define __TTDRIVER_H__
+#ifndef TTDRIVER_H_
+#define TTDRIVER_H_
#include <ft2build.h>
@@ -32,7 +32,7 @@ FT_BEGIN_HEADER
FT_END_HEADER
-#endif /* __TTDRIVER_H__ */
+#endif /* TTDRIVER_H_ */
/* END */
diff --git a/src/truetype/tterrors.h b/src/truetype/tterrors.h
index ba32cf7..895989f 100644
--- a/src/truetype/tterrors.h
+++ b/src/truetype/tterrors.h
@@ -4,7 +4,7 @@
/* */
/* TrueType error codes (specification only). */
/* */
-/* Copyright 2001-2015 by */
+/* Copyright 2001-2016 by */
/* David Turner, Robert Wilhelm, and Werner Lemberg. */
/* */
/* This file is part of the FreeType project, and may only be used, */
@@ -23,12 +23,12 @@
/* */
/*************************************************************************/
-#ifndef __TTERRORS_H__
-#define __TTERRORS_H__
+#ifndef TTERRORS_H_
+#define TTERRORS_H_
#include FT_MODULE_ERRORS_H
-#undef __FTERRORS_H__
+#undef FTERRORS_H_
#undef FT_ERR_PREFIX
#define FT_ERR_PREFIX TT_Err_
@@ -36,6 +36,7 @@
#include FT_ERRORS_H
-#endif /* __TTERRORS_H__ */
+#endif /* TTERRORS_H_ */
+
/* END */
diff --git a/src/truetype/ttgload.c b/src/truetype/ttgload.c
index d94fc92..2d0b29f 100644
--- a/src/truetype/ttgload.c
+++ b/src/truetype/ttgload.c
@@ -4,7 +4,7 @@
/* */
/* TrueType Glyph Loader (body). */
/* */
-/* Copyright 1996-2015 by */
+/* Copyright 1996-2016 by */
/* David Turner, Robert Wilhelm, and Werner Lemberg. */
/* */
/* This file is part of the FreeType project, and may only be used, */
@@ -122,7 +122,7 @@
FT_UInt glyph_index )
{
TT_Face face = loader->face;
-#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
+#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY
TT_Driver driver = (TT_Driver)FT_FACE_DRIVER( face );
#endif
@@ -153,7 +153,7 @@
loader->top_bearing = top_bearing;
loader->vadvance = advance_height;
-#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
+#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY
if ( driver->interpreter_version == TT_INTERPRETER_VERSION_38 &&
loader->exec )
{
@@ -165,7 +165,7 @@
/* backwards compatibility mode on and off. */
sph_set_tweaks( loader, glyph_index );
}
-#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */
+#endif /* TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY */
if ( !loader->linear_def )
{
@@ -427,7 +427,8 @@
load->glyph->control_len = n_ins;
load->glyph->control_data = load->exec->glyphIns;
- FT_MEM_COPY( load->exec->glyphIns, p, (FT_Long)n_ins );
+ if ( n_ins )
+ FT_MEM_COPY( load->exec->glyphIns, p, (FT_Long)n_ins );
}
#endif /* TT_USE_BYTECODE_INTERPRETER */
@@ -732,7 +733,8 @@
TT_Hint_Glyph( TT_Loader loader,
FT_Bool is_composite )
{
-#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
+#if defined TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY || \
+ defined TT_SUPPORT_SUBPIXEL_HINTING_MINIMAL
TT_Face face = loader->face;
TT_Driver driver = (TT_Driver)FT_FACE_DRIVER( face );
#endif
@@ -815,13 +817,23 @@
#endif
- /* save glyph phantom points */
- loader->pp1 = zone->cur[zone->n_points - 4];
- loader->pp2 = zone->cur[zone->n_points - 3];
- loader->pp3 = zone->cur[zone->n_points - 2];
- loader->pp4 = zone->cur[zone->n_points - 1];
+#ifdef TT_SUPPORT_SUBPIXEL_HINTING_MINIMAL
+ /* Save possibly modified glyph phantom points unless in v40 backwards */
+ /* compatibility mode, where no movement on the x axis means no reason */
+ /* to change bearings or advance widths. */
+ if ( !( driver->interpreter_version == TT_INTERPRETER_VERSION_40 &&
+ !loader->exec->backwards_compatibility ) )
+ {
+#endif
+ loader->pp1 = zone->cur[zone->n_points - 4];
+ loader->pp2 = zone->cur[zone->n_points - 3];
+ loader->pp3 = zone->cur[zone->n_points - 2];
+ loader->pp4 = zone->cur[zone->n_points - 1];
+#ifdef TT_SUPPORT_SUBPIXEL_HINTING_MINIMAL
+ }
+#endif
-#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
+#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY
if ( driver->interpreter_version == TT_INTERPRETER_VERSION_38 )
{
if ( loader->exec->sph_tweak_flags & SPH_TWEAK_DEEMBOLDEN )
@@ -830,7 +842,7 @@
else if ( loader->exec->sph_tweak_flags & SPH_TWEAK_EMBOLDEN )
FT_Outline_EmboldenXY( &loader->gloader->current.outline, 24, 0 );
}
-#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */
+#endif /* TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY */
return FT_Err_Ok;
}
@@ -896,7 +908,7 @@
}
{
-#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
+#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY
TT_Face face = loader->face;
TT_Driver driver = (TT_Driver)FT_FACE_DRIVER( face );
@@ -915,7 +927,7 @@
FT_Bool do_scale = FALSE;
-#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
+#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY
if ( driver->interpreter_version == TT_INTERPRETER_VERSION_38 )
{
@@ -946,7 +958,7 @@
}
else
-#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */
+#endif /* TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY */
{
/* scale the glyph */
@@ -1077,7 +1089,7 @@
: -subglyph->transform.yx;
int c = subglyph->transform.xy > 0 ? subglyph->transform.xy
: -subglyph->transform.xy;
- int d = subglyph->transform.yy > 0 ? subglyph->transform.yy
+ int d = subglyph->transform.yy > 0 ? subglyph->transform.yy
: -subglyph->transform.yy;
int m = a > b ? a : b;
int n = c > d ? c : d;
@@ -1323,49 +1335,71 @@
* (3) for everything else.
*
*/
+ static void
+ tt_loader_set_pp( TT_Loader loader )
+ {
+ FT_Bool subpixel_hinting = 0;
+ FT_Bool grayscale = 0;
+ FT_Bool use_aw_2 = 0;
+
#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
+ TT_Driver driver = (TT_Driver)FT_FACE_DRIVER( loader->face );
+#endif
-#define TT_LOADER_SET_PP( loader ) \
- do \
- { \
- 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; \
- (loader)->pp1.y = 0; \
- (loader)->pp2.x = (loader)->pp1.x + (loader)->advance; \
- (loader)->pp2.y = 0; \
- \
- (loader)->pp3.x = use_aw_2_ ? (loader)->advance / 2 : 0; \
- (loader)->pp3.y = (loader)->bbox.yMax + (loader)->top_bearing; \
- (loader)->pp4.x = use_aw_2_ ? (loader)->advance / 2 : 0; \
- (loader)->pp4.y = (loader)->pp3.y - (loader)->vadvance; \
- } while ( 0 )
-
-#else /* !TT_CONFIG_OPTION_SUBPIXEL_HINTING */
-
-#define TT_LOADER_SET_PP( loader ) \
- do \
- { \
- (loader)->pp1.x = (loader)->bbox.xMin - (loader)->left_bearing; \
- (loader)->pp1.y = 0; \
- (loader)->pp2.x = (loader)->pp1.x + (loader)->advance; \
- (loader)->pp2.y = 0; \
- \
- (loader)->pp3.x = 0; \
- (loader)->pp3.y = (loader)->bbox.yMax + (loader)->top_bearing; \
- (loader)->pp4.x = 0; \
- (loader)->pp4.y = (loader)->pp3.y - (loader)->vadvance; \
- } while ( 0 )
-
-#endif /* !TT_CONFIG_OPTION_SUBPIXEL_HINTING */
+#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY
+ if ( driver->interpreter_version == TT_INTERPRETER_VERSION_38 )
+ {
+ subpixel_hinting = loader->exec ? loader->exec->subpixel_hinting
+ : 0;
+ grayscale = loader->exec ? loader->exec->grayscale
+ : 0;
+ }
+#endif
+#ifdef TT_SUPPORT_SUBPIXEL_HINTING_MINIMAL
+ if ( driver->interpreter_version == TT_INTERPRETER_VERSION_40 )
+ {
+ subpixel_hinting = loader->exec ? loader->exec->subpixel_hinting_lean
+ : 0;
+ grayscale = loader->exec ? loader->exec->grayscale_cleartype
+ : 0;
+ }
+#endif
+
+ use_aw_2 = (FT_Bool)( subpixel_hinting && grayscale );
+
+ loader->pp1.x = loader->bbox.xMin - loader->left_bearing;
+ loader->pp1.y = 0;
+ loader->pp2.x = loader->pp1.x + loader->advance;
+ loader->pp2.y = 0;
+
+ loader->pp3.x = use_aw_2 ? loader->advance / 2 : 0;
+ loader->pp3.y = loader->bbox.yMax + loader->top_bearing;
+ loader->pp4.x = use_aw_2 ? loader->advance / 2 : 0;
+ loader->pp4.y = loader->pp3.y - loader->vadvance;
+ }
+
+
+ /* a utility function to retrieve i-th node from given FT_List */
+ static FT_ListNode
+ ft_list_get_node_at( FT_List list,
+ FT_UInt index )
+ {
+ FT_ListNode cur;
+
+
+ if ( !list )
+ return NULL;
+
+ for ( cur = list->head; cur; cur = cur->next )
+ {
+ if ( !index )
+ return cur;
+
+ index--;
+ }
+
+ return NULL;
+ }
/*************************************************************************/
@@ -1402,13 +1436,12 @@
FT_TRACE5(( " nesting level: %d\n", recurse_count ));
#endif
- /* some fonts have an incorrect value of `maxComponentDepth', */
- /* thus we allow depth 1 to catch the majority of them */
- if ( recurse_count > 1 &&
- recurse_count > face->max_profile.maxComponentDepth )
+ /* some fonts have an incorrect value of `maxComponentDepth' */
+ if ( recurse_count > face->max_profile.maxComponentDepth )
{
- error = FT_THROW( Invalid_Composite );
- goto Exit;
+ FT_TRACE1(( "load_truetype_glyph: maxComponentDepth set to %d\n",
+ recurse_count ));
+ face->max_profile.maxComponentDepth = (FT_UShort)recurse_count;
}
#ifndef FT_CONFIG_OPTION_INCREMENTAL
@@ -1523,7 +1556,7 @@
/* must initialize points before (possibly) overriding */
/* glyph metrics from the incremental interface */
- TT_LOADER_SET_PP( loader );
+ tt_loader_set_pp( loader );
#ifdef FT_CONFIG_OPTION_INCREMENTAL
tt_get_metrics_incr_overrides( loader, glyph_index );
@@ -1598,7 +1631,7 @@
/* must initialize phantom points before (possibly) overriding */
/* glyph metrics from the incremental interface */
- TT_LOADER_SET_PP( loader );
+ tt_loader_set_pp( loader );
#ifdef FT_CONFIG_OPTION_INCREMENTAL
tt_get_metrics_incr_overrides( loader, glyph_index );
@@ -1640,6 +1673,8 @@
FT_UInt start_contour;
FT_ULong ins_pos; /* position of composite instructions, if any */
+ FT_ListNode node, node2;
+
/*
* We store the glyph index directly in the `node->data' pointer,
@@ -1648,6 +1683,12 @@
* pointers with a width of at least 32 bits.
*/
+
+ /* clear the nodes filled by sibling chains */
+ node = ft_list_get_node_at( &loader->composites, recurse_count );
+ for ( node2 = node; node2; node2 = node2->next )
+ node2->data = (void*)ULONG_MAX;
+
/* check whether we already have a composite glyph with this index */
if ( FT_List_Find( &loader->composites,
(void*)(unsigned long)glyph_index ) )
@@ -1657,11 +1698,12 @@
error = FT_THROW( Invalid_Composite );
goto Exit;
}
- else
- {
- FT_ListNode node = NULL;
+ else if ( node )
+ node->data = (void*)(unsigned long)glyph_index;
+ else
+ {
if ( FT_NEW( node ) )
goto Exit;
node->data = (void*)(unsigned long)glyph_index;
@@ -1703,6 +1745,10 @@
outline.n_points = (short)( gloader->current.num_subglyphs + 4 );
outline.n_contours = outline.n_points;
+ outline.points = NULL;
+ outline.tags = NULL;
+ outline.contours = NULL;
+
if ( FT_NEW_ARRAY( points, outline.n_points ) ||
FT_NEW_ARRAY( tags, outline.n_points ) ||
FT_NEW_ARRAY( contours, outline.n_points ) )
@@ -1761,11 +1807,11 @@
for ( i = 0; i < limit; i++, subglyph++ )
{
- /* 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;
+ if ( subglyph->flags & ARGS_ARE_XY_VALUES )
+ {
+ subglyph->arg1 = (FT_Int16)points[i].x;
+ subglyph->arg2 = (FT_Int16)points[i].y;
+ }
}
loader->pp1.x = points[i + 0].x;
@@ -1942,7 +1988,8 @@
FT_UInt glyph_index )
{
TT_Face face = loader->face;
-#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
+#if defined TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY || \
+ defined TT_SUPPORT_SUBPIXEL_HINTING_MINIMAL
TT_Driver driver = (TT_Driver)FT_FACE_DRIVER( face );
#endif
@@ -1969,11 +2016,18 @@
glyph->metrics.horiBearingY = bbox.yMax;
glyph->metrics.horiAdvance = loader->pp2.x - loader->pp1.x;
- /* adjust advance width to the value contained in the hdmx table */
- /* unless FT_LOAD_COMPUTE_METRICS is set */
- if ( !face->postscript.isFixedPitch &&
- IS_HINTED( loader->load_flags ) &&
- !( loader->load_flags & FT_LOAD_COMPUTE_METRICS ) )
+ /* Adjust advance width to the value contained in the hdmx table */
+ /* unless FT_LOAD_COMPUTE_METRICS is set or backwards compatibility */
+ /* mode of the v40 interpreter is active. See `ttinterp.h' for */
+ /* details on backwards compatibility mode. */
+ if (
+#ifdef TT_SUPPORT_SUBPIXEL_HINTING_MINIMAL
+ !( driver->interpreter_version == TT_INTERPRETER_VERSION_40 &&
+ ( loader->exec && loader->exec->backwards_compatibility ) ) &&
+#endif
+ !face->postscript.isFixedPitch &&
+ IS_HINTED( loader->load_flags ) &&
+ !( loader->load_flags & FT_LOAD_COMPUTE_METRICS ) )
{
FT_Byte* widthp;
@@ -1982,7 +2036,7 @@
size->root.metrics.x_ppem,
glyph_index );
-#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
+#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY
if ( driver->interpreter_version == TT_INTERPRETER_VERSION_38 )
{
@@ -2000,7 +2054,7 @@
}
else
-#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */
+#endif /* TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY */
{
if ( widthp )
@@ -2189,6 +2243,10 @@
#ifdef TT_USE_BYTECODE_INTERPRETER
FT_Bool pedantic = FT_BOOL( load_flags & FT_LOAD_PEDANTIC );
#endif
+#if defined TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY || \
+ defined TT_SUPPORT_SUBPIXEL_HINTING_MINIMAL
+ TT_Driver driver = (TT_Driver)FT_FACE_DRIVER( (TT_Face)glyph->face );
+#endif
face = (TT_Face)glyph->face;
@@ -2202,11 +2260,13 @@
if ( IS_HINTED( load_flags ) && !glyf_table_only )
{
TT_ExecContext exec;
- FT_Bool grayscale;
-
-#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
- TT_Driver driver = (TT_Driver)FT_FACE_DRIVER( face );
+ FT_Bool grayscale = TRUE;
+#ifdef TT_SUPPORT_SUBPIXEL_HINTING_MINIMAL
+ FT_Bool subpixel_hinting_lean;
+ FT_Bool grayscale_cleartype;
+#endif
+#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY
FT_Bool subpixel_hinting = FALSE;
#if 0
@@ -2218,7 +2278,7 @@
FT_Bool subpixel_positioned;
FT_Bool gray_cleartype;
#endif
-#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */
+#endif /* TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY */
FT_Bool reexecute = FALSE;
@@ -2239,7 +2299,26 @@
if ( !exec )
return FT_THROW( Could_Not_Find_Context );
-#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
+#ifdef TT_SUPPORT_SUBPIXEL_HINTING_MINIMAL
+ if ( driver->interpreter_version == TT_INTERPRETER_VERSION_40 )
+ {
+ subpixel_hinting_lean = TRUE;
+ grayscale_cleartype = !FT_BOOL( load_flags &
+ FT_LOAD_TARGET_LCD ||
+ load_flags &
+ FT_LOAD_TARGET_LCD_V );
+ exec->vertical_lcd_lean = FT_BOOL( load_flags &
+ FT_LOAD_TARGET_LCD_V );
+ }
+ else
+ {
+ subpixel_hinting_lean = FALSE;
+ grayscale_cleartype = FALSE;
+ exec->vertical_lcd_lean = FALSE;
+ }
+#endif
+
+#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY
if ( driver->interpreter_version == TT_INTERPRETER_VERSION_38 )
{
@@ -2296,18 +2375,23 @@
}
else
-#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */
+#endif /* TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY */
- {
+#ifdef TT_SUPPORT_SUBPIXEL_HINTING_MINIMAL
+ if ( driver->interpreter_version == TT_INTERPRETER_VERSION_40 )
+ grayscale = FT_BOOL( !subpixel_hinting_lean &&
+ FT_LOAD_TARGET_MODE( load_flags ) !=
+ FT_RENDER_MODE_MONO );
+ else
+#endif
grayscale = FT_BOOL( FT_LOAD_TARGET_MODE( load_flags ) !=
- FT_RENDER_MODE_MONO );
- }
+ FT_RENDER_MODE_MONO );
error = TT_Load_Context( exec, face, size );
if ( error )
return error;
-#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
+#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY
if ( driver->interpreter_version == TT_INTERPRETER_VERSION_38 )
{
@@ -2335,9 +2419,37 @@
}
else
-#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */
+#endif /* TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY */
{
+
+#ifdef TT_SUPPORT_SUBPIXEL_HINTING_MINIMAL
+ if ( driver->interpreter_version == TT_INTERPRETER_VERSION_40 )
+ {
+ /* a change from mono to subpixel rendering (and vice versa) */
+ /* requires a re-execution of the CVT program */
+ if ( subpixel_hinting_lean != exec->subpixel_hinting_lean )
+ {
+ FT_TRACE4(( "tt_loader_init: subpixel hinting change,"
+ " re-executing `prep' table\n" ));
+
+ exec->subpixel_hinting_lean = subpixel_hinting_lean;
+ reexecute = TRUE;
+ }
+
+ /* a change from colored to grayscale subpixel rendering (and */
+ /* vice versa) requires a re-execution of the CVT program */
+ if ( grayscale_cleartype != exec->grayscale_cleartype )
+ {
+ FT_TRACE4(( "tt_loader_init: grayscale subpixel hinting change,"
+ " re-executing `prep' table\n" ));
+
+ exec->grayscale_cleartype = grayscale_cleartype;
+ reexecute = TRUE;
+ }
+ }
+#endif
+
/* a change from mono to grayscale rendering (and vice versa) */
/* requires a re-execution of the CVT program */
if ( grayscale != exec->grayscale )
@@ -2370,10 +2482,11 @@
if ( exec->GS.instruct_control & 2 )
exec->GS = tt_default_graphics_state;
-#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
+#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY
/* 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 )
+ if ( driver->interpreter_version == TT_INTERPRETER_VERSION_38 &&
+ exec->GS.instruct_control & 4 )
exec->ignore_x_mode = 0;
#endif
diff --git a/src/truetype/ttgload.h b/src/truetype/ttgload.h
index 8e3255e..bfa29e4 100644
--- a/src/truetype/ttgload.h
+++ b/src/truetype/ttgload.h
@@ -4,7 +4,7 @@
/* */
/* TrueType Glyph Loader (specification). */
/* */
-/* Copyright 1996-2015 by */
+/* Copyright 1996-2016 by */
/* David Turner, Robert Wilhelm, and Werner Lemberg. */
/* */
/* This file is part of the FreeType project, and may only be used, */
@@ -16,8 +16,8 @@
/***************************************************************************/
-#ifndef __TTGLOAD_H__
-#define __TTGLOAD_H__
+#ifndef TTGLOAD_H_
+#define TTGLOAD_H_
#include <ft2build.h>
@@ -56,7 +56,7 @@ FT_BEGIN_HEADER
FT_END_HEADER
-#endif /* __TTGLOAD_H__ */
+#endif /* TTGLOAD_H_ */
/* END */
diff --git a/src/truetype/ttgxvar.c b/src/truetype/ttgxvar.c
index 5d4384e..c0d013c 100644
--- a/src/truetype/ttgxvar.c
+++ b/src/truetype/ttgxvar.c
@@ -4,7 +4,7 @@
/* */
/* TrueType GX Font Variation loader */
/* */
-/* Copyright 2004-2015 by */
+/* Copyright 2004-2016 by */
/* David Turner, Robert Wilhelm, Werner Lemberg, and George Williams. */
/* */
/* This file is part of the FreeType project, and may only be used, */
@@ -158,48 +158,49 @@
return NULL;
}
- if ( FT_NEW_ARRAY( points, n ) )
+ /* in the nested loops below we increase `i' twice; */
+ /* it is faster to simply allocate one more slot */
+ /* than to add another test within the loop */
+ if ( FT_NEW_ARRAY( points, n + 1 ) )
return NULL;
*point_cnt = n;
- i = 0;
+ first = 0;
+ i = 0;
while ( i < n )
{
runcnt = FT_GET_BYTE();
if ( runcnt & GX_PT_POINTS_ARE_WORDS )
{
runcnt &= GX_PT_POINT_RUN_COUNT_MASK;
- first = FT_GET_USHORT();
+ first += FT_GET_USHORT();
points[i++] = first;
- if ( runcnt < 1 || i + runcnt > n )
- goto Exit;
-
/* first point not included in run count */
for ( j = 0; j < runcnt; j++ )
{
first += FT_GET_USHORT();
points[i++] = first;
+ if ( i >= n )
+ break;
}
}
else
{
- first = FT_GET_BYTE();
+ first += FT_GET_BYTE();
points[i++] = first;
- if ( runcnt < 1 || i + runcnt > n )
- goto Exit;
-
for ( j = 0; j < runcnt; j++ )
{
first += FT_GET_BYTE();
points[i++] = first;
+ if ( i >= n )
+ break;
}
}
}
- Exit:
return points;
}
@@ -551,7 +552,7 @@
for ( i = 0; i < blend->tuplecount; i++ )
{
FT_TRACE5(( " [ " ));
- for ( j = 0 ; j < (FT_UInt)gvar_head.axisCount; j++ )
+ for ( j = 0; j < (FT_UInt)gvar_head.axisCount; j++ )
{
blend->tuplecoords[i * gvar_head.axisCount + j] =
FT_GET_SHORT() * 4; /* convert to FT_Fixed */
@@ -613,6 +614,11 @@
{
FT_TRACE6(( " axis coordinate %d (%.4f):\n",
i, blend->normalizedcoords[i] / 65536.0 ));
+ if ( !( tupleIndex & GX_TI_INTERMEDIATE_TUPLE ) )
+ FT_TRACE6(( " intermediate coordinates %d (%.4f, %.4f):\n",
+ i,
+ im_start_coords[i] / 65536.0,
+ im_end_coords[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. */
@@ -625,62 +631,74 @@
continue;
}
- else if ( blend->normalizedcoords[i] == 0 )
+ if ( blend->normalizedcoords[i] == 0 )
{
FT_TRACE6(( " axis coordinate is zero, stop\n" ));
apply = 0;
break;
}
- else if ( ( blend->normalizedcoords[i] < 0 && tuple_coords[i] > 0 ) ||
- ( blend->normalizedcoords[i] > 0 && tuple_coords[i] < 0 ) )
+ if ( blend->normalizedcoords[i] == tuple_coords[i] )
{
- FT_TRACE6(( " tuple coordinate value %.4f is exceeded, stop\n",
+ FT_TRACE6(( " tuple coordinate value %.4f fits perfectly\n",
tuple_coords[i] / 65536.0 ));
- apply = 0;
- break;
+ /* `apply' does not change */
+ continue;
}
- else if ( !( tupleIndex & GX_TI_INTERMEDIATE_TUPLE ) )
+ 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] )
- {
- 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;
- }
+ if ( blend->normalizedcoords[i] < FT_MIN( 0, tuple_coords[i] ) ||
+ blend->normalizedcoords[i] > FT_MAX( 0, tuple_coords[i] ) )
+ {
+ FT_TRACE6(( " tuple coordinate value %.4f is exceeded, stop\n",
+ tuple_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 ));
+ FT_TRACE6(( " tuple coordinate value %.4f fits\n",
+ tuple_coords[i] / 65536.0 ));
apply = FT_MulDiv( apply,
- blend->normalizedcoords[i] - im_start_coords[i],
- tuple_coords[i] - im_start_coords[i] );
+ blend->normalizedcoords[i],
+ tuple_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] );
+ /* intermediate tuple */
+
+ 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] );
+ }
}
}
@@ -1699,12 +1717,11 @@
/* modeled after `Ins_IUP */
static void
- tt_handle_deltas( FT_Outline* outline,
- FT_Vector* in_points,
- FT_Bool* has_delta )
+ tt_interpolate_deltas( FT_Outline* outline,
+ FT_Vector* out_points,
+ FT_Vector* in_points,
+ FT_Bool* has_delta )
{
- FT_Vector* out_points;
-
FT_Int first_point;
FT_Int end_point;
@@ -1719,8 +1736,6 @@
if ( !outline->n_contours )
return;
- out_points = outline->points;
-
contour = 0;
point = 0;
@@ -1824,6 +1839,7 @@
GX_Blend blend = face->blend;
FT_Vector* points_org = NULL;
+ FT_Vector* points_out = NULL;
FT_Bool* has_delta = NULL;
FT_Error error;
@@ -1855,6 +1871,7 @@
}
if ( FT_NEW_ARRAY( points_org, n_points ) ||
+ FT_NEW_ARRAY( points_out, n_points ) ||
FT_NEW_ARRAY( has_delta, n_points ) )
goto Fail1;
@@ -1877,7 +1894,8 @@
offsetToData = FT_GET_USHORT();
/* rough sanity test */
- if ( offsetToData + tupleCount * 4 > blend->gvar_size )
+ if ( offsetToData + ( tupleCount & GX_TC_TUPLE_COUNT_MASK ) * 4 >
+ blend->gvar_size )
{
FT_TRACE2(( "TT_Vary_Apply_Glyph_Deltas:"
" invalid glyph variation array header\n" ));
@@ -1905,6 +1923,9 @@
FT_TRACE5(( "gvar: there are %d tuples:\n",
tupleCount & GX_TC_TUPLE_COUNT_MASK ));
+ for ( j = 0; j < n_points; j++ )
+ points_org[j] = outline->points[j];
+
for ( i = 0; i < ( tupleCount & GX_TC_TUPLE_COUNT_MASK ); i++ )
{
FT_UInt tupleDataSize;
@@ -1959,10 +1980,10 @@
here = FT_Stream_FTell( stream );
+ FT_Stream_SeekSet( stream, offsetToData );
+
if ( tupleIndex & GX_TI_PRIVATE_POINT_NUMBERS )
{
- FT_Stream_SeekSet( stream, offsetToData );
-
localpoints = ft_var_readpackedpoints( stream,
blend->gvar_size,
&point_count );
@@ -1998,22 +2019,20 @@
/* this means that there are deltas for every point in the glyph */
for ( j = 0; j < n_points; j++ )
{
-#ifdef FT_DEBUG_LEVEL_TRACE
- FT_Vector point_org = outline->points[j];
-#endif
+ FT_Pos delta_x = FT_MulFix( deltas_x[j], apply );
+ FT_Pos delta_y = FT_MulFix( deltas_y[j], apply );
- outline->points[j].x += FT_MulFix( deltas_x[j], apply );
- outline->points[j].y += FT_MulFix( deltas_y[j], apply );
+ outline->points[j].x += delta_x;
+ outline->points[j].y += delta_y;
#ifdef FT_DEBUG_LEVEL_TRACE
- if ( ( point_org.x != outline->points[j].x ) ||
- ( point_org.y != outline->points[j].y ) )
+ if ( delta_x || delta_y )
{
FT_TRACE7(( " %d: (%d, %d) -> (%d, %d)\n",
j,
- point_org.x,
- point_org.y,
+ outline->points[j].x - delta_x,
+ outline->points[j].y - delta_y,
outline->points[j].x,
outline->points[j].y ));
count++;
@@ -2027,9 +2046,6 @@
#endif
}
- else if ( localpoints == NULL )
- ; /* failure, ignore it */
-
else
{
#ifdef FT_DEBUG_LEVEL_TRACE
@@ -2041,13 +2057,13 @@
/* IUP bytecode instruction */
for ( j = 0; j < n_points; j++ )
{
- points_org[j] = outline->points[j];
has_delta[j] = FALSE;
+ points_out[j] = points_org[j];
}
for ( j = 0; j < point_count; j++ )
{
- FT_UShort idx = localpoints[j];
+ FT_UShort idx = points[j];
if ( idx >= n_points )
@@ -2055,34 +2071,43 @@
has_delta[idx] = TRUE;
- outline->points[idx].x += FT_MulFix( deltas_x[j], apply );
- outline->points[idx].y += FT_MulFix( deltas_y[j], apply );
+ points_out[idx].x += FT_MulFix( deltas_x[j], apply );
+ points_out[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 );
+ tt_interpolate_deltas( outline,
+ points_out,
+ points_org,
+ has_delta );
-#ifdef FT_DEBUG_LEVEL_TRACE
FT_TRACE7(( " point deltas:\n" ));
- for ( j = 0; j < n_points; j++)
+ 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_Pos delta_x = points_out[j].x - points_org[j].x;
+ FT_Pos delta_y = points_out[j].y - points_org[j].y;
+
+
+ outline->points[j].x += delta_x;
+ outline->points[j].y += delta_y;
+
+#ifdef FT_DEBUG_LEVEL_TRACE
+ if ( delta_x || delta_y )
{
FT_TRACE7(( " %d: (%d, %d) -> (%d, %d)\n",
j,
- points_org[j].x,
- points_org[j].y,
+ outline->points[j].x - delta_x,
+ outline->points[j].y - delta_y,
outline->points[j].x,
outline->points[j].y ));
count++;
}
+#endif
}
+#ifdef FT_DEBUG_LEVEL_TRACE
if ( !count )
FT_TRACE7(( " none\n" ));
#endif
@@ -2111,6 +2136,7 @@
Fail1:
FT_FREE( points_org );
+ FT_FREE( points_out );
FT_FREE( has_delta );
return error;
diff --git a/src/truetype/ttgxvar.h b/src/truetype/ttgxvar.h
index dd1411f..aa8f6ea 100644
--- a/src/truetype/ttgxvar.h
+++ b/src/truetype/ttgxvar.h
@@ -4,7 +4,7 @@
/* */
/* TrueType GX Font Variation loader (specification) */
/* */
-/* Copyright 2004-2015 by */
+/* Copyright 2004-2016 by */
/* David Turner, Robert Wilhelm, Werner Lemberg and George Williams. */
/* */
/* This file is part of the FreeType project, and may only be used, */
@@ -16,8 +16,8 @@
/***************************************************************************/
-#ifndef __TTGXVAR_H__
-#define __TTGXVAR_H__
+#ifndef TTGXVAR_H_
+#define TTGXVAR_H_
#include <ft2build.h>
@@ -178,7 +178,7 @@ FT_BEGIN_HEADER
FT_END_HEADER
-#endif /* __TTGXVAR_H__ */
+#endif /* TTGXVAR_H_ */
/* END */
diff --git a/src/truetype/ttinterp.c b/src/truetype/ttinterp.c
index 1c1d7de..2d15ea7 100644
--- a/src/truetype/ttinterp.c
+++ b/src/truetype/ttinterp.c
@@ -4,7 +4,7 @@
/* */
/* TrueType bytecode interpreter (body). */
/* */
-/* Copyright 1996-2015 by */
+/* Copyright 1996-2016 by */
/* David Turner, Robert Wilhelm, and Werner Lemberg. */
/* */
/* This file is part of the FreeType project, and may only be used, */
@@ -26,10 +26,14 @@
#include FT_TRIGONOMETRY_H
#include FT_SYSTEM_H
#include FT_TRUETYPE_DRIVER_H
+#include FT_MULTIPLE_MASTERS_H
#include "ttinterp.h"
#include "tterrors.h"
#include "ttsubpix.h"
+#ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT
+#include "ttgxvar.h"
+#endif
#ifdef TT_USE_BYTECODE_INTERPRETER
@@ -45,10 +49,21 @@
#define FT_COMPONENT trace_ttinterp
-#define SUBPIXEL_HINTING \
+#define NO_SUBPIXEL_HINTING \
+ ( ((TT_Driver)FT_FACE_DRIVER( exc->face ))->interpreter_version == \
+ TT_INTERPRETER_VERSION_35 )
+
+#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY
+#define SUBPIXEL_HINTING_INFINALITY \
( ((TT_Driver)FT_FACE_DRIVER( exc->face ))->interpreter_version == \
TT_INTERPRETER_VERSION_38 )
+#endif
+#ifdef TT_SUPPORT_SUBPIXEL_HINTING_MINIMAL
+#define SUBPIXEL_HINTING_MINIMAL \
+ ( ((TT_Driver)FT_FACE_DRIVER( exc->face ))->interpreter_version == \
+ TT_INTERPRETER_VERSION_40 )
+#endif
#define PROJECT( v1, v2 ) \
exc->func_project( exc, (v1)->x - (v2)->x, (v1)->y - (v2)->y )
@@ -65,14 +80,6 @@
/*************************************************************************/
/* */
- /* Instruction dispatch function, as used by the interpreter. */
- /* */
- typedef void (*TInstruction_Function)( TT_ExecContext exc,
- FT_Long* args );
-
-
- /*************************************************************************/
- /* */
/* Two simple bounds-checking macros. */
/* */
#define BOUNDS( x, n ) ( (FT_UInt)(x) >= (FT_UInt)(n) )
@@ -85,20 +92,6 @@
#undef FAILURE
#define FAILURE 1
-#ifdef TT_CONFIG_OPTION_UNPATENTED_HINTING
-#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 ) do { } while (0)
-#endif
-
/*************************************************************************/
/* */
@@ -300,8 +293,8 @@
exec->stackSize = 0;
exec->glyphSize = 0;
- exec->stack = NULL;
- exec->glyphIns = NULL;
+ exec->stack = NULL;
+ exec->glyphIns = NULL;
exec->face = NULL;
exec->size = NULL;
@@ -407,6 +400,7 @@
exec->maxIDefs = size->max_instruction_defs;
exec->FDefs = size->function_defs;
exec->IDefs = size->instruction_defs;
+ exec->pointSize = size->point_size;
exec->tt_metrics = size->ttmetrics;
exec->metrics = size->metrics;
@@ -547,10 +541,6 @@
exec->GS.freeVector = exec->GS.projVector;
exec->GS.dualVector = exec->GS.projVector;
-#ifdef TT_CONFIG_OPTION_UNPATENTED_HINTING
- exec->GS.both_x_axis = TRUE;
-#endif
-
exec->GS.round_state = 1;
exec->GS.loop = 1;
@@ -577,10 +567,6 @@
{ 0x4000, 0 },
{ 0x4000, 0 },
-#ifdef TT_CONFIG_OPTION_UNPATENTED_HINTING
- TRUE,
-#endif
-
1, 64, 1,
TRUE, 68, 0, 0, 9, 3,
0, FALSE, 0, 1, 1, 1
@@ -700,17 +686,17 @@
/* IUP[0] */ PACK( 0, 0 ),
/* IUP[1] */ PACK( 0, 0 ),
- /* SHP[0] */ PACK( 0, 0 ),
- /* SHP[1] */ PACK( 0, 0 ),
+ /* SHP[0] */ PACK( 0, 0 ), /* loops */
+ /* SHP[1] */ PACK( 0, 0 ), /* loops */
/* SHC[0] */ PACK( 1, 0 ),
/* SHC[1] */ PACK( 1, 0 ),
/* SHZ[0] */ PACK( 1, 0 ),
/* SHZ[1] */ PACK( 1, 0 ),
- /* SHPIX */ PACK( 1, 0 ),
- /* IP */ PACK( 0, 0 ),
+ /* SHPIX */ PACK( 1, 0 ), /* loops */
+ /* IP */ PACK( 0, 0 ), /* loops */
/* MSIRP[0] */ PACK( 2, 0 ),
/* MSIRP[1] */ PACK( 2, 0 ),
- /* AlignRP */ PACK( 0, 0 ),
+ /* AlignRP */ PACK( 0, 0 ), /* loops */
/* RTDG */ PACK( 0, 0 ),
/* MIAP[0] */ PACK( 2, 0 ),
/* MIAP[1] */ PACK( 2, 0 ),
@@ -783,7 +769,7 @@
/* SANGW */ PACK( 1, 0 ),
/* AA */ PACK( 1, 0 ),
- /* FlipPT */ PACK( 0, 0 ),
+ /* FlipPT */ PACK( 0, 0 ), /* loops */
/* FlipRgON */ PACK( 2, 0 ),
/* FlipRgOFF */ PACK( 2, 0 ),
/* INS_$83 */ PACK( 0, 0 ),
@@ -801,8 +787,8 @@
/* INS_$8F */ PACK( 0, 0 ),
/* INS_$90 */ PACK( 0, 0 ),
- /* INS_$91 */ PACK( 0, 0 ),
- /* INS_$92 */ PACK( 0, 0 ),
+ /* GETVAR */ PACK( 0, 0 ), /* will be handled specially */
+ /* GETDATA */ PACK( 0, 1 ),
/* INS_$93 */ PACK( 0, 0 ),
/* INS_$94 */ PACK( 0, 0 ),
/* INS_$95 */ PACK( 0, 0 ),
@@ -1084,8 +1070,13 @@
"7 INS_$8F",
"7 INS_$90",
+#ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT
+ "6 GETVAR",
+ "7 GETDATA",
+#else
"7 INS_$91",
"7 INS_$92",
+#endif
"7 INS_$93",
"7 INS_$94",
"7 INS_$95",
@@ -1470,34 +1461,22 @@
{
if ( !exc->tt_metrics.ratio )
{
-#ifdef TT_CONFIG_OPTION_UNPATENTED_HINTING
- if ( exc->face->unpatented_hinting )
- {
- if ( exc->GS.both_x_axis )
- exc->tt_metrics.ratio = exc->tt_metrics.x_ratio;
- else
- exc->tt_metrics.ratio = exc->tt_metrics.y_ratio;
- }
- else
-#endif
- {
- if ( exc->GS.projVector.y == 0 )
- exc->tt_metrics.ratio = exc->tt_metrics.x_ratio;
+ if ( exc->GS.projVector.y == 0 )
+ exc->tt_metrics.ratio = exc->tt_metrics.x_ratio;
- else if ( exc->GS.projVector.x == 0 )
- exc->tt_metrics.ratio = exc->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;
+ else
+ {
+ FT_F26Dot6 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 );
- }
+ 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 exc->tt_metrics.ratio;
@@ -1595,7 +1574,7 @@
static FT_Short
GetShortIns( TT_ExecContext exc )
{
- /* Reading a byte stream so there is no endianess (DaveP) */
+ /* Reading a byte stream so there is no endianness (DaveP) */
exc->IP += 2;
return (FT_Short)( ( exc->code[exc->IP - 2] << 8 ) +
exc->code[exc->IP - 1] );
@@ -1676,6 +1655,10 @@
/* <InOut> */
/* zone :: The affected glyph zone. */
/* */
+ /* <Note> */
+ /* See `ttinterp.h' for details on backwards compatibility mode. */
+ /* `Touches' the point. */
+ /* */
static void
Direct_Move( TT_ExecContext exc,
TT_GlyphZone zone,
@@ -1685,19 +1668,28 @@
FT_F26Dot6 v;
-#ifdef TT_CONFIG_OPTION_UNPATENTED_HINTING
- FT_ASSERT( !exc->face->unpatented_hinting );
-#endif
-
v = exc->GS.freeVector.x;
if ( v != 0 )
{
-#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
- if ( !SUBPIXEL_HINTING ||
+#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY
+ if ( SUBPIXEL_HINTING_INFINALITY &&
( !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, exc->F_dot_P );
+ else
+#endif /* TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY */
+
+#ifdef TT_SUPPORT_SUBPIXEL_HINTING_MINIMAL
+ /* Exception to the post-IUP curfew: Allow the x component of */
+ /* diagonal moves, but only post-IUP. DejaVu tries to adjust */
+ /* diagonal stems like on `Z' and `z' post-IUP. */
+ if ( SUBPIXEL_HINTING_MINIMAL && !exc->backwards_compatibility )
+ zone->cur[point].x += FT_MulDiv( distance, v, exc->F_dot_P );
+ else
+#endif
+
+ if ( NO_SUBPIXEL_HINTING )
zone->cur[point].x += FT_MulDiv( distance, v, exc->F_dot_P );
zone->tags[point] |= FT_CURVE_TAG_TOUCH_X;
@@ -1707,7 +1699,13 @@
if ( v != 0 )
{
- zone->cur[point].y += FT_MulDiv( distance, v, exc->F_dot_P );
+#ifdef TT_SUPPORT_SUBPIXEL_HINTING_MINIMAL
+ if ( !( SUBPIXEL_HINTING_MINIMAL &&
+ exc->backwards_compatibility &&
+ exc->iupx_called &&
+ exc->iupy_called ) )
+#endif
+ zone->cur[point].y += FT_MulDiv( distance, v, exc->F_dot_P );
zone->tags[point] |= FT_CURVE_TAG_TOUCH_Y;
}
@@ -1740,10 +1738,6 @@
FT_F26Dot6 v;
-#ifdef TT_CONFIG_OPTION_UNPATENTED_HINTING
- FT_ASSERT( !exc->face->unpatented_hinting );
-#endif
-
v = exc->GS.freeVector.x;
if ( v != 0 )
@@ -1762,6 +1756,7 @@
/* */
/* The following versions are used whenever both vectors are both */
/* along one of the coordinate unit vectors, i.e. in 90% of the cases. */
+ /* See `ttinterp.h' for details on backwards compatibility mode. */
/* */
/*************************************************************************/
@@ -1772,12 +1767,19 @@
FT_UShort point,
FT_F26Dot6 distance )
{
- FT_UNUSED( exc );
+#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY
+ if ( SUBPIXEL_HINTING_INFINALITY && !exc->ignore_x_mode )
+ zone->cur[point].x += distance;
+ else
+#endif /* TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY */
+
+#ifdef TT_SUPPORT_SUBPIXEL_HINTING_MINIMAL
+ if ( SUBPIXEL_HINTING_MINIMAL && !exc->backwards_compatibility )
+ zone->cur[point].x += distance;
+ else
+#endif
-#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
- if ( !SUBPIXEL_HINTING ||
- !exc->ignore_x_mode )
-#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */
+ if ( NO_SUBPIXEL_HINTING )
zone->cur[point].x += distance;
zone->tags[point] |= FT_CURVE_TAG_TOUCH_X;
@@ -1792,8 +1794,14 @@
{
FT_UNUSED( exc );
- zone->cur[point].y += distance;
- zone->tags[point] |= FT_CURVE_TAG_TOUCH_Y;
+#ifdef TT_SUPPORT_SUBPIXEL_HINTING_MINIMAL
+ if ( !( SUBPIXEL_HINTING_MINIMAL &&
+ exc->backwards_compatibility &&
+ exc->iupx_called && exc->iupy_called ) )
+#endif
+ zone->cur[point].y += distance;
+
+ zone->tags[point] |= FT_CURVE_TAG_TOUCH_Y;
}
@@ -2072,7 +2080,7 @@
FT_F26Dot6 distance,
FT_F26Dot6 compensation )
{
- FT_F26Dot6 val;
+ FT_F26Dot6 val;
FT_UNUSED( exc );
@@ -2111,7 +2119,7 @@
/* Rounded distance. */
/* */
/* <Note> */
- /* The TrueType specification says very few about the relationship */
+ /* The TrueType specification says very little about the relationship */
/* between rounding and engine compensation. However, it seems from */
/* the description of super round that we should add the compensation */
/* before rounding. */
@@ -2336,10 +2344,6 @@
FT_Pos dx,
FT_Pos dy )
{
-#ifdef TT_CONFIG_OPTION_UNPATENTED_HINTING
- FT_ASSERT( !exc->face->unpatented_hinting );
-#endif
-
return TT_DotFix14( dx, dy,
exc->GS.projVector.x,
exc->GS.projVector.y );
@@ -2441,51 +2445,6 @@
static void
Compute_Funcs( TT_ExecContext exc )
{
-#ifdef TT_CONFIG_OPTION_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. */
- 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. */
- exc->GS.projVector.x = 0;
- exc->GS.projVector.y = 0;
- exc->GS.freeVector.x = 0;
- exc->GS.freeVector.y = 0;
-
- if ( exc->GS.both_x_axis )
- {
- exc->func_project = Project_x;
- exc->func_move = Direct_Move_X;
- exc->func_move_orig = Direct_Move_Orig_X;
- }
- else
- {
- exc->func_project = Project_y;
- exc->func_move = Direct_Move_Y;
- exc->func_move_orig = Direct_Move_Orig_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
- exc->func_dualproj = Dual_Project;
-
- /* Force recalculation of cached aspect ratio */
- exc->tt_metrics.ratio = 0;
-
- return;
- }
-#endif /* TT_CONFIG_OPTION_UNPATENTED_HINTING */
-
if ( exc->GS.freeVector.x == 0x4000 )
exc->F_dot_P = exc->GS.projVector.x;
else if ( exc->GS.freeVector.y == 0x4000 )
@@ -2625,13 +2584,20 @@
Ins_MPS( TT_ExecContext exc,
FT_Long* args )
{
- /* 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
+ if ( NO_SUBPIXEL_HINTING )
+ {
+ /* Microsoft's GDI bytecode interpreter always returns value 12; */
+ /* we return the current PPEM value instead. */
+ args[0] = exc->func_cur_ppem( exc );
+ }
+ else
+ {
+ /* A possible practical application of the MPS instruction is to */
+ /* implement optical scaling and similar features, which should be */
+ /* based on perceptual attributes, thus independent of the */
+ /* resolution. */
+ args[0] = exc->pointSize;
+ }
}
@@ -2924,7 +2890,7 @@
/* */
/* NEG[]: NEGate */
/* Opcode range: 0x65 */
- /* Stack: f26.6 --> f26.6 */
+ /* Stack: f26.6 --> f26.6 */
/* */
static void
Ins_NEG( FT_Long* args )
@@ -2969,8 +2935,6 @@
Ins_RS( TT_ExecContext exc,
FT_Long* args )
{
-#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
-
FT_ULong I = (FT_ULong)args[0];
@@ -2983,9 +2947,10 @@
}
else
{
+#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY
/* subpixel hinting - avoid Typeman Dstroke and */
/* IStroke and Vacuform rounds */
- if ( SUBPIXEL_HINTING &&
+ if ( SUBPIXEL_HINTING_INFINALITY &&
exc->ignore_x_mode &&
( ( I == 24 &&
( exc->face->sph_found_func_flags &
@@ -3000,25 +2965,9 @@
exc->iup_called ) ) )
args[0] = 0;
else
+#endif /* TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY */
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 */
}
@@ -3181,7 +3130,7 @@
/*************************************************************************/
/* */
/* MAX[]: MAXimum */
- /* Opcode range: 0x68 */
+ /* Opcode range: 0x8B */
/* Stack: int32? int32? --> int32 */
/* */
static void
@@ -3195,7 +3144,7 @@
/*************************************************************************/
/* */
/* MIN[]: MINimum */
- /* Opcode range: 0x69 */
+ /* Opcode range: 0x8C */
/* Stack: int32? int32? --> int32 */
/* */
static void
@@ -3500,7 +3449,7 @@
TT_DefRecord* rec;
TT_DefRecord* limit;
-#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
+#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY
/* arguments to opcodes are skipped by `SKIP_Code' */
FT_Byte opcode_pattern[9][12] = {
/* #0 inline delta function 1 */
@@ -3598,7 +3547,7 @@
FT_UShort opcode_pointer[9] = { 0, 0, 0, 0, 0, 0, 0, 0, 0 };
FT_UShort opcode_size[9] = { 12, 8, 8, 6, 7, 4, 5, 4, 2 };
FT_UShort i;
-#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */
+#endif /* TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY */
/* some font programs are broken enough to redefine functions! */
@@ -3643,7 +3592,7 @@
if ( n > exc->maxFunc )
exc->maxFunc = (FT_UInt16)n;
-#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
+#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY
/* We don't know for sure these are typeman functions, */
/* however they are only active when RS 22 is called */
if ( n >= 64 && n <= 66 )
@@ -3656,9 +3605,9 @@
while ( SkipCode( exc ) == SUCCESS )
{
-#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
+#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY
- if ( SUBPIXEL_HINTING )
+ if ( SUBPIXEL_HINTING_INFINALITY )
{
for ( i = 0; i < opcode_patterns; i++ )
{
@@ -3765,7 +3714,7 @@
( exc->face->sph_found_func_flags & SPH_FDEF_INLINE_DELTA_2 ) );
}
-#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */
+#endif /* TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY */
switch ( exc->opcode )
{
@@ -3794,9 +3743,9 @@
TT_CallRec* pRec;
-#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
+#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY
exc->sph_in_func_flags = 0x0000;
-#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */
+#endif /* TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY */
if ( exc->callTop <= 0 ) /* We encountered an ENDF without a call */
{
@@ -3882,8 +3831,8 @@
if ( !def->active )
goto Fail;
-#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
- if ( SUBPIXEL_HINTING &&
+#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY
+ if ( SUBPIXEL_HINTING_INFINALITY &&
exc->ignore_x_mode &&
( ( exc->iup_called &&
( exc->sph_tweak_flags & SPH_TWEAK_NO_CALL_AFTER_IUP ) ) ||
@@ -3891,7 +3840,7 @@
goto Fail;
else
exc->sph_in_func_flags = def->sph_fdef_flags;
-#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */
+#endif /* TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY */
/* check the call stack */
if ( exc->callTop >= exc->callSize )
@@ -3970,14 +3919,14 @@
if ( !def->active )
goto Fail;
-#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
- if ( SUBPIXEL_HINTING &&
+#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY
+ if ( SUBPIXEL_HINTING_INFINALITY &&
exc->ignore_x_mode &&
( def->sph_fdef_flags & SPH_FDEF_VACUFORM_ROUND_1 ) )
goto Fail;
else
exc->sph_in_func_flags = def->sph_fdef_flags;
-#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */
+#endif /* TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY */
/* check stack */
if ( exc->callTop >= exc->callSize )
@@ -4070,6 +4019,7 @@
exc->error = FT_THROW( Nested_DEFS );
return;
case 0x2D: /* ENDF */
+ def->end = exc->IP;
return;
}
}
@@ -4289,16 +4239,12 @@
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 );
}
@@ -4320,7 +4266,6 @@
&exc->GS.projVector ) == SUCCESS )
{
exc->GS.dualVector = exc->GS.projVector;
- GUESS_VECTOR( freeVector );
Compute_Funcs( exc );
}
}
@@ -4341,7 +4286,6 @@
(FT_UShort)args[0],
&exc->GS.freeVector ) == SUCCESS )
{
- GUESS_VECTOR( projVector );
Compute_Funcs( exc );
}
}
@@ -4356,7 +4300,6 @@
static void
Ins_SFVTPV( TT_ExecContext exc )
{
- GUESS_VECTOR( projVector );
exc->GS.freeVector = exc->GS.projVector;
Compute_Funcs( exc );
}
@@ -4385,7 +4328,6 @@
Normalize( X, Y, &exc->GS.projVector );
exc->GS.dualVector = exc->GS.projVector;
- GUESS_VECTOR( freeVector );
Compute_Funcs( exc );
}
@@ -4411,7 +4353,6 @@
X = S;
Normalize( X, Y, &exc->GS.freeVector );
- GUESS_VECTOR( projVector );
Compute_Funcs( exc );
}
@@ -4426,21 +4367,8 @@
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
}
@@ -4454,21 +4382,8 @@
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
}
@@ -4588,7 +4503,7 @@
/* */
/* FLIPOFF[]: Set auto-FLIP to OFF */
/* Opcode range: 0x4E */
- /* Stack: --> */
+ /* Stack: --> */
/* */
static void
Ins_FLIPOFF( TT_ExecContext exc )
@@ -4907,13 +4822,13 @@
}
}
-#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
+#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY
/* Disable Type 2 Vacuform Rounds - e.g. Arial Narrow */
- if ( SUBPIXEL_HINTING &&
- exc->ignore_x_mode &&
- FT_ABS( D ) == 64 )
+ if ( SUBPIXEL_HINTING_INFINALITY &&
+ exc->ignore_x_mode &&
+ FT_ABS( D ) == 64 )
D += 1;
-#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */
+#endif /* TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY */
args[0] = D;
}
@@ -4998,7 +4913,6 @@
}
Normalize( A, B, &exc->GS.projVector );
- GUESS_VECTOR( freeVector );
Compute_Funcs( exc );
}
@@ -5170,12 +5084,23 @@
exc->GS.instruct_control &= ~(FT_Byte)Kf;
exc->GS.instruct_control |= (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 );
+ {
+#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY
+ /* INSTCTRL modifying flag 3 also has an effect */
+ /* outside of the CVT program */
+ if ( SUBPIXEL_HINTING_INFINALITY )
+ exc->ignore_x_mode = FT_BOOL( L == 4 );
#endif
+
+#ifdef TT_SUPPORT_SUBPIXEL_HINTING_MINIMAL
+ /* Native ClearType fonts sign a waiver that turns off all backwards */
+ /* compatibility hacks and lets them program points to the grid like */
+ /* it's 1996. They might sign a waiver for just one glyph, though. */
+ if ( SUBPIXEL_HINTING_MINIMAL )
+ exc->backwards_compatibility = !FT_BOOL( L == 4 );
+#endif
+ }
}
@@ -5260,6 +5185,15 @@
FT_UShort point;
+#ifdef TT_SUPPORT_SUBPIXEL_HINTING_MINIMAL
+ /* See `ttinterp.h' for details on backwards compatibility mode. */
+ if ( SUBPIXEL_HINTING_MINIMAL &&
+ exc->backwards_compatibility &&
+ exc->iupx_called &&
+ exc->iupy_called )
+ goto Fail;
+#endif
+
if ( exc->top < exc->GS.loop )
{
if ( exc->pedantic_hinting )
@@ -5306,6 +5240,15 @@
FT_UShort I, K, L;
+#ifdef TT_SUPPORT_SUBPIXEL_HINTING_MINIMAL
+ /* See `ttinterp.h' for details on backwards compatibility mode. */
+ if ( SUBPIXEL_HINTING_MINIMAL &&
+ exc->backwards_compatibility &&
+ exc->iupx_called &&
+ exc->iupy_called )
+ return;
+#endif
+
K = (FT_UShort)args[1];
L = (FT_UShort)args[0];
@@ -5335,6 +5278,15 @@
FT_UShort I, K, L;
+#ifdef TT_SUPPORT_SUBPIXEL_HINTING_MINIMAL
+ /* See `ttinterp.h' for details on backwards compatibility mode. */
+ if ( SUBPIXEL_HINTING_MINIMAL &&
+ exc->backwards_compatibility &&
+ exc->iupx_called &&
+ exc->iupy_called )
+ return;
+#endif
+
K = (FT_UShort)args[1];
L = (FT_UShort)args[0];
@@ -5387,31 +5339,14 @@
d = PROJECT( zp.cur + p, zp.org + p );
-#ifdef TT_CONFIG_OPTION_UNPATENTED_HINTING
- if ( exc->face->unpatented_hinting )
- {
- if ( exc->GS.both_x_axis )
- {
- *x = d;
- *y = 0;
- }
- else
- {
- *x = 0;
- *y = d;
- }
- }
- else
-#endif
- {
- *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 );
- }
+ *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;
}
+ /* See `ttinterp.h' for details on backwards compatibility mode. */
static void
Move_Zp2_Point( TT_ExecContext exc,
FT_UShort point,
@@ -5419,35 +5354,28 @@
FT_F26Dot6 dy,
FT_Bool touch )
{
-#ifdef TT_CONFIG_OPTION_UNPATENTED_HINTING
- if ( exc->face->unpatented_hinting )
+ if ( exc->GS.freeVector.x != 0 )
{
- if ( exc->GS.both_x_axis )
- {
- exc->zp2.cur[point].x += dx;
- if ( touch )
- exc->zp2.tags[point] |= FT_CURVE_TAG_TOUCH_X;
- }
- else
- {
- exc->zp2.cur[point].y += dy;
- if ( touch )
- exc->zp2.tags[point] |= FT_CURVE_TAG_TOUCH_Y;
- }
- return;
- }
+#ifdef TT_SUPPORT_SUBPIXEL_HINTING_MINIMAL
+ if ( !( SUBPIXEL_HINTING_MINIMAL &&
+ exc->backwards_compatibility ) )
#endif
+ exc->zp2.cur[point].x += dx;
- if ( exc->GS.freeVector.x != 0 )
- {
- exc->zp2.cur[point].x += dx;
if ( touch )
exc->zp2.tags[point] |= FT_CURVE_TAG_TOUCH_X;
}
if ( exc->GS.freeVector.y != 0 )
{
- exc->zp2.cur[point].y += dy;
+#ifdef TT_SUPPORT_SUBPIXEL_HINTING_MINIMAL
+ if ( !( SUBPIXEL_HINTING_MINIMAL &&
+ exc->backwards_compatibility &&
+ exc->iupx_called &&
+ exc->iupy_called ) )
+#endif
+ exc->zp2.cur[point].y += dy;
+
if ( touch )
exc->zp2.tags[point] |= FT_CURVE_TAG_TOUCH_Y;
}
@@ -5494,13 +5422,12 @@
}
}
else
-#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
+#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY
/* doesn't follow Cleartype spec but produces better result */
- if ( SUBPIXEL_HINTING &&
- exc->ignore_x_mode )
+ if ( SUBPIXEL_HINTING_INFINALITY && exc->ignore_x_mode )
Move_Zp2_Point( exc, point, 0, dy, TRUE );
else
-#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */
+#endif /* TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY */
Move_Zp2_Point( exc, point, dx, dy, TRUE );
exc->GS.loop--;
@@ -5628,9 +5555,15 @@
{
FT_F26Dot6 dx, dy;
FT_UShort point;
-#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
+#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY
FT_Int B1, B2;
#endif
+#ifdef TT_SUPPORT_SUBPIXEL_HINTING_MINIMAL
+ FT_Bool in_twilight = exc->GS.gep0 == 0 || \
+ exc->GS.gep1 == 0 || \
+ exc->GS.gep2 == 0;
+#endif
+
if ( exc->top < exc->GS.loop + 1 )
@@ -5640,26 +5573,8 @@
goto Fail;
}
-#ifdef TT_CONFIG_OPTION_UNPATENTED_HINTING
- if ( exc->face->unpatented_hinting )
- {
- if ( exc->GS.both_x_axis )
- {
- dx = (FT_UInt32)args[0];
- dy = 0;
- }
- else
- {
- dx = 0;
- dy = (FT_UInt32)args[0];
- }
- }
- else
-#endif
- {
- dx = TT_MulFix14( args[0], exc->GS.freeVector.x );
- dy = TT_MulFix14( args[0], exc->GS.freeVector.y );
- }
+ dx = TT_MulFix14( args[0], exc->GS.freeVector.x );
+ dy = TT_MulFix14( args[0], exc->GS.freeVector.y );
while ( exc->GS.loop > 0 )
{
@@ -5676,7 +5591,8 @@
}
}
else
-#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
+#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY
+ if ( SUBPIXEL_HINTING_INFINALITY )
{
/* If not using ignore_x_mode rendering, allow ZP2 move. */
/* If inline deltas aren't allowed, skip ZP2 move. */
@@ -5686,8 +5602,7 @@
/* - 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 )
+ if ( exc->ignore_x_mode )
{
/* save point for later comparison */
if ( exc->GS.freeVector.y != 0 )
@@ -5751,15 +5666,30 @@
else
Move_Zp2_Point( exc, point, dx, dy, TRUE );
}
+ else
+#endif
+#ifdef TT_SUPPORT_SUBPIXEL_HINTING_MINIMAL
+ if ( SUBPIXEL_HINTING_MINIMAL &&
+ exc->backwards_compatibility )
+ {
+ /* Special case: allow SHPIX to move points in the twilight zone. */
+ /* Otherwise, treat SHPIX the same as DELTAP. Unbreaks various */
+ /* fonts such as older versions of Rokkitt and DTL Argo T Light */
+ /* that would glitch severly after calling ALIGNRP after a blocked */
+ /* SHPIX. */
+ if ( in_twilight ||
+ ( !( exc->iupx_called && exc->iupy_called ) &&
+ ( ( exc->is_composite && exc->GS.freeVector.y != 0 ) ||
+ ( exc->zp2.tags[point] & FT_CURVE_TAG_TOUCH_Y ) ) ) )
+ Move_Zp2_Point( exc, point, 0, dy, TRUE );
+ }
+ else
+#endif
+ Move_Zp2_Point( exc, point, dx, dy, TRUE );
+#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY
Skip:
-
-#else /* !TT_CONFIG_OPTION_SUBPIXEL_HINTING */
-
- Move_Zp2_Point( exc, point, dx, dy, TRUE );
-
-#endif /* !TT_CONFIG_OPTION_SUBPIXEL_HINTING */
-
+#endif
exc->GS.loop--;
}
@@ -5779,14 +5709,13 @@
Ins_MSIRP( TT_ExecContext exc,
FT_Long* args )
{
- FT_UShort point;
+ FT_UShort point = 0;
FT_F26Dot6 distance;
+#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY
+ FT_F26Dot6 control_value_cutin = 0;
-#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
- FT_F26Dot6 control_value_cutin = 0; /* pacify compiler */
-
- if ( SUBPIXEL_HINTING )
+ if ( SUBPIXEL_HINTING_INFINALITY )
{
control_value_cutin = exc->GS.control_value_cutin;
@@ -5795,8 +5724,7 @@
!( exc->sph_tweak_flags & SPH_TWEAK_NORMAL_ROUND ) )
control_value_cutin = 0;
}
-
-#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */
+#endif /* TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY */
point = (FT_UShort)args[0];
@@ -5819,14 +5747,14 @@
distance = PROJECT( exc->zp1.cur + point, exc->zp0.cur + exc->GS.rp0 );
-#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
+#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY
/* subpixel hinting - make MSIRP respect CVT cut-in; */
- if ( SUBPIXEL_HINTING &&
+ if ( SUBPIXEL_HINTING_INFINALITY &&
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 */
+#endif /* TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY */
exc->func_move( exc, &exc->zp1, point, args[1] - distance );
@@ -5865,10 +5793,10 @@
if ( ( exc->opcode & 1 ) != 0 )
{
cur_dist = FAST_PROJECT( &exc->zp0.cur[point] );
-#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
- if ( SUBPIXEL_HINTING &&
- exc->ignore_x_mode &&
- exc->GS.freeVector.x != 0 )
+#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY
+ if ( SUBPIXEL_HINTING_INFINALITY &&
+ exc->ignore_x_mode &&
+ exc->GS.freeVector.x != 0 )
distance = Round_None(
exc,
cur_dist,
@@ -5911,14 +5839,14 @@
cvtEntry = (FT_ULong)args[1];
point = (FT_UShort)args[0];
-#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
- if ( SUBPIXEL_HINTING &&
+#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY
+ if ( SUBPIXEL_HINTING_INFINALITY &&
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 */
+#endif /* TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY */
if ( BOUNDS( point, exc->zp0.n_points ) ||
BOUNDSL( cvtEntry, exc->cvtSize ) )
@@ -5952,27 +5880,27 @@
if ( exc->GS.gep0 == 0 ) /* If in twilight zone */
{
-#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
+#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY
/* Only adjust if not in sph_compatibility_mode or ignore_x_mode. */
/* Determined via experimentation and may be incorrect... */
- if ( !SUBPIXEL_HINTING ||
- ( !exc->ignore_x_mode ||
- !exc->face->sph_compatibility_mode ) )
-#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */
+ if ( !( SUBPIXEL_HINTING_INFINALITY &&
+ ( exc->ignore_x_mode &&
+ exc->face->sph_compatibility_mode ) ) )
+#endif /* TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY */
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 &&
+#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY
+ if ( SUBPIXEL_HINTING_INFINALITY &&
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 */
+#endif /* TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY */
org_dist = FAST_PROJECT( &exc->zp0.cur[point] );
@@ -5981,10 +5909,10 @@
if ( FT_ABS( distance - org_dist ) > control_value_cutin )
distance = org_dist;
-#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
- if ( SUBPIXEL_HINTING &&
- exc->ignore_x_mode &&
- exc->GS.freeVector.x != 0 )
+#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY
+ if ( SUBPIXEL_HINTING_INFINALITY &&
+ exc->ignore_x_mode &&
+ exc->GS.freeVector.x != 0 )
distance = Round_None( exc,
distance,
exc->tt_metrics.compensations[0] );
@@ -6013,19 +5941,19 @@
Ins_MDRP( TT_ExecContext exc,
FT_Long* args )
{
- FT_UShort point;
+ FT_UShort point = 0;
FT_F26Dot6 org_dist, distance, minimum_distance;
minimum_distance = exc->GS.minimum_distance;
-#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
- if ( SUBPIXEL_HINTING &&
+#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY
+ if ( SUBPIXEL_HINTING_INFINALITY &&
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 */
+#endif /* TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY */
point = (FT_UShort)args[0];
@@ -6089,10 +6017,10 @@
if ( ( exc->opcode & 4 ) != 0 )
{
-#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
- if ( SUBPIXEL_HINTING &&
- exc->ignore_x_mode &&
- exc->GS.freeVector.x != 0 )
+#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY
+ if ( SUBPIXEL_HINTING_INFINALITY &&
+ exc->ignore_x_mode &&
+ exc->GS.freeVector.x != 0 )
distance = Round_None(
exc,
org_dist,
@@ -6160,11 +6088,11 @@
org_dist,
control_value_cutin,
minimum_distance;
-#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
+#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY
FT_Int B1 = 0; /* pacify compiler */
FT_Int B2 = 0;
FT_Bool reverse_move = FALSE;
-#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */
+#endif /* TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY */
minimum_distance = exc->GS.minimum_distance;
@@ -6172,13 +6100,13 @@
point = (FT_UShort)args[0];
cvtEntry = (FT_ULong)( args[1] + 1 );
-#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
- if ( SUBPIXEL_HINTING &&
+#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY
+ if ( SUBPIXEL_HINTING_INFINALITY &&
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 */
+#endif /* TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY */
/* XXX: UNDOCUMENTED! cvt[-1] = 0 always */
@@ -6231,8 +6159,8 @@
cvt_dist = -cvt_dist;
}
-#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
- if ( SUBPIXEL_HINTING &&
+#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY
+ if ( SUBPIXEL_HINTING_INFINALITY &&
exc->ignore_x_mode &&
exc->GS.freeVector.y != 0 &&
( exc->sph_tweak_flags & SPH_TWEAK_TIMES_NEW_ROMAN_HACK ) )
@@ -6242,7 +6170,7 @@
else if ( cur_dist > 64 && cur_dist < 84 )
cvt_dist += 32;
}
-#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */
+#endif /* TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY */
/* control value cut-in and round */
@@ -6277,16 +6205,16 @@
else
{
-#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
+#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY
/* do cvt cut-in always in MIRP for sph */
- if ( SUBPIXEL_HINTING &&
+ if ( SUBPIXEL_HINTING_INFINALITY &&
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 */
+#endif /* TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY */
distance = Round_None(
exc,
@@ -6310,8 +6238,8 @@
}
}
-#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
- if ( SUBPIXEL_HINTING )
+#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY
+ if ( SUBPIXEL_HINTING_INFINALITY )
{
B1 = exc->zp1.cur[point].y;
@@ -6328,12 +6256,12 @@
( exc->sph_tweak_flags & SPH_TWEAK_COURIER_NEW_2_HACK ) )
distance += 64;
}
-#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */
+#endif /* TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY */
exc->func_move( exc, &exc->zp1, point, distance - cur_dist );
-#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
- if ( SUBPIXEL_HINTING )
+#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY
+ if ( SUBPIXEL_HINTING_INFINALITY )
{
B2 = exc->zp1.cur[point].y;
@@ -6357,7 +6285,7 @@
exc->func_move( exc, &exc->zp1, point, -( distance - cur_dist ) );
}
-#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */
+#endif /* TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY */
Fail:
exc->GS.rp1 = exc->GS.rp0;
@@ -6382,8 +6310,8 @@
FT_F26Dot6 distance;
-#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
- if ( SUBPIXEL_HINTING &&
+#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY
+ if ( SUBPIXEL_HINTING_INFINALITY &&
exc->ignore_x_mode &&
exc->iup_called &&
( exc->sph_tweak_flags & SPH_TWEAK_NO_ALIGNRP_AFTER_IUP ) )
@@ -6391,7 +6319,7 @@
exc->error = FT_THROW( Invalid_Reference );
goto Fail;
}
-#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */
+#endif /* TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY */
if ( exc->top < exc->GS.loop ||
BOUNDS( exc->GS.rp0, exc->zp0.n_points ) )
@@ -6506,6 +6434,7 @@
R.x = FT_MulDiv( val, dax, discriminant );
R.y = FT_MulDiv( val, day, discriminant );
+ /* XXX: Block in backwards_compatibility and/or post-IUP? */
exc->zp2.cur[point].x = exc->zp1.cur[a0].x + R.x;
exc->zp2.cur[point].y = exc->zp1.cur[a0].y + R.y;
}
@@ -6513,6 +6442,7 @@
{
/* else, take the middle of the middles of A and B */
+ /* XXX: Block in backwards_compatibility and/or post-IUP? */
exc->zp2.cur[point].x = ( exc->zp1.cur[a0].x +
exc->zp1.cur[a1].x +
exc->zp0.cur[b0].x +
@@ -6901,6 +6831,23 @@
FT_Short contour; /* current contour */
+#ifdef TT_SUPPORT_SUBPIXEL_HINTING_MINIMAL
+ /* See `ttinterp.h' for details on backwards compatibility mode. */
+ /* Allow IUP until it has been called on both axes. Immediately */
+ /* return on subsequent ones. */
+ if ( SUBPIXEL_HINTING_MINIMAL &&
+ exc->backwards_compatibility )
+ {
+ if ( exc->iupx_called && exc->iupy_called )
+ return;
+
+ if ( exc->opcode & 1 )
+ exc->iupx_called = TRUE;
+ else
+ exc->iupy_called = TRUE;
+ }
+#endif
+
/* ignore empty outlines */
if ( exc->pts.n_contours == 0 )
return;
@@ -6924,15 +6871,15 @@
contour = 0;
point = 0;
-#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
- if ( SUBPIXEL_HINTING &&
- exc->ignore_x_mode )
+#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY
+ if ( SUBPIXEL_HINTING_INFINALITY &&
+ exc->ignore_x_mode )
{
exc->iup_called = TRUE;
if ( exc->sph_tweak_flags & SPH_TWEAK_SKIP_IUP )
return;
}
-#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */
+#endif /* TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY */
do
{
@@ -7004,37 +6951,16 @@
FT_UShort A;
FT_ULong C, P;
FT_Long B;
-#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
+#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY
FT_UShort B1, B2;
- if ( SUBPIXEL_HINTING &&
+ if ( SUBPIXEL_HINTING_INFINALITY &&
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 ( exc->face->unpatented_hinting )
- {
- FT_Long n = args[0] * 2;
-
-
- if ( exc->args < n )
- {
- if ( exc->pedantic_hinting )
- exc->error = FT_THROW( Too_Few_Arguments );
- n = exc->args;
- }
-
- exc->args -= n;
- exc->new_top = exc->args;
- return;
- }
-#endif
+#endif /* TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY */
P = (FT_ULong)exc->func_cur_ppem( exc );
nump = (FT_ULong)args[0]; /* some points theoretically may occur more
@@ -7088,9 +7014,9 @@
B++;
B *= 1L << ( 6 - exc->GS.delta_shift );
-#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
+#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY
- if ( SUBPIXEL_HINTING )
+ if ( SUBPIXEL_HINTING_INFINALITY )
{
/*
* Allow delta move if
@@ -7147,9 +7073,25 @@
}
}
else
-#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */
+#endif /* TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY */
+
+ {
- exc->func_move( exc, &exc->zp0, A, B );
+#ifdef TT_SUPPORT_SUBPIXEL_HINTING_MINIMAL
+ /* See `ttinterp.h' for details on backwards compatibility */
+ /* mode. */
+ if ( SUBPIXEL_HINTING_MINIMAL &&
+ exc->backwards_compatibility )
+ {
+ if ( !( exc->iupx_called && exc->iupy_called ) &&
+ ( ( exc->is_composite && exc->GS.freeVector.y != 0 ) ||
+ ( exc->zp0.tags[A] & FT_CURVE_TAG_TOUCH_Y ) ) )
+ exc->func_move( exc, &exc->zp0, A, B );
+ }
+ else
+#endif
+ exc->func_move( exc, &exc->zp0, A, B );
+ }
}
}
else
@@ -7177,26 +7119,6 @@
FT_Long B;
-#ifdef TT_CONFIG_OPTION_UNPATENTED_HINTING
- /* Delta hinting is covered by US Patent 5159668. */
- if ( exc->face->unpatented_hinting )
- {
- FT_Long n = args[0] * 2;
-
-
- if ( exc->args < n )
- {
- if ( exc->pedantic_hinting )
- exc->error = FT_THROW( Too_Few_Arguments );
- n = exc->args;
- }
-
- exc->args -= n;
- exc->new_top = exc->args;
- return;
- }
-#endif
-
P = (FT_ULong)exc->func_cur_ppem( exc );
nump = (FT_ULong)args[0];
@@ -7285,20 +7207,21 @@
Ins_GETINFO( TT_ExecContext exc,
FT_Long* args )
{
- FT_Long K;
+ FT_Long K;
+ TT_Driver driver = (TT_Driver)FT_FACE_DRIVER( exc->face );
K = 0;
-#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
+#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY
/********************************/
/* RASTERIZER VERSION */
/* Selector Bit: 0 */
/* Return Bit(s): 0-7 */
/* */
- if ( SUBPIXEL_HINTING &&
- ( args[0] & 1 ) != 0 &&
- exc->subpixel_hinting )
+ if ( SUBPIXEL_HINTING_INFINALITY &&
+ ( args[0] & 1 ) != 0 &&
+ exc->subpixel_hinting )
{
if ( exc->ignore_x_mode )
{
@@ -7312,9 +7235,9 @@
K = TT_INTERPRETER_VERSION_38;
}
else
-#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */
+#endif /* TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY */
if ( ( args[0] & 1 ) != 0 )
- K = TT_INTERPRETER_VERSION_35;
+ K = driver->interpreter_version;
/********************************/
/* GLYPH ROTATED */
@@ -7322,7 +7245,7 @@
/* Return Bit(s): 8 */
/* */
if ( ( args[0] & 2 ) != 0 && exc->tt_metrics.rotated )
- K |= 0x80;
+ K |= 1 << 8;
/********************************/
/* GLYPH STRETCHED */
@@ -7330,19 +7253,83 @@
/* Return Bit(s): 9 */
/* */
if ( ( args[0] & 4 ) != 0 && exc->tt_metrics.stretched )
- K |= 1 << 8;
+ K |= 1 << 9;
+#ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT
/********************************/
- /* HINTING FOR GRAYSCALE */
+ /* VARIATION GLYPH */
+ /* Selector Bit: 3 */
+ /* Return Bit(s): 10 */
+ /* */
+ /* XXX: UNDOCUMENTED! */
+ if ( (args[0] & 8 ) != 0 && exc->face->blend )
+ K |= 1 << 10;
+#endif
+
+ /********************************/
+ /* BI-LEVEL HINTING AND */
+ /* GRAYSCALE RENDERING */
/* Selector Bit: 5 */
/* Return Bit(s): 12 */
/* */
if ( ( args[0] & 32 ) != 0 && exc->grayscale )
K |= 1 << 12;
-#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
+#ifdef TT_SUPPORT_SUBPIXEL_HINTING_MINIMAL
+ if ( SUBPIXEL_HINTING_MINIMAL )
+ {
+ /********************************/
+ /* HINTING FOR SUBPIXEL */
+ /* Selector Bit: 6 */
+ /* Return Bit(s): 13 */
+ /* */
+ /* v40 does subpixel hinting by default. */
+ if ( ( args[0] & 64 ) != 0 )
+ K |= 1 << 13;
+
+ /********************************/
+ /* VERTICAL LCD SUBPIXELS? */
+ /* Selector Bit: 8 */
+ /* Return Bit(s): 15 */
+ /* */
+ if ( ( args[0] & 256 ) != 0 && exc->vertical_lcd_lean )
+ K |= 1 << 15;
+
+ /********************************/
+ /* SUBPIXEL POSITIONED? */
+ /* Selector Bit: 10 */
+ /* Return Bit(s): 17 */
+ /* */
+ /* XXX: FreeType supports it, dependent on what client does? */
+ if ( ( args[0] & 1024 ) != 0 )
+ K |= 1 << 17;
+
+ /********************************/
+ /* SYMMETRICAL SMOOTHING */
+ /* Selector Bit: 11 */
+ /* Return Bit(s): 18 */
+ /* */
+ /* The only smoothing method FreeType supports unless someone sets */
+ /* FT_LOAD_TARGET_MONO. */
+ if ( ( args[0] & 2048 ) != 0 )
+ K |= 1 << 18;
+
+ /********************************/
+ /* CLEARTYPE HINTING AND */
+ /* GRAYSCALE RENDERING */
+ /* Selector Bit: 12 */
+ /* Return Bit(s): 19 */
+ /* */
+ /* Grayscale rendering is what FreeType does anyway unless someone */
+ /* sets FT_LOAD_TARGET_MONO or FT_LOAD_TARGET_LCD(_V) */
+ if ( ( args[0] & 4096 ) != 0 && exc->grayscale_cleartype )
+ K |= 1 << 19;
+ }
+#endif
+
+#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY
- if ( SUBPIXEL_HINTING &&
+ if ( SUBPIXEL_HINTING_INFINALITY &&
exc->rasterizer_version >= TT_INTERPRETER_VERSION_35 )
{
@@ -7415,12 +7402,63 @@
}
}
-#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */
+#endif /* TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY */
args[0] = K;
}
+#ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT
+
+ /*************************************************************************/
+ /* */
+ /* GETVARIATION[]: get normalized variation (blend) coordinates */
+ /* Opcode range: 0x91 */
+ /* Stack: --> f2.14... */
+ /* */
+ /* XXX: UNDOCUMENTED! There is no official documentation from Apple for */
+ /* this bytecode instruction. Active only if a font has GX */
+ /* variation axes. */
+ /* */
+ static void
+ Ins_GETVARIATION( TT_ExecContext exc,
+ FT_Long* args )
+ {
+ FT_UInt num_axes = exc->face->blend->num_axis;
+ FT_Fixed* coords = exc->face->blend->normalizedcoords;
+
+ FT_UInt i;
+
+
+ if ( BOUNDS( num_axes, exc->stackSize + 1 - exc->top ) )
+ {
+ exc->error = FT_THROW( Stack_Overflow );
+ return;
+ }
+
+ for ( i = 0; i < num_axes; i++ )
+ args[i] = coords[i] >> 2; /* convert 16.16 to 2.14 format */
+ }
+
+
+ /*************************************************************************/
+ /* */
+ /* GETDATA[]: no idea what this is good for */
+ /* Opcode range: 0x92 */
+ /* Stack: --> 17 */
+ /* */
+ /* XXX: UNDOCUMENTED! There is no documentation from Apple for this */
+ /* very weird bytecode instruction. */
+ /* */
+ static void
+ Ins_GETDATA( FT_Long* args )
+ {
+ args[0] = 17;
+ }
+
+#endif /* TT_CONFIG_OPTION_GX_VAR_SUPPORT */
+
+
static void
Ins_UNKNOWN( TT_ExecContext exc )
{
@@ -7497,7 +7535,7 @@
FT_Long ins_counter = 0; /* executed instructions counter */
FT_UShort i;
-#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
+#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY
FT_Byte opcode_pattern[1][2] = {
/* #8 TypeMan Talk Align */
{
@@ -7508,12 +7546,27 @@
FT_UShort opcode_patterns = 1;
FT_UShort opcode_pointer[1] = { 0 };
FT_UShort opcode_size[1] = { 1 };
-#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */
+#endif /* TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY */
-#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
+#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY
exc->iup_called = FALSE;
-#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */
+#endif /* TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY */
+
+#ifdef TT_SUPPORT_SUBPIXEL_HINTING_MINIMAL
+ /* Toggle backwards compatibility according to what font says, except */
+ /* when it's a `tricky' font that heavily relies on the interpreter to */
+ /* render glyphs correctly, e.g. DFKai-SB. Backwards compatibility */
+ /* hacks may break it. */
+ if ( SUBPIXEL_HINTING_MINIMAL &&
+ !FT_IS_TRICKY( &exc->face->root ) )
+ exc->backwards_compatibility = !( exc->GS.instruct_control & 4 );
+ else
+ exc->backwards_compatibility = FALSE;
+
+ exc->iupx_called = FALSE;
+ exc->iupy_called = FALSE;
+#endif
/* set PPEM and CVT functions */
exc->tt_metrics.ratio = 0;
@@ -7592,7 +7645,21 @@
exc->args = 0;
}
- exc->new_top = exc->args + ( Pop_Push_Count[exc->opcode] & 15 );
+#ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT
+ if ( exc->opcode == 0x91 )
+ {
+ /* this is very special: GETVARIATION returns */
+ /* a variable number of arguments */
+
+ /* it is the job of the application to `activate' GX handling, */
+ /* this is, calling any of the GX API functions on the current */
+ /* font to select a variation instance */
+ if ( exc->face->blend )
+ exc->new_top = exc->args + exc->face->blend->num_axis;
+ }
+ else
+#endif
+ 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' */
@@ -7606,9 +7673,9 @@
exc->step_ins = TRUE;
exc->error = FT_Err_Ok;
-#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
+#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY
- if ( SUBPIXEL_HINTING )
+ if ( SUBPIXEL_HINTING_INFINALITY )
{
for ( i = 0; i < opcode_patterns; i++ )
{
@@ -7637,7 +7704,7 @@
}
}
-#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */
+#endif /* TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY */
{
FT_Long* args = exc->stack + exc->args;
@@ -7785,7 +7852,7 @@
Ins_ALIGNPTS( exc, args );
break;
- case 0x28: /* ???? */
+ case 0x28: /* RAW */
Ins_UNKNOWN( exc );
break;
@@ -8137,10 +8204,33 @@
Ins_INSTCTRL( exc, args );
break;
- case 0x8F:
+ case 0x8F: /* ADJUST */
+ case 0x90: /* ADJUST */
Ins_UNKNOWN( exc );
break;
+#ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT
+ case 0x91:
+ /* it is the job of the application to `activate' GX handling, */
+ /* this is, calling any of the GX API functions on the current */
+ /* font to select a variation instance */
+ if ( exc->face->blend )
+ Ins_GETVARIATION( exc, args );
+ else
+ Ins_UNKNOWN( exc );
+ break;
+
+ case 0x92:
+ /* there is at least one MS font (LaoUI.ttf version 5.01) that */
+ /* uses IDEFs for 0x91 and 0x92; for this reason we activate */
+ /* GETDATA for GX fonts only, similar to GETVARIATION */
+ if ( exc->face->blend )
+ Ins_GETDATA( args );
+ else
+ Ins_UNKNOWN( exc );
+ break;
+#endif
+
default:
if ( opcode >= 0xE0 )
Ins_MIRP( exc, args );
diff --git a/src/truetype/ttinterp.h b/src/truetype/ttinterp.h
index 32706d0..53f0944 100644
--- a/src/truetype/ttinterp.h
+++ b/src/truetype/ttinterp.h
@@ -4,7 +4,7 @@
/* */
/* TrueType bytecode interpreter (specification). */
/* */
-/* Copyright 1996-2015 by */
+/* Copyright 1996-2016 by */
/* David Turner, Robert Wilhelm, and Werner Lemberg. */
/* */
/* This file is part of the FreeType project, and may only be used, */
@@ -16,8 +16,8 @@
/***************************************************************************/
-#ifndef __TTINTERP_H__
-#define __TTINTERP_H__
+#ifndef TTINTERP_H_
+#define TTINTERP_H_
#include <ft2build.h>
#include "ttobjs.h"
@@ -99,7 +99,7 @@ FT_BEGIN_HEADER
} TT_CallRec, *TT_CallStack;
-#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
+#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY
/*************************************************************************/
/* */
@@ -138,7 +138,7 @@ FT_BEGIN_HEADER
} SPH_Font_Class;
-#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */
+#endif /* TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY */
/*************************************************************************/
@@ -170,6 +170,7 @@ FT_BEGIN_HEADER
pts,
twilight;
+ FT_Long pointSize; /* in 26.6 format */
FT_Size_Metrics metrics;
TT_Size_Metrics tt_metrics; /* size metrics */
@@ -247,9 +248,135 @@ FT_BEGIN_HEADER
TT_Set_CVT_Func func_write_cvt; /* write a cvt entry (in pixels) */
TT_Set_CVT_Func func_move_cvt; /* incr a cvt entry (in pixels) */
- FT_Bool grayscale; /* are we hinting for grayscale? */
-
-#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
+ FT_Bool grayscale; /* bi-level hinting and */
+ /* grayscale rendering */
+
+#ifdef TT_SUPPORT_SUBPIXEL_HINTING_MINIMAL
+ /*
+ * Modern TrueType fonts are usually rendered through Microsoft's
+ * collection of rendering techniques called ClearType (e.g., subpixel
+ * rendering and subpixel hinting). When ClearType was introduced, most
+ * fonts were not ready. Microsoft decided to implement a backwards
+ * compatibility mode that employed several simple to complicated
+ * assumptions and tricks that modified the interpretation of the
+ * bytecode contained in these fonts to make them look ClearType-y
+ * somehow. Most (web)fonts that were released since then have come to
+ * rely on these hacks to render correctly, even some of Microsoft's
+ * flagship ClearType fonts (Calibri, Cambria, Segoe UI).
+ *
+ * The minimal subpixel hinting code (interpreter version 40) employs a
+ * small list of font-agnostic hacks to bludgeon non-native-ClearType
+ * fonts (except tricky ones[1]) into submission. It will not try to
+ * toggle hacks for specific fonts for performance and complexity
+ * reasons. The focus is on modern (web)fonts rather than legacy fonts
+ * that were made for black-and-white rendering.
+ *
+ * Major hacks
+ *
+ * - Any point movement on the x axis is ignored (cf. `Direct_Move' and
+ * `Direct_Move_X'). This has the smallest code footprint and single
+ * biggest effect. The ClearType way to increase resolution is
+ * supersampling the x axis, the FreeType way is ignoring instructions
+ * on the x axis, which gives the same result in the majority of
+ * cases.
+ *
+ * - Points are not moved post-IUP (neither on the x nor on the y axis),
+ * except the x component of diagonal moves post-IUP (cf.
+ * `Direct_Move', `Direct_Move_Y', `Move_Zp2_Point'). Post-IUP
+ * changes are commonly used to `fix' pixel patterns which has little
+ * use outside monochrome rendering.
+ *
+ * - SHPIX and DELTAP don't execute unless moving a composite on the
+ * y axis or moving a previously y touched point. SHPIX additionally
+ * denies movement on the x axis (cf. `Ins_SHPIX' and `Ins_DELTAP').
+ * Both instructions are commonly used to `fix' pixel patterns for
+ * monochrome or Windows's GDI rendering but make little sense for
+ * FreeType rendering. Both can distort the outline. See [2] for
+ * details.
+ *
+ * - The hdmx table and modifications to phantom points are ignored.
+ * Bearings and advance widths remain unchanged (except rounding them
+ * outside the interpreter!), cf. `compute_glyph_metrics' and
+ * `TT_Hint_Glyph'. Letting non-native-ClearType fonts modify spacing
+ * might mess up spacing.
+ *
+ * Minor hacks
+ *
+ * - FLIPRGON, FLIPRGOFF, and FLIPPT don't execute post-IUP. This
+ * prevents dents in e.g. Arial-Regular's `D' and `G' glyphs at
+ * various sizes.
+ *
+ * (Post-IUP is the state after both IUP[x] and IUP[y] have been
+ * executed.)
+ *
+ * The best results are achieved for fonts that were from the outset
+ * designed with ClearType in mind, meaning they leave the x axis mostly
+ * alone and don't mess with the `final' outline to produce more
+ * pleasing pixel patterns. The harder the designer tried to produce
+ * very specific patterns (`superhinting') for pre-ClearType-displays,
+ * the worse the results.
+ *
+ * Microsoft defines a way to turn off backwards compatibility and
+ * interpret instructions as before (called `native ClearType')[2][3].
+ * The font designer then regains full control and is responsible for
+ * making the font work correctly with ClearType without any
+ * hand-holding by the interpreter or rasterizer[4]. The v40
+ * interpreter assumes backwards compatibility by default, which can be
+ * turned off the same way by executing the following in the control
+ * program (cf. `Ins_INSTCTRL').
+ *
+ * #PUSH 4,3
+ * INSTCTRL[]
+ *
+ * [1] Tricky fonts as FreeType defines them rely on the bytecode
+ * interpreter to display correctly. Hacks can interfere with them,
+ * so they get treated like native ClearType fonts (v40 with
+ * backwards compatibility turned off). Cf. `TT_RunIns'.
+ *
+ * [2] Proposed by Microsoft's Greg Hitchcock in
+ * https://www.microsoft.com/typography/cleartype/truetypecleartype.aspx
+ *
+ * [3] Beat Stamm describes it in more detail:
+ * http://www.beatstamm.com/typography/RTRCh4.htm#Sec12
+ *
+ * [4] The list of `native ClearType' fonts is small at the time of this
+ * writing; I found the following on a Windows 10 Update 1511
+ * installation: Constantia, Corbel, Sitka, Malgun Gothic, Microsoft
+ * JhengHei (Bold and UI Bold), Microsoft YaHei (Bold and UI Bold),
+ * SimSun, NSimSun, and Yu Gothic.
+ *
+ */
+
+ /* Using v40 implies subpixel hinting. Used to detect interpreter */
+ /* version switches. `_lean' to differentiate from the Infinality */
+ /* `subpixel_hinting', which is managed differently. */
+ FT_Bool subpixel_hinting_lean;
+
+ /* Long side of a LCD subpixel is vertical (e.g., screen is rotated). */
+ /* `_lean' to differentiate from the Infinality `vertical_lcd', which */
+ /* is managed differently. */
+ FT_Bool vertical_lcd_lean;
+
+ /* Default to backwards compatibility mode in v40 interpreter. If */
+ /* this is false, it implies the interpreter is in v35 or in native */
+ /* ClearType mode. */
+ FT_Bool backwards_compatibility;
+
+ /* Useful for detecting and denying post-IUP trickery that is usually */
+ /* used to fix pixel patterns (`superhinting'). */
+ FT_Bool iupx_called;
+ FT_Bool iupy_called;
+
+ /* ClearType hinting and grayscale rendering, as used by Universal */
+ /* Windows Platform apps (Windows 8 and above). Like the standard */
+ /* colorful ClearType mode, it utilizes a vastly increased virtual */
+ /* resolution on the x axis. Different from bi-level hinting and */
+ /* grayscale rendering, the old mode from Win9x days that roughly */
+ /* adheres to the physical pixel grid on both axes. */
+ FT_Bool grayscale_cleartype;
+#endif /* TT_SUPPORT_SUBPIXEL_HINTING_MINIMAL */
+
+#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY
TT_Round_Func func_round_sphn; /* subpixel rounding function */
FT_Bool subpixel_hinting; /* Using subpixel hinting? */
@@ -279,7 +406,7 @@ FT_BEGIN_HEADER
FT_ULong sph_in_func_flags; /* flags to indicate if in */
/* special functions */
-#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */
+#endif /* TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY */
} TT_ExecContextRec;
@@ -382,7 +509,7 @@ FT_BEGIN_HEADER
FT_END_HEADER
-#endif /* __TTINTERP_H__ */
+#endif /* TTINTERP_H_ */
/* END */
diff --git a/src/truetype/ttobjs.c b/src/truetype/ttobjs.c
index b0d9f28..ed3be2d 100644
--- a/src/truetype/ttobjs.c
+++ b/src/truetype/ttobjs.c
@@ -4,7 +4,7 @@
/* */
/* Objects manager (body). */
/* */
-/* Copyright 1996-2015 by */
+/* Copyright 1996-2016 by */
/* David Turner, Robert Wilhelm, and Werner Lemberg. */
/* */
/* This file is part of the FreeType project, and may only be used, */
@@ -32,10 +32,6 @@
#include "ttinterp.h"
#endif
-#ifdef TT_CONFIG_OPTION_UNPATENTED_HINTING
-#include FT_TRUETYPE_UNPATENTED_H
-#endif
-
#ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT
#include "ttgxvar.h"
#endif
@@ -246,7 +242,7 @@
tt_check_trickyness_sfnt_ids( TT_Face face )
{
#define TRICK_SFNT_IDS_PER_FACE 3
-#define TRICK_SFNT_IDS_NUM_FACES 17
+#define TRICK_SFNT_IDS_NUM_FACES 18
static const tt_sfnt_id_rec sfnt_id[TRICK_SFNT_IDS_NUM_FACES]
[TRICK_SFNT_IDS_PER_FACE] = {
@@ -270,6 +266,11 @@
{ 0x5A30CA3BUL, 0x00009063UL }, /* fpgm */
{ 0x13A42602UL, 0x0000007EUL } /* prep */
},
+ { /* DFKaiShu2 */
+ { 0x11E5EAD4UL, 0x00000350UL }, /* cvt */
+ { 0xA6E78C01UL, 0x00008998UL }, /* fpgm */
+ { 0x13A42602UL, 0x0000007EUL } /* prep */
+ },
{ /* HuaTianKaiTi */
{ 0xFFFBFFFCUL, 0x00000008UL }, /* cvt */
{ 0x9C9E48B8UL, 0x0000BEA2UL }, /* fpgm */
@@ -397,11 +398,11 @@
for ( j = 0; j < TRICK_SFNT_IDS_NUM_FACES; j++ )
{
if ( !has_cvt && !sfnt_id[j][TRICK_SFNT_ID_cvt].Length )
- num_matched_ids[j] ++;
+ num_matched_ids[j]++;
if ( !has_fpgm && !sfnt_id[j][TRICK_SFNT_ID_fpgm].Length )
- num_matched_ids[j] ++;
+ num_matched_ids[j]++;
if ( !has_prep && !sfnt_id[j][TRICK_SFNT_ID_prep].Length )
- num_matched_ids[j] ++;
+ num_matched_ids[j]++;
if ( num_matched_ids[j] == TRICK_SFNT_IDS_PER_FACE )
return TRUE;
}
@@ -676,29 +677,6 @@
#endif /* TT_CONFIG_OPTION_GX_VAR_SUPPORT */
-#if defined( TT_CONFIG_OPTION_UNPATENTED_HINTING ) && \
- !defined( TT_CONFIG_OPTION_BYTECODE_INTERPRETER )
-
- {
- FT_Bool unpatented_hinting;
- int i;
-
-
- /* Determine whether unpatented hinting is to be used for this face. */
- unpatented_hinting = FT_BOOL
- ( library->debug_hooks[FT_DEBUG_HOOK_UNPATENTED_HINTING] != NULL );
-
- for ( i = 0; i < num_params && !face->unpatented_hinting; i++ )
- if ( params[i].tag == FT_PARAM_TAG_UNPATENTED_HINTING )
- unpatented_hinting = TRUE;
-
- if ( !unpatented_hinting )
- ttface->internal->ignore_unpatented_hinter = TRUE;
- }
-
-#endif /* TT_CONFIG_OPTION_UNPATENTED_HINTING &&
- !TT_CONFIG_OPTION_BYTECODE_INTERPRETER */
-
/* initialize standard glyph loading routines */
TT_Init_Glyph_Loading( face );
@@ -1309,10 +1287,12 @@
TT_Driver driver = (TT_Driver)ttdriver;
-#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
- driver->interpreter_version = TT_INTERPRETER_VERSION_38;
-#else
driver->interpreter_version = TT_INTERPRETER_VERSION_35;
+#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY
+ driver->interpreter_version = TT_INTERPRETER_VERSION_38;
+#endif
+#ifdef TT_SUPPORT_SUBPIXEL_HINTING_MINIMAL
+ driver->interpreter_version = TT_INTERPRETER_VERSION_40;
#endif
#else /* !TT_USE_BYTECODE_INTERPRETER */
diff --git a/src/truetype/ttobjs.h b/src/truetype/ttobjs.h
index 9396089..98ad383 100644
--- a/src/truetype/ttobjs.h
+++ b/src/truetype/ttobjs.h
@@ -4,7 +4,7 @@
/* */
/* Objects manager (specification). */
/* */
-/* Copyright 1996-2015 by */
+/* Copyright 1996-2016 by */
/* David Turner, Robert Wilhelm, and Werner Lemberg. */
/* */
/* This file is part of the FreeType project, and may only be used, */
@@ -16,8 +16,8 @@
/***************************************************************************/
-#ifndef __TTOBJS_H__
-#define __TTOBJS_H__
+#ifndef TTOBJS_H_
+#define TTOBJS_H_
#include <ft2build.h>
@@ -72,10 +72,6 @@ FT_BEGIN_HEADER
FT_UnitVector projVector;
FT_UnitVector freeVector;
-#ifdef TT_CONFIG_OPTION_UNPATENTED_HINTING
- FT_Bool both_x_axis;
-#endif
-
FT_Long loop;
FT_F26Dot6 minimum_distance;
FT_Int round_state;
@@ -290,6 +286,8 @@ FT_BEGIN_HEADER
#ifdef TT_USE_BYTECODE_INTERPRETER
+ FT_Long point_size; /* for the `MPS' bytecode instruction */
+
FT_UInt num_function_defs; /* number of function definitions */
FT_UInt max_function_defs;
TT_DefArray function_defs; /* table of function definitions */
@@ -419,7 +417,7 @@ FT_BEGIN_HEADER
FT_END_HEADER
-#endif /* __TTOBJS_H__ */
+#endif /* TTOBJS_H_ */
/* END */
diff --git a/src/truetype/ttpic.c b/src/truetype/ttpic.c
index 242a6b7..54a5b8b 100644
--- a/src/truetype/ttpic.c
+++ b/src/truetype/ttpic.c
@@ -4,7 +4,7 @@
/* */
/* The FreeType position independent code services for truetype module. */
/* */
-/* Copyright 2009-2015 by */
+/* Copyright 2009-2016 by */
/* Oran Agra and Mickey Gabel. */
/* */
/* This file is part of the FreeType project, and may only be used, */
diff --git a/src/truetype/ttpic.h b/src/truetype/ttpic.h
index 076ae56..f725865 100644
--- a/src/truetype/ttpic.h
+++ b/src/truetype/ttpic.h
@@ -4,7 +4,7 @@
/* */
/* The FreeType position independent code services for truetype module. */
/* */
-/* Copyright 2009-2015 by */
+/* Copyright 2009-2016 by */
/* Oran Agra and Mickey Gabel. */
/* */
/* This file is part of the FreeType project, and may only be used, */
@@ -16,8 +16,8 @@
/***************************************************************************/
-#ifndef __TTPIC_H__
-#define __TTPIC_H__
+#ifndef TTPIC_H_
+#define TTPIC_H_
#include FT_INTERNAL_PIC_H
@@ -77,7 +77,7 @@ FT_END_HEADER
/* */
-#endif /* __TTPIC_H__ */
+#endif /* TTPIC_H_ */
/* END */
diff --git a/src/truetype/ttpload.c b/src/truetype/ttpload.c
index 9bf67f9..ca158ac 100644
--- a/src/truetype/ttpload.c
+++ b/src/truetype/ttpload.c
@@ -4,7 +4,7 @@
/* */
/* TrueType-specific tables loader (body). */
/* */
-/* Copyright 1996-2015 by */
+/* Copyright 1996-2016 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/truetype/ttpload.h b/src/truetype/ttpload.h
index bc92369..aa2e38e 100644
--- a/src/truetype/ttpload.h
+++ b/src/truetype/ttpload.h
@@ -4,7 +4,7 @@
/* */
/* TrueType-specific tables loader (specification). */
/* */
-/* Copyright 1996-2015 by */
+/* Copyright 1996-2016 by */
/* David Turner, Robert Wilhelm, and Werner Lemberg. */
/* */
/* This file is part of the FreeType project, and may only be used, */
@@ -16,8 +16,8 @@
/***************************************************************************/
-#ifndef __TTPLOAD_H__
-#define __TTPLOAD_H__
+#ifndef TTPLOAD_H_
+#define TTPLOAD_H_
#include <ft2build.h>
@@ -69,7 +69,7 @@ FT_BEGIN_HEADER
FT_END_HEADER
-#endif /* __TTPLOAD_H__ */
+#endif /* TTPLOAD_H_ */
/* END */
diff --git a/src/truetype/ttsubpix.c b/src/truetype/ttsubpix.c
index 0d391e9..0395096 100644
--- a/src/truetype/ttsubpix.c
+++ b/src/truetype/ttsubpix.c
@@ -4,7 +4,7 @@
/* */
/* TrueType Subpixel Hinting. */
/* */
-/* Copyright 2010-2015 by */
+/* Copyright 2010-2016 by */
/* David Turner, Robert Wilhelm, and Werner Lemberg. */
/* */
/* This file is part of the FreeType project, and may only be used, */
@@ -27,7 +27,7 @@
#include "ttsubpix.h"
-#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
+#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY
/*************************************************************************/
/* */
@@ -1000,12 +1000,12 @@
}
}
-#else /* !TT_CONFIG_OPTION_SUBPIXEL_HINTING */
+#else /* !TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY */
/* ANSI C doesn't like empty source files */
typedef int _tt_subpix_dummy;
-#endif /* !TT_CONFIG_OPTION_SUBPIXEL_HINTING */
+#endif /* !TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY */
/* END */
diff --git a/src/truetype/ttsubpix.h b/src/truetype/ttsubpix.h
index 9151aa3..86844da 100644
--- a/src/truetype/ttsubpix.h
+++ b/src/truetype/ttsubpix.h
@@ -4,7 +4,7 @@
/* */
/* TrueType Subpixel Hinting. */
/* */
-/* Copyright 2010-2015 by */
+/* Copyright 2010-2016 by */
/* David Turner, Robert Wilhelm, and Werner Lemberg. */
/* */
/* This file is part of the FreeType project, and may only be used, */
@@ -16,8 +16,8 @@
/***************************************************************************/
-#ifndef __TTSUBPIX_H__
-#define __TTSUBPIX_H__
+#ifndef TTSUBPIX_H_
+#define TTSUBPIX_H_
#include <ft2build.h>
#include "ttobjs.h"
@@ -27,7 +27,7 @@
FT_BEGIN_HEADER
-#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
+#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY
/*************************************************************************/
/* */
@@ -100,11 +100,12 @@ FT_BEGIN_HEADER
#define SPH_OPTION_SET_COMPATIBLE_WIDTHS FALSE
#define SPH_OPTION_SET_RASTERIZER_VERSION 38
-#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */
+#endif /* TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY */
FT_END_HEADER
-#endif /* __TTSUBPIX_H__ */
+#endif /* TTSUBPIX_H_ */
+
/* END */