diff options
Diffstat (limited to 'xorg-server/fb/fbstipple.c')
-rw-r--r-- | xorg-server/fb/fbstipple.c | 620 |
1 files changed, 308 insertions, 312 deletions
diff --git a/xorg-server/fb/fbstipple.c b/xorg-server/fb/fbstipple.c index bc25e462f..1316d5113 100644 --- a/xorg-server/fb/fbstipple.c +++ b/xorg-server/fb/fbstipple.c @@ -1,312 +1,308 @@ -/* - * Copyright © 1998 Keith Packard - * - * Permission to use, copy, modify, distribute, and sell this software and its - * documentation for any purpose is hereby granted without fee, provided that - * the above copyright notice appear in all copies and that both that - * copyright notice and this permission notice appear in supporting - * documentation, and that the name of Keith Packard not be used in - * advertising or publicity pertaining to distribution of the software without - * specific, written prior permission. Keith Packard makes no - * representations about the suitability of this software for any purpose. It - * is provided "as is" without express or implied warranty. - * - * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, - * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO - * EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR - * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, - * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER - * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR - * PERFORMANCE OF THIS SOFTWARE. - */ - -#ifdef HAVE_DIX_CONFIG_H -#include <dix-config.h> -#endif - -#include "fb.h" - -#ifndef FBNOPIXADDR -/* - * This is a slight abuse of the preprocessor to generate repetitive - * code, the idea is to generate code for each case of a copy-mode - * transparent stipple - */ -#define LaneCases1(c,a) case c: \ - while (n--) { FbLaneCase(c,a); a++; } \ - break -#define LaneCases2(c,a) LaneCases1(c,a); LaneCases1(c+1,a) -#define LaneCases4(c,a) LaneCases2(c,a); LaneCases2(c+2,a) -#define LaneCases8(c,a) LaneCases4(c,a); LaneCases4(c+4,a) -#define LaneCases16(c,a) LaneCases8(c,a); LaneCases8(c+8,a) -#define LaneCases32(c,a) LaneCases16(c,a); LaneCases16(c+16,a) -#define LaneCases64(c,a) LaneCases32(c,a); LaneCases32(c+32,a) -#define LaneCases128(c,a) LaneCases64(c,a); LaneCases64(c+64,a) -#define LaneCases256(c,a) LaneCases128(c,a); LaneCases128(c+128,a) - -#if FB_SHIFT == 6 -#define LaneCases(a) LaneCases256(0,a) -#endif - -#if FB_SHIFT == 5 -#define LaneCases(a) LaneCases16(0,a) -#endif - -/* - * Repeat a transparent stipple across a scanline n times - */ - -void -fbTransparentSpan (FbBits *dst, - FbBits stip, - FbBits fgxor, - int n) -{ - FbStip s; - - s = ((FbStip) (stip ) & 0x01); - s |= ((FbStip) (stip >> 8) & 0x02); - s |= ((FbStip) (stip >> 16) & 0x04); - s |= ((FbStip) (stip >> 24) & 0x08); -#if FB_SHIFT > 5 - s |= ((FbStip) (stip >> 32) & 0x10); - s |= ((FbStip) (stip >> 40) & 0x20); - s |= ((FbStip) (stip >> 48) & 0x40); - s |= ((FbStip) (stip >> 56) & 0x80); -#endif - switch (s) { - LaneCases(dst); - } -} -#endif - -void -fbEvenStipple (FbBits *dst, - FbStride dstStride, - int dstX, - int dstBpp, - - int width, - int height, - - FbStip *stip, - FbStride stipStride, - int stipHeight, - - FbBits fgand, - FbBits fgxor, - FbBits bgand, - FbBits bgxor, - - int xRot, - int yRot) -{ - FbBits startmask, endmask; - FbBits mask, and, xor; - int nmiddle, n; - FbStip *s, *stipEnd, bits; - int rot, stipX, stipY; - int pixelsPerDst; - const FbBits *fbBits; - Bool transparent; - int startbyte, endbyte; - - /* - * Check for a transparent stipple (stencil) - */ - transparent = FALSE; - if (dstBpp >= 8 && - fgand == 0 && bgand == FB_ALLONES && bgxor == 0) - transparent = TRUE; - - pixelsPerDst = FB_UNIT / dstBpp; - /* - * Adjust dest pointers - */ - dst += dstX >> FB_SHIFT; - dstX &= FB_MASK; - FbMaskBitsBytes (dstX, width, fgand == 0 && bgand == 0, - startmask, startbyte, nmiddle, endmask, endbyte); - - if (startmask) - dstStride--; - dstStride -= nmiddle; - - xRot *= dstBpp; - /* - * Compute stip start scanline and rotation parameters - */ - stipEnd = stip + stipStride * stipHeight; - modulus (- yRot, stipHeight, stipY); - s = stip + stipStride * stipY; - modulus (- xRot, FB_UNIT, stipX); - rot = stipX; - - /* - * Get pointer to stipple mask array for this depth - */ - /* fbStippleTable covers all valid bpp (4,8,16,32) */ - fbBits = fbStippleTable[pixelsPerDst]; - - while (height--) - { - /* - * Extract stipple bits for this scanline; - */ - bits = READ(s); - s += stipStride; - if (s == stipEnd) - s = stip; -#if FB_UNIT > 32 - if (pixelsPerDst == 16) - mask = FbStipple16Bits(FbLeftStipBits(bits,16)); - else -#endif - mask = fbBits[FbLeftStipBits(bits,pixelsPerDst)]; - /* - * Rotate into position and compute reduced rop values - */ - mask = FbRotLeft(mask, rot); - and = (fgand & mask) | (bgand & ~mask); - xor = (fgxor & mask) | (bgxor & ~mask); - -#ifndef FBNOPIXADDR - if (transparent) - { - if (startmask) - { - fbTransparentSpan(dst, mask&startmask, fgxor, 1); - dst++; - } - fbTransparentSpan (dst, mask, fgxor, nmiddle); - dst += nmiddle; - if (endmask) - fbTransparentSpan(dst, mask&endmask, fgxor, 1); - } - else -#endif - { - /* - * Fill scanline - */ - if (startmask) - { - FbDoLeftMaskByteRRop (dst, startbyte, startmask, and, xor); - dst++; - } - n = nmiddle; - if (!and) - while (n--) - WRITE(dst++, xor); - else - { - while (n--) - { - WRITE(dst, FbDoRRop (READ(dst), and, xor)); - dst++; - } - } - if (endmask) - FbDoRightMaskByteRRop(dst, endbyte, endmask, and, xor); - } - dst += dstStride; - } -} - -void -fbOddStipple (FbBits *dst, - FbStride dstStride, - int dstX, - int dstBpp, - - int width, - int height, - - FbStip *stip, - FbStride stipStride, - int stipWidth, - int stipHeight, - - FbBits fgand, - FbBits fgxor, - FbBits bgand, - FbBits bgxor, - - int xRot, - int yRot) -{ - int stipX, stipY, sx; - int widthTmp; - int h, w; - int x, y; - - modulus (- yRot, stipHeight, stipY); - modulus (dstX / dstBpp - xRot, stipWidth, stipX); - y = 0; - while (height) - { - h = stipHeight - stipY; - if (h > height) - h = height; - height -= h; - widthTmp = width; - x = dstX; - sx = stipX; - while (widthTmp) - { - w = (stipWidth - sx) * dstBpp; - if (w > widthTmp) - w = widthTmp; - widthTmp -= w; - fbBltOne (stip + stipY * stipStride, - stipStride, - sx, - - dst + y * dstStride, - dstStride, - x, - dstBpp, - - w, h, - - fgand, fgxor, bgand, bgxor); - x += w; - sx = 0; - } - y += h; - stipY = 0; - } -} - -void -fbStipple (FbBits *dst, - FbStride dstStride, - int dstX, - int dstBpp, - - int width, - int height, - - FbStip *stip, - FbStride stipStride, - int stipWidth, - int stipHeight, - Bool even, - - FbBits fgand, - FbBits fgxor, - FbBits bgand, - FbBits bgxor, - - int xRot, - int yRot) -{ - if (even) - fbEvenStipple (dst, dstStride, dstX, dstBpp, width, height, - stip, stipStride, stipHeight, - fgand, fgxor, bgand, bgxor, xRot, yRot); - else - fbOddStipple (dst, dstStride, dstX, dstBpp, width, height, - stip, stipStride, stipWidth, stipHeight, - fgand, fgxor, bgand, bgxor, xRot, yRot); -} +/*
+ * Copyright © 1998 Keith Packard
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the name of Keith Packard not be used in
+ * advertising or publicity pertaining to distribution of the software without
+ * specific, written prior permission. Keith Packard makes no
+ * representations about the suitability of this software for any purpose. It
+ * is provided "as is" without express or implied warranty.
+ *
+ * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+ * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#include "fb.h"
+
+/*
+ * This is a slight abuse of the preprocessor to generate repetitive
+ * code, the idea is to generate code for each case of a copy-mode
+ * transparent stipple
+ */
+#define LaneCases1(c,a) case c: \
+ while (n--) { FbLaneCase(c,a); a++; } \
+ break
+#define LaneCases2(c,a) LaneCases1(c,a); LaneCases1(c+1,a)
+#define LaneCases4(c,a) LaneCases2(c,a); LaneCases2(c+2,a)
+#define LaneCases8(c,a) LaneCases4(c,a); LaneCases4(c+4,a)
+#define LaneCases16(c,a) LaneCases8(c,a); LaneCases8(c+8,a)
+#define LaneCases32(c,a) LaneCases16(c,a); LaneCases16(c+16,a)
+#define LaneCases64(c,a) LaneCases32(c,a); LaneCases32(c+32,a)
+#define LaneCases128(c,a) LaneCases64(c,a); LaneCases64(c+64,a)
+#define LaneCases256(c,a) LaneCases128(c,a); LaneCases128(c+128,a)
+
+#if FB_SHIFT == 6
+#define LaneCases(a) LaneCases256(0,a)
+#endif
+
+#if FB_SHIFT == 5
+#define LaneCases(a) LaneCases16(0,a)
+#endif
+
+/*
+ * Repeat a transparent stipple across a scanline n times
+ */
+
+void
+fbTransparentSpan (FbBits *dst,
+ FbBits stip,
+ FbBits fgxor,
+ int n)
+{
+ FbStip s;
+
+ s = ((FbStip) (stip ) & 0x01);
+ s |= ((FbStip) (stip >> 8) & 0x02);
+ s |= ((FbStip) (stip >> 16) & 0x04);
+ s |= ((FbStip) (stip >> 24) & 0x08);
+#if FB_SHIFT > 5
+ s |= ((FbStip) (stip >> 32) & 0x10);
+ s |= ((FbStip) (stip >> 40) & 0x20);
+ s |= ((FbStip) (stip >> 48) & 0x40);
+ s |= ((FbStip) (stip >> 56) & 0x80);
+#endif
+ switch (s) {
+ LaneCases(dst);
+ }
+}
+
+void
+fbEvenStipple (FbBits *dst,
+ FbStride dstStride,
+ int dstX,
+ int dstBpp,
+
+ int width,
+ int height,
+
+ FbStip *stip,
+ FbStride stipStride,
+ int stipHeight,
+
+ FbBits fgand,
+ FbBits fgxor,
+ FbBits bgand,
+ FbBits bgxor,
+
+ int xRot,
+ int yRot)
+{
+ FbBits startmask, endmask;
+ FbBits mask, and, xor;
+ int nmiddle, n;
+ FbStip *s, *stipEnd, bits;
+ int rot, stipX, stipY;
+ int pixelsPerDst;
+ const FbBits *fbBits;
+ Bool transparent;
+ int startbyte, endbyte;
+
+ /*
+ * Check for a transparent stipple (stencil)
+ */
+ transparent = FALSE;
+ if (dstBpp >= 8 &&
+ fgand == 0 && bgand == FB_ALLONES && bgxor == 0)
+ transparent = TRUE;
+
+ pixelsPerDst = FB_UNIT / dstBpp;
+ /*
+ * Adjust dest pointers
+ */
+ dst += dstX >> FB_SHIFT;
+ dstX &= FB_MASK;
+ FbMaskBitsBytes (dstX, width, fgand == 0 && bgand == 0,
+ startmask, startbyte, nmiddle, endmask, endbyte);
+
+ if (startmask)
+ dstStride--;
+ dstStride -= nmiddle;
+
+ xRot *= dstBpp;
+ /*
+ * Compute stip start scanline and rotation parameters
+ */
+ stipEnd = stip + stipStride * stipHeight;
+ modulus (- yRot, stipHeight, stipY);
+ s = stip + stipStride * stipY;
+ modulus (- xRot, FB_UNIT, stipX);
+ rot = stipX;
+
+ /*
+ * Get pointer to stipple mask array for this depth
+ */
+ /* fbStippleTable covers all valid bpp (4,8,16,32) */
+ fbBits = fbStippleTable[pixelsPerDst];
+
+ while (height--)
+ {
+ /*
+ * Extract stipple bits for this scanline;
+ */
+ bits = READ(s);
+ s += stipStride;
+ if (s == stipEnd)
+ s = stip;
+#if FB_UNIT > 32
+ if (pixelsPerDst == 16)
+ mask = FbStipple16Bits(FbLeftStipBits(bits,16));
+ else
+#endif
+ mask = fbBits[FbLeftStipBits(bits,pixelsPerDst)];
+ /*
+ * Rotate into position and compute reduced rop values
+ */
+ mask = FbRotLeft(mask, rot);
+ and = (fgand & mask) | (bgand & ~mask);
+ xor = (fgxor & mask) | (bgxor & ~mask);
+
+ if (transparent)
+ {
+ if (startmask)
+ {
+ fbTransparentSpan(dst, mask&startmask, fgxor, 1);
+ dst++;
+ }
+ fbTransparentSpan (dst, mask, fgxor, nmiddle);
+ dst += nmiddle;
+ if (endmask)
+ fbTransparentSpan(dst, mask&endmask, fgxor, 1);
+ }
+ else
+ {
+ /*
+ * Fill scanline
+ */
+ if (startmask)
+ {
+ FbDoLeftMaskByteRRop (dst, startbyte, startmask, and, xor);
+ dst++;
+ }
+ n = nmiddle;
+ if (!and)
+ while (n--)
+ WRITE(dst++, xor);
+ else
+ {
+ while (n--)
+ {
+ WRITE(dst, FbDoRRop (READ(dst), and, xor));
+ dst++;
+ }
+ }
+ if (endmask)
+ FbDoRightMaskByteRRop(dst, endbyte, endmask, and, xor);
+ }
+ dst += dstStride;
+ }
+}
+
+void
+fbOddStipple (FbBits *dst,
+ FbStride dstStride,
+ int dstX,
+ int dstBpp,
+
+ int width,
+ int height,
+
+ FbStip *stip,
+ FbStride stipStride,
+ int stipWidth,
+ int stipHeight,
+
+ FbBits fgand,
+ FbBits fgxor,
+ FbBits bgand,
+ FbBits bgxor,
+
+ int xRot,
+ int yRot)
+{
+ int stipX, stipY, sx;
+ int widthTmp;
+ int h, w;
+ int x, y;
+
+ modulus (- yRot, stipHeight, stipY);
+ modulus (dstX / dstBpp - xRot, stipWidth, stipX);
+ y = 0;
+ while (height)
+ {
+ h = stipHeight - stipY;
+ if (h > height)
+ h = height;
+ height -= h;
+ widthTmp = width;
+ x = dstX;
+ sx = stipX;
+ while (widthTmp)
+ {
+ w = (stipWidth - sx) * dstBpp;
+ if (w > widthTmp)
+ w = widthTmp;
+ widthTmp -= w;
+ fbBltOne (stip + stipY * stipStride,
+ stipStride,
+ sx,
+
+ dst + y * dstStride,
+ dstStride,
+ x,
+ dstBpp,
+
+ w, h,
+
+ fgand, fgxor, bgand, bgxor);
+ x += w;
+ sx = 0;
+ }
+ y += h;
+ stipY = 0;
+ }
+}
+
+void
+fbStipple (FbBits *dst,
+ FbStride dstStride,
+ int dstX,
+ int dstBpp,
+
+ int width,
+ int height,
+
+ FbStip *stip,
+ FbStride stipStride,
+ int stipWidth,
+ int stipHeight,
+ Bool even,
+
+ FbBits fgand,
+ FbBits fgxor,
+ FbBits bgand,
+ FbBits bgxor,
+
+ int xRot,
+ int yRot)
+{
+ if (even)
+ fbEvenStipple (dst, dstStride, dstX, dstBpp, width, height,
+ stip, stipStride, stipHeight,
+ fgand, fgxor, bgand, bgxor, xRot, yRot);
+ else
+ fbOddStipple (dst, dstStride, dstX, dstBpp, width, height,
+ stip, stipStride, stipWidth, stipHeight,
+ fgand, fgxor, bgand, bgxor, xRot, yRot);
+}
|