[psaux] Make `t1_decoder_parse_metrics' handle `op_div' (#57519).

* src/psaux/t1decode.c (t1_decoder_parse_metrics): Copy
corresponding code from old engine's `t1_decoder_parse_charstrings'
function.
This commit is contained in:
Werner Lemberg 2020-02-21 20:57:52 +01:00
parent 49f3394d7a
commit 6e49dff005
2 changed files with 58 additions and 12 deletions

View File

@ -1,3 +1,11 @@
2020-02-21 Werner Lemberg <wl@gnu.org>
[psaux] Make `t1_decoder_parse_metrics' handle `op_div' (#57519).
* src/psaux/t1decode.c (t1_decoder_parse_metrics): Copy
corresponding code from old engine's `t1_decoder_parse_charstrings'
function.
2020-02-19 Nikolaus Waxweiler <nikolaus.waxweiler@daltonmaag.com> 2020-02-19 Nikolaus Waxweiler <nikolaus.waxweiler@daltonmaag.com>
[autofit] Add support for Hanifi Rohingya script. [autofit] Add support for Hanifi Rohingya script.

View File

@ -659,10 +659,8 @@
if ( value > 32000 || value < -32000 ) if ( value > 32000 || value < -32000 )
{ {
if ( large_int ) if ( large_int )
{
FT_ERROR(( "t1_decoder_parse_charstrings:" FT_ERROR(( "t1_decoder_parse_charstrings:"
" no `div' after large integer\n" )); " no `div' after large integer\n" ));
}
else else
large_int = TRUE; large_int = TRUE;
} }
@ -1699,6 +1697,7 @@
FT_Byte* ip; FT_Byte* ip;
FT_Byte* limit; FT_Byte* limit;
T1_Builder builder = &decoder->builder; T1_Builder builder = &decoder->builder;
FT_Bool large_int;
#ifdef FT_DEBUG_LEVEL_TRACE #ifdef FT_DEBUG_LEVEL_TRACE
FT_Bool bol = TRUE; FT_Bool bol = TRUE;
@ -1716,6 +1715,8 @@
limit = zone->limit = charstring_base + charstring_len; limit = zone->limit = charstring_base + charstring_len;
ip = zone->cursor = zone->base; ip = zone->cursor = zone->base;
large_int = FALSE;
/* now, execute loop */ /* now, execute loop */
while ( ip < limit ) while ( ip < limit )
{ {
@ -1776,6 +1777,9 @@
case 7: case 7:
op = op_sbw; op = op_sbw;
break; break;
case 12:
op = op_div;
break;
default: default:
goto No_Width; goto No_Width;
@ -1805,13 +1809,19 @@
/* anyway. */ /* anyway. */
if ( value > 32000 || value < -32000 ) if ( value > 32000 || value < -32000 )
{ {
FT_ERROR(( "t1_decoder_parse_metrics:" if ( large_int )
" large integer found for width\n" )); {
goto Syntax_Error; FT_ERROR(( "t1_decoder_parse_metrics:"
" no `div' after large integer\n" ));
goto Syntax_Error;
}
else
large_int = TRUE;
} }
else else
{ {
value = (FT_Int32)( (FT_UInt32)value << 16 ); if ( !large_int )
value = (FT_Int32)( (FT_UInt32)value << 16 );
} }
break; break;
@ -1836,7 +1846,8 @@
value = -( ( ( ip[-2] - 251 ) * 256 ) + ip[-1] + 108 ); value = -( ( ( ip[-2] - 251 ) * 256 ) + ip[-1] + 108 );
} }
value = (FT_Int32)( (FT_UInt32)value << 16 ); if ( !large_int )
value = (FT_Int32)( (FT_UInt32)value << 16 );
} }
else else
{ {
@ -1846,6 +1857,13 @@
} }
} }
if ( large_int && !( op == op_none || op == op_div ) )
{
FT_ERROR(( "t1_decoder_parse_metrics:"
" no `div' after large integer\n" ));
goto Syntax_Error;
}
/********************************************************************** /**********************************************************************
* *
* Push value on stack, or process operator * Push value on stack, or process operator
@ -1860,6 +1878,9 @@
} }
#ifdef FT_DEBUG_LEVEL_TRACE #ifdef FT_DEBUG_LEVEL_TRACE
if ( large_int )
FT_TRACE4(( " %d", value ));
else
FT_TRACE4(( " %d", value / 65536 )); FT_TRACE4(( " %d", value / 65536 ));
#endif #endif
@ -1878,11 +1899,14 @@
#ifdef FT_DEBUG_LEVEL_TRACE #ifdef FT_DEBUG_LEVEL_TRACE
if ( top - decoder->stack != num_args ) if ( op != op_div )
FT_TRACE0(( "t1_decoder_parse_metrics:" {
" too much operands on the stack" if ( top - decoder->stack != num_args )
" (seen %d, expected %d)\n", FT_TRACE0(( "t1_decoder_parse_metrics:"
top - decoder->stack, num_args )); " too much operands on the stack"
" (seen %d, expected %d)\n",
top - decoder->stack, num_args ));
}
#endif /* FT_DEBUG_LEVEL_TRACE */ #endif /* FT_DEBUG_LEVEL_TRACE */
@ -1926,12 +1950,26 @@
FT_TRACE4(( "\n" )); FT_TRACE4(( "\n" ));
return FT_Err_Ok; return FT_Err_Ok;
case op_div:
FT_TRACE4(( " div" ));
/* if `large_int' is set, we divide unscaled numbers; */
/* otherwise, we divide numbers in 16.16 format -- */
/* in both cases, it is the same operation */
*top = FT_DivFix( top[0], top[1] );
top++;
large_int = FALSE;
break;
default: default:
FT_ERROR(( "t1_decoder_parse_metrics:" FT_ERROR(( "t1_decoder_parse_metrics:"
" unhandled opcode %d\n", op )); " unhandled opcode %d\n", op ));
goto Syntax_Error; goto Syntax_Error;
} }
decoder->top = top;
} /* general operator processing */ } /* general operator processing */
} /* while ip < limit */ } /* while ip < limit */