[gtk+] css: implement font-variant as a shorthand



commit 92398bb1bbae85ead39e9579b09f86649df7aeb1
Author: Matthias Clasen <mclasen redhat com>
Date:   Mon Sep 18 11:28:05 2017 -0400

    css: implement font-variant as a shorthand
    
    Drop the current css2-style font-variant property and
    replace it with a shorthand as specified in the css3 fonts
    module. Currently, we fully support the font-variant-ligatures,
    font-variant-position, font-variant-caps, font-variant-numeric
    and font-variant-east-asian subproperties. font-variant-alternatives
    is only partially supported.

 gtk/gtkcssarrayvalue.c            |    1 -
 gtk/gtkcssenumvalue.c             |   47 --------
 gtk/gtkcssenumvalueprivate.h      |    4 -
 gtk/gtkcssshorthandpropertyimpl.c |  235 ++++++++++++++++++++++++++++++++++++-
 gtk/gtkcssstylepropertyimpl.c     |   29 -----
 gtk/gtkcsstypesprivate.h          |    1 -
 6 files changed, 230 insertions(+), 87 deletions(-)
---
diff --git a/gtk/gtkcssarrayvalue.c b/gtk/gtkcssarrayvalue.c
index edda886..c1a94c7 100644
--- a/gtk/gtkcssarrayvalue.c
+++ b/gtk/gtkcssarrayvalue.c
@@ -244,7 +244,6 @@ gtk_css_value_array_transition (GtkCssValue *start,
     case GTK_CSS_PROPERTY_BACKGROUND_COLOR:
     case GTK_CSS_PROPERTY_FONT_FAMILY:
     case GTK_CSS_PROPERTY_FONT_STYLE:
-    case GTK_CSS_PROPERTY_FONT_VARIANT:
     case GTK_CSS_PROPERTY_FONT_WEIGHT:
     case GTK_CSS_PROPERTY_TEXT_SHADOW:
     case GTK_CSS_PROPERTY_ICON_SHADOW:
diff --git a/gtk/gtkcssenumvalue.c b/gtk/gtkcssenumvalue.c
index 81e238d..b4b31da 100644
--- a/gtk/gtkcssenumvalue.c
+++ b/gtk/gtkcssenumvalue.c
@@ -376,53 +376,6 @@ _gtk_css_font_style_value_get (const GtkCssValue *value)
   return value->value;
 }
 
-/* PangoVariant */
-
-static const GtkCssValueClass GTK_CSS_VALUE_FONT_VARIANT = {
-  gtk_css_value_enum_free,
-  gtk_css_value_enum_compute,
-  gtk_css_value_enum_equal,
-  gtk_css_value_enum_transition,
-  gtk_css_value_enum_print
-};
-
-static GtkCssValue font_variant_values[] = {
-  { &GTK_CSS_VALUE_FONT_VARIANT, 1, PANGO_VARIANT_NORMAL, "normal" },
-  { &GTK_CSS_VALUE_FONT_VARIANT, 1, PANGO_VARIANT_SMALL_CAPS, "small-caps" }
-};
-
-GtkCssValue *
-_gtk_css_font_variant_value_new (PangoVariant font_variant)
-{
-  g_return_val_if_fail ((gint)font_variant < G_N_ELEMENTS (font_variant_values), NULL);
-
-  return _gtk_css_value_ref (&font_variant_values[font_variant]);
-}
-
-GtkCssValue *
-_gtk_css_font_variant_value_try_parse (GtkCssParser *parser)
-{
-  guint i;
-
-  g_return_val_if_fail (parser != NULL, NULL);
-
-  for (i = 0; i < G_N_ELEMENTS (font_variant_values); i++)
-    {
-      if (_gtk_css_parser_try (parser, font_variant_values[i].name, TRUE))
-        return _gtk_css_value_ref (&font_variant_values[i]);
-    }
-
-  return NULL;
-}
-
-PangoVariant
-_gtk_css_font_variant_value_get (const GtkCssValue *value)
-{
-  g_return_val_if_fail (value->class == &GTK_CSS_VALUE_FONT_VARIANT, PANGO_VARIANT_NORMAL);
-
-  return value->value;
-}
-
 /* PangoWeight */
 
 #define BOLDER -1
diff --git a/gtk/gtkcssenumvalueprivate.h b/gtk/gtkcssenumvalueprivate.h
index 5b6c6f3..bdb4d2a 100644
--- a/gtk/gtkcssenumvalueprivate.h
+++ b/gtk/gtkcssenumvalueprivate.h
@@ -45,10 +45,6 @@ GtkCssValue *   _gtk_css_font_style_value_new         (PangoStyle         style)
 GtkCssValue *   _gtk_css_font_style_value_try_parse   (GtkCssParser      *parser);
 PangoStyle      _gtk_css_font_style_value_get         (const GtkCssValue *value);
 
