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.
This commit is contained in:
Benjamin Otte
2016-03-17 00:36:51 +01:00
parent 974ca283ef
commit b9c77aadec
9 changed files with 590 additions and 27 deletions

View File

@@ -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;
}

View File

@@ -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

View File

@@ -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);
}

View File

@@ -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__ */

View File

@@ -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)

View File

@@ -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);

View File

@@ -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,
@@ -665,6 +672,13 @@ parse_letter_spacing (GtkCssStyleProperty *property,
return _gtk_css_number_value_parse (parser, GTK_CSS_PARSE_LENGTH);
}
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)
@@ -817,6 +831,13 @@ dpi_parse (GtkCssStyleProperty *property,
return _gtk_css_number_value_parse (parser, GTK_CSS_PARSE_NUMBER);
}
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)
@@ -843,6 +864,15 @@ outline_parse (GtkCssStyleProperty *property,
| GTK_CSS_PARSE_LENGTH);
}
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)
@@ -892,6 +922,15 @@ minmax_parse (GtkCssStyleProperty *property,
| GTK_CSS_POSITIVE_ONLY);
}
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)
{
@@ -985,6 +1024,15 @@ parse_margin (GtkCssStyleProperty *property,
| GTK_CSS_PARSE_LENGTH);
}
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)
@@ -995,6 +1043,16 @@ parse_padding (GtkCssStyleProperty *property,
| GTK_CSS_PARSE_LENGTH);
}
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)
@@ -1005,6 +1063,16 @@ parse_border_width (GtkCssStyleProperty *property,
| GTK_CSS_PARSE_LENGTH);
}
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)
{
@@ -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));

View File

@@ -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;
}

View File

@@ -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