mga_arc.c revision 0bb88ba4
1fe5e51b7Smrg/************************************************************
2fe5e51b7Smrg
3fe5e51b7SmrgCopyright 1989, 1998  The Open Group
4fe5e51b7Smrg
5fe5e51b7SmrgPermission to use, copy, modify, distribute, and sell this software and its
6fe5e51b7Smrgdocumentation for any purpose is hereby granted without fee, provided that
7fe5e51b7Smrgthe above copyright notice appear in all copies and that both that
8fe5e51b7Smrgcopyright notice and this permission notice appear in supporting
9fe5e51b7Smrgdocumentation.
10fe5e51b7Smrg
11fe5e51b7SmrgThe above copyright notice and this permission notice shall be included in
12fe5e51b7Smrgall copies or substantial portions of the Software.
13fe5e51b7Smrg
14fe5e51b7SmrgTHE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15fe5e51b7SmrgIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16fe5e51b7SmrgFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
17fe5e51b7SmrgOPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
18fe5e51b7SmrgAN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
19fe5e51b7SmrgCONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
20fe5e51b7Smrg
21fe5e51b7SmrgExcept as contained in this notice, the name of The Open Group shall not be
22fe5e51b7Smrgused in advertising or otherwise to promote the sale, use or other dealings
23fe5e51b7Smrgin this Software without prior written authorization from The Open Group.
24fe5e51b7Smrg
25fe5e51b7Smrg********************************************************/
26fe5e51b7Smrg
27fe5e51b7Smrg#ifdef HAVE_CONFIG_H
28fe5e51b7Smrg#include "config.h"
29fe5e51b7Smrg#endif
30fe5e51b7Smrg
31fe5e51b7Smrg#include <limits.h>
32fe5e51b7Smrg#include <X11/X.h>
33fe5e51b7Smrg#include "gcstruct.h"
34fe5e51b7Smrg#include "windowstr.h"
35fe5e51b7Smrg#include "pixmapstr.h"
36fe5e51b7Smrg#include "regionstr.h"
37fe5e51b7Smrg#include <X11/Xprotostr.h>
38fe5e51b7Smrg#include "regionstr.h"
39fe5e51b7Smrg#include "mizerarc.h"
40fe5e51b7Smrg#include "mi.h"
41fe5e51b7Smrg#include "scrnintstr.h"
420bb88ba4Smrg#ifdef HAVE_XAA_H
43fe5e51b7Smrg#include "xaa.h"
44fe5e51b7Smrg#include "xaalocal.h"
450bb88ba4Smrg#endif
46fe5e51b7Smrg#include "xf86.h"
47fe5e51b7Smrg#include "xf86_OSproc.h"
48fe5e51b7Smrg
49fe5e51b7Smrg#include "xf86Pci.h"
50fe5e51b7Smrg
51fe5e51b7Smrg#include "mga.h"
52fe5e51b7Smrg#include "mga_reg.h"
53fe5e51b7Smrg#include "mga_macros.h"
54fe5e51b7Smrg
55fe5e51b7Smrg
56fe5e51b7Smrg#define DRAW_POINT(x, y) { \
57fe5e51b7Smrg	tmp = x; \
58fe5e51b7Smrg	OUTREG(MGAREG_FXBNDRY, (tmp) | (((tmp) + 1) << 16)); \
59fe5e51b7Smrg	OUTREG(MGAREG_YDSTLEN + MGAREG_EXEC, ((y) << 16) | 1); \
60fe5e51b7Smrg}
61fe5e51b7Smrg
62fe5e51b7Smrgstatic void
63fe5e51b7SmrgMGAZeroArc(
64fe5e51b7Smrg    DrawablePtr pDraw,
65fe5e51b7Smrg    GCPtr pGC,
66fe5e51b7Smrg    xArc *arc
67fe5e51b7Smrg){
68fe5e51b7Smrg    int yoffset, dyoffset, x, y, a, b, d, mask, k1, k3, dx, dy, tmp;
69fe5e51b7Smrg    XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_GC(pGC);
70fe5e51b7Smrg    ScrnInfoPtr pScrn = infoRec->pScrn;
71fe5e51b7Smrg    MGAPtr pMga = MGAPTR(pScrn);
72fe5e51b7Smrg    miZeroArcRec info;
73fe5e51b7Smrg    Bool do360;
74fe5e51b7Smrg    DDXPointRec org, orgo;
75fe5e51b7Smrg
76fe5e51b7Smrg    CHECK_DMA_QUIESCENT( pMga, infoRec->pScrn );
77fe5e51b7Smrg
78fe5e51b7Smrg    (*infoRec->SetupForSolidFill)(infoRec->pScrn, pGC->fgPixel,
79fe5e51b7Smrg		pGC->alu, pGC->planemask);
80fe5e51b7Smrg
81fe5e51b7Smrg    do360 = miZeroArcSetup(arc, &info, TRUE);
82fe5e51b7Smrg    org.y = info.yorg + pDraw->y;
83fe5e51b7Smrg    org.x = 0;
84fe5e51b7Smrg    orgo.y = info.yorgo + pDraw->y;
85fe5e51b7Smrg    orgo.x = 0;
86fe5e51b7Smrg    info.xorg += pDraw->x;
87fe5e51b7Smrg    info.xorgo += pDraw->x;
88fe5e51b7Smrg
89fe5e51b7Smrg    MIARCSETUP();
90fe5e51b7Smrg    yoffset = y ? 1 : 0;
91fe5e51b7Smrg    dyoffset = 0;
92fe5e51b7Smrg    mask = info.initialMask;
93fe5e51b7Smrg    if (!(arc->width & 1)) {
94fe5e51b7Smrg	WAITFIFO(4);
95fe5e51b7Smrg	if (mask & 2)
96fe5e51b7Smrg	    DRAW_POINT(info.xorgo, org.y);
97fe5e51b7Smrg	if (mask & 8)
98fe5e51b7Smrg	    DRAW_POINT(info.xorgo, orgo.y);
99fe5e51b7Smrg    }
100fe5e51b7Smrg    if (!info.end.x || !info.end.y) {
101fe5e51b7Smrg	mask = info.end.mask;
102fe5e51b7Smrg	info.end = info.altend;
103fe5e51b7Smrg    }
104fe5e51b7Smrg    if (do360 && (arc->width == arc->height) && !(arc->width & 1)) {
105fe5e51b7Smrg        int xoffset = 1;
106fe5e51b7Smrg	DDXPointRec orghb, orgohb;
107fe5e51b7Smrg
108fe5e51b7Smrg	orghb.y = org.y + info.h;
109fe5e51b7Smrg	orghb.x = org.x + info.xorg;
110fe5e51b7Smrg	orgohb.y = orghb.y;
111fe5e51b7Smrg	orgohb.x = orghb.x - info.h;
112fe5e51b7Smrg
113fe5e51b7Smrg	org.x += info.xorg;
114fe5e51b7Smrg	orgo.x += info.xorg;
115fe5e51b7Smrg	orghb.x += info.h;
116fe5e51b7Smrg	while (1) {
117fe5e51b7Smrg	    WAITFIFO(16);
118fe5e51b7Smrg	    DRAW_POINT(org.x + x, org.y + yoffset);
119fe5e51b7Smrg	    DRAW_POINT(org.x - x, org.y + yoffset);
120fe5e51b7Smrg	    DRAW_POINT(orgo.x - x, orgo.y - yoffset);
121fe5e51b7Smrg	    DRAW_POINT(orgo.x + x, orgo.y - yoffset);
122fe5e51b7Smrg	    if (a < 0) break;
123fe5e51b7Smrg	    DRAW_POINT(orghb.x - y, orghb.y - xoffset);
124fe5e51b7Smrg	    DRAW_POINT(orgohb.x + y, orgohb.y - xoffset);
125fe5e51b7Smrg	    DRAW_POINT(orgohb.x + y, orgohb.y + xoffset);
126fe5e51b7Smrg	    DRAW_POINT(orghb.x - y, orghb.y + xoffset);
127fe5e51b7Smrg	    xoffset ++;
128fe5e51b7Smrg	    MIARCCIRCLESTEP(yoffset ++;);
129fe5e51b7Smrg	}
130fe5e51b7Smrg	org.x -= info.xorg;
131fe5e51b7Smrg	orgo.x -= info.xorg;
132fe5e51b7Smrg	x = info.w;
133fe5e51b7Smrg	yoffset = info.h;
134fe5e51b7Smrg    }
135fe5e51b7Smrg    else if (do360) {
136fe5e51b7Smrg	while (y < info.h || x < info.w) {
137fe5e51b7Smrg	    MIARCOCTANTSHIFT(dyoffset = 1;);
138fe5e51b7Smrg	    WAITFIFO(8);
139fe5e51b7Smrg	    DRAW_POINT(org.x + info.xorg + x, org.y + yoffset);
140fe5e51b7Smrg	    DRAW_POINT(org.x + info.xorgo - x, org.y + yoffset);
141fe5e51b7Smrg	    DRAW_POINT(orgo.x + info.xorgo - x, orgo.y - yoffset);
142fe5e51b7Smrg	    DRAW_POINT(orgo.x + info.xorg + x, orgo.y - yoffset);
143fe5e51b7Smrg	    MIARCSTEP(yoffset += dyoffset;, yoffset++;);
144fe5e51b7Smrg	}
145fe5e51b7Smrg    }
146fe5e51b7Smrg    else {
147fe5e51b7Smrg	while (y < info.h || x < info.w) {
148fe5e51b7Smrg	    MIARCOCTANTSHIFT(dyoffset = 1;);
149fe5e51b7Smrg	    if ((x == info.start.x) || (y == info.start.y)) {
150fe5e51b7Smrg		mask = info.start.mask;
151fe5e51b7Smrg		info.start = info.altstart;
152fe5e51b7Smrg	    }
153fe5e51b7Smrg	    WAITFIFO(8);
154fe5e51b7Smrg	    if (mask & 1)
155fe5e51b7Smrg		DRAW_POINT(org.x + info.xorg + x, org.y + yoffset);
156fe5e51b7Smrg	    if (mask & 2)
157fe5e51b7Smrg		DRAW_POINT(org.x + info.xorgo - x, org.y + yoffset);
158fe5e51b7Smrg	    if (mask & 4)
159fe5e51b7Smrg		DRAW_POINT(orgo.x + info.xorgo - x, orgo.y - yoffset);
160fe5e51b7Smrg	    if (mask & 8)
161fe5e51b7Smrg		DRAW_POINT(orgo.x + info.xorg + x, orgo.y - yoffset);
162fe5e51b7Smrg	    if ((x == info.end.x) || (y == info.end.y)) {
163fe5e51b7Smrg		mask = info.end.mask;
164fe5e51b7Smrg		info.end = info.altend;
165fe5e51b7Smrg	    }
166fe5e51b7Smrg	    MIARCSTEP(yoffset += dyoffset;, yoffset++;);
167fe5e51b7Smrg	}
168fe5e51b7Smrg    }
169fe5e51b7Smrg    if ((x == info.start.x) || (y == info.start.y))
170fe5e51b7Smrg	mask = info.start.mask;
171fe5e51b7Smrg
172fe5e51b7Smrg    WAITFIFO(4);
173fe5e51b7Smrg    if (mask & 1)
174fe5e51b7Smrg	DRAW_POINT(org.x + info.xorg + x, org.y + yoffset);
175fe5e51b7Smrg    if (mask & 4)
176fe5e51b7Smrg	DRAW_POINT(orgo.x + info.xorgo - x, orgo.y - yoffset);
177fe5e51b7Smrg    if (arc->height & 1) {
178fe5e51b7Smrg	WAITFIFO(4);
179fe5e51b7Smrg	if (mask & 2)
180fe5e51b7Smrg	    DRAW_POINT(org.x + info.xorgo - x, org.y + yoffset);
181fe5e51b7Smrg	if (mask & 8)
182fe5e51b7Smrg	    DRAW_POINT(orgo.x + info.xorg + x, orgo.y - yoffset);
183fe5e51b7Smrg    }
184fe5e51b7Smrg
185fe5e51b7Smrg    SET_SYNC_FLAG(infoRec);
186fe5e51b7Smrg}
187fe5e51b7Smrg
188fe5e51b7Smrgvoid
189fe5e51b7SmrgMGAPolyArcThinSolid (
190fe5e51b7Smrg    DrawablePtr	pDraw,
191fe5e51b7Smrg    GCPtr	pGC,
192fe5e51b7Smrg    int		narcs,
193fe5e51b7Smrg    xArc	*parcs
194fe5e51b7Smrg){
195fe5e51b7Smrg    xArc *arc;
196fe5e51b7Smrg    BoxRec box;
197fe5e51b7Smrg    int i, x2, y2;
198fe5e51b7Smrg    RegionPtr cclip;
199fe5e51b7Smrg
200fe5e51b7Smrg    cclip = pGC->pCompositeClip;
201fe5e51b7Smrg
202fe5e51b7Smrg    if(!REGION_NUM_RECTS(cclip))
203fe5e51b7Smrg	return;
204fe5e51b7Smrg
205fe5e51b7Smrg    for (arc = parcs, i = narcs; --i >= 0; arc++) {
206fe5e51b7Smrg	if (miCanZeroArc(arc)) {
207fe5e51b7Smrg	    box.x1 = arc->x + pDraw->x;
208fe5e51b7Smrg	    box.y1 = arc->y + pDraw->y;
209fe5e51b7Smrg 	    x2 = box.x1 + (int)arc->width + 1;
210fe5e51b7Smrg 	    box.x2 = x2;
211fe5e51b7Smrg 	    y2 = box.y1 + (int)arc->height + 1;
212fe5e51b7Smrg 	    box.y2 = y2;
213fe5e51b7Smrg 	    if ( (x2 <= SHRT_MAX) && (y2 <= SHRT_MAX) &&
214fe5e51b7Smrg 		    (RECT_IN_REGION(pDraw->pScreen, cclip, &box) == rgnIN) )
215fe5e51b7Smrg		MGAZeroArc (pDraw, pGC, arc);
216fe5e51b7Smrg	    else
217fe5e51b7Smrg		miZeroPolyArc(pDraw, pGC, 1, arc);
218fe5e51b7Smrg	}
219fe5e51b7Smrg	else
220fe5e51b7Smrg	    miPolyArc(pDraw, pGC, 1, arc);
221fe5e51b7Smrg    }
222fe5e51b7Smrg}
223fe5e51b7Smrg
224