[gtk+/wip/otte/tokenizer: 28/42] css: Add token parsers for shadows
- From: Benjamin Otte <otte src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gtk+/wip/otte/tokenizer: 28/42] css: Add token parsers for shadows
- Date: Sun, 20 Mar 2016 05:03:23 +0000 (UTC)
commit 6be72dc5746b4c253932a21e4da926d0afb69983
Author: Benjamin Otte <otte redhat com>
Date: Fri Mar 18 03:27:44 2016 +0100
css: Add token parsers for shadows
This also introduces the new idea of check_token() functions. These
functions check if a given function might be the initial token in
parsing a certain value. Implementations for numbers and colors are
included.
gtk/gtkcsscolorvalue.c | 22 ++++++++
gtk/gtkcsscolorvalueprivate.h | 3 +-
gtk/gtkcssnumbervalue.c | 18 +++++++
gtk/gtkcssnumbervalueprivate.h | 1 +
gtk/gtkcssshadowsvalue.c | 42 ++++++++++++++++
gtk/gtkcssshadowsvalueprivate.h | 3 +
gtk/gtkcssshadowvalue.c | 104 +++++++++++++++++++++++++++++++++++++++
gtk/gtkcssshadowvalueprivate.h | 3 +
gtk/gtkcssstylepropertyimpl.c | 20 ++++++-
9 files changed, 212 insertions(+), 4 deletions(-)
---
diff --git a/gtk/gtkcsscolorvalue.c b/gtk/gtkcsscolorvalue.c
index 246592f..37923e9 100644
--- a/gtk/gtkcsscolorvalue.c
+++ b/gtk/gtkcsscolorvalue.c
@@ -919,6 +919,27 @@ parse_percentage (GtkCssTokenSource *source,
}
}
+gboolean
+gtk_css_color_value_check_token (const GtkCssToken *token)
+{
+ GdkRGBA rgba;
+
+ return gtk_css_token_is_ident (token, "currentColor")
+ || gtk_css_token_is_ident (token, "transparent")
+ || gtk_css_token_is_function (token, "rgb")
+ || gtk_css_token_is_function (token, "rgba")
+ || gtk_css_token_is_function (token, "lighter")
+ || gtk_css_token_is_function (token, "darker")
+ || gtk_css_token_is_function (token, "shade")
+ || gtk_css_token_is_function (token, "alpha")
+ || gtk_css_token_is_function (token, "mix")
+ || gtk_css_token_is_function (token, GTK_WIN32_THEME_SYMBOLIC_COLOR_NAME)
+ || gtk_css_token_is (token, GTK_CSS_TOKEN_AT_KEYWORD)
+ || gtk_css_token_is (token, GTK_CSS_TOKEN_HASH_ID)
+ || gtk_css_token_is (token, GTK_CSS_TOKEN_HASH_UNRESTRICTED)
+ || (gtk_css_token_is (token, GTK_CSS_TOKEN_IDENT) && gdk_rgba_parse (&rgba, token->string.string));
+}
+
GtkCssValue *
gtk_css_color_value_token_parse (GtkCssTokenSource *source)
{
@@ -967,6 +988,7 @@ gtk_css_color_value_token_parse (GtkCssTokenSource *source)
if (!parse_number (source, &rgba.red) ||
!parse_comma (source) ||
!parse_number (source, &rgba.green) ||
+ !parse_comma (source) ||
!parse_number (source, &rgba.blue))
return NULL;
rgba.red = CLAMP (rgba.red, 0, 255.0) / 255.0;
diff --git a/gtk/gtkcsscolorvalueprivate.h b/gtk/gtkcsscolorvalueprivate.h
index dc3c645..9e599f1 100644
--- a/gtk/gtkcsscolorvalueprivate.h
+++ b/gtk/gtkcsscolorvalueprivate.h
@@ -42,8 +42,9 @@ GtkCssValue * _gtk_css_color_value_new_win32 (const gchar *theme_c
gint id);
GtkCssValue * _gtk_css_color_value_new_current_color (void);
-GtkCssValue * _gtk_css_color_value_parse (GtkCssParser *parser);
+GtkCssValue * _gtk_css_color_value_parse (GtkCssParser *parser);
GtkCssValue * gtk_css_color_value_token_parse (GtkCssTokenSource *source);
+gboolean gtk_css_color_value_check_token (const GtkCssToken *token);
GtkCssValue * _gtk_css_color_value_resolve (GtkCssValue *color,
GtkStyleProviderPrivate *provider,
diff --git a/gtk/gtkcssnumbervalue.c b/gtk/gtkcssnumbervalue.c
index c31874c..8151dd8 100644
--- a/gtk/gtkcssnumbervalue.c
+++ b/gtk/gtkcssnumbervalue.c
@@ -158,6 +158,24 @@ _gtk_css_number_value_parse (GtkCssParser *parser,
return gtk_css_dimension_value_parse (parser, flags);
}
+gboolean
+gtk_css_number_value_check_token (const GtkCssToken *token)
+{
+ return gtk_css_token_is (token, GTK_CSS_TOKEN_INTEGER)
+ || gtk_css_token_is (token, GTK_CSS_TOKEN_NUMBER)
+ || gtk_css_token_is (token, GTK_CSS_TOKEN_DIMENSION)
+ || gtk_css_token_is (token, GTK_CSS_TOKEN_INTEGER_DIMENSION)
+ || gtk_css_token_is (token, GTK_CSS_TOKEN_PERCENTAGE)
+ || gtk_css_token_is_function (token, "calc")
+ || gtk_css_token_is_function (token, "-gtk-win32-size")
+ || gtk_css_token_is_function (token, "-gtk-win32-part-width")
+ || gtk_css_token_is_function (token, "-gtk-win32-part-height")
+ || gtk_css_token_is_function (token, "-gtk-win32-part-border-top")
+ || gtk_css_token_is_function (token, "-gtk-win32-part-border-left")
+ || gtk_css_token_is_function (token, "-gtk-win32-part-border-bottom")
+ || gtk_css_token_is_function (token, "-gtk-win32-part-border-right");
+}
+
GtkCssValue *
gtk_css_number_value_token_parse (GtkCssTokenSource *source,
GtkCssNumberParseFlags flags)
diff --git a/gtk/gtkcssnumbervalueprivate.h b/gtk/gtkcssnumbervalueprivate.h
index b4cb0ca..4178654 100644
--- a/gtk/gtkcssnumbervalueprivate.h
+++ b/gtk/gtkcssnumbervalueprivate.h
@@ -62,6 +62,7 @@ GtkCssValue * gtk_css_number_value_transition (GtkCssValue *sta
gboolean gtk_css_number_value_can_parse (GtkCssParser *parser);
GtkCssValue * _gtk_css_number_value_parse (GtkCssParser *parser,
GtkCssNumberParseFlags flags);
+gboolean gtk_css_number_value_check_token (const GtkCssToken *token);
GtkCssValue * gtk_css_number_value_token_parse (GtkCssTokenSource *source,
GtkCssNumberParseFlags flags);
diff --git a/gtk/gtkcssshadowsvalue.c b/gtk/gtkcssshadowsvalue.c
index 083b536..87ce81e 100644
--- a/gtk/gtkcssshadowsvalue.c
+++ b/gtk/gtkcssshadowsvalue.c
@@ -240,6 +240,48 @@ _gtk_css_shadows_value_parse (GtkCssParser *parser,
return result;
}
+GtkCssValue *
+gtk_css_shadows_value_token_parse (GtkCssTokenSource *source,
+ gboolean box_shadow_mode)
+{
+ GtkCssValue *value, *result;
+ const GtkCssToken *token;
+ GPtrArray *values;
+
+ token = gtk_css_token_source_get_token (source);
+ if (gtk_css_token_is_ident (token, "none"))
+ {
+ gtk_css_token_source_consume_token (source);
+ return _gtk_css_shadows_value_new_none ();
+ }
+
+ values = g_ptr_array_new ();
+
+ while (TRUE)
+ {
+ value = gtk_css_shadow_value_token_parse (source, box_shadow_mode);
+
+ if (value == NULL)
+ {
+ g_ptr_array_set_free_func (values, (GDestroyNotify) _gtk_css_value_unref);
+ g_ptr_array_free (values, TRUE);
+ return NULL;
+ }
+
+ g_ptr_array_add (values, value);
+ gtk_css_token_source_consume_whitespace (source);
+ token = gtk_css_token_source_get_token (source);
+ if (!gtk_css_token_is (token, GTK_CSS_TOKEN_COMMA))
+ break;
+ gtk_css_token_source_consume_token (source);
+ gtk_css_token_source_consume_whitespace (source);
+ }
+
+ result = gtk_css_shadows_value_new ((GtkCssValue **) values->pdata, values->len);
+ g_ptr_array_free (values, TRUE);
+ return result;
+}
+
gboolean
_gtk_css_shadows_value_is_none (const GtkCssValue *shadows)
{
diff --git a/gtk/gtkcssshadowsvalueprivate.h b/gtk/gtkcssshadowsvalueprivate.h
index 790e8ec..fad8408 100644
--- a/gtk/gtkcssshadowsvalueprivate.h
+++ b/gtk/gtkcssshadowsvalueprivate.h
@@ -25,6 +25,7 @@
#include "gtktypes.h"
#include "gtkcssparserprivate.h"
+#include "gtkcsstokensourceprivate.h"
#include "gtkcssvalueprivate.h"
#include "gtkroundedboxprivate.h"
@@ -33,6 +34,8 @@ G_BEGIN_DECLS
GtkCssValue * _gtk_css_shadows_value_new_none (void);
GtkCssValue * _gtk_css_shadows_value_parse (GtkCssParser *parser,
gboolean box_shadow_mode);
+GtkCssValue * gtk_css_shadows_value_token_parse (GtkCssTokenSource *source,
+ gboolean box_shadow_mode);
gboolean _gtk_css_shadows_value_is_none (const GtkCssValue *shadows);
diff --git a/gtk/gtkcssshadowvalue.c b/gtk/gtkcssshadowvalue.c
index c06de2d..3202584 100644
--- a/gtk/gtkcssshadowvalue.c
+++ b/gtk/gtkcssshadowvalue.c
@@ -293,6 +293,110 @@ fail:
return NULL;
}
+GtkCssValue *
+gtk_css_shadow_value_token_parse (GtkCssTokenSource *source,
+ gboolean box_shadow_mode)
+{
+ enum {
+ HOFFSET,
+ VOFFSET,
+ RADIUS,
+ SPREAD,
+ COLOR,
+ N_VALUES
+ };
+ GtkCssValue *values[N_VALUES] = { NULL, };
+ gboolean inset = FALSE;
+ const GtkCssToken *token;
+ guint i;
+
+ for (token = gtk_css_token_source_get_token (source);
+ !gtk_css_token_is (token, GTK_CSS_TOKEN_EOF);
+ token = gtk_css_token_source_get_token (source))
+ {
+ if (box_shadow_mode && !inset &&
+ gtk_css_token_is_ident (token, "inset"))
+ {
+ inset = TRUE;
+ gtk_css_token_source_consume_token (source);
+ gtk_css_token_source_consume_whitespace (source);
+ }
+ else if (values[COLOR] == NULL && gtk_css_color_value_check_token (token))
+ {
+ values[COLOR] = gtk_css_color_value_token_parse (source);
+ if (values[COLOR] == NULL)
+ goto fail;
+ gtk_css_token_source_consume_whitespace (source);
+ }
+ else if (values[HOFFSET] == NULL && gtk_css_number_value_check_token (token))
+ {
+ values[HOFFSET] = gtk_css_number_value_token_parse (source,
+ GTK_CSS_PARSE_LENGTH
+ | GTK_CSS_NUMBER_AS_PIXELS);
+ if (values[HOFFSET] == NULL)
+ goto fail;
+ gtk_css_token_source_consume_whitespace (source);
+
+ values[VOFFSET] = gtk_css_number_value_token_parse (source,
+ GTK_CSS_PARSE_LENGTH
+ | GTK_CSS_NUMBER_AS_PIXELS);
+ if (values[VOFFSET] == NULL)
+ goto fail;
+ gtk_css_token_source_consume_whitespace (source);
+
+ if (gtk_css_number_value_check_token (gtk_css_token_source_get_token (source)))
+ {
+ values[RADIUS] = gtk_css_number_value_token_parse (source,
+ GTK_CSS_PARSE_LENGTH
+ | GTK_CSS_POSITIVE_ONLY
+ | GTK_CSS_NUMBER_AS_PIXELS);
+ if (values[RADIUS] == NULL)
+ goto fail;
+ gtk_css_token_source_consume_whitespace (source);
+ }
+ else
+ values[RADIUS] = _gtk_css_number_value_new (0.0, GTK_CSS_PX);
+
+ if (box_shadow_mode &&
+ gtk_css_number_value_check_token (gtk_css_token_source_get_token (source)))
+ {
+ values[SPREAD] = gtk_css_number_value_token_parse (source,
+ GTK_CSS_PARSE_LENGTH
+ | GTK_CSS_NUMBER_AS_PIXELS);
+ if (values[SPREAD] == NULL)
+ goto fail;
+ gtk_css_token_source_consume_whitespace (source);
+ }
+ else
+ values[SPREAD] = _gtk_css_number_value_new (0.0, GTK_CSS_PX);
+ }
+ else if (values[HOFFSET] == NULL)
+ {
+ gtk_css_token_source_error (source, "Expected a shadow definition");
+ gtk_css_token_source_consume_all (source);
+ goto fail;
+ }
+ else
+ break;
+ }
+
+ if (values[COLOR] == NULL)
+ values[COLOR] = _gtk_css_color_value_new_current_color ();
+
+ return gtk_css_shadow_value_new (values[HOFFSET], values[VOFFSET],
+ values[RADIUS], values[SPREAD],
+ inset, values[COLOR]);
+
+fail:
+ for (i = 0; i < N_VALUES; i++)
+ {
+ if (values[i])
+ _gtk_css_value_unref (values[i]);
+ }
+
+ return NULL;
+}
+
static gboolean
needs_blur (const GtkCssValue *shadow)
{
diff --git a/gtk/gtkcssshadowvalueprivate.h b/gtk/gtkcssshadowvalueprivate.h
index 5fab1cc..2ca9c7e 100644
--- a/gtk/gtkcssshadowvalueprivate.h
+++ b/gtk/gtkcssshadowvalueprivate.h
@@ -25,6 +25,7 @@
#include "gtktypes.h"
#include "gtkcssparserprivate.h"
+#include "gtkcsstokensourceprivate.h"
#include "gtkcssvalueprivate.h"
#include "gtkroundedboxprivate.h"
@@ -34,6 +35,8 @@ GtkCssValue * _gtk_css_shadow_value_new_for_transition (GtkCssValue
GtkCssValue * _gtk_css_shadow_value_parse (GtkCssParser *parser,
gboolean box_shadow_mode);
+GtkCssValue * gtk_css_shadow_value_token_parse (GtkCssTokenSource *source,
+ gboolean box_shadow_mode);
gboolean _gtk_css_shadow_value_get_inset (const GtkCssValue *shadow);
diff --git a/gtk/gtkcssstylepropertyimpl.c b/gtk/gtkcssstylepropertyimpl.c
index 927613f..9bbc81d 100644
--- a/gtk/gtkcssstylepropertyimpl.c
+++ b/gtk/gtkcssstylepropertyimpl.c
@@ -933,6 +933,13 @@ box_shadow_value_parse (GtkCssStyleProperty *property,
}
static GtkCssValue *
+box_shadow_value_token_parse (GtkCssTokenSource *source,
+ GtkCssStyleProperty *property)
+{
+ return gtk_css_shadows_value_token_parse (source, TRUE);
+}
+
+static GtkCssValue *
shadow_value_parse (GtkCssStyleProperty *property,
GtkCssParser *parser)
{
@@ -940,6 +947,13 @@ shadow_value_parse (GtkCssStyleProperty *property,
}
static GtkCssValue *
+shadow_value_token_parse (GtkCssTokenSource *source,
+ GtkCssStyleProperty *property)
+{
+ return gtk_css_shadows_value_token_parse (source, FALSE);
+}
+
+static GtkCssValue *
transform_value_parse (GtkCssStyleProperty *property,
GtkCssParser *parser)
{
@@ -1612,7 +1626,7 @@ _gtk_css_style_property_init_properties (void)
GTK_STYLE_PROPERTY_INHERIT | GTK_STYLE_PROPERTY_ANIMATED,
GTK_CSS_AFFECTS_TEXT | GTK_CSS_AFFECTS_CLIP,
shadow_value_parse,
- gtk_css_style_property_token_parse_default,
+ shadow_value_token_parse,
NULL,
NULL,
_gtk_css_shadows_value_new_none ());
@@ -1623,7 +1637,7 @@ _gtk_css_style_property_init_properties (void)
GTK_STYLE_PROPERTY_ANIMATED,
GTK_CSS_AFFECTS_BACKGROUND | GTK_CSS_AFFECTS_CLIP,
box_shadow_value_parse,
- gtk_css_style_property_token_parse_default,
+ box_shadow_value_token_parse,
NULL,
NULL,
_gtk_css_shadows_value_new_none ());
@@ -2097,7 +2111,7 @@ _gtk_css_style_property_init_properties (void)
GTK_STYLE_PROPERTY_INHERIT | GTK_STYLE_PROPERTY_ANIMATED,
GTK_CSS_AFFECTS_ICON | GTK_CSS_AFFECTS_SYMBOLIC_ICON |
GTK_CSS_AFFECTS_CLIP,
shadow_value_parse,
- gtk_css_style_property_token_parse_default,
+ shadow_value_token_parse,
NULL,
NULL,
_gtk_css_shadows_value_new_none ());
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]