xref: /inferno-os/libinterp/geom.c (revision d0e1d143ef6f03c75c008c7ec648859dd260cbab)
1 #include "lib9.h"
2 #include "interp.h"
3 #include "isa.h"
4 #include "draw.h"
5 #include "runt.h"
6 #include "raise.h"
7 
8 void
9 Point_add(void *fp)
10 {
11 	F_Point_add *f;
12 	Draw_Point *ret;
13 
14 	f = fp;
15 
16 	ret = f->ret;
17 	ret->x = f->p.x + f->q.x;
18 	ret->y = f->p.y + f->q.y;
19 }
20 
21 void
22 Point_sub(void *fp)
23 {
24 	F_Point_sub *f;
25 	Draw_Point *ret;
26 
27 	f = fp;
28 
29 	ret = f->ret;
30 	ret->x = f->p.x - f->q.x;
31 	ret->y = f->p.y - f->q.y;
32 }
33 
34 void
35 Point_mul(void *fp)
36 {
37 	F_Point_mul *f;
38 	Draw_Point *ret;
39 
40 	f = fp;
41 
42 	ret = f->ret;
43 	ret->x = f->p.x * f->i;
44 	ret->y = f->p.y * f->i;
45 }
46 
47 void
48 Point_div(void *fp)
49 {
50 	F_Point_div *f;
51 	Draw_Point *ret;
52 
53 	f = fp;
54 
55 	if(f->i == 0)
56 		error(exZdiv);
57 	ret = f->ret;
58 	ret->x = f->p.x / f->i;
59 	ret->y = f->p.y / f->i;
60 }
61 
62 void
63 Point_eq(void *fp)
64 {
65 	F_Point_eq *f;
66 
67 	f = fp;
68 	*f->ret = f->p.x == f->q.x && f->p.y == f->q.y;
69 }
70 
71 void
72 Point_in(void *fp)
73 {
74 	F_Point_in *f;
75 
76 	f = fp;
77 	*f->ret = f->p.x >= f->r.min.x && f->p.x < f->r.max.x &&
78 	       f->p.y >= f->r.min.y && f->p.y < f->r.max.y;
79 }
80 
81 void
82 Rect_canon(void *fp)
83 {
84 	F_Rect_canon *f;
85 	Draw_Rect *ret;
86 	WORD t;
87 
88 	f = fp;
89 
90 	ret = f->ret;
91 	if(f->r.max.x < f->r.min.x){
92 		t = f->r.max.x;
93 		ret->max.x = f->r.min.x;
94 		ret->min.x = t;
95 	}else{
96 		t = f->r.max.x;
97 		ret->min.x = f->r.min.x;
98 		ret->max.x = t;
99 	}
100 	if(f->r.max.y < f->r.min.y){
101 		t = f->r.max.y;
102 		ret->max.y = f->r.min.y;
103 		ret->min.y = t;
104 	}else{
105 		t = f->r.max.y;
106 		ret->min.y = f->r.min.y;
107 		ret->max.y = t;
108 	}
109 }
110 
111 void
112 Rect_combine(void *fp)
113 {
114 	F_Rect_combine *f;
115 	Draw_Rect *ret;
116 
117 	f = fp;
118 	ret = f->ret;
119 	*ret = f->r;
120 	if(f->r.min.x > f->s.min.x)
121 		ret->min.x = f->s.min.x;
122 	if(f->r.min.y > f->s.min.y)
123 		ret->min.y = f->s.min.y;
124 	if(f->r.max.x < f->s.max.x)
125 		ret->max.x = f->s.max.x;
126 	if(f->r.max.y < f->s.max.y)
127 		ret->max.y = f->s.max.y;
128 }
129 
130 void
131 Rect_eq(void *fp)
132 {
133 	F_Rect_eq *f;
134 
135 	f = fp;
136 
137 	*f->ret = f->r.min.x == f->s.min.x
138 		&& f->r.max.x == f->s.max.x
139 		&& f->r.min.y == f->s.min.y
140 		&& f->r.max.y == f->s.max.y;
141 }
142 
143 void
144 Rect_Xrect(void *fp)
145 {
146 	F_Rect_Xrect *f;
147 
148 	f = fp;
149 
150 	*f->ret = f->r.min.x < f->s.max.x
151 		&& f->s.min.x < f->r.max.x
152 		&& f->r.min.y < f->s.max.y
153 		&& f->s.min.y < f->r.max.y;
154 }
155 
156 void
157 Rect_clip(void *fp)
158 {
159 	F_Rect_clip *f;
160 	Draw_Rect *r, *s, *ret;
161 
162 	f = fp;
163 
164 	r = &f->r;
165 	s = &f->s;
166 	ret = &f->ret->t0;
167 
168 	/*
169 	 * Expand rectXrect() in line for speed
170 	 */
171 	if(!(r->min.x<s->max.x && s->min.x<r->max.x
172 	&& r->min.y<s->max.y && s->min.y<r->max.y)){
173 		*ret = *r;
174 		f->ret->t1 = 0;
175 		return;
176 	}
177 
178 	/* They must overlap */
179 	if(r->min.x < s->min.x)
180 		ret->min.x = s->min.x;
181 	else
182 		ret->min.x = r->min.x;
183 	if(r->min.y < s->min.y)
184 		ret->min.y = s->min.y;
185 	else
186 		ret->min.y = r->min.y;
187 	if(r->max.x > s->max.x)
188 		ret->max.x = s->max.x;
189 	else
190 		ret->max.x = r->max.x;
191 	if(r->max.y > s->max.y)
192 		ret->max.y = s->max.y;
193 	else
194 		ret->max.y = r->max.y;
195 	f->ret->t1 = 1;
196 }
197 
198 void
199 Rect_inrect(void *fp)
200 {
201 	F_Rect_inrect *f;
202 
203 	f = fp;
204 
205 	*f->ret = f->s.min.x <= f->r.min.x
206 		&& f->r.max.x <= f->s.max.x
207 		&& f->s.min.y <= f->r.min.y
208 		&& f->r.max.y <= f->s.max.y;
209 }
210 
211 void
212 Rect_contains(void *fp)
213 {
214 	F_Rect_contains *f;
215 	WORD x, y;
216 
217 	f = fp;
218 
219 	x = f->p.x;
220 	y = f->p.y;
221 	*f->ret = x >= f->r.min.x && x < f->r.max.x
222 		&& y >= f->r.min.y && y < f->r.max.y;
223 }
224 
225 void
226 Rect_addpt(void *fp)
227 {
228 	F_Rect_addpt *f;
229 	Draw_Rect *ret;
230 	WORD n;
231 
232 	f = fp;
233 
234 	ret = f->ret;
235 	n = f->p.x;
236 	ret->min.x = f->r.min.x + n;
237 	ret->max.x = f->r.max.x + n;
238 	n = f->p.y;
239 	ret->min.y = f->r.min.y + n;
240 	ret->max.y = f->r.max.y + n;
241 }
242 
243 void
244 Rect_subpt(void *fp)
245 {
246 	WORD n;
247 	F_Rect_subpt *f;
248 	Draw_Rect *ret;
249 
250 	f = fp;
251 
252 	ret = f->ret;
253 	n = f->p.x;
254 	ret->min.x = f->r.min.x - n;
255 	ret->max.x = f->r.max.x - n;
256 	n = f->p.y;
257 	ret->min.y = f->r.min.y - n;
258 	ret->max.y = f->r.max.y - n;
259 }
260 
261 void
262 Rect_inset(void *fp)
263 {
264 	WORD n;
265 	Draw_Rect *ret;
266 	F_Rect_inset *f;
267 
268 	f = fp;
269 
270 	ret = f->ret;
271 	n = f->n;
272 	ret->min.x = f->r.min.x + n;
273 	ret->min.y = f->r.min.y + n;
274 	ret->max.x = f->r.max.x - n;
275 	ret->max.y = f->r.max.y - n;
276 }
277 
278 void
279 Rect_dx(void *fp)
280 {
281 	F_Rect_dx *f;
282 
283 	f = fp;
284 
285 	*f->ret = f->r.max.x-f->r.min.x;
286 }
287 
288 void
289 Rect_dy(void *fp)
290 {
291 	F_Rect_dy *f;
292 
293 	f = fp;
294 
295 	*f->ret = f->r.max.y-f->r.min.y;
296 }
297 
298 void
299 Rect_size(void *fp)
300 {
301 	F_Rect_size *f;
302 	Draw_Point *ret;
303 
304 	f = fp;
305 
306 	ret = f->ret;
307 	ret->x = f->r.max.x-f->r.min.x;
308 	ret->y = f->r.max.y-f->r.min.y;
309 }
310