[gtk+/client-side-windows: 23/284] Track clip_mask in GdkGC. Fix gdk_gc_add_drawable_clip to handle clip masks



commit b647c6e5fdae7d814f0926881c2827e2b7a10195
Author: Alexander Larsson <alexl redhat com>
Date:   Thu Dec 4 21:38:19 2008 +0100

    Track clip_mask in GdkGC. Fix gdk_gc_add_drawable_clip to handle clip masks
---
 gdk/gdkgc.c |   95 ++++++++++++++++++++++++++++++++++++++++++++++++++--------
 1 files changed, 82 insertions(+), 13 deletions(-)

diff --git a/gdk/gdkgc.c b/gdk/gdkgc.c
index a85a3b7..f3ac968 100644
--- a/gdk/gdkgc.c
+++ b/gdk/gdkgc.c
@@ -48,12 +48,15 @@ struct _GdkGCPrivate
   int region_tag_offset_y;
   
   GdkRegion *old_clip_region;
+  GdkPixmap *old_clip_mask;
   
   GdkSubwindowMode subwindow_mode;
   
   GdkFill fill;
   GdkBitmap *stipple;
   GdkPixmap *tile;
+
+  GdkPixmap *clip_mask;
   
   guint32 fg_pixel;
   guint32 bg_pixel;
@@ -158,6 +161,8 @@ _gdk_gc_init (GdkGC           *gc,
     gc->clip_x_origin = values->clip_x_origin;
   if (values_mask & GDK_GC_CLIP_Y_ORIGIN)
     gc->clip_y_origin = values->clip_y_origin;
+  if ((values_mask & GDK_GC_CLIP_MASK) && values->clip_mask)
+    priv->clip_mask = g_object_ref (values->clip_mask);
   if (values_mask & GDK_GC_TS_X_ORIGIN)
     gc->ts_x_origin = values->ts_x_origin;
   if (values_mask & GDK_GC_TS_Y_ORIGIN)
@@ -198,6 +203,10 @@ gdk_gc_finalize (GObject *object)
     gdk_region_destroy (priv->clip_region);
   if (priv->old_clip_region)
     gdk_region_destroy (priv->old_clip_region);
+  if (priv->clip_mask)
+    g_object_unref (priv->clip_mask);
+  if (priv->old_clip_mask)
+    g_object_unref (priv->old_clip_mask);
   if (gc->colormap)
     g_object_unref (gc->colormap);
   if (priv->tile)
@@ -297,6 +306,14 @@ gdk_gc_set_values (GdkGC           *gc,
     gc->ts_y_origin = values->ts_y_origin;
   if (values_mask & GDK_GC_CLIP_MASK)
     {
+      if (priv->clip_mask)
+	{
+	  g_object_unref (priv->clip_mask);
+	  priv->clip_mask = NULL;
+	}
+      if (values->clip_mask)
+	priv->clip_mask = g_object_ref (values->clip_mask);
+      
       if (priv->clip_region)
 	{
 	  gdk_region_destroy (priv->clip_region);
@@ -570,6 +587,12 @@ _gdk_gc_set_clip_region_real (GdkGC     *gc,
 {
   GdkGCPrivate *priv = GDK_GC_GET_PRIVATE (gc);
 
+  if (priv->clip_mask)
+    {
+      g_object_unref (priv->clip_mask);
+      priv->clip_mask = NULL;
+    }
+  
   if (priv->clip_region)
     gdk_region_destroy (priv->clip_region);
 
@@ -607,21 +630,48 @@ _gdk_gc_add_drawable_clip (GdkGC     *gc,
   if (priv->region_tag_applied)
     _gdk_gc_remove_drawable_clip (gc);
 
-  priv->region_tag_applied = region_tag;
-  priv->region_tag_offset_x = offset_x;
-  priv->region_tag_offset_y = offset_y;
-  
-  priv->old_clip_region = priv->clip_region;
-
   region = gdk_region_copy (region);
   if (offset_x != 0 || offset_y != 0)
     gdk_region_offset (region, offset_x, offset_y);
-  
-  priv->clip_region = region;
-  if (priv->old_clip_region)
-    gdk_region_intersect (region, priv->old_clip_region);
 
-  _gdk_windowing_gc_set_clip_region (gc, priv->clip_region, FALSE);
+  if (priv->clip_mask)
+    {
+      int w, h;
+      GdkPixmap *new_mask;
+      GdkGC *tmp_gc;
+      GdkColor black = {0, 0, 0, 0};
+      
+      priv->old_clip_mask = g_object_ref (priv->clip_mask);
+      gdk_drawable_get_size (priv->old_clip_mask, &w, &h);
+
+      new_mask = gdk_pixmap_new	(priv->old_clip_mask, w, h, -1);
+      tmp_gc = _gdk_drawable_get_scratch_gc ((GdkDrawable *)new_mask, FALSE);
+
+      gdk_gc_set_foreground (tmp_gc, &black);
+      gdk_draw_rectangle (new_mask, tmp_gc, TRUE, 0, 0, -1, -1);
+      _gdk_gc_set_clip_region_internal (tmp_gc, region, TRUE); /* Takes ownership of region */
+      gdk_draw_drawable  (new_mask,
+			  tmp_gc,
+			  priv->old_clip_mask,
+			  0, 0,
+			  0, 0,
+			  -1, -1);
+      gdk_gc_set_clip_region (tmp_gc, NULL);
+      gdk_gc_set_clip_mask (gc, new_mask);
+    }
+  else
+    {
+      priv->old_clip_region = priv->clip_region;
+      priv->clip_region = region;
+      if (priv->old_clip_region)
+	gdk_region_intersect (region, priv->old_clip_region);
+      
+      _gdk_windowing_gc_set_clip_region (gc, priv->clip_region, FALSE);
+    }
+
+  priv->region_tag_applied = region_tag;
+  priv->region_tag_offset_x = offset_x;
+  priv->region_tag_offset_y = offset_y;
 }
 
 void
@@ -631,9 +681,18 @@ _gdk_gc_remove_drawable_clip (GdkGC *gc)
 
   if (priv->region_tag_applied)
     {
-      _gdk_gc_set_clip_region_real (gc, priv->old_clip_region, FALSE);
-      priv->old_clip_region = NULL;
       priv->region_tag_applied = 0;
+      if (priv->old_clip_mask)
+	{
+	  gdk_gc_set_clip_mask (gc, priv->old_clip_mask);
+	  g_object_unref (priv->old_clip_mask);
+	  priv->old_clip_mask = NULL;
+	}
+      else
+	{
+	  _gdk_gc_set_clip_region_real (gc, priv->old_clip_region, FALSE);
+	  priv->old_clip_region = NULL;
+	}
     }
 }
 
@@ -999,6 +1058,16 @@ gdk_gc_copy (GdkGC *dst_gc,
     dst_priv->old_clip_region = gdk_region_copy (src_priv->old_clip_region);
   else
     dst_priv->old_clip_region = NULL;
+
+  if (src_priv->clip_mask)
+    dst_priv->clip_mask = g_object_ref (src_priv->clip_mask);
+  else
+    dst_priv->clip_mask = NULL;
+  
+  if (src_priv->old_clip_mask)
+    dst_priv->old_clip_mask = g_object_ref (src_priv->old_clip_mask);
+  else
+    dst_priv->old_clip_mask = NULL;
   
   dst_priv->fill = src_priv->fill;
   



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