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
This commit is contained in:
Owen Taylor 2005-05-02 23:29:24 +00:00 committed by Owen Taylor
parent b1cebb4c50
commit 788bbf520a
20 changed files with 1021 additions and 739 deletions

View File

@ -1,3 +1,52 @@
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
2005-05-02 Matthias Clasen <mclasen@redhat.com>
* tests/testiconview.c: Test cell renderers.

View File

@ -1,3 +1,52 @@
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
2005-05-02 Matthias Clasen <mclasen@redhat.com>
* tests/testiconview.c: Test cell renderers.

View File

@ -1,3 +1,52 @@
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
2005-05-02 Matthias Clasen <mclasen@redhat.com>
* tests/testiconview.c: Test cell renderers.

View File

@ -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

View File

@ -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);

View File

@ -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 (GdkGCClass *class)
{
GObjectClass *object_class = G_OBJECT_CLASS (class);
object_class->finalize = gdk_gc_finalize;
g_type_class_add_private (object_class, sizeof (GdkGCPrivate));
}
static void
gdk_gc_class_init (GObjectClass *class)
gdk_gc_init (GdkGC *gc)
{
parent_class = g_type_class_peek_parent (class);
class->finalize = gdk_gc_finalize;
}
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:
@ -598,6 +841,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
@ -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"

View File

@ -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 *

View File

@ -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;
@ -79,10 +81,6 @@ gdk_pango_renderer_finalize (GObject *object)
if (priv->drawable)
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;
const PangoMatrix *matrix;
priv->cr = gdk_drawable_create_cairo_context (priv->drawable);
pattern = cairo_pattern_create_for_surface (surface);
cairo_pattern_set_extend (pattern, CAIRO_EXTEND_REPEAT);
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);
}
}
priv->last_part = (PangoRenderPart)-1;
if (part != priv->last_part)
{
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_set_source (cr, pattern);
cairo_pattern_destroy (pattern);
}
else
{
set_part_color (gdk_renderer, cr, part);
_gdk_gc_update_context (priv->base_gc,
priv->cr,
color,
priv->stipple[part]);
priv->last_part = part;
}
matrix = pango_renderer_get_matrix (renderer);
if (matrix)
{
cairo_matrix_t *cairo_matrix;
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);
}
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,25 +353,37 @@ 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");
}
}
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;

View File

@ -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);
}

View File

@ -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);

View File

@ -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)
_gdk_windowing_gc_set_clip_region (GdkGC *gc,
GdkRegion *region)
{
GdkGC *private = (GdkGC *)gc;
GdkGCFBData *data;
GdkGCFBData *data = GDK_GC_FBDATA (gc);
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)
{
GdkGC *private = (GdkGC *)gc;
GdkGCFBData *data;
g_return_if_fail (gc != NULL);
data = GDK_GC_FBDATA (gc);
if (region == data->clip_region)
return;
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);
}

View File

@ -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;

View File

@ -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
{

View File

@ -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)
_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);
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)
{
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");
}

View File

@ -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;

View File

@ -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;

View File

@ -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"

View File

@ -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

View File

