[truetype] Rework handling of rendering mode in bytecode.
This replaces a large number of confusing boolean constructs that
describe the target rendering mode in the execution context with
the straight mode variable. It might fix some hidden bugs when
FT_LOAD_TARGET_XXX were used as flags, which they are not.
The condition that triggers the CV program re-execution is simplified.
These events due the rendering mode change are rather rare and unexpected
and, therefore, should not be over-analyzed. In v40, all mode changes
now trigger the CV program. In v35, only switches to/from mono do.
* src/truetype/ttinterp.h (TT_ExecContext): Replace 'grayscale',
'grayscale_cleartype', 'subpixel_hinting_lean', and 'vertical_lcd_lean'
with the rendering 'mode'.
* src/truetype/ttinterp.c (Ins_GETINFO): Updated.
* src/truetype/ttgload.c (tt_loader_init): Replace 'prep' re-execution
trigger and update 'backward_compatibility' condition.
(tt_loader_set_pp): Updated.
diff --git a/src/truetype/ttgload.c b/src/truetype/ttgload.c
index b3621f3..9a19cf8 100644
--- a/src/truetype/ttgload.c
+++ b/src/truetype/ttgload.c
@@ -1370,8 +1370,9 @@
if ( driver->interpreter_version == TT_INTERPRETER_VERSION_40 &&
loader->exec &&
- loader->exec->subpixel_hinting_lean &&
- loader->exec->grayscale_cleartype )
+ loader->exec->mode != FT_RENDER_MODE_MONO &&
+ loader->exec->mode != FT_RENDER_MODE_LCD &&
+ loader->exec->mode != FT_RENDER_MODE_LCD_V )
{
loader->pp3.x = loader->advance / 2;
loader->pp4.x = loader->advance / 2;
@@ -2205,15 +2206,13 @@
{
FT_Error error;
TT_ExecContext exec;
- FT_Bool grayscale = TRUE;
+ FT_Render_Mode mode = FT_LOAD_TARGET_MODE( load_flags );
+ FT_Bool grayscale = FT_BOOL( mode != FT_RENDER_MODE_MONO );
+ FT_Bool reexecute = FALSE;
#ifdef TT_SUPPORT_SUBPIXEL_HINTING_MINIMAL
- FT_Bool subpixel_hinting_lean;
- FT_Bool grayscale_cleartype;
- TT_Driver driver = (TT_Driver)FT_FACE_DRIVER( glyph->face );
+ TT_Driver driver = (TT_Driver)FT_FACE_DRIVER( glyph->face );
#endif
- FT_Bool reexecute = FALSE;
-
if ( size->bytecode_ready > 0 )
return size->bytecode_ready;
@@ -2229,53 +2228,20 @@
exec = size->context;
- grayscale = FT_BOOL( FT_LOAD_TARGET_MODE( load_flags ) !=
- FT_RENDER_MODE_MONO );
-
#ifdef TT_SUPPORT_SUBPIXEL_HINTING_MINIMAL
if ( driver->interpreter_version == TT_INTERPRETER_VERSION_40 )
{
- subpixel_hinting_lean =
- FT_BOOL( FT_LOAD_TARGET_MODE( load_flags ) !=
- FT_RENDER_MODE_MONO );
- grayscale_cleartype =
- FT_BOOL( subpixel_hinting_lean &&
- !( ( load_flags &
- FT_LOAD_TARGET_LCD ) ||
- ( load_flags &
- FT_LOAD_TARGET_LCD_V ) ) );
- exec->vertical_lcd_lean =
- FT_BOOL( subpixel_hinting_lean &&
- ( load_flags &
- FT_LOAD_TARGET_LCD_V ) );
- grayscale = FT_BOOL( grayscale && !subpixel_hinting_lean );
+ grayscale = FALSE;
- /* 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 )
+ /* any mode change requires a re-execution of the CVT program */
+ if ( mode != exec->mode )
{
- FT_TRACE4(( "tt_loader_init: subpixel hinting change,"
+ FT_TRACE4(( "tt_loader_init: render mode change,"
" re-executing `prep' table\n" ));
- exec->subpixel_hinting_lean = subpixel_hinting_lean;
- reexecute = TRUE;
+ exec->mode = mode;
+ 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;
- }
- }
- else
- {
- subpixel_hinting_lean = FALSE;
- exec->vertical_lcd_lean = FALSE;
}
#endif
@@ -2326,7 +2292,7 @@
*
*/
if ( driver->interpreter_version == TT_INTERPRETER_VERSION_40 &&
- subpixel_hinting_lean &&
+ mode != FT_RENDER_MODE_MONO &&
!FT_IS_TRICKY( glyph->face ) )
exec->backward_compatibility = ( size->GS.instruct_control & 4 ) ^ 4;
else
diff --git a/src/truetype/ttinterp.c b/src/truetype/ttinterp.c
index ac3e3b7..58bf908 100644
--- a/src/truetype/ttinterp.c
+++ b/src/truetype/ttinterp.c
@@ -6550,7 +6550,7 @@
/* Otherwise, instructions may behave weirdly and rendering results */
/* may differ between v35 and v40 mode, e.g., in `Times New Roman */
/* Bold Italic'. */
- if ( SUBPIXEL_HINTING_MINIMAL && exc->subpixel_hinting_lean )
+ if ( SUBPIXEL_HINTING_MINIMAL && exc->mode != FT_RENDER_MODE_MONO )
{
/*********************************
* HINTING FOR SUBPIXEL
@@ -6567,7 +6567,7 @@
* Selector Bit: 8
* Return Bit(s): 15
*/
- if ( ( args[0] & 256 ) != 0 && exc->vertical_lcd_lean )
+ if ( ( args[0] & 256 ) != 0 && exc->mode == FT_RENDER_MODE_LCD_V )
K |= 1 << 15;
/*********************************
@@ -6588,7 +6588,7 @@
* The only smoothing method FreeType supports unless someone sets
* FT_LOAD_TARGET_MONO.
*/
- if ( ( args[0] & 2048 ) != 0 && exc->subpixel_hinting_lean )
+ if ( ( args[0] & 2048 ) != 0 && exc->mode != FT_RENDER_MODE_MONO )
K |= 1 << 18;
/*********************************
@@ -6600,7 +6600,10 @@
* 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 )
+ if ( ( args[0] & 4096 ) != 0 &&
+ exc->mode != FT_RENDER_MODE_MONO &&
+ exc->mode != FT_RENDER_MODE_LCD &&
+ exc->mode != FT_RENDER_MODE_LCD_V )
K |= 1 << 19;
}
#endif
diff --git a/src/truetype/ttinterp.h b/src/truetype/ttinterp.h
index 0b61fd7..99b2aba 100644
--- a/src/truetype/ttinterp.h
+++ b/src/truetype/ttinterp.h
@@ -329,20 +329,8 @@
/* or in native ClearType mode. */
FT_Int backward_compatibility;
- /* Using v40 implies subpixel hinting, unless FT_RENDER_MODE_MONO */
- /* has been requested. Used to detect interpreter version switches. */
- FT_Bool subpixel_hinting_lean;
+ FT_Render_Mode mode; /* target render mode */
- /* Long side of a LCD subpixel is vertical (e.g., screen is rotated). */
- FT_Bool vertical_lcd_lean;
-
- /* 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 */
/* We maintain two counters (in addition to the instruction counter) */