1/************************************************************
2
3Copyright 1989, 1998  The Open Group
4
5Permission to use, copy, modify, distribute, and sell this software and its
6documentation for any purpose is hereby granted without fee, provided that
7the above copyright notice appear in all copies and that both that
8copyright notice and this permission notice appear in supporting
9documentation.
10
11The above copyright notice and this permission notice shall be included in
12all copies or substantial portions of the Software.
13
14THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
17OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
18AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
19CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
20
21Except as contained in this notice, the name of The Open Group shall not be
22used in advertising or otherwise to promote the sale, use or other dealings
23in this Software without prior written authorization from The Open Group.
24
25********************************************************/
26
27
28#ifndef __MIFILLARC_H__
29#define __MIFILLARC_H__
30
31#define FULLCIRCLE (360 * 64)
32
33typedef struct _miFillArc {
34    int xorg, yorg;
35    int y;
36    int dx, dy;
37    int e;
38    int ym, yk, xm, xk;
39} miFillArcRec;
40
41/* could use 64-bit integers */
42typedef struct _miFillArcD {
43    int xorg, yorg;
44    int y;
45    int dx, dy;
46    double e;
47    double ym, yk, xm, xk;
48} miFillArcDRec;
49
50#define miFillArcEmpty(arc) (!(arc)->angle2 || \
51			     !(arc)->width || !(arc)->height || \
52			     (((arc)->width == 1) && ((arc)->height & 1)))
53
54#define miCanFillArc(arc) (((arc)->width == (arc)->height) || \
55			   (((arc)->width <= 800) && ((arc)->height <= 800)))
56
57#define MIFILLARCSETUP() \
58    x = 0; \
59    y = info.y; \
60    e = info.e; \
61    xk = info.xk; \
62    xm = info.xm; \
63    yk = info.yk; \
64    ym = info.ym; \
65    dx = info.dx; \
66    dy = info.dy; \
67    xorg = info.xorg; \
68    yorg = info.yorg
69
70#define MIFILLARCSTEP(slw) \
71    e += yk; \
72    while (e >= 0) \
73    { \
74	x++; \
75	xk -= xm; \
76	e += xk; \
77    } \
78    y--; \
79    yk -= ym; \
80    slw = (x << 1) + dx; \
81    if ((e == xk) && (slw > 1)) \
82	slw--
83
84#define MIFILLCIRCSTEP(slw) MIFILLARCSTEP(slw)
85#define MIFILLELLSTEP(slw) MIFILLARCSTEP(slw)
86
87#define miFillArcLower(slw) (((y + dy) != 0) && ((slw > 1) || (e != xk)))
88
89typedef struct _miSliceEdge {
90    int	    x;
91    int     stepx;
92    int	    deltax;
93    int	    e;
94    int	    dy;
95    int	    dx;
96} miSliceEdgeRec, *miSliceEdgePtr;
97
98typedef struct _miArcSlice {
99    miSliceEdgeRec edge1, edge2;
100    int min_top_y, max_top_y;
101    int min_bot_y, max_bot_y;
102    Bool edge1_top, edge2_top;
103    Bool flip_top, flip_bot;
104} miArcSliceRec;
105
106#define MIARCSLICESTEP(edge) \
107    edge.x -= edge.stepx; \
108    edge.e -= edge.dx; \
109    if (edge.e <= 0) \
110    { \
111	edge.x -= edge.deltax; \
112	edge.e += edge.dy; \
113    }
114
115#define miFillSliceUpper(slice) \
116		((y >= slice.min_top_y) && (y <= slice.max_top_y))
117
118#define miFillSliceLower(slice) \
119		((y >= slice.min_bot_y) && (y <= slice.max_bot_y))
120
121#define MIARCSLICEUPPER(xl,xr,slice,slw) \
122    xl = xorg - x; \
123    xr = xl + slw - 1; \
124    if (slice.edge1_top && (slice.edge1.x < xr)) \
125	xr = slice.edge1.x; \
126    if (slice.edge2_top && (slice.edge2.x > xl)) \
127	xl = slice.edge2.x;
128
129#define MIARCSLICELOWER(xl,xr,slice,slw) \
130    xl = xorg - x; \
131    xr = xl + slw - 1; \
132    if (!slice.edge1_top && (slice.edge1.x > xl)) \
133	xl = slice.edge1.x; \
134    if (!slice.edge2_top && (slice.edge2.x < xr)) \
135	xr = slice.edge2.x;
136
137#define MIWIDEARCSETUP(x,y,dy,slw,e,xk,xm,yk,ym) \
138    x = 0; \
139    y = slw >> 1; \
140    yk = y << 3; \
141    xm = 8; \
142    ym = 8; \
143    if (dy) \
144    { \
145	xk = 0; \
146	if (slw & 1) \
147	    e = -1; \
148	else \
149	    e = -(y << 2) - 2; \
150    } \
151    else \
152    { \
153	y++; \
154	yk += 4; \
155	xk = -4; \
156	if (slw & 1) \
157	    e = -(y << 2) - 3; \
158	else \
159	    e = - (y << 3); \
160    }
161
162#define MIFILLINARCSTEP(slw) \
163    ine += inyk; \
164    while (ine >= 0) \
165    { \
166	inx++; \
167	inxk -= inxm; \
168	ine += inxk; \
169    } \
170    iny--; \
171    inyk -= inym; \
172    slw = (inx << 1) + dx; \
173    if ((ine == inxk) && (slw > 1)) \
174	slw--
175
176#define miFillInArcLower(slw) (((iny + dy) != 0) && \
177			       ((slw > 1) || (ine != inxk)))
178
179extern _X_EXPORT void miFillArcSetup(
180    xArc * /*arc*/,
181    miFillArcRec * /*info*/
182);
183
184extern _X_EXPORT void miFillArcSliceSetup(
185    xArc * /*arc*/,
186    miArcSliceRec * /*slice*/,
187    GCPtr /*pGC*/
188);
189
190#endif /* __MIFILLARC_H__ */
191