summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAdrian Johnson <ajohnson@redneon.com>2010-11-28 03:46:10 +1030
committerAdrian Johnson <ajohnson@redneon.com>2010-11-28 03:46:10 +1030
commit7feefc75f6dcb9381cd5bc1bdc3e2d722789b155 (patch)
treec3a16d2e27a1bd6e9dd50c4174b1fdc0c91c8a6c
parentf85af7fe8d92f5ac304d742fcbfdaac512bace33 (diff)
CFF subset: fix subsetting of Euro glyph
https://bugs.freedesktop.org/show_bug.cgi?id=31878
-rw-r--r--src/cairo-cff-subset.c51
1 files changed, 38 insertions, 13 deletions
diff --git a/src/cairo-cff-subset.c b/src/cairo-cff-subset.c
index 44d1f5e56..26c39a4d8 100644
--- a/src/cairo-cff-subset.c
+++ b/src/cairo-cff-subset.c
@@ -131,6 +131,7 @@ typedef struct _cairo_cff_font {
char *subset_font_name;
cairo_array_t charstrings_subset_index;
cairo_array_t strings_subset_index;
+ int euro_sid;
int *fdselect_subset;
unsigned int num_subset_fontdicts;
int *fd_subset_map;
@@ -1247,6 +1248,33 @@ cairo_cff_font_subset_strings (cairo_cff_font_t *font)
return status;
}
+/* The Euro is the only the only character in the winansi encoding
+ * with a glyph name that is not a CFF standard string. As the strings
+ * are written before the charset, we need to check during the
+ * subsetting phase if the Euro glyph is required and add the
+ * glyphname to the list of strings to write out.
+ */
+static cairo_status_t
+cairo_cff_font_subset_charset_strings (cairo_cff_font_t *font)
+{
+ cairo_status_t status;
+ unsigned int i;
+ int ch;
+ const char *euro = "Euro";
+
+ for (i = 1; i < font->scaled_font_subset->num_glyphs; i++) {
+ ch = font->scaled_font_subset->to_latin_char[i];
+ if (ch == 128) {
+ font->euro_sid = NUM_STD_STRINGS + _cairo_array_num_elements (&font->strings_subset_index);
+ status = cff_index_append_copy (&font->strings_subset_index,
+ (unsigned char *)euro, strlen(euro));
+ return status;
+ }
+ }
+
+ return CAIRO_STATUS_SUCCESS;
+}
+
static cairo_status_t
cairo_cff_font_subset_font (cairo_cff_font_t *font)
{
@@ -1279,6 +1307,9 @@ cairo_cff_font_subset_font (cairo_cff_font_t *font)
if (unlikely (status))
return status;
+ if (font->scaled_font_subset->is_latin)
+ status = cairo_cff_font_subset_charset_strings (font);
+
return status;
}
@@ -1500,12 +1531,10 @@ static const int winansi_to_cff_std_string[] = {
147, 225, 222, 223, 224, 226, 162, 227,
};
-static cairo_status_t
-cairo_cff_font_get_sid_for_winansi_char (cairo_cff_font_t *font, int ch, int *sid_out)
+static int
+cairo_cff_font_get_sid_for_winansi_char (cairo_cff_font_t *font, int ch)
{
int sid;
- cairo_status_t status;
- const char *euro = "Euro";
if (ch == 39) {
sid = 104;
@@ -1517,11 +1546,8 @@ cairo_cff_font_get_sid_for_winansi_char (cairo_cff_font_t *font, int ch, int *s
sid = ch - 31;
} else if (ch == 128) {
- sid = NUM_STD_STRINGS + _cairo_array_num_elements (&font->strings_subset_index);
- status = cff_index_append_copy (&font->strings_subset_index,
- (unsigned char *)euro, strlen(euro));
- if (unlikely (status))
- return status;
+ assert (font->euro_sid >= NUM_STD_STRINGS);
+ sid = font->euro_sid;
} else if (ch >= 128 && ch <= 255) {
sid = winansi_to_cff_std_string[ch - 128];
@@ -1530,9 +1556,7 @@ cairo_cff_font_get_sid_for_winansi_char (cairo_cff_font_t *font, int ch, int *s
sid = 0;
}
- *sid_out = sid;
-
- return CAIRO_STATUS_SUCCESS;
+ return sid;
}
static cairo_status_t
@@ -1551,7 +1575,7 @@ cairo_cff_font_write_type1_charset (cairo_cff_font_t *font)
for (i = 1; i < font->scaled_font_subset->num_glyphs; i++) {
ch = font->scaled_font_subset->to_latin_char[i];
- status = cairo_cff_font_get_sid_for_winansi_char (font, ch, &sid);
+ sid = cairo_cff_font_get_sid_for_winansi_char (font, ch);
if (unlikely (status))
return status;
@@ -2021,6 +2045,7 @@ _cairo_cff_font_create (cairo_scaled_font_subset_t *scaled_font_subset,
cff_index_init (&font->local_sub_index);
cff_index_init (&font->charstrings_subset_index);
cff_index_init (&font->strings_subset_index);
+ font->euro_sid = 0;
font->fdselect = NULL;
font->fd_dict = NULL;
font->fd_private_dict = NULL;