1 module x11.Xregion;
2 import core.stdc.config;
3 
4 import x11.Xlibint;
5 import x11.Xlib : XPoint;
6 
7 extern (C) nothrow:
8 
9 struct Box{
10     short x1, x2, y1, y2;
11 }
12 alias Box   BOX;
13 alias Box   BoxRec;
14 alias Box*  BoxPtr;
15 
16 struct RECTANGLE{
17     short x, y, width, height;
18 }
19 alias RECTANGLE     RectangleRec;
20 alias RECTANGLE*    RectanglePtr;
21 
22 const int TRUE      = 1;
23 const int FALSE     = 0;
24 const int MAXSHORT  = 32767;
25 const int MINSHORT  = -MAXSHORT;
26 
27 int MAX(int a, int b) { return (a < b) ? b : a; }
28 int MIN(int a, int b) { return (a > b) ? b : a; }
29 
30 
31 /*
32  *   clip region
33  */
34 
35 struct _XRegion {
36     c_long size;
37     c_long numRects;
38     BOX* rects;
39     BOX  extents;
40 }
41 alias _XRegion REGION;
42 
43 /* Xutil.d contains the declaration:
44  * typedef struct _XRegion *Region;
45  */
46 
47 /*  1 if two BOXs overlap.
48  *  0 if two BOXs do not overlap.
49  *  Remember, x2 and y2 are not in the region
50  */
51 bool EXTENTCHECK(Box* r1, Box* r2){
52     return  ( r1.x2 > r2.x1 )
53         &&  ( r1.x1 < r2.x2 )
54         &&  ( r1.y2 > r2.y1 )
55         &&  ( r1.y1 < r2.y2 );
56  }
57 
58 /*
59  *  update region extents
60  */
61 void EXTENTS( Box* r, REGION* idRect ){
62     if(r.x1 < idRect.extents.x1)
63         idRect.extents.x1 = r.x1;
64     if(r.y1 < idRect.extents.y1)
65         idRect.extents.y1 = r.y1;
66     if(r.x2 > idRect.extents.x2)
67         idRect.extents.x2 = r.x2;
68     if(r.y2 > idRect.extents.y2)
69         idRect.extents.y2 = r.y2;
70 }
71 
72 /*
73  *   Check to see if there is enough memory in the present region.
74  */
75 bool MEMCHECK(REGION* reg, Box* rect, Box* firstrect){
76     bool result = false;
77     if (reg.numRects >= (reg.size - 1)){
78         firstrect = cast(BOX*) Xrealloc( cast(void*) firstrect, cast(uint)(2 * BOX.sizeof * reg.size ) );
79         if (firstrect is null)
80             result = false;
81         else{
82             reg.size *= 2;
83             rect = &firstrect[reg.numRects];
84             result = true;
85         }
86     }
87     return result;
88 }
89 
90 /*  this routine checks to see if the previous rectangle is the same
91  *  or subsumes the new rectangle to add.
92  */
93 bool CHECK_PREVIOUS(REGION* Reg, Box* R, short Rx1, short Ry1, short Rx2, short Ry2){
94     return !( (Reg.numRects > 0) && ((R-1).y1 == Ry1) && ((R-1).y2 == Ry2) && ((R-1).x1 <= Rx1) && ((R-1).x2 >= Rx2) );
95 }
96 
97 /*  add a rectangle to the given Region */
98 void ADDRECT(REGION* reg, Box* r, short rx1, short ry1, short rx2, short ry2){
99     if ( (rx1 < rx2) && (ry1 < ry2) && CHECK_PREVIOUS(reg, r, rx1, ry1, rx2, ry2) ){
100         r.x1 = rx1;
101         r.y1 = ry1;
102         r.x2 = rx2;
103         r.y2 = ry2;
104         EXTENTS( r, reg );
105         reg.numRects++;
106         r++;
107     }
108 }
109 
110 
111 
112 /*  add a rectangle to the given Region */
113 void ADDRECTNOX(REGION* reg, Box* r, short rx1, short ry1, short rx2, short ry2){
114     if ( (rx1 < rx2) && (ry1 < ry2) && CHECK_PREVIOUS(reg, r, rx1, ry1, rx2, ry2) ){
115         r.x1 = rx1;
116         r.y1 = ry1;
117         r.x2 = rx2;
118         r.y2 = ry2;
119         reg.numRects++;
120         r++;
121     }
122 }
123 
124 void EMPTY_REGION(REGION* pReg){
125     pReg.numRects = 0;
126 }
127 
128 c_long REGION_NOT_EMPTY(REGION* pReg){
129     return pReg.numRects;
130 }
131 
132 bool INBOX(Box* r, short x, short y){
133     return ( (r.x2 >  x) && (r.x1 <= x) && (r.y2 >  y) && (r.y1 <= y) );
134 }
135 
136 /*
137  * number of points to buffer before sending them off
138  * to scanlines() :  Must be an even number
139  */
140 const int NUMPTSTOBUFFER = 200;
141 
142 /*
143  * used to allocate buffers for points and link
144  * the buffers together
145  */
146 struct POINTBLOCK {
147     XPoint[NUMPTSTOBUFFER]      pts;
148     POINTBLOCK* next;
149 }