[gtk+/client-side-windows: 21/284] Move drawable clip tracking into GdkGC
- From: Alexander Larsson <alexl src gnome org>
- To: svn-commits-list gnome org
- Subject: [gtk+/client-side-windows: 21/284] Move drawable clip tracking into GdkGC
- Date: Thu, 2 Apr 2009 14:01:28 -0400 (EDT)
commit e9ee842db1cec299f6b67ecfa9eb23985d60aad3
Author: Alexander Larsson <alexl redhat com>
Date: Thu Dec 4 20:18:02 2008 +0100
Move drawable clip tracking into GdkGC
---
gdk/gdkgc.c | 91 ++++++++++++++++++++++++++++++++++++++--------------
gdk/gdkinternals.h | 11 +++---
gdk/gdkwindow.c | 71 +++++++++++++++++++++-------------------
gdk/gdkwindow.h | 1 +
4 files changed, 112 insertions(+), 62 deletions(-)
diff --git a/gdk/gdkgc.c b/gdk/gdkgc.c
index 6bc3a99..355a346 100644
--- a/gdk/gdkgc.c
+++ b/gdk/gdkgc.c
@@ -43,6 +43,10 @@ struct _GdkGCPrivate
{
GdkRegion *clip_region;
+ guint32 region_tag_applied;
+
+ GdkRegion *old_clip_region;
+
GdkSubwindowMode subwindow_mode;
GdkFill fill;
@@ -190,6 +194,8 @@ gdk_gc_finalize (GObject *object)
if (priv->clip_region)
gdk_region_destroy (priv->clip_region);
+ if (priv->old_clip_region)
+ gdk_region_destroy (priv->old_clip_region);
if (gc->colormap)
g_object_unref (gc->colormap);
if (priv->tile)
@@ -273,6 +279,12 @@ gdk_gc_set_values (GdkGC *gc,
priv = GDK_GC_GET_PRIVATE (gc);
+ if ((values_mask & GDK_GC_CLIP_X_ORIGIN) ||
+ (values_mask & GDK_GC_CLIP_Y_ORIGIN) ||
+ (values_mask & GDK_GC_CLIP_MASK) ||
+ (values_mask & GDK_GC_SUBWINDOW))
+ _gdk_gc_remove_drawable_clip (gc);
+
if (values_mask & GDK_GC_CLIP_X_ORIGIN)
gc->clip_x_origin = values->clip_x_origin;
if (values_mask & GDK_GC_CLIP_Y_ORIGIN)
@@ -549,10 +561,10 @@ gdk_gc_set_clip_mask (GdkGC *gc,
}
/* Takes ownership of passed in region */
-void
-_gdk_gc_set_clip_region_internal (GdkGC *gc,
- GdkRegion *region,
- gboolean reset_origin)
+static void
+_gdk_gc_set_clip_region_real (GdkGC *gc,
+ GdkRegion *region,
+ gboolean reset_origin)
{
GdkGCPrivate *priv = GDK_GC_GET_PRIVATE (gc);
@@ -564,37 +576,54 @@ _gdk_gc_set_clip_region_internal (GdkGC *gc,
_gdk_windowing_gc_set_clip_region (gc, region, reset_origin);
}
+/* Doesn't copy region, allows not to reset origin */
+void
+_gdk_gc_set_clip_region_internal (GdkGC *gc,
+ GdkRegion *region,
+ gboolean reset_origin)
+{
+ _gdk_gc_remove_drawable_clip (gc);
+ _gdk_gc_set_clip_region_real (gc, region, reset_origin);
+}
+
+
/* returns old clip region */
void
-_gdk_gc_intersect_clip_region (GdkGC *gc,
- GdkRegion *region,
- int offset_x,
- int offset_y,
- GdkRegion **old_clip_region)
+_gdk_gc_add_drawable_clip (GdkGC *gc,
+ guint32 region_tag,
+ GdkRegion *region,
+ int offset_x,
+ int offset_y)
{
GdkGCPrivate *priv = GDK_GC_GET_PRIVATE (gc);
- GdkRegion *old_clip;
- gboolean free;
- old_clip = priv->clip_region;
+ g_assert (priv->old_clip_region == NULL);
+
+ priv->region_tag_applied = region_tag;
+ 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 (old_clip)
- gdk_region_intersect (region, old_clip);
+ if (priv->old_clip_region)
+ gdk_region_intersect (region, priv->old_clip_region);
- if (old_clip_region)
- *old_clip_region = old_clip;
- else
- gdk_region_destroy (old_clip);
-
_gdk_windowing_gc_set_clip_region (gc, priv->clip_region, FALSE);
-
- return old_clip;
+}
+
+void
+_gdk_gc_remove_drawable_clip (GdkGC *gc)
+{
+ GdkGCPrivate *priv = GDK_GC_GET_PRIVATE (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;
+ }
}
/**
@@ -614,12 +643,14 @@ gdk_gc_set_clip_rectangle (GdkGC *gc,
g_return_if_fail (GDK_IS_GC (gc));
+ _gdk_gc_remove_drawable_clip (gc);
+
if (rectangle)
region = gdk_region_rectangle (rectangle);
else
region = NULL;
- _gdk_gc_set_clip_region_internal (gc, region, TRUE);
+ _gdk_gc_set_clip_region_real (gc, region, TRUE);
}
/**
@@ -639,12 +670,14 @@ gdk_gc_set_clip_region (GdkGC *gc,
g_return_if_fail (GDK_IS_GC (gc));
+ _gdk_gc_remove_drawable_clip (gc);
+
if (region)
copy = gdk_region_copy (region);
else
copy = NULL;
- _gdk_gc_set_clip_region_internal (gc, copy, TRUE);
+ _gdk_gc_set_clip_region_real (gc, copy, TRUE);
}
/**
@@ -945,6 +978,16 @@ gdk_gc_copy (GdkGC *dst_gc,
dst_priv->clip_region = gdk_region_copy (src_priv->clip_region);
else
dst_priv->clip_region = NULL;
+
+ dst_priv->region_tag_applied = src_priv->region_tag_applied;
+
+ if (dst_priv->old_clip_region)
+ gdk_region_destroy (dst_priv->old_clip_region);
+
+ if (src_priv->old_clip_region)
+ dst_priv->old_clip_region = gdk_region_copy (src_priv->old_clip_region);
+ else
+ dst_priv->old_clip_region = NULL;
dst_priv->fill = src_priv->fill;
diff --git a/gdk/gdkinternals.h b/gdk/gdkinternals.h
index 995f3bf..c9d5378 100644
--- a/gdk/gdkinternals.h
+++ b/gdk/gdkinternals.h
@@ -293,11 +293,12 @@ GdkPixmap *_gdk_gc_get_tile (GdkGC *gc);
GdkBitmap *_gdk_gc_get_stipple (GdkGC *gc);
guint32 _gdk_gc_get_fg_pixel (GdkGC *gc);
guint32 _gdk_gc_get_bg_pixel (GdkGC *gc);
-void _gdk_gc_intersect_clip_region (GdkGC *gc,
- GdkRegion *region,
- int offset_x,
- int offset_y,
- GdkRegion **old_region);
+void _gdk_gc_add_drawable_clip (GdkGC *gc,
+ guint32 region_tag,
+ GdkRegion *region,
+ int offset_x,
+ int offset_y);
+void _gdk_gc_remove_drawable_clip (GdkGC *gc);
void _gdk_gc_set_clip_region_internal (GdkGC *gc,
GdkRegion *region,
gboolean reset_origin);
diff --git a/gdk/gdkwindow.c b/gdk/gdkwindow.c
index 5d9b812..7043b83 100644
--- a/gdk/gdkwindow.c
+++ b/gdk/gdkwindow.c
@@ -69,6 +69,7 @@ struct _GdkWindowPaint
gint y_offset;
cairo_surface_t *surface;
guint uses_implicit : 1;
+ guint32 region_tag;
};
/* Global info */
@@ -234,6 +235,14 @@ static gpointer parent_class = NULL;
static const cairo_user_data_key_t gdk_window_cairo_key;
+static guint32
+new_region_tag (void)
+{
+ static guint32 tag = 0;
+
+ return ++tag;
+}
+
GType
gdk_window_object_get_type (void)
{
@@ -509,6 +518,7 @@ recompute_visible_regions_internal (GdkWindowObject *private,
if (private->clip_region)
gdk_region_destroy (private->clip_region);
private->clip_region = new_clip;
+ private->clip_tag = new_region_tag ();
private->clip_region_with_children = gdk_region_copy (private->clip_region);
remove_child_area (private, NULL, private->clip_region_with_children);
@@ -1925,17 +1935,19 @@ gdk_window_begin_paint_region (GdkWindow *window,
implicit_paint = impl_window->implicit_paint;
paint = g_new (GdkWindowPaint, 1);
+ paint->region = gdk_region_copy (region);
+ paint->region_tag = new_region_tag ();
+
if (implicit_paint)
{
int width, height;
-
+
paint->uses_implicit = TRUE;
paint->pixmap = g_object_ref (implicit_paint->pixmap);
paint->x_offset = -private->abs_x + implicit_paint->x_offset;
paint->y_offset = -private->abs_y + implicit_paint->y_offset;
- paint->region = gdk_region_copy (region);
gdk_region_intersect (paint->region, private->clip_region_with_children);
-
+
/* It would be nice if we had some cairo support here so we
could set the clip rect on the cairo surface */
width = private->abs_x + private->width;
@@ -1943,9 +1955,6 @@ gdk_window_begin_paint_region (GdkWindow *window,
paint->surface = _gdk_windowing_create_cairo_surface (((GdkPixmapObject *)paint->pixmap)->impl,
width, height);
- if (paint->surface)
- cairo_surface_set_device_offset (paint->surface,
- - paint->x_offset, - paint->y_offset);
/* Mark the region as valid on the implicit paint */
gdk_region_offset (paint->region, private->abs_x, private->abs_y);
@@ -1955,19 +1964,18 @@ gdk_window_begin_paint_region (GdkWindow *window,
else
{
paint->uses_implicit = FALSE;
- paint->region = gdk_region_copy (region);
paint->x_offset = clip_box.x;
paint->y_offset = clip_box.y;
paint->pixmap =
gdk_pixmap_new (window,
MAX (clip_box.width, 1), MAX (clip_box.height, 1), -1);
-
paint->surface = _gdk_drawable_ref_cairo_surface (paint->pixmap);
- cairo_surface_set_device_offset (paint->surface,
- - paint->x_offset, - paint->y_offset);
}
+
+ if (paint->surface)
+ cairo_surface_set_device_offset (paint->surface,
+ -paint->x_offset, -paint->y_offset);
-
for (list = private->paint_stack; list != NULL; list = list->next)
{
GdkWindowPaint *tmp_paint = list->data;
@@ -2264,8 +2272,7 @@ gdk_window_get_internal_paint_info (GdkWindow *window,
static void
setup_clip_for_draw (GdkDrawable *drawable,
GdkGC *gc,
- int old_clip_x, int old_clip_y,
- GdkRegion **old_clip_region)
+ int old_clip_x, int old_clip_y)
{
GdkWindowObject *private = (GdkWindowObject *)drawable;
GdkRegion *clip;
@@ -2275,27 +2282,27 @@ setup_clip_for_draw (GdkDrawable *drawable,
else
clip = private->clip_region;
- _gdk_gc_intersect_clip_region (gc, clip,
- /* If there was a clip origin set appart from the
- * window offset, need to take that into consideration */
- -old_clip_x, -old_clip_y,
- old_clip_region);
+ _gdk_gc_add_drawable_clip (gc,
+ private->clip_tag,
+ clip,
+ /* If there was a clip origin set appart from the
+ * window offset, need to take that into consideration */
+ -old_clip_x, -old_clip_y);
}
static void
setup_clip_for_paint (GdkDrawable *drawable,
GdkWindowPaint *paint,
GdkGC *gc,
- int old_clip_x, int old_clip_y,
- GdkRegion **old_clip_region)
+ int old_clip_x, int old_clip_y)
{
- _gdk_gc_intersect_clip_region (gc,
- /* This includes the window clip */
- paint->region,
- /* If there was a clip origin set appart from the
- * window offset, need to take that into consideration */
- -old_clip_x, -old_clip_y,
- old_clip_region);
+ _gdk_gc_add_drawable_clip (gc,
+ paint->region_tag,
+ /* This includes the window clip */
+ paint->region,
+ /* If there was a clip origin set appart from the
+ * window offset, need to take that into consideration */
+ -old_clip_x, -old_clip_y);
}
@@ -2322,23 +2329,21 @@ setup_clip_for_paint (GdkDrawable *drawable,
}
#define SETUP_PAINT_GC_CLIP(gc) \
- GdkRegion *old_clip_region; \
if (paint->uses_implicit) \
setup_clip_for_paint (drawable, paint, gc, old_clip_x, \
- old_clip_y, &old_clip_region);
+ old_clip_y);
#define RESTORE_PAINT_GC_CLIP(gc) \
if (paint->uses_implicit) \
- _gdk_gc_set_clip_region_internal (gc, old_clip_region, FALSE);
+ _gdk_gc_remove_drawable_clip (gc);
#define SETUP_DIRECT_GC_CLIP(gc) \
- GdkRegion *old_clip_region; \
gdk_window_flush_implicit_paint ((GdkWindow *)drawable);\
- setup_clip_for_draw (drawable, gc, old_clip_x, old_clip_y, &old_clip_region);
+ setup_clip_for_draw (drawable, gc, old_clip_x, old_clip_y);
#define RESTORE_DIRECT_GC_CLIP(gc) \
- _gdk_gc_set_clip_region_internal (gc, old_clip_region, FALSE);
+ _gdk_gc_remove_drawable_clip (gc);
static GdkGC *
gdk_window_create_gc (GdkDrawable *drawable,
diff --git a/gdk/gdkwindow.h b/gdk/gdkwindow.h
index ec3f67a..7a628b5 100644
--- a/gdk/gdkwindow.h
+++ b/gdk/gdkwindow.h
@@ -328,6 +328,7 @@ struct _GdkWindowObject
int abs_x, abs_y; /* Absolute offset in impl */
gint width, height;
+ guint32 clip_tag;
GdkRegion *clip_region; /* Clip region (wrt toplevel) in window coords */
GdkRegion *clip_region_with_children; /* Clip region in window coords */
GdkColormap *colormap;
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]