From 0a11e4d36bcb3cb94d8993151c69f87ac031f220 Mon Sep 17 00:00:00 2001 From: Benjamin Otte Date: Wed, 16 Mar 2016 00:45:59 +0100 Subject: [PATCH] css: Add token parsing for colors ... and add infrastructure to use it to longhand properties. --- gtk/gtkcsscolorvalue.c | 347 ++++++++++++++++++++++++++++++++++ gtk/gtkcsscolorvalueprivate.h | 2 + gtk/gtkcssstylepropertyimpl.c | 111 ++++++++++- gtk/gtkcsstokenizer.c | 8 + gtk/gtkcsstokenizerprivate.h | 2 + gtk/gtkwin32theme.c | 20 ++ gtk/gtkwin32themeprivate.h | 2 + 7 files changed, 483 insertions(+), 9 deletions(-) diff --git a/gtk/gtkcsscolorvalue.c b/gtk/gtkcsscolorvalue.c index 0224018d40..246592fa7f 100644 --- a/gtk/gtkcsscolorvalue.c +++ b/gtk/gtkcsscolorvalue.c @@ -860,3 +860,350 @@ _gtk_css_color_value_parse (GtkCssParser *parser) return NULL; } +static gboolean +parse_comma (GtkCssTokenSource *source) +{ + gtk_css_token_source_consume_whitespace (source); + if (!gtk_css_token_is (gtk_css_token_source_get_token (source), GTK_CSS_TOKEN_COMMA)) + { + gtk_css_token_source_error (source, "Expected ','"); + gtk_css_token_source_consume_all (source); + return FALSE; + } + + gtk_css_token_source_consume_token (source); + gtk_css_token_source_consume_whitespace (source); + return TRUE; +} + +static gboolean +parse_number (GtkCssTokenSource *source, + double *d) +{ + const GtkCssToken *token; + + token = gtk_css_token_source_get_token (source); + if (gtk_css_token_is (token, GTK_CSS_TOKEN_INTEGER) || + gtk_css_token_is (token, GTK_CSS_TOKEN_NUMBER)) + { + *d = token->number.number; + gtk_css_token_source_consume_token (source); + return TRUE; + } + else + { + gtk_css_token_source_error (source, "Expected a number."); + gtk_css_token_source_consume_all (source); + return FALSE; + } +} + +static gboolean +parse_percentage (GtkCssTokenSource *source, + double *d) +{ + const GtkCssToken *token; + + token = gtk_css_token_source_get_token (source); + if (gtk_css_token_is (token, GTK_CSS_TOKEN_PERCENTAGE)) + { + *d = token->number.number; + gtk_css_token_source_consume_token (source); + return TRUE; + } + else + { + gtk_css_token_source_error (source, "Expected a percentage."); + gtk_css_token_source_consume_all (source); + return FALSE; + } +} + +GtkCssValue * +gtk_css_color_value_token_parse (GtkCssTokenSource *source) +{ + const GtkCssToken *token; + GtkCssValue *value; + + token = gtk_css_token_source_get_token (source); + if (gtk_css_token_is_ident (token, "currentColor")) + { + value = _gtk_css_color_value_new_current_color (); + gtk_css_token_source_consume_token (source); + } + else if (gtk_css_token_is_ident (token, "transparent")) + { + GdkRGBA transparent = { 0, 0, 0, 0 }; + + value = _gtk_css_color_value_new_literal (&transparent); + gtk_css_token_source_consume_token (source); + } + else if (gtk_css_token_is (token, GTK_CSS_TOKEN_FUNCTION)) + { + if (gtk_css_token_is_function (token, "rgb") || + gtk_css_token_is_function (token, "rgba")) + { + gboolean has_alpha = gtk_css_token_is_function (token, "rgba"); + GdkRGBA rgba; + + gtk_css_token_source_consume_token (source); + gtk_css_token_source_consume_whitespace (source); + + token = gtk_css_token_source_get_token (source); + if (gtk_css_token_is (token, GTK_CSS_TOKEN_PERCENTAGE)) + { + if (!parse_percentage (source, &rgba.red) || + !parse_comma (source) || + !parse_percentage (source, &rgba.green) || + !parse_comma (source) || + !parse_percentage (source, &rgba.blue)) + return NULL; + rgba.red = CLAMP (rgba.red, 0, 100.0) / 100.0; + rgba.green = CLAMP (rgba.green, 0, 100.0) / 100.0; + rgba.blue = CLAMP (rgba.blue, 0, 100.0) / 100.0; + } + else + { + if (!parse_number (source, &rgba.red) || + !parse_comma (source) || + !parse_number (source, &rgba.green) || + !parse_number (source, &rgba.blue)) + return NULL; + rgba.red = CLAMP (rgba.red, 0, 255.0) / 255.0; + rgba.green = CLAMP (rgba.green, 0, 255.0) / 255.0; + rgba.blue = CLAMP (rgba.blue, 0, 255.0) / 255.0; + } + + if (has_alpha) + { + if (!parse_comma (source) || + !parse_number (source, &rgba.alpha)) + return NULL; + rgba.alpha = CLAMP (rgba.alpha, 0, 1.0); + } + else + rgba.alpha = 1.0; + + value = _gtk_css_color_value_new_literal (&rgba); + } + else if (gtk_css_token_is_function (token, "lighter")) + { + GtkCssValue *child; + + gtk_css_token_source_consume_token (source); + gtk_css_token_source_consume_whitespace (source); + + child = gtk_css_color_value_token_parse (source); + if (child == NULL) + return NULL; + + value = _gtk_css_color_value_new_shade (child, 1.3); + + _gtk_css_value_unref (child); + } + else if (gtk_css_token_is_function (token, "darker")) + { + GtkCssValue *child; + + gtk_css_token_source_consume_token (source); + gtk_css_token_source_consume_whitespace (source); + + child = gtk_css_color_value_token_parse (source); + if (child == NULL) + return NULL; + + value = _gtk_css_color_value_new_shade (child, 0.7); + + _gtk_css_value_unref (child); + } + else if (gtk_css_token_is_function (token, "shade")) + { + GtkCssValue *child; + double d; + + gtk_css_token_source_consume_token (source); + gtk_css_token_source_consume_whitespace (source); + + child = gtk_css_color_value_token_parse (source); + if (child == NULL) + return NULL; + if (!parse_comma (source) || + !parse_number (source, &d)) + { + _gtk_css_value_unref (child); + return NULL; + } + + value = _gtk_css_color_value_new_shade (child, d); + + _gtk_css_value_unref (child); + } + else if (gtk_css_token_is_function (token, "alpha")) + { + GtkCssValue *child; + double d; + + gtk_css_token_source_consume_token (source); + gtk_css_token_source_consume_whitespace (source); + + child = gtk_css_color_value_token_parse (source); + if (child == NULL) + return NULL; + if (!parse_comma (source) || + !parse_number (source, &d)) + { + _gtk_css_value_unref (child); + return NULL; + } + + value = _gtk_css_color_value_new_alpha (child, d); + + _gtk_css_value_unref (child); + } + else if (gtk_css_token_is_function (token, "mix")) + { + GtkCssValue *child1, *child2; + double d; + + gtk_css_token_source_consume_token (source); + gtk_css_token_source_consume_whitespace (source); + + child1 = gtk_css_color_value_token_parse (source); + if (child1 == NULL) + return NULL; + if (!parse_comma (source) || + !(child2 = gtk_css_color_value_token_parse (source))) + { + _gtk_css_value_unref (child1); + return NULL; + } + if (!parse_comma (source) || + !parse_number (source, &d)) + { + _gtk_css_value_unref (child1); + _gtk_css_value_unref (child2); + return NULL; + } + value = _gtk_css_color_value_new_mix (child1, child2, d); + _gtk_css_value_unref (child1); + _gtk_css_value_unref (child2); + } + else if (gtk_css_token_is_function (token, GTK_WIN32_THEME_SYMBOLIC_COLOR_NAME)) + { + GtkWin32Theme *theme; + int id; + + gtk_css_token_source_consume_token (source); + gtk_css_token_source_consume_whitespace (source); + + theme = gtk_win32_theme_token_parse (source); + if (theme == NULL) + return NULL; + + if (!parse_comma (source)) + { + gtk_win32_theme_unref (theme); + return NULL; + } + + token = gtk_css_token_source_get_token (source); + if (gtk_css_token_is (token, GTK_CSS_TOKEN_IDENT)) + { + id = gtk_win32_get_sys_color_id_for_name (token->string.string); + if (id == -1) + { + gtk_css_token_source_error (source, "'%s' is not a win32 color name.", token->string.string); + gtk_css_token_source_consume_all (source); + return NULL; + } + gtk_css_token_source_consume_token (source); + } + else if (gtk_css_token_is (token, GTK_CSS_TOKEN_INTEGER)) + { + id = token->number.number; + gtk_css_token_source_consume_token (source); + } + else + { + gtk_css_token_source_error (source, "Expected a valid integer value"); + gtk_css_token_source_consume_all (source); + gtk_win32_theme_unref (theme); + return NULL; + } + + value = gtk_css_color_value_new_win32_for_theme (theme, id); + gtk_win32_theme_unref (theme); + } + + gtk_css_token_source_consume_whitespace (source); + token = gtk_css_token_source_get_token (source); + if (!gtk_css_token_is (token, GTK_CSS_TOKEN_CLOSE_PARENS)) + { + gtk_css_token_source_error (source, "No closing ')' in color definition"); + gtk_css_token_source_consume_all (source); + return NULL; + } + gtk_css_token_source_consume_token (source); + } + else if (gtk_css_token_is (token, GTK_CSS_TOKEN_AT_KEYWORD)) + { + value = _gtk_css_color_value_new_name (token->string.string); + gtk_css_token_source_consume_token (source); + } + else if (gtk_css_token_is (token, GTK_CSS_TOKEN_HASH_ID) || + gtk_css_token_is (token, GTK_CSS_TOKEN_HASH_UNRESTRICTED)) + { + GdkRGBA rgba; + const char *s = token->string.string; + + if (g_ascii_isxdigit (s[0]) && g_ascii_isxdigit (s[1]) && g_ascii_isxdigit (s[2]) && s[3] == '\0') + { + rgba.red = g_ascii_xdigit_value(s[0]) / 15.0; + rgba.green = g_ascii_xdigit_value(s[1]) / 15.0; + rgba.blue = g_ascii_xdigit_value(s[2]) / 15.0; + rgba.alpha = 1.0; + } + else if (g_ascii_isxdigit (s[0]) && g_ascii_isxdigit (s[1]) && g_ascii_isxdigit (s[2]) && + g_ascii_isxdigit (s[3]) && g_ascii_isxdigit (s[4]) && g_ascii_isxdigit (s[5]) && + s[6] == '\0') + { + rgba.red = (g_ascii_xdigit_value(s[0]) * 16 + g_ascii_xdigit_value(s[1])) / 255.0; + rgba.green = (g_ascii_xdigit_value(s[2]) * 16 + g_ascii_xdigit_value(s[3])) / 255.0; + rgba.blue = (g_ascii_xdigit_value(s[4]) * 16 + g_ascii_xdigit_value(s[5])) / 255.0; + rgba.alpha = 1.0; + } + else + { + gtk_css_token_source_error (source, "Not a valid color value, needs to be #RGB or #RRGGBB"); + gtk_css_token_source_consume_all (source); + return NULL; + } + value = _gtk_css_color_value_new_literal (&rgba); + gtk_css_token_source_consume_token (source); + } + else if (gtk_css_token_is (token, GTK_CSS_TOKEN_IDENT)) + { + GdkRGBA rgba; + const char *name = token->string.string; + + if (!gdk_rgba_parse (&rgba, name)) + { + gtk_css_token_source_error (source, "'%s' is not a valid color name", name); + gtk_css_token_source_consume_all (source); + return NULL; + } + + value = _gtk_css_color_value_new_literal (&rgba); + gtk_css_token_source_consume_token (source); + } + else + { + gtk_css_token_source_error (source, "Not a color definition"); + gtk_css_token_source_consume_all (source); + return NULL; + } + + return value; + + return NULL; +} diff --git a/gtk/gtkcsscolorvalueprivate.h b/gtk/gtkcsscolorvalueprivate.h index b80d52100d..dc3c645196 100644 --- a/gtk/gtkcsscolorvalueprivate.h +++ b/gtk/gtkcsscolorvalueprivate.h @@ -19,6 +19,7 @@ #define __GTK_CSS_COLOR_VALUE_PRIVATE_H__ #include "gtkcssparserprivate.h" +#include "gtkcsstokensourceprivate.h" #include "gtkcssvalueprivate.h" G_BEGIN_DECLS @@ -42,6 +43,7 @@ GtkCssValue * _gtk_css_color_value_new_win32 (const gchar *theme_c GtkCssValue * _gtk_css_color_value_new_current_color (void); GtkCssValue * _gtk_css_color_value_parse (GtkCssParser *parser); +GtkCssValue * gtk_css_color_value_token_parse (GtkCssTokenSource *source); GtkCssValue * _gtk_css_color_value_resolve (GtkCssValue *color, GtkStyleProviderPrivate *provider, diff --git a/gtk/gtkcssstylepropertyimpl.c b/gtk/gtkcssstylepropertyimpl.c index 850206e004..4a4f1fed91 100644 --- a/gtk/gtkcssstylepropertyimpl.c +++ b/gtk/gtkcssstylepropertyimpl.c @@ -72,15 +72,16 @@ typedef enum { } GtkStylePropertyFlags; static void -gtk_css_style_property_register (const char * name, - guint expected_id, - GType value_type, - GtkStylePropertyFlags flags, - GtkCssAffects affects, - GtkCssStylePropertyParseFunc parse_value, - GtkCssStylePropertyQueryFunc query_value, - GtkCssStylePropertyAssignFunc assign_value, - GtkCssValue * initial_value) +gtk_css_style_property_register (const char * name, + guint expected_id, + GType value_type, + GtkStylePropertyFlags flags, + GtkCssAffects affects, + GtkCssStylePropertyParseFunc parse_value, + GtkCssStylePropertyTokenParseFunc token_parse_value, + GtkCssStylePropertyQueryFunc query_value, + GtkCssStylePropertyAssignFunc assign_value, + GtkCssValue * initial_value) { GtkCssStyleProperty *node; @@ -99,6 +100,8 @@ gtk_css_style_property_register (const char * name, NULL); node->parse_value = parse_value; + if (token_parse_value) + node->token_parse = token_parse_value; node->query_value = query_value; node->assign_value = assign_value; @@ -180,6 +183,13 @@ color_parse (GtkCssStyleProperty *property, return _gtk_css_color_value_parse (parser); } +static GtkCssValue * +color_token_parse (GtkCssStyleProperty *property, + GtkCssTokenSource *source) +{ + return gtk_css_color_value_token_parse (source); +} + static void color_query (GtkCssStyleProperty *property, const GtkCssValue *css_value, @@ -1030,6 +1040,7 @@ _gtk_css_style_property_init_properties (void) GTK_STYLE_PROPERTY_INHERIT | GTK_STYLE_PROPERTY_ANIMATED, GTK_CSS_AFFECTS_FOREGROUND | GTK_CSS_AFFECTS_TEXT | GTK_CSS_AFFECTS_SYMBOLIC_ICON, color_parse, + color_token_parse, color_query, color_assign, _gtk_css_color_value_new_rgba (1, 1, 1, 1)); @@ -1041,6 +1052,7 @@ _gtk_css_style_property_init_properties (void) dpi_parse, NULL, NULL, + NULL, _gtk_css_number_value_new (96.0, GTK_CSS_NUMBER)); gtk_css_style_property_register ("font-size", GTK_CSS_PROPERTY_FONT_SIZE, @@ -1048,6 +1060,7 @@ _gtk_css_style_property_init_properties (void) GTK_STYLE_PROPERTY_INHERIT | GTK_STYLE_PROPERTY_ANIMATED, GTK_CSS_AFFECTS_FONT | GTK_CSS_AFFECTS_TEXT | GTK_CSS_AFFECTS_SIZE, font_size_parse, + NULL, query_length_as_double, assign_length_from_double, _gtk_css_font_size_value_new (GTK_CSS_FONT_SIZE_MEDIUM)); @@ -1059,6 +1072,7 @@ _gtk_css_style_property_init_properties (void) icon_theme_value_parse, NULL, NULL, + NULL, gtk_css_icon_theme_value_new (NULL)); gtk_css_style_property_register ("-gtk-icon-palette", GTK_CSS_PROPERTY_ICON_PALETTE, @@ -1066,6 +1080,7 @@ _gtk_css_style_property_init_properties (void) GTK_STYLE_PROPERTY_ANIMATED | GTK_STYLE_PROPERTY_INHERIT, GTK_CSS_AFFECTS_SYMBOLIC_ICON, icon_palette_parse, + NULL, NULL, NULL, gtk_css_palette_value_new_default ()); @@ -1079,6 +1094,7 @@ _gtk_css_style_property_init_properties (void) GTK_STYLE_PROPERTY_ANIMATED, GTK_CSS_AFFECTS_BACKGROUND, color_parse, + color_token_parse, color_query, color_assign, _gtk_css_color_value_new_rgba (0, 0, 0, 0)); @@ -1089,6 +1105,7 @@ _gtk_css_style_property_init_properties (void) GTK_STYLE_PROPERTY_INHERIT, GTK_CSS_AFFECTS_FONT | GTK_CSS_AFFECTS_TEXT, font_family_parse, + NULL, font_family_query, font_family_assign, _gtk_css_array_value_new (_gtk_css_string_value_new ("Sans"))); @@ -1098,6 +1115,7 @@ _gtk_css_style_property_init_properties (void) GTK_STYLE_PROPERTY_INHERIT, GTK_CSS_AFFECTS_FONT | GTK_CSS_AFFECTS_TEXT, parse_pango_style, + NULL, query_pango_style, assign_pango_style, _gtk_css_font_style_value_new (PANGO_STYLE_NORMAL)); @@ -1107,6 +1125,7 @@ _gtk_css_style_property_init_properties (void) GTK_STYLE_PROPERTY_INHERIT, GTK_CSS_AFFECTS_FONT | GTK_CSS_AFFECTS_TEXT, parse_pango_variant, + NULL, query_pango_variant, assign_pango_variant, _gtk_css_font_variant_value_new (PANGO_VARIANT_NORMAL)); @@ -1116,6 +1135,7 @@ _gtk_css_style_property_init_properties (void) GTK_STYLE_PROPERTY_INHERIT | GTK_STYLE_PROPERTY_ANIMATED, GTK_CSS_AFFECTS_FONT | GTK_CSS_AFFECTS_TEXT, parse_pango_weight, + NULL, query_pango_weight, assign_pango_weight, _gtk_css_font_weight_value_new (PANGO_WEIGHT_NORMAL)); @@ -1125,6 +1145,7 @@ _gtk_css_style_property_init_properties (void) GTK_STYLE_PROPERTY_INHERIT, GTK_CSS_AFFECTS_FONT | GTK_CSS_AFFECTS_TEXT, parse_pango_stretch, + NULL, query_pango_stretch, assign_pango_stretch, _gtk_css_font_stretch_value_new (PANGO_STRETCH_NORMAL)); @@ -1137,6 +1158,7 @@ _gtk_css_style_property_init_properties (void) parse_letter_spacing, NULL, NULL, + NULL, _gtk_css_number_value_new (0.0, GTK_CSS_PX)); gtk_css_style_property_register ("text-decoration-line", @@ -1147,6 +1169,7 @@ _gtk_css_style_property_init_properties (void) parse_text_decoration_line, NULL, NULL, + NULL, _gtk_css_text_decoration_line_value_new (GTK_CSS_TEXT_DECORATION_LINE_NONE)); gtk_css_style_property_register ("text-decoration-color", GTK_CSS_PROPERTY_TEXT_DECORATION_COLOR, @@ -1154,6 +1177,7 @@ _gtk_css_style_property_init_properties (void) GTK_STYLE_PROPERTY_ANIMATED, GTK_CSS_AFFECTS_TEXT | GTK_CSS_AFFECTS_TEXT_ATTRS, color_parse, + color_token_parse, NULL, NULL, _gtk_css_color_value_new_current_color ()); @@ -1165,6 +1189,7 @@ _gtk_css_style_property_init_properties (void) parse_text_decoration_style, NULL, NULL, + NULL, _gtk_css_text_decoration_style_value_new (GTK_CSS_TEXT_DECORATION_STYLE_SOLID)); gtk_css_style_property_register ("text-shadow", @@ -1175,6 +1200,7 @@ _gtk_css_style_property_init_properties (void) shadow_value_parse, NULL, NULL, + NULL, _gtk_css_shadows_value_new_none ()); gtk_css_style_property_register ("box-shadow", @@ -1185,6 +1211,7 @@ _gtk_css_style_property_init_properties (void) box_shadow_value_parse, NULL, NULL, + NULL, _gtk_css_shadows_value_new_none ()); gtk_css_style_property_register ("margin-top", @@ -1193,6 +1220,7 @@ _gtk_css_style_property_init_properties (void) GTK_STYLE_PROPERTY_ANIMATED, GTK_CSS_AFFECTS_SIZE, parse_margin, + NULL, query_length_as_int, assign_length_from_int, _gtk_css_number_value_new (0.0, GTK_CSS_PX)); @@ -1202,6 +1230,7 @@ _gtk_css_style_property_init_properties (void) GTK_STYLE_PROPERTY_ANIMATED, GTK_CSS_AFFECTS_SIZE, parse_margin, + NULL, query_length_as_int, assign_length_from_int, _gtk_css_number_value_new (0.0, GTK_CSS_PX)); @@ -1211,6 +1240,7 @@ _gtk_css_style_property_init_properties (void) GTK_STYLE_PROPERTY_ANIMATED, GTK_CSS_AFFECTS_SIZE, parse_margin, + NULL, query_length_as_int, assign_length_from_int, _gtk_css_number_value_new (0.0, GTK_CSS_PX)); @@ -1220,6 +1250,7 @@ _gtk_css_style_property_init_properties (void) GTK_STYLE_PROPERTY_ANIMATED, GTK_CSS_AFFECTS_SIZE, parse_margin, + NULL, query_length_as_int, assign_length_from_int, _gtk_css_number_value_new (0.0, GTK_CSS_PX)); @@ -1229,6 +1260,7 @@ _gtk_css_style_property_init_properties (void) GTK_STYLE_PROPERTY_ANIMATED, GTK_CSS_AFFECTS_SIZE, parse_padding, + NULL, query_length_as_int, assign_length_from_int, _gtk_css_number_value_new (0.0, GTK_CSS_PX)); @@ -1238,6 +1270,7 @@ _gtk_css_style_property_init_properties (void) GTK_STYLE_PROPERTY_ANIMATED, GTK_CSS_AFFECTS_SIZE, parse_padding, + NULL, query_length_as_int, assign_length_from_int, _gtk_css_number_value_new (0.0, GTK_CSS_PX)); @@ -1247,6 +1280,7 @@ _gtk_css_style_property_init_properties (void) GTK_STYLE_PROPERTY_ANIMATED, GTK_CSS_AFFECTS_SIZE, parse_padding, + NULL, query_length_as_int, assign_length_from_int, _gtk_css_number_value_new (0.0, GTK_CSS_PX)); @@ -1256,6 +1290,7 @@ _gtk_css_style_property_init_properties (void) GTK_STYLE_PROPERTY_ANIMATED, GTK_CSS_AFFECTS_SIZE, parse_padding, + NULL, query_length_as_int, assign_length_from_int, _gtk_css_number_value_new (0.0, GTK_CSS_PX)); @@ -1268,6 +1303,7 @@ _gtk_css_style_property_init_properties (void) 0, GTK_CSS_AFFECTS_BORDER, parse_border_style, + NULL, query_border_style, assign_border_style, _gtk_css_border_style_value_new (GTK_BORDER_STYLE_NONE)); @@ -1277,6 +1313,7 @@ _gtk_css_style_property_init_properties (void) GTK_STYLE_PROPERTY_ANIMATED, GTK_CSS_AFFECTS_BORDER | GTK_CSS_AFFECTS_SIZE, parse_border_width, + NULL, query_length_as_int, assign_length_from_int, _gtk_css_number_value_new (0.0, GTK_CSS_PX)); @@ -1286,6 +1323,7 @@ _gtk_css_style_property_init_properties (void) 0, GTK_CSS_AFFECTS_BORDER, parse_border_style, + NULL, query_border_style, assign_border_style, _gtk_css_border_style_value_new (GTK_BORDER_STYLE_NONE)); @@ -1295,6 +1333,7 @@ _gtk_css_style_property_init_properties (void) GTK_STYLE_PROPERTY_ANIMATED, GTK_CSS_AFFECTS_BORDER | GTK_CSS_AFFECTS_SIZE, parse_border_width, + NULL, query_length_as_int, assign_length_from_int, _gtk_css_number_value_new (0.0, GTK_CSS_PX)); @@ -1304,6 +1343,7 @@ _gtk_css_style_property_init_properties (void) 0, GTK_CSS_AFFECTS_BORDER, parse_border_style, + NULL, query_border_style, assign_border_style, _gtk_css_border_style_value_new (GTK_BORDER_STYLE_NONE)); @@ -1313,6 +1353,7 @@ _gtk_css_style_property_init_properties (void) GTK_STYLE_PROPERTY_ANIMATED, GTK_CSS_AFFECTS_BORDER | GTK_CSS_AFFECTS_SIZE, parse_border_width, + NULL, query_length_as_int, assign_length_from_int, _gtk_css_number_value_new (0.0, GTK_CSS_PX)); @@ -1322,6 +1363,7 @@ _gtk_css_style_property_init_properties (void) 0, GTK_CSS_AFFECTS_BORDER, parse_border_style, + NULL, query_border_style, assign_border_style, _gtk_css_border_style_value_new (GTK_BORDER_STYLE_NONE)); @@ -1331,6 +1373,7 @@ _gtk_css_style_property_init_properties (void) GTK_STYLE_PROPERTY_ANIMATED, GTK_CSS_AFFECTS_BORDER | GTK_CSS_AFFECTS_SIZE, parse_border_width, + NULL, query_length_as_int, assign_length_from_int, _gtk_css_number_value_new (0.0, GTK_CSS_PX)); @@ -1343,6 +1386,7 @@ _gtk_css_style_property_init_properties (void) border_corner_radius_value_parse, NULL, NULL, + NULL, _gtk_css_corner_value_new (_gtk_css_number_value_new (0, GTK_CSS_PX), _gtk_css_number_value_new (0, GTK_CSS_PX))); gtk_css_style_property_register ("border-top-right-radius", @@ -1353,6 +1397,7 @@ _gtk_css_style_property_init_properties (void) border_corner_radius_value_parse, NULL, NULL, + NULL, _gtk_css_corner_value_new (_gtk_css_number_value_new (0, GTK_CSS_PX), _gtk_css_number_value_new (0, GTK_CSS_PX))); gtk_css_style_property_register ("border-bottom-right-radius", @@ -1363,6 +1408,7 @@ _gtk_css_style_property_init_properties (void) border_corner_radius_value_parse, NULL, NULL, + NULL, _gtk_css_corner_value_new (_gtk_css_number_value_new (0, GTK_CSS_PX), _gtk_css_number_value_new (0, GTK_CSS_PX))); gtk_css_style_property_register ("border-bottom-left-radius", @@ -1373,6 +1419,7 @@ _gtk_css_style_property_init_properties (void) border_corner_radius_value_parse, NULL, NULL, + NULL, _gtk_css_corner_value_new (_gtk_css_number_value_new (0, GTK_CSS_PX), _gtk_css_number_value_new (0, GTK_CSS_PX))); @@ -1382,6 +1429,7 @@ _gtk_css_style_property_init_properties (void) 0, GTK_CSS_AFFECTS_OUTLINE | GTK_CSS_AFFECTS_CLIP, parse_border_style, + NULL, query_border_style, assign_border_style, _gtk_css_border_style_value_new (GTK_BORDER_STYLE_NONE)); @@ -1391,6 +1439,7 @@ _gtk_css_style_property_init_properties (void) GTK_STYLE_PROPERTY_ANIMATED, GTK_CSS_AFFECTS_OUTLINE | GTK_CSS_AFFECTS_CLIP, parse_border_width, + NULL, query_length_as_int, assign_length_from_int, _gtk_css_number_value_new (0.0, GTK_CSS_PX)); @@ -1400,6 +1449,7 @@ _gtk_css_style_property_init_properties (void) GTK_STYLE_PROPERTY_ANIMATED, GTK_CSS_AFFECTS_OUTLINE | GTK_CSS_AFFECTS_CLIP, outline_parse, + NULL, query_length_as_int, assign_length_from_int, _gtk_css_number_value_new (0.0, GTK_CSS_PX)); @@ -1412,6 +1462,7 @@ _gtk_css_style_property_init_properties (void) border_corner_radius_value_parse, NULL, NULL, + NULL, _gtk_css_corner_value_new (_gtk_css_number_value_new (0, GTK_CSS_PX), _gtk_css_number_value_new (0, GTK_CSS_PX))); _gtk_style_property_add_alias ("-gtk-outline-top-left-radius", "outline-top-left-radius"); @@ -1423,6 +1474,7 @@ _gtk_css_style_property_init_properties (void) border_corner_radius_value_parse, NULL, NULL, + NULL, _gtk_css_corner_value_new (_gtk_css_number_value_new (0, GTK_CSS_PX), _gtk_css_number_value_new (0, GTK_CSS_PX))); _gtk_style_property_add_alias ("-gtk-outline-top-right-radius", "outline-top-right-radius"); @@ -1434,6 +1486,7 @@ _gtk_css_style_property_init_properties (void) border_corner_radius_value_parse, NULL, NULL, + NULL, _gtk_css_corner_value_new (_gtk_css_number_value_new (0, GTK_CSS_PX), _gtk_css_number_value_new (0, GTK_CSS_PX))); _gtk_style_property_add_alias ("-gtk-outline-bottom-right-radius", "outline-bottom-right-radius"); @@ -1445,6 +1498,7 @@ _gtk_css_style_property_init_properties (void) border_corner_radius_value_parse, NULL, NULL, + NULL, _gtk_css_corner_value_new (_gtk_css_number_value_new (0, GTK_CSS_PX), _gtk_css_number_value_new (0, GTK_CSS_PX))); _gtk_style_property_add_alias ("-gtk-outline-bottom-left-radius", "outline-bottom-left-radius"); @@ -1457,6 +1511,7 @@ _gtk_css_style_property_init_properties (void) parse_css_area, NULL, NULL, + NULL, _gtk_css_array_value_new (_gtk_css_area_value_new (GTK_CSS_AREA_BORDER_BOX))); gtk_css_style_property_register ("background-origin", GTK_CSS_PROPERTY_BACKGROUND_ORIGIN, @@ -1466,6 +1521,7 @@ _gtk_css_style_property_init_properties (void) parse_css_area, NULL, NULL, + NULL, _gtk_css_array_value_new (_gtk_css_area_value_new (GTK_CSS_AREA_PADDING_BOX))); gtk_css_style_property_register ("background-size", GTK_CSS_PROPERTY_BACKGROUND_SIZE, @@ -1475,6 +1531,7 @@ _gtk_css_style_property_init_properties (void) background_size_parse, NULL, NULL, + NULL, _gtk_css_array_value_new (_gtk_css_bg_size_value_new (NULL, NULL))); gtk_css_style_property_register ("background-position", GTK_CSS_PROPERTY_BACKGROUND_POSITION, @@ -1484,6 +1541,7 @@ _gtk_css_style_property_init_properties (void) background_position_parse, NULL, NULL, + NULL, _gtk_css_array_value_new (_gtk_css_position_value_new (_gtk_css_number_value_new (0, GTK_CSS_PERCENT), _gtk_css_number_value_new (0, GTK_CSS_PERCENT)))); @@ -1493,6 +1551,7 @@ _gtk_css_style_property_init_properties (void) GTK_STYLE_PROPERTY_ANIMATED, GTK_CSS_AFFECTS_BORDER, color_parse, + color_token_parse, color_query, color_assign, _gtk_css_color_value_new_current_color ()); @@ -1502,6 +1561,7 @@ _gtk_css_style_property_init_properties (void) GTK_STYLE_PROPERTY_ANIMATED, GTK_CSS_AFFECTS_BORDER, color_parse, + color_token_parse, color_query, color_assign, _gtk_css_color_value_new_current_color ()); @@ -1511,6 +1571,7 @@ _gtk_css_style_property_init_properties (void) GTK_STYLE_PROPERTY_ANIMATED, GTK_CSS_AFFECTS_BORDER, color_parse, + color_token_parse, color_query, color_assign, _gtk_css_color_value_new_current_color ()); @@ -1520,6 +1581,7 @@ _gtk_css_style_property_init_properties (void) GTK_STYLE_PROPERTY_ANIMATED, GTK_CSS_AFFECTS_BORDER, color_parse, + color_token_parse, color_query, color_assign, _gtk_css_color_value_new_current_color ()); @@ -1529,6 +1591,7 @@ _gtk_css_style_property_init_properties (void) GTK_STYLE_PROPERTY_ANIMATED, GTK_CSS_AFFECTS_OUTLINE, color_parse, + color_token_parse, color_query, color_assign, _gtk_css_color_value_new_current_color ()); @@ -1541,6 +1604,7 @@ _gtk_css_style_property_init_properties (void) background_repeat_value_parse, NULL, NULL, + NULL, _gtk_css_array_value_new (_gtk_css_background_repeat_value_new (GTK_CSS_REPEAT_STYLE_REPEAT, GTK_CSS_REPEAT_STYLE_REPEAT))); gtk_css_style_property_register ("background-image", @@ -1549,6 +1613,7 @@ _gtk_css_style_property_init_properties (void) GTK_STYLE_PROPERTY_ANIMATED, GTK_CSS_AFFECTS_BACKGROUND, background_image_value_parse, + NULL, background_image_value_query, background_image_value_assign, _gtk_css_array_value_new (_gtk_css_image_value_new (NULL))); @@ -1559,6 +1624,7 @@ _gtk_css_style_property_init_properties (void) GTK_STYLE_PROPERTY_ANIMATED, GTK_CSS_AFFECTS_BORDER, css_image_value_parse, + NULL, css_image_value_query, css_image_value_assign, _gtk_css_image_value_new (NULL)); @@ -1570,6 +1636,7 @@ _gtk_css_style_property_init_properties (void) border_image_repeat_parse, NULL, NULL, + NULL, _gtk_css_border_repeat_value_new (GTK_CSS_REPEAT_STYLE_STRETCH, GTK_CSS_REPEAT_STYLE_STRETCH)); @@ -1579,6 +1646,7 @@ _gtk_css_style_property_init_properties (void) 0, GTK_CSS_AFFECTS_BORDER, border_image_slice_parse, + NULL, query_border, assign_border, _gtk_css_border_value_new (_gtk_css_number_value_new (100, GTK_CSS_PERCENT), @@ -1591,6 +1659,7 @@ _gtk_css_style_property_init_properties (void) 0, GTK_CSS_AFFECTS_BORDER, border_image_width_parse, + NULL, query_border, assign_border, _gtk_css_border_value_new (_gtk_css_number_value_new (1, GTK_CSS_NUMBER), @@ -1606,6 +1675,7 @@ _gtk_css_style_property_init_properties (void) css_image_value_parse_with_builtin, NULL, NULL, + NULL, _gtk_css_image_value_new (gtk_css_image_builtin_new ())); gtk_css_style_property_register ("-gtk-icon-shadow", GTK_CSS_PROPERTY_ICON_SHADOW, @@ -1615,6 +1685,7 @@ _gtk_css_style_property_init_properties (void) shadow_value_parse, NULL, NULL, + NULL, _gtk_css_shadows_value_new_none ()); _gtk_style_property_add_alias ("-gtk-icon-shadow", "icon-shadow"); gtk_css_style_property_register ("-gtk-icon-style", @@ -1625,6 +1696,7 @@ _gtk_css_style_property_init_properties (void) icon_style_parse, NULL, NULL, + NULL, _gtk_css_icon_style_value_new (GTK_CSS_ICON_STYLE_REQUESTED)); gtk_css_style_property_register ("-gtk-icon-transform", GTK_CSS_PROPERTY_ICON_TRANSFORM, @@ -1634,6 +1706,7 @@ _gtk_css_style_property_init_properties (void) transform_value_parse, NULL, NULL, + NULL, _gtk_css_transform_value_new_none ()); gtk_css_style_property_register ("min-width", @@ -1642,6 +1715,7 @@ _gtk_css_style_property_init_properties (void) GTK_STYLE_PROPERTY_ANIMATED, GTK_CSS_AFFECTS_SIZE, minmax_parse, + NULL, query_length_as_int, NULL, _gtk_css_number_value_new (0, GTK_CSS_PX)); @@ -1651,6 +1725,7 @@ _gtk_css_style_property_init_properties (void) GTK_STYLE_PROPERTY_ANIMATED, GTK_CSS_AFFECTS_SIZE, minmax_parse, + NULL, query_length_as_int, NULL, _gtk_css_number_value_new (0, GTK_CSS_PX)); @@ -1663,6 +1738,7 @@ _gtk_css_style_property_init_properties (void) transition_property_parse, NULL, NULL, + NULL, _gtk_css_array_value_new (_gtk_css_ident_value_new ("all"))); gtk_css_style_property_register ("transition-duration", GTK_CSS_PROPERTY_TRANSITION_DURATION, @@ -1672,6 +1748,7 @@ _gtk_css_style_property_init_properties (void) transition_time_parse, NULL, NULL, + NULL, _gtk_css_array_value_new (_gtk_css_number_value_new (0, GTK_CSS_S))); gtk_css_style_property_register ("transition-timing-function", GTK_CSS_PROPERTY_TRANSITION_TIMING_FUNCTION, @@ -1681,6 +1758,7 @@ _gtk_css_style_property_init_properties (void) transition_timing_function_parse, NULL, NULL, + NULL, _gtk_css_array_value_new ( _gtk_css_ease_value_new_cubic_bezier (0.25, 0.1, 0.25, 1.0))); gtk_css_style_property_register ("transition-delay", @@ -1691,6 +1769,7 @@ _gtk_css_style_property_init_properties (void) transition_time_parse, NULL, NULL, + NULL, _gtk_css_array_value_new (_gtk_css_number_value_new (0, GTK_CSS_S))); gtk_css_style_property_register ("animation-name", @@ -1701,6 +1780,7 @@ _gtk_css_style_property_init_properties (void) transition_property_parse, NULL, NULL, + NULL, _gtk_css_array_value_new (_gtk_css_ident_value_new ("none"))); gtk_css_style_property_register ("animation-duration", GTK_CSS_PROPERTY_ANIMATION_DURATION, @@ -1710,6 +1790,7 @@ _gtk_css_style_property_init_properties (void) transition_time_parse, NULL, NULL, + NULL, _gtk_css_array_value_new (_gtk_css_number_value_new (0, GTK_CSS_S))); gtk_css_style_property_register ("animation-timing-function", GTK_CSS_PROPERTY_ANIMATION_TIMING_FUNCTION, @@ -1719,6 +1800,7 @@ _gtk_css_style_property_init_properties (void) transition_timing_function_parse, NULL, NULL, + NULL, _gtk_css_array_value_new ( _gtk_css_ease_value_new_cubic_bezier (0.25, 0.1, 0.25, 1.0))); gtk_css_style_property_register ("animation-iteration-count", @@ -1729,6 +1811,7 @@ _gtk_css_style_property_init_properties (void) iteration_count_parse, NULL, NULL, + NULL, _gtk_css_array_value_new (_gtk_css_number_value_new (1, GTK_CSS_NUMBER))); gtk_css_style_property_register ("animation-direction", GTK_CSS_PROPERTY_ANIMATION_DIRECTION, @@ -1738,6 +1821,7 @@ _gtk_css_style_property_init_properties (void) parse_css_direction, NULL, NULL, + NULL, _gtk_css_array_value_new (_gtk_css_direction_value_new (GTK_CSS_DIRECTION_NORMAL))); gtk_css_style_property_register ("animation-play-state", GTK_CSS_PROPERTY_ANIMATION_PLAY_STATE, @@ -1747,6 +1831,7 @@ _gtk_css_style_property_init_properties (void) parse_css_play_state, NULL, NULL, + NULL, _gtk_css_array_value_new (_gtk_css_play_state_value_new (GTK_CSS_PLAY_STATE_RUNNING))); gtk_css_style_property_register ("animation-delay", GTK_CSS_PROPERTY_ANIMATION_DELAY, @@ -1756,6 +1841,7 @@ _gtk_css_style_property_init_properties (void) transition_time_parse, NULL, NULL, + NULL, _gtk_css_array_value_new (_gtk_css_number_value_new (0, GTK_CSS_S))); gtk_css_style_property_register ("animation-fill-mode", GTK_CSS_PROPERTY_ANIMATION_FILL_MODE, @@ -1765,6 +1851,7 @@ _gtk_css_style_property_init_properties (void) parse_css_fill_mode, NULL, NULL, + NULL, _gtk_css_array_value_new (_gtk_css_fill_mode_value_new (GTK_CSS_FILL_NONE))); gtk_css_style_property_register ("opacity", @@ -1773,6 +1860,7 @@ _gtk_css_style_property_init_properties (void) GTK_STYLE_PROPERTY_ANIMATED, 0, opacity_parse, + NULL, opacity_query, NULL, _gtk_css_number_value_new (1, GTK_CSS_NUMBER)); @@ -1782,6 +1870,7 @@ _gtk_css_style_property_init_properties (void) GTK_STYLE_PROPERTY_INHERIT, GTK_CSS_AFFECTS_ICON, image_effect_parse, + NULL, NULL, NULL, _gtk_css_icon_effect_value_new (GTK_CSS_ICON_EFFECT_NONE)); @@ -1794,6 +1883,7 @@ G_GNUC_BEGIN_IGNORE_DEPRECATIONS 0, 0, engine_parse, + NULL, engine_query, engine_assign, _gtk_css_engine_value_new (gtk_theming_engine_load (NULL))); @@ -1806,6 +1896,7 @@ G_GNUC_END_IGNORE_DEPRECATIONS 0, 0, bindings_value_parse, + NULL, bindings_value_query, bindings_value_assign, _gtk_css_array_value_new (_gtk_css_string_value_new (NULL))); @@ -1817,6 +1908,7 @@ G_GNUC_END_IGNORE_DEPRECATIONS GTK_STYLE_PROPERTY_INHERIT | GTK_STYLE_PROPERTY_ANIMATED, GTK_CSS_AFFECTS_TEXT, color_parse, + color_token_parse, color_query, color_assign, _gtk_css_color_value_new_current_color ()); @@ -1826,6 +1918,7 @@ G_GNUC_END_IGNORE_DEPRECATIONS GTK_STYLE_PROPERTY_INHERIT | GTK_STYLE_PROPERTY_ANIMATED, GTK_CSS_AFFECTS_TEXT, color_parse, + color_token_parse, color_query, color_assign, _gtk_css_color_value_new_current_color ()); diff --git a/gtk/gtkcsstokenizer.c b/gtk/gtkcsstokenizer.c index e26e70d5eb..35fb51b7a3 100644 --- a/gtk/gtkcsstokenizer.c +++ b/gtk/gtkcsstokenizer.c @@ -246,6 +246,14 @@ gtk_css_token_is_ident (const GtkCssToken *token, && (g_ascii_strcasecmp (token->string.string, ident) == 0); } +gboolean +gtk_css_token_is_function (const GtkCssToken *token, + const char *ident) +{ + return gtk_css_token_is (token, GTK_CSS_TOKEN_FUNCTION) + && (g_ascii_strcasecmp (token->string.string, ident) == 0); +} + gboolean gtk_css_token_is_delim (const GtkCssToken *token, gunichar delim) diff --git a/gtk/gtkcsstokenizerprivate.h b/gtk/gtkcsstokenizerprivate.h index 4dba797b4f..1f178af2fc 100644 --- a/gtk/gtkcsstokenizerprivate.h +++ b/gtk/gtkcsstokenizerprivate.h @@ -113,6 +113,8 @@ gboolean gtk_css_token_is_finite (const GtkCssTok #define gtk_css_token_is(token, _type) ((token)->type == (_type)) gboolean gtk_css_token_is_ident (const GtkCssToken *token, const char *ident); +gboolean gtk_css_token_is_function (const GtkCssToken *token, + const char *ident); gboolean gtk_css_token_is_delim (const GtkCssToken *token, gunichar delim); diff --git a/gtk/gtkwin32theme.c b/gtk/gtkwin32theme.c index 3861e507d4..e8dcdf336c 100644 --- a/gtk/gtkwin32theme.c +++ b/gtk/gtkwin32theme.c @@ -307,6 +307,26 @@ gtk_win32_theme_parse (GtkCssParser *parser) return theme; } +GtkWin32Theme * +gtk_win32_theme_token_parse (GtkCssTokenSource *source) +{ + GtkWin32Theme *theme; + const GtkCssToken *token; + + token = gtk_css_token_source_get_token (source); + if (!gtk_css_token_is (token, GTK_CSS_TOKEN_IDENT)) + { + gtk_css_token_source_error (source, "Expected valid win32 theme name"); + gtk_css_token_source_consume_all (source); + return NULL; + } + + theme = gtk_win32_theme_lookup (token->string.string); + gtk_css_token_source_consume_token (source); + + return theme; +} + cairo_surface_t * gtk_win32_theme_create_surface (GtkWin32Theme *theme, int xp_part, diff --git a/gtk/gtkwin32themeprivate.h b/gtk/gtkwin32themeprivate.h index 9ea7777366..81b768e4da 100644 --- a/gtk/gtkwin32themeprivate.h +++ b/gtk/gtkwin32themeprivate.h @@ -21,6 +21,7 @@ #define __GTK_WIN32_THEME_PART_H__ #include "gtkcssparserprivate.h" +#include "gtkcsstokensourceprivate.h" G_BEGIN_DECLS @@ -30,6 +31,7 @@ typedef struct _GtkWin32Theme GtkWin32Theme; GtkWin32Theme * gtk_win32_theme_lookup (const char *class_name); GtkWin32Theme * gtk_win32_theme_parse (GtkCssParser *parser); +GtkWin32Theme * gtk_win32_theme_token_parse (GtkCssTokenSource *source); GtkWin32Theme * gtk_win32_theme_ref (GtkWin32Theme *theme); void gtk_win32_theme_unref (GtkWin32Theme *theme);