[gtk+/wip/cssvalue] Use GtkCssValue in symbolic color resolving



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]