diff options
author | Ewald Hew <ewaldhew@gmail.com> | 2017-07-24 11:38:04 +0800 |
---|---|---|
committer | Ewald Hew <ewaldhew@gmail.com> | 2017-08-28 08:29:08 +0800 |
commit | 9e2dc76299b6ad21283b956aaf16d66b5257fa63 (patch) | |
tree | fdfa396d78115cf4a508fed6020cc0955873176e | |
parent | d5ea39a756158294eda127b29b89baabdbee45a3 (diff) | |
download | freetype2-9e2dc76299b6ad21283b956aaf16d66b5257fa63.tar.gz |
[psaux] Extend Adobe interpreter. (Numbers)
* src/psaux/psintrp.c (cf2_interpT2CharString)
<div>: Add Type 1 mode. Type 1 requires large integers to be followed by div.
cf. "Adobe Type 1 Font Format", section 6.2.
<255>: Push Type 1 four-byte numbers as Int always. This is to ensure div and
callsubr get values they can use.
-rw-r--r-- | src/psaux/psintrp.c | 53 |
1 files changed, 46 insertions, 7 deletions
diff --git a/src/psaux/psintrp.c b/src/psaux/psintrp.c index 4132931ff..34607ca43 100644 --- a/src/psaux/psintrp.c +++ b/src/psaux/psintrp.c @@ -491,7 +491,7 @@ /* Stuff for Type 1 */ FT_Int known_othersubr_result_cnt = 0; FT_Int unknown_othersubr_result_cnt = 0; - FT_Bool large_int; + FT_Bool large_int = FALSE; /* save this for hinting seac accents */ CF2_Fixed hintOriginY = curY; @@ -1389,14 +1389,22 @@ FT_TRACE4(( " div\n" )); - divisor = cf2_stack_popFixed( opStack ); - dividend = cf2_stack_popFixed( opStack ); + if ( font->isT1 && large_int ) + { + divisor = (CF2_F16Dot16)cf2_stack_popInt( opStack ); + dividend = (CF2_F16Dot16)cf2_stack_popInt( opStack ); + + large_int = FALSE; + } + else + { + divisor = cf2_stack_popFixed( opStack ); + dividend = cf2_stack_popFixed( opStack ); + } cf2_stack_pushFixed( opStack, FT_DivFix( dividend, divisor ) ); - if ( font->isT1 ) - large_int = FALSE; } continue; /* do not clear the stack */ @@ -2237,9 +2245,40 @@ ( byte3 << 8 ) | byte4 ); - FT_TRACE4(( " %.5f", v / 65536.0 )); + /* For Type 1: */ + /* According to the specification, values > 32000 or < -32000 must */ + /* be followed by a `div' operator to make the result be in the */ + /* range [-32000;32000]. We expect that the second argument of */ + /* `div' is not a large number. Additionally, we don't handle */ + /* stuff like `<large1> <large2> <num> div <num> div' or */ + /* <large1> <large2> <num> div div'. This is probably not allowed */ + /* anyway. */ + /* <large> <num> <num>+ div is not checked but should not be */ + /* allowed as the large value remains untouched. */ + if ( font->isT1 ) + { + if ( v > 32000 || v < -32000 ) + { + if ( large_int ) + { + FT_ERROR(( "cf2_interpT2CharString (Type 1 mode):" + " no `div' after large integer\n" )); + } + else + large_int = TRUE; + } + + FT_TRACE4(( " %d", v )); + + cf2_stack_pushInt( opStack, (CF2_Int)v ); + } + else + { + FT_TRACE4(( " %.5fF", v / 65536.0 )); + + cf2_stack_pushFixed( opStack, v ); + } - cf2_stack_pushFixed( opStack, v ); } } continue; /* don't clear stack */ |