summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAdrian Johnson <ajohnson@redneon.com>2012-10-28 20:58:52 +1030
committerAdrian Johnson <ajohnson@redneon.com>2012-10-28 22:13:31 +1030
commit5a6e1d680a5bf1c4091e74f999abd611abd92334 (patch)
tree0792b36468fedb0f56cbd3610c3c75a9854e0e1d
parent0e2458697848cf8c89c9d57fa9b64f0ea7bd0877 (diff)
downloadcairo-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.c35
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,