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 }