[gtk+] css: Implement font-stretch



commit 5ad60caa3c35f86c11545b53052acdb6b9f7a76f
Author: Emmanuele Bassi <ebassi gnome org>
Date:   Thu Aug 28 12:50:49 2014 +0100

    css: Implement font-stretch
    
    The font-stretch CSS property is defined in the Level 3 CSS Fonts
    module, available at:
    
      http://dev.w3.org/csswg/css-fonts/#propdef-font-stretch
    
    It allows defining a normal, condensed, or expanded face to the font
    description. Pango already supports it, so this is literally just the
    CSS parser machinery needed to bridge our CSS to the FontDescription
    API.
    
    https://bugzilla.gnome.org/show_bug.cgi?id=735593

 gtk/gtkcssenumvalue.c                              |   54 ++++++++++++++++++++
 gtk/gtkcssenumvalueprivate.h                       |    4 ++
 gtk/gtkcssprovider.c                               |   18 ++++++-
 gtk/gtkcssshorthandpropertyimpl.c                  |   22 +++++++-
 gtk/gtkcssstylepropertyimpl.c                      |   36 +++++++++++++
 gtk/gtkcsstypesprivate.h                           |    1 +
 testsuite/css/parser/declarations-valid-02.ref.css |    1 +
 testsuite/css/parser/declarations-valid-03.ref.css |    1 +
 testsuite/css/parser/declarations-valid-04.ref.css |    1 +
 testsuite/css/parser/declarations-valid-08.ref.css |    1 +
 .../css/parser/value-inherit-shorthand.ref.css     |    1 +
 testsuite/css/parser/value-inherit.css             |    1 +
 .../css/parser/value-initial-shorthand.ref.css     |    1 +
 13 files changed, 139 insertions(+), 3 deletions(-)
---
diff --git a/gtk/gtkcssenumvalue.c b/gtk/gtkcssenumvalue.c
index b131823..d898c03 100644
--- a/gtk/gtkcssenumvalue.c
+++ b/gtk/gtkcssenumvalue.c
@@ -436,6 +436,60 @@ _gtk_css_font_weight_value_get (const GtkCssValue *value)
   return value->value;
 }
 
