@ -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 th e */
/* 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 th e */
/* 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 ) ) ;