1241 lines
36 KiB
C
1241 lines
36 KiB
C
|
/*
|
||
|
*
|
||
|
* 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.
|
||
|
*/
|
||
|
|
||
|
#ifdef HAVE_DIX_CONFIG_H
|
||
|
#include <dix-config.h>
|
||
|
#endif
|
||
|
|
||
|
#include <string.h>
|
||
|
|
||
|
#include "fb.h"
|
||
|
|
||
|
|
||
|
#include "picturestr.h"
|
||
|
#include "mipict.h"
|
||
|
#include "fbpict.h"
|
||
|
|
||
|
typedef void (*CompositeFunc) (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
|
||
|
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;
|
||
|
}
|
||
|
|
||
|
/*
|
||
|
* 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, pDst->format);
|
||
|
|
||
|
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, pDst->format);
|
||
|
|
||
|
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, pDst->format);
|
||
|
|
||
|
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, pDst->format);
|
||
|
|
||
|
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, pDst->format);
|
||
|
|
||
|
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, pDst->format);
|
||
|
|
||
|
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 = NULL;
|
||
|
|
||
|
Bool srcRepeat = pSrc->pDrawable && 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;
|
||
|
if (pSrc->pDrawable) {
|
||
|
xSrc += pSrc->pDrawable->x;
|
||
|
ySrc += pSrc->pDrawable->y;
|
||
|
}
|
||
|
if (pMask && pMask->pDrawable) {
|
||
|
xMask += pMask->pDrawable->x;
|
||
|
yMask += pMask->pDrawable->y;
|
||
|
maskRepeat = pMask->repeat == RepeatNormal;
|
||
|
maskAlphaMap = pMask->alphaMap != 0;
|
||
|
}
|
||
|
|
||
|
if (pSrc->pDrawable && (!pMask || pMask->pDrawable)
|
||
|
&& !pSrc->transform && !(pMask && pMask->transform)
|
||
|
&& !maskAlphaMap && !srcAlphaMap && !dstAlphaMap
|
||
|
&& (pSrc->filter != PictFilterConvolution)
|
||
|
&& (!pMask || pMask->filter != PictFilterConvolution))
|
||
|
switch (op) {
|
||
|
case PictOpSrc:
|
||
|
break;
|
||
|
case PictOpOver:
|
||
|
if (pMask) {
|
||
|
if (fbCanGetSolid(pSrc) && !maskRepeat) {
|
||
|
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;
|
||
|
default:
|
||
|
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;
|
||
|
default:
|
||
|
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;
|
||
|
default:
|
||
|
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;
|
||
|
default:
|
||
|
break;
|
||
|
}
|
||
|
break;
|
||
|
default:
|
||
|
break;
|
||
|
}
|
||
|
default:
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
else if (!srcRepeat) { /* has mask and non-repeating source */
|
||
|
if (pSrc->pDrawable == pMask->pDrawable &&
|
||
|
xSrc == xMask && ySrc == yMask &&
|
||
|
!pMask->componentAlpha && !maskRepeat) {
|
||
|
/* source == mask: non-premultiplied data */
|
||
|
switch (pSrc->format) {
|
||
|
case PICT_x8b8g8r8:
|
||
|
switch (pMask->format) {
|
||
|
case PICT_a8r8g8b8:
|
||
|
case PICT_a8b8g8r8:
|
||
|
switch (pDst->format) {
|
||
|
case PICT_a8r8g8b8:
|
||
|
case PICT_x8r8g8b8:
|
||
|
break;
|
||
|
case PICT_r5g6b5:
|
||
|
break;
|
||
|
default:
|
||
|
break;
|
||
|
}
|
||
|
break;
|
||
|
default:
|
||
|
break;
|
||
|
}
|
||
|
break;
|
||
|
case PICT_x8r8g8b8:
|
||
|
switch (pMask->format) {
|
||
|
case PICT_a8r8g8b8:
|
||
|
case PICT_a8b8g8r8:
|
||
|
switch (pDst->format) {
|
||
|
case PICT_a8b8g8r8:
|
||
|
case PICT_x8b8g8r8:
|
||
|
break;
|
||
|
case PICT_r5g6b5:
|
||
|
break;
|
||
|
default:
|
||
|
break;
|
||
|
}
|
||
|
break;
|
||
|
default:
|
||
|
break;
|
||
|
}
|
||
|
break;
|
||
|
default:
|
||
|
break;
|
||
|
}
|
||
|
break;
|
||
|
}
|
||
|
else {
|
||
|
/* non-repeating source, repeating mask => translucent window */
|
||
|
if (fbCanGetSolid(pMask)) {
|
||
|
if (pSrc->format == PICT_x8r8g8b8 &&
|
||
|
pDst->format == PICT_x8r8g8b8 &&
|
||
|
pMask->format == PICT_a8) {
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
else { /* no mask */
|
||
|
|
||
|
if (fbCanGetSolid(pSrc)) {
|
||
|
/* no mask and repeating source */
|
||
|
switch (pSrc->format) {
|
||
|
case PICT_a8r8g8b8:
|
||
|
switch (pDst->format) {
|
||
|
case PICT_a8r8g8b8:
|
||
|
case PICT_x8r8g8b8:
|
||
|
break;
|
||
|
case PICT_r5g6b5:
|
||
|
break;
|
||
|
default:
|
||
|
break;
|
||
|
}
|
||
|
break;
|
||
|
default:
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
else if (!srcRepeat) {
|
||
|
switch (pSrc->format) {
|
||
|
case PICT_a8r8g8b8:
|
||
|
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;
|
||
|
default:
|
||
|
break;
|
||
|
}
|
||
|
break;
|
||
|
case PICT_x8r8g8b8:
|
||
|
switch (pDst->format) {
|
||
|
case PICT_a8r8g8b8:
|
||
|
case PICT_x8r8g8b8:
|
||
|
break;
|
||
|
default:
|
||
|
break;
|
||
|
}
|
||
|
case PICT_x8b8g8r8:
|
||
|
switch (pDst->format) {
|
||
|
case PICT_a8b8g8r8:
|
||
|
case PICT_x8b8g8r8:
|
||
|
break;
|
||
|
default:
|
||
|
break;
|
||
|
}
|
||
|
break;
|
||
|
case PICT_a8b8g8r8:
|
||
|
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;
|
||
|
default:
|
||
|
break;
|
||
|
}
|
||
|
break;
|
||
|
case PICT_r5g6b5:
|
||
|
switch (pDst->format) {
|
||
|
case PICT_r5g6b5:
|
||
|
func = fbCompositeSrc_0565x0565;
|
||
|
break;
|
||
|
default:
|
||
|
break;
|
||
|
}
|
||
|
break;
|
||
|
case PICT_b5g6r5:
|
||
|
switch (pDst->format) {
|
||
|
case PICT_b5g6r5:
|
||
|
func = fbCompositeSrc_0565x0565;
|
||
|
break;
|
||
|
default:
|
||
|
break;
|
||
|
}
|
||
|
break;
|
||
|
default:
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
break;
|
||
|
case PictOpAdd:
|
||
|
if (pMask == 0) {
|
||
|
switch (pSrc->format) {
|
||
|
case PICT_a8r8g8b8:
|
||
|
switch (pDst->format) {
|
||
|
case PICT_a8r8g8b8:
|
||
|
func = fbCompositeSrcAdd_8888x8888;
|
||
|
break;
|
||
|
default:
|
||
|
break;
|
||
|
}
|
||
|
break;
|
||
|
case PICT_a8b8g8r8:
|
||
|
switch (pDst->format) {
|
||
|
case PICT_a8b8g8r8:
|
||
|
func = fbCompositeSrcAdd_8888x8888;
|
||
|
break;
|
||
|
default:
|
||
|
break;
|
||
|
}
|
||
|
break;
|
||
|
case PICT_a8:
|
||
|
switch (pDst->format) {
|
||
|
case PICT_a8:
|
||
|
func = fbCompositeSrcAdd_8000x8000;
|
||
|
break;
|
||
|
default:
|
||
|
break;
|
||
|
}
|
||
|
break;
|
||
|
case PICT_a1:
|
||
|
switch (pDst->format) {
|
||
|
case PICT_a1:
|
||
|
func = fbCompositeSrcAdd_1000x1000;
|
||
|
break;
|
||
|
default:
|
||
|
break;
|
||
|
}
|
||
|
break;
|
||
|
default:
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
if (!func) {
|
||
|
/* no fast path, use the general code */
|
||
|
fbCompositeGeneral(op, pSrc, pMask, pDst, xSrc, ySrc, xMask, yMask,
|
||
|
xDst, yDst, width, height);
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
if (!miComputeCompositeRegion(®ion,
|
||
|
pSrc,
|
||
|
pMask,
|
||
|
pDst,
|
||
|
xSrc,
|
||
|
ySrc,
|
||
|
xMask, yMask, xDst, yDst, width, height))
|
||
|
return;
|
||
|
|
||
|
n = REGION_NUM_RECTS(®ion);
|
||
|
pbox = REGION_RECTS(®ion);
|
||
|
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->y, pMask->pDrawable->height);
|
||
|
if (h_this > pMask->pDrawable->height - y_msk)
|
||
|
h_this = pMask->pDrawable->height - y_msk;
|
||
|
y_msk += pMask->pDrawable->y;
|
||
|
}
|
||
|
if (srcRepeat) {
|
||
|
y_src =
|
||
|
mod(y_src - pSrc->pDrawable->y, pSrc->pDrawable->height);
|
||
|
if (h_this > pSrc->pDrawable->height - y_src)
|
||
|
h_this = pSrc->pDrawable->height - y_src;
|
||
|
y_src += pSrc->pDrawable->y;
|
||
|
}
|
||
|
while (w) {
|
||
|
w_this = w;
|
||
|
if (maskRepeat) {
|
||
|
x_msk =
|
||
|
mod(x_msk - pMask->pDrawable->x,
|
||
|
pMask->pDrawable->width);
|
||
|
if (w_this > pMask->pDrawable->width - x_msk)
|
||
|
w_this = pMask->pDrawable->width - x_msk;
|
||
|
x_msk += pMask->pDrawable->x;
|
||
|
}
|
||
|
if (srcRepeat) {
|
||
|
x_src =
|
||
|
mod(x_src - pSrc->pDrawable->x, pSrc->pDrawable->width);
|
||
|
if (w_this > pSrc->pDrawable->width - x_src)
|
||
|