diff --git a/src/cairo-pdf-surface.c b/src/cairo-pdf-surface.c index 91a1968..9f099ae 100644 --- a/src/cairo-pdf-surface.c +++ b/src/cairo-pdf-surface.c @@ -274,7 +274,7 @@ _cairo_pdf_surface_create_for_stream_int _cairo_array_init (&surface->streams, sizeof (cairo_pdf_resource_t)); _cairo_array_init (&surface->alphas, sizeof (double)); - surface->font_subsets = _cairo_scaled_font_subsets_create (PDF_SURFACE_MAX_GLYPHS_PER_FONT); + surface->font_subsets = _cairo_scaled_font_subsets_create (PDF_SURFACE_MAX_GLYPHS_PER_FONT, TRUE); if (! surface->font_subsets) { _cairo_error (CAIRO_STATUS_NO_MEMORY); free (surface); diff --git a/src/cairo-ps-surface.c b/src/cairo-ps-surface.c index 6ae3a38..f1151c2 100644 --- a/src/cairo-ps-surface.c +++ b/src/cairo-ps-surface.c @@ -761,7 +761,7 @@ _cairo_ps_surface_create_for_stream_inte if (status) goto CLEANUP_TMPFILE; - surface->font_subsets = _cairo_scaled_font_subsets_create (PS_SURFACE_MAX_GLYPHS_PER_FONT); + surface->font_subsets = _cairo_scaled_font_subsets_create (PS_SURFACE_MAX_GLYPHS_PER_FONT, TRUE); if (! surface->font_subsets) goto CLEANUP_OUTPUT_STREAM; diff --git a/src/cairo-scaled-font-subsets-private.h b/src/cairo-scaled-font-subsets-private.h index c41e477..6d0e942 100644 --- a/src/cairo-scaled-font-subsets-private.h +++ b/src/cairo-scaled-font-subsets-private.h @@ -58,6 +58,8 @@ typedef struct _cairo_scaled_font_subset * @max_glyphs_per_subset: the maximum number of glyphs that should * appear in any subset. A value of 0 indicates that there is no limit * to the number of glyphs per subset. + * @merge_scaled: merge all scaled fonts with the same face into + * the same subset. * * Create a new #cairo_scaled_font_subsets_t object which can be used * to create subsets of any number of cairo_scaled_font_t @@ -71,7 +73,7 @@ typedef struct _cairo_scaled_font_subset * _cairo_scaled_font_subsets_destroy() when done with it. **/ cairo_private cairo_scaled_font_subsets_t * -_cairo_scaled_font_subsets_create (int max_glyphs_per_subset); +_cairo_scaled_font_subsets_create (int max_glyphs_per_subset, cairo_bool_t merge_scaled); /** * _cairo_scaled_font_subsets_destroy: diff --git a/src/cairo-scaled-font-subsets.c b/src/cairo-scaled-font-subsets.c index 0c428e7..d1e25b4 100644 --- a/src/cairo-scaled-font-subsets.c +++ b/src/cairo-scaled-font-subsets.c @@ -46,6 +46,7 @@ struct _cairo_scaled_font_subsets { int max_glyphs_per_subset_limit; int max_glyphs_per_subset_used; int num_sub_fonts; + cairo_bool_t merge_scaled; cairo_hash_table_t *sub_fonts; }; @@ -55,6 +56,7 @@ typedef struct _cairo_sub_font { cairo_scaled_font_subsets_t *parent; cairo_scaled_font_t *scaled_font; + cairo_font_face_t *font_face; unsigned int font_id; int current_subset; @@ -174,6 +176,23 @@ _cairo_sub_font_init_key (cairo_sub_font sub_font->scaled_font = scaled_font; } +static cairo_bool_t +_cairo_sub_fonts_merged_equal (const void *key_a, const void *key_b) +{ + const cairo_sub_font_t *sub_font_a = key_a; + const cairo_sub_font_t *sub_font_b = key_b; + + return sub_font_a->font_face == sub_font_b->font_face; +} + +static void +_cairo_sub_font_merged_init_key (cairo_sub_font_t *sub_font, + cairo_font_face_t *font_face) +{ + sub_font->base.hash = (unsigned long) font_face; + sub_font->font_face = font_face; +} + static cairo_sub_font_t * _cairo_sub_font_create (cairo_scaled_font_subsets_t *parent, cairo_scaled_font_t *scaled_font, @@ -186,7 +205,10 @@ _cairo_sub_font_create (cairo_scaled_fon if (sub_font == NULL) return NULL; - _cairo_sub_font_init_key (sub_font, scaled_font); + if (parent->merge_scaled) + _cairo_sub_font_merged_init_key (sub_font, scaled_font->font_face); + else + _cairo_sub_font_init_key (sub_font, scaled_font); sub_font->parent = parent; sub_font->scaled_font = cairo_scaled_font_reference (scaled_font); @@ -196,7 +218,9 @@ _cairo_sub_font_create (cairo_scaled_fon sub_font->num_glyphs_in_current_subset = 0; sub_font->max_glyphs_per_subset = max_glyphs_per_subset; - sub_font->sub_font_glyphs = _cairo_hash_table_create (_cairo_sub_font_glyphs_equal); + if (parent->merge_scaled) + sub_font->sub_font_glyphs = _cairo_hash_table_create (_cairo_sub_font_glyphs_equal); + sub_font->sub_font_glyphs = _cairo_hash_table_create (_cairo_sub_font_glyphs_equal); if (! sub_font->sub_font_glyphs) { free (sub_font); return NULL; @@ -298,7 +322,7 @@ _cairo_sub_font_collect (void *entry, vo } cairo_scaled_font_subsets_t * -_cairo_scaled_font_subsets_create (int max_glyphs_per_subset) +_cairo_scaled_font_subsets_create (int max_glyphs_per_subset, cairo_bool_t merge_scaled) { cairo_scaled_font_subsets_t *subsets; @@ -309,7 +333,11 @@ _cairo_scaled_font_subsets_create (int m subsets->max_glyphs_per_subset_limit = max_glyphs_per_subset; subsets->max_glyphs_per_subset_used = 0; subsets->num_sub_fonts = 0; + subsets->merge_scaled = merge_scaled; + if (merge_scaled) + subsets->sub_fonts = _cairo_hash_table_create (_cairo_sub_fonts_merged_equal); + else subsets->sub_fonts = _cairo_hash_table_create (_cairo_sub_fonts_equal); if (! subsets->sub_fonts) { free (subsets); @@ -338,7 +366,10 @@ _cairo_scaled_font_subsets_map_glyph (ca cairo_sub_font_t key, *sub_font; cairo_status_t status; - _cairo_sub_font_init_key (&key, scaled_font); + if (subsets->merge_scaled) + _cairo_sub_font_merged_init_key (&key, scaled_font->font_face); + else + _cairo_sub_font_init_key (&key, scaled_font); if (! _cairo_hash_table_lookup (subsets->sub_fonts, &key.base, (cairo_hash_entry_t **) &sub_font)) { diff --git a/src/cairo-svg-surface.c b/src/cairo-svg-surface.c index abc1ec3..55ed08a 100644 --- a/src/cairo-svg-surface.c +++ b/src/cairo-svg-surface.c @@ -1697,7 +1697,7 @@ _cairo_svg_document_create (cairo_output } /* The use of defs for font glyphs imposes no per-subset limit. */ - document->font_subsets = _cairo_scaled_font_subsets_create (0); + document->font_subsets = _cairo_scaled_font_subsets_create (0, FALSE); if (document->font_subsets == NULL) { _cairo_error (CAIRO_STATUS_NO_MEMORY); free (document);