summaryrefslogtreecommitdiff
path: root/afb/afbply1rct.c
diff options
context:
space:
mode:
authorKaleb Keithley <kaleb@freedesktop.org>2003-11-14 16:48:57 +0000
committerKaleb Keithley <kaleb@freedesktop.org>2003-11-14 16:48:57 +0000
commit9508a382f8a9f241dab097d921b6d290c1c3a776 (patch)
treefa456480bae7040c3f971a70b390f2d091c680b5 /afb/afbply1rct.c
parentded6147bfb5d75ff1e67c858040a628b61bc17d1 (diff)
Initial revision
Diffstat (limited to 'afb/afbply1rct.c')
-rw-r--r--afb/afbply1rct.c296
1 files changed, 296 insertions, 0 deletions
diff --git a/afb/afbply1rct.c b/afb/afbply1rct.c
new file mode 100644
index 000000000..c0c2065f1
--- /dev/null
+++ b/afb/afbply1rct.c
@@ -0,0 +1,296 @@
+/* $XFree86: xc/programs/Xserver/afb/afbply1rct.c,v 3.2 2001/10/28 03:32:58 tsi Exp $ */
+/*
+ * $XConsortium: afbply1rct.c,v 1.9 94/04/17 20:28:28 dpw Exp $
+ *
+Copyright (c) 1990 X Consortium
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of the X Consortium shall not be
+used in advertising or otherwise to promote the sale, use or other dealings
+in this Software without prior written authorization from the X Consortium.
+ *
+ * Author: Keith Packard, MIT X Consortium
+ */
+
+#include "X.h"
+
+#include "gcstruct.h"
+#include "windowstr.h"
+#include "pixmapstr.h"
+#include "regionstr.h"
+#include "scrnintstr.h"
+#include "mistruct.h"
+
+#include "afb.h"
+#include "maskbits.h"
+
+#if defined(mips) || defined(sparc)
+#define GetHighWord(x) (((int)(x)) >> 16)
+#else
+#define GetHighWord(x) (((int)(x)) / 65536)
+#endif
+
+#if IMAGE_BYTE_ORDER == MSBFirst
+#define intToCoord(i,x,y) (((x) = GetHighWord(i)), ((y) = (int)((short) (i))))
+#define coordToInt(x,y) (((x) << 16) | (y))
+#define intToX(i) (GetHighWord(i))
+#define intToY(i) ((int)((short) i))
+#else
+#define intToCoord(i,x,y) (((x) = (int)((short) (i))), ((y) = GetHighWord(i)))
+#define coordToInt(x,y) (((y) << 16) | (x))
+#define intToX(i) ((int)((short) (i)))
+#define intToY(i) (GetHighWord(i))
+#endif
+
+void
+afbFillPolygonSolid (pDrawable, pGC, shape, mode, count, ptsIn)
+ DrawablePtr pDrawable;
+ GCPtr pGC;
+ int shape;
+ int mode;
+ int count;
+ DDXPointPtr ptsIn;
+{
+ afbPrivGCPtr devPriv;
+ int nlwidth;
+ PixelType *addrl, *addr;
+ int maxy;
+ int origin;
+ register int vertex1, vertex2;
+ int c;
+ BoxPtr extents;
+ int clip;
+ int y;
+ int *vertex1p = NULL, *vertex2p;
+ int *endp;
+ int x1 = 0, x2 = 0;
+ int dx1 = 0, dx2 = 0;
+ int dy1 = 0, dy2 = 0;
+ int e1 = 0, e2 = 0;
+ int step1 = 0, step2 = 0;
+ int sign1 = 0, sign2 = 0;
+ int h;
+ int l, r;
+ PixelType mask, bits = ~((PixelType)0);
+ int nmiddle;
+ register unsigned char *rrops;
+ register int n;
+ register int d;
+ int sizeDst;
+ int depthDst;
+ register PixelType *pdst;
+
+ devPriv = (afbPrivGC *)(pGC->devPrivates[afbGCPrivateIndex].ptr);
+
+ if (mode == CoordModePrevious || shape != Convex ||
+ REGION_NUM_RECTS(pGC->pCompositeClip) != 1) {
+ miFillPolygon (pDrawable, pGC, shape, mode, count, ptsIn);
+ return;
+ }
+ origin = *((int *) &pDrawable->x);
+ origin -= (origin & 0x8000) << 1;
+ extents = &pGC->pCompositeClip->extents;
+ vertex1 = *((int *) &extents->x1) - origin;
+ vertex2 = *((int *) &extents->x2) - origin - 0x00010001;
+ clip = 0;
+ y = 32767;
+ maxy = 0;
+ vertex2p = (int *) ptsIn;
+ endp = vertex2p + count;
+ while (count--) {
+ c = *vertex2p;
+ clip |= (c - vertex1) | (vertex2 - c);
+ c = intToY(c);
+ if (c < y) {
+ y = c;
+ vertex1p = vertex2p;
+ }
+ vertex2p++;
+ if (c > maxy)
+ maxy = c;
+ }
+ if (y == maxy)
+ return;
+
+ if (clip & 0x80008000) {
+ miFillPolygon (pDrawable, pGC, shape, mode, vertex2p - (int *) ptsIn, ptsIn);
+ return;
+ }
+
+ afbGetPixelWidthSizeDepthAndPointer(pDrawable, nlwidth, sizeDst, depthDst,
+ addrl);
+ rrops = devPriv->rrops;
+ addrl = afbScanlineDelta(addrl, y + pDrawable->y, nlwidth);
+ origin = intToX(origin);
+ vertex2p = vertex1p;
+ vertex2 = vertex1 = *vertex2p++;
+ if (vertex2p == endp)
+ vertex2p = (int *) ptsIn;
+#define Setup(c,x,vertex,dx,dy,e,sign,step) {\
+ x = intToX(vertex); \
+ if ((dy = intToY(c) - y)) { \
+ dx = intToX(c) - x; \
+ step = 0; \
+ if (dx >= 0) { \
+ e = 0; \
+ sign = 1; \
+ if (dx >= dy) {\
+ step = dx / dy; \
+ dx = dx % dy; \
+ } \
+ } else { \
+ e = 1 - dy; \
+ sign = -1; \
+ dx = -dx; \
+ if (dx >= dy) { \
+ step = - (dx / dy); \
+ dx = dx % dy; \
+ } \
+ } \
+ } \
+ x += origin; \
+ vertex = c; \
+}
+
+#define Step(x,dx,dy,e,sign,step) {\
+ x += step; \
+ if ((e += dx) > 0) { \
+ x += sign; \
+ e -= dy; \
+ } \
+}
+ for (;;) {
+ if (y == intToY(vertex1)) {
+ do {
+ if (vertex1p == (int *) ptsIn)
+ vertex1p = endp;
+ c = *--vertex1p;
+ Setup (c,x1,vertex1,dx1,dy1,e1,sign1,step1)
+ } while (y >= intToY(vertex1));
+ h = dy1;
+ } else {
+ Step(x1,dx1,dy1,e1,sign1,step1)
+ h = intToY(vertex1) - y;
+ }
+ if (y == intToY(vertex2)) {
+ do {
+ c = *vertex2p++;
+ if (vertex2p == endp)
+ vertex2p = (int *) ptsIn;
+ Setup (c,x2,vertex2,dx2,dy2,e2,sign2,step2)
+ } while (y >= intToY(vertex2));
+ if (dy2 < h)
+ h = dy2;
+ } else {
+ Step(x2,dx2,dy2,e2,sign2,step2)
+ if ((c = (intToY(vertex2) - y)) < h)
+ h = c;
+ }
+ /* fill spans for this segment */
+ y += h;
+ for (;;) {
+ l = x1;
+ r = x2;
+ nmiddle = x2 - x1;
+ if (nmiddle < 0) {
+ nmiddle = -nmiddle;
+ l = x2;
+ r = x1;
+ }
+ c = l & PIM;
+ l -= c;
+ l = l >> PWSH;
+ addr = addrl + l;
+ if (c + nmiddle < PPW) {
+ mask = SCRRIGHT (bits,c) ^ SCRRIGHT (bits,c+nmiddle);
+ for (pdst = addr, d = 0; d < depthDst; d++, pdst += sizeDst) { /* @@@ NEXT PLANE @@@ */
+ switch (rrops[d]) {
+ case RROP_BLACK:
+ *pdst &= ~mask;
+ break;
+ case RROP_WHITE:
+ *pdst |= mask;
+ break;
+ case RROP_INVERT:
+ *pdst ^= mask;
+ break;
+ case RROP_NOP:
+ break;
+ }
+ }
+ } else {
+ if (c) {
+ mask = SCRRIGHT(bits, c);
+ for (pdst = addr, d = 0; d < depthDst; d++, pdst += sizeDst) { /* @@@ NEXT PLANE @@@ */
+ switch (rrops[d]) {
+ case RROP_BLACK:
+ *pdst &= ~mask;
+ break;
+ case RROP_WHITE:
+ *pdst |= mask;
+ break;
+ case RROP_INVERT:
+ *pdst ^= mask;
+ break;
+ case RROP_NOP:
+ break;
+ }
+ }
+ nmiddle += c - PPW;
+ addr++;
+ }
+ nmiddle >>= PWSH;
+ mask = ~SCRRIGHT(bits, r & PIM);
+
+ for (d = 0; d < depthDst; d++, addr += sizeDst) { /* @@@ NEXT PLANE @@@ */
+ n = nmiddle;
+ pdst = addr;
+
+ switch (rrops[d]) {
+ case RROP_BLACK:
+ Duff (n, *pdst++ = 0;)
+ if (mask)
+ *pdst &= ~mask;
+ break;
+ case RROP_WHITE:
+ Duff (n, *pdst++ = ~0;);
+ if (mask)
+ *pdst |= mask;
+ break;
+ case RROP_INVERT:
+ Duff (n, *pdst++ ^= ~0;);
+ if (mask)
+ *pdst ^= mask;
+ break;
+ case RROP_NOP:
+ break;
+ }
+ }
+ }
+ if (!--h)
+ break;
+ afbScanlineInc(addrl, nlwidth);
+ Step(x1,dx1,dy1,e1,sign1,step1)
+ Step(x2,dx2,dy2,e2,sign2,step2)
+ }
+ if (y == maxy)
+ break;
+ afbScanlineInc(addrl, nlwidth);
+ }
+}