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