#include "X.h"
#include "Xprotostr.h"
#include "regionstr.h"
#include "gcstruct.h"
#include "pixmapstr.h"
#include "scrnintstr.h"
#include "afb.h"
#include "maskbits.h"
#include "mizerarc.h"
#include "mi.h"
#if (BITMAP_BIT_ORDER == MSBFirst)
#define LEFTMOST ((PixelType) LONG2CHARS((1 << PLST)))
#else
#define LEFTMOST ((PixelType) LONG2CHARS(1))
#endif
#define Pixelate(base,yoff,xoff) \
{ \
paddr = afbScanlineOffset(base, (yoff) + ((xoff)>>PWSH)); \
pmask = SCRRIGHT(LEFTMOST, (xoff) & PIM); \
for (de = 0; de < depthDst; de++, paddr += sizeDst) \
switch (rrops[de]) { \
case RROP_BLACK: \
*paddr &= ~pmask; \
break; \
case RROP_WHITE: \
*paddr |= pmask; \
break; \
case RROP_INVERT: \
*paddr ^= pmask; \
break; \
case RROP_NOP: \
break; \
} \
}
#define DoPix(bit,base,yoff,xoff) if (mask & bit) Pixelate(base,yoff,xoff);
static void
afbZeroArcSS(pDraw, pGC, arc)
DrawablePtr pDraw;
GCPtr pGC;
xArc *arc;
{
miZeroArcRec info;
Bool do360;
register int de;
register int x, y, a, b, d, mask;
register int k1, k3, dx, dy;
PixelType *addrl;
PixelType *yorgl, *yorgol;
int nlwidth, yoffset, dyoffset;
int sizeDst, depthDst;
PixelType pmask;
register PixelType *paddr;
register unsigned char *rrops;
rrops = ((afbPrivGC *)(pGC->devPrivates[afbGCPrivateIndex].ptr))->rrops;
afbGetPixelWidthSizeDepthAndPointer(pDraw, nlwidth, sizeDst, depthDst,
addrl);
do360 = miZeroArcSetup(arc, &info, TRUE);
yorgl = addrl + ((info.yorg + pDraw->y) * nlwidth);
yorgol = addrl + ((info.yorgo + pDraw->y) * nlwidth);
info.xorg += pDraw->x;
info.xorgo += pDraw->x;
MIARCSETUP();
yoffset = y ? nlwidth : 0;
dyoffset = 0;
mask = info.initialMask;
if (!(arc->width & 1)) {
DoPix(2, yorgl, 0, info.xorgo);
DoPix(8, yorgol, 0, info.xorgo);
}
if (!info.end.x || !info.end.y) {
mask = info.end.mask;
info.end = info.altend;
}
if (do360 && (arc->width == arc->height) && !(arc->width & 1)) {
int xoffset = nlwidth;
PixelType *yorghl = afbScanlineDeltaNoBankSwitch(yorgl, info.h, nlwidth);
int xorghp = info.xorg + info.h;
int xorghn = info.xorg - info.h;
while (1) {
Pixelate(yorgl, yoffset, info.xorg + x);
Pixelate(yorgl, yoffset, info.xorg - x);
Pixelate(yorgol, -yoffset, info.xorg - x);
Pixelate(yorgol, -yoffset, info.xorg + x);
if (a < 0)
break;
Pixelate(yorghl, -xoffset, xorghp - y);
Pixelate(yorghl, -xoffset, xorghn + y);
Pixelate(yorghl, xoffset, xorghn + y);
Pixelate(yorghl, xoffset, xorghp - y);
xoffset += nlwidth;
MIARCCIRCLESTEP(yoffset += nlwidth;);
}
x = info.w;
yoffset = info.h * nlwidth;
} else if (do360) {
while (y < info.h || x < info.w) {
MIARCOCTANTSHIFT(dyoffset = nlwidth;);
Pixelate(yorgl, yoffset, info.xorg + x);
Pixelate(yorgl, yoffset, info.xorgo - x);
Pixelate(yorgol, -yoffset, info.xorgo - x);
Pixelate(yorgol, -yoffset, info.xorg + x);
MIARCSTEP(yoffset += dyoffset;, yoffset += nlwidth;);
}
} else {
while (y < info.h || x < info.w) {
MIARCOCTANTSHIFT(dyoffset = nlwidth;);
if ((x == info.start.x) || (y == info.start.y)) {
mask = info.start.mask;
info.start = info.altstart;
}
DoPix(1, yorgl, yoffset, info.xorg + x);
DoPix(2, yorgl, yoffset, info.xorgo - x);
DoPix(4, yorgol, -yoffset, info.xorgo - x);
DoPix(8, yorgol, -yoffset, info.xorg + x);
if ((x == info.end.x) || (y == info.end.y)) {
mask = info.end.mask;
info.end = info.altend;
}
MIARCSTEP(yoffset += dyoffset;, yoffset += nlwidth;);
}
}
if ((x == info.start.x) || (y == info.start.y))
mask = info.start.mask;
DoPix(1, yorgl, yoffset, info.xorg + x);
DoPix(4, yorgol, -yoffset, info.xorgo - x);
if (arc->height & 1) {
DoPix(2, yorgl, yoffset, info.xorgo - x);
DoPix(8, yorgol, -yoffset, info.xorg + x);
}
}
void
afbZeroPolyArcSS(pDraw, pGC, narcs, parcs)
DrawablePtr pDraw;
GCPtr pGC;
int narcs;
xArc *parcs;
{
register xArc *arc;
register int i;
BoxRec box;
RegionPtr cclip;
cclip = pGC->pCompositeClip;
for (arc = parcs, i = narcs; --i >= 0; arc++) {
if (miCanZeroArc(arc)) {
box.x1 = arc->x + pDraw->x;
box.y1 = arc->y + pDraw->y;
box.x2 = box.x1 + (int)arc->width + 1;
box.y2 = box.y1 + (int)arc->height + 1;
if (RECT_IN_REGION(pDraw->pScreen, cclip, &box) == rgnIN)
afbZeroArcSS(pDraw, pGC, arc);
else
miZeroPolyArc(pDraw, pGC, 1, arc);
} else
miPolyArc(pDraw, pGC, 1, arc);
}
}