|
| 1 | +From ff4fd6f960deb7afdac233465a1f4e807234ad15 Mon Sep 17 00:00:00 2001 |
| 2 | +From: Adrian Johnson <ajohnson@redneon.com> |
| 3 | +Date: Sun, 3 Apr 2022 20:03:58 +0930 |
| 4 | +Subject: [PATCH] Fix type1-subset indexing |
| 5 | + |
| 6 | +Fixes #551 |
| 7 | + |
| 8 | +Signed-off-by: Laurent Carlier <lordheavym@gmail.com> |
| 9 | +--- |
| 10 | + src/cairo-type1-subset.c | 50 ++++++++++++++++++++++++++-------------- |
| 11 | + 1 file changed, 33 insertions(+), 17 deletions(-) |
| 12 | + |
| 13 | +diff --git a/src/cairo-type1-subset.c b/src/cairo-type1-subset.c |
| 14 | +index 73f414dc4..0166f7a78 100644 |
| 15 | +--- a/src/cairo-type1-subset.c |
| 16 | ++++ b/src/cairo-type1-subset.c |
| 17 | +@@ -70,7 +70,7 @@ typedef struct _cairo_type1_font_subset { |
| 18 | + struct { |
| 19 | + unsigned int font_id; |
| 20 | + char *base_font; |
| 21 | +- unsigned int num_glyphs; |
| 22 | ++ unsigned int num_glyphs; /* Num /CharStrings in font */ |
| 23 | + double x_min, y_min, x_max, y_max; |
| 24 | + double ascent, descent; |
| 25 | + double units_per_em; |
| 26 | +@@ -81,6 +81,9 @@ typedef struct _cairo_type1_font_subset { |
| 27 | + unsigned long trailer_size; |
| 28 | + } base; |
| 29 | + |
| 30 | ++ /* Num glyphs in subset. May be greater than |
| 31 | ++ * scaled_font_subset->num_glyphs due to glyphs required by the |
| 32 | ++ * SEAC operator. */ |
| 33 | + int num_glyphs; |
| 34 | + |
| 35 | + /* The glyphs and glyph_names arrays are indexed by the order of |
| 36 | +@@ -89,12 +92,12 @@ typedef struct _cairo_type1_font_subset { |
| 37 | + * function is used to map the glyph index to the glyph order in |
| 38 | + * the Charstrings. */ |
| 39 | + |
| 40 | +- glyph_data_t *glyphs; |
| 41 | +- char **glyph_names; |
| 42 | + cairo_array_t glyphs_array; |
| 43 | ++ glyph_data_t *glyphs; /* pointer to first element of above array */ |
| 44 | + cairo_array_t glyph_names_array; |
| 45 | ++ char **glyph_names; /* pointer to first element of above array */ |
| 46 | + |
| 47 | +- int num_subrs; |
| 48 | ++ int num_subrs; /* Num /Subrs routines in the font */ |
| 49 | + cairo_bool_t subset_subrs; |
| 50 | + struct { |
| 51 | + const char *subr_string; |
| 52 | +@@ -102,12 +105,17 @@ typedef struct _cairo_type1_font_subset { |
| 53 | + const char *np; |
| 54 | + int np_length; |
| 55 | + cairo_bool_t used; |
| 56 | +- } *subrs; |
| 57 | ++ } *subrs; /* array with num_subrs elements */ |
| 58 | + |
| 59 | +- /* Indexed by subset_index this maps to the glyph order in the |
| 60 | +- * glyph_names and glyphs arrays. Has font->num_glyphs |
| 61 | +- * elements. */ |
| 62 | +- int *subset_index_to_glyphs; |
| 63 | ++ /* Maps scaled_font_subset index to glyphs_array. |
| 64 | ++ * Array size = scaled_font_subset->num_glyphs. */ |
| 65 | ++ int *scaled_subset_index_to_glyphs; |
| 66 | ++ |
| 67 | ++ /* Keeps track of the glyphs that will be emitted in the subset. |
| 68 | ++ * Allocated size = base.num_glyphs. Number of entries = num_glyphs. |
| 69 | ++ * Array values are glyph_array indexes. |
| 70 | ++ */ |
| 71 | ++ int *type1_subset_index_to_glyphs; |
| 72 | + |
| 73 | + cairo_output_stream_t *output; |
| 74 | + cairo_array_t contents; |
| 75 | +@@ -159,7 +167,12 @@ _cairo_type1_font_subset_init (cairo_type1_font_subset_t *font, |
| 76 | + |
| 77 | + _cairo_array_init (&font->glyphs_array, sizeof (glyph_data_t)); |
| 78 | + _cairo_array_init (&font->glyph_names_array, sizeof (char *)); |
| 79 | +- font->subset_index_to_glyphs = NULL; |
| 80 | ++ font->scaled_subset_index_to_glyphs = calloc (scaled_font_subset->num_glyphs, sizeof font->scaled_subset_index_to_glyphs[0]); |
| 81 | ++ if (unlikely (font->scaled_subset_index_to_glyphs == NULL)) |
| 82 | ++ return _cairo_error (CAIRO_STATUS_NO_MEMORY); |
| 83 | ++ |
| 84 | ++ |
| 85 | ++ font->type1_subset_index_to_glyphs = NULL; |
| 86 | + font->base.num_glyphs = 0; |
| 87 | + font->num_subrs = 0; |
| 88 | + font->subset_subrs = TRUE; |
| 89 | +@@ -180,7 +193,7 @@ cairo_type1_font_subset_use_glyph (cairo_type1_font_subset_t *font, int glyph) |
| 90 | + return; |
| 91 | + |
| 92 | + font->glyphs[glyph].subset_index = font->num_glyphs; |
| 93 | +- font->subset_index_to_glyphs[font->num_glyphs] = glyph; |
| 94 | ++ font->type1_subset_index_to_glyphs[font->num_glyphs] = glyph; |
| 95 | + font->num_glyphs++; |
| 96 | + } |
| 97 | + |
| 98 | +@@ -552,7 +565,7 @@ cairo_type1_font_subset_write_header (cairo_type1_font_subset_t *font, |
| 99 | + } |
| 100 | + } else { |
| 101 | + for (i = 1; i < font->scaled_font_subset->num_glyphs; i++) { |
| 102 | +- glyph = font->scaled_font_subset->glyphs[i]; |
| 103 | ++ glyph = font->scaled_subset_index_to_glyphs[i]; |
| 104 | + _cairo_output_stream_printf (font->output, |
| 105 | + "dup %d /%s put\n", |
| 106 | + i, |
| 107 | +@@ -1391,8 +1404,8 @@ skip_subrs: |
| 108 | + font->glyphs = _cairo_array_index (&font->glyphs_array, 0); |
| 109 | + font->glyph_names = _cairo_array_index (&font->glyph_names_array, 0); |
| 110 | + font->base.num_glyphs = _cairo_array_num_elements (&font->glyphs_array); |
| 111 | +- font->subset_index_to_glyphs = calloc (font->base.num_glyphs, sizeof font->subset_index_to_glyphs[0]); |
| 112 | +- if (unlikely (font->subset_index_to_glyphs == NULL)) |
| 113 | ++ font->type1_subset_index_to_glyphs = calloc (font->base.num_glyphs, sizeof font->type1_subset_index_to_glyphs[0]); |
| 114 | ++ if (unlikely (font->type1_subset_index_to_glyphs == NULL)) |
| 115 | + return _cairo_error (CAIRO_STATUS_NO_MEMORY); |
| 116 | + |
| 117 | + backend = font->scaled_font_subset->scaled_font->backend; |
| 118 | +@@ -1414,6 +1427,7 @@ skip_subrs: |
| 119 | + return status; |
| 120 | + |
| 121 | + cairo_type1_font_subset_use_glyph (font, index); |
| 122 | ++ font->scaled_subset_index_to_glyphs[i] = index; |
| 123 | + } |
| 124 | + |
| 125 | + /* Go through the charstring of each glyph in use, get the glyph |
| 126 | +@@ -1421,7 +1435,7 @@ skip_subrs: |
| 127 | + * seac operator (which may cause font->num_glyphs to increase |
| 128 | + * while this loop is executing). Also subset the Subrs. */ |
| 129 | + for (j = 0; j < font->num_glyphs; j++) { |
| 130 | +- glyph = font->subset_index_to_glyphs[j]; |
| 131 | ++ glyph = font->type1_subset_index_to_glyphs[j]; |
| 132 | + font->build_stack.sp = 0; |
| 133 | + font->ps_stack.sp = 0; |
| 134 | + status = cairo_type1_font_subset_parse_charstring (font, |
| 135 | +@@ -1711,7 +1725,9 @@ _cairo_type1_font_subset_fini (cairo_type1_font_subset_t *font) |
| 136 | + |
| 137 | + free (font->base.base_font); |
| 138 | + |
| 139 | +- free (font->subset_index_to_glyphs); |
| 140 | ++ free (font->scaled_subset_index_to_glyphs); |
| 141 | ++ |
| 142 | ++ free (font->type1_subset_index_to_glyphs); |
| 143 | + |
| 144 | + free (font->cleartext); |
| 145 | + |
| 146 | +@@ -1765,7 +1781,7 @@ _cairo_type1_subset_init (cairo_type1_subset_t *type1_subset, |
| 147 | + goto fail2; |
| 148 | + |
| 149 | + for (i = 0; i < font.scaled_font_subset->num_glyphs; i++) { |
| 150 | +- glyph = font.scaled_font_subset->glyphs[i]; |
| 151 | ++ glyph = font.scaled_subset_index_to_glyphs[i]; |
| 152 | + type1_subset->widths[i] = font.glyphs[glyph].width; |
| 153 | + } |
| 154 | + |
| 155 | +-- |
| 156 | +2.35.1 |
| 157 | + |
0 commit comments