Keith Packard <[EMAIL PROTECTED]> writes:
> Around 18 o'clock on Aug 1, Bradley T Hughes wrote:
>
> > I have kept the code in qpainter_x11.cpp as is, using XRender* calls
> > directly. Clipping and such things are working now, so why break them,
> > right? :)
>
> Please don't use XRender calls directly -- that means Xft2 won't be usable
> on servers which don't support Render. I can export an
> XftDrawSetClipRectangles call if you like; the alternative is to simply
> construct an X region from your list of X rectangles and use the existing
> XftDrawSetClip call.
Here's a patch to add XftDrawSetClipRectangles that I had sitting
around (did it when coming back from Boston).
I'm of slightly mixed feelings about this addition:
- Having two interfaces to do the same thing is always ugly.
- Converting to a Region and back probably doesn't affect
speed significantly cases much if reasonably clipping shapes
are used.
But:
- Repeatedly calling XUnionRectWithRegion is algorithmically
very inefficient.
The 'ordering' parameter probably could be omitted; I put it in since
(for the non-Render case) it saves the server the work when
reconstructing the region. (The interesting case for me, as presumably
for Qt, involves a set of YXBanded rectangles.)
Regards,
Owen
--- fcpackage.02-07-13.12-22/Xft/xftdraw.c.cliprects Mon Jul 22 09:44:00 2002
+++ fcpackage.02-07-13.12-22/Xft/xftdraw.c Mon Jul 22 11:29:17 2002
@@ -153,7 +153,8 @@
draw->render.pict = 0;
draw->core.gc = 0;
draw->core.use_pixmap = 0;
- draw->clip = 0;
+ draw->have_clip_rects = False;
+ draw->clip.region = 0;
draw->subwindow_mode = ClipByChildren;
XftMemAlloc (XFT_MEM_DRAW, sizeof (XftDraw));
return draw;
@@ -177,7 +178,8 @@
draw->colormap = 0;
draw->render.pict = 0;
draw->core.gc = 0;
- draw->clip = 0;
+ draw->have_clip_rects = False;
+ draw->clip.region = 0;
draw->subwindow_mode = ClipByChildren;
XftMemAlloc (XFT_MEM_DRAW, sizeof (XftDraw));
return draw;
@@ -202,7 +204,8 @@
draw->colormap = 0;
draw->render.pict = 0;
draw->core.gc = 0;
- draw->clip = 0;
+ draw->have_clip_rects = False;
+ draw->clip.region = 0;
draw->subwindow_mode = ClipByChildren;
XftMemAlloc (XFT_MEM_DRAW, sizeof (XftDraw));
return draw;
@@ -284,8 +287,16 @@
XRenderFreePicture (draw->dpy, draw->render.pict);
if (draw->core.gc)
XFreeGC (draw->dpy, draw->core.gc);
- if (draw->clip)
- XDestroyRegion (draw->clip);
+ if (draw->have_clip_rects)
+ {
+ if (draw->clip.rects.r)
+ XFree (draw->clip.rects.r);
+ }
+ else
+ {
+ if (draw->clip.region)
+ XDestroyRegion (draw->clip.region);
+ }
XftMemFree (XFT_MEM_DRAW, sizeof (XftDraw));
free (draw);
}
@@ -398,9 +409,18 @@
format, mask, &pa);
if (!draw->render.pict)
return FcFalse;
- if (draw->clip)
- XRenderSetPictureClipRegion (draw->dpy, draw->render.pict,
- draw->clip);
+ if (draw->have_clip_rects)
+ {
+ XRenderSetPictureClipRectangles (draw->dpy, draw->render.pict,
+ draw->clip.rects.xOrigin, draw->clip.rects.yOrigin,
+ draw->clip.rects.r, draw->clip.rects.n);
+ }
+ else
+ {
+ if (draw->clip.region)
+ XRenderSetPictureClipRegion (draw->dpy, draw->render.pict,
+ draw->clip.region);
+ }
}
return FcTrue;
}
@@ -420,8 +440,17 @@
draw->core.gc = XCreateGC (draw->dpy, draw->drawable, mask, &gcv);
if (!draw->core.gc)
return FcFalse;
- if (draw->clip)
- XSetRegion (draw->dpy, draw->core.gc, draw->clip);
+ if (draw->have_clip_rects)
+ {
+ XSetClipRectangles (draw->dpy, draw->core.gc,
+ draw->clip.rects.xOrigin, draw->clip.rects.yOrigin,
+ draw->clip.rects.r, draw->clip.rects.n, draw->clip.rects.ordering);
+ }
+ else
+ {
+ if (draw->clip.region)
+ XSetRegion (draw->dpy, draw->core.gc, draw->clip.region);
+ }
}
XSetForeground (draw->dpy, draw->core.gc, color->pixel);
return FcTrue;
@@ -739,16 +768,79 @@
}
Bool
+XftDrawSetClipRectangles(XftDraw *draw,
+ int xOrigin,
+ int yOrigin,
+ _Xconst XRectangle *rects,
+ int n,
+ int ordering)
+{
+ XRectangle *new;
+
+ if (draw->have_clip_rects &&
+ n == draw->clip.rects.n &&
+ memcmp (draw->clip.rects.r, rects, n * sizeof (XRectangle)) == 0)
+ return True;
+
+ if (n)
+ {
+ new = (XRectangle *) malloc (n * sizeof (XRectangle));
+ if (!new)
+ return False;
+
+ memcpy (new, rects, n * sizeof (XRectangle));
+ }
+ else
+ {
+ new = 0;
+ }
+
+ if (draw->have_clip_rects)
+ {
+ if (draw->clip.rects.r)
+ XFree (draw->clip.rects.r);
+ }
+ else if (!draw->have_clip_rects && draw->clip.region)
+ {
+ if (draw->clip.region)
+ XDestroyRegion (draw->clip.region);
+ draw->have_clip_rects = True;
+ }
+
+ draw->have_clip_rects = True;
+ draw->clip.rects.r = new;
+ draw->clip.rects.n = n;
+ draw->clip.rects.xOrigin = xOrigin;
+ draw->clip.rects.yOrigin = yOrigin;
+ draw->clip.rects.ordering = ordering;
+
+ if (draw->render.pict)
+ {
+ XRenderSetPictureClipRectangles (draw->dpy, draw->render.pict, xOrigin, yOrigin, rects, n);
+ }
+ if (draw->core.gc)
+ {
+ XSetClipRectangles (draw->dpy, draw->core.gc, xOrigin, yOrigin,
+ draw->clip.rects.r, n, ordering);
+ }
+
+ return True;
+}
+
+Bool
XftDrawSetClip (XftDraw *draw,
Region r)
{
Region n = 0;
- if (!r && !draw->clip)
- return True;
-
- if (r && draw->clip && XEqualRegion (r, draw->clip))
- return True;
+ if (!draw->have_clip_rects)
+ {
+ if (!r && !draw->clip.region)
+ return True;
+
+ if (r && draw->clip.region && XEqualRegion (r, draw->clip.region))
+ return True;
+ }
if (r)
{
@@ -761,10 +853,25 @@
return False;
}
}
+ else
+ return False;
+ }
+
+ if (draw->have_clip_rects)
+ {
+ if (draw->clip.rects.r)
+ XFree (draw->clip.rects.r);
+
+ draw->have_clip_rects = False;
}
- if (draw->clip)
- XDestroyRegion (draw->clip);
- draw->clip = n;
+ else
+ {
+ if (draw->clip.region)
+ XDestroyRegion (draw->clip.region);
+ }
+
+ draw->clip.region = n;
+
if (draw->render.pict)
{
if (n)
@@ -780,7 +887,7 @@
if (draw->core.gc)
{
if (n)
- XSetRegion (draw->dpy, draw->core.gc, draw->clip);
+ XSetRegion (draw->dpy, draw->core.gc, draw->clip.region);
else
XSetClipMask (draw->dpy, draw->core.gc, None);
}
--- fcpackage.02-07-13.12-22/Xft/xftint.h.cliprects Mon Jul 22 10:03:41 2002
+++ fcpackage.02-07-13.12-22/Xft/xftint.h Mon Jul 22 10:12:27 2002
@@ -162,7 +162,17 @@
Drawable drawable;
Visual *visual; /* NULL for bitmaps */
Colormap colormap;
- Region clip;
+ Bool have_clip_rects;
+ union {
+ Region region;
+ struct {
+ XRectangle *r;
+ int n;
+ int xOrigin;
+ int yOrigin;
+ int ordering;
+ } rects;
+ } clip;
int subwindow_mode;
struct {
Picture pict;
--- fcpackage.02-07-13.12-22/Xft/Xft.h.cliprects Mon Jul 22 11:03:03 2002
+++ fcpackage.02-07-13.12-22/Xft/Xft.h Mon Jul 22 11:05:14 2002
@@ -262,6 +262,14 @@
Bool
+XftDrawSetClipRectangles(XftDraw *draw,
+ int xOrigin,
+ int yOrigin,
+ _Xconst XRectangle *rects,
+ int n,
+ int ordering);
+
+Bool
XftDrawSetClip (XftDraw *d,
Region r);