[pango/wip/matthiasc/font-variations: 1/2] Add basic support for font variations



commit 64bb612be4dca287adb6b99c15f02b49e73f7e8c
Author: Matthias Clasen <mclasen redhat com>
Date:   Tue Sep 5 07:37:31 2017 -0400

    Add basic support for font variations
    
    This lets PangoFontDescription carry font variation information
    as a string.

 pango/fonts.c      |   80 ++++++++++++++++++++++++++++++++++++++++++++++------
 pango/pango-font.h |   10 ++++++-
 2 files changed, 80 insertions(+), 10 deletions(-)
---
diff --git a/pango/fonts.c b/pango/fonts.c
index 49e035b..71a0e00 100644
--- a/pango/fonts.c
+++ b/pango/fonts.c
@@ -52,6 +52,8 @@ struct _PangoFontDescription
   PangoStretch stretch;
   PangoGravity gravity;
 
+  char *variations;
+
   guint16 mask;
   guint static_family : 1;
   guint size_is_absolute : 1;
@@ -71,6 +73,7 @@ static const PangoFontDescription pfd_defaults = {
   PANGO_WEIGHT_NORMAL, /* weight */
   PANGO_STRETCH_NORMAL,        /* stretch */
   PANGO_GRAVITY_SOUTH,  /* gravity */
+  NULL,                 /* variations */
 
   0,                   /* mask */
   0,                   /* static_family */
@@ -479,6 +482,29 @@ pango_font_description_get_gravity (const PangoFontDescription *desc)
   return desc->gravity;
 }
 
+void
+pango_font_description_set_variations (PangoFontDescription *desc,
+                                       const char           *variations)
+{
+  g_return_if_fail (desc != NULL);
+
+  g_free (desc->variations);
+  desc->variations = g_strdup (variations);
+
+  if (variations != NULL)
+    desc->mask |= PANGO_FONT_MASK_VARIATIONS;
+  else
+    desc->mask &= ~PANGO_FONT_MASK_VARIATIONS;
+}
+
+const char *
+pango_font_description_get_variations (const PangoFontDescription *desc)
+{
+  g_return_val_if_fail (desc != NULL, NULL);
+
+  return desc->variations;
+}
+
 /**
  * pango_font_description_get_set_fields:
  * @desc: a #PangoFontDescription
@@ -697,6 +723,8 @@ pango_font_description_copy  (const PangoFontDescription  *desc)
       result->static_family = FALSE;
     }
 
+  result->variations = g_strdup (result->variations);
+
   return result;
 }
 
@@ -760,7 +788,8 @@ pango_font_description_equal (const PangoFontDescription  *desc1,
         desc1->size_is_absolute == desc2->size_is_absolute &&
         desc1->gravity == desc2->gravity &&
         (desc1->family_name == desc2->family_name ||
-         (desc1->family_name && desc2->family_name && g_ascii_strcasecmp (desc1->family_name, 
desc2->family_name) == 0));
+         (desc1->family_name && desc2->family_name && g_ascii_strcasecmp (desc1->family_name, 
desc2->family_name) == 0)) &&
+         (g_strcmp0 (desc1->variations, desc2->variations) == 0);
 }
 
 #define TOLOWER(c) \
@@ -800,6 +829,8 @@ pango_font_description_hash (const PangoFontDescription *desc)
 
   if (desc->family_name)
     hash = case_insensitive_hash (desc->family_name);
+  if (desc->variations)
+    hash ^= g_str_hash (desc->variations);
   hash ^= desc->size;
   hash ^= desc->size_is_absolute ? 0xc33ca55a : 0;
   hash ^= desc->style << 16;
@@ -826,6 +857,8 @@ pango_font_description_free  (PangoFontDescription  *desc)
   if (desc->family_name && !desc->static_family)
     g_free (desc->family_name);
 
+  g_free (desc->variations);
+
   g_slice_free (PangoFontDescription, desc);
 }
 
@@ -1031,7 +1064,7 @@ find_field_any (const char *str, int len, PangoFontDescription *desc)
 }
 
 static const char *
-getword (const char *str, const char *last, size_t *wordlen)
+getword (const char *str, const char *last, size_t *wordlen, const char *stop)
 {
   const char *result;
 
@@ -1039,7 +1072,7 @@ getword (const char *str, const char *last, size_t *wordlen)
     last--;
 
   result = last;
-  while (result > str && !g_ascii_isspace (*(result - 1)) && *(result - 1) != ',')
+  while (result > str && !g_ascii_isspace (*(result - 1)) && !strchr (stop, *(result - 1)))
     result--;
 
   *wordlen = last - result;
@@ -1073,6 +1106,20 @@ parse_size (const char *word,
   return FALSE;
 }
 
+static gboolean
+parse_variations (const char  *word,
+                  size_t       wordlen,
+                  char       **variations)
+{
+  if (word[0] != '@')
+    return FALSE;
+
+  /* XXX: actually validate here */
+  *variations = g_strndup (word + 1, wordlen - 1);
+
+  return TRUE;
+}
+
 /**
  * pango_font_description_from_string:
  * @str: string representation of a font description.
@@ -1110,10 +1157,19 @@ pango_font_description_from_string (const char *str)
 
   len = strlen (str);
   last = str + len;
-  p = getword (str, last, &wordlen);
+  p = getword (str, last, &wordlen, "");
+  /* Look for variations at the end of the string */
+  if (wordlen != 0)
+    {
+      if (parse_variations (p, wordlen, &desc->variations))
+        {
+         desc->mask |= PANGO_FONT_MASK_VARIATIONS;
+         last = p;
+        }
+    }
 
