[truetype] Improve handling of buggy `prep' tables.

In case of an error in the `prep' table, no longer try to execute it
again and again.  This makes FreeType handle endless loops in buggy
fonts much faster.

* src/truetype/ttobjs.h (TT_SizeRec): The fields `bytecode_ready'
and `cvt_ready' are now negative if not initialized yet, otherwise
they indicate the error code of the last run.

* src/truetype/ttobjs.c (tt_size_run_fpgm, tt_size_run_prep,
tt_size_done_bytecode, tt_size_init_bytecode,
tt_size_ready_bytecode, tt_size_init, tt_size_done, tt_size_reset):
Updated.

* src/truetype/ttgload.c (tt_loader_init): Updated.
* src/truetype/ttinterp.c (TT_RunIns): Force reexecution of `fpgm'
and `prep' only if we are in the `glyf' table.
This commit is contained in:
Werner Lemberg 2014-07-13 02:28:14 +09:00
parent e98e2bc1aa
commit 441b3f3898
6 changed files with 60 additions and 30 deletions

View File

@ -1,3 +1,24 @@
2014-07-13 Werner Lemberg <wl@gnu.org>
[truetype] Improve handling of buggy `prep' tables.
In case of an error in the `prep' table, no longer try to execute it
again and again. This makes FreeType handle endless loops in buggy
fonts much faster.
* src/truetype/ttobjs.h (TT_SizeRec): The fields `bytecode_ready'
and `cvt_ready' are now negative if not initialized yet, otherwise
they indicate the error code of the last run.
* src/truetype/ttobjs.c (tt_size_run_fpgm, tt_size_run_prep,
tt_size_done_bytecode, tt_size_init_bytecode,
tt_size_ready_bytecode, tt_size_init, tt_size_done, tt_size_reset):
Updated.
* src/truetype/ttgload.c (tt_loader_init): Updated.
* src/truetype/ttinterp.c (TT_RunIns): Force reexecution of `fpgm'
and `prep' only if we are in the `glyf' table.
2014-07-12 Werner Lemberg <wl@gnu.org>
* builds/vms/ftconfig.h: Synchronize.

View File

@ -2120,7 +2120,7 @@
FT_Bool reexecute = FALSE;
if ( !size->cvt_ready )
if ( size->bytecode_ready < 0 || size->cvt_ready < 0 )
{
FT_Error error = tt_size_ready_bytecode( size, pedantic );
@ -2128,6 +2128,10 @@
if ( error )
return error;
}
else if ( size->bytecode_ready )
return size->bytecode_ready;
else if ( size->cvt_ready )
return size->cvt_ready;
/* query new execution context */
exec = size->debug ? size->context
@ -2238,12 +2242,15 @@
if ( reexecute )
{
FT_UInt i;
FT_UInt i;
FT_Error error;
for ( i = 0; i < size->cvt_size; i++ )
size->cvt[i] = FT_MulFix( face->cvt[i], size->ttmetrics.scale );
tt_size_run_prep( size, pedantic );
error = tt_size_run_prep( size, pedantic );
if ( error )
return error;
}
/* see whether the cvt program has disabled hinting */

View File

@ -9035,10 +9035,13 @@
/* If any errors have occurred, function tables may be broken. */
/* Force a re-execution of `prep' and `fpgm' tables if no */
/* bytecode debugger is run. */
if ( CUR.error && !CUR.instruction_trap )
if ( CUR.error
&& !CUR.instruction_trap
&& CUR.curRange == tt_coderange_glyph )
{
FT_TRACE1(( " The interpreter returned error 0x%x\n", CUR.error ));
exc->size->cvt_ready = FALSE;
exc->size->bytecode_ready = -1;
exc->size->cvt_ready = -1;
}
return CUR.error;

View File

