Fix PS/PDF Type 1 font embedding when glyph 0 is used

cairo-scaled-fonts-subsets.c reserves position 0 in each subset for
glyph 0 (.notdef) as the font embedding of each font type requires
.notdef as the first glyph. For some reason this was done by reserving
the position then inserting glyph 0 in the collect function instead of
just adding the glyph to the hash table when the subset is
created. The problem this caused was that when an application called
show_glyphs() with glyph 0, the glyph was added to the hash table
(because it was not already there) resulting in two .notdef glyphs in
the subset. This resulted in breakage in the Type 1 subsetting where
the second .notdef was not emitted and all subsequent glyphs were
moved up one place resulting in incorrect font encoding in the PS/PDF
output.

Fix this by adding .notdef to the subset hash table when the subset is
created.

This fixes #13841.
This commit is contained in:
Adrian Johnson 2008-01-20 01:14:19 +10:30
parent 574bdd01fd
commit 8887fb3593

View file

@ -106,6 +106,11 @@ typedef struct _cairo_string_entry {
char *string;
} cairo_string_entry_t;
static cairo_status_t
_cairo_sub_font_map_glyph (cairo_sub_font_t *sub_font,
unsigned long scaled_font_glyph_index,
cairo_scaled_font_subsets_glyph_t *subset_glyph);
static void
_cairo_sub_font_glyph_init_key (cairo_sub_font_glyph_t *sub_font_glyph,
unsigned long scaled_font_glyph_index)
@ -221,6 +226,8 @@ _cairo_sub_font_create (cairo_scaled_font_subsets_t *parent,
cairo_bool_t is_composite)
{
cairo_sub_font_t *sub_font;
cairo_status_t status;
cairo_scaled_font_subsets_glyph_t subset_glyph;
sub_font = malloc (sizeof (cairo_sub_font_t));
if (sub_font == NULL) {
@ -246,9 +253,11 @@ _cairo_sub_font_create (cairo_scaled_font_subsets_t *parent,
return NULL;
}
if (parent->type != CAIRO_SUBSETS_SCALED) {
/* Reserve first glyph in subset for the .notdef glyph */
sub_font->num_glyphs_in_current_subset++;
/* Reserve first glyph in subset for the .notdef glyph */
status = _cairo_sub_font_map_glyph (sub_font, 0, &subset_glyph);
if (status) {
_cairo_error_throw (status);
return NULL;
}
return sub_font;
@ -307,6 +316,7 @@ _cairo_sub_font_map_glyph (cairo_sub_font_t *sub_font,
cairo_sub_font_glyph_t key, *sub_font_glyph;
cairo_status_t status;
cairo_scaled_glyph_t *scaled_glyph;
cairo_scaled_font_subsets_glyph_t tmp_subset_glyph;
_cairo_sub_font_glyph_init_key (&key, scaled_font_glyph_index);
if (! _cairo_hash_table_lookup (sub_font->sub_font_glyphs, &key.base,
@ -317,10 +327,10 @@ _cairo_sub_font_map_glyph (cairo_sub_font_t *sub_font,
sub_font->current_subset++;
sub_font->num_glyphs_in_current_subset = 0;
if (sub_font->parent->type != CAIRO_SUBSETS_SCALED) {
/* Reserve first glyph in subset for the .notdef glyph */
sub_font->num_glyphs_in_current_subset++;
}
/* Reserve first glyph in subset for the .notdef glyph */
status = _cairo_sub_font_map_glyph (sub_font, 0, &tmp_subset_glyph);
if (status)
return status;
}
status = _cairo_scaled_glyph_lookup (sub_font->scaled_font,
@ -381,16 +391,8 @@ _cairo_sub_font_collect (void *entry, void *closure)
for (i = 0; i <= sub_font->current_subset; i++) {
collection->subset_id = i;
if (sub_font->parent->type == CAIRO_SUBSETS_SCALED) {
collection->num_glyphs = 0;
collection->max_glyph = 0;
} else {
/* Assign .notdef glyph to the first glyph in the subset */
collection->glyphs[0] = 0;
collection->num_glyphs = 1;
collection->max_glyph = 0;
}
collection->num_glyphs = 0;
collection->max_glyph = 0;
_cairo_hash_table_foreach (sub_font->sub_font_glyphs,
_cairo_sub_font_glyph_collect, collection);