hippo-canvas r7261 - in trunk: linux/hippo tests



Author: otaylor
Date: Sun May 25 01:00:09 2008
New Revision: 7261
URL: http://svn.gnome.org/viewvc/hippo-canvas?rev=7261&view=rev

Log:
Support canvas { background-color: <translucent color> }
 if we have a RGBA visual.


Modified:
   trunk/linux/hippo/hippo-canvas-helper.c
   trunk/tests/test.css

Modified: trunk/linux/hippo/hippo-canvas-helper.c
==============================================================================
--- trunk/linux/hippo/hippo-canvas-helper.c	(original)
+++ trunk/linux/hippo/hippo-canvas-helper.c	Sun May 25 01:00:09 2008
@@ -109,6 +109,7 @@
 
     unsigned int root_hovering : 1;
     unsigned int fixing_up_resize_state : 1;
+    unsigned int need_background_paint : 1;
 };
 
 struct _HippoCanvasHelperClass {
@@ -387,21 +388,38 @@
 {
     
     cairo_t *cr;
-    int window_x, window_y;
-    HippoRectangle damage_box;
-
-    if (helper->root == NULL)
-        return FALSE;
 
     cr = gdk_cairo_create(event->window);
-    get_root_item_window_coords(helper, &window_x, &window_y);
 
-    damage_box.x = event->area.x;
-    damage_box.y = event->area.y;
-    damage_box.width = event->area.width;
-    damage_box.height = event->area.height;
-    hippo_canvas_item_process_paint(helper->root, cr, &damage_box,
-                                    window_x, window_y);
+    if (helper->need_background_paint) {
+        HippoCanvasStyle *style = hippo_canvas_context_get_style(HIPPO_CANVAS_CONTEXT(helper));
+        guint32 color = hippo_canvas_style_get_background_color(style);
+
+        cairo_save(cr);
+        cairo_set_source_rgba(cr,
+                              ((color & 0xFF000000) >> 24) / 255.,
+                              ((color & 0x00FF0000) >> 16) / 255.,
+                              ((color & 0x0000FF00) >> 8) / 255.,
+                              ((color & 0x000000FF)) / 255.);
+        cairo_set_operator(cr, CAIRO_OPERATOR_SOURCE);
+        cairo_paint(cr);
+        cairo_restore(cr);
+    }
+
+    if (helper->root != NULL) {
+        int window_x, window_y;
+        HippoRectangle damage_box;
+    
+        get_root_item_window_coords(helper, &window_x, &window_y);
+
+        damage_box.x = event->area.x;
+        damage_box.y = event->area.y;
+        damage_box.width = event->area.width;
+        damage_box.height = event->area.height;
+        hippo_canvas_item_process_paint(helper->root, cr, &damage_box,
+                                        window_x, window_y);
+    }
+    
     cairo_destroy(cr);
 
     return FALSE;
@@ -706,6 +724,14 @@
     cancel_tooltip(helper);
 }
 
+static int
+premultiply(int component,
+            int alpha)
+{
+    int temp = component * alpha + 0x80;
+    return ((temp >> 8) + temp) >> 8;
+}
+
 void
 hippo_canvas_helper_set_window_background (HippoCanvasHelper *helper,
                                            GdkWindow         *window)
@@ -713,18 +739,51 @@
     HippoCanvasStyle *style = hippo_canvas_context_get_style(HIPPO_CANVAS_CONTEXT(helper));
     guint32 color;
     
+    helper->need_background_paint = FALSE;
+
+    /* We don't use hippo_canvas_style_get_background_color() here because we treat
+     * background-color: transparent on the canvas as being different from
+     * not specifying it ... which should give us the theme color. Perhaps
+     * a cleaner thing to do would be to support the CSS2 system colors
+     * and have a default stylesheet with canvas { background-color: Window; }
+     */
     if (hippo_canvas_style_get_color(style, "background-color", FALSE, &color)) {
         GdkColormap *colormap = gdk_window_get_colormap(window);
+        GdkVisual *visual = gdk_colormap_get_visual(colormap);
         GdkColor color_gdk;
 
-        color_gdk.red =   (color & 0xFF000000) >> 24;
-        color_gdk.red = color_gdk.red * 0x101;
-        color_gdk.green = (color & 0x00FF0000) >> 16;
-        color_gdk.green = color_gdk.green * 0x101;
-        color_gdk.blue =  (color & 0x0000FF00) >> 8;
-        color_gdk.blue = color_gdk.blue * 0x101;
-
-        gdk_rgb_find_color(colormap, &color_gdk);
+        /* Special-case the RGBA visual. If visuals other than ARGB32 were in use
+         * (say ABGR32) then we should support them here as well.
+         */
+        if (visual->depth == 32 &&
+            visual->red_mask == 0xff0000 &&
+            visual->green_mask == 0x00ff00 &&
+            visual->blue_mask  == 0x0000ff)
+        {
+            int alpha = color & 0x000000FF;
+
+            if (alpha != 0xFF)
+                /* GTK+ (as of 2.12) doesn't handle clearing to a RGBA color correctly
+                 * so we'll need to fix up the double-buffer pixmap ourself.
+                 */
+                helper->need_background_paint = TRUE;
+
+            color_gdk.pixel = ((alpha << 24) |
+                               (premultiply((color & 0xFF000000) >> 24, alpha) << 16) |
+                               (premultiply((color & 0x00FF0000) >> 16, alpha) << 8) |
+                               (premultiply((color & 0x0000FF00) >> 8,  alpha)));
+	}
+        else
+        {
+            color_gdk.red =   (color & 0xFF000000) >> 24;
+            color_gdk.red = color_gdk.red * 0x101;
+            color_gdk.green = (color & 0x00FF0000) >> 16;
+            color_gdk.green = color_gdk.green * 0x101;
+            color_gdk.blue =  (color & 0x0000FF00) >> 8;
+            color_gdk.blue = color_gdk.blue * 0x101;
+            
+            gdk_rgb_find_color(colormap, &color_gdk);
+        }
 
         gdk_window_set_background(window, &color_gdk);
     } else {

Modified: trunk/tests/test.css
==============================================================================
--- trunk/tests/test.css	(original)
+++ trunk/tests/test.css	Sun May 25 01:00:09 2008
@@ -1,6 +1,3 @@
-/* The canvas itself doesn't paint a background, but it's immediate box
- * child does.
- */
 canvas {
     background-color: white;
 }



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