>From 827a965e6297650b04aaf12dd3a8b69635ff6336 Mon Sep 17 00:00:00 2001
From: Nikolaus Waxweiler
Date: Sun, 13 Mar 2016 15:56:33 +0100
Subject: [PATCH 2/2] Implement v38 bytecode interpreter and make it the
default [2/2]
Implement interpreter changes.
---
src/truetype/ttinterp.c | 330 +++++++++++++++++++++++++++++++++++++++++++++---
1 file changed, 314 insertions(+), 16 deletions(-)
diff --git a/src/truetype/ttinterp.c b/src/truetype/ttinterp.c
index ccbb1d7..ef639df 100644
--- a/src/truetype/ttinterp.c
+++ b/src/truetype/ttinterp.c
@@ -1642,6 +1642,11 @@
/* */
/* zone :: The affected glyph zone. */
/* */
+ /* */
+ /* Will not move points on the X-axis if using the v38 interpreter in */
+ /* backwards compatibility mode except post-IUP. Will not move points */
+ /* on the Y-axis post-IUP. Will still `touch' the point. */
+ /* */
static void
Direct_Move( TT_ExecContext exc,
TT_GlyphZone zone,
@@ -1660,6 +1665,11 @@
( !exc->ignore_x_mode ||
( exc->sph_tweak_flags & SPH_TWEAK_ALLOW_X_DMOVE ) ) )
#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */
+ /* 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 ( exc->backwards_compatibility &&
+ exc->iupx_called && exc->iupy_called )
zone->cur[point].x += FT_MulDiv( distance, v, exc->F_dot_P );
zone->tags[point] |= FT_CURVE_TAG_TOUCH_X;
@@ -1669,7 +1679,12 @@
if ( v != 0 )
{
- zone->cur[point].y += FT_MulDiv( distance, v, exc->F_dot_P );
+ /* Prevent everything post-IUP that might distort the result. Post-IUP
+ * changes are commonly used to "fix" pixel patterns which has little use
+ * outside monochrome rendering. */
+ if ( !( exc->backwards_compatibility &&
+ exc->iupx_called && exc->iupy_called ) )
+ zone->cur[point].y += FT_MulDiv( distance, v, exc->F_dot_P );
zone->tags[point] |= FT_CURVE_TAG_TOUCH_Y;
}
@@ -1721,6 +1736,10 @@
/* The following versions are used whenever both vectors are both */
/* along one of the coordinate unit vectors, i.e. in 90% of the cases. */
/* */
+ /* Will not move points on the X-axis if using the v38 interpreter */
+ /* in backwards compatibility mode, as well as the Y-axis post-IUP. */
+ /* Will still `touch' the point. */
+ /* */
/*************************************************************************/
@@ -1736,6 +1755,10 @@
if ( !SUBPIXEL_HINTING ||
!exc->ignore_x_mode )
#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */
+ /* Some non-native ClearType fonts seem to shuffle x-coordinates around,
+ * presumably to clean up rounding results. This creates dents in the
+ * outline. Deny, but still `touch' point so IUP works as expected. */
+ if ( ! exc->backwards_compatibility )
zone->cur[point].x += distance;
zone->tags[point] |= FT_CURVE_TAG_TOUCH_X;
@@ -1750,7 +1773,12 @@
{
FT_UNUSED( exc );
- zone->cur[point].y += distance;
+ /* Prevent everything post-IUP that might distort the result. Post-IUP
+ * changes are commonly used to "fix" pixel patterns which has little use
+ * outside monochrome rendering. */
+ if ( !( exc->backwards_compatibility &&
+ exc->iupx_called && exc->iupy_called ) )
+ zone->cur[point].y += distance;
zone->tags[point] |= FT_CURVE_TAG_TOUCH_Y;
}
@@ -1853,6 +1881,10 @@
/* */
/* Rounded distance. */
/* */
+ /* */
+ /* Will not round on the X-axis if using the v38 interpreter */
+ /* in backwards compatibility mode. */
+ /* */
static FT_F26Dot6
Round_To_Grid( TT_ExecContext exc,
FT_F26Dot6 distance,
@@ -1860,8 +1892,13 @@
{
FT_F26Dot6 val;
- FT_UNUSED( exc );
+ /* Given ClearType's virtual increase of resolution on the X-axis, rounding
+ * to the physical pixel grid there doesn't make much sense. Native ClearType
+ * fonts know this, the rest (where backwards compatibility applies) may or
+ * may not. Short out rounding if freedom vector is parallel to X-axis. */
+ if ( exc->backwards_compatibility && exc->GS.freeVector.y == 0x0 )
+ return Round_None( exc, distance, compensation );
if ( distance >= 0 )
{
@@ -1896,6 +1933,10 @@
/* */
/* Rounded distance. */
/* */
+ /* */
+ /* Will not round on the X-axis if using the v38 interpreter in */
+ /* backwards compatibility mode. */
+ /* */
static FT_F26Dot6
Round_To_Half_Grid( TT_ExecContext exc,
FT_F26Dot6 distance,
@@ -1903,8 +1944,13 @@
{
FT_F26Dot6 val;
- FT_UNUSED( exc );
+ /* Given ClearType's virtual increase of resolution on the X-axis, rounding
+ * to the physical pixel grid there doesn't make much sense. Native ClearType
+ * fonts know this, the rest (where backwards compatibility applies) may or
+ * may not. Short out rounding if freedom vector is parallel to X-axis. */
+ if ( exc->backwards_compatibility && exc->GS.freeVector.y == 0x0 )
+ return Round_None( exc, distance, compensation );
if ( distance >= 0 )
{
@@ -1939,6 +1985,10 @@
/* */
/* Rounded distance. */
/* */
+ /* */
+ /* Will not round on the X-axis if using the v38 interpreter in */
+ /* backwards compatibility mode. */
+ /* */
static FT_F26Dot6
Round_Down_To_Grid( TT_ExecContext exc,
FT_F26Dot6 distance,
@@ -1946,8 +1996,13 @@
{
FT_F26Dot6 val;
- FT_UNUSED( exc );
+ /* Given ClearType's virtual increase of resolution on the X-axis, rounding
+ * to the physical pixel grid there doesn't make much sense. Native ClearType
+ * fonts know this, the rest (where backwards compatibility applies) may or
+ * may not. Short out rounding if freedom vector is parallel to X-axis. */
+ if ( exc->backwards_compatibility && exc->GS.freeVector.y == 0x0 )
+ return Round_None( exc, distance, compensation );
if ( distance >= 0 )
{
@@ -1982,6 +2037,10 @@
/* */
/* Rounded distance. */
/* */
+ /* */
+ /* Will not round on the X-axis if using the v38 interpreter in */
+ /* backwards compatibility mode. */
+ /* */
static FT_F26Dot6
Round_Up_To_Grid( TT_ExecContext exc,
FT_F26Dot6 distance,
@@ -1989,8 +2048,13 @@
{
FT_F26Dot6 val;
- FT_UNUSED( exc );
+ /* Given ClearType's virtual increase of resolution on the X-axis, rounding
+ * to the physical pixel grid there doesn't make much sense. Native ClearType
+ * fonts know this, the rest (where backwards compatibility applies) may or
+ * may not. Short out rounding if freedom vector is parallel to X-axis. */
+ if ( exc->backwards_compatibility && exc->GS.freeVector.y == 0x0 )
+ return Round_None( exc, distance, compensation );
if ( distance >= 0 )
{
@@ -2025,6 +2089,10 @@
/* */
/* Rounded distance. */
/* */
+ /* */
+ /* Will not round on the X-axis if using the v38 interpreter in */
+ /* backwards compatibility mode. */
+ /* */
static FT_F26Dot6
Round_To_Double_Grid( TT_ExecContext exc,
FT_F26Dot6 distance,
@@ -2032,8 +2100,13 @@
{
FT_F26Dot6 val;
- FT_UNUSED( exc );
+ /* Given ClearType's virtual increase of resolution on the X-axis, rounding
+ * to the physical pixel grid there doesn't make much sense. Native ClearType
+ * fonts know this, the rest (where backwards compatibility applies) may or
+ * may not. Short out rounding if freedom vector is parallel to X-axis. */
+ if ( exc->backwards_compatibility && exc->GS.freeVector.y == 0x0 )
+ return Round_None( exc, distance, compensation );
if ( distance >= 0 )
{
@@ -2074,6 +2147,9 @@
/* the description of super round that we should add the compensation */
/* before rounding. */
/* */
+ /* Will not round on the X-axis if using the v38 interpreter in */
+ /* backwards compatibility mode. */
+ /* */
static FT_F26Dot6
Round_Super( TT_ExecContext exc,
FT_F26Dot6 distance,
@@ -2082,6 +2158,13 @@
FT_F26Dot6 val;
+ /* Given ClearType's virtual increase of resolution on the X-axis, rounding
+ * to the physical pixel grid there doesn't make much sense. Native ClearType
+ * fonts know this, the rest (where backwards compatibility applies) may or
+ * may not. Short out rounding if freedom vector is parallel to X-axis. */
+ if ( exc->backwards_compatibility && exc->GS.freeVector.y == 0x0 )
+ return Round_None( exc, distance, compensation );
+
if ( distance >= 0 )
{
val = ( distance - exc->phase + exc->threshold + compensation ) &
@@ -2123,6 +2206,9 @@
/* There is a separate function for Round_Super_45() as we may need */
/* greater precision. */
/* */
+ /* Will not round on the X-axis if using the v38 interpreter in */
+ /* backwards compatibility mode. */
+ /* */
static FT_F26Dot6
Round_Super_45( TT_ExecContext exc,
FT_F26Dot6 distance,
@@ -2131,6 +2217,13 @@
FT_F26Dot6 val;
+ /* Given ClearType's virtual increase of resolution on the X-axis, rounding
+ * to the physical pixel grid there doesn't make much sense. Native ClearType
+ * fonts know this, the rest (where backwards compatibility applies) may or
+ * may not. Short out rounding if freedom vector is parallel to X-axis. */
+ if ( exc->backwards_compatibility && exc->GS.freeVector.y == 0x0 )
+ return Round_None( exc, distance, compensation );
+
if ( distance >= 0 )
{
val = ( ( distance - exc->phase + exc->threshold + compensation ) /
@@ -5049,6 +5142,11 @@
if ( K == 3 )
exc->ignore_x_mode = FT_BOOL( L == 4 );
#endif
+ /* 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 ( K == 3 )
+ exc->backwards_compatibility = ! FT_BOOL( L == 4 );
}
@@ -5133,6 +5231,12 @@
FT_UShort point;
+ /* Prevent everything post-IUP that might distort the result. Post-IUP
+ * changes are commonly used to "fix" pixel patterns which has little use
+ * outside monochrome rendering. */
+ if ( exc->backwards_compatibility && exc->iupx_called && exc->iupy_called )
+ goto Fail;
+
if ( exc->top < exc->GS.loop )
{
if ( exc->pedantic_hinting )
@@ -5179,6 +5283,15 @@
FT_UShort I, K, L;
+ /* Prevent everything post-IUP that might distort the result. Post-IUP
+ * changes are commonly used to "fix" pixel patterns which has little use
+ * outside monochrome rendering.
+ *
+ * Examples: Arial Regular uses FLIPRGON post-IUP on 'D' and 'G' to make
+ * them blocky. */
+ if ( exc->backwards_compatibility && exc->iupx_called && exc->iupy_called )
+ return;
+
K = (FT_UShort)args[1];
L = (FT_UShort)args[0];
@@ -5208,6 +5321,12 @@
FT_UShort I, K, L;
+ /* Prevent everything post-IUP that might distort the result. Post-IUP
+ * changes are commonly used to "fix" pixel patterns which has little use
+ * outside monochrome rendering. */
+ if ( exc->backwards_compatibility && exc->iupx_called && exc->iupy_called )
+ return;
+
K = (FT_UShort)args[1];
L = (FT_UShort)args[0];
@@ -5276,14 +5395,24 @@
{
if ( exc->GS.freeVector.x != 0 )
{
- exc->zp2.cur[point].x += dx;
+ /* Prevent everything post-IUP that might distort the result. Post-IUP
+ * changes are commonly used to "fix" pixel patterns which has little use
+ * outside monochrome rendering. */
+ if ( !( exc->backwards_compatibility &&
+ exc->iupx_called && exc->iupy_called ) )
+ 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;
+ /* Prevent everything post-IUP that might distort the result. Post-IUP
+ * changes are commonly used to "fix" pixel patterns which has little use
+ * outside monochrome rendering. */
+ if ( !( exc->backwards_compatibility &&
+ exc->iupx_called && exc->iupy_called ) )
+ exc->zp2.cur[point].y += dy;
if ( touch )
exc->zp2.tags[point] |= FT_CURVE_TAG_TOUCH_Y;
}
@@ -5337,7 +5466,12 @@
Move_Zp2_Point( exc, point, 0, dy, TRUE );
else
#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */
- Move_Zp2_Point( exc, point, dx, dy, TRUE );
+ /* Stop movement on the X-axis when using the v38 interpreter in
+ * backwards compatibility mode. Prevents dents in outlines. */
+ if ( exc->backwards_compatibility )
+ Move_Zp2_Point( exc, point, 0, dy, TRUE );
+ else
+ Move_Zp2_Point( exc, point, dx, dy, TRUE );
exc->GS.loop--;
}
@@ -5468,7 +5602,6 @@
FT_Int B1, B2;
#endif
-
if ( exc->top < exc->GS.loop + 1 )
{
if ( exc->pedantic_hinting )
@@ -5574,7 +5707,22 @@
#else /* !TT_CONFIG_OPTION_SUBPIXEL_HINTING */
- Move_Zp2_Point( exc, point, dx, dy, TRUE );
+ /* In backwards compatibility mode, block SHPIX under the same
+ * circumstances as DELTAP and additionally stop movement on the X-axis.
+ * This prevents dents in outlines by overeager designers back in the bad
+ * old days ("superhinting").
+ *
+ * XXX: breaks Rokkitt < v1.2 (glyphs explode vertically on ALIGNRP).
+ */
+ if ( exc->backwards_compatibility )
+ {
+ if ( !( 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
+ Move_Zp2_Point( exc, point, dx, dy, TRUE );
#endif /* !TT_CONFIG_OPTION_SUBPIXEL_HINTING */
@@ -5616,6 +5764,17 @@
#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */
+ FT_F26Dot6 control_value_cutin = exc->GS.control_value_cutin;
+
+ /* From "Backwards Compatibility of TrueType Instructions with Microsoft
+ * ClearType" by Greg Hitchcock, 2009: "Some fonts pre-calculate stroke
+ * weights and subsequently use MSIRP[.], which involves neither rounding
+ * nor CVT cut-ins. Therefore MSIRP[.] now respects the CVT cut-in". Cut-in
+ * is set to zero because there's no movement on the X-axis anyway
+ * ("infinite resolution"). */
+ if ( exc->backwards_compatibility && exc->GS.freeVector.y == 0x0 )
+ control_value_cutin = 0;
+
point = (FT_UShort)args[0];
if ( BOUNDS( point, exc->zp1.n_points ) ||
@@ -5646,6 +5805,10 @@
distance = args[1];
#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */
+ if ( exc->backwards_compatibility &&
+ FT_ABS( distance - args[1] ) >= control_value_cutin )
+ distance = args[1];
+
exc->func_move( exc, &exc->zp1, point, args[1] - distance );
exc->GS.rp1 = exc->GS.rp0;
@@ -5738,6 +5901,16 @@
control_value_cutin = 0;
#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */
+ /* From "Backwards Compatibility of TrueType Instructions with Microsoft
+ * ClearType" by Greg Hitchcock, 2009: "In some fonts fractional stroke
+ * weights were calculated and used in MIRP[â¦râ¦]. While this provides some
+ * extra granularity in font smoothing, it unnecessarily quantizes stroke
+ * weights in ClearType, because un-rounded MIRPs now respect CVT cut-in.
+ * [...] with ClearType on, do CVT cut-in always". Cut-in is set to zero
+ * because there's no movement on the X-axis anyway ("infinite resolution"). */
+ if ( exc->backwards_compatibility && exc->GS.freeVector.y == 0x0 )
+ control_value_cutin = 0;
+
if ( BOUNDS( point, exc->zp0.n_points ) ||
BOUNDSL( cvtEntry, exc->cvtSize ) )
{
@@ -5845,6 +6018,11 @@
minimum_distance = 0;
#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */
+ /* Like in MSIRP and MIRP, no movement on the X-axis ("infinite
+ * resolution") means minimum_distance might as well be zero. */
+ if ( exc->backwards_compatibility && exc->GS.freeVector.y == 0x0 )
+ minimum_distance = 0;
+
point = (FT_UShort)args[0];
if ( BOUNDS( point, exc->zp1.n_points ) ||
@@ -5998,6 +6176,17 @@
control_value_cutin = minimum_distance = 0;
#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */
+ /* From "Backwards Compatibility of TrueType Instructions with Microsoft
+ * ClearType" by Greg Hitchcock, 2009: "In some fonts fractional stroke
+ * weights were calculated and used in MIRP[â¦râ¦]. While this provides some
+ * extra granularity in font smoothing, it unnecessarily quantizes stroke
+ * weights in ClearType, because un-rounded MIRPs now respect CVT cut-in.
+ * [...] with ClearType on, do CVT cut-in always". Cut-in and minimum
+ * distance are set to zero because there's no movement on the X-axis
+ * anyway ("infinite resolution"). */
+ if ( exc->backwards_compatibility && exc->GS.freeVector.y == 0x0 )
+ control_value_cutin = minimum_distance = 0;
+
/* XXX: UNDOCUMENTED! cvt[-1] = 0 always */
if ( BOUNDS( point, exc->zp1.n_points ) ||
@@ -6106,6 +6295,13 @@
}
#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */
+ if ( exc->backwards_compatibility &&
+ exc->GS.gep0 == exc->GS.gep1 )
+ {
+ if ( FT_ABS( cvt_dist - org_dist ) > control_value_cutin )
+ cvt_dist = org_dist;
+ }
+
distance = Round_None(
exc,
cvt_dist,
@@ -6324,6 +6520,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;
}
@@ -6331,6 +6528,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 +
@@ -6719,6 +6917,21 @@
FT_Short contour; /* current contour */
+ /* In backwards compatibility mode, allow IUP until it has been called on
+ * both axes, immediately return on subsequent ones. Changes to the outline
+ * after IUP[x] and IUP[y] are usually intending to fix pixel patterns for
+ * bi-level display. */
+ if ( exc->backwards_compatibility )
+ {
+ if ( exc->iupx_called && exc->iupy_called )
+ return;
+
+ if ( exc->opcode & 1 )
+ exc->iupx_called = TRUE;
+ else
+ exc->iupy_called = TRUE;
+ }
+
/* ignore empty outlines */
if ( exc->pts.n_contours == 0 )
return;
@@ -6945,8 +7158,25 @@
}
else
#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */
-
- exc->func_move( exc, &exc->zp0, A, B );
+ /* Like with SHPIX, DELTAP was/is often used to pop pixels on or
+ * off to produce some specific black-and-white pixel pattern the
+ * designer wanted to see ("superhinting"). Bad for everything
+ * except monochrome rendering. Short out as much as possible in
+ * backwards compatibility mode, except if we are DELTAPing in a
+ * composite glyph and on the Y-axis (e.g. offsetting diacritics
+ * from base glyphs) or if we're moving previously y-touched points
+ * (moves entire outline instead of denting it, that's ok).
+ * Details in "Backwards Compatibility of TrueType Instructions
+ * with Microsoft ClearType" by Greg Hitchcock, 2009.
+ */
+ if ( 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
+ exc->func_move( exc, &exc->zp0, A, B );
}
}
else
@@ -7063,9 +7293,11 @@
FT_Long* args )
{
FT_Long K;
+ TT_Driver driver;
K = 0;
+ driver = (TT_Driver)FT_FACE_DRIVER( exc->face );
#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
/********************************/
@@ -7091,7 +7323,7 @@
else
#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */
if ( ( args[0] & 1 ) != 0 )
- K = TT_INTERPRETER_VERSION_35;
+ K = driver->interpreter_version;
/********************************/
/* GLYPH ROTATED */
@@ -7110,13 +7342,65 @@
K |= 1 << 8;
/********************************/
- /* HINTING FOR GRAYSCALE */
+ /* BI-LEVEL HINTING AND */
+ /* GRAYSCALE RENDERING */
/* Selector Bit: 5 */
/* Return Bit(s): 12 */
/* */
if ( ( args[0] & 32 ) != 0 && exc->grayscale )
K |= 1 << 12;
+
+ if ( driver->interpreter_version == TT_INTERPRETER_VERSION_38 )
+ {
+ /********************************/
+ /* HINTING FOR SUBPIXEL */
+ /* Selector Bit: 6 */
+ /* Return Bit(s): 13 */
+ /* */
+ /* v38 will do 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 )
+ K |= 1 << 15;
+
+ /********************************/
+ /* SUBPIXEL POSITIONED? */
+ /* Selector Bit: 10 */
+ /* Return Bit(s): 17 */
+ /* */
+ /* XXX: FreeType supports it, dependant 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 set
+ * 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 set
+ * FT_LOAD_TARGET_MONO or FT_LOAD_TARGET_LCD(_V) */
+ if ( ( args[0] & 4096 ) != 0 && exc->grayscale_cleartype )
+ K |= 1 << 19;
+ }
+
#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
if ( SUBPIXEL_HINTING &&
@@ -7274,6 +7558,8 @@
FT_Long ins_counter = 0; /* executed instructions counter */
FT_UShort i;
+ TT_Driver driver = (TT_Driver)FT_FACE_DRIVER( exc->face );
+
#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
FT_Byte opcode_pattern[1][2] = {
/* #8 TypeMan Talk Align */
@@ -7291,6 +7577,18 @@
#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
exc->iup_called = FALSE;
#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */
+ /* 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 ( driver->interpreter_version == TT_INTERPRETER_VERSION_38 &&
+ !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;
/* set PPEM and CVT functions */
exc->tt_metrics.ratio = 0;
--
2.5.0