Esempio n. 1
0
/**
 * _cairo_cache_remove_random:
 * @cache: a cache
 *
 * Remove a random entry from the cache.
 *
 * Return value: %TRUE if an entry was successfully removed.
 * %FALSE if there are no entries that can be removed.
 **/
static cairo_bool_t
_cairo_cache_remove_random (cairo_cache_t *cache)
{
    cairo_cache_entry_t *entry;

    entry = _cairo_hash_table_random_entry (cache->hash_table, NULL);
    if (unlikely (entry == NULL))
        return FALSE;

    _cairo_cache_remove (cache, entry);

    return TRUE;
}
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;
}