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