mga_arc.c revision 0bb88ba4
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#ifdef HAVE_CONFIG_H
28#include "config.h"
29#endif
30
31#include <limits.h>
32#include <X11/X.h>
33#include "gcstruct.h"
34#include "windowstr.h"
35#include "pixmapstr.h"
36#include "regionstr.h"
37#include <X11/Xprotostr.h>
38#include "regionstr.h"
39#include "mizerarc.h"
40#include "mi.h"
41#include "scrnintstr.h"
42#ifdef HAVE_XAA_H
43#include "xaa.h"
44#include "xaalocal.h"
45#endif
46#include "xf86.h"
47#include "xf86_OSproc.h"
48
49#include "xf86Pci.h"
50
51#include "mga.h"
52#include "mga_reg.h"
53#include "mga_macros.h"
54
55
56#define DRAW_POINT(x, y) { \
57	tmp = x; \
58	OUTREG(MGAREG_FXBNDRY, (tmp) | (((tmp) + 1) << 16)); \
59	OUTREG(MGAREG_YDSTLEN + MGAREG_EXEC, ((y) << 16) | 1); \
60}
61
62static void
63MGAZeroArc(
64    DrawablePtr pDraw,
65    GCPtr pGC,
66    xArc *arc
67){
68    int yoffset, dyoffset, x, y, a, b, d, mask, k1, k3, dx, dy, tmp;
69    XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_GC(pGC);
70    ScrnInfoPtr pScrn = infoRec->pScrn;
71    MGAPtr pMga = MGAPTR(pScrn);
72    miZeroArcRec info;
73    Bool do360;
74    DDXPointRec org, orgo;
75
76    CHECK_DMA_QUIESCENT( pMga, infoRec->pScrn );
77
78    (*infoRec->SetupForSolidFill)(infoRec->pScrn, pGC->fgPixel,
79		pGC->alu, pGC->planemask);
80
81    do360 = miZeroArcSetup(arc, &info, TRUE);
82    org.y = info.yorg + pDraw->y;
83    org.x = 0;
84    orgo.y = info.yorgo + pDraw->y;
85    orgo.x = 0;
86    info.xorg += pDraw->x;
87    info.xorgo += pDraw->x;
88
89    MIARCSETUP();
90    yoffset = y ? 1 : 0;
91    dyoffset = 0;
92    mask = info.initialMask;
93    if (!(arc->width & 1)) {
94	WAITFIFO(4);
95	if (mask & 2)
96	    DRAW_POINT(info.xorgo, org.y);
97	if (mask & 8)
98	    DRAW_POINT(info.xorgo, orgo.y);
99    }
100    if (!info.end.x || !info.end.y) {
101	mask = info.end.mask;
102	info.end = info.altend;
103    }
104    if (do360 && (arc->width == arc->height) && !(arc->width & 1)) {
105        int xoffset = 1;
106	DDXPointRec orghb, orgohb;
107
108	orghb.y = org.y + info.h;
109	orghb.x = org.x + info.xorg;
110	orgohb.y = orghb.y;
111	orgohb.x = orghb.x - info.h;
112
113	org.x += info.xorg;
114	orgo.x += info.xorg;
115	orghb.x += info.h;
116	while (1) {
117	    WAITFIFO(16);
118	    DRAW_POINT(org.x + x, org.y + yoffset);
119	    DRAW_POINT(org.x - x, org.y + yoffset);
120	    DRAW_POINT(orgo.x - x, orgo.y - yoffset);
121	    DRAW_POINT(orgo.x + x, orgo.y - yoffset);
122	    if (a < 0) break;
123	    DRAW_POINT(orghb.x - y, orghb.y - xoffset);
124	    DRAW_POINT(orgohb.x + y, orgohb.y - xoffset);
125	    DRAW_POINT(orgohb.x + y, orgohb.y + xoffset);
126	    DRAW_POINT(orghb.x - y, orghb.y + xoffset);
127	    xoffset ++;
128	    MIARCCIRCLESTEP(yoffset ++;);
129	}
130	org.x -= info.xorg;
131	orgo.x -= info.xorg;
132	x = info.w;
133	yoffset = info.h;
134    }
135    else if (do360) {
136	while (y < info.h || x < info.w) {
137	    MIARCOCTANTSHIFT(dyoffset = 1;);
138	    WAITFIFO(8);
139	    DRAW_POINT(org.x + info.xorg + x, org.y + yoffset);
140	    DRAW_POINT(org.x + info.xorgo - x, org.y + yoffset);
141	    DRAW_POINT(orgo.x + info.xorgo - x, orgo.y - yoffset);
142	    DRAW_POINT(orgo.x + info.xorg + x, orgo.y - yoffset);
143	    MIARCSTEP(yoffset += dyoffset;, yoffset++;);
144	}
145    }
146    else {
147	while (y < info.h || x < info.w) {
148	    MIARCOCTANTSHIFT(dyoffset = 1;);
149	    if ((x == info.start.x) || (y == info.start.y)) {
150		mask = info.start.mask;
151		info.start = info.altstart;
152	    }
153	    WAITFIFO(8);
154	    if (mask & 1)
155		DRAW_POINT(org.x + info.xorg + x, org.y + yoffset);
156	    if (mask & 2)
157		DRAW_POINT(org.x + info.xorgo - x, org.y + yoffset);
158	    if (mask & 4)
159		DRAW_POINT(orgo.x + info.xorgo - x, orgo.y - yoffset);
160	    if (mask & 8)
161		DRAW_POINT(orgo.x + info.xorg + x, orgo.y - yoffset);
162	    if ((x == info.end.x) || (y == info.end.y)) {
163		mask = info.end.mask;
164		info.end = info.altend;
165	    }
166	    MIARCSTEP(yoffset += dyoffset;, yoffset++;);
167	}
168    }
169    if ((x == info.start.x) || (y == info.start.y))
170	mask = info.start.mask;
171
172    WAITFIFO(4);
173    if (mask & 1)
174	DRAW_POINT(org.x + info.xorg + x, org.y + yoffset);
175    if (mask & 4)
176	DRAW_POINT(orgo.x + info.xorgo - x, orgo.y - yoffset);
177    if (arc->height & 1) {
178	WAITFIFO(4);
179	if (mask & 2)
180	    DRAW_POINT(org.x + info.xorgo - x, org.y + yoffset);
181	if (mask & 8)
182	    DRAW_POINT(orgo.x + info.xorg + x, orgo.y - yoffset);
183    }
184
185    SET_SYNC_FLAG(infoRec);
186}
187
188void
189MGAPolyArcThinSolid (
190    DrawablePtr	pDraw,
191    GCPtr	pGC,
192    int		narcs,
193    xArc	*parcs
194){
195    xArc *arc;
196    BoxRec box;
197    int i, x2, y2;
198    RegionPtr cclip;
199
200    cclip = pGC->pCompositeClip;
201
202    if(!REGION_NUM_RECTS(cclip))
203	return;
204
205    for (arc = parcs, i = narcs; --i >= 0; arc++) {
206	if (miCanZeroArc(arc)) {
207	    box.x1 = arc->x + pDraw->x;
208	    box.y1 = arc->y + pDraw->y;
209 	    x2 = box.x1 + (int)arc->width + 1;
210 	    box.x2 = x2;
211 	    y2 = box.y1 + (int)arc->height + 1;
212 	    box.y2 = y2;
213 	    if ( (x2 <= SHRT_MAX) && (y2 <= SHRT_MAX) &&
214 		    (RECT_IN_REGION(pDraw->pScreen, cclip, &box) == rgnIN) )
215		MGAZeroArc (pDraw, pGC, arc);
216	    else
217		miZeroPolyArc(pDraw, pGC, 1, arc);
218	}
219	else
220	    miPolyArc(pDraw, pGC, 1, arc);
221    }
222}
223
224