css: Make the 'currentColor' keyword a symbolic color

This is the first step on a quest to ensure that there is only ever one
GType in use for GValues in every stage of the CSS resolving process.
This commit is contained in:
Benjamin Otte 2012-01-14 02:38:42 +01:00
parent 6b04c0f828
commit 05f14af24c
6 changed files with 89 additions and 52 deletions

View File

@ -30,6 +30,7 @@
#include "gtkcsstypesprivate.h" #include "gtkcsstypesprivate.h"
#include "gtkprivatetypebuiltins.h" #include "gtkprivatetypebuiltins.h"
#include "gtkstylepropertiesprivate.h" #include "gtkstylepropertiesprivate.h"
#include "gtksymboliccolorprivate.h"
#include "gtktypebuiltins.h" #include "gtktypebuiltins.h"
/* this is in case round() is not provided by the compiler, /* this is in case round() is not provided by the compiler,
@ -161,19 +162,18 @@ parse_border_color (GtkCssShorthandProperty *shorthand,
{ {
if (_gtk_css_parser_try (parser, "currentcolor", TRUE)) if (_gtk_css_parser_try (parser, "currentcolor", TRUE))
{ {
g_value_init (&values[i], GTK_TYPE_CSS_SPECIAL_VALUE); symbolic = gtk_symbolic_color_ref (_gtk_symbolic_color_get_current_color ());
g_value_set_enum (&values[i], GTK_CSS_CURRENT_COLOR);
} }
else else
{ {
symbolic = _gtk_css_parser_read_symbolic_color (parser); symbolic = _gtk_css_parser_read_symbolic_color (parser);
if (symbolic == NULL) if (symbolic == NULL)
return FALSE; return FALSE;
g_value_init (&values[i], GTK_TYPE_SYMBOLIC_COLOR);
g_value_set_boxed (&values[i], symbolic);
} }
g_value_init (&values[i], GTK_TYPE_SYMBOLIC_COLOR);
g_value_set_boxed (&values[i], symbolic);
if (value_is_done_parsing (parser)) if (value_is_done_parsing (parser))
break; break;
} }

View File

@ -37,6 +37,7 @@
#include "gtkprivatetypebuiltins.h" #include "gtkprivatetypebuiltins.h"
#include "gtkshadowprivate.h" #include "gtkshadowprivate.h"
#include "gtkstylecontextprivate.h" #include "gtkstylecontextprivate.h"
#include "gtksymboliccolorprivate.h"
#include "gtkthemingengine.h" #include "gtkthemingengine.h"
#include "gtktypebuiltins.h" #include "gtktypebuiltins.h"
#include "gtkwin32themeprivate.h" #include "gtkwin32themeprivate.h"
@ -173,15 +174,14 @@ rgba_value_parse (GtkCssParser *parser,
if (_gtk_css_parser_try (parser, "currentcolor", TRUE)) if (_gtk_css_parser_try (parser, "currentcolor", TRUE))
{ {
g_value_unset (value); symbolic = gtk_symbolic_color_ref (_gtk_symbolic_color_get_current_color ());
g_value_init (value, GTK_TYPE_CSS_SPECIAL_VALUE); }
g_value_set_enum (value, GTK_CSS_CURRENT_COLOR); else
return TRUE; {
symbolic = _gtk_css_parser_read_symbolic_color (parser);
if (symbolic == NULL)
return FALSE;
} }
symbolic = _gtk_css_parser_read_symbolic_color (parser);
if (symbolic == NULL)
return FALSE;
if (gtk_symbolic_color_resolve (symbolic, NULL, &rgba)) if (gtk_symbolic_color_resolve (symbolic, NULL, &rgba))
{ {
@ -223,14 +223,16 @@ rgba_value_compute (GValue *computed,
if (G_VALUE_HOLDS (specified, GTK_TYPE_CSS_SPECIAL_VALUE)) if (G_VALUE_HOLDS (specified, GTK_TYPE_CSS_SPECIAL_VALUE))
{ {
g_assert (g_value_get_enum (specified) == GTK_CSS_CURRENT_COLOR);
g_value_copy (_gtk_style_context_peek_property (context, "color"), computed);
} }
else if (G_VALUE_HOLDS (specified, GTK_TYPE_SYMBOLIC_COLOR)) else if (G_VALUE_HOLDS (specified, GTK_TYPE_SYMBOLIC_COLOR))
{ {
if (_gtk_style_context_resolve_color (context, GtkSymbolicColor *symbolic = g_value_get_boxed (specified);
g_value_get_boxed (specified),
&rgba)) if (symbolic == _gtk_symbolic_color_get_current_color ())
g_value_copy (_gtk_style_context_peek_property (context, "color"), computed);
else if (_gtk_style_context_resolve_color (context,
symbolic,
&rgba))
g_value_set_boxed (computed, &rgba); g_value_set_boxed (computed, &rgba);
else else
g_value_set_boxed (computed, &white); g_value_set_boxed (computed, &white);

View File

@ -39,6 +39,7 @@
#include "gtkcssimageprivate.h" #include "gtkcssimageprivate.h"
#include "gtkgradient.h" #include "gtkgradient.h"
#include "gtkshadowprivate.h" #include "gtkshadowprivate.h"
#include "gtksymboliccolorprivate.h"
#include "gtkthemingengine.h" #include "gtkthemingengine.h"
#include "gtktypebuiltins.h" #include "gtktypebuiltins.h"
#include "gtkwin32themeprivate.h" #include "gtkwin32themeprivate.h"
@ -56,43 +57,45 @@ color_compute (GtkCssStyleProperty *property,
/* for when resolvage fails */ /* for when resolvage fails */
restart: restart:
if (G_VALUE_HOLDS (specified, GTK_TYPE_CSS_SPECIAL_VALUE)) if (G_VALUE_HOLDS (specified, GTK_TYPE_SYMBOLIC_COLOR))
{
g_assert (g_value_get_enum (specified) == GTK_CSS_CURRENT_COLOR);
/* The computed value of the currentColor keyword is the computed
* value of the color property. If the currentColor keyword is
* set on the color property itself, it is treated as color: inherit.
*/
if (g_str_equal (_gtk_style_property_get_name (GTK_STYLE_PROPERTY (property)), "color"))
{
GtkStyleContext *parent = gtk_style_context_get_parent (context);
if (parent)
g_value_copy (_gtk_style_context_peek_property (parent, "color"), computed);
else
_gtk_css_style_compute_value (computed,
context,
_gtk_css_style_property_get_initial_value (property));
}
else
{
g_value_copy (_gtk_style_context_peek_property (context, "color"), computed);
}
}
else if (G_VALUE_HOLDS (specified, GTK_TYPE_SYMBOLIC_COLOR))
{ {
GtkSymbolicColor *symbolic = g_value_get_boxed (specified);
GdkRGBA rgba; GdkRGBA rgba;
if (!_gtk_style_context_resolve_color (context, if (symbolic == _gtk_symbolic_color_get_current_color ())
g_value_get_boxed (specified), {
&rgba)) /* The computed value of the currentColor keyword is the computed
* value of the color property. If the currentColor keyword is
* set on the color property itself, it is treated as color: inherit.
*/
if (g_str_equal (_gtk_style_property_get_name (GTK_STYLE_PROPERTY (property)), "color"))
{
GtkStyleContext *parent = gtk_style_context_get_parent (context);
if (parent)
g_value_copy (_gtk_style_context_peek_property (parent, "color"), computed);
else
_gtk_css_style_compute_value (computed,
context,
_gtk_css_style_property_get_initial_value (property));
}
else
{
g_value_copy (_gtk_style_context_peek_property (context, "color"), computed);
}
}
else if (_gtk_style_context_resolve_color (context,
symbolic,
&rgba))
{
g_value_set_boxed (computed, &rgba);
}
else
{ {
specified = _gtk_css_style_property_get_initial_value (property); specified = _gtk_css_style_property_get_initial_value (property);
goto restart; goto restart;
} }
g_value_set_boxed (computed, &rgba);
} }
else else
g_value_copy (specified, computed); g_value_copy (specified, computed);
@ -819,8 +822,8 @@ _gtk_css_style_property_init_properties (void)
NULL, NULL,
GTK_CSS_AREA_PADDING_BOX); GTK_CSS_AREA_PADDING_BOX);
g_value_init (&value, GTK_TYPE_CSS_SPECIAL_VALUE); g_value_init (&value, GTK_TYPE_SYMBOLIC_COLOR);
g_value_set_enum (&value, GTK_CSS_CURRENT_COLOR); g_value_set_boxed (&value, _gtk_symbolic_color_get_current_color ());
_gtk_style_property_register ("border-top-color", _gtk_style_property_register ("border-top-color",
GDK_TYPE_RGBA, GDK_TYPE_RGBA,
0, 0,

View File

@ -26,8 +26,7 @@ G_BEGIN_DECLS
typedef enum { typedef enum {
GTK_CSS_INHERIT, GTK_CSS_INHERIT,
GTK_CSS_INITIAL, GTK_CSS_INITIAL
GTK_CSS_CURRENT_COLOR /*< nick=currentColor >*/
} GtkCssSpecialValue; } GtkCssSpecialValue;
/* We encode horizontal and vertical repeat in one enum value. /* We encode horizontal and vertical repeat in one enum value.

View File

@ -52,7 +52,8 @@ typedef enum {
COLOR_TYPE_SHADE, COLOR_TYPE_SHADE,
COLOR_TYPE_ALPHA, COLOR_TYPE_ALPHA,
COLOR_TYPE_MIX, COLOR_TYPE_MIX,
COLOR_TYPE_WIN32 COLOR_TYPE_WIN32,
COLOR_TYPE_CURRENT_COLOR
} ColorType; } ColorType;
struct _GtkSymbolicColor struct _GtkSymbolicColor
@ -267,6 +268,30 @@ gtk_symbolic_color_new_win32 (const gchar *theme_class,
return symbolic_color; return symbolic_color;
} }
/**
* _gtk_symbolic_color_get_current_color:
*
* Gets the color representing the CSS 'currentColor' keyword.
* This color will resolve to the color set for the color property.
*
* Returns: (transfer none): The singleton representing the
* 'currentColor' keyword
**/
GtkSymbolicColor *
_gtk_symbolic_color_get_current_color (void)
{
static GtkSymbolicColor *current_color = NULL;
if (G_UNLIKELY (current_color == NULL))
{
current_color = g_slice_new0 (GtkSymbolicColor);
current_color->type = COLOR_TYPE_CURRENT_COLOR;
current_color->ref_count = 1;
}
return current_color;
}
/** /**
* gtk_symbolic_color_ref: * gtk_symbolic_color_ref:
* @color: a #GtkSymbolicColor * @color: a #GtkSymbolicColor
@ -628,6 +653,9 @@ _gtk_symbolic_color_resolve_full (GtkSymbolicColor *color,
color->win32.id, color->win32.id,
resolved_color); resolved_color);
break;
case COLOR_TYPE_CURRENT_COLOR:
return FALSE;
break; break;
default: default:
g_assert_not_reached (); g_assert_not_reached ();
@ -701,6 +729,9 @@ gtk_symbolic_color_to_string (GtkSymbolicColor *color)
color->win32.theme_class, color->win32.id); color->win32.theme_class, color->win32.id);
} }
break; break;
case COLOR_TYPE_CURRENT_COLOR:
s = g_strdup ("currentColor");
break;
default: default:
g_assert_not_reached (); g_assert_not_reached ();
} }

View File

@ -31,6 +31,8 @@ gboolean _gtk_symbolic_color_resolve_full (GtkSymbolicColor
gpointer data, gpointer data,
GdkRGBA *resolved_color); GdkRGBA *resolved_color);
GtkSymbolicColor * _gtk_symbolic_color_get_current_color (void);
G_END_DECLS G_END_DECLS
#endif /* __GTK_SYMBOLIC_COLOR_PRIVATE_H__ */ #endif /* __GTK_SYMBOLIC_COLOR_PRIVATE_H__ */