diff options
Diffstat (limited to 'gfx/cairo/cairo/src/cairo-scaled-font-subsets.c')
-rw-r--r-- | gfx/cairo/cairo/src/cairo-scaled-font-subsets.c | 127 |
1 files changed, 60 insertions, 67 deletions
diff --git a/gfx/cairo/cairo/src/cairo-scaled-font-subsets.c b/gfx/cairo/cairo/src/cairo-scaled-font-subsets.c index 1f0e53577f..8a25a4612d 100644 --- a/gfx/cairo/cairo/src/cairo-scaled-font-subsets.c +++ b/gfx/cairo/cairo/src/cairo-scaled-font-subsets.c @@ -1,3 +1,4 @@ +/* -*- Mode: c; tab-width: 8; c-basic-offset: 4; indent-tabs-mode: t; -*- */ /* cairo - a vector graphics library with display and print output * * Copyright © 2003 University of Southern California @@ -61,7 +62,6 @@ typedef enum { typedef enum { CAIRO_SUBSETS_FOREACH_UNSCALED, CAIRO_SUBSETS_FOREACH_SCALED, - CAIRO_SUBSETS_FOREACH_USER } cairo_subsets_foreach_type_t; typedef struct _cairo_sub_font { @@ -69,7 +69,6 @@ typedef struct _cairo_sub_font { cairo_bool_t is_scaled; cairo_bool_t is_composite; - cairo_bool_t is_user; cairo_bool_t use_latin_subset; cairo_bool_t reserve_notdef; cairo_scaled_font_subsets_t *parent; @@ -255,12 +254,12 @@ _cairo_sub_font_init_key (cairo_sub_font_t *sub_font, { if (sub_font->is_scaled) { - sub_font->base.hash = (unsigned long) scaled_font; + sub_font->base.hash = (uintptr_t) scaled_font; sub_font->scaled_font = scaled_font; } else { - sub_font->base.hash = (unsigned long) scaled_font->font_face; + sub_font->base.hash = (uintptr_t) scaled_font->font_face; sub_font->scaled_font = scaled_font; } } @@ -283,8 +282,7 @@ _cairo_sub_font_create (cairo_scaled_font_subsets_t *parent, sub_font->is_scaled = is_scaled; sub_font->is_composite = is_composite; - sub_font->is_user = _cairo_font_face_is_user (scaled_font->font_face); - sub_font->reserve_notdef = !sub_font->is_user; + sub_font->reserve_notdef = !sub_font->is_scaled; _cairo_sub_font_init_key (sub_font, scaled_font); sub_font->parent = parent; @@ -294,7 +292,7 @@ _cairo_sub_font_create (cairo_scaled_font_subsets_t *parent, sub_font->use_latin_subset = parent->use_latin_subset; /* latin subsets of Type 3 and CID CFF fonts are not supported */ - if (sub_font->is_user || sub_font->is_scaled || + if (sub_font->is_scaled || _cairo_cff_scaled_font_is_cid_cff (scaled_font) ) { sub_font->use_latin_subset = FALSE; @@ -404,12 +402,10 @@ _cairo_sub_font_glyph_lookup_unicode (cairo_scaled_font_t *scaled_font, if (unicode != (uint32_t) -1) { len = _cairo_ucs4_to_utf8 (unicode, buf); if (len > 0) { - *utf8_out = _cairo_malloc (len + 1); - if (unlikely (*utf8_out == NULL)) - return _cairo_error (CAIRO_STATUS_NO_MEMORY); + *utf8_out = _cairo_strndup (buf, len); + if (unlikely (*utf8_out == NULL)) + return _cairo_error (CAIRO_STATUS_NO_MEMORY); - memcpy (*utf8_out, buf, len); - (*utf8_out)[len] = 0; *utf8_len_out = len; } } @@ -434,19 +430,17 @@ _cairo_sub_font_glyph_map_to_unicode (cairo_sub_font_glyph_t *sub_font_glyph, if (utf8 != NULL && utf8_len != 0) { if (sub_font_glyph->utf8 != NULL) { if (utf8_len == sub_font_glyph->utf8_len && - memcmp (utf8, sub_font_glyph->utf8, utf8_len) == 0) + strncmp (utf8, sub_font_glyph->utf8, utf8_len) == 0) { /* Requested utf8 mapping matches the existing mapping */ *is_mapped = TRUE; } } else { /* No existing mapping. Use the requested mapping */ - sub_font_glyph->utf8 = _cairo_malloc (utf8_len + 1); - if (unlikely (sub_font_glyph->utf8 == NULL)) - return _cairo_error (CAIRO_STATUS_NO_MEMORY); + sub_font_glyph->utf8 = _cairo_strndup (utf8, utf8_len); + if (unlikely (sub_font_glyph->utf8 == NULL)) + return _cairo_error (CAIRO_STATUS_NO_MEMORY); - memcpy (sub_font_glyph->utf8, utf8, utf8_len); - sub_font_glyph->utf8[utf8_len] = 0; sub_font_glyph->utf8_len = utf8_len; *is_mapped = TRUE; } @@ -513,6 +507,7 @@ _cairo_sub_font_add_glyph (cairo_sub_font_t *sub_font, status = _cairo_scaled_glyph_lookup (sub_font->scaled_font, scaled_font_glyph_index, CAIRO_SCALED_GLYPH_INFO_METRICS, + NULL, /* foreground color */ &scaled_glyph); assert (status != CAIRO_INT_STATUS_UNSUPPORTED); if (unlikely (status)) { @@ -611,25 +606,22 @@ _cairo_sub_font_map_glyph (cairo_sub_font_t *sub_font, if (ucs4_len == 1) { font_unicode = ucs4[0]; free (font_utf8); - font_utf8 = _cairo_malloc (text_utf8_len + 1); - if (font_utf8 == NULL) { - free (ucs4); - return _cairo_error (CAIRO_STATUS_NO_MEMORY); + font_utf8 = _cairo_strndup (text_utf8, text_utf8_len); + if (font_utf8 == NULL) { + free (ucs4); + return _cairo_error (CAIRO_STATUS_NO_MEMORY); } - memcpy (font_utf8, text_utf8, text_utf8_len); - font_utf8[text_utf8_len] = 0; font_utf8_len = text_utf8_len; } free (ucs4); } } - /* If glyph is in the winansi encoding and font is not a user + /* If glyph is in the winansi encoding and font is not a scaled * font, put glyph in the latin subset. */ is_latin = FALSE; latin_character = -1; - if (sub_font->use_latin_subset && - (! _cairo_font_face_is_user (sub_font->scaled_font->font_face))) + if (sub_font->use_latin_subset && !sub_font->is_scaled) { latin_character = _cairo_unicode_to_winansi (font_unicode); if (latin_character > 0) @@ -843,6 +835,9 @@ _cairo_scaled_font_subsets_map_glyph (cairo_scaled_font_subsets_t *subsets, cairo_int_status_t status; int max_glyphs; cairo_bool_t type1_font; + cairo_bool_t has_path; + cairo_bool_t has_color; + cairo_bool_t is_user; /* Lookup glyph in unscaled subsets */ if (subsets->type != CAIRO_SUBSETS_SCALED) { @@ -876,29 +871,47 @@ _cairo_scaled_font_subsets_map_glyph (cairo_scaled_font_subsets_t *subsets, /* Glyph not found. Determine whether the glyph is outline or * bitmap and add to the appropriate subset. - * - * glyph_index 0 (the .notdef glyph) is a special case. Some fonts + */ + is_user = _cairo_font_face_is_user (scaled_font->font_face); + _cairo_scaled_font_freeze_cache (scaled_font); + /* Check if glyph is color */ + status = _cairo_scaled_glyph_lookup (scaled_font, + scaled_font_glyph_index, + CAIRO_SCALED_GLYPH_INFO_COLOR_SURFACE, + NULL, /* foreground color */ + &scaled_glyph); + has_color = (status == CAIRO_INT_STATUS_SUCCESS); + + /* Check if glyph has a path */ + status = _cairo_scaled_glyph_lookup (scaled_font, + scaled_font_glyph_index, + CAIRO_SCALED_GLYPH_INFO_PATH, + NULL, /* foreground color */ + &scaled_glyph); + has_path = (status == CAIRO_INT_STATUS_SUCCESS); + + /* glyph_index 0 (the .notdef glyph) is a special case. Some fonts * will return CAIRO_INT_STATUS_UNSUPPORTED when doing a * _scaled_glyph_lookup(_GLYPH_INFO_PATH). Type1-fallback creates * empty glyphs in this case so we can put the glyph in a unscaled - * subset. */ - if (scaled_font_glyph_index == 0 || - _cairo_font_face_is_user (scaled_font->font_face)) { - status = CAIRO_STATUS_SUCCESS; - } else { - _cairo_scaled_font_freeze_cache (scaled_font); - status = _cairo_scaled_glyph_lookup (scaled_font, - scaled_font_glyph_index, - CAIRO_SCALED_GLYPH_INFO_PATH, - &scaled_glyph); - _cairo_scaled_font_thaw_cache (scaled_font); - } + * subset. + */ + if (scaled_font_glyph_index == 0 && !is_user) + has_path = TRUE; + + /* If this fails there is nothing we can do with this glyph. */ + status = _cairo_scaled_glyph_lookup (scaled_font, + scaled_font_glyph_index, + CAIRO_SCALED_GLYPH_INFO_SURFACE, + NULL, /* foreground color */ + &scaled_glyph); + _cairo_scaled_font_thaw_cache (scaled_font); if (_cairo_int_status_is_error (status)) return status; - if (status == CAIRO_INT_STATUS_SUCCESS && - subsets->type != CAIRO_SUBSETS_SCALED && - ! _cairo_font_face_is_user (scaled_font->font_face)) + /* Type 3 glyphs (is_user and has_color) must be added to scaled subset */ + if (subsets->type != CAIRO_SUBSETS_SCALED && + has_path && !has_color && !is_user) { /* Path available. Add to unscaled subset. */ key.is_scaled = FALSE; @@ -1010,19 +1023,12 @@ _cairo_scaled_font_subsets_foreach_internal (cairo_scaled_font_subsets_t { cairo_sub_font_collection_t collection; cairo_sub_font_t *sub_font; - cairo_bool_t is_scaled, is_user; + cairo_bool_t is_scaled; is_scaled = FALSE; - is_user = FALSE; - - if (type == CAIRO_SUBSETS_FOREACH_USER) - is_user = TRUE; - if (type == CAIRO_SUBSETS_FOREACH_SCALED || - type == CAIRO_SUBSETS_FOREACH_USER) - { + if (type == CAIRO_SUBSETS_FOREACH_SCALED) is_scaled = TRUE; - } if (is_scaled) collection.glyphs_size = font_subsets->max_glyphs_per_scaled_subset_used; @@ -1058,9 +1064,7 @@ _cairo_scaled_font_subsets_foreach_internal (cairo_scaled_font_subsets_t sub_font = font_subsets->unscaled_sub_fonts_list; while (sub_font) { - if (sub_font->is_user == is_user) - _cairo_sub_font_collect (sub_font, &collection); - + _cairo_sub_font_collect (sub_font, &collection); sub_font = sub_font->next; } free (collection.utf8); @@ -1093,17 +1097,6 @@ _cairo_scaled_font_subsets_foreach_unscaled (cairo_scaled_font_subsets_t *fo CAIRO_SUBSETS_FOREACH_UNSCALED); } -cairo_status_t -_cairo_scaled_font_subsets_foreach_user (cairo_scaled_font_subsets_t *font_subsets, - cairo_scaled_font_subset_callback_func_t font_subset_callback, - void *closure) -{ - return _cairo_scaled_font_subsets_foreach_internal (font_subsets, - font_subset_callback, - closure, - CAIRO_SUBSETS_FOREACH_USER); -} - static cairo_bool_t _cairo_string_equal (const void *key_a, const void *key_b) { |