static cairo_bool_t _cairo_toy_font_face_destroy (void *abstract_face) { cairo_toy_font_face_t *font_face = abstract_face; cairo_hash_table_t *hash_table; hash_table = _cairo_toy_font_face_hash_table_lock (); /* All created objects must have been mapped in the hash table. */ assert (hash_table != NULL); if (! _cairo_reference_count_dec_and_test (&font_face->base.ref_count)) { /* somebody recreated the font whilst we waited for the lock */ _cairo_toy_font_face_hash_table_unlock (); return FALSE; } /* Font faces in SUCCESS status are guaranteed to be in the * hashtable. Font faces in an error status are removed from the * hashtable if they are found during a lookup, thus they should * only be removed if they are in the hashtable. */ if (likely (font_face->base.status == CAIRO_STATUS_SUCCESS) || _cairo_hash_table_lookup (hash_table, &font_face->base.hash_entry) == font_face) _cairo_hash_table_remove (hash_table, &font_face->base.hash_entry); _cairo_toy_font_face_hash_table_unlock (); _cairo_toy_font_face_fini (font_face); return TRUE; }
static void _cairo_toy_font_face_destroy (void *abstract_face) { cairo_toy_font_face_t *font_face = abstract_face; cairo_hash_table_t *hash_table; if (font_face == NULL) return; hash_table = _cairo_toy_font_face_hash_table_lock (); /* All created objects must have been mapped in the hash table. */ assert (hash_table != NULL); _cairo_hash_table_remove (hash_table, &font_face->base.hash_entry); _cairo_toy_font_face_hash_table_unlock (); _cairo_toy_font_face_fini (font_face); }
static void _cairo_toy_font_face_destroy (void *abstract_face) { cairo_toy_font_face_t *font_face = abstract_face; cairo_hash_table_t *hash_table; if (font_face == NULL || CAIRO_REFERENCE_COUNT_IS_INVALID (&font_face->base.ref_count)) return; hash_table = _cairo_toy_font_face_hash_table_lock (); /* All created objects must have been mapped in the hash table. */ assert (hash_table != NULL); if (font_face->base.hash_entry.hash != 0) _cairo_hash_table_remove (hash_table, &font_face->base.hash_entry); _cairo_toy_font_face_hash_table_unlock (); _cairo_toy_font_face_fini (font_face); }
/** * 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; }
/** * 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; }