void _cairo_scaled_font_subsets_destroy (cairo_scaled_font_subsets_t *subsets) { _cairo_hash_table_foreach (subsets->scaled_sub_fonts, _cairo_sub_font_pluck, subsets->scaled_sub_fonts); _cairo_hash_table_destroy (subsets->scaled_sub_fonts); _cairo_hash_table_foreach (subsets->unscaled_sub_fonts, _cairo_sub_font_pluck, subsets->unscaled_sub_fonts); _cairo_hash_table_destroy (subsets->unscaled_sub_fonts); free (subsets); }
void _cairo_scaled_font_map_destroy (void) { int i; cairo_scaled_font_map_t *font_map = cairo_scaled_font_map; cairo_scaled_font_t *scaled_font; if (font_map == NULL) return; CAIRO_MUTEX_UNLOCK (cairo_scaled_font_map_mutex); for (i = 0; i < font_map->num_holdovers; i++) { scaled_font = font_map->holdovers[i]; /* We should only get here through the reset_static_data path * and there had better not be any active references at that * point. */ assert (scaled_font->ref_count == 0); _cairo_hash_table_remove (font_map->hash_table, &scaled_font->hash_entry); _cairo_scaled_font_fini (scaled_font); free (scaled_font); } _cairo_hash_table_destroy (font_map->hash_table); free (cairo_scaled_font_map); cairo_scaled_font_map = NULL; }
static cairo_scaled_font_subsets_t * _cairo_scaled_font_subsets_create_internal (cairo_subsets_type_t type) { cairo_scaled_font_subsets_t *subsets; subsets = malloc (sizeof (cairo_scaled_font_subsets_t)); if (subsets == NULL) return NULL; subsets->type = type; subsets->max_glyphs_per_unscaled_subset_used = 0; subsets->max_glyphs_per_scaled_subset_used = 0; subsets->num_sub_fonts = 0; subsets->unscaled_sub_fonts = _cairo_hash_table_create (_cairo_sub_fonts_equal); if (! subsets->unscaled_sub_fonts) { free (subsets); return NULL; } subsets->scaled_sub_fonts = _cairo_hash_table_create (_cairo_sub_fonts_equal); if (! subsets->scaled_sub_fonts) { _cairo_hash_table_destroy (subsets->unscaled_sub_fonts); free (subsets); return NULL; } return subsets; }
static cairo_scaled_font_subsets_t * _cairo_scaled_font_subsets_create_internal (cairo_subsets_type_t type) { cairo_scaled_font_subsets_t *subsets; subsets = malloc (sizeof (cairo_scaled_font_subsets_t)); if (unlikely (subsets == NULL)) { _cairo_error_throw (CAIRO_STATUS_NO_MEMORY); return NULL; } subsets->type = type; subsets->max_glyphs_per_unscaled_subset_used = 0; subsets->max_glyphs_per_scaled_subset_used = 0; subsets->num_sub_fonts = 0; subsets->unscaled_sub_fonts = _cairo_hash_table_create (_cairo_sub_fonts_equal); if (! subsets->unscaled_sub_fonts) { free (subsets); return NULL; } subsets->unscaled_sub_fonts_list = NULL; subsets->unscaled_sub_fonts_list_end = NULL; subsets->scaled_sub_fonts = _cairo_hash_table_create (_cairo_sub_fonts_equal); if (! subsets->scaled_sub_fonts) { _cairo_hash_table_destroy (subsets->unscaled_sub_fonts); free (subsets); return NULL; } subsets->scaled_sub_fonts_list = NULL; subsets->scaled_sub_fonts_list_end = NULL; return subsets; }
/** * _cairo_cache_fini: * @cache: a cache to destroy * * Immediately destroys the given cache, freeing all resources * associated with it. As part of this process, the entry_destroy() * function, (as passed to _cairo_cache_init()), will be called for * each entry in the cache. **/ void _cairo_cache_fini (cairo_cache_t *cache) { _cairo_hash_table_foreach (cache->hash_table, _cairo_cache_pluck, cache); assert (cache->size == 0); _cairo_hash_table_destroy (cache->hash_table); }
static void _cairo_sub_font_destroy (cairo_sub_font_t *sub_font) { _cairo_hash_table_foreach (sub_font->sub_font_glyphs, _cairo_sub_font_glyph_pluck, sub_font->sub_font_glyphs); _cairo_hash_table_destroy (sub_font->sub_font_glyphs); cairo_scaled_font_destroy (sub_font->scaled_font); free (sub_font); }
void _cairo_font_reset_static_data (void) { _cairo_scaled_font_map_destroy (); CAIRO_MUTEX_LOCK (cairo_toy_font_face_hash_table_mutex); _cairo_hash_table_destroy (cairo_toy_font_face_hash_table); cairo_toy_font_face_hash_table = NULL; CAIRO_MUTEX_UNLOCK (cairo_toy_font_face_hash_table_mutex); }
void _cairo_toy_font_face_reset_static_data (void) { /* We manually acquire the lock rather than calling * cairo_toy_font_face_hash_table_lock simply to avoid * creating the table only to destroy it again. */ CAIRO_MUTEX_LOCK (_cairo_toy_font_face_mutex); _cairo_hash_table_destroy (cairo_toy_font_face_hash_table); cairo_toy_font_face_hash_table = NULL; CAIRO_MUTEX_UNLOCK (_cairo_toy_font_face_mutex); }
static cairo_status_t _cairo_sub_font_create (cairo_scaled_font_subsets_t *parent, cairo_scaled_font_t *scaled_font, unsigned int font_id, int max_glyphs_per_subset, cairo_bool_t is_scaled, cairo_bool_t is_composite, cairo_sub_font_t **sub_font_out) { 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 (unlikely (sub_font == NULL)) return _cairo_error (CAIRO_STATUS_NO_MEMORY); 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); _cairo_sub_font_init_key (sub_font, scaled_font); sub_font->parent = parent; sub_font->scaled_font = scaled_font; sub_font->font_id = font_id; sub_font->current_subset = 0; 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 (unlikely (sub_font->sub_font_glyphs == NULL)) { free (sub_font); return _cairo_error (CAIRO_STATUS_NO_MEMORY); } sub_font->next = NULL; /* Reserve first glyph in subset for the .notdef glyph except for * Type 3 fonts */ if (! is_scaled) { status = _cairo_sub_font_map_glyph (sub_font, 0, NULL, -1, &subset_glyph); if (unlikely (status)) { _cairo_hash_table_destroy (sub_font->sub_font_glyphs); free (sub_font); return status; } } *sub_font_out = sub_font; return CAIRO_STATUS_SUCCESS; }
void _cairo_font_reset_static_data (void) { _cairo_scaled_font_map_destroy (); _cairo_lock_global_image_glyph_cache(); _cairo_cache_destroy (_global_image_glyph_cache); _global_image_glyph_cache = NULL; _cairo_unlock_global_image_glyph_cache(); CAIRO_MUTEX_LOCK (cairo_toy_font_face_hash_table_mutex); _cairo_hash_table_destroy (cairo_toy_font_face_hash_table); cairo_toy_font_face_hash_table = NULL; CAIRO_MUTEX_UNLOCK (cairo_toy_font_face_hash_table_mutex); }
cairo_int_status_t _cairo_scaled_font_subset_create_glyph_names (cairo_scaled_font_subset_t *subset) { unsigned int i; cairo_hash_table_t *names; cairo_string_entry_t key, *entry; char buf[30]; char *utf8; uint16_t *utf16; int utf16_len; cairo_status_t status = CAIRO_STATUS_SUCCESS; names = _cairo_hash_table_create (_cairo_string_equal); if (unlikely (names == NULL)) return _cairo_error (CAIRO_STATUS_NO_MEMORY); subset->glyph_names = calloc (subset->num_glyphs, sizeof (char *)); if (unlikely (subset->glyph_names == NULL)) { status = _cairo_error (CAIRO_STATUS_NO_MEMORY); goto CLEANUP_HASH; } i = 0; if (! subset->is_scaled) { subset->glyph_names[0] = strdup (".notdef"); if (unlikely (subset->glyph_names[0] == NULL)) { status = _cairo_error (CAIRO_STATUS_NO_MEMORY); goto CLEANUP_HASH; } status = create_string_entry (subset->glyph_names[0], &entry); if (unlikely (status)) goto CLEANUP_HASH; status = _cairo_hash_table_insert (names, &entry->base); if (unlikely (status)) { free (entry); goto CLEANUP_HASH; } i++; } for (; i < subset->num_glyphs; i++) { utf8 = subset->utf8[i]; utf16 = NULL; utf16_len = 0; if (utf8 && *utf8) { status = _cairo_utf8_to_utf16 (utf8, -1, &utf16, &utf16_len); if (unlikely (status)) goto CLEANUP_HASH; } if (utf16_len == 1) { int ch = _cairo_unicode_to_winansi (utf16[0]); if (ch > 0 && _cairo_winansi_to_glyphname (ch)) strncpy (buf, _cairo_winansi_to_glyphname (ch), sizeof (buf)); else snprintf (buf, sizeof (buf), "uni%04X", (int) utf16[0]); _cairo_string_init_key (&key, buf); entry = _cairo_hash_table_lookup (names, &key.base); if (entry != NULL) snprintf (buf, sizeof (buf), "g%d", i); } else { snprintf (buf, sizeof (buf), "g%d", i); } free (utf16); subset->glyph_names[i] = strdup (buf); if (unlikely (subset->glyph_names[i] == NULL)) { status = _cairo_error (CAIRO_STATUS_NO_MEMORY); goto CLEANUP_HASH; } status = create_string_entry (subset->glyph_names[i], &entry); if (unlikely (status)) goto CLEANUP_HASH; status = _cairo_hash_table_insert (names, &entry->base); if (unlikely (status)) { free (entry); goto CLEANUP_HASH; } } CLEANUP_HASH: _cairo_hash_table_foreach (names, _pluck_entry, names); _cairo_hash_table_destroy (names); if (likely (status == CAIRO_STATUS_SUCCESS)) return CAIRO_STATUS_SUCCESS; if (subset->glyph_names != NULL) { for (i = 0; i < subset->num_glyphs; i++) { free (subset->glyph_names[i]); } free (subset->glyph_names); subset->glyph_names = NULL; } return status; }
cairo_int_status_t _cairo_scaled_font_subset_create_glyph_names (cairo_scaled_font_subset_t *subset) { const cairo_scaled_font_backend_t *backend; unsigned int i; cairo_status_t status; cairo_hash_table_t *names; cairo_string_entry_t key, *entry; char buf[30]; if (subset->to_unicode == NULL) return CAIRO_INT_STATUS_UNSUPPORTED; status = _cairo_truetype_create_glyph_to_unicode_map (subset); if (status) { if (status != CAIRO_INT_STATUS_UNSUPPORTED) return status; backend = subset->scaled_font->backend; if (backend->map_glyphs_to_unicode == NULL) return CAIRO_INT_STATUS_UNSUPPORTED; status = backend->map_glyphs_to_unicode (subset->scaled_font, subset); if (status) return status; } names = _cairo_hash_table_create (_cairo_string_equal); if (names == NULL) return _cairo_error (CAIRO_STATUS_NO_MEMORY); subset->glyph_names = calloc (subset->num_glyphs, sizeof (char *)); if (subset->glyph_names == NULL) { status = _cairo_error (CAIRO_STATUS_NO_MEMORY); goto CLEANUP_HASH; } subset->glyph_names[0] = strdup (".notdef"); if (subset->glyph_names[0] == NULL) { status = _cairo_error (CAIRO_STATUS_NO_MEMORY); goto CLEANUP_HASH; } status = create_string_entry (subset->glyph_names[0], &entry); if (status) goto CLEANUP_HASH; status = _cairo_hash_table_insert (names, &entry->base); if (status) { free (entry); goto CLEANUP_HASH; } for (i = 1; i < subset->num_glyphs; i++) { if (subset->to_unicode[i] <= 0xffff) { snprintf (buf, sizeof(buf), "uni%04X", (unsigned int)(subset->to_unicode[i])); _cairo_string_init_key (&key, buf); if (_cairo_hash_table_lookup (names, &key.base, (cairo_hash_entry_t **) &entry)) { snprintf (buf, sizeof(buf), "g%d", i); } } else { snprintf (buf, sizeof(buf), "g%d", i); } subset->glyph_names[i] = strdup (buf); if (subset->glyph_names[i] == NULL) { status = _cairo_error (CAIRO_STATUS_NO_MEMORY); goto CLEANUP_HASH; } status = create_string_entry (subset->glyph_names[i], &entry); if (status) goto CLEANUP_HASH; status = _cairo_hash_table_insert (names, &entry->base); if (status) { free (entry); goto CLEANUP_HASH; } } CLEANUP_HASH: while (1) { entry = _cairo_hash_table_random_entry (names, NULL); if (entry == NULL) break; _cairo_hash_table_remove (names, (cairo_hash_entry_t *) entry); free (entry); } _cairo_hash_table_destroy (names); if (status == CAIRO_STATUS_SUCCESS) return CAIRO_STATUS_SUCCESS; if (subset->glyph_names != NULL) { for (i = 0; i < subset->num_glyphs; i++) { if (subset->glyph_names[i] != NULL) free (subset->glyph_names[i]); } free (subset->glyph_names); subset->glyph_names = NULL; } return status; }