summaryrefslogtreecommitdiff
path: root/fb/fbpict.c
diff options
context:
space:
mode:
Diffstat (limited to 'fb/fbpict.c')
-rw-r--r--fb/fbpict.c1167
1 files changed, 1167 insertions, 0 deletions
diff --git a/fb/fbpict.c b/fb/fbpict.c
new file mode 100644
index 000000000..894d5cd62
--- /dev/null
+++ b/fb/fbpict.c
@@ -0,0 +1,1167 @@
+/*
+ * $XFree86: xc/programs/Xserver/fb/fbpict.c,v 1.16 2002/12/14 01:46:02 dawes Exp $
+ *
+ * Copyright © 2000 SuSE, Inc.
+ *
+ * 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 SuSE not be used in advertising or
+ * publicity pertaining to distribution of the software without specific,
+ * written prior permission. SuSE makes no representations about the
+ * suitability of this software for any purpose. It is provided "as is"
+ * without express or implied warranty.
+ *
+ * SuSE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL SuSE
+ * 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.
+ *
+ * Author: Keith Packard, SuSE, Inc.
+ */
+
+#include "fb.h"
+
+#ifdef RENDER
+
+#include "picturestr.h"
+#include "mipict.h"
+#include "fbpict.h"
+
+#define cvt8888to0565(s) ((((s) >> 3) & 0x001f) | \
+ (((s) >> 5) & 0x07e0) | \
+ (((s) >> 8) & 0xf800))
+#define cvt0565to8888(s) (((((s) << 3) & 0xf8) | (((s) >> 2) & 0x7)) | \
+ ((((s) << 5) & 0xfc00) | (((s) >> 1) & 0x300)) | \
+ ((((s) << 8) & 0xf80000) | (((s) << 3) & 0x70000)))
+
+#if IMAGE_BYTE_ORDER == MSBFirst
+#define Fetch24(a) ((unsigned long) (a) & 1 ? \
+ ((*(a) << 16) | *((CARD16 *) ((a)+1))) : \
+ ((*((CARD16 *) (a)) << 8) | *((a)+2)))
+#define Store24(a,v) ((unsigned long) (a) & 1 ? \
+ ((*(a) = (CARD8) ((v) >> 16)), \
+ (*((CARD16 *) ((a)+1)) = (CARD16) (v))) : \
+ ((*((CARD16 *) (a)) = (CARD16) ((v) >> 8)), \
+ (*((a)+2) = (CARD8) (v))))
+#else
+#define Fetch24(a) ((unsigned long) (a) & 1 ? \
+ ((*(a)) | (*((CARD16 *) ((a)+1)) << 8)) : \
+ ((*((CARD16 *) (a))) | (*((a)+2) << 16)))
+#define Store24(a,v) ((unsigned long) (a) & 1 ? \
+ ((*(a) = (CARD8) (v)), \
+ (*((CARD16 *) ((a)+1)) = (CARD16) ((v) >> 8))) : \
+ ((*((CARD16 *) (a)) = (CARD16) (v)),\
+ (*((a)+2) = (CARD8) ((v) >> 16))))
+#endif
+
+CARD32
+fbOver (CARD32 x, CARD32 y)
+{
+ CARD16 a = ~x >> 24;
+ CARD16 t;
+ CARD32 m,n,o,p;
+
+ m = FbOverU(x,y,0,a,t);
+ n = FbOverU(x,y,8,a,t);
+ o = FbOverU(x,y,16,a,t);
+ p = FbOverU(x,y,24,a,t);
+ return m|n|o|p;
+}
+
+CARD32
+fbOver24 (CARD32 x, CARD32 y)
+{
+ CARD16 a = ~x >> 24;
+ CARD16 t;
+ CARD32 m,n,o;
+
+ m = FbOverU(x,y,0,a,t);
+ n = FbOverU(x,y,8,a,t);
+ o = FbOverU(x,y,16,a,t);
+ return m|n|o;
+}
+
+CARD32
+fbIn (CARD32 x, CARD8 y)
+{
+ CARD16 a = y;
+ CARD16 t;
+ CARD32 m,n,o,p;
+
+ m = FbInU(x,0,a,t);
+ n = FbInU(x,8,a,t);
+ o = FbInU(x,16,a,t);
+ p = FbInU(x,24,a,t);
+ return m|n|o|p;
+}
+
+#define fbComposeGetSolid(pict, bits) { \
+ FbBits *__bits__; \
+ FbStride __stride__; \
+ int __bpp__; \
+ int __xoff__,__yoff__; \
+\
+ fbGetDrawable((pict)->pDrawable,__bits__,__stride__,__bpp__,__xoff__,__yoff__); \
+ switch (__bpp__) { \
+ case 32: \
+ (bits) = *(CARD32 *) __bits__; \
+ break; \
+ case 24: \
+ (bits) = Fetch24 ((CARD8 *) __bits__); \
+ break; \
+ case 16: \
+ (bits) = *(CARD16 *) __bits__; \
+ (bits) = cvt0565to8888(bits); \
+ break; \
+ default: \
+ return; \
+ } \
+ /* manage missing src alpha */ \
+ if ((pict)->pFormat->direct.alphaMask == 0) \
+ (bits) |= 0xff000000; \
+}
+
+#define fbComposeGetStart(pict,x,y,type,stride,line,mul) {\
+ FbBits *__bits__; \
+ FbStride __stride__; \
+ int __bpp__; \
+ int __xoff__,__yoff__; \
+\
+ fbGetDrawable((pict)->pDrawable,__bits__,__stride__,__bpp__,__xoff__,__yoff__); \
+ (stride) = __stride__ * sizeof (FbBits) / sizeof (type); \
+ (line) = ((type *) __bits__) + (stride) * ((y) - __yoff__) + (mul) * ((x) - __xoff__); \
+}
+
+/*
+ * Naming convention:
+ *
+ * opSRCxMASKxDST
+ */
+
+void
+fbCompositeSolidMask_nx8x8888 (CARD8 op,
+ PicturePtr pSrc,
+ PicturePtr pMask,
+ PicturePtr pDst,
+ INT16 xSrc,
+ INT16 ySrc,
+ INT16 xMask,
+ INT16 yMask,
+ INT16 xDst,
+ INT16 yDst,
+ CARD16 width,
+ CARD16 height)
+{
+ CARD32 src, srca;
+ CARD32 *dstLine, *dst, d, dstMask;
+ CARD8 *maskLine, *mask, m;
+ FbStride dstStride, maskStride;
+ CARD16 w;
+
+ fbComposeGetSolid(pSrc, src);
+
+ dstMask = FbFullMask (pDst->pDrawable->depth);
+ srca = src >> 24;
+ if (src == 0)
+ return;
+
+ fbComposeGetStart (pDst, xDst, yDst, CARD32, dstStride, dstLine, 1);
+ fbComposeGetStart (pMask, xMask, yMask, CARD8, maskStride, maskLine, 1);
+
+ while (height--)
+ {
+ dst = dstLine;
+ dstLine += dstStride;
+ mask = maskLine;
+ maskLine += maskStride;
+ w = width;
+
+ while (w--)
+ {
+ m = *mask++;
+ if (m == 0xff)
+ {
+ if (srca == 0xff)
+ *dst = src & dstMask;
+ else
+ *dst = fbOver (src, *dst) & dstMask;
+ }
+ else if (m)
+ {
+ d = fbIn (src, m);
+ *dst = fbOver (d, *dst) & dstMask;
+ }
+ dst++;
+ }
+ }
+}
+
+void
+fbCompositeSolidMask_nx8888x8888C (CARD8 op,
+ PicturePtr pSrc,
+ PicturePtr pMask,
+ PicturePtr pDst,
+ INT16 xSrc,
+ INT16 ySrc,
+ INT16 xMask,
+ INT16 yMask,
+ INT16 xDst,
+ INT16 yDst,
+ CARD16 width,
+ CARD16 height)
+{
+ CARD32 src, srca;
+ CARD32 *dstLine, *dst, d, dstMask;
+ CARD32 *maskLine, *mask, ma;
+ FbStride dstStride, maskStride;
+ CARD16 w;
+ CARD32 m, n, o, p;
+
+ fbComposeGetSolid(pSrc, src);
+
+ dstMask = FbFullMask (pDst->pDrawable->depth);
+ srca = src >> 24;
+ if (src == 0)
+ return;
+
+ fbComposeGetStart (pDst, xDst, yDst, CARD32, dstStride, dstLine, 1);
+ fbComposeGetStart (pMask, xMask, yMask, CARD32, maskStride, maskLine, 1);
+
+ while (height--)
+ {
+ dst = dstLine;
+ dstLine += dstStride;
+ mask = maskLine;
+ maskLine += maskStride;
+ w = width;
+
+ while (w--)
+ {
+ ma = *mask++;
+ if (ma == 0xffffffff)
+ {
+ if (srca == 0xff)
+ *dst = src & dstMask;
+ else
+ *dst = fbOver (src, *dst) & dstMask;
+ }
+ else if (ma)
+ {
+ d = *dst;
+#define FbInOverC(src,srca,msk,dst,i,result) { \
+ CARD16 __a = FbGet8(msk,i); \
+ CARD32 __t, __ta; \
+ CARD32 __i; \
+ __t = FbIntMult (FbGet8(src,i), __a,__i); \
+ __ta = (CARD8) ~FbIntMult (srca, __a,__i); \
+ __t = __t + FbIntMult(FbGet8(dst,i),__ta,__i); \
+ __t = (CARD32) (CARD8) (__t | (-(__t >> 8))); \
+ result = __t << (i); \
+}
+ FbInOverC (src, srca, ma, d, 0, m);
+ FbInOverC (src, srca, ma, d, 8, n);
+ FbInOverC (src, srca, ma, d, 16, o);
+ FbInOverC (src, srca, ma, d, 24, p);
+ *dst = m|n|o|p;
+ }
+ dst++;
+ }
+ }
+}
+
+void
+fbCompositeSolidMask_nx8x0888 (CARD8 op,
+ PicturePtr pSrc,
+ PicturePtr pMask,
+ PicturePtr pDst,
+ INT16 xSrc,
+ INT16 ySrc,
+ INT16 xMask,
+ INT16 yMask,
+ INT16 xDst,
+ INT16 yDst,
+ CARD16 width,
+ CARD16 height)
+{
+ CARD32 src, srca;
+ CARD8 *dstLine, *dst;
+ CARD32 d;
+ CARD8 *maskLine, *mask, m;
+ FbStride dstStride, maskStride;
+ CARD16 w;
+
+ fbComposeGetSolid(pSrc, src);
+
+ srca = src >> 24;
+ if (src == 0)
+ return;
+
+ fbComposeGetStart (pDst, xDst, yDst, CARD8, dstStride, dstLine, 3);
+ fbComposeGetStart (pMask, xMask, yMask, CARD8, maskStride, maskLine, 1);
+
+ while (height--)
+ {
+ dst = dstLine;
+ dstLine += dstStride;
+ mask = maskLine;
+ maskLine += maskStride;
+ w = width;
+
+ while (w--)
+ {
+ m = *mask++;
+ if (m == 0xff)
+ {
+ if (srca == 0xff)
+ d = src;
+ else
+ {
+ d = Fetch24(dst);
+ d = fbOver24 (src, d);
+ }
+ Store24(dst,d);
+ }
+ else if (m)
+ {
+ d = fbOver24 (fbIn(src,m), Fetch24(dst));
+ Store24(dst,d);
+ }
+ dst += 3;
+ }
+ }
+}
+
+void
+fbCompositeSolidMask_nx8x0565 (CARD8 op,
+ PicturePtr pSrc,
+ PicturePtr pMask,
+ PicturePtr pDst,
+ INT16 xSrc,
+ INT16 ySrc,
+ INT16 xMask,
+ INT16 yMask,
+ INT16 xDst,
+ INT16 yDst,
+ CARD16 width,
+ CARD16 height)
+{
+ CARD32 src, srca;
+ CARD16 *dstLine, *dst;
+ CARD32 d;
+ CARD8 *maskLine, *mask, m;
+ FbStride dstStride, maskStride;
+ CARD16 w;
+
+ fbComposeGetSolid(pSrc, src);
+
+ srca = src >> 24;
+ if (src == 0)
+ return;
+
+ fbComposeGetStart (pDst, xDst, yDst, CARD16, dstStride, dstLine, 1);
+ fbComposeGetStart (pMask, xMask, yMask, CARD8, maskStride, maskLine, 1);
+
+ while (height--)
+ {
+ dst = dstLine;
+ dstLine += dstStride;
+ mask = maskLine;
+ maskLine += maskStride;
+ w = width;
+
+ while (w--)
+ {
+ m = *mask++;
+ if (m == 0xff)
+ {
+ if (srca == 0xff)
+ d = src;
+ else
+ {
+ d = *dst;
+ d = fbOver24 (src, cvt0565to8888(d));
+ }
+ *dst = cvt8888to0565(d);
+ }
+ else if (m)
+ {
+ d = *dst;
+ d = fbOver24 (fbIn(src,m), cvt0565to8888(d));
+ *dst = cvt8888to0565(d);
+ }
+ dst++;
+ }
+ }
+}
+
+void
+fbCompositeSolidMask_nx8888x0565C (CARD8 op,
+ PicturePtr pSrc,
+ PicturePtr pMask,
+ PicturePtr pDst,
+ INT16 xSrc,
+ INT16 ySrc,
+ INT16 xMask,
+ INT16 yMask,
+ INT16 xDst,
+ INT16 yDst,
+ CARD16 width,
+ CARD16 height)
+{
+ CARD32 src, srca;
+ CARD16 src16;
+ CARD16 *dstLine, *dst;
+ CARD32 d;
+ CARD32 *maskLine, *mask, ma;
+ FbStride dstStride, maskStride;
+ CARD16 w;
+ CARD32 m, n, o;
+
+ fbComposeGetSolid(pSrc, src);
+
+ srca = src >> 24;
+ if (src == 0)
+ return;
+
+ src16 = cvt8888to0565(src);
+
+ fbComposeGetStart (pDst, xDst, yDst, CARD16, dstStride, dstLine, 1);
+ fbComposeGetStart (pMask, xMask, yMask, CARD32, maskStride, maskLine, 1);
+
+ while (height--)
+ {
+ dst = dstLine;
+ dstLine += dstStride;
+ mask = maskLine;
+ maskLine += maskStride;
+ w = width;
+
+ while (w--)
+ {
+ ma = *mask++;
+ if (ma == 0xffffffff)
+ {
+ if (srca == 0xff)
+ {
+ *dst = src16;
+ }
+ else
+ {
+ d = *dst;
+ d = fbOver24 (src, cvt0565to8888(d));
+ *dst = cvt8888to0565(d);
+ }
+ }
+ else if (ma)
+ {
+ d = *dst;
+ d = cvt0565to8888(d);
+ FbInOverC (src, srca, ma, d, 0, m);
+ FbInOverC (src, srca, ma, d, 8, n);
+ FbInOverC (src, srca, ma, d, 16, o);
+ d = m|n|o;
+ *dst = cvt8888to0565(d);
+ }
+ dst++;
+ }
+ }
+}
+
+void
+fbCompositeSrc_8888x8888 (CARD8 op,
+ PicturePtr pSrc,
+ PicturePtr pMask,
+ PicturePtr pDst,
+ INT16 xSrc,
+ INT16 ySrc,
+ INT16 xMask,
+ INT16 yMask,
+ INT16 xDst,
+ INT16 yDst,
+ CARD16 width,
+ CARD16 height)
+{
+ CARD32 *dstLine, *dst, dstMask;
+ CARD32 *srcLine, *src, s;
+ FbStride dstStride, srcStride;
+ CARD8 a;
+ CARD16 w;
+
+ fbComposeGetStart (pDst, xDst, yDst, CARD32, dstStride, dstLine, 1);
+ fbComposeGetStart (pSrc, xSrc, ySrc, CARD32, srcStride, srcLine, 1);
+
+ dstMask = FbFullMask (pDst->pDrawable->depth);
+
+ while (height--)
+ {
+ dst = dstLine;
+ dstLine += dstStride;
+ src = srcLine;
+ srcLine += srcStride;
+ w = width;
+
+ while (w--)
+ {
+ s = *src++;
+ a = s >> 24;
+ if (a == 0xff)
+ *dst = s & dstMask;
+ else if (a)
+ *dst = fbOver (s, *dst) & dstMask;
+ dst++;
+ }
+ }
+}
+
+void
+fbCompositeSrc_8888x0888 (CARD8 op,
+ PicturePtr pSrc,
+ PicturePtr pMask,
+ PicturePtr pDst,
+ INT16 xSrc,
+ INT16 ySrc,
+ INT16 xMask,
+ INT16 yMask,
+ INT16 xDst,
+ INT16 yDst,
+ CARD16 width,
+ CARD16 height)
+{
+ CARD8 *dstLine, *dst;
+ CARD32 d;
+ CARD32 *srcLine, *src, s;
+ CARD8 a;
+ FbStride dstStride, srcStride;
+ CARD16 w;
+
+ fbComposeGetStart (pDst, xDst, yDst, CARD8, dstStride, dstLine, 3);
+ fbComposeGetStart (pSrc, xSrc, ySrc, CARD32, srcStride, srcLine, 1);
+
+ while (height--)
+ {
+ dst = dstLine;
+ dstLine += dstStride;
+ src = srcLine;
+ srcLine += srcStride;
+ w = width;
+
+ while (w--)
+ {
+ s = *src++;
+ a = s >> 24;
+ if (a)
+ {
+ if (a == 0xff)
+ d = s;
+ else
+ d = fbOver24 (s, Fetch24(dst));
+ Store24(dst,d);
+ }
+ dst += 3;
+ }
+ }
+}
+
+void
+fbCompositeSrc_8888x0565 (CARD8 op,
+ PicturePtr pSrc,
+ PicturePtr pMask,
+ PicturePtr pDst,
+ INT16 xSrc,
+ INT16 ySrc,
+ INT16 xMask,
+ INT16 yMask,
+ INT16 xDst,
+ INT16 yDst,
+ CARD16 width,
+ CARD16 height)
+{
+ CARD16 *dstLine, *dst;
+ CARD32 d;
+ CARD32 *srcLine, *src, s;
+ CARD8 a;
+ FbStride dstStride, srcStride;
+ CARD16 w;
+
+ fbComposeGetStart (pSrc, xSrc, ySrc, CARD32, srcStride, srcLine, 1);
+ fbComposeGetStart (pDst, xDst, yDst, CARD16, dstStride, dstLine, 1);
+
+ while (height--)
+ {
+ dst = dstLine;
+ dstLine += dstStride;
+ src = srcLine;
+ srcLine += srcStride;
+ w = width;
+
+ while (w--)
+ {
+ s = *src++;
+ a = s >> 24;
+ if (a)
+ {
+ if (a == 0xff)
+ d = s;
+ else
+ {
+ d = *dst;
+ d = fbOver24 (s, cvt0565to8888(d));
+ }
+ *dst = cvt8888to0565(d);
+ }
+ dst++;
+ }
+ }
+}
+
+void
+fbCompositeSrc_0565x0565 (CARD8 op,
+ PicturePtr pSrc,
+ PicturePtr pMask,
+ PicturePtr pDst,
+ INT16 xSrc,
+ INT16 ySrc,
+ INT16 xMask,
+ INT16 yMask,
+ INT16 xDst,
+ INT16 yDst,
+ CARD16 width,
+ CARD16 height)
+{
+ CARD16 *dstLine, *dst;
+ CARD16 *srcLine, *src;
+ FbStride dstStride, srcStride;
+ CARD16 w;
+
+ fbComposeGetStart (pSrc, xSrc, ySrc, CARD16, srcStride, srcLine, 1);
+
+ fbComposeGetStart (pDst, xDst, yDst, CARD16, dstStride, dstLine, 1);
+
+ while (height--)
+ {
+ dst = dstLine;
+ dstLine += dstStride;
+ src = srcLine;
+ srcLine += srcStride;
+ w = width;
+
+ while (w--)
+ *dst++ = *src++;
+ }
+}
+
+void
+fbCompositeSrcAdd_8000x8000 (CARD8 op,
+ PicturePtr pSrc,
+ PicturePtr pMask,
+ PicturePtr pDst,
+ INT16 xSrc,
+ INT16 ySrc,
+ INT16 xMask,
+ INT16 yMask,
+ INT16 xDst,
+ INT16 yDst,
+ CARD16 width,
+ CARD16 height)
+{
+ CARD8 *dstLine, *dst;
+ CARD8 *srcLine, *src;
+ FbStride dstStride, srcStride;
+ CARD16 w;
+ CARD8 s, d;
+ CARD16 t;
+
+ fbComposeGetStart (pSrc, xSrc, ySrc, CARD8, srcStride, srcLine, 1);
+ fbComposeGetStart (pDst, xDst, yDst, CARD8, dstStride, dstLine, 1);
+
+ while (height--)
+ {
+ dst = dstLine;
+ dstLine += dstStride;
+ src = srcLine;
+ srcLine += srcStride;
+ w = width;
+
+ while (w--)
+ {
+ s = *src++;
+ if (s)
+ {
+ if (s != 0xff)
+ {
+ d = *dst;
+ t = d + s;
+ s = t | (0 - (t >> 8));
+ }
+ *dst = s;
+ }
+ dst++;
+ }
+ }
+}
+
+void
+fbCompositeSrcAdd_8888x8888 (CARD8 op,
+ PicturePtr pSrc,
+ PicturePtr pMask,
+ PicturePtr pDst,
+ INT16 xSrc,
+ INT16 ySrc,
+ INT16 xMask,
+ INT16 yMask,
+ INT16 xDst,
+ INT16 yDst,
+ CARD16 width,
+ CARD16 height)
+{
+ CARD32 *dstLine, *dst;
+ CARD32 *srcLine, *src;
+ FbStride dstStride, srcStride;
+ CARD16 w;
+ CARD32 s, d;
+ CARD16 t;
+ CARD32 m,n,o,p;
+
+ fbComposeGetStart (pSrc, xSrc, ySrc, CARD32, srcStride, srcLine, 1);
+ fbComposeGetStart (pDst, xDst, yDst, CARD32, dstStride, dstLine, 1);
+
+ while (height--)
+ {
+ dst = dstLine;
+ dstLine += dstStride;
+ src = srcLine;
+ srcLine += srcStride;
+ w = width;
+
+ while (w--)
+ {
+ s = *src++;
+ if (s)
+ {
+ if (s != 0xffffffff)
+ {
+ d = *dst;
+ if (d)
+ {
+ m = FbAdd(s,d,0,t);
+ n = FbAdd(s,d,8,t);
+ o = FbAdd(s,d,16,t);
+ p = FbAdd(s,d,24,t);
+ s = m|n|o|p;
+ }
+ }
+ *dst = s;
+ }
+ dst++;
+ }
+ }
+}
+
+void
+fbCompositeSrcAdd_1000x1000 (CARD8 op,
+ PicturePtr pSrc,
+ PicturePtr pMask,
+ PicturePtr pDst,
+ INT16 xSrc,
+ INT16 ySrc,
+ INT16 xMask,
+ INT16 yMask,
+ INT16 xDst,
+ INT16 yDst,
+ CARD16 width,
+ CARD16 height)
+{
+ FbBits *dstBits, *srcBits;
+ FbStride dstStride, srcStride;
+ int dstBpp, srcBpp;
+ int dstXoff, dstYoff;
+ int srcXoff, srcYoff;
+
+ fbGetDrawable(pSrc->pDrawable, srcBits, srcStride, srcBpp, srcXoff, srcYoff);
+
+ fbGetDrawable(pDst->pDrawable, dstBits, dstStride, dstBpp, dstXoff, dstYoff);
+
+ fbBlt (srcBits + srcStride * (ySrc + srcYoff),
+ srcStride,
+ xSrc + srcXoff,
+
+ dstBits + dstStride * (yDst + dstYoff),
+ dstStride,
+ xDst + dstXoff,
+
+ width,
+ height,
+
+ GXor,
+ FB_ALLONES,
+ srcBpp,
+
+ FALSE,
+ FALSE);
+}
+
+void
+fbCompositeSolidMask_nx1xn (CARD8 op,
+ PicturePtr pSrc,
+ PicturePtr pMask,
+ PicturePtr pDst,
+ INT16 xSrc,
+ INT16 ySrc,
+ INT16 xMask,
+ INT16 yMask,
+ INT16 xDst,
+ INT16 yDst,
+ CARD16 width,
+ CARD16 height)
+{
+ FbBits *dstBits;
+ FbStip *maskBits;
+ FbStride dstStride, maskStride;
+ int dstBpp, maskBpp;
+ int dstXoff, dstYoff;
+ int maskXoff, maskYoff;
+ FbBits src;
+
+ fbComposeGetSolid(pSrc, src);
+
+ if ((src & 0xff000000) != 0xff000000)
+ {
+ fbCompositeGeneral (op, pSrc, pMask, pDst,
+ xSrc, ySrc, xMask, yMask, xDst, yDst,
+ width, height);
+ return;
+ }
+ fbGetStipDrawable (pMask->pDrawable, maskBits, maskStride, maskBpp, maskXoff, maskYoff);
+ fbGetDrawable (pDst->pDrawable, dstBits, dstStride, dstBpp, dstXoff, dstYoff);
+
+ switch (dstBpp) {
+ case 32:
+ break;
+ case 24:
+ break;
+ case 16:
+ src = cvt8888to0565(src);
+ break;
+ }
+
+ src = fbReplicatePixel (src, dstBpp);
+
+ fbBltOne (maskBits + maskStride * (yMask + maskYoff),
+ maskStride,
+ xMask + maskXoff,
+
+ dstBits + dstStride * (yDst + dstYoff),
+ dstStride,
+ (xDst + dstXoff) * dstBpp,
+ dstBpp,
+
+ width * dstBpp,
+ height,
+
+ 0x0,
+ src,
+ FB_ALLONES,
+ 0x0);
+}
+
+# define mod(a,b) ((b) == 1 ? 0 : (a) >= 0 ? (a) % (b) : (b) - (-a) % (b))
+
+void
+fbComposite (CARD8 op,
+ PicturePtr pSrc,
+ PicturePtr pMask,
+ PicturePtr pDst,
+ INT16 xSrc,
+ INT16 ySrc,
+ INT16 xMask,
+ INT16 yMask,
+ INT16 xDst,
+ INT16 yDst,
+ CARD16 width,
+ CARD16 height)
+{
+ RegionRec region;
+ int n;
+ BoxPtr pbox;
+ CompositeFunc func;
+ Bool srcRepeat = pSrc->repeat;
+ Bool maskRepeat = FALSE;
+ Bool srcAlphaMap = pSrc->alphaMap != 0;
+ Bool maskAlphaMap = FALSE;
+ Bool dstAlphaMap = pDst->alphaMap != 0;
+ int x_msk, y_msk, x_src, y_src, x_dst, y_dst;
+ int w, h, w_this, h_this;
+
+ xDst += pDst->pDrawable->x;
+ yDst += pDst->pDrawable->y;
+ xSrc += pSrc->pDrawable->x;
+ ySrc += pSrc->pDrawable->y;
+ if (pMask)
+ {
+ xMask += pMask->pDrawable->x;
+ yMask += pMask->pDrawable->y;
+ maskRepeat = pMask->repeat;
+ maskAlphaMap = pMask->alphaMap != 0;
+ }
+
+ if (!miComputeCompositeRegion (&region,
+ pSrc,
+ pMask,
+ pDst,
+ xSrc,
+ ySrc,
+ xMask,
+ yMask,
+ xDst,
+ yDst,
+ width,
+ height))
+ return;
+
+ func = fbCompositeGeneral;
+ if (!pSrc->transform && !(pMask && pMask->transform))
+ if (!maskAlphaMap && !srcAlphaMap && !dstAlphaMap)
+ switch (op) {
+ case PictOpOver:
+ if (pMask)
+ {
+ if (srcRepeat &&
+ pSrc->pDrawable->width == 1 &&
+ pSrc->pDrawable->height == 1)
+ {
+ srcRepeat = FALSE;
+ if (PICT_FORMAT_COLOR(pSrc->format)) {
+ switch (pMask->format) {
+ case PICT_a8:
+ switch (pDst->format) {
+ case PICT_r5g6b5:
+ case PICT_b5g6r5:
+ func = fbCompositeSolidMask_nx8x0565;
+ break;
+ case PICT_r8g8b8:
+ case PICT_b8g8r8:
+ func = fbCompositeSolidMask_nx8x0888;
+ break;
+ case PICT_a8r8g8b8:
+ case PICT_x8r8g8b8:
+ case PICT_a8b8g8r8:
+ case PICT_x8b8g8r8:
+ func = fbCompositeSolidMask_nx8x8888;
+ break;
+ }
+ break;
+ case PICT_a8r8g8b8:
+ if (pMask->componentAlpha) {
+ switch (pDst->format) {
+ case PICT_a8r8g8b8:
+ case PICT_x8r8g8b8:
+ func = fbCompositeSolidMask_nx8888x8888C;
+ break;
+ case PICT_r5g6b5:
+ func = fbCompositeSolidMask_nx8888x0565C;
+ break;
+ }
+ }
+ break;
+ case PICT_a8b8g8r8:
+ if (pMask->componentAlpha) {
+ switch (pDst->format) {
+ case PICT_a8b8g8r8:
+ case PICT_x8b8g8r8:
+ func = fbCompositeSolidMask_nx8888x8888C;
+ break;
+ case PICT_b5g6r5:
+ func = fbCompositeSolidMask_nx8888x0565C;
+ break;
+ }
+ }
+ break;
+ case PICT_a1:
+ switch (pDst->format) {
+ case PICT_r5g6b5:
+ case PICT_b5g6r5:
+ case PICT_r8g8b8:
+ case PICT_b8g8r8:
+ case PICT_a8r8g8b8:
+ case PICT_x8r8g8b8:
+ case PICT_a8b8g8r8:
+ case PICT_x8b8g8r8:
+ func = fbCompositeSolidMask_nx1xn;
+ break;
+ }
+ }
+ }
+ }
+ }
+ else
+ {
+ switch (pSrc->format) {
+ case PICT_a8r8g8b8:
+ case PICT_x8r8g8b8:
+ switch (pDst->format) {
+ case PICT_a8r8g8b8:
+ case PICT_x8r8g8b8:
+ func = fbCompositeSrc_8888x8888;
+ break;
+ case PICT_r8g8b8:
+ func = fbCompositeSrc_8888x0888;
+ break;
+ case PICT_r5g6b5:
+ func = fbCompositeSrc_8888x0565;
+ break;
+ }
+ break;
+ case PICT_a8b8g8r8:
+ case PICT_x8b8g8r8:
+ switch (pDst->format) {
+ case PICT_a8b8g8r8:
+ case PICT_x8b8g8r8:
+ func = fbCompositeSrc_8888x8888;
+ break;
+ case PICT_b8g8r8:
+ func = fbCompositeSrc_8888x0888;
+ break;
+ case PICT_b5g6r5:
+ func = fbCompositeSrc_8888x0565;
+ break;
+ }
+ break;
+ case PICT_r5g6b5:
+ switch (pDst->format) {
+ case PICT_r5g6b5:
+ func = fbCompositeSrc_0565x0565;
+ break;
+ }
+ break;
+ case PICT_b5g6r5:
+ switch (pDst->format) {
+ case PICT_b5g6r5:
+ func = fbCompositeSrc_0565x0565;
+ break;
+ }
+ break;
+ }
+ }
+ break;
+ case PictOpAdd:
+ if (pMask == 0)
+ {
+ switch (pSrc->format) {
+ case PICT_a8r8g8b8:
+ switch (pDst->format) {
+ case PICT_a8r8g8b8:
+ func = fbCompositeSrcAdd_8888x8888;
+ break;
+ }
+ break;
+ case PICT_a8b8g8r8:
+ switch (pDst->format) {
+ case PICT_a8b8g8r8:
+ func = fbCompositeSrcAdd_8888x8888;
+ break;
+ }
+ break;
+ case PICT_a8:
+ switch (pDst->format) {
+ case PICT_a8:
+ func = fbCompositeSrcAdd_8000x8000;
+ break;
+ }
+ break;
+ case PICT_a1:
+ switch (pDst->format) {
+ case PICT_a1:
+ func = fbCompositeSrcAdd_1000x1000;
+ break;
+ }
+ break;
+ }
+ }
+ break;
+ }
+ n = REGION_NUM_RECTS (&region);
+ pbox = REGION_RECTS (&region);
+ while (n--)
+ {
+ h = pbox->y2 - pbox->y1;
+ y_src = pbox->y1 - yDst + ySrc;
+ y_msk = pbox->y1 - yDst + yMask;
+ y_dst = pbox->y1;
+ while (h)
+ {
+ h_this = h;
+ w = pbox->x2 - pbox->x1;
+ x_src = pbox->x1 - xDst + xSrc;
+ x_msk = pbox->x1 - xDst + xMask;
+ x_dst = pbox->x1;
+ if (maskRepeat)
+ {
+ y_msk = mod (y_msk, pMask->pDrawable->height);
+ if (h_this > pMask->pDrawable->height - y_msk)
+ h_this = pMask->pDrawable->height - y_msk;
+ }
+ if (srcRepeat)
+ {
+ y_src = mod (y_src, pSrc->pDrawable->height);
+ if (h_this > pSrc->pDrawable->height - y_src)
+ h_this = pSrc->pDrawable->height - y_src;
+ }
+ while (w)
+ {
+ w_this = w;
+ if (maskRepeat)
+ {
+ x_msk = mod (x_msk, pMask->pDrawable->width);
+ if (w_this > pMask->pDrawable->width - x_msk)
+ w_this = pMask->pDrawable->width - x_msk;
+ }
+ if (srcRepeat)
+ {
+ x_src = mod (x_src, pSrc->pDrawable->width);
+ if (w_this > pSrc->pDrawable->width - x_src)
+ w_this = pSrc->pDrawable->width - x_src;
+ }
+ (*func) (op, pSrc, pMask, pDst,
+ x_src, y_src, x_msk, y_msk, x_dst, y_dst,
+ w_this, h_this);
+ w -= w_this;
+ x_src += w_this;
+ x_msk += w_this;
+ x_dst += w_this;
+ }
+ h -= h_this;
+ y_src += h_this;
+ y_msk += h_this;
+ y_dst += h_this;
+ }
+ pbox++;
+ }
+ REGION_UNINIT (pDst->pDrawable->pScreen, &region);
+}
+
+#endif /* RENDER */
+
+Bool
+fbPictureInit (ScreenPtr pScreen, PictFormatPtr formats, int nformats)
+{
+
+#ifdef RENDER
+
+ PictureScreenPtr ps;
+
+ if (!miPictureInit (pScreen, formats, nformats))
+ return FALSE;
+ ps = GetPictureScreen(pScreen);
+ ps->Composite = fbComposite;
+ ps->Glyphs = miGlyphs;
+ ps->CompositeRects = miCompositeRects;
+ ps->RasterizeTrapezoid = fbRasterizeTrapezoid;
+
+#endif /* RENDER */
+
+ return TRUE;
+}