[gnome-shell] StThemeNodeDrawing: generalize render_gradient to render_background_with_border



commit a7fa7d748dd285023d3fcdc770f185c7ea8d51d4
Author: Ray Strode <rstrode redhat com>
Date:   Sun Dec 12 15:41:41 2010 -0500

    StThemeNodeDrawing: generalize render_gradient to render_background_with_border
    
    A lot of the border drawing logic in st_theme_node_render_gradient is
    applicable to other non-solid background types than gradients.
    
    This commit refactors that code so that support for other non-solid
    background types can be more easily integrated later.
    
    https://bugzilla.gnome.org/show_bug.cgi?id=636976

 src/st/st-theme-node-drawing.c |   97 +++++++++++++++++++++++++++------------
 1 files changed, 67 insertions(+), 30 deletions(-)
---
diff --git a/src/st/st-theme-node-drawing.c b/src/st/st-theme-node-drawing.c
index 9ffb7bb..59b3f84 100644
--- a/src/st/st-theme-node-drawing.c
+++ b/src/st/st-theme-node-drawing.c
@@ -451,15 +451,54 @@ st_theme_node_has_visible_outline (StThemeNode *node)
   return FALSE;
 }
 
+static cairo_pattern_t *
+create_cairo_pattern_of_background_gradient (StThemeNode *node)
+{
+  cairo_pattern_t *pattern;
+
+  g_return_val_if_fail (node->background_gradient_type != ST_GRADIENT_NONE,
+                        NULL);
+
+  if (node->background_gradient_type == ST_GRADIENT_VERTICAL)
+    pattern = cairo_pattern_create_linear (0, 0, 0, node->alloc_height);
+  else if (node->background_gradient_type == ST_GRADIENT_HORIZONTAL)
+    pattern = cairo_pattern_create_linear (0, 0, node->alloc_width, 0);
+  else
+    {
+      gdouble cx, cy;
+
+      cx = node->alloc_width / 2.;
+      cy = node->alloc_height / 2.;
+      pattern = cairo_pattern_create_radial (cx, cy, 0, cx, cy, MIN (cx, cy));
+    }
+
+  cairo_pattern_add_color_stop_rgba (pattern, 0,
+                                     node->background_color.red / 255.,
+                                     node->background_color.green / 255.,
+                                     node->background_color.blue / 255.,
+                                     node->background_color.alpha / 255.);
+  cairo_pattern_add_color_stop_rgba (pattern, 1,
+                                     node->background_gradient_end.red / 255.,
+                                     node->background_gradient_end.green / 255.,
+                                     node->background_gradient_end.blue / 255.,
+                                     node->background_gradient_end.alpha / 255.);
+  return pattern;
+}
+
+/* In order for borders to be smoothly blended with non-solid backgrounds,
+ * we need to use cairo.  This function is a slow fallback path for those
+ * cases.  It currently only supports gradients, however.
+ */
 static CoglHandle
-st_theme_node_render_gradient (StThemeNode *node)
+st_theme_node_render_background_with_border (StThemeNode *node)
 {
   StBorderImage *border_image;
   CoglHandle texture;
   int radius[4], i;
   cairo_t *cr;
   cairo_surface_t *surface;
-  cairo_pattern_t *pattern;
+  cairo_pattern_t *pattern = NULL;
+  gboolean draw_solid_background;
   ClutterColor border_color;
   int border_width[4];
   guint rowstride;
@@ -486,30 +525,17 @@ st_theme_node_render_gradient (StThemeNode *node)
       radius[i] = st_theme_node_get_border_radius (node, i);
     }
 
-  if (node->background_gradient_type == ST_GRADIENT_VERTICAL)
-    pattern = cairo_pattern_create_linear (0, 0, 0, node->alloc_height);
-  else if (node->background_gradient_type == ST_GRADIENT_HORIZONTAL)
-    pattern = cairo_pattern_create_linear (0, 0, node->alloc_width, 0);
+  if (node->background_gradient_type != ST_GRADIENT_NONE)
+    {
+      pattern = create_cairo_pattern_of_background_gradient (node);
+      draw_solid_background = FALSE;
+    }
   else
     {
-      gdouble cx, cy;
-
-      cx = node->alloc_width / 2.;
-      cy = node->alloc_height / 2.;
-      pattern = cairo_pattern_create_radial (cx, cy, 0, cx, cy, MIN (cx, cy));
+      g_warning ("st_theme_node_render_background_with_border called with non-gradient background (which isn't yet supported). Falling back to solid background color.");
+      draw_solid_background = TRUE;
     }
 
-  cairo_pattern_add_color_stop_rgba (pattern, 0,
-                                     node->background_color.red / 255.,
-                                     node->background_color.green / 255.,
-                                     node->background_color.blue / 255.,
-                                     node->background_color.alpha / 255.);
-  cairo_pattern_add_color_stop_rgba (pattern, 1,
-                                     node->background_gradient_end.red / 255.,
-                                     node->background_gradient_end.green / 255.,
-                                     node->background_gradient_end.blue / 255.,
-                                     node->background_gradient_end.alpha / 255.);
-
   /* Create a path for the background's outline first */
   if (radius[ST_CORNER_TOPLEFT] > 0)
     cairo_arc (cr,
@@ -538,11 +564,10 @@ st_theme_node_render_gradient (StThemeNode *node)
                radius[ST_CORNER_BOTTOMLEFT], M_PI / 2, M_PI);
   cairo_close_path (cr);
 
-
-  /* If we have a solid border, we fill the outline with the border
-   * color and create the inline shape for the background gradient;
+  /* If we have a solid border, we fill the outline shape with the border
+   * color and create the inline shape for the background;
    * otherwise the outline shape is filled with the background
-   * gradient directly
+   * directly
    */
   if (border_image == NULL &&
       (border_width[ST_SIDE_TOP] > 0 ||
@@ -624,10 +649,22 @@ st_theme_node_render_gradient (StThemeNode *node)
       cairo_close_path (cr);
     }
 
-  cairo_set_source (cr, pattern);
-  cairo_fill (cr);
+  if (draw_solid_background)
+    {
+      cairo_set_source_rgba (cr,
+                             node->background_color.red / 255.,
+                             node->background_color.green / 255.,
+                             node->background_color.blue / 255.,
+                             node->background_color.alpha / 255.);
+      cairo_fill_preserve (cr);
+    }
 
-  cairo_pattern_destroy (pattern);
+  if (pattern != NULL)
+    {
+      cairo_set_source (cr, pattern);
+      cairo_fill (cr);
+      cairo_pattern_destroy (pattern);
+    }
 
   texture = cogl_texture_new_from_data (node->alloc_width, node->alloc_height,
                                         COGL_TEXTURE_NONE,
@@ -741,7 +778,7 @@ st_theme_node_render_resources (StThemeNode   *node,
     }
 
   if (node->background_gradient_type != ST_GRADIENT_NONE)
-    node->prerendered_texture = st_theme_node_render_gradient (node);
+    node->prerendered_texture = st_theme_node_render_background_with_border (node);
 
   if (node->border_slices_texture)
     node->border_slices_material = _st_create_texture_material (node->border_slices_texture);



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