summaryrefslogtreecommitdiff
path: root/src/cairo-font-face.c
diff options
context:
space:
mode:
authorBehdad Esfahbod <behdad@behdad.org>2008-08-06 21:37:36 -0400
committerBehdad Esfahbod <behdad@behdad.org>2008-08-08 03:01:14 -0400
commit7e57892983bbc639fe4a402a427b255e4d4ab746 (patch)
tree8d535d5bf6b819543a868e7ce5d025d1704f06ec /src/cairo-font-face.c
parentbca9a21e98c870cdb4695c9155517377757beaea (diff)
downloadcairo-7e57892983bbc639fe4a402a427b255e4d4ab746.tar.gz
Add toy font constructor and getters
New public API: cairo_toy_font_face_create() cairo_toy_font_face_get_family() cairo_toy_font_face_get_slant() cairo_toy_font_face_get_weight()
Diffstat (limited to 'src/cairo-font-face.c')
-rw-r--r--src/cairo-font-face.c196
1 files changed, 183 insertions, 13 deletions
diff --git a/src/cairo-font-face.c b/src/cairo-font-face.c
index 1d6739823..4f822a21c 100644
--- a/src/cairo-font-face.c
+++ b/src/cairo-font-face.c
@@ -41,19 +41,78 @@
#define _BSD_SOURCE /* for strdup() */
#include "cairoint.h"
-/* Forward declare so we can use it as an arbitrary backend for
- * _cairo_font_face_nil.
- */
static const cairo_font_face_backend_t _cairo_toy_font_face_backend;
/* #cairo_font_face_t */
-const cairo_font_face_t _cairo_font_face_nil = {
- { 0 }, /* hash_entry */
- CAIRO_STATUS_NO_MEMORY, /* status */
+const cairo_toy_font_face_t _cairo_font_face_nil = {
+ {
+ { 0 }, /* hash_entry */
+ CAIRO_STATUS_NO_MEMORY, /* status */
+ CAIRO_REFERENCE_COUNT_INVALID, /* ref_count */
+ { 0, 0, 0, NULL }, /* user_data */
+ &_cairo_toy_font_face_backend
+ },
+ CAIRO_FONT_FAMILY_DEFAULT, /* family */
+ TRUE, /* owns_family */
+ CAIRO_FONT_SLANT_DEFAULT, /* slant */
+ CAIRO_FONT_WEIGHT_DEFAULT /* weight */
+};
+
+static const cairo_toy_font_face_t _cairo_font_face_null_pointer = {
+ {
+ { 0 }, /* hash_entry */
+ CAIRO_STATUS_NULL_POINTER, /* status */
+ CAIRO_REFERENCE_COUNT_INVALID, /* ref_count */
+ { 0, 0, 0, NULL }, /* user_data */
+ &_cairo_toy_font_face_backend
+ },
+ CAIRO_FONT_FAMILY_DEFAULT, /* family */
+ TRUE, /* owns_family */
+ CAIRO_FONT_SLANT_DEFAULT, /* slant */
+ CAIRO_FONT_WEIGHT_DEFAULT /* weight */
+};
+
+static const cairo_toy_font_face_t _cairo_font_face_invalid_string = {
+ {
+ { 0 }, /* hash_entry */
+ CAIRO_STATUS_INVALID_STRING, /* status */
+ CAIRO_REFERENCE_COUNT_INVALID, /* ref_count */
+ { 0, 0, 0, NULL }, /* user_data */
+ &_cairo_toy_font_face_backend
+ },
+ CAIRO_FONT_FAMILY_DEFAULT, /* family */
+ TRUE, /* owns_family */
+ CAIRO_FONT_SLANT_DEFAULT, /* slant */
+ CAIRO_FONT_WEIGHT_DEFAULT /* weight */
+};
+
+static const cairo_toy_font_face_t _cairo_font_face_invalid_slant = {
+ {
+ { 0 }, /* hash_entry */
+ CAIRO_STATUS_INVALID_SLANT, /* status */
+ CAIRO_REFERENCE_COUNT_INVALID, /* ref_count */
+ { 0, 0, 0, NULL }, /* user_data */
+ &_cairo_toy_font_face_backend
+ },
+ CAIRO_FONT_FAMILY_DEFAULT, /* family */
+ TRUE, /* owns_family */
+ CAIRO_FONT_SLANT_DEFAULT, /* slant */
+ CAIRO_FONT_WEIGHT_DEFAULT /* weight */
+};
+
+static const cairo_toy_font_face_t _cairo_font_face_invalid_weight = {
+ {
+ { 0 }, /* hash_entry */
+ CAIRO_STATUS_INVALID_WEIGHT, /* status */
CAIRO_REFERENCE_COUNT_INVALID, /* ref_count */
- { 0, 0, 0, NULL }, /* user_data */
+ { 0, 0, 0, NULL }, /* user_data */
&_cairo_toy_font_face_backend
+ },
+ CAIRO_FONT_FAMILY_DEFAULT, /* family */
+ TRUE, /* owns_family */
+ CAIRO_FONT_SLANT_DEFAULT, /* slant */
+ CAIRO_FONT_WEIGHT_DEFAULT /* weight */
};
cairo_status_t
@@ -371,7 +430,7 @@ _cairo_toy_font_face_keys_equal (const void *key_a,
}
/**
- * _cairo_toy_font_face_create:
+ * 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
@@ -380,18 +439,57 @@ _cairo_toy_font_face_keys_equal (const void *key_a,
* 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()
+ * 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_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;
@@ -444,6 +542,7 @@ _cairo_toy_font_face_create (const char *family,
UNWIND:
return (cairo_font_face_t*) &_cairo_font_face_nil;
}
+slim_hidden_def (cairo_toy_font_face_create);
static void
_cairo_toy_font_face_destroy (void *abstract_face)
@@ -493,6 +592,77 @@ _cairo_toy_font_face_scaled_font_create (void *abstract_font_face
scaled_font));
}
+static cairo_bool_t
+_cairo_font_face_is_toy (cairo_font_face_t *font_face)
+{
+ return font_face->backend == &_cairo_toy_font_face_backend;
+}
+
+/**
+ * cairo_toy_font_face_get_family:
+ * @font_face: A toy font face
+ *
+ * Gets the familly name of a toy font.
+ *
+ * Return value: The family name. This string is owned by the font face
+ * and remains valid as long as the font face is alive (referenced).
+ *
+ * Since: 1.8
+ **/
+const char *
+cairo_toy_font_face_get_family (cairo_font_face_t *font_face)
+{
+ cairo_toy_font_face_t *toy_font_face = (cairo_toy_font_face_t *) font_face;
+ if (! _cairo_font_face_is_toy (font_face)) {
+ if (_cairo_font_face_set_error (font_face, CAIRO_STATUS_FONT_TYPE_MISMATCH))
+ return CAIRO_FONT_FAMILY_DEFAULT;
+ }
+ assert (toy_font_face->owns_family);
+ return toy_font_face->family;
+}
+
+/**
+ * cairo_toy_font_face_get_slant:
+ * @font_face: A toy font face
+ *
+ * Gets the slant a toy font.
+ *
+ * Return value: The slant value
+ *
+ * Since: 1.8
+ **/
+cairo_font_slant_t
+cairo_toy_font_face_get_slant (cairo_font_face_t *font_face)
+{
+ cairo_toy_font_face_t *toy_font_face = (cairo_toy_font_face_t *) font_face;
+ if (! _cairo_font_face_is_toy (font_face)) {
+ if (_cairo_font_face_set_error (font_face, CAIRO_STATUS_FONT_TYPE_MISMATCH))
+ return CAIRO_FONT_SLANT_DEFAULT;
+ }
+ return toy_font_face->slant;
+}
+
+/**
+ * cairo_toy_font_face_get_weight:
+ * @font_face: A toy font face
+ *
+ * Gets the weight a toy font.
+ *
+ * Return value: The weight value
+ *
+ * Since: 1.8
+ **/
+cairo_font_weight_t
+cairo_toy_font_face_get_weight (cairo_font_face_t *font_face)
+{
+ cairo_toy_font_face_t *toy_font_face = (cairo_toy_font_face_t *) font_face;
+ if (! _cairo_font_face_is_toy (font_face)) {
+ if (_cairo_font_face_set_error (font_face, CAIRO_STATUS_FONT_TYPE_MISMATCH))
+ return CAIRO_FONT_WEIGHT_DEFAULT;
+ }
+ return toy_font_face->weight;
+}
+
static const cairo_font_face_backend_t _cairo_toy_font_face_backend = {
CAIRO_FONT_TYPE_TOY,
_cairo_toy_font_face_destroy,