1 /*  Part of XPCE --- The SWI-Prolog GUI toolkit
2 
3     Author:        Jan Wielemaker and Anjo Anjewierden
4     E-mail:        jan@swi.psy.uva.nl
5     WWW:           http://www.swi.psy.uva.nl/projects/xpce/
6     Copyright (c)  1985-2002, University of Amsterdam
7     All rights reserved.
8 
9     Redistribution and use in source and binary forms, with or without
10     modification, are permitted provided that the following conditions
11     are met:
12 
13     1. Redistributions of source code must retain the above copyright
14        notice, this list of conditions and the following disclaimer.
15 
16     2. Redistributions in binary form must reproduce the above copyright
17        notice, this list of conditions and the following disclaimer in
18        the documentation and/or other materials provided with the
19        distribution.
20 
21     THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22     "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23     LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
24     FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
25     COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
26     INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
27     BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
28     LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
29     CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
30     LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
31     ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
32     POSSIBILITY OF SUCH DAMAGE.
33 */
34 
35 #include <h/kernel.h>
36 
37 /* FN will include the following names from this comment.  Donot remove
38    it!
39 
40 NAME_northWest
41 NAME_southWest
42 NAME_northEast
43 NAME_southEast
44 */
45 
46 #define InitAreaA	int ax = valInt(a->x), ay = valInt(a->y),	\
47 			    aw = valInt(a->w), ah = valInt(a->h)
48 
49 #define InitAreaB	int bx = valInt(b->x), by = valInt(b->y),	\
50 			    bw = valInt(b->w), bh = valInt(b->h)
51 
52 #define ExitAreaA	assign(a, x, toInt(ax));			\
53 		        assign(a, y, toInt(ay));			\
54 		        assign(a, w, toInt(aw));			\
55 		        assign(a, h, toInt(ah));
56 
57 static status normaliseArea(Area a);
58 static status inArea(Area a, Int x, Int y);
59 
60 static status
initialiseArea(Area a,Int x,Int y,Int w,Int h)61 initialiseArea(Area a, Int x, Int y, Int w, Int h)
62 { assign(a, x, isDefault(x) ? ZERO : x);
63   assign(a, y, isDefault(y) ? ZERO : y);
64   assign(a, w, isDefault(w) ? ZERO : w);
65   assign(a, h, isDefault(h) ? ZERO : h);
66 
67   succeed;
68 }
69 
70 
71 static status
equalArea(Area a,Area b)72 equalArea(Area a, Area b)
73 { InitAreaA;
74   InitAreaB;
75 
76   NormaliseArea(ax, ay, aw, ah);
77   NormaliseArea(bx, by, bw, bh);
78 
79   if (ax == bx && ay == by && aw == bw && ah == bh)
80     succeed;
81   fail;
82 }
83 
84 
85 status
intersectionArea(Area a,Area b)86 intersectionArea(Area a, Area b)
87 { int x, y, w, h;
88   Name orientation;
89 
90   InitAreaA;
91   InitAreaB;
92 
93   orientation = OrientationArea(aw, ah);
94 
95   NormaliseArea(ax, ay, aw, ah);
96   NormaliseArea(bx, by, bw, bh);
97 
98   x = (ax > bx ? ax : bx);
99   y = (ay > by ? ay : by);
100   w = (ax + aw < bx + bw ? ax + aw : bx + bw) - x;
101   h = (ay + ah < by + bh ? ay + ah : by + bh) - y;
102 
103   if (w < 0 || h < 0)
104     fail;
105 
106   OrientateArea(x, y, w, h, orientation);
107 
108   assign(a, x, toInt(x));
109   assign(a, y, toInt(y));
110   assign(a, w, toInt(w));
111   assign(a, h, toInt(h));
112 
113   succeed;
114 }
115 
116 
117 static Area
getIntersectionArea(Area a,Area b)118 getIntersectionArea(Area a, Area b)
119 { Area c;
120 
121   c = answerObject(ClassArea, a->x, a->y, a->w, a->h, EAV);
122   if ( intersectionArea(c, b) )
123     answer(c);
124 
125   freeObject(c);
126   fail;
127 }
128 
129 
130 static status
unionArea(Area a,Area b)131 unionArea(Area a, Area b)
132 { int x, y, w, h;
133   Name orientation;
134 
135   if ( b->w == ZERO && b->h == ZERO )
136     succeed;
137   if ( a->w == ZERO && a->h == ZERO )
138   { copyArea(a, b);
139     return normaliseArea(a);
140   }
141 
142   { InitAreaA;
143     InitAreaB;
144 
145     orientation = OrientationArea(aw, ah);
146 
147     NormaliseArea(ax, ay, aw, ah);
148     NormaliseArea(bx, by, bw, bh);
149 
150     x = (ax < bx ? ax : bx);
151     y = (ay < by ? ay : by);
152     w = (ax + aw > bx + bw ? ax + aw : bx + bw) - x;
153     h = (ay + ah > by + bh ? ay + ah : by + bh) - y;
154 
155     OrientateArea(x, y, w, h, orientation);
156 
157     assign(a, x, toInt(x));
158     assign(a, y, toInt(y));
159     assign(a, w, toInt(w));
160     assign(a, h, toInt(h));
161   }
162 
163   succeed;
164 }
165 
166 
167 status
unionNormalisedArea(Area a,Area b)168 unionNormalisedArea(Area a, Area b)
169 { int x, y, w, h;
170 
171   if ( b->w == ZERO && b->h == ZERO )
172     succeed;
173   if ( a->w == ZERO && a->h == ZERO )
174   { copyArea(a, b);
175     return normaliseArea(a);
176   }
177 
178   { InitAreaA;
179     InitAreaB;
180 
181     NormaliseArea(bx, by, bw, bh);
182 
183     x = (ax < bx ? ax : bx);
184     y = (ay < by ? ay : by);
185     w = (ax + aw > bx + bw ? ax + aw : bx + bw) - x;
186     h = (ay + ah > by + bh ? ay + ah : by + bh) - y;
187 
188     assign(a, x, toInt(x));
189     assign(a, y, toInt(y));
190     assign(a, w, toInt(w));
191     assign(a, h, toInt(h));
192   }
193 
194   succeed;
195 }
196 
197 
198 static Area
getUnionArea(Area a,Area b)199 getUnionArea(Area a, Area b)
200 { Area c;
201 
202   c = answerObject(ClassArea, a->x, a->y, a->w, a->h, EAV);
203   unionArea(c, b);
204   answer(c);
205 }
206 
207 
208 status
sizeArea(Area a,Size s)209 sizeArea(Area a, Size s)
210 { assign(a, w, s->w);
211   assign(a, h, s->h);
212 
213   succeed;
214 }
215 
216 
217 Size
getSizeArea(Area a)218 getSizeArea(Area a)
219 { answer(answerObject(ClassSize, a->w, a->h, EAV));
220 }
221 
222 
223 static Int
getMeasureArea(Area a)224 getMeasureArea(Area a)
225 { int w = valInt(a->w);
226   int h = valInt(a->h);
227 
228   answer(toInt(abs(w) * abs(h)));
229 }
230 
231 
232 status
pointInArea(Area a,Point p)233 pointInArea(Area a, Point p)
234 { return inArea(a, p->x, p->y);
235 }
236 
237 
238 status
overlapArea(Area a,Area b)239 overlapArea(Area a, Area b)
240 { InitAreaA;
241   InitAreaB;
242 
243   NormaliseArea(ax, ay, aw, ah);
244   NormaliseArea(bx, by, bw, bh);
245 
246   if (by >= ay+ah || by+bh <= ay || bx >= ax+aw || bx+bw <= ax)
247     fail;
248   succeed;
249 }
250 
251 
252 status
relativeMoveArea(Area a,Point p)253 relativeMoveArea(Area a, Point p)
254 { assign(a,x, add(a->x, p->x));
255   assign(a,y, add(a->y, p->y));
256 
257   succeed;
258 }
259 
260 
261 status
relativeMoveBackArea(Area a,Point p)262 relativeMoveBackArea(Area a, Point p)
263 { assign(a,x, sub(a->x, p->x));
264   assign(a,y, sub(a->y, p->y));
265 
266   succeed;
267 }
268 
269 
270 static status
positionArea(Area a,Point p)271 positionArea(Area a, Point p)
272 { assign(a, x, p->x);
273   assign(a, y, p->y);
274 
275   succeed;
276 }
277 
278 
279 Point
getPositionArea(Area a)280 getPositionArea(Area a)
281 { answer(answerObject(ClassPoint, a->x, a->y, EAV));
282 }
283 
284 
285 static status
inArea(Area a,Int x,Int y)286 inArea(Area a, Int x, Int y)
287 { InitAreaA;
288 
289   NormaliseArea(ax, ay, aw, ah);
290 
291   if (valInt(x) >= ax && valInt(x) <= ax+aw
292    && valInt(y) >= ay && valInt(y) <= ay+ah)
293     succeed;
294   fail;
295 }
296 
297 
298 status
copyArea(Area a,Area b)299 copyArea(Area a, Area b)
300 { assign(a, x, b->x);
301   assign(a, y, b->y);
302   assign(a, w, b->w);
303   assign(a, h, b->h);
304 
305   succeed;
306 }
307 
308 
309 Area
getCopyArea(Area a)310 getCopyArea(Area a)
311 { answer(answerObject(classOfObject(a), a->x, a->y, a->w, a->h, EAV));
312 }
313 
314 
315 status
insideArea(Area a,Area b)316 insideArea(Area a, Area b)
317 { InitAreaA;
318   InitAreaB;
319 
320   NormaliseArea(ax, ay, aw, ah);
321   NormaliseArea(bx, by, bw, bh);
322 
323   if (bx < ax)		fail;
324   if (bx+bw > ax+aw-1)	fail;
325   if (by < ay)		fail;
326   if (by+bh > ay+ah-1)	fail;
327 
328   succeed;
329 }
330 
331 
332 Int
getDistanceXArea(Area a,Area b)333 getDistanceXArea(Area a, Area b)
334 { int ax = valInt(a->x), aw = valInt(a->w);
335   int bx = valInt(b->x), bw = valInt(b->w);
336 
337   if ( aw < 0 ) ax += aw, aw = -aw;
338   if ( bw < 0 ) bx += bw, bw = -bw;
339 
340   if ( ax + aw < bx ) answer(toInt(bx-(ax+aw)));
341   if ( bx + bw < ax ) answer(toInt(ax-(bx+bw)));
342 
343   answer(ZERO);
344 }
345 
346 
347 Int
getDistanceYArea(Area a,Area b)348 getDistanceYArea(Area a, Area b)
349 { int ay = valInt(a->y), ah = valInt(a->h);
350   int by = valInt(b->y), bh = valInt(b->h);
351 
352   if ( ah < 0 ) ay += ah, ah = -ah;
353   if ( bh < 0 ) by += bh, bh = -bh;
354 
355   if ( ay + ah < by ) answer(toInt(by-(ay+ah)));
356   if ( by + bh < ay ) answer(toInt(ay-(by+bh)));
357 
358   answer(ZERO);
359 }
360 
361 
362 Int
getDistanceArea(Area a,Area b)363 getDistanceArea(Area a, Area b)
364 { InitAreaA;
365   InitAreaB;
366 
367   NormaliseArea(ax, ay, aw, ah);
368   NormaliseArea(bx, by, bw, bh);
369 
370   if (overlapArea(a, b) == SUCCEED)
371     answer(ZERO);
372 
373   if (ay+ah < by)
374   { if (bx+bw < ax)
375       answer(toInt(distance(bx+bw, by, ax, ay+ah)));
376     if (bx > ax+aw)
377       answer(toInt(distance(ax+aw, ay+ah, bx, by)));
378     answer(toInt(by-(ay+ah)));
379   }
380 
381   if (by+bh < ay)
382   { if (ax+aw < bx)
383       answer(toInt(distance(ax+aw, ay, bx, by+bh)));
384     if (bx+bw < ax)
385       answer(toInt(distance(bx+bw, by+bh, ax, ay)));
386     answer(toInt(ay-(by+bh)));
387   }
388 
389   if (ax+aw < bx)
390     answer(toInt(bx-(ax+aw)));
391 
392   answer(toInt(ax-(bx+bw)));
393 }
394 
395 
396 status
clearArea(Area a)397 clearArea(Area a)
398 { assign(a, x, ZERO);
399   assign(a, y, ZERO);
400   assign(a, w, ZERO);
401   assign(a, h, ZERO);
402 
403   succeed;
404 }
405 
406 
407 static status
centerArea(Area a,Point pos)408 centerArea(Area a, Point pos)
409 { assign(a, x, dif(pos->x,a->w));
410   assign(a, y, dif(pos->y,a->h));
411 
412   succeed;
413 }
414 
415 
416 static Int
getLeftSideArea(Area a)417 getLeftSideArea(Area a)
418 { if ( valInt(a->w) >= 0 )
419     answer(a->x);
420   else
421     answer(add(a->x, a->w));
422 }
423 
424 
425 static Int
getRightSideArea(Area a)426 getRightSideArea(Area a)
427 { if ( valInt(a->w) >= 0 )
428     answer(add(a->x, a->w));
429   else
430     answer(a->x);
431 }
432 
433 
434 static Int
getTopSideArea(Area a)435 getTopSideArea(Area a)
436 { if ( valInt(a->h) >= 0 )
437     answer(a->y);
438   else
439     answer(add(a->y, a->h));
440 }
441 
442 
443 static Int
getBottomSideArea(Area a)444 getBottomSideArea(Area a)
445 { if ( valInt(a->h) >= 0 )
446     answer(add(a->y, a->h));
447   else
448     answer(a->y);
449 }
450 
451 
452 static Point
getCenterArea(Area a)453 getCenterArea(Area a)
454 { answer(answerObject(ClassPoint, mid(a->x,a->w), mid(a->y,a->h), EAV));
455 }
456 
457 
458 static status
cornerArea(Area a,Point pos)459 cornerArea(Area a, Point pos)
460 { int w, h;
461 
462   w = valInt(pos->x) - valInt(a->x);
463   w += (w>=0 ? 1 : -1);
464   h = valInt(pos->y) - valInt(a->y);
465   h += (h>=0 ? 1 : -1);
466 
467   assign(a, w, toInt(w));
468   assign(a, h, toInt(h));
469 
470   succeed;
471 }
472 
473 
474 static Point
getCornerArea(Area a)475 getCornerArea(Area a)
476 { answer(answerObject(ClassPoint, add(a->x,a->w), add(a->y,a->h), EAV));
477 }
478 
479 
480 status
setArea(Area a,Int x,Int y,Int w,Int h)481 setArea(Area a, Int x, Int y, Int w, Int h)
482 { if (notDefault(x)) assign(a, x, x);
483   if (notDefault(y)) assign(a, y, y);
484   if (notDefault(w)) assign(a, w, w);
485   if (notDefault(h)) assign(a, h, h);
486 
487   succeed;
488 }
489 
490 
491 status
increaseArea(Area a,Int i)492 increaseArea(Area a, Int i)
493 { int d = valInt(i);
494   InitAreaA;
495 
496   if (aw >= 0)
497     aw += 2*d, ax -= d;
498   else
499     aw -= 2*d, ax += d;
500 
501   if (ah >= 0)
502     ah += 2*d, ay -= d;
503   else
504     ah -= 2*d, ay += d;
505 
506   ExitAreaA;
507 
508   succeed;
509 }
510 
511 
512 static status
decreaseArea(Area a,Int i)513 decreaseArea(Area a, Int i)
514 { return increaseArea(a, toInt(-valInt(i)));
515 }
516 
517 
518 static status
normaliseArea(Area a)519 normaliseArea(Area a)
520 { if ( valInt(a->w) < 0 || valInt(a->h) < 0 )
521   { InitAreaA;
522     NormaliseArea(ax, ay, aw, ah);
523     ExitAreaA;
524   }
525 
526   succeed;
527 }
528 
529 
530 static Area
getNormalisedArea(Area a)531 getNormalisedArea(Area a)
532 { InitAreaA;
533   NormaliseArea(ax, ay, aw, ah);
534 
535   answer(answerObject(ClassArea,
536 		      toInt(ax), toInt(ay), toInt(aw), toInt(ah), EAV));
537 }
538 
539 
540 status
orientationArea(Area a,Name orientation)541 orientationArea(Area a, Name orientation)
542 { InitAreaA;
543   OrientateArea(ax, ay, aw, ah, orientation);
544   ExitAreaA;
545 
546   succeed;
547 }
548 
549 
550 Name
getOrientationArea(Area a)551 getOrientationArea(Area a)
552 { Name orientation;
553   int aw = valInt(a->w);
554   int ah = valInt(a->h);
555 
556   orientation = OrientationArea(aw, ah);
557 
558   answer(orientation);
559 }
560 
561 
562 #undef NEAR
563 #undef SAME
564 #undef LESS
565 #define NEAR(a, b, d, m, p)	{ if (abs(a-b) <= d) m |= p; }
566 #define SAME(a, b, m, p)	{ if (a == b) m |= p; }
567 #define LESS(a, b, m, p)	{ if (a < b) m |= p; }
568 
569 static Int
getNearSidesArea(Area a,Area b,Int distance)570 getNearSidesArea(Area a, Area b, Int distance)
571 { int d=valInt(distance);
572   int a_top, a_center, a_bottom, a_left, a_middle, a_right;
573   int b_top, b_center, b_bottom, b_left, b_middle, b_right;
574   register unsigned long mask;
575 
576   InitAreaA;
577   InitAreaB;
578 
579   NormaliseArea(ax, ay, aw, ah);
580   NormaliseArea(bx, by, bw, bh);
581 
582   a_top = ay;
583   a_bottom = ay+ah-1;
584   a_center = (a_top+a_bottom+1)/2;
585 
586   a_left = ax;
587   a_right = ax+aw-1;
588   a_middle = (a_left+a_right+1)/2;
589 
590   b_top = by;
591   b_bottom = by+bh-1;
592   b_center = (b_top+b_bottom+1)/2;
593 
594   b_left = bx;
595   b_right = bx+bw-1;
596   b_middle = (b_left+b_right+1)/2;
597 
598   mask = 0;
599 
600   NEAR(a_top,    b_top,    d, mask, 01);
601   NEAR(a_top,    b_center, d, mask, 02);
602   NEAR(a_top,    b_bottom, d, mask, 04);
603   NEAR(a_center, b_top,    d, mask, 010);
604   NEAR(a_center, b_center, d, mask, 020);
605   NEAR(a_center, b_bottom, d, mask, 040);
606   NEAR(a_bottom, b_top,    d, mask, 0100);
607   NEAR(a_bottom, b_center, d, mask, 0200);
608   NEAR(a_bottom, b_bottom, d, mask, 0400);
609 
610   NEAR(a_left,   b_left,   d, mask, 01000);
611   NEAR(a_left,   b_middle, d, mask, 02000);
612   NEAR(a_left,   b_right,  d, mask, 04000);
613   NEAR(a_middle, b_left,   d, mask, 010000);
614   NEAR(a_middle, b_middle, d, mask, 020000);
615   NEAR(a_middle, b_right,  d, mask, 040000);
616   NEAR(a_right,  b_left,   d, mask, 0100000);
617   NEAR(a_right,  b_middle, d, mask, 0200000);
618   NEAR(a_right,  b_right,  d, mask, 0400000);
619 
620   answer(toInt(mask));
621 }
622 
623 
624 static Int
sameSidesArea(Area a,Area b)625 sameSidesArea(Area a, Area b)
626 { int a_top, a_center, a_bottom, a_left, a_middle, a_right;
627   int b_top, b_center, b_bottom, b_left, b_middle, b_right;
628   register unsigned long mask;
629 
630   InitAreaA;
631   InitAreaB;
632 
633   NormaliseArea(ax, ay, aw, ah);
634   NormaliseArea(bx, by, bw, bh);
635 
636   a_top = ay;
637   a_bottom = ay+ah-1;
638   a_center = (a_top+a_bottom+1)/2;
639 
640   a_left = ax;
641   a_right = ax+aw-1;
642   a_middle = (a_left+a_right+1)/2;
643 
644   b_top = by;
645   b_bottom = by+bh-1;
646   b_center = (b_top+b_bottom+1)/2;
647 
648   b_left = bx;
649   b_right = bx+bw-1;
650   b_middle = (b_left+b_right+1)/2;
651 
652   mask = 0;
653 
654   SAME(a_top,    b_top,    mask, 01);
655   SAME(a_top,    b_center, mask, 02);
656   SAME(a_top,    b_bottom, mask, 04);
657   SAME(a_center, b_top,    mask, 010);
658   SAME(a_center, b_center, mask, 020);
659   SAME(a_center, b_bottom, mask, 040);
660   SAME(a_bottom, b_top,    mask, 0100);
661   SAME(a_bottom, b_center, mask, 0200);
662   SAME(a_bottom, b_bottom, mask, 0400);
663 
664   SAME(a_left,   b_left,   mask, 01000);
665   SAME(a_left,   b_middle, mask, 02000);
666   SAME(a_left,   b_right,  mask, 04000);
667   SAME(a_middle, b_left,   mask, 010000);
668   SAME(a_middle, b_middle, mask, 020000);
669   SAME(a_middle, b_right,  mask, 040000);
670   SAME(a_right,  b_left,   mask, 0100000);
671   SAME(a_right,  b_middle, mask, 0200000);
672   SAME(a_right,  b_right,  mask, 0400000);
673 
674   answer(toInt(mask));
675 }
676 
677 
678 static Int
getLessSidesArea(Area a,Area b)679 getLessSidesArea(Area a, Area b)
680 { int a_top, a_center, a_bottom, a_left, a_middle, a_right;
681   int b_top, b_center, b_bottom, b_left, b_middle, b_right;
682   register unsigned long mask;
683 
684   InitAreaA;
685   InitAreaB;
686 
687   NormaliseArea(ax, ay, aw, ah);
688   NormaliseArea(bx, by, bw, bh);
689 
690   a_top = ay;
691   a_bottom = ay+ah-1;
692   a_center = (a_top+a_bottom+1)/2;
693 
694   a_left = ax;
695   a_right = ax+aw-1;
696   a_middle = (a_left+a_right+1)/2;
697 
698   b_top = by;
699   b_bottom = by+bh-1;
700   b_center = (b_top+b_bottom+1)/2;
701 
702   b_left = bx;
703   b_right = bx+bw-1;
704   b_middle = (b_left+b_right+1)/2;
705 
706   mask = 0;
707 
708   LESS(a_top,    b_top,    mask, 01);
709   LESS(a_top,    b_center, mask, 02);
710   LESS(a_top,    b_bottom, mask, 04);
711   LESS(a_center, b_top,    mask, 010);
712   LESS(a_center, b_center, mask, 020);
713   LESS(a_center, b_bottom, mask, 040);
714   LESS(a_bottom, b_top,    mask, 0100);
715   LESS(a_bottom, b_center, mask, 0200);
716   LESS(a_bottom, b_bottom, mask, 0400);
717 
718   LESS(a_left,   b_left,   mask, 01000);
719   LESS(a_left,   b_middle, mask, 02000);
720   LESS(a_left,   b_right,  mask, 04000);
721   LESS(a_middle, b_left,   mask, 010000);
722   LESS(a_middle, b_middle, mask, 020000);
723   LESS(a_middle, b_right,  mask, 040000);
724   LESS(a_right,  b_left,   mask, 0100000);
725   LESS(a_right,  b_middle, mask, 0200000);
726   LESS(a_right,  b_right,  mask, 0400000);
727 
728   answer(toInt(mask));
729 }
730 
731 
732 		 /*******************************
733 		 *	 CLASS DECLARATION	*
734 		 *******************************/
735 
736 /* Type declaractions */
737 
738 static char *T_nearSides[] =
739         { "area", "int" };
740 static char *T_dxdydwdh[] =
741         { "x=[int]", "y=[int]", "width=[int]", "height=[int]" };
742 
743 /* Instance Variables */
744 
745 static vardecl var_area[] =
746 { IV(NAME_x, "int", IV_BOTH,
747      NAME_position, "Origin's X-value"),
748   IV(NAME_y, "int", IV_BOTH,
749      NAME_position, "Origin's Y-value"),
750   IV(NAME_width, "int", IV_BOTH,
751      NAME_dimension, "Width in pixels (may be negative)"),
752   IV(NAME_height, "int", IV_BOTH,
753      NAME_dimension, "Height in pixels (may be negative)")
754 };
755 
756 /* Send Methods */
757 
758 static senddecl send_area[] =
759 { SM(NAME_initialise, 4, T_dxdydwdh, initialiseArea,
760      DEFAULT, "Create area from X, Y, W and H"),
761   SM(NAME_copy, 1, "area", copyArea,
762      NAME_copy, "Copy X, Y, W and H from argument area"),
763   SM(NAME_equal, 1, "area", equalArea,
764      NAME_equality, "Test if area is equal to the argument"),
765   SM(NAME_normalise, 0, NULL, normaliseArea,
766      NAME_orientation, "Make top-left corner the origin"),
767   SM(NAME_orientation, 1, "{north_west,south_west,north_east,south_east}",
768      orientationArea,
769      NAME_orientation, "Put origin at indicated corner"),
770   SM(NAME_center, 1, "point", centerArea,
771      NAME_position, "Move to make point the center"),
772   SM(NAME_position, 1, "point", positionArea,
773      NAME_position, "Move origin to point"),
774   SM(NAME_relativeMove, 1, "point", relativeMoveArea,
775      NAME_position, "Move origin relative by point"),
776   SM(NAME_in, 1, "point", pointInArea,
777      NAME_relation, "Test if point is in area"),
778   SM(NAME_inside, 1, "area", insideArea,
779      NAME_relation, "Test if argument is entirely in area"),
780   SM(NAME_intersection, 1, "area", intersectionArea,
781      NAME_relation, "Make area the intersection with argument"),
782   SM(NAME_overlap, 1, "area", overlapArea,
783      NAME_relation, "Test whether area overlaps argument"),
784   SM(NAME_clear, 0, NULL, clearArea,
785      NAME_resize, "Set X, Y, W and H to 0"),
786   SM(NAME_corner, 1, "point", cornerArea,
787      NAME_resize, "Resize to make opposite of origin point"),
788   SM(NAME_decrease, 1, "int", decreaseArea,
789      NAME_resize, "Move all sides inwards"),
790   SM(NAME_increase, 1, "int", increaseArea,
791      NAME_resize, "Move all sides outwards"),
792   SM(NAME_set, 4, T_dxdydwdh, setArea,
793      NAME_resize, "Set X, Y, W and H values"),
794   SM(NAME_size, 1, "size", sizeArea,
795      NAME_resize, "Resize area to size"),
796   SM(NAME_union, 1, "area", unionArea,
797      NAME_resize, "Enlarge area to entail argument")
798 };
799 
800 /* Get Methods */
801 
802 static getdecl get_area[] =
803 { GM(NAME_normalised, 0, "area", NULL, getNormalisedArea,
804      NAME_copy, "New area with origin at top-left"),
805   GM(NAME_measure, 0, "int", NULL, getMeasureArea,
806      NAME_dimension, "`Area' of the area"),
807   GM(NAME_size, 0, "size", NULL, getSizeArea,
808      NAME_dimension, "New size from size of area"),
809   GM(NAME_orientation, 0, "{north_west,south_west,north_east,south_east}", NULL, getOrientationArea,
810      NAME_orientation, "Current orientation"),
811   GM(NAME_center, 0, "point", NULL, getCenterArea,
812      NAME_position, "New point from center position"),
813   GM(NAME_corner, 0, "point", NULL, getCornerArea,
814      NAME_position, "New point from point opposite origin"),
815   GM(NAME_position, 0, "point", NULL, getPositionArea,
816      NAME_position, "New point from origin"),
817   GM(NAME_distance, 1, "int", "area", getDistanceArea,
818      NAME_relation, "Closest distance between areas"),
819   GM(NAME_distanceX, 1, "int", "area", getDistanceXArea,
820      NAME_relation, "Distance between area's in X-direction"),
821   GM(NAME_distanceY, 1, "int", "area", getDistanceYArea,
822      NAME_relation, "Distance between area's in Y-direction"),
823   GM(NAME_intersection, 1, "area", "area", getIntersectionArea,
824      NAME_relation, "New area from intersection"),
825   GM(NAME_lessSides, 1, "int", "area", getLessSidesArea,
826      NAME_relation, "Bitmask (int) of sides closer to origin"),
827   GM(NAME_nearSides, 2, "int", T_nearSides, getNearSidesArea,
828      NAME_relation, "Bitmask (int) of almost equal sides"),
829   GM(NAME_sameSides, 1, "int", "area", sameSidesArea,
830      NAME_relation, "Bitmask (int) of equal sides"),
831   GM(NAME_union, 1, "area", "area", getUnionArea,
832      NAME_resize, "New area from union"),
833   GM(NAME_bottomSide, 0, "int", NULL, getBottomSideArea,
834      NAME_side, "Bottom-side of area"),
835   GM(NAME_leftSide, 0, "int", NULL, getLeftSideArea,
836      NAME_side, "Left-side of area"),
837   GM(NAME_rightSide, 0, "int", NULL, getRightSideArea,
838      NAME_side, "Right-side of area"),
839   GM(NAME_topSide, 0, "int", NULL, getTopSideArea,
840      NAME_side, "Top-side of area")
841 };
842 
843 /* Resources */
844 
845 #define rc_area NULL
846 /*
847 static classvardecl rc_area[] =
848 {
849 };
850 */
851 
852 /* Class Declaration */
853 
854 static Name area_termnames[] = { NAME_x, NAME_y, NAME_width, NAME_height };
855 
856 ClassDecl(area_decls,
857           var_area, send_area, get_area, rc_area,
858           4, area_termnames,
859           "$Rev$");
860 
861 
862 status
makeClassArea(Class class)863 makeClassArea(Class class)
864 { return declareClass(class, &area_decls);
865 }
866