1 /* $XConsortium: miwideline.h,v 1.11 94/04/17 20:28:02 dpw Exp $ */
2 /*
3 
4 Copyright (c) 1988  X Consortium
5 
6 Permission is hereby granted, free of charge, to any person obtaining
7 a copy of this software and associated documentation files (the
8 "Software"), to deal in the Software without restriction, including
9 without limitation the rights to use, copy, modify, merge, publish,
10 distribute, sublicense, and/or sell copies of the Software, and to
11 permit persons to whom the Software is furnished to do so, subject to
12 the following conditions:
13 
14 The above copyright notice and this permission notice shall be included
15 in all copies or substantial portions of the Software.
16 
17 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
18 OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
19 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
20 IN NO EVENT SHALL THE X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR
21 OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
22 ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
23 OTHER DEALINGS IN THE SOFTWARE.
24 
25 Except as contained in this notice, the name of the X Consortium shall
26 not be used in advertising or otherwise to promote the sale, use or
27 other dealings in this Software without prior written authorization
28 from the X Consortium.
29 
30 */
31 
32 /* Author:  Keith Packard, MIT X Consortium */
33 
34 #include "mispans.h"
35 
36 /*
37  * interface data to span-merging polygon filler
38  */
39 
40 typedef struct _SpanData {
41     SpanGroup	fgGroup, bgGroup;
42 } SpanDataRec, *SpanDataPtr;
43 
44 #define AppendSpanGroup(pGC, pixel, spanPtr, spanData) { \
45 	SpanGroup   *group, *othergroup = NULL; \
46 	if (pixel == pGC->fgPixel) \
47 	{ \
48 	    group = &spanData->fgGroup; \
49 	    if (pGC->lineStyle == LineDoubleDash) \
50 		othergroup = &spanData->bgGroup; \
51 	} \
52 	else \
53 	{ \
54 	    group = &spanData->bgGroup; \
55 	    othergroup = &spanData->fgGroup; \
56 	} \
57 	miAppendSpans (group, othergroup, spanPtr); \
58 }
59 
60 /*
61  * Polygon edge description for integer wide-line routines
62  */
63 
64 typedef struct _PolyEdge {
65     int	    height;	/* number of scanlines to process */
66     int	    x;		/* starting x coordinate */
67     int	    stepx;	/* fixed integral dx */
68     int	    signdx;	/* variable dx sign */
69     int	    e;		/* initial error term */
70     int	    dy;
71     int	    dx;
72 } PolyEdgeRec, *PolyEdgePtr;
73 
74 #define SQSECANT 108.856472512142 /* 1/sin^2(11/2) - miter limit constant */
75 
76 /*
77  * types for general polygon routines
78  */
79 
80 typedef struct _PolyVertex {
81     double  x, y;
82 } PolyVertexRec, *PolyVertexPtr;
83 
84 typedef struct _PolySlope {
85     int	    dx, dy;
86     double  k;	    /* x0 * dy - y0 * dx */
87 } PolySlopeRec, *PolySlopePtr;
88 
89 /*
90  * Line face description for caps/joins
91  */
92 
93 typedef struct _LineFace {
94     double  xa, ya;
95     int	    dx, dy;
96     int	    x, y;
97     double  k;
98 } LineFaceRec, *LineFacePtr;
99 
100 /*
101  * macros for polygon fillers
102  */
103 
104 #define MIPOLYRELOADLEFT    if (!left_height && left_count) { \
105 	    	    	    	left_height = left->height; \
106 	    	    	    	left_x = left->x; \
107 	    	    	    	left_stepx = left->stepx; \
108 	    	    	    	left_signdx = left->signdx; \
109 	    	    	    	left_e = left->e; \
110 	    	    	    	left_dy = left->dy; \
111 	    	    	    	left_dx = left->dx; \
112 	    	    	    	--left_count; \
113 	    	    	    	++left; \
114 			    }
115 
116 #define MIPOLYRELOADRIGHT   if (!right_height && right_count) { \
117 	    	    	    	right_height = right->height; \
118 	    	    	    	right_x = right->x; \
119 	    	    	    	right_stepx = right->stepx; \
120 	    	    	    	right_signdx = right->signdx; \
121 	    	    	    	right_e = right->e; \
122 	    	    	    	right_dy = right->dy; \
123 	    	    	    	right_dx = right->dx; \
124 	    	    	    	--right_count; \
125 	    	    	    	++right; \
126 			}
127 
128 #define MIPOLYSTEPLEFT  left_x += left_stepx; \
129     	    	    	left_e += left_dx; \
130     	    	    	if (left_e > 0) \
131     	    	    	{ \
132 	    	    	    left_x += left_signdx; \
133 	    	    	    left_e -= left_dy; \
134     	    	    	}
135 
136 #define MIPOLYSTEPRIGHT right_x += right_stepx; \
137     	    	    	right_e += right_dx; \
138     	    	    	if (right_e > 0) \
139     	    	    	{ \
140 	    	    	    right_x += right_signdx; \
141 	    	    	    right_e -= right_dy; \
142     	    	    	}
143 
144 #define MILINESETPIXEL(pDrawable, pGC, pixel, oldPixel) { \
145     oldPixel = pGC->fgPixel; \
146     if (pixel != oldPixel) { \
147 	DoChangeGC (pGC, GCForeground, (XID *) &pixel, FALSE); \
148 	ValidateGC (pDrawable, pGC); \
149     } \
150 }
151 #define MILINERESETPIXEL(pDrawable, pGC, pixel, oldPixel) { \
152     if (pixel != oldPixel) { \
153 	DoChangeGC (pGC, GCForeground, (XID *) &oldPixel, FALSE); \
154 	ValidateGC (pDrawable, pGC); \
155     } \
156 }
157 
158 #ifdef NOINLINEICEIL
159 #define ICEIL(x) ((int)ceil(x))
160 #else
161 #ifdef __GNUC__
ICEIL(x)162 static __inline int ICEIL(x)
163     double x;
164 {
165     int _cTmp = x;
166     return ((x == _cTmp) || (x < 0.0)) ? _cTmp : _cTmp+1;
167 }
168 #else
169 #define ICEIL(x) ((((x) == (_cTmp = (x))) || ((x) < 0.0)) ? _cTmp : _cTmp+1)
170 #define ICEILTEMPDECL static int _cTmp;
171 #endif
172 #endif
173 
174 extern void miFillPolyHelper(
175 #if NeedFunctionPrototypes
176     DrawablePtr /*pDrawable*/,
177     GCPtr /*pGC*/,
178     unsigned long /*pixel*/,
179     SpanDataPtr /*spanData*/,
180     int /*y*/,
181     int /*overall_height*/,
182     PolyEdgePtr /*left*/,
183     PolyEdgePtr /*right*/,
184     int /*left_count*/,
185     int /*right_count*/
186 #endif
187 );
188 extern int miRoundJoinFace(
189 #if NeedFunctionPrototypes
190     LineFacePtr /*face*/,
191     PolyEdgePtr /*edge*/,
192     Bool * /*leftEdge*/
193 #endif
194 );
195 
196 extern void miRoundJoinClip(
197 #if NeedFunctionPrototypes
198     LineFacePtr /*pLeft*/,
199     LineFacePtr /*pRight*/,
200     PolyEdgePtr /*edge1*/,
201     PolyEdgePtr /*edge2*/,
202     int * /*y1*/,
203     int * /*y2*/,
204     Bool * /*left1*/,
205     Bool * /*left2*/
206 #endif
207 );
208 
209 extern int miRoundCapClip(
210 #if NeedFunctionPrototypes
211     LineFacePtr /*face*/,
212     Bool /*isInt*/,
213     PolyEdgePtr /*edge*/,
214     Bool * /*leftEdge*/
215 #endif
216 );
217 
218 extern void miLineProjectingCap(
219 #if NeedFunctionPrototypes
220     DrawablePtr /*pDrawable*/,
221     GCPtr /*pGC*/,
222     unsigned long /*pixel*/,
223     SpanDataPtr /*spanData*/,
224     LineFacePtr /*face*/,
225     Bool /*isLeft*/,
226     double /*xorg*/,
227     double /*yorg*/,
228     Bool /*isInt*/
229 #endif
230 );
231 
232 extern SpanDataPtr miSetupSpanData(
233 #if NeedFunctionPrototypes
234     GCPtr /*pGC*/,
235     SpanDataPtr /*spanData*/,
236     int /*npt*/
237 #endif
238 );
239 
240 extern void miCleanupSpanData(
241 #if NeedFunctionPrototypes
242     DrawablePtr /*pDrawable*/,
243     GCPtr /*pGC*/,
244     SpanDataPtr /*spanData*/
245 #endif
246 );
247