1 /* Copyright (C) 1997, 1998, 1999 artofcode LLC.  All rights reserved.
2 
3   This program is free software; you can redistribute it and/or modify it
4   under the terms of the GNU General Public License as published by the
5   Free Software Foundation; either version 2 of the License, or (at your
6   option) any later version.
7 
8   This program is distributed in the hope that it will be useful, but
9   WITHOUT ANY WARRANTY; without even the implied warranty of
10   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
11   General Public License for more details.
12 
13   You should have received a copy of the GNU General Public License along
14   with this program; if not, write to the Free Software Foundation, Inc.,
15   59 Temple Place, Suite 330, Boston, MA, 02111-1307.
16 
17 */
18 
19 /*$Id: gsrect.h,v 1.2.6.1.2.1 2003/01/17 00:49:03 giles Exp $ */
20 /* Rectangle utilities */
21 
22 #ifndef gsrect_INCLUDED
23 #  define gsrect_INCLUDED
24 
25 #include "gxfixed.h"
26 
27 /* Check whether one rectangle is included entirely within another. */
28 #define rect_within(inner, outer)\
29   ((inner).q.y <= (outer).q.y && (inner).q.x <= (outer).q.x &&\
30    (inner).p.y >= (outer).p.y && (inner).p.x >= (outer).p.x)
31 
32 /*
33  * Intersect two rectangles, replacing the first.  The result may be
34  * anomalous (q < p) if the intersection is empty.
35  */
36 #define rect_intersect(to, from)\
37   BEGIN\
38     if ((from).p.x > (to).p.x) (to).p.x = (from).p.x;\
39     if ((from).q.x < (to).q.x) (to).q.x = (from).q.x;\
40     if ((from).p.y > (to).p.y) (to).p.y = (from).p.y;\
41     if ((from).q.y < (to).q.y) (to).q.y = (from).q.y;\
42   END
43 
44 /*
45  * Merge two rectangles, replacing the first.  The result may be
46  * anomalous (q < p) if the first rectangle was anomalous.
47  */
48 #define rect_merge(to, from)\
49   BEGIN\
50     if ((from).p.x < (to).p.x) (to).p.x = (from).p.x;\
51     if ((from).q.x > (to).q.x) (to).q.x = (from).q.x;\
52     if ((from).p.y < (to).p.y) (to).p.y = (from).p.y;\
53     if ((from).q.y > (to).q.y) (to).q.y = (from).q.y;\
54   END
55 
56 /*
57  * Calculate the difference of two rectangles, a list of up to 4 rectangles.
58  * Return the number of rectangles in the list, and set the first rectangle
59  * to the intersection.  The resulting first rectangle is guaranteed not to
60  * be anomalous (q < p) iff it was not anomalous originally.
61  *
62  * Note that unlike the macros above, we need different versions of this
63  * depending on the data type of the individual values: we'll only implement
64  * the variations that we need.
65  */
66 int int_rect_difference(P3(gs_int_rect * outer, const gs_int_rect * inner,
67 			   gs_int_rect * diffs /*[4] */ ));
68 
69 /*
70  * Check whether a parallelogram is a rectangle.
71  */
72 #define PARALLELOGRAM_IS_RECT(ax, ay, bx, by)\
73   ( ((ax) | (by)) == 0 || ((bx) | (ay)) == 0 )
74 
75 /*
76  * Convert a rectangular parallelogram to a rectangle, carefully following
77  * the center-of-pixel rule in all cases.
78  */
79 #define INT_RECT_FROM_PARALLELOGRAM(prect, px, py, ax, ay, bx, by)\
80   BEGIN\
81     int px_ = fixed2int_pixround(px);\
82     int py_ = fixed2int_pixround(py);\
83     int qx_ = fixed2int_pixround((px) + (ax) + (bx));  /* only one is non-zero */\
84     int qy_ = fixed2int_pixround((py) + (ay) + (by));  /* ditto */\
85 \
86     if (qx_ < px_)\
87       (prect)->p.x = qx_, (prect)->q.x = px_;\
88     else\
89       (prect)->p.x = px_, (prect)->q.x = qx_;\
90     if (qy_ < py_)\
91       (prect)->p.y = qy_, (prect)->q.y = py_;\
92     else\
93       (prect)->p.y = py_, (prect)->q.y = qy_;\
94   END
95 
96 #endif /* gsrect_INCLUDED */
97