summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorOwen Taylor <otaylor@redhat.com>2001-11-05 17:48:58 +0000
committerOwen Taylor <otaylor@src.gnome.org>2001-11-05 17:48:58 +0000
commit42634ee7355c628f88908a9c4a73f3b4ee0335c5 (patch)
treec2fb9149a02ca46b97dd72d1070b707c2fe945e9
parent8a31888a046a56fb05f7b409537122d72e671ff7 (diff)
downloadgtk+-42634ee7355c628f88908a9c4a73f3b4ee0335c5.tar.gz
Redo Xft support to go directly to Picture objects instead of using
Mon Nov 5 12:46:44 2001 Owen Taylor <otaylor@redhat.com> * gdk/x11/gdkdrawable-x11.[ch] gdk/x11/gdkgc-x11.c gdk/x11/gdkpixmap-x11.c gdk/x11/gdkprivate-x11.h gdk/x11/gdkwindow-x11.c: Redo Xft support to go directly to Picture objects instead of using XftDraw. This fixes the problem where we weren't able to properly destroy XftDraw objects before destroying the accompanying windows, and probably improves efficiency a bit too. (#50214)
-rw-r--r--ChangeLog11
-rw-r--r--ChangeLog.pre-2-011
-rw-r--r--ChangeLog.pre-2-1011
-rw-r--r--ChangeLog.pre-2-211
-rw-r--r--ChangeLog.pre-2-411
-rw-r--r--ChangeLog.pre-2-611
-rw-r--r--ChangeLog.pre-2-811
-rw-r--r--gdk/x11/gdkdrawable-x11.c136
-rw-r--r--gdk/x11/gdkdrawable-x11.h10
-rw-r--r--gdk/x11/gdkgc-x11.c102
-rw-r--r--gdk/x11/gdkpixmap-x11.c9
-rw-r--r--gdk/x11/gdkprivate-x11.h16
-rw-r--r--gdk/x11/gdkwindow-x11.c9
13 files changed, 282 insertions, 77 deletions
diff --git a/ChangeLog b/ChangeLog
index e8912c4145..2f34bfae10 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,14 @@
+Mon Nov 5 12:46:44 2001 Owen Taylor <otaylor@redhat.com>
+
+ * gdk/x11/gdkdrawable-x11.[ch] gdk/x11/gdkgc-x11.c
+ gdk/x11/gdkpixmap-x11.c gdk/x11/gdkprivate-x11.h
+ gdk/x11/gdkwindow-x11.c: Redo Xft support to go
+ directly to Picture objects instead of using XftDraw.
+ This fixes the problem where we weren't able to
+ properly destroy XftDraw objects before destroying
+ the accompanying windows, and probably improves
+ efficiency a bit too. (#50214)
+
Mon Nov 5 10:01:49 2001 Owen Taylor <otaylor@redhat.com>
* gdk/x11/gdkgeometry-x11.c (gdk_window_compute_position):
diff --git a/ChangeLog.pre-2-0 b/ChangeLog.pre-2-0
index e8912c4145..2f34bfae10 100644
--- a/ChangeLog.pre-2-0
+++ b/ChangeLog.pre-2-0
@@ -1,3 +1,14 @@
+Mon Nov 5 12:46:44 2001 Owen Taylor <otaylor@redhat.com>
+
+ * gdk/x11/gdkdrawable-x11.[ch] gdk/x11/gdkgc-x11.c
+ gdk/x11/gdkpixmap-x11.c gdk/x11/gdkprivate-x11.h
+ gdk/x11/gdkwindow-x11.c: Redo Xft support to go
+ directly to Picture objects instead of using XftDraw.
+ This fixes the problem where we weren't able to
+ properly destroy XftDraw objects before destroying
+ the accompanying windows, and probably improves
+ efficiency a bit too. (#50214)
+
Mon Nov 5 10:01:49 2001 Owen Taylor <otaylor@redhat.com>
* gdk/x11/gdkgeometry-x11.c (gdk_window_compute_position):
diff --git a/ChangeLog.pre-2-10 b/ChangeLog.pre-2-10
index e8912c4145..2f34bfae10 100644
--- a/ChangeLog.pre-2-10
+++ b/ChangeLog.pre-2-10
@@ -1,3 +1,14 @@
+Mon Nov 5 12:46:44 2001 Owen Taylor <otaylor@redhat.com>
+
+ * gdk/x11/gdkdrawable-x11.[ch] gdk/x11/gdkgc-x11.c
+ gdk/x11/gdkpixmap-x11.c gdk/x11/gdkprivate-x11.h
+ gdk/x11/gdkwindow-x11.c: Redo Xft support to go
+ directly to Picture objects instead of using XftDraw.
+ This fixes the problem where we weren't able to
+ properly destroy XftDraw objects before destroying
+ the accompanying windows, and probably improves
+ efficiency a bit too. (#50214)
+
Mon Nov 5 10:01:49 2001 Owen Taylor <otaylor@redhat.com>
* gdk/x11/gdkgeometry-x11.c (gdk_window_compute_position):
diff --git a/ChangeLog.pre-2-2 b/ChangeLog.pre-2-2
index e8912c4145..2f34bfae10 100644
--- a/ChangeLog.pre-2-2
+++ b/ChangeLog.pre-2-2
@@ -1,3 +1,14 @@
+Mon Nov 5 12:46:44 2001 Owen Taylor <otaylor@redhat.com>
+
+ * gdk/x11/gdkdrawable-x11.[ch] gdk/x11/gdkgc-x11.c
+ gdk/x11/gdkpixmap-x11.c gdk/x11/gdkprivate-x11.h
+ gdk/x11/gdkwindow-x11.c: Redo Xft support to go
+ directly to Picture objects instead of using XftDraw.
+ This fixes the problem where we weren't able to
+ properly destroy XftDraw objects before destroying
+ the accompanying windows, and probably improves
+ efficiency a bit too. (#50214)
+
Mon Nov 5 10:01:49 2001 Owen Taylor <otaylor@redhat.com>
* gdk/x11/gdkgeometry-x11.c (gdk_window_compute_position):
diff --git a/ChangeLog.pre-2-4 b/ChangeLog.pre-2-4
index e8912c4145..2f34bfae10 100644
--- a/ChangeLog.pre-2-4
+++ b/ChangeLog.pre-2-4
@@ -1,3 +1,14 @@
+Mon Nov 5 12:46:44 2001 Owen Taylor <otaylor@redhat.com>
+
+ * gdk/x11/gdkdrawable-x11.[ch] gdk/x11/gdkgc-x11.c
+ gdk/x11/gdkpixmap-x11.c gdk/x11/gdkprivate-x11.h
+ gdk/x11/gdkwindow-x11.c: Redo Xft support to go
+ directly to Picture objects instead of using XftDraw.
+ This fixes the problem where we weren't able to
+ properly destroy XftDraw objects before destroying
+ the accompanying windows, and probably improves
+ efficiency a bit too. (#50214)
+
Mon Nov 5 10:01:49 2001 Owen Taylor <otaylor@redhat.com>
* gdk/x11/gdkgeometry-x11.c (gdk_window_compute_position):
diff --git a/ChangeLog.pre-2-6 b/ChangeLog.pre-2-6
index e8912c4145..2f34bfae10 100644
--- a/ChangeLog.pre-2-6
+++ b/ChangeLog.pre-2-6
@@ -1,3 +1,14 @@
+Mon Nov 5 12:46:44 2001 Owen Taylor <otaylor@redhat.com>
+
+ * gdk/x11/gdkdrawable-x11.[ch] gdk/x11/gdkgc-x11.c
+ gdk/x11/gdkpixmap-x11.c gdk/x11/gdkprivate-x11.h
+ gdk/x11/gdkwindow-x11.c: Redo Xft support to go
+ directly to Picture objects instead of using XftDraw.
+ This fixes the problem where we weren't able to
+ properly destroy XftDraw objects before destroying
+ the accompanying windows, and probably improves
+ efficiency a bit too. (#50214)
+
Mon Nov 5 10:01:49 2001 Owen Taylor <otaylor@redhat.com>
* gdk/x11/gdkgeometry-x11.c (gdk_window_compute_position):
diff --git a/ChangeLog.pre-2-8 b/ChangeLog.pre-2-8
index e8912c4145..2f34bfae10 100644
--- a/ChangeLog.pre-2-8
+++ b/ChangeLog.pre-2-8
@@ -1,3 +1,14 @@
+Mon Nov 5 12:46:44 2001 Owen Taylor <otaylor@redhat.com>
+
+ * gdk/x11/gdkdrawable-x11.[ch] gdk/x11/gdkgc-x11.c
+ gdk/x11/gdkpixmap-x11.c gdk/x11/gdkprivate-x11.h
+ gdk/x11/gdkwindow-x11.c: Redo Xft support to go
+ directly to Picture objects instead of using XftDraw.
+ This fixes the problem where we weren't able to
+ properly destroy XftDraw objects before destroying
+ the accompanying windows, and probably improves
+ efficiency a bit too. (#50214)
+
Mon Nov 5 10:01:49 2001 Owen Taylor <otaylor@redhat.com>
* gdk/x11/gdkgeometry-x11.c (gdk_window_compute_position):
diff --git a/gdk/x11/gdkdrawable-x11.c b/gdk/x11/gdkdrawable-x11.c
index f5589dcb0a..0ca8d12201 100644
--- a/gdk/x11/gdkdrawable-x11.c
+++ b/gdk/x11/gdkdrawable-x11.c
@@ -203,6 +203,70 @@ gdk_drawable_impl_x11_finalize (GObject *object)
G_OBJECT_CLASS (parent_class)->finalize (object);
}
+#ifdef HAVE_XFT
+static Picture
+gdk_x11_drawable_get_picture (GdkDrawable *drawable)
+{
+ GdkDrawableImplX11 *impl = GDK_DRAWABLE_IMPL_X11 (drawable);
+
+ if (impl->picture == None)
+ {
+ GdkVisual *visual = gdk_drawable_get_visual (drawable);
+ XRenderPictFormat *format;
+
+ if (!visual)
+ {
+ g_warning ("Using Xft rendering requires the drawable argument to\n"
+ "have a specified colormap. All windows have a colormap,\n"
+ "however, pixmaps only have colormap by default if they\n"
+ "were created with a non-NULL window argument. Otherwise\n"
+ "a colormap must be set on them with gdk_drawable_set_colormap");
+ return None;
+ }
+
+ format = XRenderFindVisualFormat (impl->xdisplay, GDK_VISUAL_XVISUAL (visual));
+ impl->picture = XRenderCreatePicture (impl->xdisplay, impl->xid, format, 0, NULL);
+ }
+
+ return impl->picture;
+}
+
+static void
+gdk_x11_drawable_update_picture_clip (GdkDrawable *drawable,
+ GdkGC *gc)
+{
+ GdkGCX11 *gc_private = GDK_GC_X11 (gc);
+ GdkDrawableImplX11 *impl = GDK_DRAWABLE_IMPL_X11 (drawable);
+ Picture picture = gdk_x11_drawable_get_picture (drawable);
+
+ if (gc_private->clip_region)
+ {
+ GdkRegionBox *boxes = gc_private->clip_region->rects;
+ gint n_boxes = gc_private->clip_region->numRects;
+ XRectangle *rects = g_new (XRectangle, n_boxes);
+ int i;
+
+ for (i=0; i < n_boxes; i++)
+ {
+ rects[i].x = CLAMP (boxes[i].x1 + gc->clip_x_origin, G_MINSHORT, G_MAXSHORT);
+ rects[i].y = CLAMP (boxes[i].y1 + gc->clip_y_origin, G_MINSHORT, G_MAXSHORT);
+ rects[i].width = CLAMP (boxes[i].x2 + gc->clip_x_origin, G_MINSHORT, G_MAXSHORT) - rects[i].x;
+ rects[i].height = CLAMP (boxes[i].y2 + gc->clip_y_origin, G_MINSHORT, G_MAXSHORT) - rects[i].y;
+ }
+
+ XRenderSetPictureClipRectangles (impl->xdisplay, picture, 0, 0, rects, n_boxes);
+
+ g_free (rects);
+ }
+ else
+ {
+ XRenderPictureAttributes pa;
+ pa.clip_mask = None;
+ XRenderChangePicture (impl->xdisplay, picture, CPClipMask, &pa);
+ }
+}
+#endif
+
/*****************************************************
* X11 specific implementations of generic functions *
*****************************************************/
@@ -581,40 +645,6 @@ gdk_x11_draw_lines (GdkDrawable *drawable,
g_free (tmp_points);
}
-#if HAVE_XFT
-static void
-update_xft_draw_clip (GdkGC *gc)
-{
- GdkGCX11 *private = GDK_GC_X11 (gc);
- int i;
-
- if (private->xft_draw)
- {
- if (private->clip_region)
- {
- GdkRegionBox *boxes = private->clip_region->rects;
- Region region = XCreateRegion ();
-
- for (i=0; i<private->clip_region->numRects; i++)
- {
- XRectangle rect;
-
- rect.x = CLAMP (boxes[i].x1 + gc->clip_x_origin, G_MINSHORT, G_MAXSHORT);
- rect.y = CLAMP (boxes[i].y1 + gc->clip_y_origin, G_MINSHORT, G_MAXSHORT);
- rect.width = CLAMP (boxes[i].x2 + gc->clip_x_origin, G_MINSHORT, G_MAXSHORT) - rect.x;
- rect.height = CLAMP (boxes[i].y2 + gc->clip_y_origin, G_MINSHORT, G_MAXSHORT) - rect.y;
- XUnionRectWithRegion (&rect, region, region);
- }
-
- XftDrawSetClip (private->xft_draw, region);
- XDestroyRegion (region);
- }
- else
- XftDrawSetClip (private->xft_draw, NULL);
- }
-}
-#endif
-
static void
gdk_x11_draw_glyphs (GdkDrawable *drawable,
GdkGC *gc,
@@ -630,39 +660,15 @@ gdk_x11_draw_glyphs (GdkDrawable *drawable,
#if HAVE_XFT
if (PANGO_XFT_IS_FONT (font))
{
- GdkGCX11 *gc_x11 = GDK_GC_X11 (gc);
- XftColor xft_color;
- GdkColormap *cmap;
- GdkColor color;
-
- cmap = gdk_gc_get_colormap (gc);
+ Picture src_picture;
+ Picture dest_picture;
- _gdk_x11_gc_flush (gc);
-
- if (!gc_x11->xft_draw)
- {
- gc_x11->xft_draw = XftDrawCreate (impl->xdisplay,
- impl->xid,
- GDK_VISUAL_XVISUAL (gdk_colormap_get_visual (cmap)),
- GDK_COLORMAP_XCOLORMAP (cmap));
- update_xft_draw_clip (gc);
- }
-
- else
- {
- XftDrawChange (gc_x11->xft_draw, impl->xid);
- update_xft_draw_clip (gc);
- }
-
- gdk_colormap_query_color (cmap, gc_x11->fg_pixel, &color);
-
- xft_color.color.red = color.red;
- xft_color.color.green = color.green;
- xft_color.color.blue = color.blue;
- xft_color.color.alpha = 0xffff;
+ src_picture = _gdk_x11_gc_get_fg_picture (gc);
+
+ gdk_x11_drawable_update_picture_clip (drawable, gc);
+ dest_picture = gdk_x11_drawable_get_picture (drawable);
- pango_xft_render (gc_x11->xft_draw, &xft_color,
- font, glyphs, x, y);
+ pango_xft_picture_render (impl->xdisplay, src_picture, dest_picture, font, glyphs, x, y);
}
else
#endif /* !HAVE_XFT */
diff --git a/gdk/x11/gdkdrawable-x11.h b/gdk/x11/gdkdrawable-x11.h
index 7d20d50d52..aa681585d4 100644
--- a/gdk/x11/gdkdrawable-x11.h
+++ b/gdk/x11/gdkdrawable-x11.h
@@ -27,9 +27,15 @@
#ifndef __GDK_DRAWABLE_X11_H__
#define __GDK_DRAWABLE_X11_H__
+#include <config.h>
+
#include <gdk/gdkdrawable.h>
#include <gdk/x11/gdkx.h>
+#ifdef HAVE_XFT
+#include <X11/extensions/Xrender.h>
+#endif
+
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
@@ -57,6 +63,10 @@ struct _GdkDrawableImplX11
Window xid;
Display *xdisplay;
+
+#ifdef HAVE_XFT
+ Picture picture;
+#endif
};
struct _GdkDrawableImplX11Class
diff --git a/gdk/x11/gdkgc-x11.c b/gdk/x11/gdkgc-x11.c
index ce3c60490e..f6c4da625c 100644
--- a/gdk/x11/gdkgc-x11.c
+++ b/gdk/x11/gdkgc-x11.c
@@ -26,10 +26,6 @@
#include <config.h>
-#if HAVE_XFT
-#include <pango/pangoxft.h>
-#endif
-
#include "gdkgc.h"
#include "gdkprivate-x11.h"
#include "gdkregion-generic.h"
@@ -112,13 +108,13 @@ gdk_gc_x11_finalize (GObject *object)
if (x11_gc->clip_region)
gdk_region_destroy (x11_gc->clip_region);
- XFreeGC (GDK_GC_XDISPLAY (x11_gc), GDK_GC_XGC (x11_gc));
-
#if HAVE_XFT
- if (x11_gc->xft_draw)
- XftDrawDestroy (x11_gc->xft_draw);
+ if (x11_gc->fg_picture != None)
+ XRenderFreePicture (x11_gc->xdisplay, x11_gc->fg_picture);
#endif
+ XFreeGC (GDK_GC_XDISPLAY (x11_gc), GDK_GC_XGC (x11_gc));
+
G_OBJECT_CLASS (parent_class)->finalize (object);
}
@@ -757,3 +753,93 @@ gdk_x11_gc_get_xgc (GdkGC *gc)
return gc_x11->xgc;
}
+
+/* Various bits of the below are roughly cribbed from XFree86
+ * lib/Xft/xftdraw.c, Copyright 2000, Keith Packard
+ */
+
+static XRenderPictFormat *
+foreground_format (GdkGC *gc)
+{
+ XRenderPictFormat pf;
+
+ pf.type = PictTypeDirect;
+ pf.depth = 32;
+ pf.direct.redMask = 0xff;
+ pf.direct.greenMask = 0xff;
+ pf.direct.blueMask = 0xff;
+ pf.direct.alphaMask = 0xff;
+
+ return XRenderFindFormat (GDK_GC_XDISPLAY (gc),
+ (PictFormatType |
+ PictFormatDepth |
+ PictFormatRedMask |
+ PictFormatGreenMask |
+ PictFormatBlueMask |
+ PictFormatAlphaMask),
+ &pf,
+ 0);
+}
+
+#ifdef HAVE_XFT
+/**
+ * _gdk_x11_gc_get_fg_picture:
+ * @gc: a #GdkGC
+ *
+ * Gets a Xrender Picture object suitable for being the source
+ * drawable for drawing with the foreground the graphics context.
+ * (Currently, only foreground color is handled, but in the
+ * future we should handle tiles/stipples as well.)
+ *
+ * Return value: a Picture, owned by the GC; this cannot be
+ * used over subsequent modification of the GC.
+ **/
+Picture
+_gdk_x11_gc_get_fg_picture (GdkGC *gc)
+{
+ GdkGCX11 *x11_gc;
+ GdkColormap *cmap = gdk_gc_get_colormap (gc);
+ gboolean new = FALSE;
+ GdkColor color;
+
+ g_return_val_if_fail (GDK_IS_GC_X11 (gc), None);
+
+ x11_gc = GDK_GC_X11 (gc);
+
+ if (x11_gc->fg_picture == None)
+ {
+ XRenderPictureAttributes pa;
+ XRenderPictFormat *pix_format = foreground_format (gc);
+
+ Pixmap pix = XCreatePixmap (x11_gc->xdisplay, _gdk_root_window,
+ 1, 1, pix_format->depth);
+ pa.repeat = True;
+ x11_gc->fg_picture = XRenderCreatePicture (x11_gc->xdisplay,
+ pix,
+ pix_format,
+ CPRepeat, &pa);
+ XFreePixmap (x11_gc->xdisplay, pix);
+
+ new = TRUE;
+ }
+
+ gdk_colormap_query_color (cmap, x11_gc->fg_pixel, &color);
+
+ if (new ||
+ x11_gc->fg_picture_color.red != color.red ||
+ x11_gc->fg_picture_color.green != color.green ||
+ x11_gc->fg_picture_color.blue != color.blue)
+ {
+ x11_gc->fg_picture_color.red = color.red;
+ x11_gc->fg_picture_color.green = color.green;
+ x11_gc->fg_picture_color.blue = color.blue;
+ x11_gc->fg_picture_color.alpha = 0xffff;
+
+ XRenderFillRectangle (x11_gc->xdisplay, PictOpSrc,
+ x11_gc->fg_picture, &x11_gc->fg_picture_color,
+ 0, 0, 1, 1);
+ }
+
+ return x11_gc->fg_picture;
+}
+#endif /* HAVE_XFT */
diff --git a/gdk/x11/gdkpixmap-x11.c b/gdk/x11/gdkpixmap-x11.c
index 15804ce8a4..ae50cc3375 100644
--- a/gdk/x11/gdkpixmap-x11.c
+++ b/gdk/x11/gdkpixmap-x11.c
@@ -122,6 +122,15 @@ gdk_pixmap_impl_x11_finalize (GObject *object)
GdkPixmapImplX11 *impl = GDK_PIXMAP_IMPL_X11 (object);
GdkPixmap *wrapper = GDK_PIXMAP (GDK_DRAWABLE_IMPL_X11 (impl)->wrapper);
+#ifdef HAVE_XFT
+ {
+ GdkDrawableImplX11 *draw_impl = GDK_DRAWABLE_IMPL_X11 (impl);
+
+ if (draw_impl->picture)
+ XRenderFreePicture (draw_impl->xdisplay, draw_impl->picture);
+ }
+#endif /* HAVE_XFT */
+
if (!impl->is_foreign)
XFreePixmap (GDK_PIXMAP_XDISPLAY (wrapper), GDK_PIXMAP_XID (wrapper));
diff --git a/gdk/x11/gdkprivate-x11.h b/gdk/x11/gdkprivate-x11.h
index 8b960974fb..6552ff5383 100644
--- a/gdk/x11/gdkprivate-x11.h
+++ b/gdk/x11/gdkprivate-x11.h
@@ -39,6 +39,10 @@
#include <config.h>
+#if HAVE_XFT
+#include <X11/extensions/Xrender.h>
+#endif
+
#define GDK_TYPE_GC_X11 (_gdk_gc_x11_get_type ())
#define GDK_GC_X11(object) (G_TYPE_CHECK_INSTANCE_CAST ((object), GDK_TYPE_GC_X11, GdkGCX11))
#define GDK_GC_X11_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GDK_TYPE_GC_X11, GdkGCX11Class))
@@ -60,10 +64,10 @@ struct _GdkGCX11
GdkRegion *clip_region;
guint dirty_mask;
- /* We can't conditionalize on HAVE_XFT here, so we simply always
- * have this here as a gpointer.
- */
- gpointer xft_draw;
+#ifdef HAVE_XFT
+ Picture fg_picture;
+ XRenderColor fg_picture_color;
+#endif
gulong fg_pixel;
};
@@ -95,6 +99,10 @@ gint gdk_send_xevent (Window window,
GType _gdk_gc_x11_get_type (void);
+#ifdef HAVE_XFT
+Picture _gdk_x11_gc_get_fg_picture (GdkGC *gc);
+#endif /* HAVE_XFT */
+
GdkGC *_gdk_x11_gc_new (GdkDrawable *drawable,
GdkGCValues *values,
GdkGCValuesMask values_mask);
diff --git a/gdk/x11/gdkwindow-x11.c b/gdk/x11/gdkwindow-x11.c
index f6d6d89d90..49a6636943 100644
--- a/gdk/x11/gdkwindow-x11.c
+++ b/gdk/x11/gdkwindow-x11.c
@@ -738,6 +738,15 @@ _gdk_windowing_window_destroy (GdkWindow *window,
if (private->extension_events != 0)
gdk_input_window_destroy (window);
+#ifdef HAVE_XFT
+ {
+ GdkDrawableImplX11 *draw_impl = GDK_DRAWABLE_IMPL_X11 (private->impl);
+
+ if (draw_impl->picture)
+ XRenderFreePicture (draw_impl->xdisplay, draw_impl->picture);
+ }
+#endif /* HAVE_XFT */
+
if (private->window_type == GDK_WINDOW_FOREIGN)
{
if (!foreign_destroy && (private->parent != NULL))