diff options
author | Adrian Johnson <ajohnson@redneon.com> | 2012-10-28 20:58:52 +1030 |
---|---|---|
committer | Adrian Johnson <ajohnson@redneon.com> | 2012-10-28 22:13:31 +1030 |
commit | 5a6e1d680a5bf1c4091e74f999abd611abd92334 (patch) | |
tree | 0792b36468fedb0f56cbd3610c3c75a9854e0e1d | |
parent | 0e2458697848cf8c89c9d57fa9b64f0ea7bd0877 (diff) | |
download | cairo-5a6e1d680a5bf1c4091e74f999abd611abd92334.tar.gz |
type1-subset: restore correct callothersub behavior
that was removed in d57e652f. Without this subsetting of subroutines
won't work for some fonts.
-rw-r--r-- | src/cairo-type1-subset.c | 35 |
1 files changed, 29 insertions, 6 deletions
diff --git a/src/cairo-type1-subset.c b/src/cairo-type1-subset.c index c7f613a01..786055a3b 100644 --- a/src/cairo-type1-subset.c +++ b/src/cairo-type1-subset.c @@ -141,6 +141,11 @@ typedef struct _cairo_type1_font_subset { int sp; } build_stack; + struct { + int stack[TYPE1_STACKSIZE]; + int sp; + } ps_stack; + } cairo_type1_font_subset_t; @@ -767,7 +772,9 @@ use_standard_encoding_glyph (cairo_type1_font_subset_t *font, int index) #define TYPE1_CHARSTRING_COMMAND_POP 0x0c11 #define TYPE1_CHARSTRING_COMMAND_SETCURRENTPOINT 0x0c21 -/* Get glyph width and look for seac operatorParse charstring */ +/* Parse the charstring, including recursing into subroutines. Find + * the glyph width, subroutines called, and glyphs required by the + * SEAC operator. */ static cairo_status_t cairo_type1_font_subset_parse_charstring (cairo_type1_font_subset_t *font, int glyph, @@ -814,6 +821,7 @@ cairo_type1_font_subset_parse_charstring (cairo_type1_font_subset_t *font, case TYPE1_CHARSTRING_COMMAND_RETURN: case TYPE1_CHARSTRING_COMMAND_ENDCHAR: default: + /* stack clearing operator */ font->build_stack.sp = 0; break; @@ -848,8 +856,8 @@ cairo_type1_font_subset_parse_charstring (cairo_type1_font_subset_t *font, case TYPE1_CHARSTRING_COMMAND_VSTEM3: case TYPE1_CHARSTRING_COMMAND_HSTEM3: case TYPE1_CHARSTRING_COMMAND_SETCURRENTPOINT: - case TYPE1_CHARSTRING_COMMAND_CALLOTHERSUBR: default: + /* stack clearing operator */ font->build_stack.sp = 0; break; @@ -896,11 +904,25 @@ cairo_type1_font_subset_parse_charstring (cairo_type1_font_subset_t *font, } break; + case TYPE1_CHARSTRING_COMMAND_CALLOTHERSUBR: + if (font->build_stack.sp < 1) + return CAIRO_INT_STATUS_UNSUPPORTED; + + font->build_stack.sp--; + font->ps_stack.sp = 0; + while (font->build_stack.sp) + font->ps_stack.stack[font->ps_stack.sp++] = font->build_stack.stack[--font->build_stack.sp]; + + break; + case TYPE1_CHARSTRING_COMMAND_POP: - if (font->build_stack.sp < TYPE1_STACKSIZE) { - /* use negative number to prevent it being used as a subr_num */ - font->build_stack.stack[font->build_stack.sp++] = -1.0; - } + if (font->ps_stack.sp < 1) + return CAIRO_INT_STATUS_UNSUPPORTED; + + /* T1 spec states that if the interpreter does not + * support executing the callothersub, the results + * must be taken from the callothersub arguments. */ + font->build_stack.stack[font->build_stack.sp++] = font->ps_stack.stack[--font->ps_stack.sp]; break; } break; @@ -1355,6 +1377,7 @@ skip_subrs: for (j = 0; j < font->num_glyphs; j++) { glyph = font->subset_index_to_glyphs[j]; font->build_stack.sp = 0; + font->ps_stack.sp = 0; status = cairo_type1_font_subset_parse_charstring (font, glyph, font->glyphs[glyph].encrypted_charstring, |