-GtkCssValue *   _gtk_css_font_variant_value_new       (PangoVariant       variant);
-GtkCssValue *   _gtk_css_font_variant_value_try_parse (GtkCssParser      *parser);
-PangoVariant    _gtk_css_font_variant_value_get       (const GtkCssValue *value);
-
 GtkCssValue *   _gtk_css_font_weight_value_new        (PangoWeight        weight);
 GtkCssValue *   _gtk_css_font_weight_value_try_parse  (GtkCssParser      *parser);
 PangoWeight     _gtk_css_font_weight_value_get        (const GtkCssValue *value);
diff --git a/gtk/gtkcssshorthandpropertyimpl.c b/gtk/gtkcssshorthandpropertyimpl.c
index 845e31b..c2081f4 100644
--- a/gtk/gtkcssshorthandpropertyimpl.c
+++ b/gtk/gtkcssshorthandpropertyimpl.c
@@ -416,6 +416,16 @@ parse_border (GtkCssShorthandProperty  *shorthand,
   return TRUE;
 }
 
+static GtkCssValue *
+_gtk_css_font_variant_value_try_parse (GtkCssParser *parser)
+{
+  if (_gtk_css_parser_try (parser, "normal", TRUE))
+    return _gtk_css_ident_value_new ("normal");
+  else if (_gtk_css_parser_try (parser, "small-caps", TRUE))
+    return _gtk_css_ident_value_new ("small-caps");
+  return NULL;
+}
+
 static gboolean
 parse_font (GtkCssShorthandProperty  *shorthand,
             GtkCssValue             **values,
@@ -857,6 +867,219 @@ parse_text_decoration (GtkCssShorthandProperty  *shorthand,
 }
 
 static gboolean
+parse_font_variant (GtkCssShorthandProperty  *shorthand,
+                    GtkCssValue             **values,
+                    GtkCssParser             *parser)
+{
+  if (_gtk_css_parser_try (parser, "normal", TRUE))
+    {
+      /* all initial values */
+    }
+  else if (_gtk_css_parser_try (parser, "none", TRUE))
+    {
+      /* all initial values, except for font-variant-ligatures */
+      values[0] = _gtk_css_array_value_new (_gtk_css_ident_value_new ("none"));
+    }
+  else
+    {
+      gboolean found;
+      GtkCssValue *lig_values[4] = { NULL, NULL, NULL, NULL };
+      guint n_ligs = 0;
+      gboolean common = FALSE;
+      gboolean discretionary = FALSE;
+      gboolean historical = FALSE;
+      gboolean contextual = FALSE;
+      GtkCssValue *num_values[5] = { NULL, NULL, NULL, NULL };
+      guint n_num = 0;
+      gboolean figure = FALSE;
+      gboolean spacing = FALSE;
+      gboolean fraction = FALSE;
+      gboolean ordinal = FALSE;
+      gboolean zero = FALSE;
+      GtkCssValue *alt_value;
+      GtkCssValue *ea_values[5] = { NULL, NULL, NULL, NULL };
+      guint n_ea = 0;
+      gboolean variant = FALSE;
+      gboolean width = FALSE;
+      gboolean ruby = FALSE;
+
+      do {
+        found = FALSE;
+        if (!common)
+          {
+            lig_values[n_ligs] = _gtk_css_ident_value_try (parser, "common-ligatures",
+                                                                   "no-common-ligatures", NULL);
+            if (lig_values[n_ligs])
+              {
+                n_ligs++;
+                common = TRUE;
+                found = TRUE;
+              }
+          }
+        if (!discretionary)
+          {
+            lig_values[n_ligs] = _gtk_css_ident_value_try (parser, "discretionary-ligatures",
+                                                                   "no-discretionary-ligatures", NULL);
+            if (lig_values[n_ligs])
+              {
+                n_ligs++;
+                discretionary = TRUE;
+                found = TRUE;
+              }
+          }
+        if (!historical)
+          {
+            lig_values[n_ligs] = _gtk_css_ident_value_try (parser, "historical-ligatures",
+                                                                   "no-historical-ligatures", NULL);
+            if (lig_values[n_ligs])
+              {
+                n_ligs++;
+                historical = TRUE;
+                found = TRUE;
+              }
+          }
+        if (!contextual)
+          {
+            lig_values[n_ligs] = _gtk_css_ident_value_try (parser, "contextual",
+                                                                   "no-contextual", NULL);
+            if (lig_values[n_ligs])
+              {
+                n_ligs++;
+                contextual = TRUE;
+                found = TRUE;
+              }
+          }
+
+        if (!figure)
+          {
+            num_values[n_num] = _gtk_css_ident_value_try (parser, "lining-nums",
+                                                                  "oldstyle-nums", NULL);
+            if (num_values[n_num])
+              {
+                n_num++;
+                figure = TRUE;
+                found = TRUE;
+              }
+          }
+        if (!spacing)
+          {
+            num_values[n_num] = _gtk_css_ident_value_try (parser, "proportional-nums",
+                                                                  "tabular-nums", NULL);
+            if (num_values[n_num])
+              {
+                n_num++;
+                spacing = TRUE;
+                found = TRUE;
+              }
+          }
+        if (!fraction)
+          {
+            num_values[n_num] = _gtk_css_ident_value_try (parser, "diagonal-fractions",
+                                                                  "stacked-fractions", NULL);
+            if (num_values[n_num])
+              {
+                n_num++;
+                fraction = TRUE;
+                found = TRUE;
+              }
+          }
+        if (!ordinal)
+          {
+            num_values[n_num] = _gtk_css_ident_value_try (parser, "ordinal", NULL);
+            if (num_values[n_num])
+              {
+                n_num++;
+                ordinal = TRUE;
+                found = TRUE;
+              }
+          }
+        if (!zero)
+          {
+            num_values[n_num] = _gtk_css_ident_value_try (parser, "slashed-zero", NULL);
+            if (num_values[n_num])
+              {
+                n_num++;
+                zero = TRUE;
+                found = TRUE;
+              }
+          }
+        if (alt_value == NULL)
+          {
+            alt_value = _gtk_css_ident_value_try (parser, "historical-forms", NULL);
+            if (alt_value)
+              found = TRUE;
+          }
+
+        if (values[1] == NULL)
+          {
+            values[1] = _gtk_css_ident_value_try (parser, "sub", "super", NULL);
+            if (values[1])
+              found = TRUE;
+          }
+        if (values[2] == NULL)
+          {
+            values[2] = _gtk_css_ident_value_try (parser, "small-caps", "all-small-caps",
+                                                          "petite-caps", "all-petite-caps",
+                                                          "unicase", "titling-caps", NULL);
+            if (values[2])
+              found = TRUE;
+          }
+
+        if (!variant)
+          {
+            ea_values[n_ea] = _gtk_css_ident_value_try (parser, "jis78", "jis83", "jis90", "jis04",
+                                                        "simplified", "traditional", NULL);
+            if (ea_values[n_ea])
+              {
+                n_ea++;
+                variant = TRUE;
+              }
+         }
+        if (!width)
+          {
+            ea_values[n_ea] = _gtk_css_ident_value_try (parser, "full-width"
+                                                                "proportional-width", NULL);
+            if (ea_values[n_ea])
+              {
+                n_ea++;
+                width = TRUE;
+              }
+         }
+        if (!ruby)
+          {
+            ea_values[n_ea] = _gtk_css_ident_value_try (parser, "ruby", NULL);
+            if (ea_values[n_ea])
+              {
+                n_ea++;
+                ruby = TRUE;
+              }
+         }
+
+
+        if (!found)
+          {
+            _gtk_css_parser_error (parser, "Unknown value for property");
+            return FALSE;
+          }
+      } while (!value_is_done_parsing (parser));
+
+      if (n_ligs > 0)
+        values[0] = _gtk_css_array_value_new_from_array (lig_values, n_ligs);
+
+      if (n_num > 0)
+        values[3] = _gtk_css_array_value_new_from_array (num_values, n_num);
+
+      if (alt_value)
+        values[4] = _gtk_css_array_value_new (alt_value);
+
+      if (n_ea > 0)
+        values[5] = _gtk_css_array_value_new_from_array  (ea_values, n_ea);
+    }
+
+  return TRUE;
+}
+
+static gboolean
 parse_all (GtkCssShorthandProperty  *shorthand,
            GtkCssValue             **values,
            GtkCssParser             *parser)
@@ -949,10 +1172,6 @@ pack_font_description (GtkCssShorthandProperty *shorthand,
   if (v)
     pango_font_description_set_style (description, _gtk_css_font_style_value_get (v));
 
-  v = (* query_func) (_gtk_css_style_property_get_id (GTK_CSS_STYLE_PROPERTY (_gtk_style_property_lookup 
("font-variant"))), query_data);
-  if (v)
-    pango_font_description_set_variant (description, _gtk_css_font_variant_value_get (v));
-
   v = (* query_func) (_gtk_css_style_property_get_id (GTK_CSS_STYLE_PROPERTY (_gtk_style_property_lookup 
("font-weight"))), query_data);
   if (v)
     pango_font_description_set_weight (description, _gtk_css_font_weight_value_get (v));
@@ -1027,7 +1246,7 @@ void
 _gtk_css_shorthand_property_init_properties (void)
 {
   /* The order is important here, be careful when changing it */
-  const char *font_subproperties[] = { "font-family", "font-style", "font-variant", "font-weight", 
"font-stretch", "font-size", NULL };
+  const char *font_subproperties[] = { "font-family", "font-style", "font-variant-caps", "font-weight", 
"font-stretch", "font-size", NULL };
   const char *margin_subproperties[] = { "margin-top", "margin-right", "margin-bottom", "margin-left", NULL 
};
   const char *padding_subproperties[] = { "padding-top", "padding-right", "padding-bottom", "padding-left", 
NULL };
   const char *border_width_subproperties[] = { "border-top-width", "border-right-width", 
"border-bottom-width", "border-left-width", NULL };
@@ -1053,6 +1272,7 @@ _gtk_css_shorthand_property_init_properties (void)
   const char *animation_subproperties[] = { "animation-name", "animation-iteration-count", 
"animation-duration", "animation-delay", 
                                             "animation-timing-function", "animation-direction", 
"animation-fill-mode", NULL };
   const char *text_decoration_subproperties[] = { "text-decoration-line", "text-decoration-style", 
"text-decoration-color", NULL };
+  const char *font_variant_subproperties[] = { "font-variant-ligatures", "font-variant-position", 
"font-variant-caps", "font-variant-numeric", "font-variant-alternatives", "font-variant-east-asian", NULL };
 
   const char **all_subproperties;
 
@@ -1151,6 +1371,11 @@ _gtk_css_shorthand_property_init_properties (void)
                                           text_decoration_subproperties,
                                           parse_text_decoration,
                                           NULL);
+  _gtk_css_shorthand_property_register   ("font-variant",
+                                          G_TYPE_NONE,
+                                          font_variant_subproperties,
+                                          parse_font_variant,
+                                          NULL);
 
   all_subproperties = get_all_subproperties ();
   _gtk_css_shorthand_property_register   ("all",
diff --git a/gtk/gtkcssstylepropertyimpl.c b/gtk/gtkcssstylepropertyimpl.c
index a81a5a2..adc7ea3 100644
--- a/gtk/gtkcssstylepropertyimpl.c
+++ b/gtk/gtkcssstylepropertyimpl.c
@@ -260,27 +260,6 @@ font_weight_query (GtkCssStyleProperty *property,
 }
 
 static GtkCssValue *
-font_variant_parse (GtkCssStyleProperty *property,
-                    GtkCssParser        *parser)
-{
-  GtkCssValue *value = _gtk_css_font_variant_value_try_parse (parser);
-  
-  if (value == NULL)
-    _gtk_css_parser_error (parser, "unknown value for property");
-
-  return value;
-}
-
-static void
-font_variant_query (GtkCssStyleProperty *property,
-                    const GtkCssValue   *css_value,
-                     GValue              *value)
-{
-  g_value_init (value, PANGO_TYPE_VARIANT);
-  g_value_set_enum (value, _gtk_css_font_variant_value_get (css_value));
-}
-
-static GtkCssValue *
 font_stretch_parse (GtkCssStyleProperty *property,
                     GtkCssParser        *parser)
 {
@@ -1238,14 +1217,6 @@ _gtk_css_style_property_init_properties (void)
                                           font_style_parse,
                                           font_style_query,
                                           _gtk_css_font_style_value_new (PANGO_STYLE_NORMAL));
-  gtk_css_style_property_register        ("font-variant",
-                                          GTK_CSS_PROPERTY_FONT_VARIANT,
-                                          PANGO_TYPE_VARIANT,
-                                          GTK_STYLE_PROPERTY_INHERIT,
-                                          GTK_CSS_AFFECTS_FONT | GTK_CSS_AFFECTS_TEXT,
-                                          font_variant_parse,
-                                          font_variant_query,
-                                          _gtk_css_font_variant_value_new (PANGO_VARIANT_NORMAL));
   gtk_css_style_property_register        ("font-weight",
                                           GTK_CSS_PROPERTY_FONT_WEIGHT,
                                           PANGO_TYPE_WEIGHT,
diff --git a/gtk/gtkcsstypesprivate.h b/gtk/gtkcsstypesprivate.h
index 8e939f3..a7fe8c9 100644
--- a/gtk/gtkcsstypesprivate.h
+++ b/gtk/gtkcsstypesprivate.h
@@ -156,7 +156,6 @@ enum { /*< skip >*/
   GTK_CSS_PROPERTY_BACKGROUND_COLOR,
   GTK_CSS_PROPERTY_FONT_FAMILY,
   GTK_CSS_PROPERTY_FONT_STYLE,
-  GTK_CSS_PROPERTY_FONT_VARIANT,
   GTK_CSS_PROPERTY_FONT_WEIGHT,
   GTK_CSS_PROPERTY_FONT_STRETCH,
   GTK_CSS_PROPERTY_LETTER_SPACING,


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