1 /*
2  * $Id: ir.c,v 1.5 2000/08/10 21:02:50 danny Exp $
3  *
4  * Copyright � 1992, 1993 Free Software Foundation, Inc.
5  *
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 2, or (at your option)
9  * any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this software; see the file COPYING.  If not, write to
18  * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
19  */
20 #ifdef HAVE_CONFIG_H
21 #include "config.h"
22 #endif
23 
24 #ifdef	WITH_DMALLOC
25 #include <dmalloc.h>
26 #endif
27 
28 #include "ir.h"
29 
30 int
xx_IRencloses(xx_IntRectangle r1,xx_IntRectangle r2)31 xx_IRencloses (xx_IntRectangle r1, xx_IntRectangle r2)
32 {
33   return (xx_IRhits_point (r1, xx_IRllx (r2), xx_IRlly (r2))
34 	  && (!xx_IRw (r2) || !xx_IRh (r2)
35 	      || (xx_IRhits_point (r1, xx_IRurx (r2), xx_IRlly (r2))
36 		  && xx_IRhits_point (r1, xx_IRllx (r2), xx_IRury (r2))
37 		  && xx_IRhits_point (r1, xx_IRurx (r2), xx_IRury (r2)))));
38 }
39 
40 int
xx_IRencloses_width(xx_IntRectangle r1,xx_IntRectangle r2)41 xx_IRencloses_width (xx_IntRectangle r1, xx_IntRectangle r2)
42 {
43   return (xx_IRhits_point (r1, xx_IRllx (r2), xx_IRlly (r1))
44 	  && (!xx_IRw (r2)
45 	      || (xx_IRhits_point (r1, xx_IRurx (r2), xx_IRlly (r1)))));
46 }
47 
48 
49 int
xx_IRequiv(xx_IntRectangle r1,xx_IntRectangle r2)50 xx_IRequiv (xx_IntRectangle r1, xx_IntRectangle r2)
51 {
52   return (xx_IRllx (r2) == xx_IRllx (r1) &&
53 	  xx_IRlly (r2) == xx_IRlly (r1) &&
54 	  xx_IRurx (r2) == xx_IRurx (r1) &&
55 	  xx_IRury (r2) == xx_IRury (r1));
56 }
57 
58 
59 #define MAX(A,B)	((A) > (B) ? (A) : (B))
60 #define MIN(A,B)	((A) < (B) ? (A) : (B))
61 #define ROUND(F) 	(int)((F) + 0.5)
62 
63 void
xx_IRbound(xx_IntRectangle r1,xx_IntRectangle r2)64 xx_IRbound (xx_IntRectangle r1, xx_IntRectangle r2)
65 {
66   int x, y;
67   int X, Y;
68 
69   x = MIN (xx_IRllx (r1), xx_IRllx (r2));
70   y = MIN (xx_IRlly (r1), xx_IRlly (r2));
71   X = MAX (xx_IRurx (r1), xx_IRurx (r2));
72   Y = MAX (xx_IRury (r1), xx_IRury (r2));
73 
74   r1->x = x;
75   r1->y = y;
76   r1->w = X - x + 1;
77   r1->h = Y - y + 1;
78 }
79 
80 
81 int
xx_IRarea(xx_IntRectangle r)82 xx_IRarea (xx_IntRectangle r)
83 {
84   return r->w * r->h;
85 }
86 
87 
88 int
xx_IRhits_point(xx_IntRectangle rect,int x,int y)89 xx_IRhits_point (xx_IntRectangle rect, int x, int y)
90 {
91   return (x >= rect->x
92 	  && y >= rect->y
93 	  && x < rect->x + rect->w
94 	  && y < rect->y + rect->h);
95 }
96 
97 
98 void
xx_IRclip(xx_IntRectangle r1,xx_IntRectangle r2)99 xx_IRclip (xx_IntRectangle r1, xx_IntRectangle r2)
100 {
101   int x = MAX (r1->x, r2->x);
102   int y = MAX (r1->y, r2->y);
103   int X = MIN (xx_IRurx (r1), xx_IRurx (r2));
104   int Y = MIN (xx_IRury (r1), xx_IRury (r2));
105   int t;
106   r1->x = x;
107   r1->y = y;
108   t = X - x + 1;
109   if (t < 0)
110     r1->w = 0;
111   else
112     r1->w = t;
113   t = Y - y + 1;
114   if (t < 0)
115     r1->h = 0;
116   else
117     r1->h = t;
118 }
119 
120 
121 
122 
123 int
xx_IRsubtract(xx_IntRectangle outv,xx_IntRectangle a,xx_IntRectangle b)124 xx_IRsubtract (xx_IntRectangle outv, xx_IntRectangle a, xx_IntRectangle b)
125 {
126   struct xx_sIntRectangle arect;
127   struct xx_sIntRectangle brect;
128   int outp = 0;
129 
130   if (!(a->w && a->h))
131     return 0;
132   if (!(b->w && b->h))
133     {
134       *outv = *a;
135       return 1;
136     }
137 
138   arect = *a;
139   brect = *b;
140 
141   xx_IRclip (&brect, &arect);
142 
143   if (xx_IRhits_point (&arect,
144 		       xx_IRllx (&brect),
145 		       xx_IRlly (&brect)))
146     {
147       /*
148 
149 	 -----------------.
150 	|        |//////brect
151 	|        |////////|
152         |        |---------
153 	|   I    |  II    |
154 	| 	 |        |
155          -----------------  arect
156 	*/
157 
158       /* I  */
159       outv[outp] = arect;
160       outv[outp].w = xx_IRllx (&brect) - xx_IRllx (&arect);
161 
162       if (outv[outp].w)
163 	++outp;
164 
165       /* II */
166       outv[outp] = arect;
167       outv[outp].x = xx_IRllx (&brect);
168       outv[outp].w = xx_IRurx (&arect) - xx_IRllx (&brect) + 1;
169       outv[outp].h = xx_IRlly (&brect) - xx_IRlly (&arect);
170 
171       if (outv[outp].h)
172 	++outp;
173 
174       arect.w = xx_IRurx (&arect) - xx_IRllx (&brect) + 1;
175       arect.h = xx_IRury (&arect) - xx_IRlly (&brect) + 1;
176       arect.x = xx_IRllx (&brect);
177       arect.y = xx_IRlly (&brect);
178     }
179 
180   if (xx_IRhits_point (&arect,
181 		       xx_IRurx (&brect),
182 		       xx_IRury (&brect)))
183     {
184       /*
185 	          --------------
186                  |           I  | arect
187                  |--------------|
188                  |////////|     |
189                  |////////|  II |
190                   --------------
191              brect
192 
193 
194 	*/
195 
196       /* I */
197       outv[outp] = arect;
198       outv[outp].h = xx_IRury (&arect) - xx_IRury (&brect);
199       outv[outp].y = xx_IRury (&brect) + 1;
200       if (outv[outp].h)
201 	++outp;
202 
203       /* II */
204       outv[outp] = arect;
205       outv[outp].h = xx_IRury (&brect) - xx_IRlly (&arect) + 1;
206       outv[outp].w = xx_IRurx (&arect) - xx_IRurx (&brect);
207       outv[outp].x = xx_IRurx (&brect) + 1;
208 
209       if (outv[outp].w)
210 	++outp;
211     }
212   return outp;
213 }
214