# [Xr] Re: Rectangle operators

Bill Spitzak spitzak at d2.com
Wed Jun 4 11:48:25 PDT 2003

```On Wednesday 04 June 2003 06:23 am, Carl Worth wrote:
> On Jun 2, Soorya Kuloor wrote:
>  > While using clipping stuff I found that it is very slow (you had told me
>  > so before too). Here is a sample application that draws stuff and uses
>  > clipping. Without clipping the painting takes approx. 20-40msecs. With
>  > clipping it takes approx 1500 msecs, that is approx. 50-80 times
>  > slowdown. Are there any plans to fix this pretty soon?

I would also be very interested in pixel-aligned rectangle clipping. In
particular my code "clips out" *many* rectangles in order to draw overlapping

It does seem like adding direct support for rectangles would be very useful
as they can be very fast and they are very common. I'm thinking that the

XrFillRectangle(xrs,x,y,r,t)
XrClipToRectangle(xrs,x,y,r,t)
XrClipOutRectangle(xrs,x,y,r,t)

In all cases these are equivalent to newpath, moveto, 3 lineto's, and
closepath, then some operation, and then newpath again. Fill rectangle does
fill, cliptorectangle intersects the current clip with the rectangle, and
clipoutrectangle does invertpath and then clips with the rectangle (thus
removing the rectangle). I don't think there is any need for
XrStrokeRectangle() or any other operations on rectangular paths besides
these three.

If the current transformation is not rotated and the corners land within some
epsilon of integer values these should be very fast. It is also possible that
even non-integer corners will be much faster as long as the rectangle is not
rotated.

If Xr has some way of enumerating the current clippath or turning it into a
path, it may be best to say that whether this returned path includes the
results of these rectangles is undefined. It might be best to not allow a way
to get the clipping path back at all. Instead of reading the clipping path, I
have found it useful to have a function that might be called

int XrClippedRectangle(xrs, int X,Y,R,T, int*x, int*y, int*r, int*t)

This intersects the XYRT rectangle with the current clip and takes the
bounding box of the result and puts it in xyrt (it is legal for an
implementation to return any box between the minimum bounding box and the
passed one, this allows the math to be done in device space). I have also
found it slightly useful (though not that important) to return 0 if the
result is empty, 1 if it is the same rectangle, and other numbers if the
rectangle is different, primarily because any implementation probably figured
this out this useful information anyways.

Drawing code can use this to skip over sections that it knows will not be
drawn. This should only be used to skip large numbers of Xr calls as it is
probably faster to have Xr clip up to 10 calls than to do this.

spitzak at d2.com

```