1 /* This file is part of the GNU libxmi package.
2 
3    Copyright (C) 1985, 1986, 1987, 1988, 1989, X Consortium.  For an
4    associated permission notice, see the accompanying file README-X.
5 
6    GNU enhancements Copyright (C) 1998, 1999, 2000, 2005, Free Software
7    Foundation, Inc.
8 
9    The GNU libxmi package is free software.  You may redistribute it
10    and/or modify it under the terms of the GNU General Public License as
11    published by the Free Software foundation; either version 2, or (at your
12    option) any later version.
13 
14    The GNU libxmi package is distributed in the hope that it will be
15    useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
16    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
17    General Public License for more details.
18 
19    You should have received a copy of the GNU General Public License along
20    with the GNU plotutils package; see the file COPYING.  If not, write to
21    the Free Software Foundation, Inc., 51 Franklin St., Fifth Floor,
22    Boston, MA 02110-1301, USA. */
23 
24 /* This header file is included by mi_zerarc.c, which draws a single-pixel
25    (i.e. Bresenham) poly-arc using a fast integer algorithm.  It defines
26    structures and macros used in the algorithm. */
27 
28 typedef struct
29 {
30   int x;
31   int y;
32   unsigned int mask;
33 } miZeroArcPt;
34 
35 typedef struct
36 {
37   int x, y, k1, k3, a, b, d, dx, dy;
38   int alpha, beta;
39   int xorg, yorg;		/* upper left corner */
40   int xorgo, yorgo;
41   unsigned int w, h;
42   unsigned int initialMask;
43   miZeroArcPt start, altstart, end, altend;
44   int firstx, firsty;
45   int startAngle, endAngle;	/* in 1/64 degrees */
46 } miZeroArc;
47 
48 /* miZeroPolyArc() draws an arc only if it satisfies the following size
49    constraint.  If it doesn't, miZeroPolyArc() hands it off to miPolyArc(),
50    which uses a floating point algorithm. */
51 #define MI_CAN_ZERO_ARC(arc) (((arc)->width == (arc)->height) || \
52 			     (((arc)->width <= 800) && ((arc)->height <= 800)))
53 
54 /* used for setup only */
55 #define MIARCSETUP(info, x, y, k1, k3, a, b, d, dx, dy) \
56 x = info.x; \
57 y = info.y; \
58 k1 = info.k1; \
59 k3 = info.k3; \
60 a = info.a; \
61 b = info.b; \
62 d = info.d; \
63 dx = info.dx; \
64 dy = info.dy
65 
66 #define MIARCOCTANTSHIFT(info, x, y, dx, dy, a, b, d, k1, k3, clause) \
67 if (a < 0) \
68 { \
69     if (y == (int)info.h) \
70       { \
71 	d = -1; \
72 	a = b = k1 = 0; \
73       } \
74   else \
75     { \
76       dx = (k1 << 1) - k3; \
77       k1 = dx - k1; \
78       k3 = -k3; \
79       b = b + a - (k1 >> 1); \
80       d = b + ((-a) >> 1) - d + (k3 >> 3); \
81       if (dx < 0) \
82 	  a = -((-dx) >> 1) - a; \
83       else \
84 	  a = (dx >> 1) - a; \
85       dx = 0; \
86       dy = 1; \
87       clause \
88     } \
89 }
90 
91 #define MIARCSTEP(x, y, dx, dy, a, b, d, k1, k3, move1, move2) \
92 b -= k1; \
93 if (d < 0) \
94 { \
95     x += dx; \
96     y += dy; \
97     a += k1; \
98     d += b; \
99     move1 \
100 } \
101 else \
102 { \
103     x++; \
104     y++; \
105     a += k3; \
106     d -= a; \
107     move2 \
108 }
109 
110 #define MIARCCIRCLESTEP(x, y, a, b, d, k1, k3, clause) \
111 b -= k1; \
112 x++; \
113 if (d < 0) \
114 { \
115   a += k1; \
116   d += b; \
117 } \
118 else \
119 { \
120   y++; \
121   a += k3; \
122   d -= a; \
123   clause \
124 }
125