5 static void rprint(Rlist*);
8 growrlist(Rlist *rlist, int n)
12 if(rlist->nrect+n <= rlist->maxrect)
16 while(rlist->nrect+n > rlist->maxrect){
17 if(rlist->maxrect == 0)
23 tot += rlist->maxrect - old;
25 sysfatal("too many rectangles");
27 rlist->rect = realloc(rlist->rect, rlist->maxrect*sizeof(rlist->rect[0]));
28 if(rlist->rect == nil)
29 sysfatal("realloc failed in growrlist");
33 rappend(Rlist *rl, Rectangle r)
36 rl->rect[rl->nrect++] = r;
39 /* remove rectangle i from the list */
41 rtrim(Rlist *r, int i)
43 if(i < 0 || i >= r->nrect)
49 r->rect[i] = r->rect[--r->nrect];
54 rectadjacent(Rectangle r, Rectangle s)
56 return r.min.x<=s.max.x && s.min.x<=r.max.x &&
57 r.min.y<=s.max.y && s.min.y<=r.max.y;
61 * If s shares three edges with r, compute the
62 * rectangle r - s and return 1.
66 rectubr(Rectangle *r, Rectangle s)
68 if(r->min.y==s.min.y && r->max.y==s.max.y){
69 if(r->min.x == s.min.x){
71 assert(r->max.x > r->min.x);
74 if(r->max.x == s.max.x){
76 assert(r->max.x > r->min.x);
80 if(r->min.x==s.min.x && r->max.x==s.max.x){
81 if(r->min.y == s.min.y){
83 assert(r->max.y > r->min.y);
86 if(r->max.y == s.max.y){
88 assert(r->max.y > r->min.y);
96 * If s is a corner of r, remove s from r, yielding
97 * two rectangles r and rr. R holds the part with
98 * smaller coordinates.
101 rectcornersubr(Rectangle *r, Rectangle s, Rectangle *rr)
103 # define UPRIGHT(r) Pt((r).max.x, (r).min.y)
104 # define LOWLEFT(r) Pt((r).min.x, (r).max.y)
108 if(s.min.x == r->min.x){
109 if(s.min.y == r->min.y){ // upper left
110 *rr = Rpt(UPRIGHT(s), r->max);
111 *r = Rpt(LOWLEFT(s), LOWLEFT(*rr));
114 if(s.max.y == r->max.y){ // lower left
115 *rr = Rpt(Pt(s.max.x, r->min.y), r->max);
116 *r = Rpt(r->min, UPRIGHT(s));
120 if(s.max.x == r->max.x){
121 if(s.max.y == r->max.y){ // lower right
122 *rr = Rpt(Pt(s.min.x, r->min.y), UPRIGHT(s));
123 *r = Rpt(r->min, LOWLEFT(s));
126 if(s.min.y == r->min.y){ // upper right
127 *rr = Rpt(LOWLEFT(s), r->max);
128 *r = Rpt(r->min, LOWLEFT(*rr));
136 * If s is a band cutting r into two pieces, set r to one piece
137 * and rr to the other.
140 recttridesubr(Rectangle *nr, Rectangle s, Rectangle *rr)
143 if((nr->min.x == s.min.x && nr->max.x == s.max.x) &&
144 (nr->min.y < s.min.y && s.max.y < nr->max.y)){
150 if((nr->min.y == s.min.y && nr->max.y == s.max.y) &&
151 (nr->min.x < s.min.x && s.max.x < nr->max.x)){
160 addtorlist(Rlist *rlist, Rectangle r)
163 Rectangle ir, cr, rr;
166 if(r.min.x >= r.max.x || r.min.y >= r.max.y)
169 memset(&tmp, 0, sizeof tmp);
173 fprint(2, "region union add %R:\n", r);
175 combinerect(&rlist->bbox, r); // must do this first
176 for(j = 0; j < tmp.nrect; j++){
179 for(i=0; i < rlist->nrect; i++){
183 fprint(2, "checking %R against %R\n", r, ir);
184 if(!rectadjacent(ir, r))
187 /* r is covered by ir? */
188 if(rectinrect(r, ir))
192 if(rectinrect(ir, r)){
198 /* aligned and overlapping? */
199 if((ir.min.y == r.min.y && ir.max.y == r.max.y) ||
200 (ir.min.x == r.min.x && ir.max.x == r.max.x)){
209 fprint(2, "break up rect %R and %R\n", ir, r);
212 if (!rectclip(&cr, r)) /* share only one point */
218 if(rectubr(&rlist->rect[i], cr))
223 if(recttridesubr(&r, cr, &rr)){
229 if(rectcornersubr(&r, cr, &rr)){
235 if(i == rlist->nrect)
258 fprint(2, "rlist %p:", r);
259 for(i=0; i<r->nrect; i++)
260 fprint(2, " %R", r->rect[i]);
269 void main(int argc, char * argv[])
271 Rectangle r1 = Rect(0, 0, 300, 200);
272 Rectangle r2 = Rect(100, 100, 400, 300);
273 Rectangle r3 = Rect(200, 100, 500, 300);
276 if(initdraw(0, 0, "vncviewer") < 0){
277 fprint(2, "%s: initdraw failed: %r\n", argv[0]);
281 region_union(®, r1, r1);
282 region_union(®, r2, r2);
283 region_union(®, r3, r3);