+/* PangoStretch */
+
+static const GtkCssValueClass GTK_CSS_VALUE_FONT_STRETCH = {
+  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_stretch_values[] = {
+  { &GTK_CSS_VALUE_FONT_STRETCH, 1, PANGO_STRETCH_ULTRA_CONDENSED, "ultra-condensed" },
+  { &GTK_CSS_VALUE_FONT_STRETCH, 1, PANGO_STRETCH_EXTRA_CONDENSED, "extra-condensed" },
+  { &GTK_CSS_VALUE_FONT_STRETCH, 1, PANGO_STRETCH_CONDENSED, "condensed" },
+  { &GTK_CSS_VALUE_FONT_STRETCH, 1, PANGO_STRETCH_SEMI_CONDENSED, "semi-condensed" },
+  { &GTK_CSS_VALUE_FONT_STRETCH, 1, PANGO_STRETCH_NORMAL, "normal" },
+  { &GTK_CSS_VALUE_FONT_STRETCH, 1, PANGO_STRETCH_SEMI_EXPANDED, "semi-expanded" },
+  { &GTK_CSS_VALUE_FONT_STRETCH, 1, PANGO_STRETCH_EXPANDED, "expanded" },
+  { &GTK_CSS_VALUE_FONT_STRETCH, 1, PANGO_STRETCH_EXTRA_EXPANDED, "extra-expanded" },
+  { &GTK_CSS_VALUE_FONT_STRETCH, 1, PANGO_STRETCH_ULTRA_EXPANDED, "ultra-expanded" },
+};
+
+GtkCssValue *
+_gtk_css_font_stretch_value_new (PangoStretch font_stretch)
+{
+  g_return_val_if_fail (font_stretch < G_N_ELEMENTS (font_stretch_values), NULL);
+
+  return _gtk_css_value_ref (&font_stretch_values[font_stretch]);
+}
+
+GtkCssValue *
+_gtk_css_font_stretch_value_try_parse (GtkCssParser *parser)
+{
+  guint i;
+
+  g_return_val_if_fail (parser != NULL, NULL);
+
+  for (i = 0; i < G_N_ELEMENTS (font_stretch_values); i++)
+    {
+      if (_gtk_css_parser_try (parser, font_stretch_values[i].name, TRUE))
+        return _gtk_css_value_ref (&font_stretch_values[i]);
+    }
+
+  return NULL;
+}
+
+PangoStretch
+_gtk_css_font_stretch_value_get (const GtkCssValue *value)
+{
+  g_return_val_if_fail (value->class == &GTK_CSS_VALUE_FONT_STRETCH, PANGO_STRETCH_NORMAL);
+
+  return value->value;
+}
+
 /* GtkCssArea */
 
 static const GtkCssValueClass GTK_CSS_VALUE_AREA = {
diff --git a/gtk/gtkcssenumvalueprivate.h b/gtk/gtkcssenumvalueprivate.h
index d0a5d3f..ad09adb 100644
--- a/gtk/gtkcssenumvalueprivate.h
+++ b/gtk/gtkcssenumvalueprivate.h
@@ -48,6 +48,10 @@ 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);
 
+GtkCssValue *   _gtk_css_font_stretch_value_new       (PangoStretch       stretch);
+GtkCssValue *   _gtk_css_font_stretch_value_try_parse (GtkCssParser      *parser);
+PangoStretch    _gtk_css_font_stretch_value_get       (const GtkCssValue *value);
+
 GtkCssValue *   _gtk_css_area_value_new               (GtkCssArea         area);
 GtkCssValue *   _gtk_css_area_value_try_parse         (GtkCssParser      *parser);
 GtkCssArea      _gtk_css_area_value_get               (const GtkCssValue *value);
diff --git a/gtk/gtkcssprovider.c b/gtk/gtkcssprovider.c
index 429713b..8d6b216 100644
--- a/gtk/gtkcssprovider.c
+++ b/gtk/gtkcssprovider.c
@@ -766,7 +766,23 @@
  *  font-size: 12px;
  * ]|
  *
- * ## font: [family] [style] [variant] [size];
+ * ## font-stretch: [face]
+ *
+ * Selects a normal, condensed, or expanded face from a font family.
+ *
+ * Absolute keyword values have the following ordering, from narrowest to widest:
+ *
+ * - ultra-condensed
+ * - extra-condensed
+ * - condensed
+ * - semi-condensed
+ * - normal
+ * - semi-expanded
+ * - expanded
+ * - extra-expanded
+ * - ultra-expanded
+ *
+ * ## font: [family] [style] [variant] [stretch] [size];
  *
  * A shorthand for setting a few font properties at once.
  * - Supports any format accepted by pango_font_description_from_string()
