Commit 42634ee7 authored by Owen Taylor's avatar Owen Taylor Committed by Owen Taylor

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)
parent 8a31888a
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):
......
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):
......
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):
......
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):
......
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):
......
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):
......
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):
......
......@@ -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 */
......
......@@ -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
......
......@@ -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 */
......@@ -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));
......
......@@ -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);
......
......@@ -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))
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment