[cairo-commit] 3 commits - doc/public src/cairo-font-face-twin.c src/cairo.h src/cairoint.h

Behdad Esfahbod behdad at kemper.freedesktop.org
Tue Mar 17 16:47:32 PDT 2009


 doc/public/tmpl/cairo-status.sgml |    1 
 src/cairo-font-face-twin.c        |  173 ++++++++++++++++++++++++++++++--------
 src/cairo.h                       |   12 ++
 src/cairoint.h                    |   10 --
 4 files changed, 153 insertions(+), 43 deletions(-)

New commits:
commit 496bbcf58233ceecfffc52ae5b1a3a1f07516c67
Author: Behdad Esfahbod <behdad at behdad.org>
Date:   Tue Mar 17 19:46:25 2009 -0400

    Make CAIRO_STATUS_LAST_STATUS public

diff --git a/doc/public/tmpl/cairo-status.sgml b/doc/public/tmpl/cairo-status.sgml
index d2636c6..b74856f 100644
--- a/doc/public/tmpl/cairo-status.sgml
+++ b/doc/public/tmpl/cairo-status.sgml
@@ -71,6 +71,7 @@ code is required before or after each individual cairo function call.
 @CAIRO_STATUS_INVALID_SLANT: 
 @CAIRO_STATUS_INVALID_WEIGHT: 
 @CAIRO_STATUS_INVALID_SIZE: 
+ at _CAIRO_STATUS_LAST_STATUS: 
 
 <!-- ##### FUNCTION cairo_status_to_string ##### -->
 <para>