-  /* Look for a size at the end of the string
-   */
+  p = getword (str, last, &wordlen, ",");
+  /* Look for a size */
   if (wordlen != 0)
     {
       gboolean size_is_absolute;
@@ -1127,7 +1183,7 @@ pango_font_description_from_string (const char *str)
 
   /* Now parse style words
    */
-  p = getword (str, last, &wordlen);
+  p = getword (str, last, &wordlen, ",");
   while (wordlen != 0)
     {
       if (!find_field_any (p, wordlen, desc))
@@ -1135,7 +1191,7 @@ pango_font_description_from_string (const char *str)
       else
        {
          last = p;
-         p = getword (str, last, &wordlen);
+         p = getword (str, last, &wordlen, ",");
        }
     }
 
@@ -1234,7 +1290,7 @@ pango_font_description_to_string (const PangoFontDescription  *desc)
        * in a keyword like "Bold", or if the family name ends in
        * a number and no keywords will be added.
        */
-      p = getword (desc->family_name, desc->family_name + strlen(desc->family_name), &wordlen);
+      p = getword (desc->family_name, desc->family_name + strlen(desc->family_name), &wordlen, ",");
       if (wordlen != 0 &&
          (find_field_any (p, wordlen, NULL) ||
           (parse_size (p, wordlen, NULL, NULL) &&
@@ -1275,6 +1331,12 @@ pango_font_description_to_string (const PangoFontDescription  *desc)
        g_string_append (result, "px");
     }
 
+  if (desc->variations && desc->mask & PANGO_FONT_MASK_VARIATIONS)
+    {
+      g_string_append (result, " @");
+      g_string_append (result, desc->variations);
+    }
+
   return g_string_free (result, FALSE);
 }
 
diff --git a/pango/pango-font.h b/pango/pango-font.h
index cdc07cd..98f9891 100644
--- a/pango/pango-font.h
+++ b/pango/pango-font.h
@@ -145,6 +145,7 @@ typedef enum {
  * @PANGO_FONT_MASK_STRETCH: the font stretch is specified.
  * @PANGO_FONT_MASK_SIZE: the font size is specified.
  * @PANGO_FONT_MASK_GRAVITY: the font gravity is specified (Since: 1.16.)
+ * @PANGO_FONT_MASK_VARIATIONS: OpenType font variations are specified (Since: 1.42)
  *
  * The bits in a #PangoFontMask correspond to fields in a
  * #PangoFontDescription that have been set.
@@ -156,7 +157,8 @@ typedef enum {
   PANGO_FONT_MASK_WEIGHT  = 1 << 3,
   PANGO_FONT_MASK_STRETCH = 1 << 4,
   PANGO_FONT_MASK_SIZE    = 1 << 5,
-  PANGO_FONT_MASK_GRAVITY = 1 << 6
+  PANGO_FONT_MASK_GRAVITY = 1 << 6,
+  PANGO_FONT_MASK_VARIATIONS = 1 << 7,
 } PangoFontMask;
 
 /* CSS scale factors (1.2 factor between each size) */
@@ -277,6 +279,12 @@ void                 pango_font_description_set_gravity       (PangoFontDescript
 PANGO_AVAILABLE_IN_1_16
 PangoGravity         pango_font_description_get_gravity       (const PangoFontDescription *desc) G_GNUC_PURE;
 
+PANGO_AVAILABLE_IN_1_40
+void                 pango_font_description_set_variations    (PangoFontDescription       *desc,
+                                                               const char                 *settings);
+PANGO_AVAILABLE_IN_1_40
+const char          *pango_font_description_get_variations    (const PangoFontDescription *desc) G_GNUC_PURE;
+
 PANGO_AVAILABLE_IN_ALL
 PangoFontMask pango_font_description_get_set_fields (const PangoFontDescription *desc) G_GNUC_PURE;
 PANGO_AVAILABLE_IN_ALL


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]