css: support text-decoration-style
authorPaolo Borelli <pborelli@gnome.org>
Mon, 6 Jul 2015 18:03:54 +0000 (20:03 +0200)
committerPaolo Borelli <pborelli@gnome.org>
Mon, 6 Jul 2015 18:06:20 +0000 (20:06 +0200)
The support is limited to underline single, double and wavy, which
is what pango has today.

gtk/gtkcssenumvalue.c
gtk/gtkcssenumvalueprivate.h
gtk/gtkcssshorthandpropertyimpl.c
gtk/gtkcssstylepropertyimpl.c
gtk/gtkcsstypesprivate.h
gtk/gtkstylecontext.c

index 15d9b4af106ca751547af8011e28137a6f26fa1c..a3555acb4345dd8b64dd11f417bb2c2eb5b3c5d5 100644 (file)
@@ -577,7 +577,8 @@ _gtk_css_text_decoration_line_value_new (GtkTextDecorationLine line)
   return _gtk_css_value_ref (&text_decoration_line_values[line]);
 }
 
-GtkCssValue *_gtk_css_text_decoration_line_value_try_parse (GtkCssParser *parser)
+GtkCssValue *
+_gtk_css_text_decoration_line_value_try_parse (GtkCssParser *parser)
 {
   guint i;
 
@@ -592,13 +593,62 @@ GtkCssValue *_gtk_css_text_decoration_line_value_try_parse (GtkCssParser *parser
   return NULL;
 }
 
-GtkTextDecorationLine _gtk_css_text_decoration_line_value_get (const GtkCssValue *value)
+GtkTextDecorationLine
+_gtk_css_text_decoration_line_value_get (const GtkCssValue *value)
 {
   g_return_val_if_fail (value->class == &GTK_CSS_VALUE_TEXT_DECORATION_LINE, GTK_CSS_TEXT_DECORATION_LINE_NONE);
 
   return value->value;
 }
 
+/* GtkTextDecorationStyle */
+
+static const GtkCssValueClass GTK_CSS_VALUE_TEXT_DECORATION_STYLE = {
+  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 text_decoration_style_values[] = {
+  { &GTK_CSS_VALUE_TEXT_DECORATION_STYLE, 1, GTK_CSS_TEXT_DECORATION_STYLE_SOLID, "solid" },
+  { &GTK_CSS_VALUE_TEXT_DECORATION_STYLE, 1, GTK_CSS_TEXT_DECORATION_STYLE_DOUBLE, "double" },
+  { &GTK_CSS_VALUE_TEXT_DECORATION_STYLE, 1, GTK_CSS_TEXT_DECORATION_STYLE_WAVY, "wavy" },
+};
+
+GtkCssValue *
+_gtk_css_text_decoration_style_value_new (GtkTextDecorationStyle style)
+{
+  g_return_val_if_fail (style < G_N_ELEMENTS (text_decoration_style_values), NULL);
+
+  return _gtk_css_value_ref (&text_decoration_style_values[style]);
+}
+
+GtkCssValue *
+_gtk_css_text_decoration_style_value_try_parse (GtkCssParser *parser)
+{
+  guint i;
+
+  g_return_val_if_fail (parser != NULL, NULL);
+
+  for (i = 0; i < G_N_ELEMENTS (text_decoration_style_values); i++)
+    {
+      if (_gtk_css_parser_try (parser, text_decoration_style_values[i].name, TRUE))
+        return _gtk_css_value_ref (&text_decoration_style_values[i]);
+    }
+
+  return NULL;
+}
+
+GtkTextDecorationStyle
+_gtk_css_text_decoration_style_value_get (const GtkCssValue *value)
+{
+  g_return_val_if_fail (value->class == &GTK_CSS_VALUE_TEXT_DECORATION_STYLE, GTK_CSS_TEXT_DECORATION_STYLE_SOLID);
+
+  return value->value;
+}
+
 /* GtkCssArea */
 
 static const GtkCssValueClass GTK_CSS_VALUE_AREA = {
index 008b548adcfdea287e14edfaa7427d1d53f8fc7c..6f1efb510a383269aeb85e2fd5780b43f32f491f 100644 (file)
@@ -56,6 +56,10 @@ GtkCssValue *         _gtk_css_text_decoration_line_value_new       (GtkTextDeco
 GtkCssValue *         _gtk_css_text_decoration_line_value_try_parse (GtkCssParser          *parser);
 GtkTextDecorationLine _gtk_css_text_decoration_line_value_get       (const GtkCssValue     *value);
 
+GtkCssValue *          _gtk_css_text_decoration_style_value_new       (GtkTextDecorationStyle  style);
+GtkCssValue *          _gtk_css_text_decoration_style_value_try_parse (GtkCssParser           *parser);
+GtkTextDecorationStyle _gtk_css_text_decoration_style_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);
index 61afcc69467186e4ca2c2a298f7c33b11b977706..759804895653355bbd3631d4ee024c6495fdb4ec 100644 (file)
@@ -836,12 +836,18 @@ parse_text_decoration (GtkCssShorthandProperty  *shorthand,
         if (values[0] == NULL)
           return FALSE;
       }
-    else if (values[1] == NULL)
+    else if (values[1] == NULL &&
+        (values[1] = _gtk_css_text_decoration_style_value_try_parse (parser)))
       {
-        values[1] = _gtk_css_color_value_parse (parser);
         if (values[1] == NULL)
           return FALSE;
       }
+    else if (values[2] == NULL)
+      {
+        values[2] = _gtk_css_color_value_parse (parser);
+        if (values[2] == NULL)
+          return FALSE;
+      }
     else
       {
         /* We parsed and there's still stuff left?
@@ -1202,7 +1208,7 @@ _gtk_css_shorthand_property_init_properties (void)
   const char *transition_subproperties[] = { "transition-property", "transition-duration", "transition-delay", "transition-timing-function", NULL };
   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-color", NULL };
+  const char *text_decoration_subproperties[] = { "text-decoration-line", "text-decoration-style", "text-decoration-color", NULL };
 
   const char **all_subproperties;
 
index 3a5dd8530f06a193072310c31a7318eb07f51261..7f2607bcfadab1588aac2aa54c6a309157738956 100644 (file)
@@ -629,6 +629,18 @@ parse_text_decoration_line (GtkCssStyleProperty *property,
   return value;
 }
 
+static GtkCssValue *
+parse_text_decoration_style (GtkCssStyleProperty *property,
+                             GtkCssParser        *parser)
+{
+  GtkCssValue *value = _gtk_css_text_decoration_style_value_try_parse (parser);
+
+  if (value == NULL)
+    _gtk_css_parser_error (parser, "unknown value for property");
+
+  return value;
+}
+
 static GtkCssValue *
 box_shadow_value_parse (GtkCssStyleProperty *property,
                         GtkCssParser        *parser)
@@ -1114,6 +1126,16 @@ _gtk_css_style_property_init_properties (void)
                                           NULL,
                                           _gtk_css_color_value_new_current_color ());
 
+  gtk_css_style_property_register        ("text-decoration-style",
+                                          GTK_CSS_PROPERTY_TEXT_DECORATION_STYLE,
+                                          G_TYPE_NONE,
+                                          GTK_STYLE_PROPERTY_INHERIT,
+                                          GTK_CSS_AFFECTS_TEXT | GTK_CSS_AFFECTS_TEXT_ATTRS,
+                                          parse_text_decoration_style,
+                                          NULL,
+                                          NULL,
+                                          _gtk_css_text_decoration_style_value_new (GTK_CSS_TEXT_DECORATION_STYLE_SOLID));
+
   gtk_css_style_property_register        ("text-shadow",
                                           GTK_CSS_PROPERTY_TEXT_SHADOW,
                                           G_TYPE_NONE,
index 5466269084a7106dfc0735cbcc364fa8cd85b965..b3754297ce979a0fbc74d299c2b8b27ca840c070 100644 (file)
@@ -148,6 +148,7 @@ enum { /*< skip >*/
   GTK_CSS_PROPERTY_LETTER_SPACING,
   GTK_CSS_PROPERTY_TEXT_DECORATION_LINE,
   GTK_CSS_PROPERTY_TEXT_DECORATION_COLOR,
+  GTK_CSS_PROPERTY_TEXT_DECORATION_STYLE,
   GTK_CSS_PROPERTY_TEXT_SHADOW,
   GTK_CSS_PROPERTY_BOX_SHADOW,
   GTK_CSS_PROPERTY_MARGIN_TOP,
@@ -273,6 +274,12 @@ typedef enum /*< skip >*/ {
   GTK_CSS_TEXT_DECORATION_LINE_LINE_THROUGH
 } GtkTextDecorationLine;
 
+typedef enum /*< skip >*/ {
+  GTK_CSS_TEXT_DECORATION_STYLE_SOLID,
+  GTK_CSS_TEXT_DECORATION_STYLE_DOUBLE,
+  GTK_CSS_TEXT_DECORATION_STYLE_WAVY
+} GtkTextDecorationStyle;
+
 /* for the order in arrays */
 typedef enum /*< skip >*/ {
   GTK_CSS_TOP,
index 70bc394b20d9546c5fc25ec91977f249d89e0f9a..6c7f1e4fa52822a8dc5d767d1c3dc5375f7ad586 100644 (file)
@@ -3148,6 +3148,23 @@ _gtk_style_context_get_icon_extents (GtkStyleContext *context,
   extents->height += border.top + border.bottom;
 }
 
+static PangoUnderline
+get_pango_underline_from_style (GtkTextDecorationStyle style)
+{
+  switch (style)
+    {
+    case GTK_CSS_TEXT_DECORATION_STYLE_DOUBLE:
+      return PANGO_UNDERLINE_DOUBLE;
+    case GTK_CSS_TEXT_DECORATION_STYLE_WAVY:
+      return PANGO_UNDERLINE_ERROR;
+    case GTK_CSS_TEXT_DECORATION_STYLE_SOLID:
+    default:
+      return PANGO_UNDERLINE_SINGLE;
+    }
+
+  g_return_val_if_reached (PANGO_UNDERLINE_SINGLE);
+}
+
 static PangoAttrList *
 add_pango_attr(PangoAttrList *attrs, PangoAttribute *attr)
 {
@@ -3164,27 +3181,29 @@ _gtk_style_context_get_pango_attributes (GtkStyleContext *context)
 {
   PangoAttrList *attrs = NULL;
   GtkTextDecorationLine decoration_line;
+  GtkTextDecorationStyle decoration_style;
   const GdkRGBA *color;
   const GdkRGBA *decoration_color;
   gint letter_spacing;
 
   /* text-decoration */
   decoration_line = _gtk_css_text_decoration_line_value_get (_gtk_style_context_peek_property (context, GTK_CSS_PROPERTY_TEXT_DECORATION_LINE));
+  decoration_style = _gtk_css_text_decoration_style_value_get (_gtk_style_context_peek_property (context, GTK_CSS_PROPERTY_TEXT_DECORATION_STYLE));
   color = _gtk_css_rgba_value_get_rgba (_gtk_style_context_peek_property (context, GTK_CSS_PROPERTY_COLOR));
   decoration_color = _gtk_css_rgba_value_get_rgba (_gtk_style_context_peek_property (context, GTK_CSS_PROPERTY_TEXT_DECORATION_COLOR));
 
   switch (decoration_line)
     {
     case GTK_CSS_TEXT_DECORATION_LINE_UNDERLINE:
-      attrs = add_pango_attr (attrs, pango_attr_underline_new (PANGO_UNDERLINE_SINGLE));
-      if (!gdk_rgba_equal(color, decoration_color))
+      attrs = add_pango_attr (attrs, pango_attr_underline_new (get_pango_underline_from_style (decoration_style)));
+      if (!gdk_rgba_equal (color, decoration_color))
         attrs = add_pango_attr (attrs, pango_attr_underline_color_new (decoration_color->red * 65535. + 0.5,
                                                                        decoration_color->green * 65535. + 0.5,
                                                                        decoration_color->blue * 65535. + 0.5));
       break;
     case GTK_CSS_TEXT_DECORATION_LINE_LINE_THROUGH:
       attrs = add_pango_attr (attrs, pango_attr_strikethrough_new (TRUE));
-      if (!gdk_rgba_equal(color, decoration_color))
+      if (!gdk_rgba_equal (color, decoration_color))
         attrs = add_pango_attr (attrs, pango_attr_strikethrough_color_new (decoration_color->red * 65535. + 0.5,
                                                                            decoration_color->green * 65535. + 0.5,
                                                                            decoration_color->blue * 65535. + 0.5));