summaryrefslogtreecommitdiff
path: root/gdk
diff options
context:
space:
mode:
authorOwen Taylor <otaylor@redhat.com>2005-05-02 23:29:24 +0000
committerOwen Taylor <otaylor@src.gnome.org>2005-05-02 23:29:24 +0000
commit788bbf520a8c62f7798cb032228434ac7da39ada (patch)
tree6c6d244362bce12b25c5e252af4f8133327f7182 /gdk
parentb1cebb4c50256b2ed3c4b2167ab84dac6eb834c3 (diff)
downloadgdk-pixbuf-788bbf520a8c62f7798cb032228434ac7da39ada.tar.gz
Add a draw-border style property to allow themes to draw outside the
2005-04-28 Owen Taylor <otaylor@redhat.com> * gtk/gtkwidget.c: Add a draw-border style property to allow themes to draw outside the widget's allocation. * gdk/gdkwindow.c gtk/gtkstyle.c: Remove some save/restore pairs that were working around the clip-leakage bug in Cairo. * gtk/gtkstyle.c: Use cairo_fill_preserve() rathe than save/fill/restore. * gdk/gdkgc.c gdk/gdkinternals.h: Add _gdk_gc_update_context() That updates a Cairo context to match a GC. * gdk/gdkdraw.c: Use _gdk_gc_update_context() to add support for tiles/stipples/clipping to gdk_draw_glyphs(), gdk_draw_trapezoids(). * gdk/gdkpango.c: Use _gdk_gc_update_context() instead of internal implementation of stipples. Use one cairo_t across the entire drawing operation. Replace cairo_matrix_create() with stack-allocated matrices. * gdk/gdkgc.c gdk/gdkinternals.h gdk/x11/gdkgc-x11.c gdk/win32/gdkgc-win32.c: Save various aspects of the GC state (fill, tile, stipple, foreground, background, clip region) in instance-private-data for future use. Add getters. Get rid of _gdk_windowing_gc_get_foreground() function implemented by the backends. * gdk/gdkgc.c gdk/gdkinternals.h gdk/x11/gdkgc-x11.c gdk/win32/gdkgc-win32.c gdk/linux-fb/gdkgc-fb.c: Add _gdk_gc_init() to do initial setup of the GC from values; fixes some problems from drawable redirection. * gdk/gdkgc.c gdk/gdkinternals.h gdk/x11/gdkgc-x11.c gdk/win32/gdkgc-win32.c gdk/linux-fb/gdkgc-fb.c: Move gdk_gc_copy() and gdk_gc_set_clip_{region,rectangle}() into the generic code, add _gdk_windowing_gc_copy(), _gdk_windowing_gc_set_clip_region() to do backend specific stuff. * gdk/x11/{gdkprivate-x11.h,gdkgc-x11.c.c,gdkdrawable-x11.c} gdk/win32/{gdkprivate-win32.h,gdkgc-x11.c.c,gdkdrawable-x11.c} gdk/linux-fb/{gdkprivate-fb.h,gdkgc-fb.c.c,gdkdrawable-fb.c}: Don't duplicate state that now is stored by the generic code. * gdk/gdk.symbols Update
Diffstat (limited to 'gdk')
-rw-r--r--gdk/gdk.symbols6
-rw-r--r--gdk/gdkdraw.c10
-rw-r--r--gdk/gdkgc.c622
-rw-r--r--gdk/gdkinternals.h49
-rw-r--r--gdk/gdkpango.c193
-rw-r--r--gdk/gdkwindow.c4
-rw-r--r--gdk/linux-fb/gdkdrawable-fb2.c6
-rw-r--r--gdk/linux-fb/gdkgc-fb.c129
-rw-r--r--gdk/linux-fb/gdkprivate-fb.h1
-rw-r--r--gdk/win32/gdkdrawable-win32.c33
-rw-r--r--gdk/win32/gdkgc-win32.c173
-rw-r--r--gdk/win32/gdkprivate-win32.h6
-rw-r--r--gdk/x11/gdkdrawable-x11.c8
-rw-r--r--gdk/x11/gdkgc-x11.c247
-rw-r--r--gdk/x11/gdkprivate-x11.h9
15 files changed, 797 insertions, 699 deletions
diff --git a/gdk/gdk.symbols b/gdk/gdk.symbols
index b5904f096..a7883569b 100644
--- a/gdk/gdk.symbols
+++ b/gdk/gdk.symbols
@@ -579,11 +579,14 @@ gdk_gc_set_stipple
gdk_gc_set_ts_origin
gdk_gc_set_clip_origin
gdk_gc_set_clip_mask
+gdk_gc_set_clip_rectangle
+gdk_gc_set_clip_region
gdk_gc_set_subwindow
gdk_gc_set_exposures
gdk_gc_set_line_attributes
gdk_gc_set_dashes
gdk_gc_offset
+gdk_gc_copy
gdk_gc_get_colormap
gdk_gc_set_colormap
gdk_gc_set_rgb_bg_color
@@ -593,10 +596,7 @@ gdk_gc_set_rgb_fg_color
#if IN_HEADER(__GDK_GC_H__)
#if IN_FILE(__GDK_GC_X11_C__)
-gdk_gc_copy
gdk_gc_get_screen
-gdk_gc_set_clip_rectangle
-gdk_gc_set_clip_region
#endif
#endif
diff --git a/gdk/gdkdraw.c b/gdk/gdkdraw.c
index c5bd2d8b6..ca0950d2c 100644
--- a/gdk/gdkdraw.c
+++ b/gdk/gdkdraw.c
@@ -877,13 +877,10 @@ real_draw_glyphs (GdkDrawable *drawable,
gdouble y,
PangoGlyphString *glyphs)
{
- GdkColor color;
cairo_t *cr;
cr = gdk_drawable_create_cairo_context (drawable);
-
- _gdk_windowing_gc_get_foreground (gc, &color);
- gdk_cairo_set_source_color (cr, &color);
+ _gdk_gc_update_context (gc, cr, NULL, NULL);
if (matrix)
{
@@ -999,7 +996,6 @@ gdk_draw_trapezoids (GdkDrawable *drawable,
GdkTrapezoid *trapezoids,
gint n_trapezoids)
{
- GdkColor color;
cairo_t *cr;
int i;
@@ -1008,10 +1004,8 @@ gdk_draw_trapezoids (GdkDrawable *drawable,
g_return_if_fail (n_trapezoids == 0 || trapezoids != NULL);
cr = gdk_drawable_create_cairo_context (drawable);
+ _gdk_gc_update_context (gc, cr, NULL, NULL);
- _gdk_windowing_gc_get_foreground (gc, &color);
- gdk_cairo_set_source_color (cr, &color);
-
for (i = 0; i < n_trapezoids; i++)
{
cairo_move_to (cr, trapezoids[i].x11, trapezoids[i].y1);
diff --git a/gdk/gdkgc.c b/gdk/gdkgc.c
index c51b43338..50179d411 100644
--- a/gdk/gdkgc.c
+++ b/gdk/gdkgc.c
@@ -28,52 +28,56 @@
#include <string.h>
#include "gdkgc.h"
+#include "gdkinternals.h"
+#include "gdkpixmap.h"
+#include "gdkregion-generic.h"
#include "gdkrgb.h"
#include "gdkprivate.h"
#include "gdkalias.h"
-static void gdk_gc_class_init (GObjectClass *class);
static void gdk_gc_finalize (GObject *object);
-static GObjectClass *parent_class;
+typedef struct _GdkGCPrivate GdkGCPrivate;
-GType
-gdk_gc_get_type (void)
+struct _GdkGCPrivate
{
- static GType object_type = 0;
+ GdkRegion *clip_region;
- if (!object_type)
- {
- static const GTypeInfo object_info =
- {
- sizeof (GdkGCClass),
- (GBaseInitFunc) NULL,
- (GBaseFinalizeFunc) NULL,
- (GClassInitFunc) gdk_gc_class_init,
- NULL, /* class_finalize */
- NULL, /* class_data */
- sizeof (GdkGC),
- 0, /* n_preallocs */
- (GInstanceInitFunc) NULL,
- };
-
- object_type = g_type_register_static (G_TYPE_OBJECT,
- "GdkGC",
- &object_info,
- G_TYPE_FLAG_ABSTRACT);
- }
+ GdkFill fill;
+ GdkBitmap *stipple;
+ GdkPixmap *tile;
- return object_type;
-}
+ guint32 fg_pixel;
+ guint32 bg_pixel;
+};
+
+#define GDK_GC_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), GDK_TYPE_GC, GdkGCPrivate))
+
+G_DEFINE_TYPE (GdkGC, gdk_gc, G_TYPE_OBJECT);
static void
-gdk_gc_class_init (GObjectClass *class)
+gdk_gc_class_init (GdkGCClass *class)
{
- parent_class = g_type_class_peek_parent (class);
+ GObjectClass *object_class = G_OBJECT_CLASS (class);
- class->finalize = gdk_gc_finalize;
+ object_class->finalize = gdk_gc_finalize;
+
+ g_type_class_add_private (object_class, sizeof (GdkGCPrivate));
}
+static void
+gdk_gc_init (GdkGC *gc)
+{
+ GdkGCPrivate *priv = GDK_GC_GET_PRIVATE (gc);
+
+ priv->fill = GDK_SOLID;
+
+ /* These are the default X11 value, which we match. They are clearly
+ * wrong for TrueColor displays, so apps have to change them.
+ */
+ priv->fg_pixel = 0;
+ priv->bg_pixel = 1;
+}
/**
* gdk_gc_new:
@@ -109,17 +113,39 @@ gdk_gc_new_with_values (GdkDrawable *drawable,
GdkGCValues *values,
GdkGCValuesMask values_mask)
{
- GdkGC *gc;
-
g_return_val_if_fail (drawable != NULL, NULL);
- gc = GDK_DRAWABLE_GET_CLASS (drawable)->create_gc (drawable,
- values,
- values_mask);
+ return GDK_DRAWABLE_GET_CLASS (drawable)->create_gc (drawable,
+ values,
+ values_mask);
+}
+
+/**
+ * _gdk_gc_init:
+ * @gc: a #GdkGC
+ * @drawable: a #GdkDrawable.
+ * @values: a structure containing initial values for the GC.
+ * @values_mask: a bit mask indicating which fields in @values
+ * are set.
+ *
+ * Does initialization of the generic portions of a #GdkGC
+ * created with the specified values and values_mask. This
+ * should be called out of the implementation of
+ * GdkDrawable.create_gc() immediately after creating the
+ * #GdkGC object.
+ **/
+void
+_gdk_gc_init (GdkGC *gc,
+ GdkDrawable *drawable,
+ GdkGCValues *values,
+ GdkGCValuesMask values_mask)
+{
+ GdkGCPrivate *priv;
+
+ g_return_if_fail (GDK_IS_GC (gc));
+
+ priv = GDK_GC_GET_PRIVATE (gc);
- if (gc == NULL) /* This would mean the drawable was destroyed. */
- return NULL;
-
if (values_mask & GDK_GC_CLIP_X_ORIGIN)
gc->clip_x_origin = values->clip_x_origin;
if (values_mask & GDK_GC_CLIP_Y_ORIGIN)
@@ -128,29 +154,42 @@ gdk_gc_new_with_values (GdkDrawable *drawable,
gc->ts_x_origin = values->ts_x_origin;
if (values_mask & GDK_GC_TS_Y_ORIGIN)
gc->ts_y_origin = values->ts_y_origin;
-
- /* gc->colormap will already be set if gdk_gc_new_with_values()
- * recurses - as in GdkPixmap => impl object.
- */
- if (!gc->colormap)
+ if (values_mask & GDK_GC_FILL)
+ priv->fill = values->fill;
+ if (values_mask & GDK_GC_STIPPLE)
{
- gc->colormap = gdk_drawable_get_colormap (drawable);
- if (gc->colormap)
- g_object_ref (gc->colormap);
+ priv->stipple = values->stipple;
+ if (priv->stipple)
+ g_object_ref (priv->stipple);
}
-
- return gc;
+ if (values_mask & GDK_GC_TILE)
+ {
+ priv->tile = values->tile;
+ if (priv->tile)
+ g_object_ref (priv->tile);
+ }
+ if (values_mask & GDK_GC_FOREGROUND)
+ priv->fg_pixel = values->foreground.pixel;
+ if (values_mask & GDK_GC_BACKGROUND)
+ priv->bg_pixel = values->background.pixel;
+
+ gc->colormap = gdk_drawable_get_colormap (drawable);
+ if (gc->colormap)
+ g_object_ref (gc->colormap);
}
static void
gdk_gc_finalize (GObject *object)
{
GdkGC *gc = GDK_GC (object);
+ GdkGCPrivate *priv = GDK_GC_GET_PRIVATE (gc);
+ if (priv->clip_region)
+ gdk_region_destroy (priv->clip_region);
if (gc->colormap)
g_object_unref (gc->colormap);
- parent_class->finalize (object);
+ G_OBJECT_CLASS (gdk_gc_parent_class)->finalize (object);
}
/**
@@ -219,9 +258,13 @@ gdk_gc_set_values (GdkGC *gc,
GdkGCValues *values,
GdkGCValuesMask values_mask)
{
+ GdkGCPrivate *priv;
+
g_return_if_fail (GDK_IS_GC (gc));
g_return_if_fail (values != NULL);
+ priv = GDK_GC_GET_PRIVATE (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)
@@ -230,6 +273,43 @@ gdk_gc_set_values (GdkGC *gc,
gc->ts_x_origin = values->ts_x_origin;
if (values_mask & GDK_GC_TS_Y_ORIGIN)
gc->ts_y_origin = values->ts_y_origin;
+ if (values_mask & GDK_GC_CLIP_MASK)
+ {
+ GdkGCPrivate *priv = GDK_GC_GET_PRIVATE (gc);
+ if (priv->clip_region)
+ {
+ gdk_region_destroy (priv->clip_region);
+ priv->clip_region = NULL;
+ }
+ }
+ if (values_mask & GDK_GC_FILL)
+ priv->fill = values->fill;
+ if (values_mask & GDK_GC_STIPPLE)
+ {
+ if (priv->stipple != values->stipple)
+ {
+ if (priv->stipple)
+ g_object_unref (priv->stipple);
+ priv->stipple = values->stipple;
+ if (priv->stipple)
+ g_object_ref (priv->stipple);
+ }
+ }
+ if (values_mask & GDK_GC_TILE)
+ {
+ if (priv->tile != values->tile)
+ {
+ if (priv->tile)
+ g_object_unref (priv->tile);
+ priv->tile = values->tile;
+ if (priv->tile)
+ g_object_ref (priv->tile);
+ }
+ }
+ if (values_mask & GDK_GC_FOREGROUND)
+ priv->fg_pixel = values->foreground.pixel;
+ if (values_mask & GDK_GC_BACKGROUND)
+ priv->bg_pixel = values->background.pixel;
GDK_GC_GET_CLASS (gc)->set_values (gc, values, values_mask);
}
@@ -459,6 +539,169 @@ gdk_gc_set_clip_mask (GdkGC *gc,
gdk_gc_set_values (gc, &values, GDK_GC_CLIP_MASK);
}
+static void
+_gdk_gc_set_clip_region_internal (GdkGC *gc,
+ GdkRegion *region)
+{
+ GdkGCPrivate *priv = GDK_GC_GET_PRIVATE (gc);
+
+ if (priv->clip_region)
+ gdk_region_destroy (priv->clip_region);
+
+ priv->clip_region = region;
+
+ _gdk_windowing_gc_set_clip_region (gc, region);
+}
+
+/**
+ * gdk_gc_set_clip_rectangle:
+ * @gc: a #GdkGC.
+ * @rectangle: the rectangle to clip to.
+ *
+ * Sets the clip mask for a graphics context from a
+ * rectangle. The clip mask is interpreted relative to the clip
+ * origin. (See gdk_gc_set_clip_origin()).
+ **/
+void
+gdk_gc_set_clip_rectangle (GdkGC *gc,
+ GdkRectangle *rectangle)
+{
+ GdkRegion *region;
+
+ g_return_if_fail (GDK_IS_GC (gc));
+
+ if (rectangle)
+ region = gdk_region_rectangle (rectangle);
+ else
+ region = NULL;
+
+ _gdk_gc_set_clip_region_internal (gc, region);
+}
+
+/**
+ * gdk_gc_set_clip_region:
+ * @gc: a #GdkGC.
+ * @region: the #GdkRegion.
+ *
+ * Sets the clip mask for a graphics context from a region structure.
+ * The clip mask is interpreted relative to the clip origin. (See
+ * gdk_gc_set_clip_origin()).
+ **/
+void
+gdk_gc_set_clip_region (GdkGC *gc,
+ GdkRegion *region)
+{
+ g_return_if_fail (GDK_IS_GC (gc));
+
+ if (region)
+ region = gdk_region_copy (region);
+
+ _gdk_gc_set_clip_region_internal (gc, region);
+}
+
+/**
+ * _gdk_gc_get_clip_region:
+ * @gc: a #GdkGC
+ *
+ * Gets the current clip region for @gc, if any.
+ *
+ * Return value: the clip region for the GC, or %NULL.
+ * (if a clip mask is set, the return will be %NULL)
+ * This value is owned by the GC and must not be freed.
+ **/
+GdkRegion *
+_gdk_gc_get_clip_region (GdkGC *gc)
+{
+ g_return_val_if_fail (GDK_IS_GC (gc), NULL);
+
+ return GDK_GC_GET_PRIVATE (gc)->clip_region;
+}
+
+/**
+ * _gdk_gc_get_fill:
+ * @gc: a #GdkGC
+ *
+ * Gets the current file style for the GC
+ *
+ * Return value: the file style for the GC
+ **/
+GdkFill
+_gdk_gc_get_fill (GdkGC *gc)
+{
+ g_return_val_if_fail (GDK_IS_GC (gc), GDK_SOLID);
+
+ return GDK_GC_GET_PRIVATE (gc)->fill;
+}
+
+/**
+ * _gdk_gc_get_tile:
+ * @gc: a #GdkGC
+ *
+ * Gets the tile pixmap for @gc, if any
+ *
+ * Return value: the tile set on the GC, or %NULL. The
+ * value is owned by the GC and must not be freed.
+ **/
+GdkPixmap *
+_gdk_gc_get_tile (GdkGC *gc)
+{
+ g_return_val_if_fail (GDK_IS_GC (gc), NULL);
+
+ return GDK_GC_GET_PRIVATE (gc)->tile;
+}
+
+/**
+ * _gdk_gc_get_stipple:
+ * @gc: a #GdkGC
+ *
+ * Gets the stipple pixmap for @gc, if any
+ *
+ * Return value: the stipple set on the GC, or %NULL. The
+ * value is owned by the GC and must not be freed.
+ **/
+GdkBitmap *
+_gdk_gc_get_stipple (GdkGC *gc)
+{
+ g_return_val_if_fail (GDK_IS_GC (gc), NULL);
+
+ return GDK_GC_GET_PRIVATE (gc)->stipple;
+}
+
+/**
+ * _gdk_gc_get_fg_pixel:
+ * @gc: a #GdkGC
+ *
+ * Gets the foreground pixel value for @gc. If the
+ * foreground pixel has never been set, returns the
+ * default value 0.
+ *
+ * Return value: the foreground pixel value of the GC
+ **/
+guint32
+_gdk_gc_get_fg_pixel (GdkGC *gc)
+{
+ g_return_val_if_fail (GDK_IS_GC (gc), 0);
+
+ return GDK_GC_GET_PRIVATE (gc)->fg_pixel;
+}
+
+/**
+ * _gdk_gc_get_bg_pixel:
+ * @gc: a #GdkGC
+ *
+ * Gets the background pixel value for @gc.If the
+ * foreground pixel has never been set, returns the
+ * default value 1.
+ *
+ * Return value: the foreground pixel value of the GC
+ **/
+guint32
+_gdk_gc_get_bg_pixel (GdkGC *gc)
+{
+ g_return_val_if_fail (GDK_IS_GC (gc), 0);
+
+ return GDK_GC_GET_PRIVATE (gc)->bg_pixel;
+}
/**
* gdk_gc_set_subwindow:
@@ -599,6 +842,67 @@ gdk_gc_offset (GdkGC *gc,
}
/**
+ * gdk_gc_copy:
+ * @dst_gc: the destination graphics context.
+ * @src_gc: the source graphics context.
+ *
+ * Copy the set of values from one graphics context
+ * onto another graphics context.
+ **/
+void
+gdk_gc_copy (GdkGC *dst_gc,
+ GdkGC *src_gc)
+{
+ GdkGCPrivate *dst_priv, *src_priv;
+
+ g_return_if_fail (GDK_IS_GC (dst_gc));
+ g_return_if_fail (GDK_IS_GC (src_gc));
+
+ dst_priv = GDK_GC_GET_PRIVATE (dst_gc);
+ src_priv = GDK_GC_GET_PRIVATE (src_gc);
+
+ _gdk_windowing_gc_copy (dst_gc, src_gc);
+
+ dst_gc->clip_x_origin = src_gc->clip_x_origin;
+ dst_gc->clip_y_origin = src_gc->clip_y_origin;
+ dst_gc->ts_x_origin = src_gc->ts_x_origin;
+ dst_gc->ts_y_origin = src_gc->ts_y_origin;
+
+ if (src_gc->colormap)
+ g_object_ref (src_gc->colormap);
+
+ if (dst_gc->colormap)
+ g_object_unref (dst_gc->colormap);
+
+ dst_gc->colormap = src_gc->colormap;
+
+ if (dst_priv->clip_region)
+ gdk_region_destroy (dst_priv->clip_region);
+
+ if (src_priv->clip_region)
+ dst_priv->clip_region = gdk_region_copy (src_priv->clip_region);
+ else
+ dst_priv->clip_region = NULL;
+
+ dst_priv->fill = src_priv->fill;
+
+ if (dst_priv->stipple)
+ g_object_unref (dst_priv->stipple);
+ dst_priv->stipple = src_priv->stipple;
+ if (dst_priv->stipple)
+ g_object_ref (dst_priv->stipple);
+
+ if (dst_priv->tile)
+ g_object_unref (dst_priv->tile);
+ dst_priv->tile = src_priv->tile;
+ if (dst_priv->tile)
+ g_object_ref (dst_priv->tile);
+
+ dst_priv->fg_pixel = src_priv->fg_pixel;
+ dst_priv->bg_pixel = src_priv->bg_pixel;
+}
+
+/**
* gdk_gc_set_colormap:
* @gc: a #GdkGC
* @colormap: a #GdkColormap
@@ -724,5 +1028,225 @@ gdk_gc_set_rgb_bg_color (GdkGC *gc,
gdk_gc_set_background (gc, &tmp_color);
}
+static cairo_surface_t *
+make_stipple_tile_surface (cairo_t *cr,
+ GdkBitmap *stipple,
+ GdkColor *foreground,
+ GdkColor *background)
+{
+ cairo_t *tmp_cr;
+ cairo_surface_t *surface;
+ cairo_surface_t *alpha_surface;
+ gint width, height;
+
+ gdk_drawable_get_size (stipple,
+ &width, &height);
+
+ alpha_surface = _gdk_drawable_ref_cairo_surface (stipple);
+
+ surface = cairo_surface_create_similar (cairo_get_target_surface (cr),
+ CAIRO_FORMAT_ARGB32,
+ width, height);
+
+ tmp_cr = cairo_create ();
+ cairo_set_target_surface (tmp_cr, surface);
+
+ cairo_set_operator (tmp_cr, CAIRO_OPERATOR_SRC);
+
+ if (background)
+ gdk_cairo_set_source_color (tmp_cr, background);
+ else
+ cairo_set_source_rgba (tmp_cr, 0, 0, 0 ,0);
+
+ cairo_paint (tmp_cr);
+
+ cairo_set_operator (tmp_cr, CAIRO_OPERATOR_OVER);
+
+ gdk_cairo_set_source_color (tmp_cr, foreground);
+ cairo_mask_surface (tmp_cr, alpha_surface, 0, 0);
+
+ cairo_destroy (tmp_cr);
+ cairo_surface_destroy (alpha_surface);
+
+ return surface;
+}
+
+static void
+gc_get_foreground (GdkGC *gc,
+ GdkColor *color)
+{
+ GdkGCPrivate *priv = GDK_GC_GET_PRIVATE (gc);
+
+ color->pixel = priv->bg_pixel;
+
+ if (gc->colormap)
+ gdk_colormap_query_color (gc->colormap, priv->bg_pixel, color);
+ else
+ g_warning ("No colormap in gc_get_background");
+}
+
+static void
+gc_get_background (GdkGC *gc,
+ GdkColor *color)
+{
+ GdkGCPrivate *priv = GDK_GC_GET_PRIVATE (gc);
+
+ color->pixel = priv->bg_pixel;
+
+ if (gc->colormap)
+ gdk_colormap_query_color (gc->colormap, priv->bg_pixel, color);
+ else
+ g_warning ("No colormap in gc_get_background");
+}
+
+/**
+ * _gdk_gc_update_context:
+ * @gc: a #GdkGC
+ * @cr: a #cairo_t
+ * @override_foreground: a foreground color to use to override the
+ * foreground color of the GC
+ * @override_stipple: a stipple pattern to use to override the
+ * stipple from the GC. If this is present and the fill mode
+ * of the GC isn't %GDK_STIPPLED or %GDK_OPAQUE_STIPPLED
+ * the fill mode will be forced to %GDK_STIPPLED
+ *
+ * Set the attributes of a cairo context to match those of a #GdkGC
+ * as far as possible. Some aspects of a #GdkGC, such as clip masks
+ * and functions other than %GDK_COPY are not currently handled.
+ **/
+void
+_gdk_gc_update_context (GdkGC *gc,
+ cairo_t *cr,
+ GdkColor *override_foreground,
+ GdkBitmap *override_stipple)
+{
+ GdkGCPrivate *priv;
+ GdkFill fill;
+ GdkColor foreground;
+ GdkColor background;
+ cairo_surface_t *tile_surface = NULL;
+ GdkBitmap *stipple = NULL;
+
+ g_return_if_fail (GDK_IS_GC (gc));
+ g_return_if_fail (cr != NULL);
+ g_return_if_fail (override_stipple == NULL || GDK_IS_PIXMAP (override_stipple));
+
+ priv = GDK_GC_GET_PRIVATE (gc);
+
+ fill = priv->fill;
+ if (override_stipple && fill != GDK_OPAQUE_STIPPLED)
+ fill = GDK_STIPPLED;
+
+ if (fill != GDK_TILED)
+ {
+ if (override_foreground)
+ foreground = *override_foreground;
+ else
+ gc_get_foreground (gc, &foreground);
+ }
+
+ if (fill == GDK_OPAQUE_STIPPLED)
+ {
+ if (override_foreground)
+ foreground = *override_foreground;
+ else
+ gc_get_background (gc, &background);
+ }
+
+ switch (fill)
+ {
+ case GDK_SOLID:
+ break;
+ case GDK_TILED:
+ if (!priv->tile)
+ fill = GDK_SOLID;
+ break;
+ case GDK_STIPPLED:
+ case GDK_OPAQUE_STIPPLED:
+ if (override_stipple)
+ stipple = override_stipple;
+ else
+ stipple = priv->stipple;
+
+ if (!stipple)
+ fill = GDK_SOLID;
+ break;
+ }
+
+ switch (fill)
+ {
+ case GDK_SOLID:
+ gdk_cairo_set_source_color (cr, &foreground);
+ break;
+ case GDK_TILED:
+ tile_surface = _gdk_drawable_ref_cairo_surface (priv->tile);
+ break;
+ case GDK_STIPPLED:
+ tile_surface = make_stipple_tile_surface (cr, stipple, &foreground, NULL);
+ break;
+ case GDK_OPAQUE_STIPPLED:
+ tile_surface = make_stipple_tile_surface (cr, stipple, &foreground, &background);
+ break;
+ }
+
+ /* Tiles, stipples, and clip regions are all specified in device space,
+ * not user space. For the clip region, we can simply change the matrix,
+ * clip, then clip back, but for the source pattern, we need to
+ * compute the right matrix.
+ *
+ * What we want is:
+ *
+ * CTM_inverse * Pattern_matrix = Translate(- ts_x, - ts_y)
+ *
+ * (So that ts_x, ts_y in device space is taken to 0,0 in pattern
+ * space). So, pattern_matrix = CTM * Translate(- ts_x, - tx_y);
+ */
+
+ if (tile_surface)
+ {
+ cairo_pattern_t *pattern = cairo_pattern_create_for_surface (tile_surface);
+ cairo_matrix_t user_to_device;
+ cairo_matrix_t user_to_pattern;
+ cairo_matrix_t device_to_pattern;
+
+ cairo_get_matrix (cr, &user_to_device);
+ cairo_matrix_init_translate (&device_to_pattern,
+ - gc->ts_x_origin, - gc->ts_y_origin);
+ cairo_matrix_multiply (&user_to_pattern,
+ &user_to_device, &device_to_pattern);
+
+ cairo_pattern_set_matrix (pattern, &user_to_pattern);
+ cairo_pattern_set_extend (pattern, CAIRO_EXTEND_REPEAT);
+ cairo_set_source (cr, pattern);
+
+ cairo_surface_destroy (tile_surface);
+ cairo_pattern_destroy (pattern);
+ }
+
+ cairo_reset_clip (cr);
+ if (priv->clip_region)
+ {
+ GdkRegionBox *boxes = priv->clip_region->rects;
+ gint n_boxes = priv->clip_region->numRects;
+ int i;
+
+ cairo_save (cr);
+
+ cairo_identity_matrix (cr);
+
+ cairo_new_path (cr);
+ for (i=0; i < n_boxes; i++)
+ cairo_rectangle (cr,
+ boxes[i].x1 + gc->clip_x_origin,
+ boxes[i].y1 + gc->clip_y_origin,
+ boxes[i].x2 - boxes[i].x1,
+ boxes[i].y2 - boxes[i].y1);
+
+ cairo_restore (cr);
+
+ cairo_clip (cr);
+ }
+}
+
#define __GDK_GC_C__
#include "gdkaliasdef.c"
diff --git a/gdk/gdkinternals.h b/gdk/gdkinternals.h
index ffe770017..c5aaca8aa 100644
--- a/gdk/gdkinternals.h
+++ b/gdk/gdkinternals.h
@@ -216,6 +216,11 @@ cairo_surface_t *_gdk_drawable_ref_cairo_surface (GdkDrawable *drawable);
GdkGC *_gdk_drawable_get_scratch_gc (GdkDrawable *drawable,
gboolean graphics_exposures);
+void _gdk_gc_update_context (GdkGC *gc,
+ cairo_t *cr,
+ GdkColor *override_foreground,
+ GdkBitmap *override_stipple);
+
/*************************************
* Interfaces used by windowing code *
*************************************/
@@ -228,6 +233,18 @@ void _gdk_screen_close (GdkScreen *screen);
const char *_gdk_get_sm_client_id (void);
+void _gdk_gc_init (GdkGC *gc,
+ GdkDrawable *drawable,
+ GdkGCValues *values,
+ GdkGCValuesMask values_mask);
+
+GdkRegion *_gdk_gc_get_clip_region (GdkGC *gc);
+GdkFill _gdk_gc_get_fill (GdkGC *gc);
+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);
+
/*****************************************
* Interfaces provided by windowing code *
*****************************************/
@@ -323,9 +340,41 @@ GType _gdk_window_impl_get_type (void) G_GNUC_CONST;
GType _gdk_pixmap_impl_get_type (void) G_GNUC_CONST;
+/**
+ * _gdk_windowing_gc_set_clip_region:
+ * @gc: a #GdkGC
+ * @region: the new clip region
+ *
+ * Do any window-system specific processing necessary
+ * for a change in clip region. Since the clip origin
+ * will likely change before the GC is used with the
+ * new clip, frequently this function will only set a flag and
+ * do the real processing later.
+ *
+ * When this function is called, _gdk_gc_get_clip_region
+ * will already return the new region.
+ **/
+void _gdk_windowing_gc_set_clip_region (GdkGC *gc,
+ GdkRegion *region);
+
+/**
+ * _gdk_windowing_gc_copy:
+ * @dst_gc: a #GdkGC from the GDK backend
+ * @src_gc: a #GdkGC from the GDK backend
+ *
+ * Copies backend specific state from @src_gc to @dst_gc.
+ * This is called before the generic state is copied, so
+ * the old generic state is still available from @dst_gc
+ **/
+void _gdk_windowing_gc_copy (GdkGC *dst_gc,
+ GdkGC *src_gc);
+
/* Queries the current foreground color of a GdkGC */
void _gdk_windowing_gc_get_foreground (GdkGC *gc,
GdkColor *color);
+/* Queries the current background color of a GdkGC */
+void _gdk_windowing_gc_get_background (GdkGC *gc,
+ GdkColor *color);
/************************************
* Initialization and exit routines *
diff --git a/gdk/gdkpango.c b/gdk/gdkpango.c
index bf5b517cf..a5801fcbf 100644
--- a/gdk/gdkpango.c
+++ b/gdk/gdkpango.c
@@ -49,9 +49,11 @@ struct _GdkPangoRendererPrivate
gboolean override_color_set[MAX_RENDER_PART + 1];
GdkBitmap *stipple[MAX_RENDER_PART + 1];
- cairo_surface_t *stipple_surface[MAX_RENDER_PART + 1];
gboolean embossed;
+ cairo_t *cr;
+ PangoRenderPart last_part;
+
/* Current target */
GdkDrawable *drawable;
GdkGC *base_gc;
@@ -80,10 +82,6 @@ gdk_pango_renderer_finalize (GObject *object)
g_object_unref (priv->drawable);
for (i = 0; i <= MAX_RENDER_PART; i++)
- if (priv->stipple_surface[i])
- cairo_surface_destroy (priv->stipple_surface[i]);
-
- for (i = 0; i <= MAX_RENDER_PART; i++)
if (priv->stipple[i])
g_object_unref (priv->stipple[i]);
@@ -132,122 +130,56 @@ emboss_context (cairo_t *cr)
cairo_set_source_rgb (cr, 1.0, 1.0, 1.0);
}
-static void
-set_part_color (GdkPangoRenderer *gdk_renderer,
- cairo_t *cr,
- PangoRenderPart part)
-{
- PangoColor *color = pango_renderer_get_color (PANGO_RENDERER (gdk_renderer),
- part);
- if (color)
- {
- cairo_set_source_rgb (cr,
- color->red / 65535.,
- color->green / 65535.,
- color->blue / 65535.);
- }
- else
- {
- GdkColor gc_color;
-
- _gdk_windowing_gc_get_foreground (gdk_renderer->priv->base_gc, &gc_color);
- gdk_cairo_set_source_color (cr, &gc_color);
- }
-}
-
-static cairo_surface_t *
-get_stipple_surface (GdkPangoRenderer *gdk_renderer,
- cairo_t *cr,
- PangoRenderPart part)
-{
- if (!gdk_renderer->priv->stipple_surface[part])
- {
- cairo_t *tmp_cr;
- cairo_surface_t *surface;
- cairo_surface_t *alpha_surface;
- gint width, height;
-
- gdk_drawable_get_size (gdk_renderer->priv->stipple[part],
- &width, &height);
-
- alpha_surface = _gdk_drawable_ref_cairo_surface (gdk_renderer->priv->stipple[part]);
-
- surface = cairo_surface_create_similar (cairo_get_target_surface (cr),
- CAIRO_FORMAT_ARGB32,
- width, height);
-
- tmp_cr = cairo_create ();
- cairo_set_target_surface (tmp_cr, surface);
-
- cairo_set_operator (tmp_cr, CAIRO_OPERATOR_SRC);
- cairo_show_surface (tmp_cr, alpha_surface, width, height);
-
- set_part_color (gdk_renderer, tmp_cr, part);
- cairo_set_operator (tmp_cr, CAIRO_OPERATOR_ATOP);
-
- cairo_rectangle (tmp_cr, 0, 0, width, height);
- cairo_fill (tmp_cr);
-
- cairo_destroy (tmp_cr);
- cairo_surface_destroy (alpha_surface);
-
- gdk_renderer->priv->stipple_surface[part] = surface;
- }
-
- return gdk_renderer->priv->stipple_surface[part];
-}
-
static cairo_t *
-create_cairo_context (GdkPangoRenderer *gdk_renderer,
- PangoRenderPart part)
+get_cairo_context (GdkPangoRenderer *gdk_renderer,
+ PangoRenderPart part)
{
PangoRenderer *renderer = PANGO_RENDERER (gdk_renderer);
- const PangoMatrix *matrix;
- cairo_t *cr = gdk_drawable_create_cairo_context (gdk_renderer->priv->drawable);
+ GdkPangoRendererPrivate *priv = gdk_renderer->priv;
- if (gdk_renderer->priv->stipple[part])
+ if (!priv->cr)
{
- cairo_surface_t *surface = get_stipple_surface (gdk_renderer, cr, part);
- cairo_pattern_t *pattern;
-
- pattern = cairo_pattern_create_for_surface (surface);
- cairo_pattern_set_extend (pattern, CAIRO_EXTEND_REPEAT);
+ const PangoMatrix *matrix;
+
+ priv->cr = gdk_drawable_create_cairo_context (priv->drawable);
- if (gdk_renderer->priv->base_gc->ts_x_origin != 0 ||
- gdk_renderer->priv->base_gc->ts_y_origin != 0)
+ matrix = pango_renderer_get_matrix (renderer);
+ if (matrix)
{
- cairo_matrix_t *matrix = cairo_matrix_create ();
- cairo_matrix_translate (matrix,
- - gdk_renderer->priv->base_gc->ts_x_origin,
- - gdk_renderer->priv->base_gc->ts_y_origin);
- cairo_pattern_set_matrix (pattern, matrix);
- cairo_matrix_destroy (matrix);
+ cairo_matrix_t cairo_matrix;
+
+ cairo_matrix_init (&cairo_matrix,
+ matrix->xx, matrix->yx,
+ matrix->xy, matrix->yy,
+ matrix->x0, matrix->y0);
+ cairo_set_matrix (priv->cr, &cairo_matrix);
}
-
- cairo_set_source (cr, pattern);
- cairo_pattern_destroy (pattern);
}
- else
- {
- set_part_color (gdk_renderer, cr, part);
- }
-
- matrix = pango_renderer_get_matrix (renderer);
- if (matrix)
+
+ priv->last_part = (PangoRenderPart)-1;
+ if (part != priv->last_part)
{
- cairo_matrix_t *cairo_matrix;
+ PangoColor *pango_color = pango_renderer_get_color (renderer,
+ part);
+ GdkColor *color = NULL;
+ GdkColor tmp_color;
+ if (pango_color)
+ {
+ tmp_color.red = pango_color->red;
+ tmp_color.green = pango_color->green;
+ tmp_color.blue = pango_color->blue;
+
+ color = &tmp_color;
+ }
- cairo_matrix = cairo_matrix_create ();
- cairo_matrix_set_affine (cairo_matrix,
- matrix->xx, matrix->yx,
- matrix->xy, matrix->yy,
- matrix->x0, matrix->y0);
-
- cairo_set_matrix (cr, cairo_matrix);
- cairo_matrix_destroy (cairo_matrix);
+ _gdk_gc_update_context (priv->base_gc,
+ priv->cr,
+ color,
+ priv->stipple[part]);
+ priv->last_part = part;
}
- return cr;
+ return priv->cr;
}
static void
@@ -261,8 +193,8 @@ gdk_pango_renderer_draw_glyphs (PangoRenderer *renderer,
GdkPangoRendererPrivate *priv = gdk_renderer->priv;
cairo_t *cr;
- cr = create_cairo_context (gdk_renderer,
- PANGO_RENDER_PART_FOREGROUND);
+ cr = get_cairo_context (gdk_renderer,
+ PANGO_RENDER_PART_FOREGROUND);
if (priv->embossed)
{
@@ -275,8 +207,6 @@ gdk_pango_renderer_draw_glyphs (PangoRenderer *renderer,
cairo_move_to (cr, x / PANGO_SCALE, y / PANGO_SCALE);
pango_cairo_show_glyph_string (cr, font, glyphs);
-
- cairo_destroy (cr);
}
/* Draws an error underline that looks like one of:
@@ -369,7 +299,7 @@ gdk_pango_renderer_draw_rectangle (PangoRenderer *renderer,
GdkPangoRendererPrivate *priv = gdk_renderer->priv;
cairo_t *cr;
- cr = create_cairo_context (gdk_renderer, part);
+ cr = get_cairo_context (gdk_renderer, part);
if (priv->embossed && part != PANGO_RENDER_PART_BACKGROUND)
{
@@ -387,8 +317,6 @@ gdk_pango_renderer_draw_rectangle (PangoRenderer *renderer,
(double)x / PANGO_SCALE, (double)y / PANGO_SCALE,
(double)width / PANGO_SCALE, (double)height / PANGO_SCALE);
cairo_fill (cr);
-
- cairo_destroy (cr);
}
static void
@@ -402,7 +330,7 @@ gdk_pango_renderer_draw_error_underline (PangoRenderer *renderer,
GdkPangoRendererPrivate *priv = gdk_renderer->priv;
cairo_t *cr;
- cr = create_cairo_context (gdk_renderer, PANGO_RENDER_PART_UNDERLINE);
+ cr = get_cairo_context (gdk_renderer, PANGO_RENDER_PART_UNDERLINE);
if (priv->embossed)
{
@@ -417,8 +345,6 @@ gdk_pango_renderer_draw_error_underline (PangoRenderer *renderer,
draw_error_underline (cr,
(double)x / PANGO_SCALE, (double)y / PANGO_SCALE,
(double)width / PANGO_SCALE, (double)height / PANGO_SCALE);
-
- cairo_destroy (cr);
}
static void
@@ -427,19 +353,17 @@ gdk_pango_renderer_part_changed (PangoRenderer *renderer,
{
GdkPangoRenderer *gdk_renderer = GDK_PANGO_RENDERER (renderer);
- if (gdk_renderer->priv->stipple_surface[part])
- {
- cairo_surface_destroy (gdk_renderer->priv->stipple_surface[part]);
- gdk_renderer->priv->stipple_surface[part] = NULL;
- }
+ if (gdk_renderer->priv->last_part == part)
+ gdk_renderer->priv->last_part = (PangoRenderPart)-1;
}
-void
+static void
gdk_pango_renderer_begin (PangoRenderer *renderer)
{
GdkPangoRenderer *gdk_renderer = GDK_PANGO_RENDERER (renderer);
-
- if (!gdk_renderer->priv->drawable || !gdk_renderer->priv->base_gc)
+ GdkPangoRendererPrivate *priv = gdk_renderer->priv;
+
+ if (!priv->drawable || !priv->base_gc)
{
g_warning ("gdk_pango_renderer_set_drawable() and gdk_pango_renderer_set_drawable()"
"must be used to set the target drawable and GC before using the renderer\n");
@@ -447,6 +371,20 @@ gdk_pango_renderer_begin (PangoRenderer *renderer)
}
static void
+gdk_pango_renderer_end (PangoRenderer *renderer)
+{
+ GdkPangoRenderer *gdk_renderer = GDK_PANGO_RENDERER (renderer);
+ GdkPangoRendererPrivate *priv = gdk_renderer->priv;
+
+ if (priv->cr)
+ {
+ cairo_destroy (priv->cr);
+ priv->cr = NULL;
+ }
+ priv->last_part = (PangoRenderPart)-1;
+}
+
+static void
gdk_pango_renderer_prepare_run (PangoRenderer *renderer,
PangoLayoutRun *run)
{
@@ -541,6 +479,8 @@ gdk_pango_renderer_init (GdkPangoRenderer *renderer)
renderer->priv = G_TYPE_INSTANCE_GET_PRIVATE (renderer,
GDK_TYPE_PANGO_RENDERER,
GdkPangoRendererPrivate);
+
+ renderer->priv->last_part = (PangoRenderPart)-1;
}
static void
@@ -555,6 +495,7 @@ gdk_pango_renderer_class_init (GdkPangoRendererClass *klass)
renderer_class->draw_error_underline = gdk_pango_renderer_draw_error_underline;
renderer_class->part_changed = gdk_pango_renderer_part_changed;
renderer_class->begin = gdk_pango_renderer_begin;
+ renderer_class->end = gdk_pango_renderer_end;
renderer_class->prepare_run = gdk_pango_renderer_prepare_run;
object_class->finalize = gdk_pango_renderer_finalize;
diff --git a/gdk/gdkwindow.c b/gdk/gdkwindow.c
index 03829181b..145e27519 100644
--- a/gdk/gdkwindow.c
+++ b/gdk/gdkwindow.c
@@ -1800,16 +1800,12 @@ gdk_window_clear_backing_rect (GdkWindow *window,
gdk_window_set_bg_pattern (window, cr, 0, 0);
- cairo_save (cr);
-
cairo_rectangle (cr, x, y, width, height);
cairo_clip (cr);
region_path (cr, paint->region);
cairo_fill (cr);
- cairo_restore (cr);
-
cairo_destroy (cr);
}
diff --git a/gdk/linux-fb/gdkdrawable-fb2.c b/gdk/linux-fb/gdkdrawable-fb2.c
index 20d110530..adbb79cee 100644
--- a/gdk/linux-fb/gdkdrawable-fb2.c
+++ b/gdk/linux-fb/gdkdrawable-fb2.c
@@ -433,9 +433,11 @@ gdk_fb_clip_region (GdkDrawable *drawable,
if (gc)
{
- if (GDK_GC_FBDATA (gc)->clip_region)
+ GdkRegion *gc = _gdk_gc_get_clip_region (gc);
+
+ if (clip_region)
{
- tmpreg = gdk_region_copy (GDK_GC_FBDATA (gc)->clip_region);
+ tmpreg = gdk_region_copy (clip_region);
gdk_region_offset (tmpreg, private->abs_x + GDK_GC_P (gc)->clip_x_origin,
private->abs_y + GDK_GC_P (gc)->clip_y_origin);
gdk_region_intersect (real_clip_region, tmpreg);
diff --git a/gdk/linux-fb/gdkgc-fb.c b/gdk/linux-fb/gdkgc-fb.c
index 8b8a4c702..a27b9ea96 100644
--- a/gdk/linux-fb/gdkgc-fb.c
+++ b/gdk/linux-fb/gdkgc-fb.c
@@ -79,6 +79,8 @@ _gdk_fb_gc_new (GdkDrawable *drawable,
gc = g_object_new (gdk_gc_fb_get_type (), NULL);
+ _gdk_gc_init (gc, drawable, values, values_mask);
+
private = (GdkGCFBData *)gc;
private->depth = GDK_DRAWABLE_FBDATA (drawable)->depth;
@@ -103,14 +105,8 @@ gdk_fb_gc_finalize (GObject *obj)
private = GDK_GC_FBDATA (gc);
- if (private->clip_region)
- gdk_region_destroy (private->clip_region);
if (private->values.clip_mask)
gdk_pixmap_unref (private->values.clip_mask);
- if (private->values.stipple)
- gdk_pixmap_unref (private->values.stipple);
- if (private->values.tile)
- gdk_pixmap_unref (private->values.tile);
g_free (private->dash_list);
@@ -175,7 +171,7 @@ gdk_fb_gc_set_values (GdkGC *gc,
if (values->tile)
g_assert (GDK_DRAWABLE_IMPL_FBDATA (values->tile)->depth >= 8);
- private->values.tile = values->tile ? gdk_pixmap_ref (values->tile) : NULL;
+ private->values.tile = values->tile;
private->values_mask |= GDK_GC_TILE;
if (oldpm)
gdk_pixmap_unref (oldpm);
@@ -186,7 +182,7 @@ gdk_fb_gc_set_values (GdkGC *gc,
oldpm = private->values.stipple;
if (values->stipple)
g_assert (GDK_DRAWABLE_IMPL_FBDATA (values->stipple)->depth == 1);
- private->values.stipple = values->stipple ? gdk_pixmap_ref (values->stipple) : NULL;
+ private->values.stipple = values->stipple;
private->values_mask |= GDK_GC_STIPPLE;
if (oldpm)
gdk_pixmap_unref (oldpm);
@@ -200,12 +196,6 @@ gdk_fb_gc_set_values (GdkGC *gc,
private->values_mask |= GDK_GC_CLIP_MASK;
if (oldpm)
gdk_pixmap_unref (oldpm);
-
- if (private->clip_region)
- {
- gdk_region_destroy (private->clip_region);
- private->clip_region = NULL;
- }
}
if (values_mask & GDK_GC_SUBWINDOW)
@@ -313,60 +303,13 @@ gc_unset_cmask(GdkGC *gc)
}
void
-gdk_gc_set_clip_rectangle (GdkGC *gc,
- GdkRectangle *rectangle)
-{
- GdkGC *private = (GdkGC *)gc;
- GdkGCFBData *data;
-
- g_return_if_fail (gc != NULL);
-
- data = GDK_GC_FBDATA (gc);
-
- if (data->clip_region)
- {
- gdk_region_destroy (data->clip_region);
- data->clip_region = NULL;
- }
-
- if (rectangle)
- data->clip_region = gdk_region_rectangle (rectangle);
-
- private->clip_x_origin = 0;
- private->clip_y_origin = 0;
- data->values.clip_x_origin = 0;
- data->values.clip_y_origin = 0;
-
- gc_unset_cmask (gc);
-
- _gdk_fb_gc_calc_state (gc, GDK_GC_CLIP_X_ORIGIN|GDK_GC_CLIP_Y_ORIGIN);
-}
-
-void
-gdk_gc_set_clip_region (GdkGC *gc,
- GdkRegion *region)
+_gdk_windowing_gc_set_clip_region (GdkGC *gc,
+ GdkRegion *region)
{
- GdkGC *private = (GdkGC *)gc;
- GdkGCFBData *data;
-
- g_return_if_fail (gc != NULL);
-
- data = GDK_GC_FBDATA (gc);
-
- if (region == data->clip_region)
- return;
+ GdkGCFBData *data = GDK_GC_FBDATA (gc);
- if (data->clip_region)
- {
- gdk_region_destroy (data->clip_region);
- data->clip_region = NULL;
- }
-
- if (region)
- data->clip_region = gdk_region_copy (region);
-
- private->clip_x_origin = 0;
- private->clip_y_origin = 0;
+ gc->clip_x_origin = 0;
+ gc->clip_y_origin = 0;
data->values.clip_x_origin = 0;
data->values.clip_y_origin = 0;
@@ -377,49 +320,35 @@ gdk_gc_set_clip_region (GdkGC *gc,
void
-gdk_gc_copy (GdkGC *dst_gc, GdkGC *src_gc)
+_gdk_windowing_gc_copy (GdkGC *dst_gc,
+ GdkGC *src_gc)
{
- GdkGCFBData *dst_private;
- GdkGCFBData *src_private;
-
- src_private = GDK_GC_FBDATA (dst_gc);
- dst_private = GDK_GC_FBDATA (dst_gc);
-
- g_return_if_fail (dst_gc != NULL);
- g_return_if_fail (src_gc != NULL);
-
- if (dst_private->clip_region)
- gdk_region_destroy (dst_private->clip_region);
+ GdkGCFBData *dst_private = GDK_GC_FBDATA (dst_gc);
+ GdkGCFBData *src_private = GDK_GC_FBDATA (src_gc);
+ GdkGCValuesMask old_mask = dst_private->values_mask;
if (dst_private->values_mask & GDK_GC_FONT)
gdk_font_unref (dst_private->values.font);
- if (dst_private->values_mask & GDK_GC_TILE)
- gdk_pixmap_unref (dst_private->values.tile);
- if (dst_private->values_mask & GDK_GC_STIPPLE)
- gdk_pixmap_unref (dst_private->values.stipple);
if (dst_private->values_mask & GDK_GC_CLIP_MASK)
- gdk_pixmap_unref (dst_private->values.clip_mask);
+ g_object_unref (dst_private->values.clip_mask);
g_free (dst_private->dash_list);
- *dst_private = *src_private;
+ if (src_private->dash_list)
+ dst_private->dash_list = g_memdup (src_private->dash_list,
+ src_private->dash_list_len);
+
+ dst_private->values_mask = src_private->values_mask;
+ dst_private->values = src_private->values;
if (dst_private->values_mask & GDK_GC_FONT)
gdk_font_ref (dst_private->values.font);
- if (dst_private->values_mask & GDK_GC_TILE)
- gdk_pixmap_ref (dst_private->values.tile);
- if (dst_private->values_mask & GDK_GC_STIPPLE)
- gdk_pixmap_ref (dst_private->values.stipple);
if (dst_private->values_mask & GDK_GC_CLIP_MASK)
- gdk_pixmap_ref (dst_private->values.clip_mask);
-
- if (dst_private->clip_region)
- dst_private->clip_region = gdk_region_copy (dst_private->clip_region);
-
- if (dst_private->dash_list)
- {
- dst_private->dash_list = g_malloc (dst_private->dash_list_len);
- memcpy (dst_private->dash_list,
- src_private->dash_list,
- dst_private->dash_list_len);
- }
+ g_object_ref (dst_private->values.clip_mask);
+
+ dst_private->dash_offset = src_private->dash_offset;
+ dst_private->alu = src_private->alu;
+
+ dst_private->set_pixel = src_private->set_pixel;
+
+ _gdk_fb_gc_calc_state (gc, old_mask | dst_private->values_mask);
}
diff --git a/gdk/linux-fb/gdkprivate-fb.h b/gdk/linux-fb/gdkprivate-fb.h
index a64d06edf..4466ffcb7 100644
--- a/gdk/linux-fb/gdkprivate-fb.h
+++ b/gdk/linux-fb/gdkprivate-fb.h
@@ -229,7 +229,6 @@ typedef void gdk_fb_draw_drawable_func (GdkDrawable *drawable,
typedef struct {
GdkGC parent_instance;
- GdkRegion *clip_region;
gchar *dash_list;
GdkGCValuesMask values_mask;
GdkGCValues values;
diff --git a/gdk/win32/gdkdrawable-win32.c b/gdk/win32/gdkdrawable-win32.c
index cf4412ccd..58576ffc2 100644
--- a/gdk/win32/gdkdrawable-win32.c
+++ b/gdk/win32/gdkdrawable-win32.c
@@ -525,6 +525,7 @@ generic_draw (GdkDrawable *drawable,
GdkGCWin32 *gcwin32 = GDK_GC_WIN32 (gc);
HDC hdc;
va_list args;
+ GdkFillStyle *fill_style = _gdk_gc_get_fill (gc);
va_start (args, region);
@@ -532,14 +533,14 @@ generic_draw (GdkDrawable *drawable,
*/
if (gcwin32->values_mask & GDK_GC_FILL &&
- ((gcwin32->fill_style == GDK_TILED &&
+ ((fill_style == GDK_TILED &&
gcwin32->values_mask & GDK_GC_TILE &&
- gcwin32->tile != NULL)
+ _gdk_gc_get_tile (gc) != NULL)
||
- ((gcwin32->fill_style == GDK_OPAQUE_STIPPLED ||
- gcwin32->fill_style == GDK_STIPPLED) &&
+ ((fill_style == GDK_OPAQUE_STIPPLED ||
+ fill_style == GDK_STIPPLED) &&
gcwin32->values_mask & GDK_GC_STIPPLE &&
- gcwin32->stipple != NULL)))
+ _gdk_gc_get_stipple (gc) != NULL)))
{
const GdkGCValuesMask blitting_mask = 0;
GdkGCValuesMask drawing_mask = GDK_GC_FOREGROUND;
@@ -614,11 +615,11 @@ generic_draw (GdkDrawable *drawable,
region->extents.x1, region->extents.y1, args);
gdk_win32_hdc_release (mask_pixmap, mask_gc, drawing_mask);
- if (gcwin32->fill_style == GDK_TILED)
+ if (fill_style == GDK_TILED)
{
/* Tile pixmap with tile */
draw_tiles (tile_pixmap, tile_gc, SRCCOPY,
- gcwin32->tile,
+ _gdk_gc_get_tile (gc),
0, 0, ts_x_origin, ts_y_origin,
width, height);
}
@@ -632,14 +633,14 @@ generic_draw (GdkDrawable *drawable,
/* Tile stipple bitmap */
draw_tiles (stipple_bitmap, stipple_gc, SRCCOPY,
- gcwin32->stipple,
+ _gdk_gc_get_stipple (gc),
0, 0, ts_x_origin, ts_y_origin,
width, height);
- if (gcwin32->fill_style == GDK_OPAQUE_STIPPLED)
+ if (fill_style == GDK_OPAQUE_STIPPLED)
{
/* Fill tile pixmap with background */
- fg.pixel = gcwin32->background;
+ fg.pixel = _gdk_gc_get_bg_pixel (gc);
gdk_gc_set_foreground (tile_gc, &fg);
gdk_draw_rectangle (tile_pixmap, tile_gc, TRUE,
0, 0, width, height);
@@ -658,8 +659,8 @@ generic_draw (GdkDrawable *drawable,
if ((old_tile_hbm = SelectObject (tile_hdc, GDK_PIXMAP_HBITMAP (tile_pixmap))) == NULL)
WIN32_GDI_FAILED ("SelectObject");
- if (gcwin32->fill_style == GDK_STIPPLED ||
- gcwin32->fill_style == GDK_OPAQUE_STIPPLED)
+ if (fill_style == GDK_STIPPLED ||
+ fill_style == GDK_OPAQUE_STIPPLED)
{
HDC stipple_hdc;
HGDIOBJ old_stipple_hbm;
@@ -676,7 +677,7 @@ generic_draw (GdkDrawable *drawable,
if ((fg_brush = CreateSolidBrush
(_gdk_win32_colormap_color (impl->colormap,
- gcwin32->foreground))) == NULL)
+ _gdk_gc_get_fg_pixel (gc)))) == NULL)
WIN32_GDI_FAILED ("CreateSolidBrush");
if ((old_tile_brush = SelectObject (tile_hdc, fg_brush)) == NULL)
@@ -701,7 +702,7 @@ generic_draw (GdkDrawable *drawable,
GDI_CALL (BitBlt, (tile_hdc, 0, 0, width, height,
stipple_hdc, 0, 0, ROP3_DSPDxax));
- if (gcwin32->fill_style == GDK_STIPPLED)
+ if (fill_style == GDK_STIPPLED)
{
/* Punch holes in mask where stipple is zero */
GDI_CALL (BitBlt, (mask_hdc, 0, 0, width, height,
@@ -1549,8 +1550,8 @@ blit_from_pixmap (gboolean use_fg_bg,
if (use_fg_bg)
{
- bgix = gcwin32->background;
- fgix = gcwin32->foreground;
+ bgix = _gdk_gc_get_bg_pixel (gc);
+ fgix = _gdk_gc_get_fg_pixel (gc);
}
else
{
diff --git a/gdk/win32/gdkgc-win32.c b/gdk/win32/gdkgc-win32.c
index 787a01354..0be44dd7f 100644
--- a/gdk/win32/gdkgc-win32.c
+++ b/gdk/win32/gdkgc-win32.c
@@ -107,12 +107,6 @@ gdk_gc_win32_finalize (GObject *object)
if (win32_gc->values_mask & GDK_GC_FONT)
gdk_font_unref (win32_gc->font);
- if (win32_gc->values_mask & GDK_GC_TILE)
- g_object_unref (win32_gc->tile);
-
- if (win32_gc->values_mask & GDK_GC_STIPPLE)
- g_object_unref (win32_gc->stipple);
-
if (win32_gc->pen_dashes)
g_free (win32_gc->pen_dashes);
@@ -125,21 +119,18 @@ gdk_win32_gc_values_to_win32values (GdkGCValues *values,
GdkGCWin32 *win32_gc)
{
char *s = "";
- gint sw, sh;
GDK_NOTE (GC, g_print ("{"));
if (mask & GDK_GC_FOREGROUND)
{
- win32_gc->foreground = values->foreground.pixel;
win32_gc->values_mask |= GDK_GC_FOREGROUND;
- GDK_NOTE (GC, (g_print ("fg=%.06lx", win32_gc->foreground),
+ GDK_NOTE (GC, (g_print ("fg=%.06lx", values->,
s = ","));
}
if (mask & GDK_GC_BACKGROUND)
{
- win32_gc->background = values->background.pixel;
win32_gc->values_mask |= GDK_GC_BACKGROUND;
GDK_NOTE (GC, (g_print ("%sbg=%.06lx", s, win32_gc->background),
s = ","));
@@ -196,25 +187,20 @@ gdk_win32_gc_values_to_win32values (GdkGCValues *values,
if (mask & GDK_GC_FILL)
{
- win32_gc->fill_style = values->fill;
win32_gc->values_mask |= GDK_GC_FILL;
GDK_NOTE (GC, (g_print ("%sfill=%s", s,
- _gdk_win32_fill_style_to_string (win32_gc->fill_style)),
+ _gdk_win32_fill_style_to_string (values->fill)),
s = ","));
}
if (mask & GDK_GC_TILE)
{
- if (win32_gc->tile != NULL)
- g_object_unref (win32_gc->tile);
- win32_gc->tile = values->tile;
- if (win32_gc->tile != NULL)
+ if (values->tile != NULL)
{
- g_object_ref (win32_gc->tile);
win32_gc->values_mask |= GDK_GC_TILE;
GDK_NOTE (GC,
(g_print ("%stile=%p", s,
- GDK_PIXMAP_HBITMAP (win32_gc->tile)),
+ GDK_PIXMAP_HBITMAP (values->tile)),
s = ","));
}
else
@@ -227,17 +213,19 @@ gdk_win32_gc_values_to_win32values (GdkGCValues *values,
if (mask & GDK_GC_STIPPLE)
{
- if (win32_gc->stipple != NULL)
- g_object_unref (win32_gc->stipple);
- win32_gc->stipple = values->stipple;
- if (win32_gc->stipple != NULL)
+ if (values->stipple != NULL)
{
- gdk_drawable_get_size (win32_gc->stipple, &sw, &sh);
-
#if 0 /* HB: this size limitation is disabled to make radio and check
* buttons work. I got the impression from the API docs, that
* it shouldn't be necessary at all, but win9x would do the clipping
+ *
+ * This code will need some work if reenabled since the stipple is
+ * now stored in the backend-independent code.
*/
+ gint sw, sh;
+
+ gdk_drawable_get_size (values->stipple, &sw, &sh);
+
if ( (sw != 8 || sh != 8)
&& !G_WIN32_IS_NT_BASED ()) /* HB: the MSDN says it's a Win95 limitation */
{
@@ -257,7 +245,7 @@ gdk_win32_gc_values_to_win32values (GdkGCValues *values,
j = 0;
while (j < 8)
{
- gdk_draw_drawable (bm, gc, win32_gc->stipple, 0, 0, i, j, sw, sh);
+ gdk_draw_drawable (bm, gc, values->stipple, 0, 0, i, j, sw, sh);
j += sh;
}
i += sw;
@@ -265,13 +253,11 @@ gdk_win32_gc_values_to_win32values (GdkGCValues *values,
win32_gc->stipple = bm;
gdk_gc_unref (gc);
}
- else
#endif
- g_object_ref (win32_gc->stipple);
win32_gc->values_mask |= GDK_GC_STIPPLE;
GDK_NOTE (GC,
(g_print ("%sstipple=%p", s,
- GDK_PIXMAP_HBITMAP (win32_gc->stipple)),
+ GDK_PIXMAP_HBITMAP (values->stipple)),
s = ","));
}
else
@@ -446,18 +432,12 @@ _gdk_win32_gc_new (GdkDrawable *drawable,
gc = g_object_new (_gdk_gc_win32_get_type (), NULL);
win32_gc = GDK_GC_WIN32 (gc);
+ _gdk_gc_init (gc, drawable, values, values_mask);
+
win32_gc->hcliprgn = NULL;
- /* Use the same default values as X11 does, even if they don't make
- * sense per se. But apps always set fg and bg anyway.
- */
- win32_gc->foreground = 0;
- win32_gc->background = 1;
win32_gc->font = NULL;
win32_gc->rop2 = R2_COPYPEN;
- win32_gc->fill_style = GDK_SOLID;
- win32_gc->tile = NULL;
- win32_gc->stipple = NULL;
win32_gc->subwindow_mode = GDK_CLIP_BY_CHILDREN;
win32_gc->graphics_exposures = TRUE;
win32_gc->pen_width = 0;
@@ -485,8 +465,8 @@ gdk_win32_gc_get_values (GdkGC *gc,
{
GdkGCWin32 *win32_gc = GDK_GC_WIN32 (gc);
- values->foreground.pixel = win32_gc->foreground;
- values->background.pixel = win32_gc->background;
+ values->foreground.pixel = _gdk_gc_get_fg_pixel (gc);
+ values->background.pixel = _gdk_gc_get_bg_pixel (gc);
values->font = win32_gc->font;
switch (win32_gc->rop2)
@@ -525,10 +505,9 @@ gdk_win32_gc_get_values (GdkGC *gc,
values->function = GDK_SET; break;
}
- values->fill = win32_gc->fill_style;
-
- values->tile = win32_gc->tile;
- values->stipple = win32_gc->stipple;
+ values->fill = _gdk_gc_get_fill (gc);
+ values->tile = _gdk_gc_get_tile (gc);
+ values->stipple = _gdk_gc_get_stipple (gc);
/* Also the X11 backend always returns a NULL clip_mask */
values->clip_mask = NULL;
@@ -608,51 +587,10 @@ gdk_win32_gc_set_dashes (GdkGC *gc,
}
void
-gdk_gc_set_clip_rectangle (GdkGC *gc,
- GdkRectangle *rectangle)
-{
- GdkGCWin32 *win32_gc;
-
- g_return_if_fail (GDK_IS_GC (gc));
-
- win32_gc = GDK_GC_WIN32 (gc);
-
- if (win32_gc->hcliprgn)
- DeleteObject (win32_gc->hcliprgn);
-
- if (rectangle)
- {
- GDK_NOTE (GC, g_print ("gdk_gc_set_clip_rectangle: %p: %s\n",
- win32_gc,
- _gdk_win32_gdkrectangle_to_string (rectangle)));
- win32_gc->hcliprgn = CreateRectRgn (rectangle->x, rectangle->y,
- rectangle->x + rectangle->width,
- rectangle->y + rectangle->height);
- win32_gc->values_mask |= GDK_GC_CLIP_MASK;
- }
- else
- {
- GDK_NOTE (GC, g_print ("gdk_gc_set_clip_rectangle: NULL\n"));
-
- win32_gc->hcliprgn = NULL;
- win32_gc->values_mask &= ~GDK_GC_CLIP_MASK;
- }
-
- gc->clip_x_origin = 0;
- gc->clip_y_origin = 0;
-
- win32_gc->values_mask &= ~(GDK_GC_CLIP_X_ORIGIN | GDK_GC_CLIP_Y_ORIGIN);
-}
-
-void
-gdk_gc_set_clip_region (GdkGC *gc,
- GdkRegion *region)
+_gdk_windowing_set_clip_region (GdkGC *gc,
+ GdkRegion *region)
{
- GdkGCWin32 *win32_gc;
-
- g_return_if_fail (GDK_IS_GC (gc));
-
- win32_gc = GDK_GC_WIN32 (gc);
+ GdkGCWin32 *win32_gc = GDK_GC_WIN32 (gc);
if (win32_gc->hcliprgn)
DeleteObject (win32_gc->hcliprgn);
@@ -681,46 +619,23 @@ gdk_gc_set_clip_region (GdkGC *gc,
}
void
-gdk_gc_copy (GdkGC *dst_gc,
- GdkGC *src_gc)
+_gdk_windowing_gc_copy (GdkGC *dst_gc,
+ GdkGC *src_gc)
{
- GdkGCWin32 *dst_win32_gc;
- GdkGCWin32 *src_win32_gc;
-
- g_return_if_fail (GDK_IS_GC_WIN32 (dst_gc));
- g_return_if_fail (GDK_IS_GC_WIN32 (src_gc));
-
- dst_win32_gc = GDK_GC_WIN32 (dst_gc);
- src_win32_gc = GDK_GC_WIN32 (src_gc);
+ GdkGCWin32 *dst_win32_gc = GDK_GC_WIN32 (dst_gc);
+ GdkGCWin32 *src_win32_gc = GDK_GC_WIN32 (src_gc);
GDK_NOTE (GC, g_print ("gdk_gc_copy: %p := %p\n", dst_win32_gc, src_win32_gc));
- if (dst_gc->colormap)
- g_object_unref (dst_gc->colormap);
-
if (dst_win32_gc->hcliprgn != NULL)
DeleteObject (dst_win32_gc->hcliprgn);
if (dst_win32_gc->font != NULL)
gdk_font_unref (dst_win32_gc->font);
- if (dst_win32_gc->tile != NULL)
- g_object_unref (dst_win32_gc->tile);
-
- if (dst_win32_gc->stipple != NULL)
- g_object_unref (dst_win32_gc->stipple);
-
if (dst_win32_gc->pen_dashes)
g_free (dst_win32_gc->pen_dashes);
- dst_gc->clip_x_origin = src_gc->clip_x_origin;
- dst_gc->clip_y_origin = src_gc->clip_y_origin;
- dst_gc->ts_x_origin = src_gc->ts_x_origin;
- dst_gc->ts_y_origin = src_gc->ts_y_origin;
- dst_gc->colormap = src_gc->colormap;
- if (dst_gc->colormap)
- g_object_ref (dst_gc->colormap);
-
dst_win32_gc->hcliprgn = src_win32_gc->hcliprgn;
if (dst_win32_gc->hcliprgn)
{
@@ -732,21 +647,11 @@ gdk_gc_copy (GdkGC *dst_gc,
}
dst_win32_gc->values_mask = src_win32_gc->values_mask;
- dst_win32_gc->foreground = src_win32_gc->foreground;
- dst_win32_gc->background = src_win32_gc->background;
dst_win32_gc->font = src_win32_gc->font;
if (dst_win32_gc->font != NULL)
gdk_font_ref (dst_win32_gc->font);
dst_win32_gc->rop2 = src_win32_gc->rop2;
- dst_win32_gc->fill_style = src_win32_gc->fill_style;
- dst_win32_gc->tile = src_win32_gc->tile;
- if (dst_win32_gc->tile != NULL)
- g_object_ref (dst_win32_gc->tile);
-
- dst_win32_gc->stipple = src_win32_gc->stipple;
- if (dst_win32_gc->stipple != NULL)
- g_object_ref (dst_win32_gc->stipple);
dst_win32_gc->subwindow_mode = src_win32_gc->subwindow_mode;
dst_win32_gc->graphics_exposures = src_win32_gc->graphics_exposures;
@@ -937,7 +842,7 @@ gdk_win32_hdc_get (GdkDrawable *drawable,
if (ok && (usage & GDK_GC_FOREGROUND))
{
- fg = _gdk_win32_colormap_color (impl->colormap, win32_gc->foreground);
+ fg = _gdk_win32_colormap_color (impl->colormap, _gdk_gc_get_fg_pixel (gc));
if ((hbr = CreateSolidBrush (fg)) == NULL)
WIN32_GDI_FAILED ("CreateSolidBrush"), ok = FALSE;
@@ -1259,23 +1164,3 @@ _gdk_win32_gdkregion_to_hrgn (GdkRegion *region,
return (hrgn);
}
-
-void
-_gdk_windowing_gc_get_foreground (GdkGC *gc,
- GdkColor *color)
-{
- GdkGCWin32 *win32_gc;
- GdkColormap *cmap;
-
- g_return_if_fail (GDK_IS_GC_WIN32 (gc));
-
- win32_gc = GDK_GC_WIN32 (gc);
-
- color->pixel = win32_gc->foreground;
- cmap = gdk_gc_get_colormap (gc);
-
- if (cmap)
- gdk_colormap_query_color (cmap, win32_gc->foreground, color);
- else
- g_warning ("No colormap in _gdk_windowing_gc_get_foreground");
-}
diff --git a/gdk/win32/gdkprivate-win32.h b/gdk/win32/gdkprivate-win32.h
index 0d1ab272d..d5786a086 100644
--- a/gdk/win32/gdkprivate-win32.h
+++ b/gdk/win32/gdkprivate-win32.h
@@ -268,14 +268,8 @@ struct _GdkGCWin32
GdkGCValuesMask values_mask;
- gulong foreground; /* Pixel values from GdkColor, */
- gulong background; /* not Win32 COLORREFs */
-
GdkFont *font;
gint rop2;
- GdkFill fill_style;
- GdkPixmap *tile;
- GdkPixmap *stipple;
GdkSubwindowMode subwindow_mode;
gint graphics_exposures;
gint pen_width;
diff --git a/gdk/x11/gdkdrawable-x11.c b/gdk/x11/gdkdrawable-x11.c
index c502ffa56..71e02909f 100644
--- a/gdk/x11/gdkdrawable-x11.c
+++ b/gdk/x11/gdkdrawable-x11.c
@@ -346,13 +346,13 @@ gdk_x11_drawable_update_picture_clip (GdkDrawable *drawable,
{
GdkDrawableImplX11 *impl = GDK_DRAWABLE_IMPL_X11 (drawable);
Display *xdisplay = GDK_SCREEN_XDISPLAY (impl->screen);
- GdkGCX11 *gc_private = gc ? GDK_GC_X11 (gc) : NULL;
Picture picture = gdk_x11_drawable_get_picture (drawable);
+ GdkRegion *clip_region = gc ? _gdk_gc_get_clip_region (gc) : NULL;
- if (gc && gc_private->clip_region)
+ if (clip_region)
{
- GdkRegionBox *boxes = gc_private->clip_region->rects;
- gint n_boxes = gc_private->clip_region->numRects;
+ GdkRegionBox *boxes = clip_region->rects;
+ gint n_boxes = clip_region->numRects;
XRectangle *rects = g_new (XRectangle, n_boxes);
int i;
diff --git a/gdk/x11/gdkgc-x11.c b/gdk/x11/gdkgc-x11.c
index 806e96fe7..2d0fe34a7 100644
--- a/gdk/x11/gdkgc-x11.c
+++ b/gdk/x11/gdkgc-x11.c
@@ -107,14 +107,6 @@ gdk_gc_x11_finalize (GObject *object)
{
GdkGCX11 *x11_gc = GDK_GC_X11 (object);
- if (x11_gc->clip_region)
- gdk_region_destroy (x11_gc->clip_region);
-
- if (x11_gc->stipple)
- g_object_unref (x11_gc->stipple);
- if (x11_gc->tile)
- g_object_unref (x11_gc->tile);
-
XFreeGC (GDK_GC_XDISPLAY (x11_gc), GDK_GC_XGC (x11_gc));
G_OBJECT_CLASS (parent_class)->finalize (object);
@@ -140,9 +132,10 @@ _gdk_x11_gc_new (GdkDrawable *drawable,
gc = g_object_new (_gdk_gc_x11_get_type (), NULL);
private = GDK_GC_X11 (gc);
+ _gdk_gc_init (gc, drawable, values, values_mask);
+
private->dirty_mask = 0;
private->have_clip_mask = FALSE;
- private->clip_region = NULL;
private->screen = GDK_DRAWABLE_IMPL_X11 (drawable)->screen;
@@ -160,29 +153,6 @@ _gdk_x11_gc_new (GdkDrawable *drawable,
private->dirty_mask |= GDK_GC_DIRTY_TS;
}
- if (values_mask & GDK_GC_FOREGROUND)
- private->fg_pixel = values->foreground.pixel;
-
- if (values_mask & GDK_GC_BACKGROUND)
- private->bg_pixel = values->background.pixel;
-
- if (values_mask & GDK_GC_FILL)
- private->fill = values->fill;
-
- if (values_mask & GDK_GC_STIPPLE)
- {
- private->stipple = values->stipple;
- if (private->stipple)
- g_object_ref (private->stipple);
- }
-
- if (values_mask & GDK_GC_TILE)
- {
- private->tile = values->tile;
- if (private->tile)
- g_object_ref (private->tile);
- }
-
if ((values_mask & GDK_GC_CLIP_MASK) && values->clip_mask)
private->have_clip_mask = TRUE;
@@ -211,7 +181,9 @@ _gdk_x11_gc_flush (GdkGC *gc)
if (private->dirty_mask & GDK_GC_DIRTY_CLIP)
{
- if (!private->clip_region)
+ GdkRegion *clip_region = _gdk_gc_get_clip_region (gc);
+
+ if (!clip_region)
XSetClipOrigin (xdisplay, xgc,
gc->clip_x_origin, gc->clip_y_origin);
else
@@ -219,7 +191,7 @@ _gdk_x11_gc_flush (GdkGC *gc)
XRectangle *rectangles;
gint n_rects;
- _gdk_region_get_xrectangles (private->clip_region,
+ _gdk_region_get_xrectangles (clip_region,
gc->clip_x_origin,
gc->clip_y_origin,
&rectangles,
@@ -417,54 +389,10 @@ gdk_x11_gc_set_values (GdkGC *gc,
if (values_mask & GDK_GC_CLIP_MASK)
{
- if (x11_gc->clip_region)
- {
- gdk_region_destroy (x11_gc->clip_region);
- x11_gc->clip_region = NULL;
- }
-
+ x11_gc->have_clip_region = FALSE;
x11_gc->have_clip_mask = values->clip_mask != NULL;
}
- if (values_mask & GDK_GC_FOREGROUND)
- x11_gc->fg_pixel = values->foreground.pixel;
-
- if (values_mask & GDK_GC_BACKGROUND)
- {
- if (x11_gc->bg_pixel != values->background.pixel)
- x11_gc->bg_pixel = values->background.pixel;
- }
-
- if (values_mask & GDK_GC_FILL)
- {
- if (x11_gc->fill != values->fill)
- x11_gc->fill = values->fill;
- }
-
- if (values_mask & GDK_GC_STIPPLE)
- {
- if (x11_gc->stipple != values->stipple)
- {
- if (x11_gc->stipple)
- g_object_unref (x11_gc->stipple);
- x11_gc->stipple = values->stipple;
- if (x11_gc->stipple)
- g_object_ref (x11_gc->stipple);
- }
- }
-
- if (values_mask & GDK_GC_TILE)
- {
- if (x11_gc->tile != values->tile)
- {
- if (x11_gc->tile)
- g_object_unref (x11_gc->tile);
- x11_gc->tile = values->tile;
- if (x11_gc->tile)
- g_object_ref (x11_gc->tile);
- }
- }
-
gdk_x11_gc_values_to_xvalues (values, values_mask, &xvalues, &xvalues_mask);
XChangeGC (GDK_GC_XDISPLAY (gc),
@@ -704,158 +632,42 @@ gdk_x11_gc_values_to_xvalues (GdkGCValues *values,
}
-/**
- * gdk_gc_set_clip_rectangle:
- * @gc: a #GdkGC.
- * @rectangle: the rectangle to clip to.
- *
- * Sets the clip mask for a graphics context from a
- * rectangle. The clip mask is interpreted relative to the clip
- * origin. (See gdk_gc_set_clip_origin()).
- **/
void
-gdk_gc_set_clip_rectangle (GdkGC *gc,
- GdkRectangle *rectangle)
+_gdk_windowing_gc_set_clip_region (GdkGC *gc,
+ GdkRegion *region)
{
- GdkGCX11 *x11_gc;
- gboolean had_region = FALSE;
-
- g_return_if_fail (GDK_IS_GC (gc));
-
- x11_gc = GDK_GC_X11 (gc);
-
- if (x11_gc->clip_region)
- {
- had_region = TRUE;
- gdk_region_destroy (x11_gc->clip_region);
- }
-
- if (rectangle)
- x11_gc->clip_region = gdk_region_rectangle (rectangle);
- else
- x11_gc->clip_region = NULL;
+ GdkGCX11 *x11_gc = GDK_GC_X11 (gc);
/* Unset immediately, to make sure Xlib doesn't keep the
* XID of an old clip mask cached
*/
- if ((had_region && !rectangle) || x11_gc->have_clip_mask)
+ if ((x11_gc->have_clip_region && !region) || x11_gc->have_clip_mask)
{
XSetClipMask (GDK_GC_XDISPLAY (gc), GDK_GC_XGC (gc), None);
x11_gc->have_clip_mask = FALSE;
}
- gc->clip_x_origin = 0;
- gc->clip_y_origin = 0;
-
- x11_gc->dirty_mask |= GDK_GC_DIRTY_CLIP;
-}
-
-/**
- * gdk_gc_set_clip_region:
- * @gc: a #GdkGC.
- * @region: the #GdkRegion.
- *
- * Sets the clip mask for a graphics context from a region structure.
- * The clip mask is interpreted relative to the clip origin. (See
- * gdk_gc_set_clip_origin()).
- **/
-void
-gdk_gc_set_clip_region (GdkGC *gc,
- GdkRegion *region)
-{
- GdkGCX11 *x11_gc;
- gboolean had_region = FALSE;
-
- g_return_if_fail (GDK_IS_GC (gc));
-
- x11_gc = GDK_GC_X11 (gc);
-
- if (x11_gc->clip_region)
- {
- had_region = TRUE;
- gdk_region_destroy (x11_gc->clip_region);
- }
-
- if (region)
- x11_gc->clip_region = gdk_region_copy (region);
- else
- x11_gc->clip_region = NULL;
-
- /* Unset immediately, to make sure Xlib doesn't keep the
- * XID of an old clip mask cached
- */
- if ((had_region && !region) || x11_gc->have_clip_mask)
- {
- XSetClipMask (GDK_GC_XDISPLAY (gc), GDK_GC_XGC (gc), None);
- x11_gc->have_clip_mask = FALSE;
- }
+ x11_gc->have_clip_region = region != NULL;
gc->clip_x_origin = 0;
gc->clip_y_origin = 0;
-
+
x11_gc->dirty_mask |= GDK_GC_DIRTY_CLIP;
}
-
-/**
- * gdk_gc_copy:
- * @dst_gc: the destination graphics context.
- * @src_gc: the source graphics context.
- *
- * Copy the set of values from one graphics context
- * onto another graphics context.
- **/
void
-gdk_gc_copy (GdkGC *dst_gc, GdkGC *src_gc)
+_gdk_windowing_gc_copy (GdkGC *dst_gc,
+ GdkGC *src_gc)
{
- GdkGCX11 *x11_src_gc;
- GdkGCX11 *x11_dst_gc;
-
- g_return_if_fail (GDK_IS_GC_X11 (dst_gc));
- g_return_if_fail (GDK_IS_GC_X11 (src_gc));
+ GdkGCX11 *x11_src_gc = GDK_GC_X11 (src_gc);
+ GdkGCX11 *x11_dst_gc = GDK_GC_X11 (dst_gc);
- x11_dst_gc = GDK_GC_X11 (dst_gc);
- x11_src_gc = GDK_GC_X11 (src_gc);
-
XCopyGC (GDK_GC_XDISPLAY (src_gc), GDK_GC_XGC (src_gc), ~((~1) << GCLastBit),
GDK_GC_XGC (dst_gc));
- dst_gc->clip_x_origin = src_gc->clip_x_origin;
- dst_gc->clip_y_origin = src_gc->clip_y_origin;
- dst_gc->ts_x_origin = src_gc->ts_x_origin;
- dst_gc->ts_y_origin = src_gc->ts_y_origin;
-
- if (src_gc->colormap)
- g_object_ref (src_gc->colormap);
-
- if (dst_gc->colormap)
- g_object_unref (dst_gc->colormap);
-
- dst_gc->colormap = src_gc->colormap;
-
- if (x11_dst_gc->clip_region)
- gdk_region_destroy (x11_dst_gc->clip_region);
-
- if (x11_src_gc->clip_region)
- x11_dst_gc->clip_region = gdk_region_copy (x11_src_gc->clip_region);
- else
- x11_dst_gc->clip_region = NULL;
-
x11_dst_gc->dirty_mask = x11_src_gc->dirty_mask;
- x11_dst_gc->fg_pixel = x11_src_gc->fg_pixel;
- x11_dst_gc->fill = x11_src_gc->fill;
-
- if (x11_dst_gc->stipple)
- g_object_unref (x11_dst_gc->stipple);
- x11_dst_gc->stipple = x11_src_gc->stipple;
- if (x11_dst_gc->stipple)
- g_object_ref (x11_dst_gc->stipple);
-
- if (x11_dst_gc->tile)
- g_object_unref (x11_dst_gc->tile);
- x11_dst_gc->tile = x11_src_gc->tile;
- if (x11_dst_gc->tile)
- g_object_ref (x11_dst_gc->tile);
+ x11_dst_gc->have_clip_region = x11_src_gc->have_clip_region;
+ x11_dst_gc->have_clip_mask = x11_src_gc->have_clip_mask;
}
/**
@@ -915,26 +727,5 @@ gdk_x11_gc_get_xgc (GdkGC *gc)
return gc_x11->xgc;
}
-void
-_gdk_windowing_gc_get_foreground (GdkGC *gc,
- GdkColor *color)
-{
- GdkGCX11 *x11_gc;
- GdkColormap *cmap;
-
- g_return_if_fail (GDK_IS_GC_X11 (gc));
-
- x11_gc = GDK_GC_X11 (gc);
-
- color->pixel = x11_gc->fg_pixel;
-
- cmap = gdk_gc_get_colormap (gc);
-
- if (cmap)
- gdk_colormap_query_color (cmap, x11_gc->fg_pixel, color);
- else
- g_warning ("No colormap in _gdk_windowing_gc_get_foreground");
-}
-
#define __GDK_GC_X11_C__
#include "gdkaliasdef.c"
diff --git a/gdk/x11/gdkprivate-x11.h b/gdk/x11/gdkprivate-x11.h
index 8554beb76..cde9042f6 100644
--- a/gdk/x11/gdkprivate-x11.h
+++ b/gdk/x11/gdkprivate-x11.h
@@ -59,17 +59,10 @@ struct _GdkGCX11
GC xgc;
GdkScreen *screen;
- GdkRegion *clip_region;
guint16 dirty_mask;
+ guint have_clip_region : 1;
guint have_clip_mask : 1;
guint depth : 8;
-
- GdkFill fill;
- GdkBitmap *stipple;
- GdkPixmap *tile;
-
- gulong fg_pixel;
- gulong bg_pixel;
};
struct _GdkGCX11Class