@ -2905,7 +2905,6 @@ draw_arrow (GdkWindow *window,
if (area)
{
cairo_save (cr);
cairo_rectangle (cr, area->x, area->y, area->width, area->height);
cairo_clip (cr);
cairo_new_path (cr);
@ -2939,9 +2938,6 @@ draw_arrow (GdkWindow *window,
cairo_close_path (cr);
cairo_fill (cr);
if (area)
cairo_restore (cr);
cairo_destroy (cr);
}
@ -3631,7 +3627,6 @@ gtk_default_draw_check (GtkStyle *style,
if (area)
{
cairo_save (cr);
cairo_rectangle (cr, area->x, area->y, area->width, area->height);
cairo_clip (cr);
cairo_new_path (cr);
@ -3726,9 +3721,6 @@ gtk_default_draw_check (GtkStyle *style,
cairo_fill (cr);
}
if (area)
cairo_restore (cr);
cairo_destroy (cr);
}
@ -3759,7 +3751,6 @@ gtk_default_draw_option (GtkStyle *style,
if (area)
{
cairo_save (cr);
cairo_rectangle (cr, area->x, area->y, area->width, area->height);
cairo_clip (cr);
cairo_new_path (cr);
@ -3784,9 +3775,7 @@ gtk_default_draw_option (GtkStyle *style,
(exterior_size - 1) / 2.,
0, 2 * G_PI);
cairo_save (cr);
cairo_fill (cr);
cairo_restore (cr);
cairo_fill_preserve (cr);
if (type == BUTTON)
gdk_cairo_set_source_color (cr, &style->fg[state_type]);
@ -3853,9 +3842,6 @@ gtk_default_draw_option (GtkStyle *style,
cairo_fill (cr);
}
if (area)
cairo_restore (cr);
cairo_destroy (cr);
}
@ -4811,7 +4797,6 @@ gtk_default_draw_expander (GtkStyle *style,
if (area)
{
cairo_save (cr);
cairo_rectangle (cr, area->x, area->y, area->width, area->height);
cairo_clip (cr);
cairo_new_path (cr);
@ -4888,7 +4873,6 @@ gtk_default_draw_expander (GtkStyle *style,
cairo_set_line_width (cr, line_width);
cairo_save (cr);
if (state_type == GTK_STATE_PRELIGHT)
gdk_cairo_set_source_color (cr,
&style->fg[GTK_STATE_PRELIGHT]);
@ -4899,15 +4883,11 @@ gtk_default_draw_expander (GtkStyle *style,
gdk_cairo_set_source_color (cr,
&style->base[GTK_STATE_NORMAL]);
cairo_fill (cr);
cairo_restore (cr);
cairo_fill_preserve (cr);
gdk_cairo_set_source_color (cr, &style->fg[state_type]);
cairo_stroke (cr);
if (area)
cairo_restore (cr);
cairo_destroy (cr);
}

View File

@ -227,6 +227,8 @@ static gboolean gtk_widget_real_can_activate_accel (GtkWidget *widg
static void gtk_widget_set_usize_internal (GtkWidget *widget,
gint width,
gint height);
static void gtk_widget_get_draw_rectangle (GtkWidget *widget,
GdkRectangle *rect);
/* --- variables --- */
@ -1456,6 +1458,12 @@ gtk_widget_class_init (GtkWidgetClass *klass)
P_("Aspect ratio with which to draw insertion cursor"),
0.0, 1.0, 0.04,
GTK_PARAM_READABLE));
gtk_widget_class_install_style_property (klass,
g_param_spec_boxed ("draw-border",
P_("Draw Border"),
P_("Size of areas outside the widget's allocation to draw"),
GTK_TYPE_BORDER,
GTK_PARAM_READABLE));
}
static void
@ -2430,6 +2438,55 @@ gtk_widget_queue_draw_area (GtkWidget *widget,
gdk_window_invalidate_rect (widget->window, &invalid_rect, TRUE);
}
static void
widget_add_child_draw_rectangle (GtkWidget *widget,
GdkRectangle *rect)
{
GdkRectangle child_rect;
if (!GTK_WIDGET_REALIZED (widget) ||
widget->window != widget->parent->window)
return;
gtk_widget_get_draw_rectangle (widget, &child_rect);
gdk_rectangle_union (rect, &child_rect, rect);
}
static void
gtk_widget_get_draw_rectangle (GtkWidget *widget,
GdkRectangle *rect)
{
if (GTK_WIDGET_NO_WINDOW (widget))
{
GtkBorder *draw_border = NULL;
*rect = widget->allocation;
gtk_widget_style_get (widget,
"draw-border", &draw_border,
NULL);
if (draw_border)
{
rect->x -= draw_border->top;
rect->y -= draw_border->left;
rect->width += draw_border->left + draw_border->right;
rect->height += draw_border->top + draw_border->bottom;
}
if (GTK_IS_CONTAINER (widget))
gtk_container_forall (GTK_CONTAINER (widget),
(GtkCallback)widget_add_child_draw_rectangle,
rect);
}
else
{
rect->x = 0;
rect->y = 0;
rect->width = widget->allocation.width;
rect->height = widget->allocation.height;
}
}
/**
* gtk_widget_queue_draw:
* @widget: a #GtkWidget
@ -2441,20 +2498,15 @@ gtk_widget_queue_draw_area (GtkWidget *widget,
void
gtk_widget_queue_draw (GtkWidget *widget)
{
GdkRectangle rect;
g_return_if_fail (GTK_IS_WIDGET (widget));
if (widget->allocation.width || widget->allocation.height)
{
if (GTK_WIDGET_NO_WINDOW (widget))
gtk_widget_queue_draw_area (widget, widget->allocation.x,
widget->allocation.y,
widget->allocation.width,
widget->allocation.height);
else
gtk_widget_queue_draw_area (widget, 0, 0,
widget->allocation.width,
widget->allocation.height);
}
gtk_widget_get_draw_rectangle (widget, &rect);
gtk_widget_queue_draw_area (widget,
rect.x, rect.y,
rect.width, rect.height);
}
/* Invalidates the given area (allocation-relative-coordinates)
@ -2687,11 +2739,13 @@ gtk_widget_invalidate_widget_windows (GtkWidget *widget,
static void
gtk_widget_queue_shallow_draw (GtkWidget *widget)
{
GdkRectangle rect;
GdkRegion *region;
g_return_if_fail (GTK_IS_WIDGET (widget));
region = gdk_region_rectangle (&widget->allocation);
gtk_widget_get_draw_rectangle (widget, &rect);
region = gdk_region_rectangle (&rect);
gtk_widget_invalidate_widget_windows (widget, region);
gdk_region_destroy (region);
}
@ -3883,12 +3937,15 @@ GdkRegion *
gtk_widget_region_intersect (GtkWidget *widget,
GdkRegion *region)
{
GdkRectangle rect;
GdkRegion *dest;
g_return_val_if_fail (GTK_IS_WIDGET (widget), NULL);
g_return_val_if_fail (region != NULL, NULL);
gtk_widget_get_draw_rectangle (widget, &rect);
dest = gdk_region_rectangle (&widget->allocation);
dest = gdk_region_rectangle (&rect);
gdk_region_intersect (dest, region);