1
/* $XFree86: xc/programs/Xserver/cfb/cfbzerarc.c,v 3.4tsi Exp $ */
2
/************************************************************
4
Copyright 1989, 1998 The Open Group
6
Permission to use, copy, modify, distribute, and sell this software and its
7
documentation for any purpose is hereby granted without fee, provided that
8
the above copyright notice appear in all copies and that both that
9
copyright notice and this permission notice appear in supporting
12
The above copyright notice and this permission notice shall be included in
13
all copies or substantial portions of the Software.
15
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
19
AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
20
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22
Except as contained in this notice, the name of The Open Group shall not be
23
used in advertising or otherwise to promote the sale, use or other dealings
24
in this Software without prior written authorization from The Open Group.
26
********************************************************/
28
/* $Xorg: cfbzerarc.c,v 1.4 2001/02/09 02:04:39 xorgcvs Exp $ */
31
* "Algorithm for drawing ellipses or hyperbolae with a digital plotter"
32
* by M. L. V. Pitteway
33
* The Computer Journal, November 1967, Volume 10, Number 3, pp. 282-289
36
#ifdef HAVE_DIX_CONFIG_H
37
#include <dix-config.h>
41
#include <X11/Xprotostr.h>
42
#include "regionstr.h"
44
#include "pixmapstr.h"
45
#include "scrnintstr.h"
47
#include "cfbmskbits.h"
55
RROP_NAME(cfbZeroArcSS8)(
64
register PixelType *yorgp, *yorgop;
66
int xorg, xorg3, xorgo, xorgo3;
71
int npwidth, dyoffset;
72
register int y, a, b, d, mask;
73
register int k1, k3, dx, dy;
75
cfbGetPixelWidthAndPointer(pDraw,npwidth, addrp)
78
do360 = miZeroArcSetup(arc, &info, TRUE);
79
yorgp = addrp + ((info.yorg + pDraw->y) * npwidth);
80
yorgop = addrp + ((info.yorgo + pDraw->y) * npwidth);
81
info.xorg += pDraw->x;
82
info.xorgo += pDraw->x;
86
info.xorg = (info.xorg * 3) >> 2;
89
info.xorgo = (info.xorgo * 3) >> 2;
92
yoffset = y ? npwidth : 0;
94
mask = info.initialMask;
95
if (!(arc->width & 1))
99
RROP_SOLID24((yorgp + info.xorgo), xorgo);
101
RROP_SOLID24((yorgop + info.xorgo), xorgo);
104
RROP_SOLID((yorgp + info.xorgo));
106
RROP_SOLID((yorgop + info.xorgo));
107
#endif /* PSZ == 24 */
109
if (!info.end.x || !info.end.y)
111
mask = info.end.mask;
112
info.end = info.altend;
114
if (do360 && (arc->width == arc->height) && !(arc->width & 1))
116
register int xoffset = npwidth;
118
PixelType *yorghb = yorgp + (info.h * npwidth);
119
register int tmp1, tmp2, tmp1_3, tmp2_3;
121
tmp1 = xorg + info.h;
123
tmp2 = xorg - info.h;
127
xtmp = (xorg3 + x * 3) >> 2;
128
RROP_SOLID24(yorgp + yoffset + xtmp, xorg + x);
129
RROP_SOLID24(yorgop - yoffset + xtmp, xorg + x);
130
xtmp = (xorg3 - x * 3) >> 2;
131
RROP_SOLID24(yorgp + yoffset + xtmp, xorg - x);
132
RROP_SOLID24(yorgop - yoffset + xtmp, xorg - x);
135
xtmp = (tmp1_3 - y * 3) >> 2;
136
RROP_SOLID24(yorghb - xoffset + xtmp, tmp1 - y);
137
RROP_SOLID24(yorghb + xoffset + xtmp, tmp1 - y);
138
xtmp = (tmp2_3 + y * 3) >> 2;
139
RROP_SOLID24(yorghb - xoffset + xtmp, tmp2 + y);
140
RROP_SOLID24(yorghb + xoffset + xtmp, tmp2 + y);
142
MIARCCIRCLESTEP(yoffset += npwidth;);
145
PixelType *yorghb = yorgp + (info.h * npwidth) + info.xorg;
146
PixelType *yorgohb = yorghb - info.h;
153
RROP_SOLID(yorgp + yoffset + x);
154
RROP_SOLID(yorgp + yoffset - x);
155
RROP_SOLID(yorgop - yoffset - x);
156
RROP_SOLID(yorgop - yoffset + x);
159
RROP_SOLID(yorghb - xoffset - y);
160
RROP_SOLID(yorgohb - xoffset + y);
161
RROP_SOLID(yorgohb + xoffset + y);
162
RROP_SOLID(yorghb + xoffset - y);
164
MIARCCIRCLESTEP(yoffset += npwidth;);
168
#endif /* PSZ == 24 */
170
yoffset = info.h * npwidth;
174
while (y < info.h || x < info.w)
176
MIARCOCTANTSHIFT(dyoffset = npwidth;);
178
xtmp = (xorg3 + x * 3) >> 2;
179
RROP_SOLID24(yorgp + yoffset + xtmp, xorg + x);
180
RROP_SOLID24(yorgop - yoffset + xtmp, xorg + x);
181
xtmp = (xorgo3 - x * 3) >> 2;
182
RROP_SOLID24(yorgp + yoffset + xtmp, xorgo - x);
183
RROP_SOLID24(yorgop - yoffset + xtmp, xorgo - x);
185
RROP_SOLID(yorgp + yoffset + info.xorg + x);
186
RROP_SOLID(yorgp + yoffset + info.xorgo - x);
187
RROP_SOLID(yorgop - yoffset + info.xorgo - x);
188
RROP_SOLID(yorgop - yoffset + info.xorg + x);
190
MIARCSTEP(yoffset += dyoffset;, yoffset += npwidth;);
195
while (y < info.h || x < info.w)
197
MIARCOCTANTSHIFT(dyoffset = npwidth;);
198
if ((x == info.start.x) || (y == info.start.y))
200
mask = info.start.mask;
201
info.start = info.altstart;
205
xtmp = (xorg3 + x * 3) >> 2;
206
RROP_SOLID24(yorgp + yoffset + xtmp, xorg + x);
209
xtmp = (xorgo3 - x * 3) >> 2;
210
RROP_SOLID24(yorgp + yoffset + xtmp, xorgo - x);
213
xtmp = (xorgo3 - x * 3) >> 2;
214
RROP_SOLID24(yorgop - yoffset + xtmp, xorgo - x);
217
xtmp = (xorg3 + x * 3) >> 2;
218
RROP_SOLID24(yorgop - yoffset + xtmp, xorg + x);
222
RROP_SOLID(yorgp + yoffset + info.xorg + x);
224
RROP_SOLID(yorgp + yoffset + info.xorgo - x);
226
RROP_SOLID(yorgop - yoffset + info.xorgo - x);
228
RROP_SOLID(yorgop - yoffset + info.xorg + x);
229
#endif /* PSZ == 24 */
230
if ((x == info.end.x) || (y == info.end.y))
232
mask = info.end.mask;
233
info.end = info.altend;
235
MIARCSTEP(yoffset += dyoffset;, yoffset += npwidth;);
238
if ((x == info.start.x) || (y == info.start.y))
239
mask = info.start.mask;
242
xtmp = (xorg3 + x * 3) >> 2;
243
RROP_SOLID24(yorgp + yoffset + xtmp, xorg + x);
246
xtmp = (xorgo3 - x * 3) >> 2;
247
RROP_SOLID24(yorgop - yoffset + xtmp, xorgo - x);
251
RROP_SOLID(yorgp + yoffset + info.xorg + x);
253
RROP_SOLID(yorgop - yoffset + info.xorgo - x);
254
#endif /* PSZ == 24 */
259
xtmp = (xorgo3 - x * 3) >> 2;
260
RROP_SOLID24(yorgp + yoffset + xtmp, xorgo - x);
263
xtmp = (xorg3 + x * 3) >> 2;
264
RROP_SOLID24(yorgop - yoffset + xtmp, xorg + x);
268
RROP_SOLID(yorgp + yoffset + info.xorgo - x);
270
RROP_SOLID(yorgop - yoffset + info.xorg + x);
271
#endif /* PSZ == 24 */
277
RROP_NAME (cfbZeroPolyArcSS8) (pDraw, pGC, narcs, parcs)
278
register DrawablePtr pDraw;
289
cclip = cfbGetCompositeClip(pGC);
290
for (arc = parcs, i = narcs; --i >= 0; arc++)
292
if (miCanZeroArc(arc))
294
box.x1 = arc->x + pDraw->x;
295
box.y1 = arc->y + pDraw->y;
297
* Because box.x2 and box.y2 get truncated to 16 bits, and the
298
* RECT_IN_REGION test treats the resulting number as a signed
299
* integer, the RECT_IN_REGION test alone can go the wrong way.
300
* This can result in a server crash because the rendering
301
* routines in this file deal directly with cpu addresses
302
* of pixels to be stored, and do not clip or otherwise check
303
* that all such addresses are within their respective pixmaps.
304
* So we only allow the RECT_IN_REGION test to be used for
305
* values that can be expressed correctly in a signed short.
307
x2 = box.x1 + (int)arc->width + 1;
309
y2 = box.y1 + (int)arc->height + 1;
311
if ( (x2 <= MAXSHORT) && (y2 <= MAXSHORT) &&
312
(RECT_IN_REGION(pDraw->pScreen, cclip, &box) == rgnIN) )
313
RROP_NAME (cfbZeroArcSS8) (pDraw, pGC, arc);
315
miZeroPolyArc(pDraw, pGC, 1, arc);
318
miPolyArc(pDraw, pGC, 1, arc);