[gtk+/wip/pango-shadow-cache: 5/5] pango shadow cache



commit 6defcce9e92b6e14466120e7b391e914fc3a1b2a
Author: Jasper St. Pierre <jstpierre mecheye net>
Date:   Fri Aug 29 13:51:30 2014 -0700

    pango shadow cache

 gtk/gtkcssshadowvalue.c |   64 +++++++++++++++++++++++++++++++++++++++-------
 1 files changed, 54 insertions(+), 10 deletions(-)
---
diff --git a/gtk/gtkcssshadowvalue.c b/gtk/gtkcssshadowvalue.c
index 7e8e3b0..22f21a5 100644
--- a/gtk/gtkcssshadowvalue.c
+++ b/gtk/gtkcssshadowvalue.c
@@ -322,6 +322,17 @@ needs_blur (const GtkCssValue *shadow)
   return TRUE;
 }
 
+static void
+setup_cairo_for_shadow_apply (const GtkCssValue *shadow,
+                              cairo_t           *cr)
+{
+  gdk_cairo_set_source_rgba (cr, _gtk_css_rgba_value_get_rgba (shadow->color));
+
+  cairo_translate (cr,
+                   _gtk_css_number_value_get (shadow->hoffset, 0),
+                   _gtk_css_number_value_get (shadow->voffset, 0));
+}
+
 static cairo_t *
 gtk_css_shadow_value_start_drawing (const GtkCssValue *shadow,
                                     cairo_t           *cr)
@@ -331,11 +342,7 @@ gtk_css_shadow_value_start_drawing (const GtkCssValue *shadow,
   cairo_t *blur_cr;
   gdouble radius, clip_radius;
 
-  gdk_cairo_set_source_rgba (cr, _gtk_css_rgba_value_get_rgba (shadow->color));
-
-  cairo_translate (cr,
-                   _gtk_css_number_value_get (shadow->hoffset, 0),
-                   _gtk_css_number_value_get (shadow->voffset, 0));
+  setup_cairo_for_shadow_apply (shadow, cr);
 
   if (!needs_blur (shadow))
     return cr;
@@ -389,6 +396,17 @@ gtk_css_shadow_value_finish_drawing (const GtkCssValue *shadow,
   return original_cr;
 }
 
+static char *
+shadow_value_get_hash_string (const GtkCssValue *shadow)
+{
+  /* We use this for caching blurred layouts, and layouts don't
+   * support spread, so we don't need to add spread here. */
+  return g_strdup_printf ("gtk+ shadow blur radius=%d spread=%d %s",
+                          (int) _gtk_css_number_value_get (shadow->radius, 0),
+                          (int) _gtk_css_number_value_get (shadow->spread, 0),
+                          shadow->inset ? "inset=y" : "inset=n");
+}
+
 void
 _gtk_css_shadow_value_paint_layout (const GtkCssValue *shadow,
                                     cairo_t           *cr,
@@ -399,11 +417,37 @@ _gtk_css_shadow_value_paint_layout (const GtkCssValue *shadow,
   if (!cairo_has_current_point (cr))
     cairo_move_to (cr, 0, 0);
 
-  cairo_save (cr);
-  cr = gtk_css_shadow_value_start_drawing (shadow, cr);
-  _gtk_pango_fill_layout (cr, layout);
-  cr = gtk_css_shadow_value_finish_drawing (shadow, cr);
-  cairo_restore (cr);
+  if (needs_blur (shadow))
+    {
+      char *hash_string = shadow_value_get_hash_string (shadow);
+      cairo_surface_t *cached_surface = g_object_get_data (G_OBJECT (layout), hash_string);
+      if (cached_surface)
+        {
+          setup_cairo_for_shadow_apply (shadow, cr);
+          cairo_mask_surface (cr, cached_surface, 0, 0);
+        }
+      else
+        {
+          cairo_save (cr);
+          cr = gtk_css_shadow_value_start_drawing (shadow, cr);
+          _gtk_pango_fill_layout (cr, layout);
+          cached_surface = cairo_get_target (cr);
+          g_object_set_data_full (G_OBJECT (layout), hash_string,
+                                  cairo_surface_reference (cached_surface),
+                                  (GDestroyNotify) cairo_surface_destroy);
+          cr = gtk_css_shadow_value_finish_drawing (shadow, cr);
+          cairo_restore (cr);
+        }
+      g_free (hash_string);
+    }
+  else
+    {
+      cairo_save (cr);
+      cr = gtk_css_shadow_value_start_drawing (shadow, cr);
+      _gtk_pango_fill_layout (cr, layout);
+      cr = gtk_css_shadow_value_finish_drawing (shadow, cr);
+      cairo_restore (cr);
+    }
 }
 
 void


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]