1428d7b3dSmrg/* 2428d7b3dSmrg * Copyright © 1998 Keith Packard 3428d7b3dSmrg * Copyright © 2012 Intel Corporation 4428d7b3dSmrg * 5428d7b3dSmrg * Permission to use, copy, modify, distribute, and sell this software and its 6428d7b3dSmrg * documentation for any purpose is hereby granted without fee, provided that 7428d7b3dSmrg * the above copyright notice appear in all copies and that both that 8428d7b3dSmrg * copyright notice and this permission notice appear in supporting 9428d7b3dSmrg * documentation, and that the name of Keith Packard not be used in 10428d7b3dSmrg * advertising or publicity pertaining to distribution of the software without 11428d7b3dSmrg * specific, written prior permission. Keith Packard makes no 12428d7b3dSmrg * representations about the suitability of this software for any purpose. It 13428d7b3dSmrg * is provided "as is" without express or implied warranty. 14428d7b3dSmrg * 15428d7b3dSmrg * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, 16428d7b3dSmrg * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO 17428d7b3dSmrg * EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR 18428d7b3dSmrg * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, 19428d7b3dSmrg * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER 20428d7b3dSmrg * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 21428d7b3dSmrg * PERFORMANCE OF THIS SOFTWARE. 22428d7b3dSmrg */ 23428d7b3dSmrg 24428d7b3dSmrg#define isClipped(c,ul,lr) (((c) | ((c) - (ul)) | ((lr) - (c))) & 0x80008000) 25428d7b3dSmrg#define RROP(b,a,x) WRITE((b), FbDoRRop (READ(b), (a), (x))) 26428d7b3dSmrg 27428d7b3dSmrg#define ARCCOPY(d) WRITE(d,xorBits) 28428d7b3dSmrg#define ARCRROP(d) RROP(d,andBits,xorBits) 29428d7b3dSmrg 30428d7b3dSmrgstatic void 31428d7b3dSmrgARC(FbBits * dst, 32428d7b3dSmrg FbStride dstStride, 33428d7b3dSmrg int dstBpp, xArc * arc, int drawX, int drawY, FbBits and, FbBits xor) 34428d7b3dSmrg{ 35428d7b3dSmrg BITS *bits; 36428d7b3dSmrg FbStride bitsStride; 37428d7b3dSmrg miZeroArcRec info; 38428d7b3dSmrg Bool do360; 39428d7b3dSmrg int x; 40428d7b3dSmrg BITS *yorgp, *yorgop; 41428d7b3dSmrg BITS andBits, xorBits; 42428d7b3dSmrg int yoffset, dyoffset; 43428d7b3dSmrg int y, a, b, d, mask; 44428d7b3dSmrg int k1, k3, dx, dy; 45428d7b3dSmrg 46428d7b3dSmrg bits = (BITS *) dst; 47428d7b3dSmrg bitsStride = dstStride * (sizeof(FbBits) / sizeof(BITS)); 48428d7b3dSmrg andBits = (BITS) and; 49428d7b3dSmrg xorBits = (BITS) xor; 50428d7b3dSmrg do360 = miZeroArcSetup(arc, &info, TRUE); 51428d7b3dSmrg yorgp = bits + ((info.yorg + drawY) * bitsStride); 52428d7b3dSmrg yorgop = bits + ((info.yorgo + drawY) * bitsStride); 53428d7b3dSmrg info.xorg = (info.xorg + drawX); 54428d7b3dSmrg info.xorgo = (info.xorgo + drawX); 55428d7b3dSmrg MIARCSETUP(); 56428d7b3dSmrg yoffset = y ? bitsStride : 0; 57428d7b3dSmrg dyoffset = 0; 58428d7b3dSmrg mask = info.initialMask; 59428d7b3dSmrg 60428d7b3dSmrg if (!(arc->width & 1)) { 61428d7b3dSmrg if (andBits == 0) { 62428d7b3dSmrg if (mask & 2) 63428d7b3dSmrg ARCCOPY(yorgp + info.xorgo); 64428d7b3dSmrg if (mask & 8) 65428d7b3dSmrg ARCCOPY(yorgop + info.xorgo); 66428d7b3dSmrg } else { 67428d7b3dSmrg if (mask & 2) 68428d7b3dSmrg ARCRROP(yorgp + info.xorgo); 69428d7b3dSmrg if (mask & 8) 70428d7b3dSmrg ARCRROP(yorgop + info.xorgo); 71428d7b3dSmrg } 72428d7b3dSmrg } 73428d7b3dSmrg if (!info.end.x || !info.end.y) { 74428d7b3dSmrg mask = info.end.mask; 75428d7b3dSmrg info.end = info.altend; 76428d7b3dSmrg } 77428d7b3dSmrg if (do360 && (arc->width == arc->height) && !(arc->width & 1)) { 78428d7b3dSmrg int xoffset = bitsStride; 79428d7b3dSmrg BITS *yorghb = yorgp + (info.h * bitsStride) + info.xorg; 80428d7b3dSmrg BITS *yorgohb = yorghb - info.h; 81428d7b3dSmrg 82428d7b3dSmrg yorgp += info.xorg; 83428d7b3dSmrg yorgop += info.xorg; 84428d7b3dSmrg yorghb += info.h; 85428d7b3dSmrg while (1) { 86428d7b3dSmrg if (andBits == 0) { 87428d7b3dSmrg ARCCOPY(yorgp + yoffset + x); 88428d7b3dSmrg ARCCOPY(yorgp + yoffset - x); 89428d7b3dSmrg ARCCOPY(yorgop - yoffset - x); 90428d7b3dSmrg ARCCOPY(yorgop - yoffset + x); 91428d7b3dSmrg } else { 92428d7b3dSmrg ARCRROP(yorgp + yoffset + x); 93428d7b3dSmrg ARCRROP(yorgp + yoffset - x); 94428d7b3dSmrg ARCRROP(yorgop - yoffset - x); 95428d7b3dSmrg ARCRROP(yorgop - yoffset + x); 96428d7b3dSmrg } 97428d7b3dSmrg if (a < 0) 98428d7b3dSmrg break; 99428d7b3dSmrg if (andBits == 0) { 100428d7b3dSmrg ARCCOPY(yorghb - xoffset - y); 101428d7b3dSmrg ARCCOPY(yorgohb - xoffset + y); 102428d7b3dSmrg ARCCOPY(yorgohb + xoffset + y); 103428d7b3dSmrg ARCCOPY(yorghb + xoffset - y); 104428d7b3dSmrg } else { 105428d7b3dSmrg ARCRROP(yorghb - xoffset - y); 106428d7b3dSmrg ARCRROP(yorgohb - xoffset + y); 107428d7b3dSmrg ARCRROP(yorgohb + xoffset + y); 108428d7b3dSmrg ARCRROP(yorghb + xoffset - y); 109428d7b3dSmrg } 110428d7b3dSmrg xoffset += bitsStride; 111428d7b3dSmrg MIARCCIRCLESTEP(yoffset += bitsStride; 112428d7b3dSmrg ); 113428d7b3dSmrg } 114428d7b3dSmrg yorgp -= info.xorg; 115428d7b3dSmrg yorgop -= info.xorg; 116428d7b3dSmrg x = info.w; 117428d7b3dSmrg yoffset = info.h * bitsStride; 118428d7b3dSmrg } else if (do360) { 119428d7b3dSmrg while (y < info.h || x < info.w) { 120428d7b3dSmrg MIARCOCTANTSHIFT(dyoffset = bitsStride; 121428d7b3dSmrg ); 122428d7b3dSmrg if (andBits == 0) { 123428d7b3dSmrg ARCCOPY(yorgp + yoffset + info.xorg + x); 124428d7b3dSmrg ARCCOPY(yorgp + yoffset + info.xorgo - x); 125428d7b3dSmrg ARCCOPY(yorgop - yoffset + info.xorgo - x); 126428d7b3dSmrg ARCCOPY(yorgop - yoffset + info.xorg + x); 127428d7b3dSmrg } else { 128428d7b3dSmrg ARCRROP(yorgp + yoffset + info.xorg + x); 129428d7b3dSmrg ARCRROP(yorgp + yoffset + info.xorgo - x); 130428d7b3dSmrg ARCRROP(yorgop - yoffset + info.xorgo - x); 131428d7b3dSmrg ARCRROP(yorgop - yoffset + info.xorg + x); 132428d7b3dSmrg } 133428d7b3dSmrg MIARCSTEP(yoffset += dyoffset; 134428d7b3dSmrg , yoffset += bitsStride; 135428d7b3dSmrg ); 136428d7b3dSmrg } 137428d7b3dSmrg } else { 138428d7b3dSmrg while (y < info.h || x < info.w) { 139428d7b3dSmrg MIARCOCTANTSHIFT(dyoffset = bitsStride; 140428d7b3dSmrg ); 141428d7b3dSmrg if ((x == info.start.x) || (y == info.start.y)) { 142428d7b3dSmrg mask = info.start.mask; 143428d7b3dSmrg info.start = info.altstart; 144428d7b3dSmrg } 145428d7b3dSmrg if (andBits == 0) { 146428d7b3dSmrg if (mask & 1) 147428d7b3dSmrg ARCCOPY(yorgp + yoffset + info.xorg + x); 148428d7b3dSmrg if (mask & 2) 149428d7b3dSmrg ARCCOPY(yorgp + yoffset + info.xorgo - x); 150428d7b3dSmrg if (mask & 4) 151428d7b3dSmrg ARCCOPY(yorgop - yoffset + info.xorgo - x); 152428d7b3dSmrg if (mask & 8) 153428d7b3dSmrg ARCCOPY(yorgop - yoffset + info.xorg + x); 154428d7b3dSmrg } else { 155428d7b3dSmrg if (mask & 1) 156428d7b3dSmrg ARCRROP(yorgp + yoffset + info.xorg + x); 157428d7b3dSmrg if (mask & 2) 158428d7b3dSmrg ARCRROP(yorgp + yoffset + info.xorgo - x); 159428d7b3dSmrg if (mask & 4) 160428d7b3dSmrg ARCRROP(yorgop - yoffset + info.xorgo - x); 161428d7b3dSmrg if (mask & 8) 162428d7b3dSmrg ARCRROP(yorgop - yoffset + info.xorg + x); 163428d7b3dSmrg } 164428d7b3dSmrg if ((x == info.end.x) || (y == info.end.y)) { 165428d7b3dSmrg mask = info.end.mask; 166428d7b3dSmrg info.end = info.altend; 167428d7b3dSmrg } 168428d7b3dSmrg MIARCSTEP(yoffset += dyoffset; 169428d7b3dSmrg , yoffset += bitsStride; 170428d7b3dSmrg ); 171428d7b3dSmrg } 172428d7b3dSmrg } 173428d7b3dSmrg if ((x == info.start.x) || (y == info.start.y)) 174428d7b3dSmrg mask = info.start.mask; 175428d7b3dSmrg if (andBits == 0) { 176428d7b3dSmrg if (mask & 1) 177428d7b3dSmrg ARCCOPY(yorgp + yoffset + info.xorg + x); 178428d7b3dSmrg if (mask & 4) 179428d7b3dSmrg ARCCOPY(yorgop - yoffset + info.xorgo - x); 180428d7b3dSmrg if (arc->height & 1) { 181428d7b3dSmrg if (mask & 2) 182428d7b3dSmrg ARCCOPY(yorgp + yoffset + info.xorgo - x); 183428d7b3dSmrg if (mask & 8) 184428d7b3dSmrg ARCCOPY(yorgop - yoffset + info.xorg + x); 185428d7b3dSmrg } 186428d7b3dSmrg } else { 187428d7b3dSmrg if (mask & 1) 188428d7b3dSmrg ARCRROP(yorgp + yoffset + info.xorg + x); 189428d7b3dSmrg if (mask & 4) 190428d7b3dSmrg ARCRROP(yorgop - yoffset + info.xorgo - x); 191428d7b3dSmrg if (arc->height & 1) { 192428d7b3dSmrg if (mask & 2) 193428d7b3dSmrg ARCRROP(yorgp + yoffset + info.xorgo - x); 194428d7b3dSmrg if (mask & 8) 195428d7b3dSmrg ARCRROP(yorgop - yoffset + info.xorg + x); 196428d7b3dSmrg } 197428d7b3dSmrg } 198428d7b3dSmrg} 199428d7b3dSmrg 200428d7b3dSmrg#undef ARCCOPY 201428d7b3dSmrg#undef ARCRROP 202428d7b3dSmrg 203428d7b3dSmrg#undef RROP 204428d7b3dSmrg#undef isClipped 205