summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPaolo Borelli <pborelli@gnome.org>2015-07-06 20:03:54 +0200
committerPaolo Borelli <pborelli@gnome.org>2015-07-06 20:06:20 +0200
commit1eb1481bdf998383bf3fc58886aff50e2e164d54 (patch)
treeadfc07490e4316f8aa89463d7e8817870fe96add
parent09273d91f3a8b2e8bcbbaf5f8f81e91ff7ca1ea6 (diff)
downloadgtk+-1eb1481bdf998383bf3fc58886aff50e2e164d54.tar.gz
css: support text-decoration-style
The support is limited to underline single, double and wavy, which is what pango has today.
-rw-r--r--gtk/gtkcssenumvalue.c54
-rw-r--r--gtk/gtkcssenumvalueprivate.h4
-rw-r--r--gtk/gtkcssshorthandpropertyimpl.c12
-rw-r--r--gtk/gtkcssstylepropertyimpl.c22
-rw-r--r--gtk/gtkcsstypesprivate.h7
-rw-r--r--gtk/gtkstylecontext.c25
6 files changed, 116 insertions, 8 deletions
diff --git a/gtk/gtkcssenumvalue.c b/gtk/gtkcssenumvalue.c
index 15d9b4af10..a3555acb43 100644
--- a/gtk/gtkcssenumvalue.c
+++ b/gtk/gtkcssenumvalue.c
@@ -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 = {
diff --git a/gtk/gtkcssenumvalueprivate.h b/gtk/gtkcssenumvalueprivate.h
index 008b548adc..6f1efb510a 100644
--- a/gtk/gtkcssenumvalueprivate.h
+++ b/gtk/gtkcssenumvalueprivate.h
@@ -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);
diff --git a/gtk/gtkcssshorthandpropertyimpl.c b/gtk/gtkcssshorthandpropertyimpl.c
index 61afcc6946..7598048956 100644
--- a/gtk/gtkcssshorthandpropertyimpl.c
+++ b/gtk/gtkcssshorthandpropertyimpl.c
@@ -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;
diff --git a/gtk/gtkcssstylepropertyimpl.c b/gtk/gtkcssstylepropertyimpl.c
index 3a5dd8530f..7f2607bcfa 100644
--- a/gtk/gtkcssstylepropertyimpl.c
+++ b/gtk/gtkcssstylepropertyimpl.c
@@ -630,6 +630,18 @@ parse_text_decoration_line (GtkCssStyleProperty *property,
}
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,
diff --git a/gtk/gtkcsstypesprivate.h b/gtk/gtkcsstypesprivate.h
index 5466269084..b3754297ce 100644
--- a/gtk/gtkcsstypesprivate.h
+++ b/gtk/gtkcsstypesprivate.h
@@ -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,
diff --git a/gtk/gtkstylecontext.c b/gtk/gtkstylecontext.c
index 70bc394b20..6c7f1e4fa5 100644
--- a/gtk/gtkstylecontext.c
+++ b/gtk/gtkstylecontext.c
@@ -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));