diff --git a/src/cairo.h b/src/cairo.h
index 6994b30..206861d 100644
--- a/src/cairo.h
+++ b/src/cairo.h
@@ -208,6 +208,7 @@ typedef struct _cairo_user_data_key {
 /**
  * cairo_status_t:
  * @CAIRO_STATUS_SUCCESS: no error has occurred
+ *
  * @CAIRO_STATUS_NO_MEMORY: out of memory
  * @CAIRO_STATUS_INVALID_RESTORE: cairo_restore() called without matching cairo_save()
  * @CAIRO_STATUS_INVALID_POP_GROUP: no saved group to pop
@@ -241,6 +242,11 @@ typedef struct _cairo_user_data_key {
  * @CAIRO_STATUS_INVALID_WEIGHT: invalid value for an input #cairo_font_weight_t (Since 1.8)
  * @CAIRO_STATUS_INVALID_SIZE: invalid value (typically too big) for a size (Since 1.10)
  *
+ * @CAIRO_STATUS_LAST_STATUS: this is a special value indicating the number of
+ *   status values defined in this enumeration.  When using this value, note
+ *   that the version of cairo at run-time may have additional status values
+ *   defined than the value of this symbol at compile-time. (Since 1.10)
+ *
  * #cairo_status_t is used to indicate errors that can occur when
  * using Cairo. In some cases it is returned directly by functions.
  * but when using #cairo_t, the last error, if any, is stored in
@@ -251,6 +257,7 @@ typedef struct _cairo_user_data_key {
  **/
 typedef enum _cairo_status {
     CAIRO_STATUS_SUCCESS = 0,
+
     CAIRO_STATUS_NO_MEMORY,
     CAIRO_STATUS_INVALID_RESTORE,
     CAIRO_STATUS_INVALID_POP_GROUP,
@@ -282,8 +289,9 @@ typedef enum _cairo_status {
     CAIRO_STATUS_INVALID_CLUSTERS,
     CAIRO_STATUS_INVALID_SLANT,
     CAIRO_STATUS_INVALID_WEIGHT,
-    CAIRO_STATUS_INVALID_SIZE
-    /* after adding a new error: update CAIRO_STATUS_LAST_STATUS in cairoint.h.  */
+    CAIRO_STATUS_INVALID_SIZE,
+
+    CAIRO_STATUS_LAST_STATUS
 } cairo_status_t;
 
 /**
diff --git a/src/cairoint.h b/src/cairoint.h
index 5c4626a..035de28 100644
--- a/src/cairoint.h
+++ b/src/cairoint.h
@@ -125,12 +125,6 @@ _cairo_win32_tmpfile (void);
 #define STRINGIFY(macro_or_string)    STRINGIFY_ARG (macro_or_string)
 #define STRINGIFY_ARG(contents)       #contents
 
-/* This has to be updated whenever #cairo_status_t is extended.  That's
- * a bit of a pain, but it should be easy to always catch as long as
- * one adds a new test case to test a trigger of the new status value.
- */
-#define CAIRO_STATUS_LAST_STATUS CAIRO_STATUS_INVALID_SIZE
-
 #ifdef __GNUC__
 #define cairo_container_of(ptr, type, member) ({ \
     const typeof(((type *) 0)->member) *mptr__ = (ptr); \
commit 922c108365b940dbabf23358189bbaa8602446c9
Author: Behdad Esfahbod <behdad at behdad.org>
Date:   Tue Mar 17 19:22:31 2009 -0400

    [twin] Reorganize matching code to better reflect the code in Pango
    
    Makes it easier to update later.

diff --git a/src/cairo-font-face-twin.c b/src/cairo-font-face-twin.c
index ca847ce..712ca0d 100644
--- a/src/cairo-font-face-twin.c
+++ b/src/cairo-font-face-twin.c
@@ -57,6 +57,8 @@ static cairo_user_data_key_t twin_properties_key;
 
 /* We synthesize multiple faces from the twin data.  Here is the parameters. */
 
+/* The following tables and matching code are copied from Pango */
+
 /* CSS weight */
 typedef enum {
   TWIN_WEIGHT_THIN = 100,
@@ -85,6 +87,64 @@ typedef enum {
   TWIN_STRETCH_ULTRA_EXPANDED
 } twin_face_stretch_t;
 
+typedef struct
+{
+  int value;
+  const char str[16];
+} FieldMap;
+
+static const FieldMap slant_map[] = {
+  { CAIRO_FONT_SLANT_NORMAL, "" },
+  { CAIRO_FONT_SLANT_NORMAL, "Roman" },
+  { CAIRO_FONT_SLANT_OBLIQUE, "Oblique" },
+  { CAIRO_FONT_SLANT_ITALIC, "Italic" }
+};
+
+static const FieldMap smallcaps_map[] = {
+  { FALSE, "" },
+  { TRUE, "Small-Caps" }
+};
+
+static const FieldMap weight_map[] = {
+  { TWIN_WEIGHT_THIN, "Thin" },
+  { TWIN_WEIGHT_ULTRALIGHT, "Ultra-Light" },
+  { TWIN_WEIGHT_ULTRALIGHT, "Extra-Light" },
+  { TWIN_WEIGHT_LIGHT, "Light" },
+  { TWIN_WEIGHT_BOOK, "Book" },
+  { TWIN_WEIGHT_NORMAL, "" },
+  { TWIN_WEIGHT_NORMAL, "Regular" },
+  { TWIN_WEIGHT_MEDIUM, "Medium" },
+  { TWIN_WEIGHT_SEMIBOLD, "Semi-Bold" },
+  { TWIN_WEIGHT_SEMIBOLD, "Demi-Bold" },
+  { TWIN_WEIGHT_BOLD, "Bold" },
+  { TWIN_WEIGHT_ULTRABOLD, "Ultra-Bold" },
+  { TWIN_WEIGHT_ULTRABOLD, "Extra-Bold" },
+  { TWIN_WEIGHT_HEAVY, "Heavy" },
+  { TWIN_WEIGHT_HEAVY, "Black" },
+  { TWIN_WEIGHT_ULTRAHEAVY, "Ultra-Heavy" },
+  { TWIN_WEIGHT_ULTRAHEAVY, "Extra-Heavy" },
+  { TWIN_WEIGHT_ULTRAHEAVY, "Ultra-Black" },
+  { TWIN_WEIGHT_ULTRAHEAVY, "Extra-Black" }
+};
+
+static const FieldMap stretch_map[] = {
+  { TWIN_STRETCH_ULTRA_CONDENSED, "Ultra-Condensed" },
+  { TWIN_STRETCH_EXTRA_CONDENSED, "Extra-Condensed" },
+  { TWIN_STRETCH_CONDENSED,       "Condensed" },
+  { TWIN_STRETCH_SEMI_CONDENSED,  "Semi-Condensed" },
+  { TWIN_STRETCH_NORMAL,          "" },
+  { TWIN_STRETCH_SEMI_EXPANDED,   "Semi-Expanded" },
+  { TWIN_STRETCH_EXPANDED,        "Expanded" },
+  { TWIN_STRETCH_EXTRA_EXPANDED,  "Extra-Expanded" },
+  { TWIN_STRETCH_ULTRA_EXPANDED,  "Ultra-Expanded" }
+};
+
+static const FieldMap monospace_map[] = {
+  { FALSE, "" },
+  { TRUE, "Mono" },
+  { TRUE, "Monospace" }
+};
+
 
 typedef struct _twin_face_properties {
     cairo_font_slant_t  slant;
@@ -124,52 +184,84 @@ field_matches (const char *s1,
   return len == 0 && *s1 == '\0';
 }
 
+static cairo_bool_t
+parse_int (const char *word,
+	   size_t      wordlen,
+	   int        *out)
+{
+  char *end;
+  long val = strtol (word, &end, 10);
+  int i = val;
+
+  if (end != word && (end == word + wordlen) && val >= 0 && val == i)
+    {
+      if (out)
+        *out = i;
+
+      return TRUE;
+    }
+
+  return FALSE;
+}
+
+static cairo_bool_t
+find_field (const char *what,
+	    const FieldMap *map,
+	    int n_elements,
+	    const char *str,
+	    int len,
+	    int *val)
+{
+  int i;
+  cairo_bool_t had_prefix = FALSE;
+
+  if (what)
+    {
+      i = strlen (what);
+      if (len > i && 0 == strncmp (what, str, i) && str[i] == '=')
+	{
+	  str += i + 1;
+	  len -= i + 1;
+	  had_prefix = TRUE;
+	}
+    }
+
+  for (i=0; i<n_elements; i++)
+    {
+      if (map[i].str[0] && field_matches (map[i].str, str, len))
+	{
+	  if (val)
+	    *val = map[i].value;
+	  return TRUE;
+	}
+    }
+
+  if (!what || had_prefix)
+    return parse_int (str, len, val);
+
+  return FALSE;
+}
 
 static void
 parse_field (twin_face_properties_t *props,
-	     const char *s,
+	     const char *str,
 	     int len)
 {
-#define MATCH(s1, var, value) \
-	if (field_matches (s1, s, len)) var = value
-
-    if (0) ;
-
-    else MATCH ("Oblique",	props->slant, CAIRO_FONT_SLANT_OBLIQUE);
-    else MATCH ("Italic",	props->slant, CAIRO_FONT_SLANT_ITALIC);
-
-    else MATCH ("Thin",		props->weight, TWIN_WEIGHT_THIN);
-    else MATCH ("Ultra-Light",	props->weight, TWIN_WEIGHT_ULTRALIGHT);
-    else MATCH ("Extra-Light",	props->weight, TWIN_WEIGHT_ULTRALIGHT);
-    else MATCH ("Light",	props->weight, TWIN_WEIGHT_LIGHT);
-    else MATCH ("Book",		props->weight, TWIN_WEIGHT_BOOK);
-    else MATCH ("Regular",	props->weight, TWIN_WEIGHT_NORMAL);
-    else MATCH ("Medium",	props->weight, TWIN_WEIGHT_MEDIUM);
-    else MATCH ("Semi-Bold",	props->weight, TWIN_WEIGHT_SEMIBOLD);
-    else MATCH ("Demi-Bold",	props->weight, TWIN_WEIGHT_SEMIBOLD);
-    else MATCH ("Bold",		props->weight, TWIN_WEIGHT_BOLD);
-    else MATCH ("Ultra-Bold",	props->weight, TWIN_WEIGHT_ULTRABOLD);
-    else MATCH ("Extra-Bold",	props->weight, TWIN_WEIGHT_ULTRABOLD);
-    else MATCH ("Heavy",	props->weight, TWIN_WEIGHT_HEAVY);
-    else MATCH ("Black",	props->weight, TWIN_WEIGHT_HEAVY);
-    else MATCH ("Ultra-Heavy",	props->weight, TWIN_WEIGHT_ULTRAHEAVY);
-    else MATCH ("Extra-Heavy",	props->weight, TWIN_WEIGHT_ULTRAHEAVY);
-    else MATCH ("Ultra-Black",	props->weight, TWIN_WEIGHT_ULTRAHEAVY);
-    else MATCH ("Extra-Black",	props->weight, TWIN_WEIGHT_ULTRAHEAVY);
-
-    else MATCH ("Ultra-Condensed",	props->stretch, TWIN_STRETCH_ULTRA_CONDENSED);
-    else MATCH ("Extra-Condensed",	props->stretch, TWIN_STRETCH_EXTRA_CONDENSED);
-    else MATCH ("Condensed",		props->stretch, TWIN_STRETCH_CONDENSED);
-    else MATCH ("Semi-Condensed",	props->stretch, TWIN_STRETCH_SEMI_CONDENSED);
-    else MATCH ("Semi-Expanded",	props->stretch, TWIN_STRETCH_SEMI_EXPANDED);
-    else MATCH ("Expanded",		props->stretch, TWIN_STRETCH_EXPANDED);
-    else MATCH ("Extra-Expanded",	props->stretch, TWIN_STRETCH_EXTRA_EXPANDED);
-    else MATCH ("Ultra-Expanded",	props->stretch, TWIN_STRETCH_ULTRA_EXPANDED);
-
-    else MATCH ("Mono",		props->monospace, TRUE);
-    else MATCH ("Monospace",	props->monospace, TRUE);
-
-    else MATCH ("Small-Caps",	props->smallcaps, TRUE);
+  if (field_matches ("Normal", str, len))
+    return;
+
+#define FIELD(NAME) \
+  if (find_field (STRINGIFY (NAME), NAME##_map, ARRAY_LENGTH (NAME##_map), str, len, \
+		  (int *)(void *)&props->NAME)) \
+      return; \
+
+  FIELD (weight);
+  FIELD (slant);
+  FIELD (stretch);
+  FIELD (smallcaps);
+  FIELD (monospace);
+
+#undef FIELD
 }
 
 static void
@@ -178,11 +270,8 @@ face_props_parse (twin_face_properties_t *props,
 {
     const char *start, *end;
 
-#define ISALPHA(c) \
-   (((c) >= 'A' && (c) <= 'Z') || ((c) >= 'a' && (c) <= 'z'))
-
     for (start = end = s; *end; end++) {
-	if (ISALPHA (*end) || *end == '-')
+	if (*end != ' ' && *end != ':')
 	    continue;
 
 	if (start < end)
diff --git a/src/cairoint.h b/src/cairoint.h
index b93c4a4..5c4626a 100644
--- a/src/cairoint.h
+++ b/src/cairoint.h
@@ -120,6 +120,10 @@ _cairo_win32_tmpfile (void);
 #undef  ARRAY_LENGTH
 #define ARRAY_LENGTH(__array) ((int) (sizeof (__array) / sizeof (__array[0])))
 
+#undef STRINGIFY
+#undef STRINGIFY_ARG
+#define STRINGIFY(macro_or_string)    STRINGIFY_ARG (macro_or_string)
+#define STRINGIFY_ARG(contents)       #contents
 
 /* This has to be updated whenever #cairo_status_t is extended.  That's
  * a bit of a pain, but it should be easy to always catch as long as
commit 2b4044a36f8b156ca0e58b72614659324a9b022e
Author: Behdad Esfahbod <behdad at behdad.org>
Date:   Tue Mar 17 18:52:16 2009 -0400

    [twin] Update parsed weights and stretches from Pango

diff --git a/src/cairo-font-face-twin.c b/src/cairo-font-face-twin.c
index 3ced9b0..ca847ce 100644
--- a/src/cairo-font-face-twin.c
+++ b/src/cairo-font-face-twin.c
@@ -59,14 +59,17 @@ static cairo_user_data_key_t twin_properties_key;
 
 /* CSS weight */
 typedef enum {
+  TWIN_WEIGHT_THIN = 100,
   TWIN_WEIGHT_ULTRALIGHT = 200,
   TWIN_WEIGHT_LIGHT = 300,
+  TWIN_WEIGHT_BOOK = 380,
   TWIN_WEIGHT_NORMAL = 400,
   TWIN_WEIGHT_MEDIUM = 500,
   TWIN_WEIGHT_SEMIBOLD = 600,
   TWIN_WEIGHT_BOLD = 700,
   TWIN_WEIGHT_ULTRABOLD = 800,
-  TWIN_WEIGHT_HEAVY = 900
+  TWIN_WEIGHT_HEAVY = 900,
+  TWIN_WEIGHT_ULTRAHEAVY = 1000
 } twin_face_weight_t;
 
 /* CSS stretch */
@@ -132,30 +135,41 @@ parse_field (twin_face_properties_t *props,
 
     if (0) ;
 
-    else MATCH ("oblique",    props->slant, CAIRO_FONT_SLANT_OBLIQUE);
-    else MATCH ("italic",     props->slant, CAIRO_FONT_SLANT_ITALIC);
-
-    else MATCH ("ultra-light", props->weight, TWIN_WEIGHT_ULTRALIGHT);
-    else MATCH ("light",       props->weight, TWIN_WEIGHT_LIGHT);
-    else MATCH ("medium",      props->weight, TWIN_WEIGHT_NORMAL);
-    else MATCH ("semi-bold",   props->weight, TWIN_WEIGHT_SEMIBOLD);
-    else MATCH ("bold",        props->weight, TWIN_WEIGHT_BOLD);
-    else MATCH ("ultra-bold",  props->weight, TWIN_WEIGHT_ULTRABOLD);
-    else MATCH ("heavy",       props->weight, TWIN_WEIGHT_HEAVY);
-
-    else MATCH ("ultra-condensed", props->stretch, TWIN_STRETCH_ULTRA_CONDENSED);
-    else MATCH ("extra-condensed", props->stretch, TWIN_STRETCH_EXTRA_CONDENSED);
-    else MATCH ("condensed",       props->stretch, TWIN_STRETCH_CONDENSED);
-    else MATCH ("semi-condensed",  props->stretch, TWIN_STRETCH_SEMI_CONDENSED);
-    else MATCH ("semi-expanded",   props->stretch, TWIN_STRETCH_SEMI_EXPANDED);
-    else MATCH ("expanded",        props->stretch, TWIN_STRETCH_EXPANDED);
-    else MATCH ("extra-expanded",  props->stretch, TWIN_STRETCH_EXTRA_EXPANDED);
-    else MATCH ("ultra-expanded",  props->stretch, TWIN_STRETCH_ULTRA_EXPANDED);
-
-    else MATCH ("mono",       props->monospace, TRUE);
-    else MATCH ("monospace",  props->monospace, TRUE);
-
-    else MATCH ("small-caps", props->smallcaps, TRUE);
+    else MATCH ("Oblique",	props->slant, CAIRO_FONT_SLANT_OBLIQUE);
+    else MATCH ("Italic",	props->slant, CAIRO_FONT_SLANT_ITALIC);
+
+    else MATCH ("Thin",		props->weight, TWIN_WEIGHT_THIN);
+    else MATCH ("Ultra-Light",	props->weight, TWIN_WEIGHT_ULTRALIGHT);
+    else MATCH ("Extra-Light",	props->weight, TWIN_WEIGHT_ULTRALIGHT);
+    else MATCH ("Light",	props->weight, TWIN_WEIGHT_LIGHT);
+    else MATCH ("Book",		props->weight, TWIN_WEIGHT_BOOK);
+    else MATCH ("Regular",	props->weight, TWIN_WEIGHT_NORMAL);
+    else MATCH ("Medium",	props->weight, TWIN_WEIGHT_MEDIUM);
+    else MATCH ("Semi-Bold",	props->weight, TWIN_WEIGHT_SEMIBOLD);
+    else MATCH ("Demi-Bold",	props->weight, TWIN_WEIGHT_SEMIBOLD);
+    else MATCH ("Bold",		props->weight, TWIN_WEIGHT_BOLD);
+    else MATCH ("Ultra-Bold",	props->weight, TWIN_WEIGHT_ULTRABOLD);
+    else MATCH ("Extra-Bold",	props->weight, TWIN_WEIGHT_ULTRABOLD);
+    else MATCH ("Heavy",	props->weight, TWIN_WEIGHT_HEAVY);
+    else MATCH ("Black",	props->weight, TWIN_WEIGHT_HEAVY);
+    else MATCH ("Ultra-Heavy",	props->weight, TWIN_WEIGHT_ULTRAHEAVY);
+    else MATCH ("Extra-Heavy",	props->weight, TWIN_WEIGHT_ULTRAHEAVY);
+    else MATCH ("Ultra-Black",	props->weight, TWIN_WEIGHT_ULTRAHEAVY);
+    else MATCH ("Extra-Black",	props->weight, TWIN_WEIGHT_ULTRAHEAVY);
+
+    else MATCH ("Ultra-Condensed",	props->stretch, TWIN_STRETCH_ULTRA_CONDENSED);
+    else MATCH ("Extra-Condensed",	props->stretch, TWIN_STRETCH_EXTRA_CONDENSED);
+    else MATCH ("Condensed",		props->stretch, TWIN_STRETCH_CONDENSED);
+    else MATCH ("Semi-Condensed",	props->stretch, TWIN_STRETCH_SEMI_CONDENSED);
+    else MATCH ("Semi-Expanded",	props->stretch, TWIN_STRETCH_SEMI_EXPANDED);
+    else MATCH ("Expanded",		props->stretch, TWIN_STRETCH_EXPANDED);
+    else MATCH ("Extra-Expanded",	props->stretch, TWIN_STRETCH_EXTRA_EXPANDED);
+    else MATCH ("Ultra-Expanded",	props->stretch, TWIN_STRETCH_ULTRA_EXPANDED);
+
+    else MATCH ("Mono",		props->monospace, TRUE);
+    else MATCH ("Monospace",	props->monospace, TRUE);
+
+    else MATCH ("Small-Caps",	props->smallcaps, TRUE);
 }
 
 static void


More information about the cairo-commit mailing list