diff --git a/gtk/gtkcssshorthandpropertyimpl.c b/gtk/gtkcssshorthandpropertyimpl.c
index 6477878..bc828ea 100644
--- a/gtk/gtkcssshorthandpropertyimpl.c
+++ b/gtk/gtkcssshorthandpropertyimpl.c
@@ -453,9 +453,13 @@ parse_font (GtkCssShorthandProperty  *shorthand,
     {
       values[3] = _gtk_css_font_weight_value_new (pango_font_description_get_weight (desc));
     }
+  if (mask & PANGO_FONT_MASK_STRETCH)
+    {
+      values[4] = _gtk_css_font_stretch_value_new (pango_font_description_get_stretch (desc));
+    }
   if (mask & PANGO_FONT_MASK_SIZE)
     {
-      values[4] = _gtk_css_number_value_new ((double) pango_font_description_get_size (desc) / PANGO_SCALE, 
GTK_CSS_PX);
+      values[5] = _gtk_css_number_value_new ((double) pango_font_description_get_size (desc) / PANGO_SCALE, 
GTK_CSS_PX);
     }
 
   pango_font_description_free (desc);
@@ -996,6 +1000,16 @@ unpack_font_description (GtkCssShorthandProperty *shorthand,
       g_value_unset (&v);
     }
 
+  if (mask & PANGO_FONT_MASK_STRETCH)
+    {
+      g_value_init (&v, PANGO_TYPE_STRETCH);
+      g_value_set_enum (&v, pango_font_description_get_stretch (description));
+
+      prop = _gtk_style_property_lookup ("font-stretch");
+      _gtk_style_property_assign (prop, props, state, &v);
+      g_value_unset (&v);
+    }
+
   if (mask & PANGO_FONT_MASK_SIZE)
     {
       g_value_init (&v, G_TYPE_DOUBLE);
@@ -1041,6 +1055,10 @@ pack_font_description (GtkCssShorthandProperty *shorthand,
   if (v)
     pango_font_description_set_weight (description, _gtk_css_font_weight_value_get (v));
 
+  v = (* query_func) (_gtk_css_style_property_get_id (GTK_CSS_STYLE_PROPERTY (_gtk_style_property_lookup 
("font-stretch"))), query_data);
+  if (v)
+    pango_font_description_set_stretch (description, _gtk_css_font_stretch_value_get (v));
+
   g_value_init (value, PANGO_TYPE_FONT_DESCRIPTION);
   g_value_take_boxed (value, description);
 }
@@ -1127,7 +1145,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-size", NULL };
+  const char *font_subproperties[] = { "font-family", "font-style", "font-variant", "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 };
diff --git a/gtk/gtkcssstylepropertyimpl.c b/gtk/gtkcssstylepropertyimpl.c
index 27e77db..0cb791c 100644
--- a/gtk/gtkcssstylepropertyimpl.c
+++ b/gtk/gtkcssstylepropertyimpl.c
@@ -358,6 +358,34 @@ assign_pango_variant (GtkCssStyleProperty *property,
 }
 
 static GtkCssValue *
+parse_pango_stretch (GtkCssStyleProperty *property,
+                     GtkCssParser        *parser)
+{
+  GtkCssValue *value = _gtk_css_font_stretch_value_try_parse (parser);
+
+  if (value == NULL)
+    _gtk_css_parser_error (parser, "unknown value for property");
+
+  return value;
+}
+
+static void
+query_pango_stretch (GtkCssStyleProperty *property,
+                     const GtkCssValue   *css_value,
+                     GValue              *value)
+{
+  g_value_init (value, PANGO_TYPE_STRETCH);
+  g_value_set_enum (value, _gtk_css_font_stretch_value_get (css_value));
+}
+
+static GtkCssValue *
+assign_pango_stretch (GtkCssStyleProperty *property,
+                      const GValue        *value)
+{
+  return _gtk_css_font_stretch_value_new (g_value_get_enum (value));
+}
+
+static GtkCssValue *
 parse_border_style (GtkCssStyleProperty *property,
                     GtkCssParser        *parser)
 {
@@ -976,6 +1004,14 @@ _gtk_css_style_property_init_properties (void)
                                           query_pango_weight,
                                           assign_pango_weight,
                                           _gtk_css_font_weight_value_new (PANGO_WEIGHT_NORMAL));
+  gtk_css_style_property_register        ("font-stretch",
+                                          GTK_CSS_PROPERTY_FONT_STRETCH,
+                                          PANGO_TYPE_STRETCH,
+                                          GTK_STYLE_PROPERTY_INHERIT | GTK_STYLE_PROPERTY_AFFECTS_FONT,
+                                          parse_pango_stretch,
+                                          query_pango_stretch,
+                                          assign_pango_stretch,
+                                          _gtk_css_font_stretch_value_new (PANGO_STRETCH_NORMAL));
 
   gtk_css_style_property_register        ("text-shadow",
                                           GTK_CSS_PROPERTY_TEXT_SHADOW,
diff --git a/gtk/gtkcsstypesprivate.h b/gtk/gtkcsstypesprivate.h
index c7f9038..ca2faaf 100644
--- a/gtk/gtkcsstypesprivate.h
+++ b/gtk/gtkcsstypesprivate.h
@@ -78,6 +78,7 @@ enum { /*< skip >*/
   GTK_CSS_PROPERTY_FONT_STYLE,
   GTK_CSS_PROPERTY_FONT_VARIANT,
   GTK_CSS_PROPERTY_FONT_WEIGHT,
+  GTK_CSS_PROPERTY_FONT_STRETCH,
   GTK_CSS_PROPERTY_TEXT_SHADOW,
   GTK_CSS_PROPERTY_ICON_SOURCE,
   GTK_CSS_PROPERTY_ICON_SHADOW,
diff --git a/testsuite/css/parser/declarations-valid-02.ref.css 
b/testsuite/css/parser/declarations-valid-02.ref.css
index 0a74680..4cafd4e 100644
--- a/testsuite/css/parser/declarations-valid-02.ref.css
+++ b/testsuite/css/parser/declarations-valid-02.ref.css
@@ -1,6 +1,7 @@
 * {
   font-family: "Sans";
   font-size: 15px;
+  font-stretch: normal;
   font-style: normal;
   font-variant: normal;
   font-weight: normal;
diff --git a/testsuite/css/parser/declarations-valid-03.ref.css 
b/testsuite/css/parser/declarations-valid-03.ref.css
index 0a74680..4cafd4e 100644
--- a/testsuite/css/parser/declarations-valid-03.ref.css
+++ b/testsuite/css/parser/declarations-valid-03.ref.css
@@ -1,6 +1,7 @@
 * {
   font-family: "Sans";
   font-size: 15px;
+  font-stretch: normal;
   font-style: normal;
   font-variant: normal;
   font-weight: normal;
diff --git a/testsuite/css/parser/declarations-valid-04.ref.css 
b/testsuite/css/parser/declarations-valid-04.ref.css
index 2d8582d..92389ab 100644
--- a/testsuite/css/parser/declarations-valid-04.ref.css
+++ b/testsuite/css/parser/declarations-valid-04.ref.css
@@ -1,6 +1,7 @@
 * {
   font-family: initial;
   font-size: initial;
+  font-stretch: normal;
   font-style: normal;
   font-variant: normal;
   font-weight: bold;
diff --git a/testsuite/css/parser/declarations-valid-08.ref.css 
b/testsuite/css/parser/declarations-valid-08.ref.css
index 0a74680..4cafd4e 100644
--- a/testsuite/css/parser/declarations-valid-08.ref.css
+++ b/testsuite/css/parser/declarations-valid-08.ref.css
@@ -1,6 +1,7 @@
 * {
   font-family: "Sans";
   font-size: 15px;
+  font-stretch: normal;
   font-style: normal;
   font-variant: normal;
   font-weight: normal;
diff --git a/testsuite/css/parser/value-inherit-shorthand.ref.css 
b/testsuite/css/parser/value-inherit-shorthand.ref.css
index 4343ba4..07822f7 100644
--- a/testsuite/css/parser/value-inherit-shorthand.ref.css
+++ b/testsuite/css/parser/value-inherit-shorthand.ref.css
@@ -17,6 +17,7 @@
   border-top-width: inherit;
   font-family: inherit;
   font-size: inherit;
+  font-stretch: inherit;
   font-style: inherit;
   font-variant: inherit;
   font-weight: inherit;
diff --git a/testsuite/css/parser/value-inherit.css b/testsuite/css/parser/value-inherit.css
index 777bbac..6e18ed8 100644
--- a/testsuite/css/parser/value-inherit.css
+++ b/testsuite/css/parser/value-inherit.css
@@ -29,6 +29,7 @@
   engine: inherit;
   font-family: inherit;
   font-size: inherit;
+  font-stretch: inherit;
   font-style: inherit;
   font-variant: inherit;
   font-weight: inherit;
diff --git a/testsuite/css/parser/value-initial-shorthand.ref.css 
b/testsuite/css/parser/value-initial-shorthand.ref.css
index e6273e3..f71e9db 100644
--- a/testsuite/css/parser/value-initial-shorthand.ref.css
+++ b/testsuite/css/parser/value-initial-shorthand.ref.css
@@ -17,6 +17,7 @@
   border-top-width: initial;
   font-family: initial;
   font-size: initial;
+  font-stretch: initial;
   font-style: initial;
   font-variant: initial;
   font-weight: initial;


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