[gtk+/wip/cssvalue] Use GtkCssValue in symbolic color resolving
- From: Alexander Larsson <alexl src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gtk+/wip/cssvalue] Use GtkCssValue in symbolic color resolving
- Date: Thu, 8 Mar 2012 15:42:39 +0000 (UTC)
commit 616cc5b96dc6d04ec0dcb43fe1024dc5473bfc9b
Author: Alexander Larsson <alexl redhat com>
Date: Thu Mar 8 14:52:10 2012 +0100
Use GtkCssValue in symbolic color resolving
We now store the symbolic colors as a GtkCssValue which means that
we can reuse the color when resolving and storing the color in
the computed values in the style context.
Additionally we keep a last_resolved GtkCssValue cache in the
GtkSymbolicColor, and if resolving the color returns the same as
last time we reuse the old value. This further increases sharing
of Css Values.
gtk/gtkcssstylefuncs.c | 14 ++--
gtk/gtkcssstylepropertyimpl.c | 9 +-
gtk/gtkstylecontext.c | 28 ++++++-
gtk/gtkstylecontextprivate.h | 2 +
gtk/gtksymboliccolor.c | 184 ++++++++++++++++++++++++++---------------
gtk/gtksymboliccolorprivate.h | 6 +-
6 files changed, 158 insertions(+), 85 deletions(-)
---
diff --git a/gtk/gtkcssstylefuncs.c b/gtk/gtkcssstylefuncs.c
index b1e373e..0693e04 100644
--- a/gtk/gtkcssstylefuncs.c
+++ b/gtk/gtkcssstylefuncs.c
@@ -215,7 +215,8 @@ static GtkCssValue *
rgba_value_compute (GtkStyleContext *context,
GtkCssValue *specified)
{
- GdkRGBA rgba, white = { 1, 1, 1, 1 };
+ GdkRGBA white = { 1, 1, 1, 1 };
+ GtkCssValue *res;
if (_gtk_css_value_holds (specified, GTK_TYPE_CSS_SPECIAL_VALUE))
{
@@ -227,12 +228,13 @@ rgba_value_compute (GtkStyleContext *context,
if (symbolic == _gtk_symbolic_color_get_current_color ())
return _gtk_css_value_ref (_gtk_style_context_peek_property (context, "color"));
- else if (_gtk_style_context_resolve_color (context,
- symbolic,
- &rgba))
- return _gtk_css_value_new_from_rgba (&rgba);
- else
+ else {
+ res = _gtk_style_context_resolve_color_value (context, symbolic);
+ if (res != NULL)
+ return res;
+
return _gtk_css_value_new_from_rgba (&white);
+ }
}
else
return _gtk_css_value_ref (specified);
diff --git a/gtk/gtkcssstylepropertyimpl.c b/gtk/gtkcssstylepropertyimpl.c
index 5d206e3..f6d4b49 100644
--- a/gtk/gtkcssstylepropertyimpl.c
+++ b/gtk/gtkcssstylepropertyimpl.c
@@ -146,7 +146,7 @@ color_compute (GtkCssStyleProperty *property,
GtkCssValue *specified)
{
GtkSymbolicColor *symbolic = _gtk_css_value_get_symbolic_color (specified);
- GdkRGBA rgba;
+ GtkCssValue *resolved;
if (symbolic == _gtk_symbolic_color_get_current_color ())
{
@@ -170,11 +170,10 @@ color_compute (GtkCssStyleProperty *property,
return _gtk_css_value_ref (_gtk_style_context_peek_property (context, "color"));
}
}
- else if (_gtk_style_context_resolve_color (context,
- symbolic,
- &rgba))
+ else if ((resolved = _gtk_style_context_resolve_color_value (context,
+ symbolic)) != NULL)
{
- return _gtk_css_value_new_from_rgba (&rgba);
+ return resolved;
}
else
{
diff --git a/gtk/gtkstylecontext.c b/gtk/gtkstylecontext.c
index 42673c3..e04e03b 100644
--- a/gtk/gtkstylecontext.c
+++ b/gtk/gtkstylecontext.c
@@ -2919,19 +2919,39 @@ gtk_style_context_color_lookup_func (gpointer contextp,
return sym_color;
}
+GtkCssValue *
+_gtk_style_context_resolve_color_value (GtkStyleContext *context,
+ GtkSymbolicColor *color)
+{
+ g_return_val_if_fail (GTK_IS_STYLE_CONTEXT (context), FALSE);
+ g_return_val_if_fail (color != NULL, FALSE);
+
+ return _gtk_symbolic_color_resolve_full (color,
+ gtk_style_context_color_lookup_func,
+ context);
+}
+
+
gboolean
_gtk_style_context_resolve_color (GtkStyleContext *context,
GtkSymbolicColor *color,
GdkRGBA *result)
{
+ GtkCssValue *val;
+
g_return_val_if_fail (GTK_IS_STYLE_CONTEXT (context), FALSE);
g_return_val_if_fail (color != NULL, FALSE);
g_return_val_if_fail (result != NULL, FALSE);
- return _gtk_symbolic_color_resolve_full (color,
- gtk_style_context_color_lookup_func,
- context,
- result);
+ val = _gtk_symbolic_color_resolve_full (color,
+ gtk_style_context_color_lookup_func,
+ context);
+ if (val == NULL)
+ return FALSE;
+
+ *result = *_gtk_css_value_get_rgba (val);
+ _gtk_css_value_unref (val);
+ return TRUE;
}
/**
diff --git a/gtk/gtkstylecontextprivate.h b/gtk/gtkstylecontextprivate.h
index 06efa0f..dbec998 100644
--- a/gtk/gtkstylecontextprivate.h
+++ b/gtk/gtkstylecontextprivate.h
@@ -41,6 +41,8 @@ gboolean _gtk_style_context_check_region_name (const gchar *s
gboolean _gtk_style_context_resolve_color (GtkStyleContext *context,
GtkSymbolicColor *color,
GdkRGBA *result);
+GtkCssValue * _gtk_style_context_resolve_color_value (GtkStyleContext *context,
+ GtkSymbolicColor *color);
void _gtk_style_context_get_cursor_color (GtkStyleContext *context,
GdkRGBA *primary_color,
GdkRGBA *secondary_color);
diff --git a/gtk/gtksymboliccolor.c b/gtk/gtksymboliccolor.c
index bb4c2b8..b96a234 100644
--- a/gtk/gtksymboliccolor.c
+++ b/gtk/gtksymboliccolor.c
@@ -58,10 +58,10 @@ struct _GtkSymbolicColor
{
ColorType type;
guint ref_count;
+ GtkCssValue *last_value;
union
{
- GdkRGBA color;
gchar *name;
struct
@@ -104,7 +104,7 @@ gtk_symbolic_color_new_literal (const GdkRGBA *color)
symbolic_color = g_slice_new0 (GtkSymbolicColor);
symbolic_color->type = COLOR_TYPE_LITERAL;
- symbolic_color->color = *color;
+ symbolic_color->last_value = _gtk_css_value_new_from_rgba (color);
symbolic_color->ref_count = 1;
return symbolic_color;
@@ -328,27 +328,28 @@ gtk_symbolic_color_unref (GtkSymbolicColor *color)
if (color->ref_count == 0)
{
+ _gtk_css_value_unref (color->last_value);
switch (color->type)
- {
- case COLOR_TYPE_NAME:
- g_free (color->name);
- break;
- case COLOR_TYPE_SHADE:
- gtk_symbolic_color_unref (color->shade.color);
- break;
- case COLOR_TYPE_ALPHA:
- gtk_symbolic_color_unref (color->alpha.color);
- break;
- case COLOR_TYPE_MIX:
- gtk_symbolic_color_unref (color->mix.color1);
- gtk_symbolic_color_unref (color->mix.color2);
- break;
- case COLOR_TYPE_WIN32:
- g_free (color->win32.theme_class);
- break;
- default:
- break;
- }
+ {
+ case COLOR_TYPE_NAME:
+ g_free (color->name);
+ break;
+ case COLOR_TYPE_SHADE:
+ gtk_symbolic_color_unref (color->shade.color);
+ break;
+ case COLOR_TYPE_ALPHA:
+ gtk_symbolic_color_unref (color->alpha.color);
+ break;
+ case COLOR_TYPE_MIX:
+ gtk_symbolic_color_unref (color->mix.color1);
+ gtk_symbolic_color_unref (color->mix.color2);
+ break;
+ case COLOR_TYPE_WIN32:
+ g_free (color->win32.theme_class);
+ break;
+ default:
+ break;
+ }
g_slice_free (GtkSymbolicColor, color);
}
@@ -560,106 +561,155 @@ resolve_lookup_color (gpointer data, const char *name)
**/
gboolean
gtk_symbolic_color_resolve (GtkSymbolicColor *color,
- GtkStyleProperties *props,
- GdkRGBA *resolved_color)
+ GtkStyleProperties *props,
+ GdkRGBA *resolved_color)
{
+ GtkCssValue *v;
+
g_return_val_if_fail (color != NULL, FALSE);
g_return_val_if_fail (resolved_color != NULL, FALSE);
g_return_val_if_fail (props == NULL || GTK_IS_STYLE_PROPERTIES (props), FALSE);
- return _gtk_symbolic_color_resolve_full (color,
- resolve_lookup_color,
- props,
- resolved_color);
+ v =_gtk_symbolic_color_resolve_full (color,
+ resolve_lookup_color,
+ props);
+ if (v == NULL)
+ return FALSE;
+
+ *resolved_color = *_gtk_css_value_get_rgba (v);
+ _gtk_css_value_unref (v);
+ return TRUE;
}
-gboolean
+GtkCssValue *
_gtk_symbolic_color_resolve_full (GtkSymbolicColor *color,
- GtkSymbolicColorLookupFunc func,
- gpointer data,
- GdkRGBA *resolved_color)
+ GtkSymbolicColorLookupFunc func,
+ gpointer data)
{
+ GtkCssValue *value;
+
g_return_val_if_fail (color != NULL, FALSE);
- g_return_val_if_fail (resolved_color != NULL, FALSE);
g_return_val_if_fail (func != NULL, FALSE);
+ value = NULL;
switch (color->type)
{
case COLOR_TYPE_LITERAL:
- *resolved_color = color->color;
- return TRUE;
+ return _gtk_css_value_ref (color->last_value);
case COLOR_TYPE_NAME:
{
- GtkSymbolicColor *named_color;
+ GtkSymbolicColor *named_color;
- named_color = func (data, color->name);
+ named_color = func (data, color->name);
- if (!named_color)
- return FALSE;
+ if (!named_color)
+ return NULL;
- return _gtk_symbolic_color_resolve_full (named_color, func, data, resolved_color);
+ return _gtk_symbolic_color_resolve_full (named_color, func, data);
}
break;
case COLOR_TYPE_SHADE:
{
- GdkRGBA shade;
+ GtkCssValue *val;
+ GdkRGBA shade;
- if (!_gtk_symbolic_color_resolve_full (color->shade.color, func, data, &shade))
- return FALSE;
+ val = _gtk_symbolic_color_resolve_full (color->shade.color, func, data);
+ if (val == NULL)
+ return NULL;
- _shade_color (&shade, color->shade.factor);
- *resolved_color = shade;
+ shade = *_gtk_css_value_get_rgba (val);
+ _shade_color (&shade, color->shade.factor);
- return TRUE;
+ _gtk_css_value_unref (val);
+
+ value = _gtk_css_value_new_from_rgba (&shade);
}
break;
case COLOR_TYPE_ALPHA:
{
- GdkRGBA alpha;
+ GtkCssValue *val;
+ GdkRGBA alpha;
+
+ val = _gtk_symbolic_color_resolve_full (color->alpha.color, func, data);
+ if (val == NULL)
+ return NULL;
- if (!_gtk_symbolic_color_resolve_full (color->alpha.color, func, data, &alpha))
- return FALSE;
+ alpha = *_gtk_css_value_get_rgba (val);
+ alpha.alpha = CLAMP (alpha.alpha * color->alpha.factor, 0, 1);
- *resolved_color = alpha;
- resolved_color->alpha = CLAMP (alpha.alpha * color->alpha.factor, 0, 1);
+ _gtk_css_value_unref (val);
- return TRUE;
+ value = _gtk_css_value_new_from_rgba (&alpha);
}
+ break;
+
case COLOR_TYPE_MIX:
{
- GdkRGBA color1, color2;
+ GtkCssValue *val;
+ GdkRGBA color1, color2, res;
- if (!_gtk_symbolic_color_resolve_full (color->mix.color1, func, data, &color1))
- return FALSE;
+ val = _gtk_symbolic_color_resolve_full (color->mix.color1, func, data);
+ if (val == NULL)
+ return NULL;
+ color1 = *_gtk_css_value_get_rgba (val);
+ _gtk_css_value_unref (val);
- if (!_gtk_symbolic_color_resolve_full (color->mix.color2, func, data, &color2))
- return FALSE;
+ val = _gtk_symbolic_color_resolve_full (color->mix.color2, func, data);
+ if (val == NULL)
+ return NULL;
+ color2 = *_gtk_css_value_get_rgba (val);
+ _gtk_css_value_unref (val);
- resolved_color->red = CLAMP (color1.red + ((color2.red - color1.red) * color->mix.factor), 0, 1);
- resolved_color->green = CLAMP (color1.green + ((color2.green - color1.green) * color->mix.factor), 0, 1);
- resolved_color->blue = CLAMP (color1.blue + ((color2.blue - color1.blue) * color->mix.factor), 0, 1);
- resolved_color->alpha = CLAMP (color1.alpha + ((color2.alpha - color1.alpha) * color->mix.factor), 0, 1);
- return TRUE;
+ res.red = CLAMP (color1.red + ((color2.red - color1.red) * color->mix.factor), 0, 1);
+ res.green = CLAMP (color1.green + ((color2.green - color1.green) * color->mix.factor), 0, 1);
+ res.blue = CLAMP (color1.blue + ((color2.blue - color1.blue) * color->mix.factor), 0, 1);
+ res.alpha = CLAMP (color1.alpha + ((color2.alpha - color1.alpha) * color->mix.factor), 0, 1);
+
+ value =_gtk_css_value_new_from_rgba (&res);
}
break;
case COLOR_TYPE_WIN32:
- return _gtk_win32_theme_color_resolve (color->win32.theme_class,
+ {
+ GdkRGBA res;
+
+ if (!_gtk_win32_theme_color_resolve (color->win32.theme_class,
color->win32.id,
- resolved_color);
+ &res))
+ return NULL;
+
+ value = _gtk_css_value_new_from_rgba (&res);
+ }
break;
case COLOR_TYPE_CURRENT_COLOR:
- return FALSE;
+ return NULL;
break;
default:
g_assert_not_reached ();
}
- return FALSE;
+ if (value != NULL)
+ {
+ if (color->last_value != NULL &&
+ gdk_rgba_equal (_gtk_css_value_get_rgba (color->last_value),
+ _gtk_css_value_get_rgba (value)))
+ {
+ _gtk_css_value_unref (value);
+ value = _gtk_css_value_ref (color->last_value);
+ }
+ else
+ {
+ if (color->last_value != NULL)
+ _gtk_css_value_unref (color->last_value);
+ color->last_value = _gtk_css_value_ref (value);
+ }
+ }
+
+ return value;
}
/**
@@ -684,7 +734,7 @@ gtk_symbolic_color_to_string (GtkSymbolicColor *color)
switch (color->type)
{
case COLOR_TYPE_LITERAL:
- s = gdk_rgba_to_string (&color->color);
+ s = gdk_rgba_to_string (_gtk_css_value_get_rgba (color->last_value));
break;
case COLOR_TYPE_NAME:
s = g_strconcat ("@", color->name, NULL);
diff --git a/gtk/gtksymboliccolorprivate.h b/gtk/gtksymboliccolorprivate.h
index a469626..869af69 100644
--- a/gtk/gtksymboliccolorprivate.h
+++ b/gtk/gtksymboliccolorprivate.h
@@ -19,15 +19,15 @@
#define __GTK_SYMBOLIC_COLOR_PRIVATE_H__
#include "gtk/gtksymboliccolor.h"
+#include "gtk/gtkcssvalueprivate.h"
G_BEGIN_DECLS
typedef GtkSymbolicColor * (* GtkSymbolicColorLookupFunc) (gpointer data, const char *name);
-gboolean _gtk_symbolic_color_resolve_full (GtkSymbolicColor *color,
+GtkCssValue * _gtk_symbolic_color_resolve_full (GtkSymbolicColor *color,
GtkSymbolicColorLookupFunc func,
- gpointer data,
- GdkRGBA *resolved_color);
+ gpointer data);
GtkSymbolicColor * _gtk_symbolic_color_get_current_color (void);
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]