[gtk+/wip/otte/tokenizer: 18/78] css: Add token parsing for number values
- From: Benjamin Otte <otte src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gtk+/wip/otte/tokenizer: 18/78] css: Add token parsing for number values
- Date: Fri, 25 Nov 2016 22:39:09 +0000 (UTC)
commit b9c77aadec24a1eab82c2f9c9e7c85cbd62b4c44
Author: Benjamin Otte <otte redhat com>
Date: Thu Mar 17 00:36:51 2016 +0100
css: Add token parsing for number values
This includes calc() and the win32 number values.
CSS properties using just <length>, <angle>, <time>, <percentage> or
<number> have been converted.
gtk/gtkcsscalcvalue.c | 214 +++++++++++++++++++++++++++++++++++++
gtk/gtkcsscalcvalueprivate.h | 2 +
gtk/gtkcssdimensionvalue.c | 109 +++++++++++++++++++
gtk/gtkcssdimensionvalueprivate.h | 3 +
gtk/gtkcssnumbervalue.c | 20 ++++
gtk/gtkcssnumbervalueprivate.h | 3 +
gtk/gtkcssstylepropertyimpl.c | 106 +++++++++++++++----
gtk/gtkcsswin32sizevalue.c | 158 ++++++++++++++++++++++++++--
gtk/gtkcsswin32sizevalueprivate.h | 2 +
9 files changed, 590 insertions(+), 27 deletions(-)
---
diff --git a/gtk/gtkcsscalcvalue.c b/gtk/gtkcsscalcvalue.c
index 2004fba..4c9d79d 100644
--- a/gtk/gtkcsscalcvalue.c
+++ b/gtk/gtkcsscalcvalue.c
@@ -485,3 +485,217 @@ gtk_css_calc_value_parse (GtkCssParser *parser,
return value;
}
+GtkCssValue * gtk_css_calc_value_token_parse_sum (GtkCssTokenSource *source,
+ GtkCssNumberParseFlags flags);
+
+GtkCssValue *
+gtk_css_calc_value_token_parse_value (GtkCssTokenSource *source,
+ GtkCssNumberParseFlags flags)
+{
+ const GtkCssToken *token;
+ GtkCssValue *result;
+
+ token = gtk_css_token_source_get_token (source);
+
+ if (gtk_css_token_is_function (token, "calc"))
+ {
+ gtk_css_token_source_error (source, "Nested calc() expressions are not allowed.");
+ gtk_css_token_source_consume_all (source);
+ return NULL;
+ }
+ else if (gtk_css_token_is (token, GTK_CSS_TOKEN_OPEN_PARENS))
+ {
+ gtk_css_token_source_consume_token (source);
+ gtk_css_token_source_consume_whitespace (source);
+
+ result = gtk_css_calc_value_token_parse_sum (source, flags);
+ if (result == NULL)
+ return NULL;
+
+ 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, "Missing closing ')' in calc() subterm");
+ gtk_css_token_source_consume_all (source);
+ _gtk_css_value_unref (result);
+ return NULL;
+ }
+
+ gtk_css_token_source_consume_token (source);
+ gtk_css_token_source_consume_whitespace (source);
+
+ return result;
+ }
+ else
+ {
+ result = gtk_css_number_value_token_parse (source, flags);
+ if (result == NULL)
+ return NULL;
+
+ gtk_css_token_source_consume_whitespace (source);
+ }
+
+ return result;
+}
+
+GtkCssValue *
+gtk_css_calc_value_token_parse_product (GtkCssTokenSource *source,
+ GtkCssNumberParseFlags flags)
+{
+ GtkCssValue *result, *value, *temp;
+ GtkCssNumberParseFlags actual_flags;
+
+ actual_flags = flags | GTK_CSS_PARSE_NUMBER;
+
+ result = gtk_css_calc_value_token_parse_value (source, actual_flags);
+ if (result == NULL)
+ return NULL;
+
+ while (TRUE)
+ {
+ const GtkCssToken *token = gtk_css_token_source_get_token (source);
+
+ if (actual_flags != GTK_CSS_PARSE_NUMBER && !is_number (result))
+ actual_flags = GTK_CSS_PARSE_NUMBER;
+
+ if (gtk_css_token_is_delim (token, '*'))
+ {
+ gtk_css_token_source_consume_token (source);
+ gtk_css_token_source_consume_whitespace (source);
+
+ value = gtk_css_calc_value_token_parse_product (source, actual_flags);
+ if (value == NULL)
+ goto fail;
+ if (is_number (value))
+ temp = gtk_css_number_value_multiply (result, _gtk_css_number_value_get (value, 100));
+ else
+ temp = gtk_css_number_value_multiply (value, _gtk_css_number_value_get (result, 100));
+ _gtk_css_value_unref (value);
+ _gtk_css_value_unref (result);
+ result = temp;
+ }
+ else if (gtk_css_token_is_delim (token, '/'))
+ {
+ gtk_css_token_source_consume_token (source);
+ gtk_css_token_source_consume_whitespace (source);
+
+ value = gtk_css_calc_value_token_parse_product (source, GTK_CSS_PARSE_NUMBER);
+ if (value == NULL)
+ goto fail;
+ temp = gtk_css_number_value_multiply (result, 1.0 / _gtk_css_number_value_get (value, 100));
+ _gtk_css_value_unref (value);
+ _gtk_css_value_unref (result);
+ result = temp;
+ }
+ else
+ {
+ break;
+ }
+ }
+
+ if (is_number (result) && !(flags & GTK_CSS_PARSE_NUMBER))
+ {
+ gtk_css_token_source_error (source, "calc() product term has no units");
+ gtk_css_token_source_consume_all (source);
+ goto fail;
+ }
+
+ return result;
+
+fail:
+ _gtk_css_value_unref (result);
+ return NULL;
+}
+
+GtkCssValue *
+gtk_css_calc_value_token_parse_sum (GtkCssTokenSource *source,
+ GtkCssNumberParseFlags flags)
+{
+ GtkCssValue *result;
+ const GtkCssToken *token;
+
+ result = gtk_css_calc_value_token_parse_product (source, flags);
+ if (result == NULL)
+ return NULL;
+
+ while (TRUE)
+ {
+ GtkCssValue *next, *temp;
+
+ token = gtk_css_token_source_get_token (source);
+ if (gtk_css_token_is_delim (token, '+'))
+ {
+ gtk_css_token_source_consume_token (source);
+ gtk_css_token_source_consume_whitespace (source);
+
+ next = gtk_css_calc_value_token_parse_product (source, flags);
+ if (next == NULL)
+ goto fail;
+ }
+ else if (gtk_css_token_is_delim (token, '-'))
+ {
+ gtk_css_token_source_consume_token (source);
+ gtk_css_token_source_consume_whitespace (source);
+
+ temp = gtk_css_calc_value_token_parse_product (source, flags);
+ if (temp == NULL)
+ goto fail;
+ next = gtk_css_number_value_multiply (temp, -1);
+ _gtk_css_value_unref (temp);
+ }
+ else
+ {
+ break;
+ }
+
+ temp = gtk_css_number_value_add (result, next);
+ _gtk_css_value_unref (result);
+ _gtk_css_value_unref (next);
+ result = temp;
+ }
+
+ return result;
+
+fail:
+ _gtk_css_value_unref (result);
+ return NULL;
+}
+
+GtkCssValue *
+gtk_css_calc_value_token_parse (GtkCssTokenSource *source,
+ GtkCssNumberParseFlags flags)
+{
+ const GtkCssToken *token;
+ GtkCssValue *value;
+
+ /* This confuses '*' and '/' so we disallow backwards compat. */
+ flags &= ~GTK_CSS_NUMBER_AS_PIXELS;
+ /* This can only be handled at compute time, we allow negative numbers everywhere */
+ flags &= ~GTK_CSS_POSITIVE_ONLY;
+
+ token = gtk_css_token_source_get_token (source);
+ if (!gtk_css_token_is_function (token, "calc"))
+ {
+ gtk_css_token_source_error (source, "Expected 'calc('");
+ gtk_css_token_source_consume_all (source);
+ return NULL;
+ }
+ gtk_css_token_source_consume_token (source);
+ gtk_css_token_source_consume_whitespace (source);
+
+ value = gtk_css_calc_value_token_parse_sum (source, flags);
+ if (value == NULL)
+ return NULL;
+
+ token = gtk_css_token_source_get_token (source);
+ if (!gtk_css_token_is (token, GTK_CSS_TOKEN_CLOSE_PARENS))
+ {
+ _gtk_css_value_unref (value);
+ gtk_css_token_source_error (source, "Expected ')' after calc() statement");
+ gtk_css_token_source_consume_all (source);
+ return NULL;
+ }
+ gtk_css_token_source_consume_token (source);
+
+ return value;
+}
diff --git a/gtk/gtkcsscalcvalueprivate.h b/gtk/gtkcsscalcvalueprivate.h
index 2d11315..cd70553 100644
--- a/gtk/gtkcsscalcvalueprivate.h
+++ b/gtk/gtkcsscalcvalueprivate.h
@@ -27,6 +27,8 @@ GtkCssValue * gtk_css_calc_value_new_sum (GtkCssValue *val
GtkCssValue * gtk_css_calc_value_parse (GtkCssParser *parser,
GtkCssNumberParseFlags flags);
+GtkCssValue * gtk_css_calc_value_token_parse (GtkCssTokenSource *source,
+ GtkCssNumberParseFlags flags);
G_END_DECLS
diff --git a/gtk/gtkcssdimensionvalue.c b/gtk/gtkcssdimensionvalue.c
index 92c2d99..22365c4 100644
--- a/gtk/gtkcssdimensionvalue.c
+++ b/gtk/gtkcssdimensionvalue.c
@@ -323,3 +323,112 @@ gtk_css_dimension_value_new (double value,
return result;
}
+GtkCssValue *
+gtk_css_dimension_value_token_parse (GtkCssTokenSource *source,
+ GtkCssNumberParseFlags flags)
+{
+ const GtkCssToken *token = gtk_css_token_source_get_token (source);
+ double d;
+ GtkCssUnit unit;
+
+ if ((gtk_css_token_is (token, GTK_CSS_TOKEN_INTEGER) ||
+ gtk_css_token_is (token, GTK_CSS_TOKEN_NUMBER)) &&
+ ((flags & (GTK_CSS_PARSE_NUMBER | GTK_CSS_NUMBER_AS_PIXELS)) ||
+ (token->number.number == 0.0 && (flags & (GTK_CSS_PARSE_LENGTH | GTK_CSS_PARSE_ANGLE)))))
+ {
+ d = token->number.number;
+ if (flags & GTK_CSS_NUMBER_AS_PIXELS)
+ {
+ if (d != 0.0)
+ gtk_css_token_source_deprecated (source, "Not using units is deprecated. Assuming 'px'.");
+ unit = GTK_CSS_PX;
+ }
+ else
+ {
+ if (flags & GTK_CSS_PARSE_NUMBER)
+ unit = GTK_CSS_NUMBER;
+ else if (flags & GTK_CSS_PARSE_LENGTH)
+ unit = GTK_CSS_PX;
+ else if (flags & GTK_CSS_PARSE_ANGLE)
+ unit = GTK_CSS_DEG;
+ }
+ }
+ else if (gtk_css_token_is (token, GTK_CSS_TOKEN_PERCENTAGE) &&
+ (flags & GTK_CSS_PARSE_PERCENT))
+ {
+ d = token->number.number;
+ unit = GTK_CSS_PERCENT;
+ }
+ else if (gtk_css_token_is (token, GTK_CSS_TOKEN_INTEGER_DIMENSION) ||
+ gtk_css_token_is (token, GTK_CSS_TOKEN_DIMENSION))
+ {
+ static const struct {
+ const char *name;
+ GtkCssUnit unit;
+ GtkCssNumberParseFlags flag;
+ } units[] = {
+ { "px", GTK_CSS_PX, GTK_CSS_PARSE_LENGTH },
+ { "pt", GTK_CSS_PT, GTK_CSS_PARSE_LENGTH },
+ { "em", GTK_CSS_EM, GTK_CSS_PARSE_LENGTH },
+ { "ex", GTK_CSS_EX, GTK_CSS_PARSE_LENGTH },
+ { "rem", GTK_CSS_REM, GTK_CSS_PARSE_LENGTH },
+ { "pc", GTK_CSS_PC, GTK_CSS_PARSE_LENGTH },
+ { "in", GTK_CSS_IN, GTK_CSS_PARSE_LENGTH },
+ { "cm", GTK_CSS_CM, GTK_CSS_PARSE_LENGTH },
+ { "mm", GTK_CSS_MM, GTK_CSS_PARSE_LENGTH },
+ { "rad", GTK_CSS_RAD, GTK_CSS_PARSE_ANGLE },
+ { "deg", GTK_CSS_DEG, GTK_CSS_PARSE_ANGLE },
+ { "grad", GTK_CSS_GRAD, GTK_CSS_PARSE_ANGLE },
+ { "turn", GTK_CSS_TURN, GTK_CSS_PARSE_ANGLE },
+ { "s", GTK_CSS_S, GTK_CSS_PARSE_TIME },
+ { "ms", GTK_CSS_MS, GTK_CSS_PARSE_TIME }
+ };
+ guint i;
+
+ for (i = 0; i < G_N_ELEMENTS (units); i++)
+ {
+ if ((flags & units[i].flag) == 0)
+ continue;
+
+ if (g_ascii_strcasecmp (units[i].name, token->dimension.dimension) == 0)
+ {
+ d = token->dimension.value;
+ unit = units[i].unit;
+ break;
+ }
+ }
+
+ if (i == G_N_ELEMENTS (units))
+ {
+ gtk_css_token_source_error (source, "'%s' is not a valid unit.", token->dimension.dimension);
+ gtk_css_token_source_consume_all (source);
+ return NULL;
+ }
+ }
+ else
+ {
+ if (flags & GTK_CSS_PARSE_LENGTH)
+ gtk_css_token_source_error (source, "Expected a length");
+ else if (flags & GTK_CSS_PARSE_ANGLE)
+ gtk_css_token_source_error (source, "Expected an angle");
+ else if (flags & GTK_CSS_PARSE_TIME)
+ gtk_css_token_source_error (source, "Expected a time");
+ else if (flags & GTK_CSS_PARSE_PERCENT)
+ gtk_css_token_source_error (source, "Expected a percentage");
+ else
+ gtk_css_token_source_error (source, "Expected a number");
+ gtk_css_token_source_consume_all (source);
+ return NULL;
+ }
+
+ if ((flags & GTK_CSS_POSITIVE_ONLY) && d < 0.0)
+ {
+ gtk_css_token_source_error (source, "Negative values are not allowed");
+ gtk_css_token_source_consume_all (source);
+ return NULL;
+ }
+
+ gtk_css_token_source_consume_token (source);
+ return gtk_css_dimension_value_new (d, unit);
+}
+
diff --git a/gtk/gtkcssdimensionvalueprivate.h b/gtk/gtkcssdimensionvalueprivate.h
index 2e08eba..5a9bf97 100644
--- a/gtk/gtkcssdimensionvalueprivate.h
+++ b/gtk/gtkcssdimensionvalueprivate.h
@@ -30,6 +30,9 @@ GtkCssValue * gtk_css_dimension_value_new (double val
GtkCssValue * gtk_css_dimension_value_parse (GtkCssParser *parser,
GtkCssNumberParseFlags flags);
+GtkCssValue * gtk_css_dimension_value_token_parse (GtkCssTokenSource *source,
+ GtkCssNumberParseFlags flags);
+
G_END_DECLS
#endif /* __GTK_CSS_DIMENSION_VALUE_PRIVATE_H__ */
diff --git a/gtk/gtkcssnumbervalue.c b/gtk/gtkcssnumbervalue.c
index 54e1d1c..c31874c 100644
--- a/gtk/gtkcssnumbervalue.c
+++ b/gtk/gtkcssnumbervalue.c
@@ -158,6 +158,26 @@ _gtk_css_number_value_parse (GtkCssParser *parser,
return gtk_css_dimension_value_parse (parser, flags);
}
+GtkCssValue *
+gtk_css_number_value_token_parse (GtkCssTokenSource *source,
+ GtkCssNumberParseFlags flags)
+{
+ const GtkCssToken *token = gtk_css_token_source_get_token (source);
+
+ if (gtk_css_token_is_function (token, "calc"))
+ return gtk_css_calc_value_token_parse (source, flags);
+ else if (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"))
+ return gtk_css_win32_size_value_token_parse (source, flags);
+ else
+ return gtk_css_dimension_value_token_parse (source, flags);
+}
+
double
_gtk_css_number_value_get (const GtkCssValue *number,
double one_hundred_percent)
diff --git a/gtk/gtkcssnumbervalueprivate.h b/gtk/gtkcssnumbervalueprivate.h
index ddded66..b4cb0ca 100644
--- a/gtk/gtkcssnumbervalueprivate.h
+++ b/gtk/gtkcssnumbervalueprivate.h
@@ -21,6 +21,7 @@
#define __GTK_CSS_NUMBER_VALUE_PRIVATE_H__
#include "gtkcssparserprivate.h"
+#include "gtkcsstokensourceprivate.h"
#include "gtkcsstypesprivate.h"
#include "gtkcssvalueprivate.h"
@@ -61,6 +62,8 @@ 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);
+GtkCssValue * gtk_css_number_value_token_parse (GtkCssTokenSource *source,
+ GtkCssNumberParseFlags flags);
GtkCssDimension gtk_css_number_value_get_dimension (const GtkCssValue *value);
gboolean gtk_css_number_value_has_percent (const GtkCssValue *value);
diff --git a/gtk/gtkcssstylepropertyimpl.c b/gtk/gtkcssstylepropertyimpl.c
index 3c896bd..27918ea 100644
--- a/gtk/gtkcssstylepropertyimpl.c
+++ b/gtk/gtkcssstylepropertyimpl.c
@@ -488,6 +488,13 @@ opacity_parse (GtkCssStyleProperty *property,
return _gtk_css_number_value_parse (parser, GTK_CSS_PARSE_NUMBER);
}
+static GtkCssValue *
+opacity_token_parse (GtkCssTokenSource *source,
+ GtkCssStyleProperty *property)
+{
+ return gtk_css_number_value_token_parse (source, GTK_CSS_PARSE_NUMBER);
+}
+
static void
opacity_query (GtkCssStyleProperty *property,
const GtkCssValue *css_value,
@@ -666,6 +673,13 @@ parse_letter_spacing (GtkCssStyleProperty *property,
}
static GtkCssValue *
+token_parse_letter_spacing (GtkCssTokenSource *source,
+ GtkCssStyleProperty *property)
+{
+ return gtk_css_number_value_token_parse (source, GTK_CSS_PARSE_LENGTH);
+}
+
+static GtkCssValue *
parse_text_decoration_line (GtkCssStyleProperty *property,
GtkCssParser *parser)
{
@@ -818,6 +832,13 @@ dpi_parse (GtkCssStyleProperty *property,
}
static GtkCssValue *
+dpi_token_parse (GtkCssTokenSource *source,
+ GtkCssStyleProperty *property)
+{
+ return gtk_css_number_value_token_parse (source, GTK_CSS_PARSE_NUMBER);
+}
+
+static GtkCssValue *
font_size_parse (GtkCssStyleProperty *property,
GtkCssParser *parser)
{
@@ -844,6 +865,15 @@ outline_parse (GtkCssStyleProperty *property,
}
static GtkCssValue *
+outline_token_parse (GtkCssTokenSource *source,
+ GtkCssStyleProperty *property)
+{
+ return gtk_css_number_value_token_parse (source,
+ GTK_CSS_NUMBER_AS_PIXELS
+ | GTK_CSS_PARSE_LENGTH);
+}
+
+static GtkCssValue *
border_image_repeat_parse (GtkCssStyleProperty *property,
GtkCssParser *parser)
{
@@ -893,6 +923,15 @@ minmax_parse (GtkCssStyleProperty *property,
}
static GtkCssValue *
+minmax_token_parse (GtkCssTokenSource *source,
+ GtkCssStyleProperty *property)
+{
+ return gtk_css_number_value_token_parse (source,
+ GTK_CSS_PARSE_LENGTH
+ | GTK_CSS_POSITIVE_ONLY);
+}
+
+static GtkCssValue *
transition_property_parse_one (GtkCssParser *parser)
{
GtkCssValue *value;
@@ -986,6 +1025,15 @@ parse_margin (GtkCssStyleProperty *property,
}
static GtkCssValue *
+token_parse_margin (GtkCssTokenSource *source,
+ GtkCssStyleProperty *property)
+{
+ return gtk_css_number_value_token_parse (source,
+ GTK_CSS_NUMBER_AS_PIXELS
+ | GTK_CSS_PARSE_LENGTH);
+}
+
+static GtkCssValue *
parse_padding (GtkCssStyleProperty *property,
GtkCssParser *parser)
{
@@ -996,6 +1044,16 @@ parse_padding (GtkCssStyleProperty *property,
}
static GtkCssValue *
+token_parse_padding (GtkCssTokenSource *source,
+ GtkCssStyleProperty *property)
+{
+ return gtk_css_number_value_token_parse (source,
+ GTK_CSS_POSITIVE_ONLY
+ | GTK_CSS_NUMBER_AS_PIXELS
+ | GTK_CSS_PARSE_LENGTH);
+}
+
+static GtkCssValue *
parse_border_width (GtkCssStyleProperty *property,
GtkCssParser *parser)
{
@@ -1006,6 +1064,16 @@ parse_border_width (GtkCssStyleProperty *property,
}
static GtkCssValue *
+token_parse_border_width (GtkCssTokenSource *source,
+ GtkCssStyleProperty *property)
+{
+ return gtk_css_number_value_token_parse (source,
+ GTK_CSS_POSITIVE_ONLY
+ | GTK_CSS_NUMBER_AS_PIXELS
+ | GTK_CSS_PARSE_LENGTH);
+}
+
+static GtkCssValue *
background_repeat_value_parse_one (GtkCssParser *parser)
{
GtkCssValue *value = _gtk_css_background_repeat_value_try_parse (parser);
@@ -1072,7 +1140,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,
dpi_parse,
- gtk_css_style_property_token_parse_default,
+ dpi_token_parse,
NULL,
NULL,
_gtk_css_number_value_new (96.0, GTK_CSS_NUMBER));
@@ -1178,7 +1246,7 @@ _gtk_css_style_property_init_properties (void)
GTK_STYLE_PROPERTY_INHERIT | GTK_STYLE_PROPERTY_ANIMATED,
GTK_CSS_AFFECTS_TEXT | GTK_CSS_AFFECTS_TEXT_ATTRS,
parse_letter_spacing,
- gtk_css_style_property_token_parse_default,
+ token_parse_letter_spacing,
NULL,
NULL,
_gtk_css_number_value_new (0.0, GTK_CSS_PX));
@@ -1242,7 +1310,7 @@ _gtk_css_style_property_init_properties (void)
GTK_STYLE_PROPERTY_ANIMATED,
GTK_CSS_AFFECTS_SIZE,
parse_margin,
- gtk_css_style_property_token_parse_default,
+ token_parse_margin,
query_length_as_int,
assign_length_from_int,
_gtk_css_number_value_new (0.0, GTK_CSS_PX));
@@ -1252,7 +1320,7 @@ _gtk_css_style_property_init_properties (void)
GTK_STYLE_PROPERTY_ANIMATED,
GTK_CSS_AFFECTS_SIZE,
parse_margin,
- gtk_css_style_property_token_parse_default,
+ token_parse_margin,
query_length_as_int,
assign_length_from_int,
_gtk_css_number_value_new (0.0, GTK_CSS_PX));
@@ -1262,7 +1330,7 @@ _gtk_css_style_property_init_properties (void)
GTK_STYLE_PROPERTY_ANIMATED,
GTK_CSS_AFFECTS_SIZE,
parse_margin,
- gtk_css_style_property_token_parse_default,
+ token_parse_margin,
query_length_as_int,
assign_length_from_int,
_gtk_css_number_value_new (0.0, GTK_CSS_PX));
@@ -1272,7 +1340,7 @@ _gtk_css_style_property_init_properties (void)
GTK_STYLE_PROPERTY_ANIMATED,
GTK_CSS_AFFECTS_SIZE,
parse_margin,
- gtk_css_style_property_token_parse_default,
+ token_parse_margin,
query_length_as_int,
assign_length_from_int,
_gtk_css_number_value_new (0.0, GTK_CSS_PX));
@@ -1282,7 +1350,7 @@ _gtk_css_style_property_init_properties (void)
GTK_STYLE_PROPERTY_ANIMATED,
GTK_CSS_AFFECTS_SIZE,
parse_padding,
- gtk_css_style_property_token_parse_default,
+ token_parse_padding,
query_length_as_int,
assign_length_from_int,
_gtk_css_number_value_new (0.0, GTK_CSS_PX));
@@ -1292,7 +1360,7 @@ _gtk_css_style_property_init_properties (void)
GTK_STYLE_PROPERTY_ANIMATED,
GTK_CSS_AFFECTS_SIZE,
parse_padding,
- gtk_css_style_property_token_parse_default,
+ token_parse_padding,
query_length_as_int,
assign_length_from_int,
_gtk_css_number_value_new (0.0, GTK_CSS_PX));
@@ -1302,7 +1370,7 @@ _gtk_css_style_property_init_properties (void)
GTK_STYLE_PROPERTY_ANIMATED,
GTK_CSS_AFFECTS_SIZE,
parse_padding,
- gtk_css_style_property_token_parse_default,
+ token_parse_padding,
query_length_as_int,
assign_length_from_int,
_gtk_css_number_value_new (0.0, GTK_CSS_PX));
@@ -1312,7 +1380,7 @@ _gtk_css_style_property_init_properties (void)
GTK_STYLE_PROPERTY_ANIMATED,
GTK_CSS_AFFECTS_SIZE,
parse_padding,
- gtk_css_style_property_token_parse_default,
+ token_parse_padding,
query_length_as_int,
assign_length_from_int,
_gtk_css_number_value_new (0.0, GTK_CSS_PX));
@@ -1335,7 +1403,7 @@ _gtk_css_style_property_init_properties (void)
GTK_STYLE_PROPERTY_ANIMATED,
GTK_CSS_AFFECTS_BORDER | GTK_CSS_AFFECTS_SIZE,
parse_border_width,
- gtk_css_style_property_token_parse_default,
+ token_parse_border_width,
query_length_as_int,
assign_length_from_int,
_gtk_css_number_value_new (0.0, GTK_CSS_PX));
@@ -1355,7 +1423,7 @@ _gtk_css_style_property_init_properties (void)
GTK_STYLE_PROPERTY_ANIMATED,
GTK_CSS_AFFECTS_BORDER | GTK_CSS_AFFECTS_SIZE,
parse_border_width,
- gtk_css_style_property_token_parse_default,
+ token_parse_border_width,
query_length_as_int,
assign_length_from_int,
_gtk_css_number_value_new (0.0, GTK_CSS_PX));
@@ -1375,7 +1443,7 @@ _gtk_css_style_property_init_properties (void)
GTK_STYLE_PROPERTY_ANIMATED,
GTK_CSS_AFFECTS_BORDER | GTK_CSS_AFFECTS_SIZE,
parse_border_width,
- gtk_css_style_property_token_parse_default,
+ token_parse_border_width,
query_length_as_int,
assign_length_from_int,
_gtk_css_number_value_new (0.0, GTK_CSS_PX));
@@ -1395,7 +1463,7 @@ _gtk_css_style_property_init_properties (void)
GTK_STYLE_PROPERTY_ANIMATED,
GTK_CSS_AFFECTS_BORDER | GTK_CSS_AFFECTS_SIZE,
parse_border_width,
- gtk_css_style_property_token_parse_default,
+ token_parse_border_width,
query_length_as_int,
assign_length_from_int,
_gtk_css_number_value_new (0.0, GTK_CSS_PX));
@@ -1461,7 +1529,7 @@ _gtk_css_style_property_init_properties (void)
GTK_STYLE_PROPERTY_ANIMATED,
GTK_CSS_AFFECTS_OUTLINE | GTK_CSS_AFFECTS_CLIP,
parse_border_width,
- gtk_css_style_property_token_parse_default,
+ token_parse_border_width,
query_length_as_int,
assign_length_from_int,
_gtk_css_number_value_new (0.0, GTK_CSS_PX));
@@ -1471,7 +1539,7 @@ _gtk_css_style_property_init_properties (void)
GTK_STYLE_PROPERTY_ANIMATED,
GTK_CSS_AFFECTS_OUTLINE | GTK_CSS_AFFECTS_CLIP,
outline_parse,
- gtk_css_style_property_token_parse_default,
+ outline_token_parse,
query_length_as_int,
assign_length_from_int,
_gtk_css_number_value_new (0.0, GTK_CSS_PX));
@@ -1737,7 +1805,7 @@ _gtk_css_style_property_init_properties (void)
GTK_STYLE_PROPERTY_ANIMATED,
GTK_CSS_AFFECTS_SIZE,
minmax_parse,
- gtk_css_style_property_token_parse_default,
+ minmax_token_parse,
query_length_as_int,
NULL,
_gtk_css_number_value_new (0, GTK_CSS_PX));
@@ -1747,7 +1815,7 @@ _gtk_css_style_property_init_properties (void)
GTK_STYLE_PROPERTY_ANIMATED,
GTK_CSS_AFFECTS_SIZE,
minmax_parse,
- gtk_css_style_property_token_parse_default,
+ minmax_token_parse,
query_length_as_int,
NULL,
_gtk_css_number_value_new (0, GTK_CSS_PX));
@@ -1882,7 +1950,7 @@ _gtk_css_style_property_init_properties (void)
GTK_STYLE_PROPERTY_ANIMATED,
0,
opacity_parse,
- gtk_css_style_property_token_parse_default,
+ opacity_token_parse,
opacity_query,
NULL,
_gtk_css_number_value_new (1, GTK_CSS_NUMBER));
diff --git a/gtk/gtkcsswin32sizevalue.c b/gtk/gtkcsswin32sizevalue.c
index 134078b..82fa5c6 100644
--- a/gtk/gtkcsswin32sizevalue.c
+++ b/gtk/gtkcsswin32sizevalue.c
@@ -33,13 +33,13 @@ typedef enum {
} GtkWin32SizeType;
static const char *css_value_names[] = {
- "-gtk-win32-size(",
- "-gtk-win32-part-width(",
- "-gtk-win32-part-height(",
- "-gtk-win32-part-border-top(",
- "-gtk-win32-part-border-right(",
- "-gtk-win32-part-border-bottom(",
- "-gtk-win32-part-border-left("
+ "-gtk-win32-size",
+ "-gtk-win32-part-width",
+ "-gtk-win32-part-height",
+ "-gtk-win32-part-border-top",
+ "-gtk-win32-part-border-right",
+ "-gtk-win32-part-border-bottom",
+ "-gtk-win32-part-border-left"
};
struct _GtkCssValue {
@@ -160,6 +160,7 @@ gtk_css_value_win32_size_print (const GtkCssValue *value,
g_string_append_printf (string, "%g * ", value->scale);
}
g_string_append (string, css_value_names[value->type]);
+ g_string_append (string, "(");
gtk_win32_theme_print (value->theme, string);
switch (value->type)
@@ -341,7 +342,7 @@ gtk_css_win32_size_value_parse (GtkCssParser *parser,
for (type = 0; type < G_N_ELEMENTS(css_value_names); type++)
{
- if (_gtk_css_parser_try (parser, css_value_names[type], TRUE))
+ if (_gtk_css_parser_try (parser, css_value_names[type], FALSE))
break;
}
@@ -351,6 +352,12 @@ gtk_css_win32_size_value_parse (GtkCssParser *parser,
return NULL;
}
+ if (!_gtk_css_parser_try (parser, "(", TRUE))
+ {
+ _gtk_css_parser_error (parser, "Expected '('");
+ return NULL;
+ }
+
theme = gtk_win32_theme_parse (parser);
if (theme == NULL)
return NULL;
@@ -399,3 +406,138 @@ gtk_css_win32_size_value_parse (GtkCssParser *parser,
return result;
}
+
+GtkCssValue *
+gtk_css_win32_size_value_token_parse (GtkCssTokenSource *source,
+ GtkCssNumberParseFlags flags)
+{
+ GtkWin32Theme *theme;
+ const GtkCssToken *token;
+ GtkCssValue *result;
+ guint type;
+
+ token = gtk_css_token_source_get_token (source);
+ for (type = 0; type < G_N_ELEMENTS(css_value_names); type++)
+ {
+ if (gtk_css_token_is_function (token, css_value_names[type]))
+ break;
+ }
+
+ if (type >= G_N_ELEMENTS(css_value_names))
+ {
+ gtk_css_token_source_error (source, "Not a win32 size value");
+ gtk_css_token_source_consume_all (source);
+ return NULL;
+ }
+
+ gtk_css_token_source_consume_token (source);
+
+ theme = gtk_win32_theme_token_parse (source);
+ if (theme == NULL)
+ return NULL;
+
+ 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))
+ {
+ gtk_win32_theme_unref (theme);
+ gtk_css_token_source_error (source, "Expected ','");
+ gtk_css_token_source_consume_all (source);
+ return NULL;
+ }
+ gtk_css_token_source_consume_token (source);
+ gtk_css_token_source_consume_whitespace (source);
+
+ result = gtk_css_win32_size_value_new (1.0, theme, type);
+ gtk_win32_theme_unref (theme);
+
+ switch (result->type)
+ {
+ case GTK_WIN32_SIZE:
+ token = gtk_css_token_source_get_token (source);
+ if (gtk_css_token_is (token, GTK_CSS_TOKEN_IDENT))
+ {
+ result->val.size.id = gtk_win32_get_sys_metric_id_for_name (token->string.string);
+ if (result->val.size.id == -1)
+ {
+ gtk_css_token_source_error (source, "'%s' is not a name for a win32 metric.",
token->string.string);
+ gtk_css_token_source_consume_all (source);
+ _gtk_css_value_unref (result);
+ return NULL;
+ }
+ gtk_css_token_source_consume_token (source);
+ }
+ else if (gtk_css_token_is (token, GTK_CSS_TOKEN_INTEGER))
+ {
+ result->val.size.id = token->number.number;
+ gtk_css_token_source_consume_token (source);
+ }
+ else
+ {
+ _gtk_css_value_unref (result);
+ gtk_css_token_source_error (source, "Expected an integer ID");
+ gtk_css_token_source_consume_all (source);
+ return NULL;
+ }
+ break;
+
+ case GTK_WIN32_PART_WIDTH:
+ case GTK_WIN32_PART_HEIGHT:
+ case GTK_WIN32_PART_BORDER_TOP:
+ case GTK_WIN32_PART_BORDER_RIGHT:
+ case GTK_WIN32_PART_BORDER_BOTTOM:
+ case GTK_WIN32_PART_BORDER_LEFT:
+ token = gtk_css_token_source_get_token (source);
+ if (!gtk_css_token_is (token, GTK_CSS_TOKEN_INTEGER))
+ {
+ _gtk_css_value_unref (result);
+ gtk_css_token_source_error (source, "Expected an integer part ID");
+ gtk_css_token_source_consume_all (source);
+ return NULL;
+ }
+ result->val.part.part = token->number.number;
+ 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_COMMA))
+ {
+ _gtk_css_value_unref (result);
+ gtk_css_token_source_error (source, "Expected ','");
+ gtk_css_token_source_consume_all (source);
+ return NULL;
+ }
+ 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_INTEGER))
+ {
+ _gtk_css_value_unref (result);
+ gtk_css_token_source_error (source, "Expected an integer state ID");
+ gtk_css_token_source_consume_all (source);
+ return NULL;
+ }
+ result->val.part.state = token->number.number;
+ gtk_css_token_source_consume_token (source);
+ break;
+
+ default:
+ g_assert_not_reached ();
+ _gtk_css_value_unref (result);
+ result = NULL;
+ break;
+ }
+
+ token = gtk_css_token_source_get_token (source);
+ if (!gtk_css_token_is (token, GTK_CSS_TOKEN_CLOSE_PARENS))
+ {
+ _gtk_css_value_unref (result);
+ gtk_css_token_source_error (source, "Expected ')'");
+ gtk_css_token_source_consume_all (source);
+ return NULL;
+ }
+ gtk_css_token_source_consume_token (source);
+
+ return result;
+}
diff --git a/gtk/gtkcsswin32sizevalueprivate.h b/gtk/gtkcsswin32sizevalueprivate.h
index fd9bf19..d426d7e 100644
--- a/gtk/gtkcsswin32sizevalueprivate.h
+++ b/gtk/gtkcsswin32sizevalueprivate.h
@@ -26,6 +26,8 @@ G_BEGIN_DECLS
GtkCssValue * gtk_css_win32_size_value_parse (GtkCssParser *parser,
GtkCssNumberParseFlags flags);
+GtkCssValue * gtk_css_win32_size_value_token_parse(GtkCssTokenSource *source,
+ GtkCssNumberParseFlags flags);
G_END_DECLS
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]