[comp.windows.x] X11 fenceposts

egc@h.gp.cs.cmu.edu (eddie caplan) (11/17/88)

under X11R2 on a (black and white) microvax 2:

XDrawRectangle(display, drawable, gc, x, y, w, h) draws a rectangle defined
by the coordinates (x,y)  (x+w,y)  (x+w,y+h)  (x,y+h)

while

XFillRectangle(display, drawable, gc, x, y, w, h) fills a rectangle defined
by the coordinates (x,y)  (x+w-1,y)  (x+w-1,y+h-1)  (x,y+h-1)

the manual (Xlib - C Library, pp 83 and 86) say that both functions
should be behaving in the first manner.  they aren't.  in addition, my
programming religion tells me that they *should* both be behaving in
the second manner anyway.

how do other devices' servers handle these functions?  is this more
consistent under X11R3?
-- 

keith@EXPO.LCS.MIT.EDU (Keith Packard) (11/17/88)

>XDrawRectangle(display, drawable, gc, x, y, w, h) draws a rectangle defined
>by the coordinates (x,y)  (x+w,y)  (x+w,y+h)  (x,y+h)

>while

>XFillRectangle(display, drawable, gc, x, y, w, h) fills a rectangle defined
>by the coordinates (x,y)  (x+w-1,y)  (x+w-1,y+h-1)  (x,y+h-1)

>the manual (Xlib - C Library, pp 83 and 86) say that both functions
>should be behaving in the first manner.

The Protocol document is quite clear on this point, the two
requests will always draw different bits.  The R3 version of the
Xlib manual quotes from the protocol document, having no copy of
the R2 manual, I don't know what it says.

The trouble is that the PolyRectangle request draws a 5 point PolyLine.
A wide-line is defined by the rectangle centered along the specified
coordinates which is as wide as the line-width.  So, the verticle
portions of the PolyRectangle will extend 1/2 pixel to the left and
right of the given coordinates.  

Read the protocol document where it talks about filling polygons; as
wide-lines are defined in terms of polygons, the discussion applies
to them as well.

(for pixels on the boundary of the polygon) "the pixel is inside if and
only if the polygon interior is immediatly to its right (x increasing
direction)".  It goes on to clarify the case on the bottom of the polygon.

The method I used in R3 to compute bounds for span generation is:

	int_left_x = (int) ceil (double_left_x);
	int_right_x = (int) ceil (double_right_x - 1);

Applying these equations to the coordinates generated for
the filled rectangle makes the right edge move left one pixel:

ceil (x + width - 1) = x + width - 1

The outlined rectangle ends up at the same coordinates it started at:

ceil (x + width + 1/2 - 1) = x + width
                   ^
		   |
                   +-- line width / 2

This discussion also applies to the horizontal portions of the
rectangles, with similar results.

Wide lines in the R2 server used a different (and incorrect) algorithm
for calculating the span boundaries, however in this case, the
results would be the same.

						Keith Packard
						MIT X Consortium
						(617) 253-1428
						keith@EXPO.LCS.MIT.EDU

garya@stan.com (Gary Aitken) (11/18/88)

In article <3595@pt.cs.cmu.edu>, egc@h.gp.cs.cmu.edu (eddie caplan) writes:
> under X11R2 on a (black and white) microvax 2:
> 
> XDrawRectangle(display, drawable, gc, x, y, w, h) draws a rectangle defined
> by the coordinates (x,y)  (x+w,y)  (x+w,y+h)  (x,y+h)
> 
> -- 

We looked at this and rationalized the draw rectangle as drawing a rectangle
with a zero width line, centered in the middle of the actual pixels.  The
rectangle (stuff inside the 0 width line) is then of the desired size.
Don't know if that's a proper interpretation or not, though.

Gary Aitken
ncar!boulder!stan!garya