[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 
widgets without blinking.

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 
following three functions be added:


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 

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

More information about the cairo mailing list