[comp.windows.x] Xlib regions

afielden@cbnewsb.cb.att.com (andrew.j.fielden) (03/28/91)

I'm writing an xview program that uses Xlib graphics primitives. I have found
a problem when trying to use Regions. What I am trying to do is detect whether
one region is contained within another region. I wrote a small program to
illustrate the problem.
I create a region with co-ordinates (5,5),(80,5),(80,80),(5,80) - call this
region b.
Now I try to determine if the following regions are contained within the above
region :-
          region a  = (10,20),(30,20),(70,70),(50,70)
          region A  = (10,20),(30,20),(70,50),(50,50)

So what I do is calculate the intersection of the regions 
(region [aA] and region b)
If region a is contained in region b, then this intersected region should be
exactly equal to region a.
Problem is, this method works for region 'a', but does not work for region 'A' !

I am a newcomer to X-Windows, so maybe I am overlooking something, but I would
appreciate any help anyone could offer.
Thanks in advance

Andrew.
==============================  CUT  =======================================

#include "/usr/openwin/include/X11/Intrinsic.h"
#include "/usr/openwin/include/X11/Xutil.h"

main()
{
  XPoint pt_a[4], pt_b[4];
  Region region_a, region_b, region_c;

/* (doesn't work) */
  pt_a[0].x = 10; pt_a[0].y = 20;
  pt_a[1].x = 30; pt_a[1].y = 20;
  pt_a[2].x = 70; pt_a[2].y = 70;
  pt_a[3].x = 50; pt_a[3].y = 70;

/* (works) */
/*
  pt_a[0].x = 10; pt_a[0].y = 20;
  pt_a[1].x = 30; pt_a[1].y = 20;
  pt_a[2].x = 70; pt_a[2].y = 50;
  pt_a[3].x = 50; pt_a[3].y = 50;
*/
  pt_b[0].x = 5; pt_b[0].y = 5;
  pt_b[1].x = 80; pt_b[1].y = 5;
  pt_b[2].x = 80; pt_b[2].y = 80;
  pt_b[3].x = 5; pt_b[3].y = 80;

  region_a = XPolygonRegion(pt_a, 4, EvenOddRule);
  region_b = XPolygonRegion(pt_b, 4, EvenOddRule);
  region_c = XCreateRegion();

  XIntersectRegion(region_b, region_a, region_c);
  if (XEqualRegion(region_a, region_c))
    printf("region a is in region b\n");
  else
    printf("region a is NOT in region b\n");
}
-- 
Andrew Fielden. AT&T Network Systems UK.
afielden@hvmpa.att.com

mouse@lightning.mcrcim.mcgill.EDU (der Mouse) (04/02/91)

> I'm writing an xview program that uses Xlib graphics primitives.  I
> have found a problem when trying to use Regions.  What I am trying to
> do is detect whether one region is contained within another region.
> I wrote a small program to illustrate the problem.

[example]

To test whether region A is inside region B, you intersect A and B and
check whether the result is equal to A.

This will work but is likely to be inefficient.  I would recommend
using XSubtractRegion to subtract B from A, then checking the result to
see whether it's empty.  (This should also keep you from being bothered
by the bug you found.)

>           region a  = (10,20),(30,20),(70,70),(50,70)
>           region A  = (10,20),(30,20),(70,50),(50,50)

> If region a is contained in region b, then this intersected region
> should be exactly equal to region a.  Problem is, this method works
> for region 'a', but does not work for region 'A' !

Your test program (once I changed the #include directives) exhibited
the behavior you describe here as well.  Dumping the internal
representations of the regions involved makes it clear what's going on:

	A
		size 50
		numRects 50
		extents X: 10 70  Y: 20 70
		rects:
			10 30 X 20 21
			11 31 X 21 22
			12 32 X 22 23
			13 33 X 23 24
NOTE>			14 34 X 24 25
NOTE>			14 34 X 25 26
			15 35 X 26 27
			16 36 X 27 28
			17 37 X 28 29
NOTE>			18 38 X 29 30
NOTE>			18 38 X 30 31
			19 39 X 31 32
			20 40 X 32 33
[many lines deleted]
	B
		size 1
		numRects 1
		extents X: 5 80  Y: 5 80
		rects:
			5 80 X 5 80
	C
		size 41
		numRects 41
		extents X: 10 70  Y: 20 70
		rects:
			10 30 X 20 21
			11 31 X 21 22
			12 32 X 22 23
			13 33 X 23 24
NOTE>			14 34 X 24 26
			15 35 X 26 27
			16 36 X 27 28
			17 37 X 28 29
NOTE>			18 38 X 29 31
			19 39 X 31 32
			20 40 X 32 33
[more lines deleted]

So it is clear that the problem is a bug in the Region implementation.
Either XPolygonRegion should merge those mergeable rectangles or
XEqualRegion should take care to do the comparison properly.
(Personally, I prefer the first fix, but the second is probably easier
to implement.)

I'll send a bug report to xbugs, since this bug appears in R4.

					der Mouse

			old: mcgill-vision!mouse
			new: mouse@larry.mcrcim.mcgill.edu