Пример #1
0
/**
 * _cairo_toy_font_face_create:
 * @family: a font family name, encoded in UTF-8
 * @slant: the slant for the font
 * @weight: the weight for the font
 *
 * Creates a font face from a triplet of family, slant, and weight.
 * These font faces are used in implementation of the the #cairo_t "toy"
 * font API.
 *
 * Return value: a newly created #cairo_font_face_t, destroy with
 *  cairo_font_face_destroy()
 **/
cairo_font_face_t *
_cairo_toy_font_face_create (const char          *family,
			     cairo_font_slant_t   slant,
			     cairo_font_weight_t  weight)
{
    cairo_status_t status;
    cairo_toy_font_face_t key, *font_face;
    cairo_hash_table_t *hash_table;

    hash_table = _cairo_toy_font_face_hash_table_lock ();
    if (hash_table == NULL)
	goto UNWIND;

    _cairo_toy_font_face_init_key (&key, family, slant, weight);

    /* Return existing font_face if it exists in the hash table. */
    if (_cairo_hash_table_lookup (hash_table,
				  &key.base.hash_entry,
				  (cairo_hash_entry_t **) &font_face))
    {
	/* We increment the reference count here manually to avoid
	   double-locking. */
	font_face->base.ref_count++;
	_cairo_toy_font_face_hash_table_unlock ();
	return &font_face->base;
    }

    /* Otherwise create it and insert into hash table. */
    font_face = malloc (sizeof (cairo_toy_font_face_t));
    if (font_face == NULL)
	goto UNWIND_HASH_TABLE_LOCK;

    status = _cairo_toy_font_face_init (font_face, family, slant, weight);
    if (status)
	goto UNWIND_FONT_FACE_MALLOC;

    status = _cairo_hash_table_insert (hash_table, &font_face->base.hash_entry);
    if (status)
	goto UNWIND_FONT_FACE_INIT;

    _cairo_toy_font_face_hash_table_unlock ();

    return &font_face->base;

 UNWIND_FONT_FACE_INIT:
 UNWIND_FONT_FACE_MALLOC:
    free (font_face);
 UNWIND_HASH_TABLE_LOCK:
    _cairo_toy_font_face_hash_table_unlock ();
 UNWIND:
    return (cairo_font_face_t*) &_cairo_font_face_nil;
}
Пример #2
0
/**
 * cairo_toy_font_face_create:
 * @family: a font family name, encoded in UTF-8
 * @slant: the slant for the font
 * @weight: the weight for the font
 *
 * Creates a font face from a triplet of family, slant, and weight.
 * These font faces are used in implementation of the the #cairo_t "toy"
 * font API.
 *
 * If @family is the zero-length string "", the platform-specific default
 * family is assumed.  The default family then can be queried using
 * cairo_toy_font_face_get_family().
 *
 * The cairo_select_font_face() function uses this to create font faces.
 * See that function for limitations of toy font faces.
 *
 * Return value: a newly created #cairo_font_face_t. Free with
 *  cairo_font_face_destroy() when you are done using it.
 *
 * Since: 1.8
 **/
cairo_font_face_t *
cairo_toy_font_face_create (const char          *family,
			    cairo_font_slant_t   slant,
			    cairo_font_weight_t  weight)
{
    cairo_status_t status;
    cairo_toy_font_face_t key, *font_face;
    cairo_hash_table_t *hash_table;

    if (family == NULL)
	return (cairo_font_face_t*) &_cairo_font_face_null_pointer;

    /* Make sure we've got valid UTF-8 for the family */
    status = _cairo_utf8_to_ucs4 (family, -1, NULL, NULL);
    if (status == CAIRO_STATUS_INVALID_STRING)
	return (cairo_font_face_t*) &_cairo_font_face_invalid_string;
    else if (status)
	return (cairo_font_face_t*) &_cairo_font_face_nil;

    switch (slant) {
	case CAIRO_FONT_SLANT_NORMAL:
	case CAIRO_FONT_SLANT_ITALIC:
	case CAIRO_FONT_SLANT_OBLIQUE:
	    break;
	default:
	    return (cairo_font_face_t*) &_cairo_font_face_invalid_slant;
    }

    switch (weight) {
	case CAIRO_FONT_WEIGHT_NORMAL:
	case CAIRO_FONT_WEIGHT_BOLD:
	    break;
	default:
	    return (cairo_font_face_t*) &_cairo_font_face_invalid_weight;
    }

    if (*family == '\0')
	family = CAIRO_FONT_FAMILY_DEFAULT;

    hash_table = _cairo_toy_font_face_hash_table_lock ();
    if (hash_table == NULL)
	goto UNWIND;

    _cairo_toy_font_face_init_key (&key, family, slant, weight);

    /* Return existing font_face if it exists in the hash table. */
    if (_cairo_hash_table_lookup (hash_table,
				  &key.base.hash_entry,
				  (cairo_hash_entry_t **) &font_face))
    {
	if (! font_face->base.status)  {
	    /* We increment the reference count here manually to avoid
	       double-locking. */
	    _cairo_reference_count_inc (&font_face->base.ref_count);
	    _cairo_toy_font_face_hash_table_unlock ();
	    return &font_face->base;
	}

	/* remove the bad font from the hash table */
	_cairo_hash_table_remove (hash_table, &key.base.hash_entry);
	font_face->base.hash_entry.hash = 0;
    }

    /* Otherwise create it and insert into hash table. */
    //+EAWebKitChange
    //11/10/2011
    font_face = cairo_malloc (sizeof (cairo_toy_font_face_t));
    //-EAWebKitChange
    if (font_face == NULL) {
	status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
	goto UNWIND_HASH_TABLE_LOCK;
    }

    status = _cairo_toy_font_face_init (font_face, family, slant, weight);
    if (status)
	goto UNWIND_FONT_FACE_MALLOC;

    status = _cairo_hash_table_insert (hash_table, &font_face->base.hash_entry);
    if (status)
	goto UNWIND_FONT_FACE_INIT;

    _cairo_toy_font_face_hash_table_unlock ();

    return &font_face->base;

 UNWIND_FONT_FACE_INIT:
    _cairo_toy_font_face_fini (font_face);
 UNWIND_FONT_FACE_MALLOC:
    //+EAWebKitChange
    //11/10/2011
    cairo_free (font_face);
    //-EAWebKitChange
 UNWIND_HASH_TABLE_LOCK:
    _cairo_toy_font_face_hash_table_unlock ();
 UNWIND:
    return (cairo_font_face_t*) &_cairo_font_face_nil;
}
Пример #3
0
/**
 * cairo_toy_font_face_create:
 * @family: a font family name, encoded in UTF-8
 * @slant: the slant for the font
 * @weight: the weight for the font
 *
 * Creates a font face from a triplet of family, slant, and weight.
 * These font faces are used in implementation of the the #cairo_t "toy"
 * font API.
 *
 * If @family is the zero-length string "", the platform-specific default
 * family is assumed.  The default family then can be queried using
 * cairo_toy_font_face_get_family().
 *
 * The cairo_select_font_face() function uses this to create font faces.
 * See that function for limitations and other details of toy font faces.
 *
 * Return value: a newly created #cairo_font_face_t. Free with
 *  cairo_font_face_destroy() when you are done using it.
 *
 * Since: 1.8
 **/
