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