@ -813,6 +813,8 @@
else
error = FT_Err_Ok;
size->bytecode_ready = error;
if ( !error )
TT_Save_Context( exec, size );
@ -884,6 +886,8 @@
else
error = FT_Err_Ok;
size->cvt_ready = error;
/* UNDOCUMENTED! The MS rasterizer doesn't allow the following */
/* graphics state variables to be modified by the CVT program. */
@ -912,10 +916,6 @@
return error;
}
#endif /* TT_USE_BYTECODE_INTERPRETER */
#ifdef TT_USE_BYTECODE_INTERPRETER
static void
tt_size_done_bytecode( FT_Size ftsize )
@ -953,8 +953,8 @@
size->max_func = 0;
size->max_ins = 0;
size->bytecode_ready = 0;
size->cvt_ready = 0;
size->bytecode_ready = -1;
size->cvt_ready = -1;
}
@ -974,8 +974,8 @@
TT_MaxProfile* maxp = &face->max_profile;
size->bytecode_ready = 1;
size->cvt_ready = 0;
size->bytecode_ready = -1;
size->cvt_ready = -1;
size->max_function_defs = maxp->maxFunctionDefs;
size->max_instruction_defs = maxp->maxInstructionDefs;
@ -1052,15 +1052,14 @@
FT_Error error = FT_Err_Ok;
if ( !size->bytecode_ready )
{
if ( size->bytecode_ready < 0 )
error = tt_size_init_bytecode( (FT_Size)size, pedantic );
if ( error )
goto Exit;
}
if ( error || size->bytecode_ready )
goto Exit;
/* rescale CVT when needed */
if ( !size->cvt_ready )
if ( size->cvt_ready < 0 )
{
FT_UInt i;
TT_Face face = (TT_Face)size->root.face;
@ -1087,8 +1086,6 @@
size->GS = tt_default_graphics_state;
error = tt_size_run_prep( size, pedantic );
if ( !error )
size->cvt_ready = 1;
}
Exit:
@ -1119,8 +1116,8 @@
FT_Error error = FT_Err_Ok;
#ifdef TT_USE_BYTECODE_INTERPRETER
size->bytecode_ready = 0;
size->cvt_ready = 0;
size->bytecode_ready = -1;
size->cvt_ready = -1;
#endif
size->ttmetrics.valid = FALSE;
@ -1148,7 +1145,7 @@
#ifdef TT_USE_BYTECODE_INTERPRETER
if ( size->bytecode_ready )
if ( size->bytecode_ready >= 0 )
tt_size_done_bytecode( ttsize );
#endif
@ -1229,7 +1226,7 @@
}
#ifdef TT_USE_BYTECODE_INTERPRETER
size->cvt_ready = 0;
size->cvt_ready = -1;
#endif /* TT_USE_BYTECODE_INTERPRETER */
if ( !error )

View File

@ -4,7 +4,7 @@
/* */
/* Objects manager (specification). */
/* */
/* Copyright 1996-2009, 2011-2013 by */
/* Copyright 1996-2009, 2011-2014 by */
/* David Turner, Robert Wilhelm, and Werner Lemberg. */
/* */
/* This file is part of the FreeType project, and may only be used, */
@ -333,8 +333,10 @@ FT_BEGIN_HEADER
FT_Bool debug;
TT_ExecContext context;
FT_Bool bytecode_ready;
FT_Bool cvt_ready;
/* if negative, `fpgm' (resp. `prep'), wasn't executed yet; */
/* otherwise it is the returned error code */
FT_Error bytecode_ready;
FT_Error cvt_ready;
#endif /* TT_USE_BYTECODE_INTERPRETER */

View File

@ -956,7 +956,7 @@
if ( loader->exec->rasterizer_version != TT_INTERPRETER_VERSION_35 )
{
loader->exec->rasterizer_version = TT_INTERPRETER_VERSION_35;
loader->exec->size->cvt_ready = FALSE;
loader->exec->size->cvt_ready = -1;
tt_size_ready_bytecode(
loader->exec->size,
@ -971,7 +971,7 @@
SPH_OPTION_SET_RASTERIZER_VERSION )
{
loader->exec->rasterizer_version = SPH_OPTION_SET_RASTERIZER_VERSION;
loader->exec->size->cvt_ready = FALSE;
loader->exec->size->cvt_ready = -1;
tt_size_ready_bytecode(
loader->exec->size,