cairo_font_face_t *
cairo_toy_font_face_create (const char          *family,
			    cairo_font_slant_t   slant,
			    cairo_font_weight_t  weight)
{
    cairo_status_t status;
    cairo_toy_font_face_t key, *font_face;
    cairo_hash_table_t *hash_table;

    if (family == NULL)
	return (cairo_font_face_t*) &_cairo_font_face_null_pointer;

    /* Make sure we've got valid UTF-8 for the family */
    status = _cairo_utf8_to_ucs4 (family, -1, NULL, NULL);
    if (unlikely (status)) {
	if (status == CAIRO_STATUS_INVALID_STRING)
	    return (cairo_font_face_t*) &_cairo_font_face_invalid_string;

	return (cairo_font_face_t*) &_cairo_font_face_nil;
    }

    switch (slant) {
	case CAIRO_FONT_SLANT_NORMAL:
	case CAIRO_FONT_SLANT_ITALIC:
	case CAIRO_FONT_SLANT_OBLIQUE:
	    break;
	default:
	    return (cairo_font_face_t*) &_cairo_font_face_invalid_slant;
    }

    switch (weight) {
	case CAIRO_FONT_WEIGHT_NORMAL:
	case CAIRO_FONT_WEIGHT_BOLD:
	    break;
	default:
	    return (cairo_font_face_t*) &_cairo_font_face_invalid_weight;
    }

    if (*family == '\0')
	family = CAIRO_FONT_FAMILY_DEFAULT;

    hash_table = _cairo_toy_font_face_hash_table_lock ();
    if (unlikely (hash_table == NULL))
	goto UNWIND;

    _cairo_toy_font_face_init_key (&key, family, slant, weight);

    /* Return existing font_face if it exists in the hash table. */
    font_face = _cairo_hash_table_lookup (hash_table,
					  &key.base.hash_entry);
    if (font_face != NULL) {
	if (font_face->base.status == CAIRO_STATUS_SUCCESS) {
	    cairo_font_face_reference (&font_face->base);
	    _cairo_toy_font_face_hash_table_unlock ();
	    return &font_face->base;
	}

	/* remove the bad font from the hash table */
	_cairo_hash_table_remove (hash_table, &font_face->base.hash_entry);
    }

    /* Otherwise create it and insert into hash table. */
    font_face = _cairo_malloc (sizeof (cairo_toy_font_face_t));
    if (unlikely (font_face == NULL)) {
	status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
	goto UNWIND_HASH_TABLE_LOCK;
    }

    status = _cairo_toy_font_face_init (font_face, family, slant, weight);
    if (unlikely (status))
	goto UNWIND_FONT_FACE_MALLOC;

    assert (font_face->base.hash_entry.hash == key.base.hash_entry.hash);
    status = _cairo_hash_table_insert (hash_table, &font_face->base.hash_entry);
    if (unlikely (status))
	goto UNWIND_FONT_FACE_INIT;

    _cairo_toy_font_face_hash_table_unlock ();

    return &font_face->base;

 UNWIND_FONT_FACE_INIT:
    _cairo_toy_font_face_fini (font_face);
 UNWIND_FONT_FACE_MALLOC:
    free (font_face);
 UNWIND_HASH_TABLE_LOCK:
    _cairo_toy_font_face_hash_table_unlock ();
 UNWIND:
    return (cairo_font_face_t*) &_cairo_font_face_nil;
}