1706f2543Smrg/************************************************************
2706f2543Smrg
3706f2543SmrgCopyright 1989, 1998  The Open Group
4706f2543Smrg
5706f2543SmrgPermission to use, copy, modify, distribute, and sell this software and its
6706f2543Smrgdocumentation for any purpose is hereby granted without fee, provided that
7706f2543Smrgthe above copyright notice appear in all copies and that both that
8706f2543Smrgcopyright notice and this permission notice appear in supporting
9706f2543Smrgdocumentation.
10706f2543Smrg
11706f2543SmrgThe above copyright notice and this permission notice shall be included in
12706f2543Smrgall copies or substantial portions of the Software.
13706f2543Smrg
14706f2543SmrgTHE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15706f2543SmrgIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16706f2543SmrgFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
17706f2543SmrgOPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
18706f2543SmrgAN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
19706f2543SmrgCONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
20706f2543Smrg
21706f2543SmrgExcept as contained in this notice, the name of The Open Group shall not be
22706f2543Smrgused in advertising or otherwise to promote the sale, use or other dealings
23706f2543Smrgin this Software without prior written authorization from The Open Group.
24706f2543Smrg
25706f2543Smrg********************************************************/
26706f2543Smrg
27706f2543Smrg
28706f2543Smrg#ifndef __MIFILLARC_H__
29706f2543Smrg#define __MIFILLARC_H__
30706f2543Smrg
31706f2543Smrg#define FULLCIRCLE (360 * 64)
32706f2543Smrg
33706f2543Smrgtypedef struct _miFillArc {
34706f2543Smrg    int xorg, yorg;
35706f2543Smrg    int y;
36706f2543Smrg    int dx, dy;
37706f2543Smrg    int e;
38706f2543Smrg    int ym, yk, xm, xk;
39706f2543Smrg} miFillArcRec;
40706f2543Smrg
41706f2543Smrg/* could use 64-bit integers */
42706f2543Smrgtypedef struct _miFillArcD {
43706f2543Smrg    int xorg, yorg;
44706f2543Smrg    int y;
45706f2543Smrg    int dx, dy;
46706f2543Smrg    double e;
47706f2543Smrg    double ym, yk, xm, xk;
48706f2543Smrg} miFillArcDRec;
49706f2543Smrg
50706f2543Smrg#define miFillArcEmpty(arc) (!(arc)->angle2 || \
51706f2543Smrg			     !(arc)->width || !(arc)->height || \
52706f2543Smrg			     (((arc)->width == 1) && ((arc)->height & 1)))
53706f2543Smrg
54706f2543Smrg#define miCanFillArc(arc) (((arc)->width == (arc)->height) || \
55706f2543Smrg			   (((arc)->width <= 800) && ((arc)->height <= 800)))
56706f2543Smrg
57706f2543Smrg#define MIFILLARCSETUP() \
58706f2543Smrg    x = 0; \
59706f2543Smrg    y = info.y; \
60706f2543Smrg    e = info.e; \
61706f2543Smrg    xk = info.xk; \
62706f2543Smrg    xm = info.xm; \
63706f2543Smrg    yk = info.yk; \
64706f2543Smrg    ym = info.ym; \
65706f2543Smrg    dx = info.dx; \
66706f2543Smrg    dy = info.dy; \
67706f2543Smrg    xorg = info.xorg; \
68706f2543Smrg    yorg = info.yorg
69706f2543Smrg
70706f2543Smrg#define MIFILLARCSTEP(slw) \
71706f2543Smrg    e += yk; \
72706f2543Smrg    while (e >= 0) \
73706f2543Smrg    { \
74706f2543Smrg	x++; \
75706f2543Smrg	xk -= xm; \
76706f2543Smrg	e += xk; \
77706f2543Smrg    } \
78706f2543Smrg    y--; \
79706f2543Smrg    yk -= ym; \
80706f2543Smrg    slw = (x << 1) + dx; \
81706f2543Smrg    if ((e == xk) && (slw > 1)) \
82706f2543Smrg	slw--
83706f2543Smrg
84706f2543Smrg#define MIFILLCIRCSTEP(slw) MIFILLARCSTEP(slw)
85706f2543Smrg#define MIFILLELLSTEP(slw) MIFILLARCSTEP(slw)
86706f2543Smrg
87706f2543Smrg#define miFillArcLower(slw) (((y + dy) != 0) && ((slw > 1) || (e != xk)))
88706f2543Smrg
89706f2543Smrgtypedef struct _miSliceEdge {
90706f2543Smrg    int	    x;
91706f2543Smrg    int     stepx;
92706f2543Smrg    int	    deltax;
93706f2543Smrg    int	    e;
94706f2543Smrg    int	    dy;
95706f2543Smrg    int	    dx;
96706f2543Smrg} miSliceEdgeRec, *miSliceEdgePtr;
97706f2543Smrg
98706f2543Smrgtypedef struct _miArcSlice {
99706f2543Smrg    miSliceEdgeRec edge1, edge2;
100706f2543Smrg    int min_top_y, max_top_y;
101706f2543Smrg    int min_bot_y, max_bot_y;
102706f2543Smrg    Bool edge1_top, edge2_top;
103706f2543Smrg    Bool flip_top, flip_bot;
104706f2543Smrg} miArcSliceRec;
105706f2543Smrg
106706f2543Smrg#define MIARCSLICESTEP(edge) \
107706f2543Smrg    edge.x -= edge.stepx; \
108706f2543Smrg    edge.e -= edge.dx; \
109706f2543Smrg    if (edge.e <= 0) \
110706f2543Smrg    { \
111706f2543Smrg	edge.x -= edge.deltax; \
112706f2543Smrg	edge.e += edge.dy; \
113706f2543Smrg    }
114706f2543Smrg
115706f2543Smrg#define miFillSliceUpper(slice) \
116706f2543Smrg		((y >= slice.min_top_y) && (y <= slice.max_top_y))
117706f2543Smrg
118706f2543Smrg#define miFillSliceLower(slice) \
119706f2543Smrg		((y >= slice.min_bot_y) && (y <= slice.max_bot_y))
120706f2543Smrg
121706f2543Smrg#define MIARCSLICEUPPER(xl,xr,slice,slw) \
122706f2543Smrg    xl = xorg - x; \
123706f2543Smrg    xr = xl + slw - 1; \
124706f2543Smrg    if (slice.edge1_top && (slice.edge1.x < xr)) \
125706f2543Smrg	xr = slice.edge1.x; \
126706f2543Smrg    if (slice.edge2_top && (slice.edge2.x > xl)) \
127706f2543Smrg	xl = slice.edge2.x;
128706f2543Smrg
129706f2543Smrg#define MIARCSLICELOWER(xl,xr,slice,slw) \
130706f2543Smrg    xl = xorg - x; \
131706f2543Smrg    xr = xl + slw - 1; \
132706f2543Smrg    if (!slice.edge1_top && (slice.edge1.x > xl)) \
133706f2543Smrg	xl = slice.edge1.x; \
134706f2543Smrg    if (!slice.edge2_top && (slice.edge2.x < xr)) \
135706f2543Smrg	xr = slice.edge2.x;
136706f2543Smrg
137706f2543Smrg#define MIWIDEARCSETUP(x,y,dy,slw,e,xk,xm,yk,ym) \
138706f2543Smrg    x = 0; \
139706f2543Smrg    y = slw >> 1; \
140706f2543Smrg    yk = y << 3; \
141706f2543Smrg    xm = 8; \
142706f2543Smrg    ym = 8; \
143706f2543Smrg    if (dy) \
144706f2543Smrg    { \
145706f2543Smrg	xk = 0; \
146706f2543Smrg	if (slw & 1) \
147706f2543Smrg	    e = -1; \
148706f2543Smrg	else \
149706f2543Smrg	    e = -(y << 2) - 2; \
150706f2543Smrg    } \
151706f2543Smrg    else \
152706f2543Smrg    { \
153706f2543Smrg	y++; \
154706f2543Smrg	yk += 4; \
155706f2543Smrg	xk = -4; \
156706f2543Smrg	if (slw & 1) \
157706f2543Smrg	    e = -(y << 2) - 3; \
158706f2543Smrg	else \
159706f2543Smrg	    e = - (y << 3); \
160706f2543Smrg    }
161706f2543Smrg
162706f2543Smrg#define MIFILLINARCSTEP(slw) \
163706f2543Smrg    ine += inyk; \
164706f2543Smrg    while (ine >= 0) \
165706f2543Smrg    { \
166706f2543Smrg	inx++; \
167706f2543Smrg	inxk -= inxm; \
168706f2543Smrg	ine += inxk; \
169706f2543Smrg    } \
170706f2543Smrg    iny--; \
171706f2543Smrg    inyk -= inym; \
172706f2543Smrg    slw = (inx << 1) + dx; \
173706f2543Smrg    if ((ine == inxk) && (slw > 1)) \
174706f2543Smrg	slw--
175706f2543Smrg
176706f2543Smrg#define miFillInArcLower(slw) (((iny + dy) != 0) && \
177706f2543Smrg			       ((slw > 1) || (ine != inxk)))
178706f2543Smrg
179706f2543Smrgextern _X_EXPORT void miFillArcSetup(
180706f2543Smrg    xArc * /*arc*/,
181706f2543Smrg    miFillArcRec * /*info*/
182706f2543Smrg);
183706f2543Smrg
184706f2543Smrgextern _X_EXPORT void miFillArcSliceSetup(
185706f2543Smrg    xArc * /*arc*/,
186706f2543Smrg    miArcSliceRec * /*slice*/,
187706f2543Smrg    GCPtr /*pGC*/
188706f2543Smrg);
189706f2543Smrg
190706f2543Smrg#endif /* __MIFILLARC_H__ */
191