[psaux] Improve `t1_decoder_parse_metrics' (#58646).
* src/psaux/t1decode.c (t1_decoder_parse_metrics): Copy corresponding code from old engine's `t1_decoder_parse_charstrings' function to handle `op_callsubr' and `op_return'.
This commit is contained in:
parent
b0667d2d36
commit
2eb8f88626
|
@ -1,3 +1,11 @@
|
|||
2020-07-06 Werner Lemberg <wl@gnu.org>
|
||||
|
||||
[psaux] Improve `t1_decoder_parse_metrics' (#58646).
|
||||
|
||||
* src/psaux/t1decode.c (t1_decoder_parse_metrics): Copy
|
||||
corresponding code from old engine's `t1_decoder_parse_charstrings'
|
||||
function to handle `op_callsubr' and `op_return'.
|
||||
|
||||
2020-07-05 David Turner <david@freetype.org>
|
||||
|
||||
[build] Improve visibility support of library function names.
|
||||
|
|
|
@ -1237,8 +1237,8 @@
|
|||
|
||||
FT_UNUSED( orig_y );
|
||||
|
||||
/* the `metrics_only' indicates that we only want to compute */
|
||||
/* the glyph's metrics (lsb + advance width), not load the */
|
||||
/* `metrics_only' indicates that we only want to compute the */
|
||||
/* glyph's metrics (lsb + advance width) without loading the */
|
||||
/* rest of it; so exit immediately */
|
||||
if ( builder->metrics_only )
|
||||
{
|
||||
|
@ -1272,8 +1272,8 @@
|
|||
x = ADD_LONG( builder->pos_x, top[0] );
|
||||
y = ADD_LONG( builder->pos_y, top[1] );
|
||||
|
||||
/* the `metrics_only' indicates that we only want to compute */
|
||||
/* the glyph's metrics (lsb + advance width), not load the */
|
||||
/* `metrics_only' indicates that we only want to compute the */
|
||||
/* glyph's metrics (lsb + advance width) without loading the */
|
||||
/* rest of it; so exit immediately */
|
||||
if ( builder->metrics_only )
|
||||
{
|
||||
|
@ -1749,8 +1749,6 @@
|
|||
case 7:
|
||||
case 8:
|
||||
case 9:
|
||||
case 10:
|
||||
case 11:
|
||||
case 14:
|
||||
case 15:
|
||||
case 21:
|
||||
|
@ -1759,6 +1757,13 @@
|
|||
case 31:
|
||||
goto No_Width;
|
||||
|
||||
case 10:
|
||||
op = op_callsubr;
|
||||
break;
|
||||
case 11:
|
||||
op = op_return;
|
||||
break;
|
||||
|
||||
case 13:
|
||||
op = op_hsbw;
|
||||
break;
|
||||
|
@ -1898,13 +1903,20 @@
|
|||
|
||||
#ifdef FT_DEBUG_LEVEL_TRACE
|
||||
|
||||
if ( op != op_div )
|
||||
switch ( op )
|
||||
{
|
||||
case op_callsubr:
|
||||
case op_div:
|
||||
case op_return:
|
||||
break;
|
||||
|
||||
default:
|
||||
if ( top - decoder->stack != num_args )
|
||||
FT_TRACE0(( "t1_decoder_parse_metrics:"
|
||||
" too much operands on the stack"
|
||||
" (seen %d, expected %d)\n",
|
||||
top - decoder->stack, num_args ));
|
||||
break;
|
||||
}
|
||||
|
||||
#endif /* FT_DEBUG_LEVEL_TRACE */
|
||||
|
@ -1925,8 +1937,8 @@
|
|||
builder->advance.y = 0;
|
||||
|
||||
/* we only want to compute the glyph's metrics */
|
||||
/* (lsb + advance width), not load the rest of */
|
||||
/* it; so exit immediately */
|
||||
/* (lsb + advance width) without loading the */
|
||||
/* rest of it; so exit immediately */
|
||||
FT_TRACE4(( "\n" ));
|
||||
return FT_Err_Ok;
|
||||
|
||||
|
@ -1944,8 +1956,8 @@
|
|||
builder->advance.y = top[3];
|
||||
|
||||
/* we only want to compute the glyph's metrics */
|
||||
/* (lsb + advance width), not load the rest of */
|
||||
/* it; so exit immediately */
|
||||
/* (lsb + advance width), without loading the */
|
||||
/* rest of it; so exit immediately */
|
||||
FT_TRACE4(( "\n" ));
|
||||
return FT_Err_Ok;
|
||||
|
||||
|
@ -1961,6 +1973,91 @@
|
|||
large_int = FALSE;
|
||||
break;
|
||||
|
||||
case op_callsubr:
|
||||
{
|
||||
FT_Int idx;
|
||||
|
||||
|
||||
FT_TRACE4(( " callsubr" ));
|
||||
|
||||
idx = Fix2Int( top[0] );
|
||||
|
||||
if ( decoder->subrs_hash )
|
||||
{
|
||||
size_t* val = ft_hash_num_lookup( idx,
|
||||
decoder->subrs_hash );
|
||||
|
||||
|
||||
if ( val )
|
||||
idx = *val;
|
||||
else
|
||||
idx = -1;
|
||||
}
|
||||
|
||||
if ( idx < 0 || idx >= decoder->num_subrs )
|
||||
{
|
||||
FT_ERROR(( "t1_decoder_parse_metrics:"
|
||||
" invalid subrs index\n" ));
|
||||
goto Syntax_Error;
|
||||
}
|
||||
|
||||
if ( zone - decoder->zones >= T1_MAX_SUBRS_CALLS )
|
||||
{
|
||||
FT_ERROR(( "t1_decoder_parse_metrics:"
|
||||
" too many nested subrs\n" ));
|
||||
goto Syntax_Error;
|
||||
}
|
||||
|
||||
zone->cursor = ip; /* save current instruction pointer */
|
||||
|
||||
zone++;
|
||||
|
||||
/* The Type 1 driver stores subroutines without the seed bytes. */
|
||||
/* The CID driver stores subroutines with seed bytes. This */
|
||||
/* case is taken care of when decoder->subrs_len == 0. */
|
||||
zone->base = decoder->subrs[idx];
|
||||
|
||||
if ( decoder->subrs_len )
|
||||
zone->limit = zone->base + decoder->subrs_len[idx];
|
||||
else
|
||||
{
|
||||
/* We are using subroutines from a CID font. We must adjust */
|
||||
/* for the seed bytes. */
|
||||
zone->base += ( decoder->lenIV >= 0 ? decoder->lenIV : 0 );
|
||||
zone->limit = decoder->subrs[idx + 1];
|
||||
}
|
||||
|
||||
zone->cursor = zone->base;
|
||||
|
||||
if ( !zone->base )
|
||||
{
|
||||
FT_ERROR(( "t1_decoder_parse_metrics:"
|
||||
" invoking empty subrs\n" ));
|
||||
goto Syntax_Error;
|
||||
}
|
||||
|
||||
decoder->zone = zone;
|
||||
ip = zone->base;
|
||||
limit = zone->limit;
|
||||
break;
|
||||
}
|
||||
|
||||
case op_return:
|
||||
FT_TRACE4(( " return" ));
|
||||
|
||||
if ( zone <= decoder->zones )
|
||||
{
|
||||
FT_ERROR(( "t1_decoder_parse_metrics:"
|
||||
" unexpected return\n" ));
|
||||
goto Syntax_Error;
|
||||
}
|
||||
|
||||
zone--;
|
||||
ip = zone->cursor;
|
||||
limit = zone->limit;
|
||||
decoder->zone = zone;
|
||||
break;
|
||||
|
||||
default:
|
||||
FT_ERROR(( "t1_decoder_parse_metrics:"
|
||||
" unhandled opcode %d\n", op ));
|
||||
|
|
Loading…
Reference in New Issue