Extend Adobe interpreter (callsubr). * src/psaux/psintrp.c (cf2_interpT2CharString) <cf2_cmdCALLSUBR>: Type 1 mode. * src/psaux/psft.c (cf2_initLocalRegionBuffer): Add Type 1 mode.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95
diff --git a/ChangeLog b/ChangeLog
index 4641f1d..1e9c972 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,14 @@
2017-09-25 Ewald Hew <ewaldhew@gmail.com>
+ [psaux] Extend Adobe interpreter (callsubr).
+
+ * src/psaux/psintrp.c (cf2_interpT2CharString) <cf2_cmdCALLSUBR>:
+ Type 1 mode.
+
+ * src/psaux/psft.c (cf2_initLocalRegionBuffer): Add Type 1 mode.
+
+2017-09-25 Ewald Hew <ewaldhew@gmail.com>
+
[psaux] Extend Adobe interpreter (div, four-byte numbers).
* src/psaux/psintrp.c (cf2_interpT2CharString) <cf2_escDIV>: Add
diff --git a/src/psaux/psft.c b/src/psaux/psft.c
index ab19826..81d3fd8 100644
--- a/src/psaux/psft.c
+++ b/src/psaux/psft.c
@@ -718,14 +718,40 @@
FT_ZERO( buf );
idx = (CF2_UInt)( subrNum + decoder->locals_bias );
- if ( idx >= decoder->num_locals )
+ if ( idx < 0 || idx >= decoder->num_locals )
return TRUE; /* error */
FT_ASSERT( decoder->locals );
- buf->start =
- buf->ptr = decoder->locals[idx];
- buf->end = decoder->locals[idx + 1];
+ buf->start = decoder->locals[idx];
+
+ if ( decoder->builder.is_t1 )
+ {
+ /* 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. */
+ if ( decoder->locals_len )
+ buf->end = buf->start + decoder->locals_len[idx];
+ else
+ {
+ /* We are using subroutines from a CID font. We must adjust */
+ /* for the seed bytes. */
+ buf->start += ( decoder->lenIV >= 0 ? decoder->lenIV : 0 );
+ buf->end = decoder->locals[idx + 1];
+ }
+
+ if ( !buf->start )
+ {
+ FT_ERROR(( "cf2_initLocalRegionBuffer (Type 1 mode):"
+ " invoking empty subrs\n" ));
+ }
+ }
+ else
+ {
+ buf->end = decoder->locals[idx + 1];
+ }
+
+ buf->ptr = buf->start;
return FALSE; /* success */
}
diff --git a/src/psaux/psintrp.c b/src/psaux/psintrp.c
index 34607ca..7ee3a25 100644
--- a/src/psaux/psintrp.c
+++ b/src/psaux/psintrp.c
@@ -975,7 +975,8 @@
FT_TRACE4(( op1 == cf2_cmdCALLGSUBR ? " callgsubr"
: " callsubr" ));
- if ( charstringIndex > CF2_MAX_SUBR )
+ if ( ( !font->isT1 && charstringIndex > CF2_MAX_SUBR ) ||
+ ( font->isT1 && charstringIndex > T1_MAX_SUBRS_CALLS ) )
{
/* max subr plus one for charstring */
lastError = FT_THROW( Invalid_Glyph_Format );
@@ -991,10 +992,10 @@
/* set up the new CFF region and pointer */
subrNum = cf2_stack_popInt( opStack );
- if ( font->isT1 && decoder->subrs_hash )
+ if ( font->isT1 && decoder->locals_hash )
{
size_t* val = ft_hash_num_lookup( subrNum,
- decoder->subrs_hash );
+ decoder->locals_hash );
if ( val )
subrNum = *val;