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.
This commit is contained in:
@@ -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;
|
||||
|
||||
@@ -44,6 +44,7 @@ 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);
|
||||
gboolean gtk_css_color_value_check_token (const GtkCssToken *token);
|
||||
|
||||
GtkCssValue * _gtk_css_color_value_resolve (GtkCssValue *color,
|
||||
GtkStyleProviderPrivate *provider,
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -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)
|
||||
{
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -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)
|
||||
{
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -932,6 +932,13 @@ box_shadow_value_parse (GtkCssStyleProperty *property,
|
||||
return _gtk_css_shadows_value_parse (parser, TRUE);
|
||||
}
|
||||
|
||||
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)
|
||||
@@ -939,6 +946,13 @@ shadow_value_parse (GtkCssStyleProperty *property,
|
||||
return _gtk_css_shadows_value_parse (parser, FALSE);
|
||||
}
|
||||
|
||||
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 ());
|
||||
|
||||
Reference in New Issue
Block a user