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