[gtk+] css: Redo value resolving
- From: Benjamin Otte <otte src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gtk+] css: Redo value resolving
- Date: Mon, 9 Jan 2012 17:50:25 +0000 (UTC)
commit e87cf5d7896746c8e9b81b037843c670f728287c
Author: Benjamin Otte <otte redhat com>
Date: Mon Jan 2 15:44:45 2012 +0100
css: Redo value resolving
Instead of on-demand resolvage, we now resolve during lookup. The step
is done via
_gtk_css_style_property_compute_value()
which currently calls into
_gtk_css_style_compute_value()
That function has all the old resolving machinery.
The only part missing for now is the handling of win32 code. It will be
added back later.
gtk/gtkcsslookup.c | 32 +++----
gtk/gtkcssstylefuncs.c | 189 ++++++++++++++++++++++++++++++----
gtk/gtkcssstylefuncsprivate.h | 4 +
gtk/gtkcssstyleproperty.c | 210 +++++---------------------------------
gtk/gtkcssstylepropertyprivate.h | 6 +
gtk/gtkshadow.c | 15 ++--
gtk/gtkshadowprivate.h | 4 +-
7 files changed, 227 insertions(+), 233 deletions(-)
---
diff --git a/gtk/gtkcsslookup.c b/gtk/gtkcsslookup.c
index dc43005..af4eddf 100644
--- a/gtk/gtkcsslookup.c
+++ b/gtk/gtkcsslookup.c
@@ -135,6 +135,7 @@ _gtk_css_lookup_resolve (GtkCssLookup *lookup,
{
GtkCssStyleProperty *prop = _gtk_css_style_property_lookup_by_id (i);
const GValue *result;
+ GValue value = { 0, };
/* http://www.w3.org/TR/css3-cascade/#cascade
* Then, for every element, the value for each property can be found
@@ -192,36 +193,31 @@ _gtk_css_lookup_resolve (GtkCssLookup *lookup,
}
}
- if (result)
- {
- _gtk_style_properties_set_property_by_property (props,
- prop,
- 0,
- result);
- }
- else if (parent == NULL)
+ if (result == NULL && parent == NULL)
{
/* If the âinheritâ value is set on the root element, the property is
* assigned its initial value. */
- _gtk_style_properties_set_property_by_property (props,
- prop,
- 0,
- _gtk_css_style_property_get_initial_value (prop));
+ result = _gtk_css_style_property_get_initial_value (prop);
+ }
+
+ if (result)
+ {
+ _gtk_css_style_property_compute_value (prop, &value, context, result);
}
else
{
- GValue value = { 0, };
/* Set NULL here and do the inheritance upon lookup? */
gtk_style_context_get_property (parent,
_gtk_style_property_get_name (GTK_STYLE_PROPERTY (prop)),
gtk_style_context_get_state (parent),
&value);
- _gtk_style_properties_set_property_by_property (props,
- prop,
- 0,
- &value);
- g_value_unset (&value);
}
+
+ _gtk_style_properties_set_property_by_property (props,
+ prop,
+ 0,
+ &value);
+ g_value_unset (&value);
}
return props;
diff --git a/gtk/gtkcssstylefuncs.c b/gtk/gtkcssstylefuncs.c
index 5ba366c..a7b31f1 100644
--- a/gtk/gtkcssstylefuncs.c
+++ b/gtk/gtkcssstylefuncs.c
@@ -35,6 +35,7 @@
#include "gtkgradient.h"
#include "gtkprivatetypebuiltins.h"
#include "gtkshadowprivate.h"
+#include "gtkstylecontextprivate.h"
#include "gtkthemingengine.h"
#include "gtktypebuiltins.h"
#include "gtkwin32themeprivate.h"
@@ -46,22 +47,31 @@
static GHashTable *parse_funcs = NULL;
static GHashTable *print_funcs = NULL;
+static GHashTable *compute_funcs = NULL;
typedef gboolean (* GtkStyleParseFunc) (GtkCssParser *parser,
GFile *base,
GValue *value);
typedef void (* GtkStylePrintFunc) (const GValue *value,
GString *string);
+typedef void (* GtkStylePrintFunc) (const GValue *value,
+ GString *string);
+typedef void (* GtkStyleComputeFunc) (GValue *computed,
+ GtkStyleContext *context,
+ const GValue *specified);
static void
-register_conversion_function (GType type,
- GtkStyleParseFunc parse,
- GtkStylePrintFunc print)
+register_conversion_function (GType type,
+ GtkStyleParseFunc parse,
+ GtkStylePrintFunc print,
+ GtkStyleComputeFunc compute)
{
if (parse)
g_hash_table_insert (parse_funcs, GSIZE_TO_POINTER (type), parse);
if (print)
g_hash_table_insert (print_funcs, GSIZE_TO_POINTER (type), print);
+ if (compute)
+ g_hash_table_insert (compute_funcs, GSIZE_TO_POINTER (type), compute);
}
static void
@@ -197,6 +207,26 @@ rgba_value_print (const GValue *value,
}
}
+static void
+rgba_value_compute (GValue *computed,
+ GtkStyleContext *context,
+ const GValue *specified)
+{
+ GdkRGBA rgba, white = { 1, 1, 1, 1 };
+
+ if (G_VALUE_HOLDS (specified, GTK_TYPE_SYMBOLIC_COLOR))
+ {
+ if (_gtk_style_context_resolve_color (context,
+ g_value_get_boxed (specified),
+ &rgba))
+ g_value_set_boxed (computed, &rgba);
+ else
+ g_value_set_boxed (computed, &white);
+ }
+ else
+ g_value_copy (specified, computed);
+}
+
static gboolean
color_value_parse (GtkCssParser *parser,
GFile *base,
@@ -245,6 +275,31 @@ color_value_print (const GValue *value,
}
}
+static void
+color_value_compute (GValue *computed,
+ GtkStyleContext *context,
+ const GValue *specified)
+{
+ GdkRGBA rgba;
+ GdkColor color = { 0, 65535, 65535, 65535 };
+
+ if (G_VALUE_HOLDS (specified, GTK_TYPE_SYMBOLIC_COLOR))
+ {
+ if (_gtk_style_context_resolve_color (context,
+ g_value_get_boxed (specified),
+ &rgba))
+ {
+ color.red = rgba.red * 65535. + 0.5;
+ color.green = rgba.green * 65535. + 0.5;
+ color.blue = rgba.blue * 65535. + 0.5;
+ }
+
+ g_value_set_boxed (computed, &color);
+ }
+ else
+ g_value_copy (specified, computed);
+}
+
static gboolean
symbolic_color_value_parse (GtkCssParser *parser,
GFile *base,
@@ -1044,6 +1099,23 @@ pattern_value_print (const GValue *value,
}
}
+static void
+pattern_value_compute (GValue *computed,
+ GtkStyleContext *context,
+ const GValue *specified)
+{
+ if (G_VALUE_HOLDS (specified, GTK_TYPE_GRADIENT))
+ {
+ cairo_pattern_t *gradient;
+
+ gradient = gtk_gradient_resolve_for_context (g_value_get_boxed (specified), context);
+
+ g_value_take_boxed (computed, gradient);
+ }
+ else
+ g_value_copy (specified, computed);
+}
+
static gboolean
shadow_value_parse (GtkCssParser *parser,
GFile *base,
@@ -1146,6 +1218,20 @@ shadow_value_print (const GValue *value,
_gtk_shadow_print (shadow, string);
}
+static void
+shadow_value_compute (GValue *computed,
+ GtkStyleContext *context,
+ const GValue *specified)
+{
+ GtkShadow *shadow;
+
+ shadow = g_value_get_boxed (specified);
+ if (shadow)
+ shadow = _gtk_shadow_resolve (shadow, context);
+
+ g_value_take_boxed (computed, shadow);
+}
+
static gboolean
background_repeat_value_parse (GtkCssParser *parser,
GFile *file,
@@ -1326,67 +1412,88 @@ gtk_css_style_funcs_init (void)
parse_funcs = g_hash_table_new (NULL, NULL);
print_funcs = g_hash_table_new (NULL, NULL);
+ compute_funcs = g_hash_table_new (NULL, NULL);
register_conversion_function (GDK_TYPE_RGBA,
rgba_value_parse,
- rgba_value_print);
+ rgba_value_print,
+ rgba_value_compute);
register_conversion_function (GDK_TYPE_COLOR,
color_value_parse,
- color_value_print);
+ color_value_print,
+ color_value_compute);
register_conversion_function (GTK_TYPE_SYMBOLIC_COLOR,
symbolic_color_value_parse,
- symbolic_color_value_print);
+ symbolic_color_value_print,
+ NULL);
register_conversion_function (PANGO_TYPE_FONT_DESCRIPTION,
font_description_value_parse,
- font_description_value_print);
+ font_description_value_print,
+ NULL);
register_conversion_function (G_TYPE_BOOLEAN,
boolean_value_parse,
- boolean_value_print);
+ boolean_value_print,
+ NULL);
register_conversion_function (G_TYPE_INT,
int_value_parse,
- int_value_print);
+ int_value_print,
+ NULL);
register_conversion_function (G_TYPE_UINT,
uint_value_parse,
- uint_value_print);
+ uint_value_print,
+ NULL);
register_conversion_function (G_TYPE_DOUBLE,
double_value_parse,
- double_value_print);
+ double_value_print,
+ NULL);
register_conversion_function (G_TYPE_FLOAT,
float_value_parse,
- float_value_print);
+ float_value_print,
+ NULL);
register_conversion_function (G_TYPE_STRING,
string_value_parse,
- string_value_print);
+ string_value_print,
+ NULL);
register_conversion_function (GTK_TYPE_THEMING_ENGINE,
theming_engine_value_parse,
- theming_engine_value_print);
+ theming_engine_value_print,
+ NULL);
register_conversion_function (GTK_TYPE_ANIMATION_DESCRIPTION,
animation_description_value_parse,
- animation_description_value_print);
+ animation_description_value_print,
+ NULL);
register_conversion_function (GTK_TYPE_BORDER,
border_value_parse,
- border_value_print);
+ border_value_print,
+ NULL);
register_conversion_function (GTK_TYPE_GRADIENT,
gradient_value_parse,
- gradient_value_print);
+ gradient_value_print,
+ NULL);
register_conversion_function (CAIRO_GOBJECT_TYPE_PATTERN,
pattern_value_parse,
- pattern_value_print);
+ pattern_value_print,
+ pattern_value_compute);
register_conversion_function (GTK_TYPE_CSS_BORDER_IMAGE_REPEAT,
border_image_repeat_value_parse,
- border_image_repeat_value_print);
+ border_image_repeat_value_print,
+ NULL);
register_conversion_function (GTK_TYPE_SHADOW,
shadow_value_parse,
- shadow_value_print);
+ shadow_value_print,
+ shadow_value_compute);
register_conversion_function (G_TYPE_ENUM,
enum_value_parse,
- enum_value_print);
+ enum_value_print,
+ NULL);
register_conversion_function (G_TYPE_FLAGS,
flags_value_parse,
- flags_value_print);
+ flags_value_print,
+ NULL);
register_conversion_function (GTK_TYPE_CSS_BACKGROUND_REPEAT,
background_repeat_value_parse,
- background_repeat_value_print);
+ background_repeat_value_print,
+ NULL);
}
/**
@@ -1463,3 +1570,39 @@ _gtk_css_style_print_value (const GValue *value,
func (value, string);
}
+/**
+ * _gtk_css_style_compute_value:
+ * @computed: (out): a value to be filled with the result
+ * @context: the context to use for computing the value
+ * @specified: the value to use for the computation
+ *
+ * Converts the @specified value into the @computed value using the
+ * information in @context. The values must have matching types, ie
+ * @specified must be a result of a call to
+ * _gtk_css_style_parse_value() with the same type as @computed.
+ **/
+void
+_gtk_css_style_compute_value (GValue *computed,
+ GtkStyleContext *context,
+ const GValue *specified)
+{
+ GtkStyleComputeFunc func;
+
+ g_return_if_fail (G_IS_VALUE (computed));
+ g_return_if_fail (GTK_IS_STYLE_CONTEXT (context));
+ g_return_if_fail (G_IS_VALUE (specified));
+
+ gtk_css_style_funcs_init ();
+
+ func = g_hash_table_lookup (compute_funcs,
+ GSIZE_TO_POINTER (G_VALUE_TYPE (computed)));
+ if (func == NULL)
+ func = g_hash_table_lookup (compute_funcs,
+ GSIZE_TO_POINTER (g_type_fundamental (G_VALUE_TYPE (computed))));
+
+ if (func)
+ func (computed, context, specified);
+ else
+ g_value_copy (specified, computed);
+}
+
diff --git a/gtk/gtkcssstylefuncsprivate.h b/gtk/gtkcssstylefuncsprivate.h
index d4d2932..a3a5641 100644
--- a/gtk/gtkcssstylefuncsprivate.h
+++ b/gtk/gtkcssstylefuncsprivate.h
@@ -21,6 +21,7 @@
#define __GTK_CSS_STYLE_FUNCS_PRIVATE_H__
#include "gtkcssparserprivate.h"
+#include "gtkstylecontext.h"
G_BEGIN_DECLS
@@ -29,6 +30,9 @@ gboolean _gtk_css_style_parse_value (GValue
GFile *base);
void _gtk_css_style_print_value (const GValue *value,
GString *string);
+void _gtk_css_style_compute_value (GValue *computed,
+ GtkStyleContext *context,
+ const GValue *specified);
G_END_DECLS
diff --git a/gtk/gtkcssstyleproperty.c b/gtk/gtkcssstyleproperty.c
index 76021dc..2f54244 100644
--- a/gtk/gtkcssstyleproperty.c
+++ b/gtk/gtkcssstyleproperty.c
@@ -28,13 +28,6 @@
#include "gtkprivatetypebuiltins.h"
#include "gtkstylepropertiesprivate.h"
-/* for resolvage */
-#include <cairo-gobject.h>
-#include "gtkgradient.h"
-#include "gtkshadowprivate.h"
-#include "gtkwin32themeprivate.h"
-
-
enum {
PROP_0,
PROP_ID,
@@ -128,180 +121,6 @@ _gtk_style_property_default_value (GtkStyleProperty *property,
g_value_copy (_gtk_css_style_property_get_initial_value (GTK_CSS_STYLE_PROPERTY (property)), value);
}
-static gboolean
-resolve_color (GtkStyleProperties *props,
- GValue *value)
-{
- GdkRGBA color;
-
- /* Resolve symbolic color to GdkRGBA */
- if (!gtk_symbolic_color_resolve (g_value_get_boxed (value), props, &color))
- return FALSE;
-
- /* Store it back, this is where GdkRGBA caching happens */
- g_value_unset (value);
- g_value_init (value, GDK_TYPE_RGBA);
- g_value_set_boxed (value, &color);
-
- return TRUE;
-}
-
-static gboolean
-resolve_color_rgb (GtkStyleProperties *props,
- GValue *value)
-{
- GdkColor color = { 0 };
- GdkRGBA rgba;
-
- if (!gtk_symbolic_color_resolve (g_value_get_boxed (value), props, &rgba))
- return FALSE;
-
- color.red = rgba.red * 65535. + 0.5;
- color.green = rgba.green * 65535. + 0.5;
- color.blue = rgba.blue * 65535. + 0.5;
-
- g_value_unset (value);
- g_value_init (value, GDK_TYPE_COLOR);
- g_value_set_boxed (value, &color);
-
- return TRUE;
-}
-
-static gboolean
-resolve_win32_theme_part (GtkStyleProperties *props,
- GValue *value,
- GValue *value_out,
- GtkStylePropertyContext *context)
-{
- GtkWin32ThemePart *part;
- cairo_pattern_t *pattern;
-
- part = g_value_get_boxed (value);
- if (part == NULL)
- return FALSE;
-
- pattern = _gtk_win32_theme_part_render (part, context->width, context->height);
-
- g_value_take_boxed (value_out, pattern);
-
- return TRUE;
-}
-
-
-static gboolean
-resolve_gradient (GtkStyleProperties *props,
- GValue *value)
-{
- cairo_pattern_t *gradient;
-
- if (!gtk_gradient_resolve (g_value_get_boxed (value), props, &gradient))
- return FALSE;
-
- /* Store it back, this is where cairo_pattern_t caching happens */
- g_value_unset (value);
- g_value_init (value, CAIRO_GOBJECT_TYPE_PATTERN);
- g_value_take_boxed (value, gradient);
-
- return TRUE;
-}
-
-static gboolean
-resolve_shadow (GtkStyleProperties *props,
- GValue *value)
-{
- GtkShadow *resolved, *base;
-
- base = g_value_get_boxed (value);
-
- if (base == NULL)
- return TRUE;
-
- if (_gtk_shadow_get_resolved (base))
- return TRUE;
-
- resolved = _gtk_shadow_resolve (base, props);
- if (resolved == NULL)
- return FALSE;
-
- g_value_take_boxed (value, resolved);
-
- return TRUE;
-}
-
-static void
-_gtk_style_property_resolve (GtkStyleProperty *property,
- GtkStyleProperties *props,
- GtkStateFlags state,
- GtkStylePropertyContext *context,
- GValue *val,
- GValue *val_out)
-{
- if (G_VALUE_TYPE (val) == GTK_TYPE_CSS_SPECIAL_VALUE)
- {
- GtkCssSpecialValue special = g_value_get_enum (val);
-
- g_value_unset (val);
- switch (special)
- {
- case GTK_CSS_CURRENT_COLOR:
- g_assert (_gtk_style_property_get_value_type (property) == GDK_TYPE_RGBA);
- gtk_style_properties_get_property (props, "color", state, val);
- break;
- case GTK_CSS_INHERIT:
- case GTK_CSS_INITIAL:
- default:
- g_assert_not_reached ();
- }
- }
- else if (G_VALUE_TYPE (val) == GTK_TYPE_SYMBOLIC_COLOR)
- {
- if (_gtk_style_property_get_value_type (property) == GDK_TYPE_RGBA)
- {
- if (resolve_color (props, val))
- goto out;
- }
- else if (_gtk_style_property_get_value_type (property) == GDK_TYPE_COLOR)
- {
- if (resolve_color_rgb (props, val))
- goto out;
- }
-
- g_value_unset (val);
- g_value_init (val, _gtk_style_property_get_value_type (property));
- _gtk_style_property_default_value (property, props, state, val);
- }
- else if (G_VALUE_TYPE (val) == GDK_TYPE_RGBA)
- {
- if (g_value_get_boxed (val) == NULL)
- _gtk_style_property_default_value (property, props, state, val);
- }
- else if (G_VALUE_TYPE (val) == GTK_TYPE_GRADIENT)
- {
- g_return_if_fail (_gtk_style_property_get_value_type (property) == CAIRO_GOBJECT_TYPE_PATTERN);
-
- if (!resolve_gradient (props, val))
- {
- g_value_unset (val);
- g_value_init (val, CAIRO_GOBJECT_TYPE_PATTERN);
- _gtk_style_property_default_value (property, props, state, val);
- }
- }
- else if (G_VALUE_TYPE (val) == GTK_TYPE_SHADOW)
- {
- if (!resolve_shadow (props, val))
- _gtk_style_property_default_value (property, props, state, val);
- }
- else if (G_VALUE_TYPE (val) == GTK_TYPE_WIN32_THEME_PART)
- {
- if (resolve_win32_theme_part (props, val, val_out, context))
- return; /* Don't copy val, this sets val_out */
- _gtk_style_property_default_value (property, props, state, val);
- }
-
- out:
- g_value_copy (val, val_out);
-}
-
static void
_gtk_css_style_property_query (GtkStyleProperty *property,
GtkStyleProperties *props,
@@ -313,7 +132,7 @@ _gtk_css_style_property_query (GtkStyleProperty *property,
val = _gtk_style_properties_peek_property (props, GTK_CSS_STYLE_PROPERTY (property), state);
if (val)
- _gtk_style_property_resolve (property, props, state, context, (GValue *) val, value);
+ g_value_copy (val, value);
else
_gtk_style_property_default_value (property, props, state, value);
}
@@ -497,6 +316,33 @@ _gtk_css_style_property_get_initial_value (GtkCssStyleProperty *property)
}
/**
+ * _gtk_css_style_property_compute_value:
+ * @property: the property
+ * @computed: (out): an uninitialized value to be filled with the result
+ * @context: the context to use for resolving
+ * @specified: the value to compute from
+ *
+ * Converts the @specified value into the @computed value using the
+ * information in @context. This step is explained in detail in
+ * <ulink url="http://www.w3.org/TR/css3-cascade/#computed>
+ * the CSS documentation</ulink>.
+ **/
+void
+_gtk_css_style_property_compute_value (GtkCssStyleProperty *property,
+ GValue *computed,
+ GtkStyleContext *context,
+ const GValue *specified)
+{
+ g_return_if_fail (GTK_IS_CSS_STYLE_PROPERTY (property));
+ g_return_if_fail (computed != NULL && !G_IS_VALUE (computed));
+ g_return_if_fail (GTK_IS_STYLE_CONTEXT (context));
+ g_return_if_fail (G_IS_VALUE (specified));
+
+ g_value_init (computed, _gtk_style_property_get_value_type (GTK_STYLE_PROPERTY (property)));
+ _gtk_css_style_compute_value (computed, context, specified);
+}
+
+/**
* _gtk_css_style_property_print_value:
* @property: the property
* @value: the value to print
diff --git a/gtk/gtkcssstylepropertyprivate.h b/gtk/gtkcssstylepropertyprivate.h
index 79516f4..c02a766 100644
--- a/gtk/gtkcssstylepropertyprivate.h
+++ b/gtk/gtkcssstylepropertyprivate.h
@@ -63,9 +63,15 @@ guint _gtk_css_style_property_get_id (GtkCssStyleProp
const GValue * _gtk_css_style_property_get_initial_value
(GtkCssStyleProperty *property);
+void _gtk_css_style_property_compute_value (GtkCssStyleProperty *property,
+ GValue *computed,
+ GtkStyleContext *context,
+ const GValue *specified);
+
void _gtk_css_style_property_print_value (GtkCssStyleProperty *property,
const GValue *value,
GString *string);
+
G_END_DECLS
diff --git a/gtk/gtkshadow.c b/gtk/gtkshadow.c
index 33c9d2e..53106b2 100644
--- a/gtk/gtkshadow.c
+++ b/gtk/gtkshadow.c
@@ -22,11 +22,10 @@
#include "config.h"
#include "gtkshadowprivate.h"
-#include "gtkstylecontext.h"
+
+#include "gtkstylecontextprivate.h"
#include "gtkthemingengineprivate.h"
-#include "gtkthemingengine.h"
#include "gtkpango.h"
-#include "gtkthemingengineprivate.h"
typedef struct _GtkShadowElement GtkShadowElement;
@@ -186,8 +185,8 @@ _gtk_shadow_append (GtkShadow *shadow,
}
GtkShadow *
-_gtk_shadow_resolve (GtkShadow *shadow,
- GtkStyleProperties *props)
+_gtk_shadow_resolve (GtkShadow *shadow,
+ GtkStyleContext *context)
{
GtkShadow *resolved_shadow;
GtkShadowElement *element, *resolved_element;
@@ -203,9 +202,9 @@ _gtk_shadow_resolve (GtkShadow *shadow,
{
element = l->data;
- if (!gtk_symbolic_color_resolve (element->symbolic_color,
- props,
- &color))
+ if (!_gtk_style_context_resolve_color (context,
+ element->symbolic_color,
+ &color))
{
_gtk_shadow_unref (resolved_shadow);
return NULL;
diff --git a/gtk/gtkshadowprivate.h b/gtk/gtkshadowprivate.h
index 5b9bad5..6537ba9 100644
--- a/gtk/gtkshadowprivate.h
+++ b/gtk/gtkshadowprivate.h
@@ -24,7 +24,7 @@
#include <glib-object.h>
-#include "gtkstyleproperties.h"
+#include "gtkstylecontext.h"
#include "gtksymboliccolor.h"
#include "gtkicontheme.h"
#include "gtkcsstypesprivate.h"
@@ -54,7 +54,7 @@ void _gtk_shadow_print (GtkShadow *shadow,
GString *string);
GtkShadow *_gtk_shadow_resolve (GtkShadow *shadow,
- GtkStyleProperties *props);
+ GtkStyleContext *context);
gboolean _gtk_shadow_get_resolved (GtkShadow *shadow);
void _gtk_text_shadow_paint_layout (GtkShadow *shadow,
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]