2868 lines
		
	
	
		
			67 KiB
		
	
	
	
		
			C
		
	
	
	
			
		
		
	
	
			2868 lines
		
	
	
		
			67 KiB
		
	
	
	
		
			C
		
	
	
	
| /*
 | |
|  * $XdotOrg: xc/programs/Xserver/fb/fbcompose.c,v 1.18 2003/12/04 17:15:12 tsi Exp $
 | |
|  * $XFree86: xc/programs/Xserver/fb/fbcompose.c,v 1.18 2003/12/04 17:15:12 tsi Exp $
 | |
|  *
 | |
|  * Copyright © 2000 Keith Packard, member of The XFree86 Project, 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 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.
 | |
|  */
 | |
| 
 | |
| #include "fb.h"
 | |
| #include "picturestr.h"
 | |
| #include "mipict.h"
 | |
| #include "fbpict.h"
 | |
| 
 | |
| /*
 | |
|  * General purpose compositing code optimized for minimal memory
 | |
|  * references
 | |
|  *
 | |
|  * All work is done on canonical ARGB values, functions for fetching
 | |
|  * and storing these exist for each format.
 | |
|  */
 | |
| 
 | |
| /*
 | |
|  * Combine src and mask using IN
 | |
|  */
 | |
| 
 | |
| CARD32
 | |
| fbCombineMaskU (FbCompositeOperand   *src,
 | |
| 		FbCompositeOperand   *msk)
 | |
| {
 | |
|     CARD32  x;
 | |
|     CARD16  a;
 | |
|     CARD16  t;
 | |
|     CARD32  m,n,o,p;
 | |
| 
 | |
|     if (!msk)
 | |
| 	return (*src->fetch) (src);
 | |
|     
 | |
|     a = (*msk->fetch) (msk) >> 24;
 | |
|     if (!a)
 | |
| 	return 0;
 | |
|     
 | |
|     x = (*src->fetch) (src);
 | |
|     if (a == 0xff)
 | |
| 	return x;
 | |
|     
 | |
|     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;
 | |
| }
 | |
| 
 | |
| FbCompSrc
 | |
| fbCombineMaskC (FbCompositeOperand   *src,
 | |
| 		FbCompositeOperand   *msk)
 | |
| {
 | |
|     FbCompSrc	s;
 | |
|     CARD32	x;
 | |
|     CARD32	a;
 | |
|     CARD16	xa;
 | |
|     CARD16	t;
 | |
|     CARD32	m,n,o,p;
 | |
| 
 | |
|     if (!msk)
 | |
|     {
 | |
| 	x = (*src->fetch) (src);
 | |
| 	s.value = x;
 | |
| 	x = x >> 24;
 | |
| 	x |= x << 8;
 | |
| 	x |= x << 16;
 | |
| 	s.alpha = x;
 | |
| 	return s;
 | |
|     }
 | |
|     
 | |
|     a = (*msk->fetcha) (msk);
 | |
|     if (!a)
 | |
|     {
 | |
| 	s.value = 0;
 | |
| 	s.alpha = 0;
 | |
| 	return s;
 | |
|     }
 | |
|     
 | |
|     x = (*src->fetch) (src);
 | |
|     if (a == 0xffffffff)
 | |
|     {
 | |
| 	s.value = x;
 | |
| 	x = x >> 24;
 | |
| 	x |= x << 8;
 | |
| 	x |= x << 16;
 | |
| 	s.alpha = x;
 | |
| 	return s;
 | |
|     }
 | |
|     
 | |
|     m = FbInC(x,0,a,t);
 | |
|     n = FbInC(x,8,a,t);
 | |
|     o = FbInC(x,16,a,t);
 | |
|     p = FbInC(x,24,a,t);
 | |
|     s.value = m|n|o|p;
 | |
|     xa = x >> 24;
 | |
|     m = FbInU(a,0,xa,t);
 | |
|     n = FbInU(a,8,xa,t);
 | |
|     o = FbInU(a,16,xa,t);
 | |
|     p = FbInU(a,24,xa,t);
 | |
|     s.alpha = m|n|o|p;
 | |
|     return s;
 | |
| }
 | |
| 
 | |
| CARD32
 | |
| fbCombineMaskValueC (FbCompositeOperand   *src,
 | |
| 		     FbCompositeOperand   *msk)
 | |
| {
 | |
|     CARD32	x;
 | |
|     CARD32	a;
 | |
|     CARD16	t;
 | |
|     CARD32	m,n,o,p;
 | |
| 
 | |
|     if (!msk)
 | |
|     {
 | |
| 	return (*src->fetch) (src);
 | |
|     }
 | |
|     
 | |
|     a = (*msk->fetcha) (msk);
 | |
|     if (!a)
 | |
| 	return a;
 | |
|     
 | |
|     x = (*src->fetch) (src);
 | |
|     if (a == 0xffffffff)
 | |
| 	return x;
 | |
|     
 | |
|     m = FbInC(x,0,a,t);
 | |
|     n = FbInC(x,8,a,t);
 | |
|     o = FbInC(x,16,a,t);
 | |
|     p = FbInC(x,24,a,t);
 | |
|     return m|n|o|p;
 | |
| }
 | |
| 
 | |
| /*
 | |
|  * Combine src and mask using IN, generating only the alpha component
 | |
|  */
 | |
| CARD32
 | |
| fbCombineMaskAlphaU (FbCompositeOperand   *src,
 | |
| 		     FbCompositeOperand   *msk)
 | |
| {
 | |
|     CARD32  x;
 | |
|     CARD16  a;
 | |
|     CARD16  t;
 | |
| 
 | |
|     if (!msk)
 | |
| 	return (*src->fetch) (src);
 | |
|     
 | |
|     a = (*msk->fetch) (msk) >> 24;
 | |
|     if (!a)
 | |
| 	return 0;
 | |
|     
 | |
|     x = (*src->fetch) (src);
 | |
|     if (a == 0xff)
 | |
| 	return x;
 | |
|     
 | |
|     return FbInU(x,24,a,t);
 | |
| }
 | |
| 
 | |
| CARD32
 | |
| fbCombineMaskAlphaC (FbCompositeOperand   *src,
 | |
| 		     FbCompositeOperand   *msk)
 | |
| {
 | |
|     CARD32	x;
 | |
|     CARD32	a;
 | |
|     CARD16	t;
 | |
|     CARD32	m,n,o,p;
 | |
| 
 | |
|     if (!msk)
 | |
| 	return (*src->fetch) (src);
 | |
|     
 | |
|     a = (*msk->fetcha) (msk);
 | |
|     if (!a)
 | |
| 	return 0;
 | |
|     
 | |
|     x = (*src->fetcha) (src);
 | |
|     if (a == 0xffffffff)
 | |
| 	return x;
 | |
|     
 | |
|     m = FbInC(x,0,a,t);
 | |
|     n = FbInC(x,8,a,t);
 | |
|     o = FbInC(x,16,a,t);
 | |
|     p = FbInC(x,24,a,t);
 | |
|     return m|n|o|p;
 | |
| }
 | |
| 
 | |
| /*
 | |
|  * All of the composing functions
 | |
|  */
 | |
| void
 | |
| fbCombineClear (FbCompositeOperand   *src,
 | |
| 		FbCompositeOperand   *msk,
 | |
| 		FbCompositeOperand   *dst)
 | |
| {
 | |
|     (*dst->store) (dst, 0);
 | |
| }
 | |
| 
 | |
| void
 | |
| fbCombineSrcU (FbCompositeOperand    *src,
 | |
| 	       FbCompositeOperand    *msk,
 | |
| 	       FbCompositeOperand    *dst)
 | |
| {
 | |
|     (*dst->store) (dst, fbCombineMaskU (src, msk));
 | |
| }
 | |
| 
 | |
| void
 | |
| fbCombineSrcC (FbCompositeOperand    *src,
 | |
| 	       FbCompositeOperand    *msk,
 | |
| 	       FbCompositeOperand    *dst)
 | |
| {
 | |
|     (*dst->store) (dst, fbCombineMaskValueC (src, msk));
 | |
| }
 | |
| 
 | |
| void
 | |
| fbCombineDst (FbCompositeOperand    *src,
 | |
| 	      FbCompositeOperand    *msk,
 | |
| 	      FbCompositeOperand    *dst)
 | |
| {
 | |
|     /* noop */
 | |
| }
 | |
| 
 | |
| void
 | |
| fbCombineOverU (FbCompositeOperand   *src,
 | |
| 		FbCompositeOperand   *msk,
 | |
| 		FbCompositeOperand   *dst)
 | |
| {
 | |
|     CARD32  s, d;
 | |
|     CARD16  a;
 | |
|     CARD16  t;
 | |
|     CARD32  m,n,o,p;
 | |
| 
 | |
|     s = fbCombineMaskU (src, msk);
 | |
|     a = ~s >> 24;
 | |
|     if (a != 0xff)
 | |
|     {
 | |
| 	if (a)
 | |
| 	{
 | |
| 	    d = (*dst->fetch) (dst);
 | |
| 	    m = FbOverU(s,d,0,a,t);
 | |
| 	    n = FbOverU(s,d,8,a,t);
 | |
| 	    o = FbOverU(s,d,16,a,t);
 | |
| 	    p = FbOverU(s,d,24,a,t);
 | |
| 	    s = m|n|o|p;
 | |
| 	}
 | |
| 	(*dst->store) (dst, s);
 | |
|     }
 | |
| }
 | |
| 
 | |
| void
 | |
| fbCombineOverC (FbCompositeOperand   *src,
 | |
| 		FbCompositeOperand   *msk,
 | |
| 		FbCompositeOperand   *dst)
 | |
| {
 | |
|     FbCompSrc	cs;
 | |
|     CARD32  s, d;
 | |
|     CARD32  a;
 | |
|     CARD16  t;
 | |
|     CARD32  m,n,o,p;
 | |
| 
 | |
|     cs = fbCombineMaskC (src, msk);
 | |
|     s = cs.value;
 | |
|     a = ~cs.alpha;
 | |
|     if (a != 0xffffffff)
 | |
|     {
 | |
| 	if (a)
 | |
| 	{
 | |
| 	    d = (*dst->fetch) (dst);
 | |
| 	    m = FbOverC(s,d,0,a,t);
 | |
| 	    n = FbOverC(s,d,8,a,t);
 | |
| 	    o = FbOverC(s,d,16,a,t);
 | |
| 	    p = FbOverC(s,d,24,a,t);
 | |
| 	    s = m|n|o|p;
 | |
| 	}
 | |
| 	(*dst->store) (dst, s);
 | |
|     }
 | |
| }
 | |
| 
 | |
| void
 | |
| fbCombineOverReverseU (FbCompositeOperand    *src,
 | |
| 		       FbCompositeOperand    *msk,
 | |
| 		       FbCompositeOperand    *dst)
 | |
| {
 | |
|     CARD32  s, d;
 | |
|     CARD16  a;
 | |
|     CARD16  t;
 | |
|     CARD32  m,n,o,p;
 | |
| 
 | |
|     d = (*dst->fetch) (dst);
 | |
|     a = ~d >> 24;
 | |
|     if (a)
 | |
|     {
 | |
| 	s = fbCombineMaskU (src, msk);
 | |
| 	if (a != 0xff)
 | |
| 	{
 | |
| 	    m = FbOverU(d,s,0,a,t);
 | |
| 	    n = FbOverU(d,s,8,a,t);
 | |
| 	    o = FbOverU(d,s,16,a,t);
 | |
| 	    p = FbOverU(d,s,24,a,t);
 | |
| 	    s = m|n|o|p;
 | |
| 	}
 | |
| 	(*dst->store) (dst, s);
 | |
|     }
 | |
| }
 | |
| 
 | |
| void
 | |
| fbCombineOverReverseC (FbCompositeOperand    *src,
 | |
| 		       FbCompositeOperand    *msk,
 | |
| 		       FbCompositeOperand    *dst)
 | |
| {
 | |
|     CARD32  s, d;
 | |
|     CARD32  a;
 | |
|     CARD16  t;
 | |
|     CARD32  m,n,o,p;
 | |
| 
 | |
|     d = (*dst->fetch) (dst);
 | |
|     a = ~d >> 24;
 | |
|     if (a)
 | |
|     {
 | |
| 	s = fbCombineMaskValueC (src, msk);
 | |
| 	if (a != 0xff)
 | |
| 	{
 | |
| 	    m = FbOverU(d,s,0,a,t);
 | |
| 	    n = FbOverU(d,s,8,a,t);
 | |
| 	    o = FbOverU(d,s,16,a,t);
 | |
| 	    p = FbOverU(d,s,24,a,t);
 | |
| 	    s = m|n|o|p;
 | |
| 	}
 | |
| 	(*dst->store) (dst, s);
 | |
|     }
 | |
| }
 | |
| 
 | |
| void
 | |
| fbCombineInU (FbCompositeOperand	    *src,
 | |
| 	      FbCompositeOperand	    *msk,
 | |
| 	      FbCompositeOperand	    *dst)
 | |
| {
 | |
|     CARD32  s, d;
 | |
|     CARD16  a;
 | |
|     CARD16  t;
 | |
|     CARD32  m,n,o,p;
 | |
| 
 | |
|     d = (*dst->fetch) (dst);
 | |
|     a = d >> 24;
 | |
|     s = 0;
 | |
|     if (a)
 | |
|     {
 | |
| 	s = fbCombineMaskU (src, msk);
 | |
| 	if (a != 0xff)
 | |
| 	{
 | |
| 	    m = FbInU(s,0,a,t);
 | |
| 	    n = FbInU(s,8,a,t);
 | |
| 	    o = FbInU(s,16,a,t);
 | |
| 	    p = FbInU(s,24,a,t);
 | |
| 	    s = m|n|o|p;
 | |
| 	}
 | |
|     }
 | |
|     (*dst->store) (dst, s);
 | |
| }
 | |
| 
 | |
| void
 | |
| fbCombineInC (FbCompositeOperand	    *src,
 | |
| 	      FbCompositeOperand	    *msk,
 | |
| 	      FbCompositeOperand	    *dst)
 | |
| {
 | |
|     CARD32  s, d;
 | |
|     CARD16  a;
 | |
|     CARD16  t;
 | |
|     CARD32  m,n,o,p;
 | |
| 
 | |
|     d = (*dst->fetch) (dst);
 | |
|     a = d >> 24;
 | |
|     s = 0;
 | |
|     if (a)
 | |
|     {
 | |
| 	s = fbCombineMaskValueC (src, msk);
 | |
| 	if (a != 0xff)
 | |
| 	{
 | |
| 	    m = FbInU(s,0,a,t);
 | |
| 	    n = FbInU(s,8,a,t);
 | |
| 	    o = FbInU(s,16,a,t);
 | |
| 	    p = FbInU(s,24,a,t);
 | |
| 	    s = m|n|o|p;
 | |
| 	}
 | |
|     }
 | |
|     (*dst->store) (dst, s);
 | |
| }
 | |
| 
 | |
| void
 | |
| fbCombineInReverseU (FbCompositeOperand  *src,
 | |
| 		     FbCompositeOperand  *msk,
 | |
| 		     FbCompositeOperand  *dst)
 | |
| {
 | |
|     CARD32  s, d;
 | |
|     CARD16  a;
 | |
|     CARD16  t;
 | |
|     CARD32  m,n,o,p;
 | |
| 
 | |
|     s = fbCombineMaskAlphaU (src, msk);
 | |
|     a = s >> 24;
 | |
|     if (a != 0xff)
 | |
|     {
 | |
| 	d = 0;
 | |
| 	if (a)
 | |
| 	{
 | |
| 	    d = (*dst->fetch) (dst);
 | |
| 	    m = FbInU(d,0,a,t);
 | |
| 	    n = FbInU(d,8,a,t);
 | |
| 	    o = FbInU(d,16,a,t);
 | |
| 	    p = FbInU(d,24,a,t);
 | |
| 	    d = m|n|o|p;
 | |
| 	}
 | |
| 	(*dst->store) (dst, d);
 | |
|     }
 | |
| }
 | |
| 
 | |
| void
 | |
| fbCombineInReverseC (FbCompositeOperand  *src,
 | |
| 		     FbCompositeOperand  *msk,
 | |
| 		     FbCompositeOperand  *dst)
 | |
| {
 | |
|     CARD32  s, d;
 | |
|     CARD32  a;
 | |
|     CARD16  t;
 | |
|     CARD32  m,n,o,p;
 | |
| 
 | |
|     s = fbCombineMaskAlphaC (src, msk);
 | |
|     a = s;
 | |
|     if (a != 0xffffffff)
 | |
|     {
 | |
| 	d = 0;
 | |
| 	if (a)
 | |
| 	{
 | |
| 	    d = (*dst->fetch) (dst);
 | |
| 	    m = FbInC(d,0,a,t);
 | |
| 	    n = FbInC(d,8,a,t);
 | |
| 	    o = FbInC(d,16,a,t);
 | |
| 	    p = FbInC(d,24,a,t);
 | |
| 	    d = m|n|o|p;
 | |
| 	}
 | |
| 	(*dst->store) (dst, d);
 | |
|     }
 | |
| }
 | |
| 
 | |
| void
 | |
| fbCombineOutU (FbCompositeOperand    *src,
 | |
| 	       FbCompositeOperand    *msk,
 | |
| 	       FbCompositeOperand    *dst)
 | |
| {
 | |
|     CARD32  s, d;
 | |
|     CARD16  a;
 | |
|     CARD16  t;
 | |
|     CARD32  m,n,o,p;
 | |
| 
 | |
|     d = (*dst->fetch) (dst);
 | |
|     a = ~d >> 24;
 | |
|     s = 0;
 | |
|     if (a)
 | |
|     {
 | |
| 	s = fbCombineMaskU (src, msk);
 | |
| 	if (a != 0xff)
 | |
| 	{
 | |
| 	    m = FbInU(s,0,a,t);
 | |
| 	    n = FbInU(s,8,a,t);
 | |
| 	    o = FbInU(s,16,a,t);
 | |
| 	    p = FbInU(s,24,a,t);
 | |
| 	    s = m|n|o|p;
 | |
| 	}
 | |
|     }
 | |
|     (*dst->store) (dst, s);
 | |
| }
 | |
| 
 | |
| void
 | |
| fbCombineOutC (FbCompositeOperand    *src,
 | |
| 	       FbCompositeOperand    *msk,
 | |
| 	       FbCompositeOperand    *dst)
 | |
| {
 | |
|     CARD32  s, d;
 | |
|     CARD16  a;
 | |
|     CARD16  t;
 | |
|     CARD32  m,n,o,p;
 | |
| 
 | |
|     d = (*dst->fetch) (dst);
 | |
|     a = ~d >> 24;
 | |
|     s = 0;
 | |
|     if (a)
 | |
|     {
 | |
| 	s = fbCombineMaskValueC (src, msk);
 | |
| 	if (a != 0xff)
 | |
| 	{
 | |
| 	    m = FbInU(s,0,a,t);
 | |
| 	    n = FbInU(s,8,a,t);
 | |
| 	    o = FbInU(s,16,a,t);
 | |
| 	    p = FbInU(s,24,a,t);
 | |
| 	    s = m|n|o|p;
 | |
| 	}
 | |
|     }
 | |
|     (*dst->store) (dst, s);
 | |
| }
 | |
| 
 | |
| void
 | |
| fbCombineOutReverseU (FbCompositeOperand *src,
 | |
| 		      FbCompositeOperand *msk,
 | |
| 		      FbCompositeOperand *dst)
 | |
| {
 | |
|     CARD32  s, d;
 | |
|     CARD16  a;
 | |
|     CARD16  t;
 | |
|     CARD32  m,n,o,p;
 | |
| 
 | |
|     s = fbCombineMaskAlphaU (src, msk);
 | |
|     a = ~s >> 24;
 | |
|     if (a != 0xff)
 | |
|     {
 | |
| 	d = 0;
 | |
| 	if (a)
 | |
| 	{
 | |
| 	    d = (*dst->fetch) (dst);
 | |
| 	    m = FbInU(d,0,a,t);
 | |
| 	    n = FbInU(d,8,a,t);
 | |
| 	    o = FbInU(d,16,a,t);
 | |
| 	    p = FbInU(d,24,a,t);
 | |
| 	    d = m|n|o|p;
 | |
| 	}
 | |
| 	(*dst->store) (dst, d);
 | |
|     }
 | |
| }
 | |
| 
 | |
| void
 | |
| fbCombineOutReverseC (FbCompositeOperand *src,
 | |
| 		      FbCompositeOperand *msk,
 | |
| 		      FbCompositeOperand *dst)
 | |
| {
 | |
|     CARD32  s, d;
 | |
|     CARD32  a;
 | |
|     CARD16  t;
 | |
|     CARD32  m,n,o,p;
 | |
| 
 | |
|     s = fbCombineMaskAlphaC (src, msk);
 | |
|     a = ~s;
 | |
|     if (a != 0xffffffff)
 | |
|     {
 | |
| 	d = 0;
 | |
| 	if (a)
 | |
| 	{
 | |
| 	    d = (*dst->fetch) (dst);
 | |
| 	    m = FbInC(d,0,a,t);
 | |
| 	    n = FbInC(d,8,a,t);
 | |
| 	    o = FbInC(d,16,a,t);
 | |
| 	    p = FbInC(d,24,a,t);
 | |
| 	    d = m|n|o|p;
 | |
| 	}
 | |
| 	(*dst->store) (dst, d);
 | |
|     }
 | |
| }
 | |
| 
 | |
| void
 | |
| fbCombineAtopU (FbCompositeOperand   *src,
 | |
| 		FbCompositeOperand   *msk,
 | |
| 		FbCompositeOperand   *dst)
 | |
| {
 | |
|     CARD32  s, d;
 | |
|     CARD16  ad, as;
 | |
|     CARD16  t,u,v;
 | |
|     CARD32  m,n,o,p;
 | |
|     
 | |
|     s = fbCombineMaskU (src, msk);
 | |
|     d = (*dst->fetch) (dst);
 | |
|     ad = ~s >> 24;
 | |
|     as = d >> 24;
 | |
|     m = FbGen(s,d,0,as,ad,t,u,v);
 | |
|     n = FbGen(s,d,8,as,ad,t,u,v);
 | |
|     o = FbGen(s,d,16,as,ad,t,u,v);
 | |
|     p = FbGen(s,d,24,as,ad,t,u,v);
 | |
|     (*dst->store) (dst, m|n|o|p);
 | |
| }
 | |
| 
 | |
| void
 | |
| fbCombineAtopC (FbCompositeOperand   *src,
 | |
| 		FbCompositeOperand   *msk,
 | |
| 		FbCompositeOperand   *dst)
 | |
| {
 | |
|     FbCompSrc	cs;
 | |
|     CARD32  s, d;
 | |
|     CARD32  ad;
 | |
|     CARD16  as;
 | |
|     CARD16  t, u, v;
 | |
|     CARD32  m,n,o,p;
 | |
|     
 | |
|     cs = fbCombineMaskC (src, msk);
 | |
|     d = (*dst->fetch) (dst);
 | |
|     s = cs.value;
 | |
|     ad = cs.alpha;
 | |
|     as = d >> 24;
 | |
|     m = FbGen(s,d,0,as,FbGet8(ad,0),t,u,v);
 | |
|     n = FbGen(s,d,8,as,FbGet8(ad,8),t,u,v);
 | |
|     o = FbGen(s,d,16,as,FbGet8(ad,16),t,u,v);
 | |
|     p = FbGen(s,d,24,as,FbGet8(ad,24),t,u,v);
 | |
|     (*dst->store) (dst, m|n|o|p);
 | |
| }
 | |
| 
 | |
| void
 | |
| fbCombineAtopReverseU (FbCompositeOperand    *src,
 | |
| 		       FbCompositeOperand    *msk,
 | |
| 		       FbCompositeOperand    *dst)
 | |
| {
 | |
|     CARD32  s, d;
 | |
|     CARD16  ad, as;
 | |
|     CARD16  t, u, v;
 | |
|     CARD32  m,n,o,p;
 | |
|     
 | |
|     s = fbCombineMaskU (src, msk);
 | |
|     d = (*dst->fetch) (dst);
 | |
|     ad = s >> 24;
 | |
|     as = ~d >> 24;
 | |
|     m = FbGen(s,d,0,as,ad,t,u,v);
 | |
|     n = FbGen(s,d,8,as,ad,t,u,v);
 | |
|     o = FbGen(s,d,16,as,ad,t,u,v);
 | |
|     p = FbGen(s,d,24,as,ad,t,u,v);
 | |
|     (*dst->store) (dst, m|n|o|p);
 | |
| }
 | |
| 
 | |
| void
 | |
| fbCombineAtopReverseC (FbCompositeOperand    *src,
 | |
| 		       FbCompositeOperand    *msk,
 | |
| 		       FbCompositeOperand    *dst)
 | |
| {
 | |
|     FbCompSrc	cs;
 | |
|     CARD32  s, d, ad;
 | |
|     CARD16  as;
 | |
|     CARD16  t, u, v;
 | |
|     CARD32  m,n,o,p;
 | |
|     
 | |
|     cs = fbCombineMaskC (src, msk);
 | |
|     d = (*dst->fetch) (dst);
 | |
|     s = cs.value;
 | |
|     ad = cs.alpha;
 | |
|     as = ~d >> 24;
 | |
|     m = FbGen(s,d,0,as,FbGet8(ad,0),t,u,v);
 | |
|     n = FbGen(s,d,8,as,FbGet8(ad,8),t,u,v);
 | |
|     o = FbGen(s,d,16,as,FbGet8(ad,16),t,u,v);
 | |
|     p = FbGen(s,d,24,as,FbGet8(ad,24),t,u,v);
 | |
|     (*dst->store) (dst, m|n|o|p);
 | |
| }
 | |
| 
 | |
| void
 | |
| fbCombineXorU (FbCompositeOperand    *src,
 | |
| 	       FbCompositeOperand    *msk,
 | |
| 	       FbCompositeOperand    *dst)
 | |
| {
 | |
|     CARD32  s, d;
 | |
|     CARD16  ad, as;
 | |
|     CARD16  t, u, v;
 | |
|     CARD32  m,n,o,p;
 | |
|     
 | |
|     s = fbCombineMaskU (src, msk);
 | |
|     d = (*dst->fetch) (dst);
 | |
|     ad = ~s >> 24;
 | |
|     as = ~d >> 24;
 | |
|     m = FbGen(s,d,0,as,ad,t,u,v);
 | |
|     n = FbGen(s,d,8,as,ad,t,u,v);
 | |
|     o = FbGen(s,d,16,as,ad,t,u,v);
 | |
|     p = FbGen(s,d,24,as,ad,t,u,v);
 | |
|     (*dst->store) (dst, m|n|o|p);
 | |
| }
 | |
| 
 | |
| void
 | |
| fbCombineXorC (FbCompositeOperand    *src,
 | |
| 	       FbCompositeOperand    *msk,
 | |
| 	       FbCompositeOperand    *dst)
 | |
| {
 | |
|     FbCompSrc	cs;
 | |
|     CARD32  s, d, ad;
 | |
|     CARD16  as;
 | |
|     CARD16  t, u, v;
 | |
|     CARD32  m,n,o,p;
 | |
|     
 | |
|     cs = fbCombineMaskC (src, msk);
 | |
|     d = (*dst->fetch) (dst);
 | |
|     s = cs.value;
 | |
|     ad = ~cs.alpha;
 | |
|     as = ~d >> 24;
 | |
|     m = FbGen(s,d,0,as,ad,t,u,v);
 | |
|     n = FbGen(s,d,8,as,ad,t,u,v);
 | |
|     o = FbGen(s,d,16,as,ad,t,u,v);
 | |
|     p = FbGen(s,d,24,as,ad,t,u,v);
 | |
|     (*dst->store) (dst, m|n|o|p);
 | |
| }
 | |
| 
 | |
| void
 | |
| fbCombineAddU (FbCompositeOperand    *src,
 | |
| 	       FbCompositeOperand    *msk,
 | |
| 	       FbCompositeOperand    *dst)
 | |
| {
 | |
|     CARD32  s, d;
 | |
|     CARD16  t;
 | |
|     CARD32  m,n,o,p;
 | |
| 
 | |
|     s = fbCombineMaskU (src, msk);
 | |
|     if (s == ~0)
 | |
| 	(*dst->store) (dst, s);
 | |
|     else
 | |
|     {
 | |
| 	d = (*dst->fetch) (dst);
 | |
| 	if (s && d != ~0)
 | |
| 	{
 | |
| 	    m = FbAdd(s,d,0,t);
 | |
| 	    n = FbAdd(s,d,8,t);
 | |
| 	    o = FbAdd(s,d,16,t);
 | |
| 	    p = FbAdd(s,d,24,t);
 | |
| 	    (*dst->store) (dst, m|n|o|p);
 | |
| 	}
 | |
|     }
 | |
| }
 | |
| 
 | |
| void
 | |
| fbCombineAddC (FbCompositeOperand    *src,
 | |
| 	       FbCompositeOperand    *msk,
 | |
| 	       FbCompositeOperand    *dst)
 | |
| {
 | |
|     CARD32  s, d;
 | |
|     CARD16  t;
 | |
|     CARD32  m,n,o,p;
 | |
| 
 | |
|     s = fbCombineMaskValueC (src, msk);
 | |
|     if (s == ~0)
 | |
| 	(*dst->store) (dst, s);
 | |
|     else
 | |
|     {
 | |
| 	d = (*dst->fetch) (dst);
 | |
| 	if (s && d != ~0)
 | |
| 	{
 | |
| 	    m = FbAdd(s,d,0,t);
 | |
| 	    n = FbAdd(s,d,8,t);
 | |
| 	    o = FbAdd(s,d,16,t);
 | |
| 	    p = FbAdd(s,d,24,t);
 | |
| 	    (*dst->store) (dst, m|n|o|p);
 | |
| 	}
 | |
|     }
 | |
| }
 | |
| 
 | |
| void
 | |
| fbCombineSaturateU (FbCompositeOperand   *src,
 | |
| 		    FbCompositeOperand   *msk,
 | |
| 		    FbCompositeOperand   *dst)
 | |
| {
 | |
|     CARD32  s = fbCombineMaskU (src, msk), d;
 | |
| #if 0
 | |
|     CARD16  sa, da;
 | |
|     CARD16  ad, as;
 | |
|     CARD16  t;
 | |
|     CARD32  m,n,o,p;
 | |
|     
 | |
|     d = (*dst->fetch) (dst);
 | |
|     sa = s >> 24;
 | |
|     da = ~d >> 24;
 | |
|     if (sa <= da)
 | |
|     {
 | |
| 	m = FbAdd(s,d,0,t);
 | |
| 	n = FbAdd(s,d,8,t);
 | |
| 	o = FbAdd(s,d,16,t);
 | |
| 	p = FbAdd(s,d,24,t);
 | |
|     }
 | |
|     else
 | |
|     {
 | |
| 	as = (da << 8) / sa;
 | |
| 	ad = 0xff;
 | |
| 	m = FbGen(s,d,0,as,ad,t,u,v);
 | |
| 	n = FbGen(s,d,8,as,ad,t,u,v);
 | |
| 	o = FbGen(s,d,16,as,ad,t,u,v);
 | |
| 	p = FbGen(s,d,24,as,ad,t,u,v);
 | |
|     }
 | |
|     (*dst->store) (dst, m|n|o|p);
 | |
| #else
 | |
|     if ((s >> 24) == 0xff)
 | |
| 	(*dst->store) (dst, s);
 | |
|     else
 | |
|     {
 | |
| 	d = (*dst->fetch) (dst);
 | |
| 	if ((s >> 24) > (d >> 24))
 | |
| 	    (*dst->store) (dst, s);
 | |
|     }
 | |
| #endif
 | |
| }
 | |
| 
 | |
| void
 | |
| fbCombineSaturateC (FbCompositeOperand   *src,
 | |
| 		    FbCompositeOperand   *msk,
 | |
| 		    FbCompositeOperand   *dst)
 | |
| {
 | |
|     FbCompSrc	cs;
 | |
|     CARD32  s, d;
 | |
|     CARD16  sa, sr, sg, sb, da;
 | |
|     CARD16  t, u, v;
 | |
|     CARD32  m,n,o,p;
 | |
|     
 | |
|     cs = fbCombineMaskC (src, msk);
 | |
|     d = (*dst->fetch) (dst);
 | |
|     s = cs.value;
 | |
|     sa = (cs.alpha >> 24) & 0xff;
 | |
|     sr = (cs.alpha >> 16) & 0xff;
 | |
|     sg = (cs.alpha >>  8) & 0xff;
 | |
|     sb = (cs.alpha      ) & 0xff;
 | |
|     da = ~d >> 24;
 | |
|     
 | |
|     if (sb <= da)
 | |
| 	m = FbAdd(s,d,0,t);
 | |
|     else
 | |
| 	m = FbGen (s, d, 0, (da << 8) / sb, 0xff, t, u, v);
 | |
|     
 | |
|     if (sg <= da)
 | |
| 	n = FbAdd(s,d,8,t);
 | |
|     else
 | |
| 	n = FbGen (s, d, 8, (da << 8) / sg, 0xff, t, u, v);
 | |
|     
 | |
|     if (sr < da)
 | |
| 	o = FbAdd(s,d,16,t);
 | |
|     else
 | |
| 	o = FbGen (s, d, 16, (da << 8) / sr, 0xff, t, u, v);
 | |
| 
 | |
|     if (sa <= da)
 | |
| 	p = FbAdd(s,d,24,t);
 | |
|     else
 | |
| 	p = FbGen (s, d, 24, (da << 8) / sa, 0xff, t, u, v);
 | |
|     
 | |
|     (*dst->store) (dst, m|n|o|p);
 | |
| }
 | |
| 
 | |
| /*
 | |
|  * All of the disjoint composing functions
 | |
| 
 | |
|  The four entries in the first column indicate what source contributions
 | |
|  come from each of the four areas of the picture -- areas covered by neither
 | |
|  A nor B, areas covered only by A, areas covered only by B and finally
 | |
|  areas covered by both A and B.
 | |
|  
 | |
| 		Disjoint			Conjoint
 | |
| 		Fa		Fb		Fa		Fb
 | |
| (0,0,0,0)	0		0		0		0
 | |
| (0,A,0,A)	1		0		1		0
 | |
| (0,0,B,B)	0		1		0		1
 | |
| (0,A,B,A)	1		min((1-a)/b,1)	1		max(1-a/b,0)
 | |
| (0,A,B,B)	min((1-b)/a,1)	1		max(1-b/a,0)	1		
 | |
| (0,0,0,A)	max(1-(1-b)/a,0) 0		min(1,b/a)	0
 | |
| (0,0,0,B)	0		max(1-(1-a)/b,0) 0		min(a/b,1)
 | |
| (0,A,0,0)	min(1,(1-b)/a)	0		max(1-b/a,0)	0
 | |
| (0,0,B,0)	0		min(1,(1-a)/b)	0		max(1-a/b,0)
 | |
| (0,0,B,A)	max(1-(1-b)/a,0) min(1,(1-a)/b)	 min(1,b/a)	max(1-a/b,0)
 | |
| (0,A,0,B)	min(1,(1-b)/a)	max(1-(1-a)/b,0) max(1-b/a,0)	min(1,a/b)
 | |
| (0,A,B,0)	min(1,(1-b)/a)	min(1,(1-a)/b)	max(1-b/a,0)	max(1-a/b,0)
 | |
| 
 | |
|  */
 | |
| 
 | |
| #define CombineAOut 1
 | |
| #define CombineAIn  2
 | |
| #define CombineBOut 4
 | |
| #define CombineBIn  8
 | |
| 
 | |
| #define CombineClear	0
 | |
| #define CombineA	(CombineAOut|CombineAIn)
 | |
| #define CombineB	(CombineBOut|CombineBIn)
 | |
| #define CombineAOver	(CombineAOut|CombineBOut|CombineAIn)
 | |
| #define CombineBOver	(CombineAOut|CombineBOut|CombineBIn)
 | |
| #define CombineAAtop	(CombineBOut|CombineAIn)
 | |
| #define CombineBAtop	(CombineAOut|CombineBIn)
 | |
| #define CombineXor	(CombineAOut|CombineBOut)
 | |
| 
 | |
| /* portion covered by a but not b */
 | |
| CARD8
 | |
| fbCombineDisjointOutPart (CARD8 a, CARD8 b)
 | |
| {
 | |
|     /* min (1, (1-b) / a) */
 | |
|     
 | |
|     b = ~b;		    /* 1 - b */
 | |
|     if (b >= a)		    /* 1 - b >= a -> (1-b)/a >= 1 */
 | |
| 	return 0xff;	    /* 1 */
 | |
|     return FbIntDiv(b,a);   /* (1-b) / a */
 | |
| }
 | |
| 
 | |
| /* portion covered by both a and b */
 | |
| CARD8
 | |
| fbCombineDisjointInPart (CARD8 a, CARD8 b)
 | |
| {
 | |
|     /* max (1-(1-b)/a,0) */
 | |
|     /*  = - min ((1-b)/a - 1, 0) */
 | |
|     /*  = 1 - min (1, (1-b)/a) */
 | |
| 
 | |
|     b = ~b;		    /* 1 - b */
 | |
|     if (b >= a)		    /* 1 - b >= a -> (1-b)/a >= 1 */
 | |
| 	return 0;	    /* 1 - 1 */
 | |
|     return ~FbIntDiv(b,a);  /* 1 - (1-b) / a */
 | |
| }
 | |
| 
 | |
| void
 | |
| fbCombineDisjointGeneralU (FbCompositeOperand   *src,
 | |
| 			   FbCompositeOperand   *msk,
 | |
| 			   FbCompositeOperand   *dst,
 | |
| 			   CARD8		combine)
 | |
| {
 | |
|     CARD32  s, d;
 | |
|     CARD32  m,n,o,p;
 | |
|     CARD16  Fa, Fb, t, u, v;
 | |
|     CARD8   sa, da;
 | |
| 
 | |
|     s = fbCombineMaskU (src, msk);
 | |
|     sa = s >> 24;
 | |
|     
 | |
|     d = (*dst->fetch) (dst);
 | |
|     da = d >> 24;
 | |
|     
 | |
|     switch (combine & CombineA) {
 | |
|     default:
 | |
| 	Fa = 0;
 | |
| 	break;
 | |
|     case CombineAOut:
 | |
| 	Fa = fbCombineDisjointOutPart (sa, da);
 | |
| 	break;
 | |
|     case CombineAIn:
 | |
| 	Fa = fbCombineDisjointInPart (sa, da);
 | |
| 	break;
 | |
|     case CombineA:
 | |
| 	Fa = 0xff;
 | |
| 	break;
 | |
|     }
 | |
|     
 | |
|     switch (combine & CombineB) {
 | |
|     default:
 | |
| 	Fb = 0;
 | |
| 	break;
 | |
|     case CombineBOut:
 | |
| 	Fb = fbCombineDisjointOutPart (da, sa);
 | |
| 	break;
 | |
|     case CombineBIn:
 | |
| 	Fb = fbCombineDisjointInPart (da, sa);
 | |
| 	break;
 | |
|     case CombineB:
 | |
| 	Fb = 0xff;
 | |
| 	break;
 | |
|     }
 | |
|     m = FbGen (s,d,0,Fa,Fb,t,u,v);
 | |
|     n = FbGen (s,d,8,Fa,Fb,t,u,v);
 | |
|     o = FbGen (s,d,16,Fa,Fb,t,u,v);
 | |
|     p = FbGen (s,d,24,Fa,Fb,t,u,v);
 | |
|     s = m|n|o|p;
 | |
|     (*dst->store) (dst, s);
 | |
| }
 | |
| 
 | |
| void
 | |
| fbCombineDisjointGeneralC (FbCompositeOperand   *src,
 | |
| 			   FbCompositeOperand   *msk,
 | |
| 			   FbCompositeOperand   *dst,
 | |
| 			   CARD8		combine)
 | |
| {
 | |
|     FbCompSrc	cs;
 | |
|     CARD32  s, d;
 | |
|     CARD32  m,n,o,p;
 | |
|     CARD32  Fa;
 | |
|     CARD16  Fb, t, u, v;
 | |
|     CARD32  sa;
 | |
|     CARD8   da;
 | |
| 
 | |
|     cs = fbCombineMaskC (src, msk);
 | |
|     s = cs.value;
 | |
|     sa = cs.alpha;
 | |
|     
 | |
|     d = (*dst->fetch) (dst);
 | |
|     da = d >> 24;
 | |
|     
 | |
|     switch (combine & CombineA) {
 | |
|     default:
 | |
| 	Fa = 0;
 | |
| 	break;
 | |
|     case CombineAOut:
 | |
| 	m = fbCombineDisjointOutPart ((CARD8) (sa >> 0), da);
 | |
| 	n = fbCombineDisjointOutPart ((CARD8) (sa >> 8), da) << 8;
 | |
| 	o = fbCombineDisjointOutPart ((CARD8) (sa >> 16), da) << 16;
 | |
| 	p = fbCombineDisjointOutPart ((CARD8) (sa >> 24), da) << 24;
 | |
| 	Fa = m|n|o|p;
 | |
| 	break;
 | |
|     case CombineAIn:
 | |
| 	m = fbCombineDisjointOutPart ((CARD8) (sa >> 0), da);
 | |
| 	n = fbCombineDisjointOutPart ((CARD8) (sa >> 8), da) << 8;
 | |
| 	o = fbCombineDisjointOutPart ((CARD8) (sa >> 16), da) << 16;
 | |
| 	p = fbCombineDisjointOutPart ((CARD8) (sa >> 24), da) << 24;
 | |
| 	Fa = m|n|o|p;
 | |
| 	break;
 | |
|     case CombineA:
 | |
| 	Fa = 0xffffffff;
 | |
| 	break;
 | |
|     }
 | |
|     
 | |
|     switch (combine & CombineB) {
 | |
|     default:
 | |
| 	Fb = 0;
 | |
| 	break;
 | |
|     case CombineBOut:
 | |
| 	Fb = fbCombineDisjointOutPart (da, sa);
 | |
| 	break;
 | |
|     case CombineBIn:
 | |
| 	Fb = fbCombineDisjointInPart (da, sa);
 | |
| 	break;
 | |
|     case CombineB:
 | |
| 	Fb = 0xff;
 | |
| 	break;
 | |
|     }
 | |
|     m = FbGen (s,d,0,FbGet8(Fa,0),Fb,t,u,v);
 | |
|     n = FbGen (s,d,8,FbGet8(Fa,8),Fb,t,u,v);
 | |
|     o = FbGen (s,d,16,FbGet8(Fa,16),Fb,t,u,v);
 | |
|     p = FbGen (s,d,24,FbGet8(Fa,24),Fb,t,u,v);
 | |
|     s = m|n|o|p;
 | |
|     (*dst->store) (dst, s);
 | |
| }
 | |
| 
 | |
| void
 | |
| fbCombineDisjointOverU (FbCompositeOperand   *src,
 | |
| 			FbCompositeOperand   *msk,
 | |
| 			FbCompositeOperand   *dst)
 | |
| {
 | |
|     CARD32  s, d;
 | |
|     CARD16  a;
 | |
|     CARD16  t;
 | |
|     CARD32  m,n,o,p;
 | |
| 
 | |
|     s = fbCombineMaskU (src, msk);
 | |
|     a = s >> 24;
 | |
|     if (a != 0x00)
 | |
|     {
 | |
| 	if (a != 0xff)
 | |
| 	{
 | |
| 	    d = (*dst->fetch) (dst);
 | |
| 	    a = fbCombineDisjointOutPart (d >> 24, a);
 | |
| 	    m = FbOverU(s,d,0,a,t);
 | |
| 	    n = FbOverU(s,d,8,a,t);
 | |
| 	    o = FbOverU(s,d,16,a,t);
 | |
| 	    p = FbOverU(s,d,24,a,t);
 | |
| 	    s = m|n|o|p;
 | |
| 	}
 | |
| 	(*dst->store) (dst, s);
 | |
|     }
 | |
| }
 | |
| 
 | |
| void
 | |
| fbCombineDisjointOverC (FbCompositeOperand   *src,
 | |
| 			FbCompositeOperand   *msk,
 | |
| 			FbCompositeOperand   *dst)
 | |
| {
 | |
|     fbCombineDisjointGeneralC (src, msk, dst, CombineAOver);
 | |
| }
 | |
| 
 | |
| void
 | |
| fbCombineDisjointOverReverseU (FbCompositeOperand    *src,
 | |
| 			       FbCompositeOperand    *msk,
 | |
| 			       FbCompositeOperand    *dst)
 | |
| {
 | |
|     fbCombineDisjointGeneralU (src, msk, dst, CombineBOver);
 | |
| }
 | |
| 
 | |
| void
 | |
| fbCombineDisjointOverReverseC (FbCompositeOperand    *src,
 | |
| 			       FbCompositeOperand    *msk,
 | |
| 			       FbCompositeOperand    *dst)
 | |
| {
 | |
|     fbCombineDisjointGeneralC (src, msk, dst, CombineBOver);
 | |
| }
 | |
| 
 | |
| void
 | |
| fbCombineDisjointInU (FbCompositeOperand	    *src,
 | |
| 		      FbCompositeOperand	    *msk,
 | |
| 		      FbCompositeOperand	    *dst)
 | |
| {
 | |
|     fbCombineDisjointGeneralU (src, msk, dst, CombineAIn);
 | |
| }
 | |
| 
 | |
| void
 | |
| fbCombineDisjointInC (FbCompositeOperand	    *src,
 | |
| 		      FbCompositeOperand	    *msk,
 | |
| 		      FbCompositeOperand	    *dst)
 | |
| {
 | |
|     fbCombineDisjointGeneralC (src, msk, dst, CombineAIn);
 | |
| }
 | |
| 
 | |
| void
 | |
| fbCombineDisjointInReverseU (FbCompositeOperand  *src,
 | |
| 			     FbCompositeOperand  *msk,
 | |
| 			     FbCompositeOperand  *dst)
 | |
| {
 | |
|     fbCombineDisjointGeneralU (src, msk, dst, CombineBIn);
 | |
| }
 | |
| 
 | |
| void
 | |
| fbCombineDisjointInReverseC (FbCompositeOperand  *src,
 | |
| 			     FbCompositeOperand  *msk,
 | |
| 			     FbCompositeOperand  *dst)
 | |
| {
 | |
|     fbCombineDisjointGeneralC (src, msk, dst, CombineBIn);
 | |
| }
 | |
| 
 | |
| void
 | |
| fbCombineDisjointOutU (FbCompositeOperand    *src,
 | |
| 		       FbCompositeOperand    *msk,
 | |
| 		       FbCompositeOperand    *dst)
 | |
| {
 | |
|     fbCombineDisjointGeneralU (src, msk, dst, CombineAOut);
 | |
| }
 | |
| 
 | |
| void
 | |
| fbCombineDisjointOutC (FbCompositeOperand    *src,
 | |
| 		       FbCompositeOperand    *msk,
 | |
| 		       FbCompositeOperand    *dst)
 | |
| {
 | |
|     fbCombineDisjointGeneralC (src, msk, dst, CombineAOut);
 | |
| }
 | |
| 
 | |
| void
 | |
| fbCombineDisjointOutReverseU (FbCompositeOperand *src,
 | |
| 			      FbCompositeOperand *msk,
 | |
| 			      FbCompositeOperand *dst)
 | |
| {
 | |
|     fbCombineDisjointGeneralU (src, msk, dst, CombineBOut);
 | |
| }
 | |
| 
 | |
| void
 | |
| fbCombineDisjointOutReverseC (FbCompositeOperand *src,
 | |
| 			      FbCompositeOperand *msk,
 | |
| 			      FbCompositeOperand *dst)
 | |
| {
 | |
|     fbCombineDisjointGeneralC (src, msk, dst, CombineBOut);
 | |
| }
 | |
| 
 | |
| void
 | |
| fbCombineDisjointAtopU (FbCompositeOperand   *src,
 | |
| 			FbCompositeOperand   *msk,
 | |
| 			FbCompositeOperand   *dst)
 | |
| {
 | |
|     fbCombineDisjointGeneralU (src, msk, dst, CombineAAtop);
 | |
| }
 | |
| 
 | |
| void
 | |
| fbCombineDisjointAtopC (FbCompositeOperand   *src,
 | |
| 			FbCompositeOperand   *msk,
 | |
| 			FbCompositeOperand   *dst)
 | |
| {
 | |
|     fbCombineDisjointGeneralC (src, msk, dst, CombineAAtop);
 | |
| }
 | |
| 
 | |
| void
 | |
| fbCombineDisjointAtopReverseU (FbCompositeOperand    *src,
 | |
| 			       FbCompositeOperand    *msk,
 | |
| 			       FbCompositeOperand    *dst)
 | |
| {
 | |
|     fbCombineDisjointGeneralU (src, msk, dst, CombineBAtop);
 | |
| }
 | |
| 
 | |
| void
 | |
| fbCombineDisjointAtopReverseC (FbCompositeOperand    *src,
 | |
| 			       FbCompositeOperand    *msk,
 | |
| 			       FbCompositeOperand    *dst)
 | |
| {
 | |
|     fbCombineDisjointGeneralC (src, msk, dst, CombineBAtop);
 | |
| }
 | |
| 
 | |
| void
 | |
| fbCombineDisjointXorU (FbCompositeOperand    *src,
 | |
| 		       FbCompositeOperand    *msk,
 | |
| 		       FbCompositeOperand    *dst)
 | |
| {
 | |
|     fbCombineDisjointGeneralU (src, msk, dst, CombineXor);
 | |
| }
 | |
| 
 | |
| void
 | |
| fbCombineDisjointXorC (FbCompositeOperand    *src,
 | |
| 		       FbCompositeOperand    *msk,
 | |
| 		       FbCompositeOperand    *dst)
 | |
| {
 | |
|     fbCombineDisjointGeneralC (src, msk, dst, CombineXor);
 | |
| }
 | |
| 
 | |
| /* portion covered by a but not b */
 | |
| CARD8
 | |
| fbCombineConjointOutPart (CARD8 a, CARD8 b)
 | |
| {
 | |
|     /* max (1-b/a,0) */
 | |
|     /* = 1-min(b/a,1) */
 | |
|     
 | |
|     /* min (1, (1-b) / a) */
 | |
|     
 | |
|     if (b >= a)		    /* b >= a -> b/a >= 1 */
 | |
| 	return 0x00;	    /* 0 */
 | |
|     return ~FbIntDiv(b,a);   /* 1 - b/a */
 | |
| }
 | |
| 
 | |
| /* portion covered by both a and b */
 | |
| CARD8
 | |
| fbCombineConjointInPart (CARD8 a, CARD8 b)
 | |
| {
 | |
|     /* min (1,b/a) */
 | |
| 
 | |
|     if (b >= a)		    /* b >= a -> b/a >= 1 */
 | |
| 	return 0xff;	    /* 1 */
 | |
|     return FbIntDiv(b,a);   /* b/a */
 | |
| }
 | |
| 
 | |
| void
 | |
| fbCombineConjointGeneralU (FbCompositeOperand   *src,
 | |
| 			   FbCompositeOperand   *msk,
 | |
| 			   FbCompositeOperand   *dst,
 | |
| 			   CARD8		combine)
 | |
| {
 | |
|     CARD32  s, d;
 | |
|     CARD32  m,n,o,p;
 | |
|     CARD16  Fa, Fb, t, u, v;
 | |
|     CARD8   sa, da;
 | |
| 
 | |
|     s = fbCombineMaskU (src, msk);
 | |
|     sa = s >> 24;
 | |
|     
 | |
|     d = (*dst->fetch) (dst);
 | |
|     da = d >> 24;
 | |
|     
 | |
|     switch (combine & CombineA) {
 | |
|     default:
 | |
| 	Fa = 0;
 | |
| 	break;
 | |
|     case CombineAOut:
 | |
| 	Fa = fbCombineConjointOutPart (sa, da);
 | |
| 	break;
 | |
|     case CombineAIn:
 | |
| 	Fa = fbCombineConjointInPart (sa, da);
 | |
| 	break;
 | |
|     case CombineA:
 | |
| 	Fa = 0xff;
 | |
| 	break;
 | |
|     }
 | |
|     
 | |
|     switch (combine & CombineB) {
 | |
|     default:
 | |
| 	Fb = 0;
 | |
| 	break;
 | |
|     case CombineBOut:
 | |
| 	Fb = fbCombineConjointOutPart (da, sa);
 | |
| 	break;
 | |
|     case CombineBIn:
 | |
| 	Fb = fbCombineConjointInPart (da, sa);
 | |
| 	break;
 | |
|     case CombineB:
 | |
| 	Fb = 0xff;
 | |
| 	break;
 | |
|     }
 | |
|     m = FbGen (s,d,0,Fa,Fb,t,u,v);
 | |
|     n = FbGen (s,d,8,Fa,Fb,t,u,v);
 | |
|     o = FbGen (s,d,16,Fa,Fb,t,u,v);
 | |
|     p = FbGen (s,d,24,Fa,Fb,t,u,v);
 | |
|     s = m|n|o|p;
 | |
|     (*dst->store) (dst, s);
 | |
| }
 | |
| 
 | |
| void
 | |
| fbCombineConjointGeneralC (FbCompositeOperand   *src,
 | |
| 			   FbCompositeOperand   *msk,
 | |
| 			   FbCompositeOperand   *dst,
 | |
| 			   CARD8		combine)
 | |
| {
 | |
|     FbCompSrc	cs;
 | |
|     CARD32  s, d;
 | |
|     CARD32  m,n,o,p;
 | |
|     CARD32  Fa;
 | |
|     CARD16  Fb, t, u, v;
 | |
|     CARD32  sa;
 | |
|     CARD8   da;
 | |
| 
 | |
|     cs = fbCombineMaskC (src, msk);
 | |
|     s = cs.value;
 | |
|     sa = cs.alpha;
 | |
|     
 | |
|     d = (*dst->fetch) (dst);
 | |
|     da = d >> 24;
 | |
|     
 | |
|     switch (combine & CombineA) {
 | |
|     default:
 | |
| 	Fa = 0;
 | |
| 	break;
 | |
|     case CombineAOut:
 | |
| 	m = fbCombineConjointOutPart ((CARD8) (sa >> 0), da);
 | |
| 	n = fbCombineConjointOutPart ((CARD8) (sa >> 8), da) << 8;
 | |
| 	o = fbCombineConjointOutPart ((CARD8) (sa >> 16), da) << 16;
 | |
| 	p = fbCombineConjointOutPart ((CARD8) (sa >> 24), da) << 24;
 | |
| 	Fa = m|n|o|p;
 | |
| 	break;
 | |
|     case CombineAIn:
 | |
| 	m = fbCombineConjointOutPart ((CARD8) (sa >> 0), da);
 | |
| 	n = fbCombineConjointOutPart ((CARD8) (sa >> 8), da) << 8;
 | |
| 	o = fbCombineConjointOutPart ((CARD8) (sa >> 16), da) << 16;
 | |
| 	p = fbCombineConjointOutPart ((CARD8) (sa >> 24), da) << 24;
 | |
| 	Fa = m|n|o|p;
 | |
| 	break;
 | |
|     case CombineA:
 | |
| 	Fa = 0xffffffff;
 | |
| 	break;
 | |
|     }
 | |
|     
 | |
|     switch (combine & CombineB) {
 | |
|     default:
 | |
| 	Fb = 0;
 | |
| 	break;
 | |
|     case CombineBOut:
 | |
| 	Fb = fbCombineConjointOutPart (da, sa);
 | |
| 	break;
 | |
|     case CombineBIn:
 | |
| 	Fb = fbCombineConjointInPart (da, sa);
 | |
| 	break;
 | |
|     case CombineB:
 | |
| 	Fb = 0xff;
 | |
| 	break;
 | |
|     }
 | |
|     m = FbGen (s,d,0,FbGet8(Fa,0),Fb,t,u,v);
 | |
|     n = FbGen (s,d,8,FbGet8(Fa,8),Fb,t,u,v);
 | |
|     o = FbGen (s,d,16,FbGet8(Fa,16),Fb,t,u,v);
 | |
|     p = FbGen (s,d,24,FbGet8(Fa,24),Fb,t,u,v);
 | |
|     s = m|n|o|p;
 | |
|     (*dst->store) (dst, s);
 | |
| }
 | |
| 
 | |
| void
 | |
| fbCombineConjointOverU (FbCompositeOperand   *src,
 | |
| 			FbCompositeOperand   *msk,
 | |
| 			FbCompositeOperand   *dst)
 | |
| {
 | |
|     fbCombineConjointGeneralU (src, msk, dst, CombineAOver);
 | |
| /*
 | |
|     CARD32  s, d;
 | |
|     CARD16  a;
 | |
|     CARD16  t;
 | |
|     CARD32  m,n,o,p;
 | |
| 
 | |
|     s = fbCombineMaskU (src, msk);
 | |
|     a = s >> 24;
 | |
|     if (a != 0x00)
 | |
|     {
 | |
| 	if (a != 0xff)
 | |
| 	{
 | |
| 	    d = (*dst->fetch) (dst);
 | |
| 	    a = fbCombineConjointOutPart (d >> 24, a);
 | |
| 	    m = FbOverU(s,d,0,a,t);
 | |
| 	    n = FbOverU(s,d,8,a,t);
 | |
| 	    o = FbOverU(s,d,16,a,t);
 | |
| 	    p = FbOverU(s,d,24,a,t);
 | |
| 	    s = m|n|o|p;
 | |
| 	}
 | |
| 	(*dst->store) (dst, s);
 | |
|     }
 | |
|  */
 | |
| }
 | |
| 
 | |
| void
 | |
| fbCombineConjointOverC (FbCompositeOperand   *src,
 | |
| 			FbCompositeOperand   *msk,
 | |
| 			FbCompositeOperand   *dst)
 | |
| {
 | |
|     fbCombineConjointGeneralC (src, msk, dst, CombineAOver);
 | |
| }
 | |
| 
 | |
| void
 | |
| fbCombineConjointOverReverseU (FbCompositeOperand    *src,
 | |
| 			       FbCompositeOperand    *msk,
 | |
| 			       FbCompositeOperand    *dst)
 | |
| {
 | |
|     fbCombineConjointGeneralU (src, msk, dst, CombineBOver);
 | |
| }
 | |
| 
 | |
| void
 | |
| fbCombineConjointOverReverseC (FbCompositeOperand    *src,
 | |
| 			       FbCompositeOperand    *msk,
 | |
| 			       FbCompositeOperand    *dst)
 | |
| {
 | |
|     fbCombineConjointGeneralC (src, msk, dst, CombineBOver);
 | |
| }
 | |
| 
 | |
| void
 | |
| fbCombineConjointInU (FbCompositeOperand	    *src,
 | |
| 		      FbCompositeOperand	    *msk,
 | |
| 		      FbCompositeOperand	    *dst)
 | |
| {
 | |
|     fbCombineConjointGeneralU (src, msk, dst, CombineAIn);
 | |
| }
 | |
| 
 | |
| void
 | |
| fbCombineConjointInC (FbCompositeOperand	    *src,
 | |
| 		      FbCompositeOperand	    *msk,
 | |
| 		      FbCompositeOperand	    *dst)
 | |
| {
 | |
|     fbCombineConjointGeneralC (src, msk, dst, CombineAIn);
 | |
| }
 | |
| 
 | |
| void
 | |
| fbCombineConjointInReverseU (FbCompositeOperand  *src,
 | |
| 			     FbCompositeOperand  *msk,
 | |
| 			     FbCompositeOperand  *dst)
 | |
| {
 | |
|     fbCombineConjointGeneralU (src, msk, dst, CombineBIn);
 | |
| }
 | |
| 
 | |
| void
 | |
| fbCombineConjointInReverseC (FbCompositeOperand  *src,
 | |
| 			     FbCompositeOperand  *msk,
 | |
| 			     FbCompositeOperand  *dst)
 | |
| {
 | |
|     fbCombineConjointGeneralC (src, msk, dst, CombineBIn);
 | |
| }
 | |
| 
 | |
| void
 | |
| fbCombineConjointOutU (FbCompositeOperand    *src,
 | |
| 		       FbCompositeOperand    *msk,
 | |
| 		       FbCompositeOperand    *dst)
 | |
| {
 | |
|     fbCombineConjointGeneralU (src, msk, dst, CombineAOut);
 | |
| }
 | |
| 
 | |
| void
 | |
| fbCombineConjointOutC (FbCompositeOperand    *src,
 | |
| 		       FbCompositeOperand    *msk,
 | |
| 		       FbCompositeOperand    *dst)
 | |
| {
 | |
|     fbCombineConjointGeneralC (src, msk, dst, CombineAOut);
 | |
| }
 | |
| 
 | |
| void
 | |
| fbCombineConjointOutReverseU (FbCompositeOperand *src,
 | |
| 			      FbCompositeOperand *msk,
 | |
| 			      FbCompositeOperand *dst)
 | |
| {
 | |
|     fbCombineConjointGeneralU (src, msk, dst, CombineBOut);
 | |
| }
 | |
| 
 | |
| void
 | |
| fbCombineConjointOutReverseC (FbCompositeOperand *src,
 | |
| 			      FbCompositeOperand *msk,
 | |
| 			      FbCompositeOperand *dst)
 | |
| {
 | |
|     fbCombineConjointGeneralC (src, msk, dst, CombineBOut);
 | |
| }
 | |
| 
 | |
| void
 | |
| fbCombineConjointAtopU (FbCompositeOperand   *src,
 | |
| 			FbCompositeOperand   *msk,
 | |
| 			FbCompositeOperand   *dst)
 | |
| {
 | |
|     fbCombineConjointGeneralU (src, msk, dst, CombineAAtop);
 | |
| }
 | |
| 
 | |
| void
 | |
| fbCombineConjointAtopC (FbCompositeOperand   *src,
 | |
| 			FbCompositeOperand   *msk,
 | |
| 			FbCompositeOperand   *dst)
 | |
| {
 | |
|     fbCombineConjointGeneralC (src, msk, dst, CombineAAtop);
 | |
| }
 | |
| 
 | |
| void
 | |
| fbCombineConjointAtopReverseU (FbCompositeOperand    *src,
 | |
| 			       FbCompositeOperand    *msk,
 | |
| 			       FbCompositeOperand    *dst)
 | |
| {
 | |
|     fbCombineConjointGeneralU (src, msk, dst, CombineBAtop);
 | |
| }
 | |
| 
 | |
| void
 | |
| fbCombineConjointAtopReverseC (FbCompositeOperand    *src,
 | |
| 			       FbCompositeOperand    *msk,
 | |
| 			       FbCompositeOperand    *dst)
 | |
| {
 | |
|     fbCombineConjointGeneralC (src, msk, dst, CombineBAtop);
 | |
| }
 | |
| 
 | |
| void
 | |
| fbCombineConjointXorU (FbCompositeOperand    *src,
 | |
| 		       FbCompositeOperand    *msk,
 | |
| 		       FbCompositeOperand    *dst)
 | |
| {
 | |
|     fbCombineConjointGeneralU (src, msk, dst, CombineXor);
 | |
| }
 | |
| 
 | |
| void
 | |
| fbCombineConjointXorC (FbCompositeOperand    *src,
 | |
| 		       FbCompositeOperand    *msk,
 | |
| 		       FbCompositeOperand    *dst)
 | |
| {
 | |
|     fbCombineConjointGeneralC (src, msk, dst, CombineXor);
 | |
| }
 | |
| 
 | |
| FbCombineFunc	fbCombineFuncU[] = {
 | |
|     fbCombineClear,
 | |
|     fbCombineSrcU,
 | |
|     fbCombineDst,
 | |
|     fbCombineOverU,
 | |
|     fbCombineOverReverseU,
 | |
|     fbCombineInU,
 | |
|     fbCombineInReverseU,
 | |
|     fbCombineOutU,
 | |
|     fbCombineOutReverseU,
 | |
|     fbCombineAtopU,
 | |
|     fbCombineAtopReverseU,
 | |
|     fbCombineXorU,
 | |
|     fbCombineAddU,
 | |
|     fbCombineDisjointOverU, /* Saturate */
 | |
|     0,
 | |
|     0,
 | |
|     fbCombineClear,
 | |
|     fbCombineSrcU,
 | |
|     fbCombineDst,
 | |
|     fbCombineDisjointOverU,
 | |
|     fbCombineDisjointOverReverseU,
 | |
|     fbCombineDisjointInU,
 | |
|     fbCombineDisjointInReverseU,
 | |
|     fbCombineDisjointOutU,
 | |
|     fbCombineDisjointOutReverseU,
 | |
|     fbCombineDisjointAtopU,
 | |
|     fbCombineDisjointAtopReverseU,
 | |
|     fbCombineDisjointXorU,
 | |
|     0,
 | |
|     0,
 | |
|     0,
 | |
|     0,
 | |
|     fbCombineClear,
 | |
|     fbCombineSrcU,
 | |
|     fbCombineDst,
 | |
|     fbCombineConjointOverU,
 | |
|     fbCombineConjointOverReverseU,
 | |
|     fbCombineConjointInU,
 | |
|     fbCombineConjointInReverseU,
 | |
|     fbCombineConjointOutU,
 | |
|     fbCombineConjointOutReverseU,
 | |
|     fbCombineConjointAtopU,
 | |
|     fbCombineConjointAtopReverseU,
 | |
|     fbCombineConjointXorU,
 | |
| };
 | |
| 
 | |
| FbCombineFunc	fbCombineFuncC[] = {
 | |
|     fbCombineClear,
 | |
|     fbCombineSrcC,
 | |
|     fbCombineDst,
 | |
|     fbCombineOverC,
 | |
|     fbCombineOverReverseC,
 | |
|     fbCombineInC,
 | |
|     fbCombineInReverseC,
 | |
|     fbCombineOutC,
 | |
|     fbCombineOutReverseC,
 | |
|     fbCombineAtopC,
 | |
|     fbCombineAtopReverseC,
 | |
|     fbCombineXorC,
 | |
|     fbCombineAddC,
 | |
|     fbCombineDisjointOverC, /* Saturate */
 | |
|     0,
 | |
|     0,
 | |
|     fbCombineClear,	    /* 0x10 */
 | |
|     fbCombineSrcC,
 | |
|     fbCombineDst,
 | |
|     fbCombineDisjointOverC,
 | |
|     fbCombineDisjointOverReverseC,
 | |
|     fbCombineDisjointInC,
 | |
|     fbCombineDisjointInReverseC,
 | |
|     fbCombineDisjointOutC,
 | |
|     fbCombineDisjointOutReverseC,
 | |
|     fbCombineDisjointAtopC,
 | |
|     fbCombineDisjointAtopReverseC,
 | |
|     fbCombineDisjointXorC,  /* 0x1b */
 | |
|     0,
 | |
|     0,
 | |
|     0,
 | |
|     0,
 | |
|     fbCombineClear,
 | |
|     fbCombineSrcC,
 | |
|     fbCombineDst,
 | |
|     fbCombineConjointOverC,
 | |
|     fbCombineConjointOverReverseC,
 | |
|     fbCombineConjointInC,
 | |
|     fbCombineConjointInReverseC,
 | |
|     fbCombineConjointOutC,
 | |
|     fbCombineConjointOutReverseC,
 | |
|     fbCombineConjointAtopC,
 | |
|     fbCombineConjointAtopReverseC,
 | |
|     fbCombineConjointXorC,
 | |
| };
 | |
| 
 | |
| /*
 | |
|  * All of the fetch functions
 | |
|  */
 | |
| 
 | |
| CARD32
 | |
| fbFetch_a8r8g8b8 (FbCompositeOperand *op)
 | |
| {
 | |
|     FbBits  *line = op->u.drawable.line; CARD32 offset = op->u.drawable.offset;
 | |
|     return ((CARD32 *)line)[offset >> 5];
 | |
| }
 | |
| 
 | |
| CARD32
 | |
| fbFetch_x8r8g8b8 (FbCompositeOperand *op)
 | |
| {
 | |
|     FbBits  *line = op->u.drawable.line; CARD32 offset = op->u.drawable.offset;
 | |
|     return ((CARD32 *)line)[offset >> 5] | 0xff000000;
 | |
| }
 | |
| 
 | |
| CARD32
 | |
| fbFetch_a8b8g8r8 (FbCompositeOperand *op)
 | |
| {
 | |
|     FbBits  *line = op->u.drawable.line; CARD32 offset = op->u.drawable.offset;
 | |
|     CARD32  pixel = ((CARD32 *)line)[offset >> 5];
 | |
| 
 | |
|     return ((pixel & 0xff000000) |
 | |
| 	    ((pixel >> 16) & 0xff) |
 | |
| 	    (pixel & 0x0000ff00) |
 | |
| 	    ((pixel & 0xff) << 16));
 | |
| }
 | |
| 
 | |
| CARD32
 | |
| fbFetch_x8b8g8r8 (FbCompositeOperand *op)
 | |
| {
 | |
|     FbBits  *line = op->u.drawable.line; CARD32 offset = op->u.drawable.offset;
 | |
|     CARD32  pixel = ((CARD32 *)line)[offset >> 5];
 | |
| 
 | |
|     return ((0xff000000) |
 | |
| 	    ((pixel >> 16) & 0xff) |
 | |
| 	    (pixel & 0x0000ff00) |
 | |
| 	    ((pixel & 0xff) << 16));
 | |
| }
 | |
| 
 | |
| CARD32
 | |
| fbFetch_r8g8b8 (FbCompositeOperand *op)
 | |
| {
 | |
|     FbBits  *line = op->u.drawable.line; CARD32 offset = op->u.drawable.offset;
 | |
|     CARD8   *pixel = ((CARD8 *) line) + (offset >> 3);
 | |
| #if IMAGE_BYTE_ORDER == MSBFirst
 | |
|     return (0xff000000 |
 | |
| 	    (pixel[0] << 16) |
 | |
| 	    (pixel[1] << 8) |
 | |
| 	    (pixel[2]));
 | |
| #else
 | |
|     return (0xff000000 |
 | |
| 	    (pixel[2] << 16) |
 | |
| 	    (pixel[1] << 8) |
 | |
| 	    (pixel[0]));
 | |
| #endif
 | |
| }
 | |
| 
 | |
| CARD32
 | |
| fbFetch_b8g8r8 (FbCompositeOperand *op)
 | |
| {
 | |
|     FbBits  *line = op->u.drawable.line; CARD32 offset = op->u.drawable.offset;
 | |
|     CARD8   *pixel = ((CARD8 *) line) + (offset >> 3);
 | |
| #if IMAGE_BYTE_ORDER == MSBFirst
 | |
|     return (0xff000000 |
 | |
| 	    (pixel[2] << 16) |
 | |
| 	    (pixel[1] << 8) |
 | |
| 	    (pixel[0]));
 | |
| #else
 | |
|     return (0xff000000 |
 | |
| 	    (pixel[0] << 16) |
 | |
| 	    (pixel[1] << 8) |
 | |
| 	    (pixel[2]));
 | |
| #endif
 | |
| }
 | |
| 
 | |
| CARD32
 | |
| fbFetch_r5g6b5 (FbCompositeOperand *op)
 | |
| {
 | |
|     FbBits  *line = op->u.drawable.line; CARD32 offset = op->u.drawable.offset;
 | |
|     CARD32  pixel = ((CARD16 *) line)[offset >> 4];
 | |
|     CARD32  r,g,b;
 | |
| 
 | |
|     r = ((pixel & 0xf800) | ((pixel & 0xe000) >> 5)) << 8;
 | |
|     g = ((pixel & 0x07e0) | ((pixel & 0x0600) >> 6)) << 5;
 | |
|     b = ((pixel & 0x001c) | ((pixel & 0x001f) << 5)) >> 2;
 | |
|     return (0xff000000 | r | g | b);
 | |
| }
 | |
| 
 | |
| CARD32
 | |
| fbFetch_b5g6r5 (FbCompositeOperand *op)
 | |
| {
 | |
|     FbBits  *line = op->u.drawable.line; CARD32 offset = op->u.drawable.offset;
 | |
|     CARD32  pixel = ((CARD16 *) line)[offset >> 4];
 | |
|     CARD32  r,g,b;
 | |
| 
 | |
|     b = ((pixel & 0xf800) | ((pixel & 0xe000) >> 5)) >> 8;
 | |
|     g = ((pixel & 0x07e0) | ((pixel & 0x0600) >> 6)) << 5;
 | |
|     r = ((pixel & 0x001c) | ((pixel & 0x001f) << 5)) << 14;
 | |
|     return (0xff000000 | r | g | b);
 | |
| }
 | |
| 
 | |
| CARD32
 | |
| fbFetch_a1r5g5b5 (FbCompositeOperand *op)
 | |
| {
 | |
|     FbBits  *line = op->u.drawable.line; CARD32 offset = op->u.drawable.offset;
 | |
|     CARD32  pixel = ((CARD16 *) line)[offset >> 4];
 | |
|     CARD32  a,r,g,b;
 | |
| 
 | |
|     a = (CARD32) ((CARD8) (0 - ((pixel & 0x8000) >> 15))) << 24;
 | |
|     r = ((pixel & 0x7c00) | ((pixel & 0x7000) >> 5)) << 9;
 | |
|     g = ((pixel & 0x03e0) | ((pixel & 0x0380) >> 5)) << 6;
 | |
|     b = ((pixel & 0x001c) | ((pixel & 0x001f) << 5)) >> 2;
 | |
|     return (a | r | g | b);
 | |
| }
 | |
| 
 | |
| CARD32
 | |
| fbFetch_x1r5g5b5 (FbCompositeOperand *op)
 | |
| {
 | |
|     FbBits  *line = op->u.drawable.line; CARD32 offset = op->u.drawable.offset;
 | |
|     CARD32  pixel = ((CARD16 *) line)[offset >> 4];
 | |
|     CARD32  r,g,b;
 | |
| 
 | |
|     r = ((pixel & 0x7c00) | ((pixel & 0x7000) >> 5)) << 9;
 | |
|     g = ((pixel & 0x03e0) | ((pixel & 0x0380) >> 5)) << 6;
 | |
|     b = ((pixel & 0x001c) | ((pixel & 0x001f) << 5)) >> 2;
 | |
|     return (0xff000000 | r | g | b);
 | |
| }
 | |
| 
 | |
| CARD32
 | |
| fbFetch_a1b5g5r5 (FbCompositeOperand *op)
 | |
| {
 | |
|     FbBits  *line = op->u.drawable.line; CARD32 offset = op->u.drawable.offset;
 | |
|     CARD32  pixel = ((CARD16 *) line)[offset >> 4];
 | |
|     CARD32  a,r,g,b;
 | |
| 
 | |
|     a = (CARD32) ((CARD8) (0 - ((pixel & 0x8000) >> 15))) << 24;
 | |
|     b = ((pixel & 0x7c00) | ((pixel & 0x7000) >> 5)) >> 7;
 | |
|     g = ((pixel & 0x03e0) | ((pixel & 0x0380) >> 5)) << 6;
 | |
|     r = ((pixel & 0x001c) | ((pixel & 0x001f) << 5)) << 14;
 | |
|     return (a | r | g | b);
 | |
| }
 | |
| 
 | |
| CARD32
 | |
| fbFetch_x1b5g5r5 (FbCompositeOperand *op)
 | |
| {
 | |
|     FbBits  *line = op->u.drawable.line; CARD32 offset = op->u.drawable.offset;
 | |
|     CARD32  pixel = ((CARD16 *) line)[offset >> 4];
 | |
|     CARD32  r,g,b;
 | |
| 
 | |
|     b = ((pixel & 0x7c00) | ((pixel & 0x7000) >> 5)) >> 7;
 | |
|     g = ((pixel & 0x03e0) | ((pixel & 0x0380) >> 5)) << 6;
 | |
|     r = ((pixel & 0x001c) | ((pixel & 0x001f) << 5)) << 14;
 | |
|     return (0xff000000 | r | g | b);
 | |
| }
 | |
| 
 | |
| CARD32
 | |
| fbFetch_a4r4g4b4 (FbCompositeOperand *op)
 | |
| {
 | |
|     FbBits  *line = op->u.drawable.line; CARD32 offset = op->u.drawable.offset;
 | |
|     CARD32  pixel = ((CARD16 *) line)[offset >> 4];
 | |
|     CARD32  a,r,g,b;
 | |
| 
 | |
|     a = ((pixel & 0xf000) | ((pixel & 0xf000) >> 4)) << 16;
 | |
|     r = ((pixel & 0x0f00) | ((pixel & 0x0f00) >> 4)) << 12;
 | |
|     g = ((pixel & 0x00f0) | ((pixel & 0x00f0) >> 4)) << 8;
 | |
|     b = ((pixel & 0x000f) | ((pixel & 0x000f) << 4));
 | |
|     return (a | r | g | b);
 | |
| }
 | |
|     
 | |
| CARD32
 | |
| fbFetch_x4r4g4b4 (FbCompositeOperand *op)
 | |
| {
 | |
|     FbBits  *line = op->u.drawable.line; CARD32 offset = op->u.drawable.offset;
 | |
|     CARD32  pixel = ((CARD16 *) line)[offset >> 4];
 | |
|     CARD32  r,g,b;
 | |
| 
 | |
|     r = ((pixel & 0x0f00) | ((pixel & 0x0f00) >> 4)) << 12;
 | |
|     g = ((pixel & 0x00f0) | ((pixel & 0x00f0) >> 4)) << 8;
 | |
|     b = ((pixel & 0x000f) | ((pixel & 0x000f) << 4));
 | |
|     return (0xff000000 | r | g | b);
 | |
| }
 | |
|     
 | |
| CARD32
 | |
| fbFetch_a4b4g4r4 (FbCompositeOperand *op)
 | |
| {
 | |
|     FbBits  *line = op->u.drawable.line; CARD32 offset = op->u.drawable.offset;
 | |
|     CARD32  pixel = ((CARD16 *) line)[offset >> 4];
 | |
|     CARD32  a,r,g,b;
 | |
| 
 | |
|     a = ((pixel & 0xf000) | ((pixel & 0xf000) >> 4)) << 16;
 | |
|     b = ((pixel & 0x0f00) | ((pixel & 0x0f00) >> 4)) << 12;
 | |
|     g = ((pixel & 0x00f0) | ((pixel & 0x00f0) >> 4)) << 8;
 | |
|     r = ((pixel & 0x000f) | ((pixel & 0x000f) << 4));
 | |
|     return (a | r | g | b);
 | |
| }
 | |
|     
 | |
| CARD32
 | |
| fbFetch_x4b4g4r4 (FbCompositeOperand *op)
 | |
| {
 | |
|     FbBits  *line = op->u.drawable.line; CARD32 offset = op->u.drawable.offset;
 | |
|     CARD32  pixel = ((CARD16 *) line)[offset >> 4];
 | |
|     CARD32  r,g,b;
 | |
| 
 | |
|     b = ((pixel & 0x0f00) | ((pixel & 0x0f00) >> 4)) << 12;
 | |
|     g = ((pixel & 0x00f0) | ((pixel & 0x00f0) >> 4)) << 8;
 | |
|     r = ((pixel & 0x000f) | ((pixel & 0x000f) << 4));
 | |
|     return (0xff000000 | r | g | b);
 | |
| }
 | |
|     
 | |
| CARD32
 | |
| fbFetch_a8 (FbCompositeOperand *op)
 | |
| {
 | |
|     FbBits  *line = op->u.drawable.line; CARD32 offset = op->u.drawable.offset;
 | |
|     CARD32   pixel = ((CARD8 *) line)[offset>>3];
 | |
|     
 | |
|     return pixel << 24;
 | |
| }
 | |
| 
 | |
| CARD32
 | |
| fbFetcha_a8 (FbCompositeOperand *op)
 | |
| {
 | |
|     FbBits  *line = op->u.drawable.line; CARD32 offset = op->u.drawable.offset;
 | |
|     CARD32   pixel = ((CARD8 *) line)[offset>>3];
 | |
|     
 | |
|     pixel |= pixel << 8;
 | |
|     pixel |= pixel << 16;
 | |
|     return pixel;
 | |
| }
 | |
| 
 | |
| CARD32
 | |
| fbFetch_r3g3b2 (FbCompositeOperand *op)
 | |
| {
 | |
|     FbBits  *line = op->u.drawable.line; CARD32 offset = op->u.drawable.offset;
 | |
|     CARD32   pixel = ((CARD8 *) line)[offset>>3];
 | |
|     CARD32  r,g,b;
 | |
|     
 | |
|     r = ((pixel & 0xe0) | ((pixel & 0xe0) >> 3) | ((pixel & 0xc0) >> 6)) << 16;
 | |
|     g = ((pixel & 0x1c) | ((pixel & 0x18) >> 3) | ((pixel & 0x1c) << 3)) << 8;
 | |
|     b = (((pixel & 0x03)     ) | 
 | |
| 	 ((pixel & 0x03) << 2) | 
 | |
| 	 ((pixel & 0x03) << 4) |
 | |
| 	 ((pixel & 0x03) << 6));
 | |
|     return (0xff000000 | r | g | b);
 | |
| }
 | |
| 
 | |
| CARD32
 | |
| fbFetch_b2g3r3 (FbCompositeOperand *op)
 | |
| {
 | |
|     FbBits  *line = op->u.drawable.line; CARD32 offset = op->u.drawable.offset;
 | |
|     CARD32   pixel = ((CARD8 *) line)[offset>>3];
 | |
|     CARD32  r,g,b;
 | |
|     
 | |
|     b = (((pixel & 0xc0)     ) | 
 | |
| 	 ((pixel & 0xc0) >> 2) |
 | |
| 	 ((pixel & 0xc0) >> 4) |
 | |
| 	 ((pixel & 0xc0) >> 6));
 | |
|     g = ((pixel & 0x38) | ((pixel & 0x38) >> 3) | ((pixel & 0x30) << 2)) << 8;
 | |
|     r = (((pixel & 0x07)     ) | 
 | |
| 	 ((pixel & 0x07) << 3) | 
 | |
| 	 ((pixel & 0x06) << 6)) << 16;
 | |
|     return (0xff000000 | r | g | b);
 | |
| }
 | |
| 
 | |
| CARD32
 | |
| fbFetch_a2r2g2b2 (FbCompositeOperand *op)
 | |
| {
 | |
|     FbBits  *line = op->u.drawable.line; CARD32 offset = op->u.drawable.offset;
 | |
|     CARD32   pixel = ((CARD8 *) line)[offset>>3];
 | |
|     CARD32   a,r,g,b;
 | |
| 
 | |
|     a = ((pixel & 0xc0) * 0x55) << 18;
 | |
|     r = ((pixel & 0x30) * 0x55) << 12;
 | |
|     g = ((pixel & 0x0c) * 0x55) << 6;
 | |
|     b = ((pixel & 0x03) * 0x55);
 | |
|     return a|r|g|b;
 | |
| }
 | |
| 
 | |
| CARD32
 | |
| fbFetch_a2b2g2r2 (FbCompositeOperand *op)
 | |
| {
 | |
|     FbBits  *line = op->u.drawable.line; CARD32 offset = op->u.drawable.offset;
 | |
|     CARD32   pixel = ((CARD8 *) line)[offset>>3];
 | |
|     CARD32   a,r,g,b;
 | |
| 
 | |
|     a = ((pixel & 0xc0) * 0x55) << 18;
 | |
|     b = ((pixel & 0x30) * 0x55) >> 6;
 | |
|     g = ((pixel & 0x0c) * 0x55) << 6;
 | |
|     r = ((pixel & 0x03) * 0x55) << 16;
 | |
|     return a|r|g|b;
 | |
| }
 | |
| 
 | |
| CARD32
 | |
| fbFetch_c8 (FbCompositeOperand *op)
 | |
| {
 | |
|     FbBits  *line = op->u.drawable.line; CARD32 offset = op->u.drawable.offset;
 | |
|     CARD32   pixel = ((CARD8 *) line)[offset>>3];
 | |
| 
 | |
|     return op->indexed->rgba[pixel];
 | |
| }
 | |
| 
 | |
| #define Fetch8(l,o)    (((CARD8 *) (l))[(o) >> 3])
 | |
| #if IMAGE_BYTE_ORDER == MSBFirst
 | |
| #define Fetch4(l,o)    ((o) & 2 ? Fetch8(l,o) & 0xf : Fetch8(l,o) >> 4)
 | |
| #else
 | |
| #define Fetch4(l,o)    ((o) & 2 ? Fetch8(l,o) >> 4 : Fetch8(l,o) & 0xf)
 | |
| #endif
 | |
| 
 | |
| CARD32
 | |
| fbFetch_a4 (FbCompositeOperand *op)
 | |
| {
 | |
|     FbBits  *line = op->u.drawable.line; CARD32 offset = op->u.drawable.offset;
 | |
|     CARD32  pixel = Fetch4(line, offset);
 | |
|     
 | |
|     pixel |= pixel << 4;
 | |
|     return pixel << 24;
 | |
| }
 | |
| 
 | |
| CARD32
 | |
| fbFetcha_a4 (FbCompositeOperand *op)
 | |
| {
 | |
|     FbBits  *line = op->u.drawable.line; CARD32 offset = op->u.drawable.offset;
 | |
|     CARD32  pixel = Fetch4(line, offset);
 | |
|     
 | |
|     pixel |= pixel << 4;
 | |
|     pixel |= pixel << 8;
 | |
|     pixel |= pixel << 16;
 | |
|     return pixel;
 | |
| }
 | |
| 
 | |
| CARD32
 | |
| fbFetch_r1g2b1 (FbCompositeOperand *op)
 | |
| {
 | |
|     FbBits  *line = op->u.drawable.line; CARD32 offset = op->u.drawable.offset;
 | |
|     CARD32  pixel = Fetch4(line, offset);
 | |
|     CARD32  r,g,b;
 | |
| 
 | |
|     r = ((pixel & 0x8) * 0xff) << 13;
 | |
|     g = ((pixel & 0x6) * 0x55) << 7;
 | |
|     b = ((pixel & 0x1) * 0xff);
 | |
|     return 0xff000000|r|g|b;
 | |
| }
 | |
| 
 | |
| CARD32
 | |
| fbFetch_b1g2r1 (FbCompositeOperand *op)
 | |
| {
 | |
|     FbBits  *line = op->u.drawable.line; CARD32 offset = op->u.drawable.offset;
 | |
|     CARD32  pixel = Fetch4(line, offset);
 | |
|     CARD32  r,g,b;
 | |
| 
 | |
|     b = ((pixel & 0x8) * 0xff) >> 3;
 | |
|     g = ((pixel & 0x6) * 0x55) << 7;
 | |
|     r = ((pixel & 0x1) * 0xff) << 16;
 | |
|     return 0xff000000|r|g|b;
 | |
| }
 | |
| 
 | |
| CARD32
 | |
| fbFetch_a1r1g1b1 (FbCompositeOperand *op)
 | |
| {
 | |
|     FbBits  *line = op->u.drawable.line; CARD32 offset = op->u.drawable.offset;
 | |
|     CARD32  pixel = Fetch4(line, offset);
 | |
|     CARD32  a,r,g,b;
 | |
| 
 | |
|     a = ((pixel & 0x8) * 0xff) << 21;
 | |
|     r = ((pixel & 0x4) * 0xff) << 14;
 | |
|     g = ((pixel & 0x2) * 0xff) << 7;
 | |
|     b = ((pixel & 0x1) * 0xff);
 | |
|     return a|r|g|b;
 | |
| }
 | |
| 
 | |
| CARD32
 | |
| fbFetch_a1b1g1r1 (FbCompositeOperand *op)
 | |
| {
 | |
|     FbBits  *line = op->u.drawable.line; CARD32 offset = op->u.drawable.offset;
 | |
|     CARD32  pixel = Fetch4(line, offset);
 | |
|     CARD32  a,r,g,b;
 | |
| 
 | |
|     a = ((pixel & 0x8) * 0xff) << 21;
 | |
|     r = ((pixel & 0x4) * 0xff) >> 3;
 | |
|     g = ((pixel & 0x2) * 0xff) << 7;
 | |
|     b = ((pixel & 0x1) * 0xff) << 16;
 | |
|     return a|r|g|b;
 | |
| }
 | |
| 
 | |
| CARD32
 | |
| fbFetch_c4 (FbCompositeOperand *op)
 | |
| {
 | |
|     FbBits  *line = op->u.drawable.line; CARD32 offset = op->u.drawable.offset;
 | |
|     CARD32  pixel = Fetch4(line, offset);
 | |
| 
 | |
|     return op->indexed->rgba[pixel];
 | |
| }
 | |
| 
 | |
| CARD32
 | |
| fbFetcha_a1 (FbCompositeOperand *op)
 | |
| {
 | |
|     FbBits  *line = op->u.drawable.line; CARD32 offset = op->u.drawable.offset;
 | |
|     CARD32  pixel = ((CARD32 *)line)[offset >> 5];
 | |
|     CARD32  a;
 | |
| #if BITMAP_BIT_ORDER == MSBFirst
 | |
|     a = pixel >> (0x1f - (offset & 0x1f));
 | |
| #else
 | |
|     a = pixel >> (offset & 0x1f);
 | |
| #endif
 | |
|     a = a & 1;
 | |
|     a |= a << 1;
 | |
|     a |= a << 2;
 | |
|     a |= a << 4;
 | |
|     a |= a << 8;
 | |
|     a |= a << 16;
 | |
|     return a;
 | |
| }
 | |
| 
 | |
| CARD32
 | |
| fbFetch_a1 (FbCompositeOperand *op)
 | |
| {
 | |
|     FbBits  *line = op->u.drawable.line; CARD32 offset = op->u.drawable.offset;
 | |
|     CARD32  pixel = ((CARD32 *)line)[offset >> 5];
 | |
|     CARD32  a;
 | |
| #if BITMAP_BIT_ORDER == MSBFirst
 | |
|     a = pixel >> (0x1f - (offset & 0x1f));
 | |
| #else
 | |
|     a = pixel >> (offset & 0x1f);
 | |
| #endif
 | |
|     a = a & 1;
 | |
|     a |= a << 1;
 | |
|     a |= a << 2;
 | |
|     a |= a << 4;
 | |
|     return a << 24;
 | |
| }
 | |
| 
 | |
| CARD32
 | |
| fbFetch_g1 (FbCompositeOperand *op)
 | |
| {
 | |
|     FbBits  *line = op->u.drawable.line; CARD32 offset = op->u.drawable.offset;
 | |
|     CARD32  pixel = ((CARD32 *)line)[offset >> 5];
 | |
|     CARD32  a;
 | |
| #if BITMAP_BIT_ORDER == MSBFirst
 | |
|     a = pixel >> (0x1f - (offset & 0x1f));
 | |
| #else
 | |
|     a = pixel >> (offset & 0x1f);
 | |
| #endif
 | |
|     a = a & 1;
 | |
|     return op->indexed->rgba[a];
 | |
| }
 | |
| 
 | |
| /*
 | |
|  * All the store functions
 | |
|  */
 | |
| 
 | |
| #define Splita(v)	CARD32	a = ((v) >> 24), r = ((v) >> 16) & 0xff, g = ((v) >> 8) & 0xff, b = (v) & 0xff
 | |
| #define Split(v)	CARD32	r = ((v) >> 16) & 0xff, g = ((v) >> 8) & 0xff, b = (v) & 0xff
 | |
| 
 | |
| void
 | |
| fbStore_a8r8g8b8 (FbCompositeOperand *op, CARD32 value)
 | |
| {
 | |
|     FbBits  *line = op->u.drawable.line; CARD32 offset = op->u.drawable.offset;
 | |
|     ((CARD32 *)line)[offset >> 5] = value;
 | |
| }
 | |
| 
 | |
| void
 | |
| fbStore_x8r8g8b8 (FbCompositeOperand *op, CARD32 value)
 | |
| {
 | |
|     FbBits  *line = op->u.drawable.line; CARD32 offset = op->u.drawable.offset;
 | |
|     ((CARD32 *)line)[offset >> 5] = value & 0xffffff;
 | |
| }
 | |
| 
 | |
| void
 | |
| fbStore_a8b8g8r8 (FbCompositeOperand *op, CARD32 value)
 | |
| {
 | |
|     FbBits  *line = op->u.drawable.line; CARD32 offset = op->u.drawable.offset;
 | |
|     Splita(value);
 | |
|     ((CARD32 *)line)[offset >> 5] = a << 24 | b << 16 | g << 8 | r;
 | |
| }
 | |
| 
 | |
| void
 | |
| fbStore_x8b8g8r8 (FbCompositeOperand *op, CARD32 value)
 | |
| {
 | |
|     FbBits  *line = op->u.drawable.line; CARD32 offset = op->u.drawable.offset;
 | |
|     Split(value);
 | |
|     ((CARD32 *)line)[offset >> 5] = b << 16 | g << 8 | r;
 | |
| }
 | |
| 
 | |
| void
 | |
| fbStore_r8g8b8 (FbCompositeOperand *op, CARD32 value)
 | |
| {
 | |
|     FbBits  *line = op->u.drawable.line; CARD32 offset = op->u.drawable.offset;
 | |
|     CARD8   *pixel = ((CARD8 *) line) + (offset >> 3);
 | |
|     Split(value);
 | |
| #if IMAGE_BYTE_ORDER == MSBFirst
 | |
|     pixel[0] = r;
 | |
|     pixel[1] = g;
 | |
|     pixel[2] = b;
 | |
| #else
 | |
|     pixel[0] = b;
 | |
|     pixel[1] = g;
 | |
|     pixel[2] = r;
 | |
| #endif
 | |
| }
 | |
| 
 | |
| void
 | |
| fbStore_b8g8r8 (FbCompositeOperand *op, CARD32 value)
 | |
| {
 | |
|     FbBits  *line = op->u.drawable.line; CARD32 offset = op->u.drawable.offset;
 | |
|     CARD8   *pixel = ((CARD8 *) line) + (offset >> 3);
 | |
|     Split(value);
 | |
| #if IMAGE_BYTE_ORDER == MSBFirst
 | |
|     pixel[0] = b;
 | |
|     pixel[1] = g;
 | |
|     pixel[2] = r;
 | |
| #else
 | |
|     pixel[0] = r;
 | |
|     pixel[1] = g;
 | |
|     pixel[2] = b;
 | |
| #endif
 | |
| }
 | |
| 
 | |
| void
 | |
| fbStore_r5g6b5 (FbCompositeOperand *op, CARD32 value)
 | |
| {
 | |
|     FbBits  *line = op->u.drawable.line; CARD32 offset = op->u.drawable.offset;
 | |
|     CARD16  *pixel = ((CARD16 *) line) + (offset >> 4);
 | |
|     Split(value);
 | |
|     *pixel = (((r << 8) & 0xf800) |
 | |
| 	      ((g << 3) & 0x07e0) |
 | |
| 	      ((b >> 3)         ));
 | |
| }
 | |
| 
 | |
| void
 | |
| fbStore_b5g6r5 (FbCompositeOperand *op, CARD32 value)
 | |
| {
 | |
|     FbBits  *line = op->u.drawable.line; CARD32 offset = op->u.drawable.offset;
 | |
|     CARD16  *pixel = ((CARD16 *) line) + (offset >> 4);
 | |
|     Split(value);
 | |
|     *pixel = (((b << 8) & 0xf800) |
 | |
| 	      ((g << 3) & 0x07e0) |
 | |
| 	      ((r >> 3)         ));
 | |
| }
 | |
| 
 | |
| void
 | |
| fbStore_a1r5g5b5 (FbCompositeOperand *op, CARD32 value)
 | |
| {
 | |
|     FbBits  *line = op->u.drawable.line; CARD32 offset = op->u.drawable.offset;
 | |
|     CARD16  *pixel = ((CARD16 *) line) + (offset >> 4);
 | |
|     Splita(value);
 | |
|     *pixel = (((a << 8) & 0x8000) |
 | |
| 	      ((r << 7) & 0x7c00) |
 | |
| 	      ((g << 2) & 0x03e0) |
 | |
| 	      ((b >> 3)         ));
 | |
| }
 | |
| 
 | |
| void
 | |
| fbStore_x1r5g5b5 (FbCompositeOperand *op, CARD32 value)
 | |
| {
 | |
|     FbBits  *line = op->u.drawable.line; CARD32 offset = op->u.drawable.offset;
 | |
|     CARD16  *pixel = ((CARD16 *) line) + (offset >> 4);
 | |
|     Split(value);
 | |
|     *pixel = (((r << 7) & 0x7c00) |
 | |
| 	      ((g << 2) & 0x03e0) |
 | |
| 	      ((b >> 3)         ));
 | |
| }
 | |
| 
 | |
| void
 | |
| fbStore_a1b5g5r5 (FbCompositeOperand *op, CARD32 value)
 | |
| {
 | |
|     FbBits  *line = op->u.drawable.line; CARD32 offset = op->u.drawable.offset;
 | |
|     CARD16  *pixel = ((CARD16 *) line) + (offset >> 4);
 | |
|     Splita(value);
 | |
|     *pixel = (((a << 8) & 0x8000) |
 | |
| 	      ((b << 7) & 0x7c00) |
 | |
| 	      ((g << 2) & 0x03e0) |
 | |
| 	      ((r >> 3)         ));
 | |
| }
 | |
| 
 | |
| void
 | |
| fbStore_x1b5g5r5 (FbCompositeOperand *op, CARD32 value)
 | |
| {
 | |
|     FbBits  *line = op->u.drawable.line; CARD32 offset = op->u.drawable.offset;
 | |
|     CARD16  *pixel = ((CARD16 *) line) + (offset >> 4);
 | |
|     Split(value);
 | |
|     *pixel = (((b << 7) & 0x7c00) |
 | |
| 	      ((g << 2) & 0x03e0) |
 | |
| 	      ((r >> 3)         ));
 | |
| }
 | |
| 
 | |
| void
 | |
| fbStore_a4r4g4b4 (FbCompositeOperand *op, CARD32 value)
 | |
| {
 | |
|     FbBits  *line = op->u.drawable.line; CARD32 offset = op->u.drawable.offset;
 | |
|     CARD16  *pixel = ((CARD16 *) line) + (offset >> 4);
 | |
|     Splita(value);
 | |
|     *pixel = (((a << 8) & 0xf000) |
 | |
| 	      ((r << 4) & 0x0f00) |
 | |
| 	      ((g     ) & 0x00f0) |
 | |
| 	      ((b >> 4)         ));
 | |
| }
 | |
| 
 | |
| void
 | |
| fbStore_x4r4g4b4 (FbCompositeOperand *op, CARD32 value)
 | |
| {
 | |
|     FbBits  *line = op->u.drawable.line; CARD32 offset = op->u.drawable.offset;
 | |
|     CARD16  *pixel = ((CARD16 *) line) + (offset >> 4);
 | |
|     Split(value);
 | |
|     *pixel = (((r << 4) & 0x0f00) |
 | |
| 	      ((g     ) & 0x00f0) |
 | |
| 	      ((b >> 4)         ));
 | |
| }
 | |
| 
 | |
| void
 | |
| fbStore_a4b4g4r4 (FbCompositeOperand *op, CARD32 value)
 | |
| {
 | |
|     FbBits  *line = op->u.drawable.line; CARD32 offset = op->u.drawable.offset;
 | |
|     CARD16  *pixel = ((CARD16 *) line) + (offset >> 4);
 | |
|     Splita(value);
 | |
|     *pixel = (((a << 8) & 0xf000) |
 | |
| 	      ((b << 4) & 0x0f00) |
 | |
| 	      ((g     ) & 0x00f0) |
 | |
| 	      ((r >> 4)         ));
 | |
| }
 | |
| 
 | |
| void
 | |
| fbStore_x4b4g4r4 (FbCompositeOperand *op, CARD32 value)
 | |
| {
 | |
|     FbBits  *line = op->u.drawable.line; CARD32 offset = op->u.drawable.offset;
 | |
|     CARD16  *pixel = ((CARD16 *) line) + (offset >> 4);
 | |
|     Split(value);
 | |
|     *pixel = (((b << 4) & 0x0f00) |
 | |
| 	      ((g     ) & 0x00f0) |
 | |
| 	      ((r >> 4)         ));
 | |
| }
 | |
| 
 | |
| void
 | |
| fbStore_a8 (FbCompositeOperand *op, CARD32 value)
 | |
| {
 | |
|     FbBits  *line = op->u.drawable.line; CARD32 offset = op->u.drawable.offset;
 | |
|     CARD8   *pixel = ((CARD8 *) line) + (offset >> 3);
 | |
|     *pixel = value >> 24;
 | |
| }
 | |
| 
 | |
| void
 | |
| fbStore_r3g3b2 (FbCompositeOperand *op, CARD32 value)
 | |
| {
 | |
|     FbBits  *line = op->u.drawable.line; CARD32 offset = op->u.drawable.offset;
 | |
|     CARD8   *pixel = ((CARD8 *) line) + (offset >> 3);
 | |
|     Split(value);
 | |
|     *pixel = (((r     ) & 0xe0) |
 | |
| 	      ((g >> 3) & 0x1c) |
 | |
| 	      ((b >> 6)       ));
 | |
| }
 | |
| 
 | |
| void
 | |
| fbStore_b2g3r3 (FbCompositeOperand *op, CARD32 value)
 | |
| {
 | |
|     FbBits  *line = op->u.drawable.line; CARD32 offset = op->u.drawable.offset;
 | |
|     CARD8   *pixel = ((CARD8 *) line) + (offset >> 3);
 | |
|     Split(value);
 | |
|     *pixel = (((b     ) & 0xe0) |
 | |
| 	      ((g >> 3) & 0x1c) |
 | |
| 	      ((r >> 6)       ));
 | |
| }
 | |
| 
 | |
| void
 | |
| fbStore_a2r2g2b2 (FbCompositeOperand *op, CARD32 value)
 | |
| {
 | |
|     FbBits  *line = op->u.drawable.line; CARD32 offset = op->u.drawable.offset;
 | |
|     CARD8   *pixel = ((CARD8 *) line) + (offset >> 3);
 | |
|     Splita(value);
 | |
|     *pixel = (((a     ) & 0xc0) |
 | |
| 	      ((r >> 2) & 0x30) |
 | |
| 	      ((g >> 4) & 0x0c) |
 | |
| 	      ((b >> 6)       ));
 | |
| }
 | |
| 
 | |
| void
 | |
| fbStore_c8 (FbCompositeOperand *op, CARD32 value)
 | |
| {
 | |
|     FbBits  *line = op->u.drawable.line; CARD32 offset = op->u.drawable.offset;
 | |
|     CARD8   *pixel = ((CARD8 *) line) + (offset >> 3);
 | |
|     *pixel = miIndexToEnt24(op->indexed,value);
 | |
| }
 | |
| 
 | |
| void
 | |
| fbStore_g8 (FbCompositeOperand *op, CARD32 value)
 | |
| {
 | |
|     FbBits  *line = op->u.drawable.line; CARD32 offset = op->u.drawable.offset;
 | |
|     CARD8   *pixel = ((CARD8 *) line) + (offset >> 3);
 | |
|     *pixel = miIndexToEntY24(op->indexed,value);
 | |
| }
 | |
| 
 | |
| #define Store8(l,o,v)  (((CARD8 *) l)[(o) >> 3] = (v))
 | |
| #if IMAGE_BYTE_ORDER == MSBFirst
 | |
| #define Store4(l,o,v)  Store8(l,o,((o) & 4 ? \
 | |
| 				   (Fetch8(l,o) & 0xf0) | (v) : \
 | |
| 				   (Fetch8(l,o) & 0x0f) | ((v) << 4)))
 | |
| #else
 | |
| #define Store4(l,o,v)  Store8(l,o,((o) & 4 ? \
 | |
| 				   (Fetch8(l,o) & 0x0f) | ((v) << 4) : \
 | |
| 				   (Fetch8(l,o) & 0xf0) | (v)))
 | |
| #endif
 | |
| 
 | |
| void
 | |
| fbStore_a4 (FbCompositeOperand *op, CARD32 value)
 | |
| {
 | |
|     FbBits  *line = op->u.drawable.line; CARD32 offset = op->u.drawable.offset;
 | |
|     Store4(line,offset,value>>28);
 | |
| }
 | |
| 
 | |
| void
 | |
| fbStore_r1g2b1 (FbCompositeOperand *op, CARD32 value)
 | |
| {
 | |
|     FbBits  *line = op->u.drawable.line; CARD32 offset = op->u.drawable.offset;
 | |
|     CARD32  pixel;
 | |
|     
 | |
|     Split(value);
 | |
|     pixel = (((r >> 4) & 0x8) |
 | |
| 	     ((g >> 5) & 0x6) |
 | |
| 	     ((b >> 7)      ));
 | |
|     Store4(line,offset,pixel);
 | |
| }
 | |
| 
 | |
| void
 | |
| fbStore_b1g2r1 (FbCompositeOperand *op, CARD32 value)
 | |
| {
 | |
|     FbBits  *line = op->u.drawable.line; CARD32 offset = op->u.drawable.offset;
 | |
|     CARD32  pixel;
 | |
|     
 | |
|     Split(value);
 | |
|     pixel = (((b >> 4) & 0x8) |
 | |
| 	     ((g >> 5) & 0x6) |
 | |
| 	     ((r >> 7)      ));
 | |
|     Store4(line,offset,pixel);
 | |
| }
 | |
| 
 | |
| void
 | |
| fbStore_a1r1g1b1 (FbCompositeOperand *op, CARD32 value)
 | |
| {
 | |
|     FbBits  *line = op->u.drawable.line; CARD32 offset = op->u.drawable.offset;
 | |
|     CARD32  pixel;
 | |
|     Splita(value);
 | |
|     pixel = (((a >> 4) & 0x8) |
 | |
| 	     ((r >> 5) & 0x4) |
 | |
| 	     ((g >> 6) & 0x2) |
 | |
| 	     ((b >> 7)      ));
 | |
|     Store4(line,offset,pixel);
 | |
| }
 | |
| 
 | |
| void
 | |
| fbStore_a1b1g1r1 (FbCompositeOperand *op, CARD32 value)
 | |
| {
 | |
|     FbBits  *line = op->u.drawable.line; CARD32 offset = op->u.drawable.offset;
 | |
|     CARD32  pixel;
 | |
|     Splita(value);
 | |
|     pixel = (((a >> 4) & 0x8) |
 | |
| 	     ((b >> 5) & 0x4) |
 | |
| 	     ((g >> 6) & 0x2) |
 | |
| 	     ((r >> 7)      ));
 | |
|     Store4(line,offset,pixel);
 | |
| }
 | |
| 
 | |
| void
 | |
| fbStore_c4 (FbCompositeOperand *op, CARD32 value)
 | |
| {
 | |
|     FbBits  *line = op->u.drawable.line; CARD32 offset = op->u.drawable.offset;
 | |
|     CARD32  pixel;
 | |
|     
 | |
|     pixel = miIndexToEnt24(op->indexed,value);
 | |
|     Store4(line,offset,pixel);
 | |
| }
 | |
| 
 | |
| void
 | |
| fbStore_g4 (FbCompositeOperand *op, CARD32 value)
 | |
| {
 | |
|     FbBits  *line = op->u.drawable.line; CARD32 offset = op->u.drawable.offset;
 | |
|     CARD32  pixel;
 | |
|     
 | |
|     pixel = miIndexToEntY24(op->indexed,value);
 | |
|     Store4(line,offset,pixel);
 | |
| }
 | |
| 
 | |
| void
 | |
| fbStore_a1 (FbCompositeOperand *op, CARD32 value)
 | |
| {
 | |
|     FbBits  *line = op->u.drawable.line; CARD32 offset = op->u.drawable.offset;
 | |
|     CARD32  *pixel = ((CARD32 *) line) + (offset >> 5);
 | |
|     CARD32  mask = FbStipMask(offset & 0x1f, 1);
 | |
| 
 | |
|     value = value & 0x80000000 ? mask : 0;
 | |
|     *pixel = (*pixel & ~mask) | value;
 | |
| }
 | |
| 
 | |
| void
 | |
| fbStore_g1 (FbCompositeOperand *op, CARD32 value)
 | |
| {
 | |
|     FbBits  *line = op->u.drawable.line; CARD32 offset = op->u.drawable.offset;
 | |
|     CARD32  *pixel = ((CARD32 *) line) + (offset >> 5);
 | |
|     CARD32  mask = FbStipMask(offset & 0x1f, 1);
 | |
| 
 | |
|     value = miIndexToEntY24(op->indexed,value) ? mask : 0;
 | |
|     *pixel = (*pixel & ~mask) | value;
 | |
| }
 | |
| 
 | |
| CARD32
 | |
| fbFetch_external (FbCompositeOperand *op)
 | |
| {
 | |
|     CARD32  rgb = (*op[1].fetch) (&op[1]);
 | |
|     CARD32  a = (*op[2].fetch) (&op[2]);
 | |
| 
 | |
|     return (rgb & 0xffffff) | (a & 0xff000000);
 | |
| }
 | |
| 
 | |
| 
 | |
| CARD32
 | |
| fbFetcha_external (FbCompositeOperand *op)
 | |
| {
 | |
|     return (*op[2].fetch) (&op[2]);
 | |
| }
 | |
| 
 | |
| void
 | |
| fbStore_external (FbCompositeOperand *op, CARD32 value)
 | |
| {
 | |
|     (*op[1].store) (&op[1], value | 0xff000000);
 | |
|     (*op[2].store) (&op[2], value & 0xff000000);
 | |
| }
 | |
| 
 | |
| #define dummyScreen screenInfo.screens[0]
 | |
| 
 | |
| CARD32
 | |
| fbFetch_transform (FbCompositeOperand *op)
 | |
| {
 | |
|     PictVector	v;
 | |
|     int		x, y;
 | |
|     int		minx, maxx, miny, maxy;
 | |
|     int		n;
 | |
|     BoxRec	box;
 | |
|     CARD32	rtot, gtot, btot, atot;
 | |
|     CARD32	xerr, yerr;
 | |
|     CARD32	bits;
 | |
| 
 | |
|     v.vector[0] = IntToxFixed(op->u.transform.x);
 | |
|     v.vector[1] = IntToxFixed(op->u.transform.y);
 | |
|     v.vector[2] = xFixed1;
 | |
|     if (!PictureTransformPoint (op->u.transform.transform, &v))
 | |
| 	return 0;
 | |
|     switch (op->u.transform.filter) {
 | |
|     case PictFilterNearest:
 | |
| 	y = xFixedToInt (v.vector[1]) + op->u.transform.top_y;
 | |
| 	x = xFixedToInt (v.vector[0]) + op->u.transform.left_x;
 | |
| 	if (POINT_IN_REGION (dummyScreen, op->clip, x, y, &box))
 | |
| 	{
 | |
| 	    (*op[1].set) (&op[1], x, y);
 | |
| 	    bits = (*op[1].fetch) (&op[1]);
 | |
| 	}
 | |
| 	else
 | |
| 	    bits = 0;
 | |
| 	break;
 | |
|     case PictFilterBilinear:
 | |
| 	rtot = gtot = btot = atot = 0;
 | |
| 	miny = xFixedToInt (v.vector[1]) + op->u.transform.top_y;
 | |
| 	maxy = xFixedToInt (xFixedCeil (v.vector[1])) + op->u.transform.top_y;
 | |
| 	
 | |
| 	minx = xFixedToInt (v.vector[0]) + op->u.transform.left_x;
 | |
| 	maxx = xFixedToInt (xFixedCeil (v.vector[0])) + op->u.transform.left_x;
 | |
| 	
 | |
| 	yerr = xFixed1 - xFixedFrac (v.vector[1]);
 | |
| 	for (y = miny; y <= maxy; y++)
 | |
| 	{
 | |
| 	    CARD32	lrtot = 0, lgtot = 0, lbtot = 0, latot = 0;
 | |
| 	    
 | |
| 	    xerr = xFixed1 - xFixedFrac (v.vector[0]);
 | |
| 	    for (x = minx; x <= maxx; x++)
 | |
| 	    {
 | |
| 		if (POINT_IN_REGION (dummyScreen, op->clip, x, y, &box))
 | |
| 		{
 | |
| 		    (*op[1].set) (&op[1], x, y);
 | |
| 		    bits = (*op[1].fetch) (&op[1]);
 | |
| 		    {
 | |
| 			Splita(bits);
 | |
| 			lrtot += r * xerr;
 | |
| 			lgtot += g * xerr;
 | |
| 			lbtot += b * xerr;
 | |
| 			latot += a * xerr;
 | |
| 			n++;
 | |
| 		    }
 | |
| 		}
 | |
| 		xerr = xFixed1 - xerr;
 | |
| 	    }
 | |
| 	    rtot += (lrtot >> 10) * yerr;
 | |
| 	    gtot += (lgtot >> 10) * yerr;
 | |
| 	    btot += (lbtot >> 10) * yerr;
 | |
| 	    atot += (latot >> 10) * yerr;
 | |
| 	    yerr = xFixed1 - yerr;
 | |
| 	}
 | |
| 	if ((atot >>= 22) > 0xff) atot = 0xff;
 | |
| 	if ((rtot >>= 22) > 0xff) rtot = 0xff;
 | |
| 	if ((gtot >>= 22) > 0xff) gtot = 0xff;
 | |
| 	if ((btot >>= 22) > 0xff) btot = 0xff;
 | |
| 	bits = ((atot << 24) |
 | |
| 		(rtot << 16) |
 | |
| 		(gtot <<  8) |
 | |
| 		(btot       ));
 | |
| 	break;
 | |
|     default:
 | |
| 	bits = 0;
 | |
| 	break;
 | |
|     }
 | |
|     return bits;
 | |
| }
 | |
| 
 | |
| CARD32
 | |
| fbFetcha_transform (FbCompositeOperand *op)
 | |
| {
 | |
|     PictVector	v;
 | |
|     int		x, y;
 | |
|     int		minx, maxx, miny, maxy;
 | |
|     int		n;
 | |
|     BoxRec	box;
 | |
|     CARD32	rtot, gtot, btot, atot;
 | |
|     CARD32	xerr, yerr;
 | |
|     CARD32	bits;
 | |
| 
 | |
|     v.vector[0] = IntToxFixed(op->u.transform.x);
 | |
|     v.vector[1] = IntToxFixed(op->u.transform.y);
 | |
|     v.vector[2] = xFixed1;
 | |
|     if (!PictureTransformPoint (op->u.transform.transform, &v))
 | |
| 	return 0;
 | |
|     switch (op->u.transform.filter) {
 | |
|     case PictFilterNearest:
 | |
| 	y = xFixedToInt (v.vector[1]) + op->u.transform.left_x;
 | |
| 	x = xFixedToInt (v.vector[0]) + op->u.transform.top_y;
 | |
| 	if (POINT_IN_REGION (dummyScreen, op->clip, x, y, &box))
 | |
| 	{
 | |
| 	    (*op[1].set) (&op[1], x, y);
 | |
| 	    bits = (*op[1].fetcha) (&op[1]);
 | |
| 	}
 | |
| 	else
 | |
| 	    bits = 0;
 | |
| 	break;
 | |
|     case PictFilterBilinear:
 | |
| 	rtot = gtot = btot = atot = 0;
 | |
| 	
 | |
| 	miny = xFixedToInt (v.vector[1]) + op->u.transform.top_y;
 | |
| 	maxy = xFixedToInt (xFixedCeil (v.vector[1])) + op->u.transform.top_y;
 | |
| 	
 | |
| 	minx = xFixedToInt (v.vector[0]) + op->u.transform.left_x;
 | |
| 	maxx = xFixedToInt (xFixedCeil (v.vector[0])) + op->u.transform.left_x;
 | |
| 	
 | |
| 	yerr = xFixed1 - xFixedFrac (v.vector[1]);
 | |
| 	for (y = miny; y <= maxy; y++)
 | |
| 	{
 | |
| 	    CARD32	lrtot = 0, lgtot = 0, lbtot = 0, latot = 0;
 | |
| 	    xerr = xFixed1 - xFixedFrac (v.vector[0]);
 | |
| 	    for (x = minx; x <= maxx; x++)
 | |
| 	    {
 | |
| 		if (POINT_IN_REGION (dummyScreen, op->clip, x, y, &box))
 | |
| 		{
 | |
| 		    (*op[1].set) (&op[1], x, y);
 | |
| 		    bits = (*op[1].fetcha) (&op[1]);
 | |
| 		    {
 | |
| 			Splita(bits);
 | |
| 			lrtot += r * xerr;
 | |
| 			lgtot += g * xerr;
 | |
| 			lbtot += b * xerr;
 | |
| 			latot += a * xerr;
 | |
| 			n++;
 | |
| 		    }
 | |
| 		}
 | |
| 		x++;
 | |
| 		xerr = xFixed1 - xerr;
 | |
| 	    }
 | |
| 	    rtot += (lrtot >> 10) * yerr;
 | |
| 	    gtot += (lgtot >> 10) * yerr;
 | |
| 	    btot += (lbtot >> 10) * yerr;
 | |
| 	    atot += (latot >> 10) * yerr;
 | |
| 	    y++;
 | |
| 	    yerr = xFixed1 - yerr;
 | |
| 	}
 | |
| 	if ((atot >>= 22) > 0xff) atot = 0xff;
 | |
| 	if ((rtot >>= 22) > 0xff) rtot = 0xff;
 | |
| 	if ((gtot >>= 22) > 0xff) gtot = 0xff;
 | |
| 	if ((btot >>= 22) > 0xff) btot = 0xff;
 | |
| 	bits = ((atot << 24) |
 | |
| 		(rtot << 16) |
 | |
| 		(gtot <<  8) |
 | |
| 		(btot       ));
 | |
| 	break;
 | |
|     default:
 | |
| 	bits = 0;
 | |
| 	break;
 | |
|     }
 | |
|     return bits;
 | |
| }
 | |
| 
 | |
| FbAccessMap fbAccessMap[] = {
 | |
|     /* 32bpp formats */
 | |
|     { PICT_a8r8g8b8,	fbFetch_a8r8g8b8,	fbFetch_a8r8g8b8,	fbStore_a8r8g8b8 },
 | |
|     { PICT_x8r8g8b8,	fbFetch_x8r8g8b8,	fbFetch_x8r8g8b8,	fbStore_x8r8g8b8 },
 | |
|     { PICT_a8b8g8r8,	fbFetch_a8b8g8r8,	fbFetch_a8b8g8r8,	fbStore_a8b8g8r8 },
 | |
|     { PICT_x8b8g8r8,	fbFetch_x8b8g8r8,	fbFetch_x8b8g8r8,	fbStore_x8b8g8r8 },
 | |
| 
 | |
|     /* 24bpp formats */
 | |
|     { PICT_r8g8b8,	fbFetch_r8g8b8,		fbFetch_r8g8b8,		fbStore_r8g8b8 },
 | |
|     { PICT_b8g8r8,	fbFetch_b8g8r8,		fbFetch_b8g8r8,		fbStore_b8g8r8 },
 | |
| 
 | |
|     /* 16bpp formats */
 | |
|     { PICT_r5g6b5,	fbFetch_r5g6b5,		fbFetch_r5g6b5,		fbStore_r5g6b5 },
 | |
|     { PICT_b5g6r5,	fbFetch_b5g6r5,		fbFetch_b5g6r5,		fbStore_b5g6r5 },
 | |
| 
 | |
|     { PICT_a1r5g5b5,	fbFetch_a1r5g5b5,	fbFetch_a1r5g5b5,	fbStore_a1r5g5b5 },
 | |
|     { PICT_x1r5g5b5,	fbFetch_x1r5g5b5,	fbFetch_x1r5g5b5,	fbStore_x1r5g5b5 },
 | |
|     { PICT_a1b5g5r5,	fbFetch_a1b5g5r5,	fbFetch_a1b5g5r5,	fbStore_a1b5g5r5 },
 | |
|     { PICT_x1b5g5r5,	fbFetch_x1b5g5r5,	fbFetch_x1b5g5r5,	fbStore_x1b5g5r5 },
 | |
|     { PICT_a4r4g4b4,	fbFetch_a4r4g4b4,	fbFetch_a4r4g4b4,	fbStore_a4r4g4b4 },
 | |
|     { PICT_x4r4g4b4,	fbFetch_x4r4g4b4,	fbFetch_x4r4g4b4,	fbStore_x4r4g4b4 },
 | |
|     { PICT_a4b4g4r4,	fbFetch_a4b4g4r4,	fbFetch_a4b4g4r4,	fbStore_a4b4g4r4 },
 | |
|     { PICT_x4b4g4r4,	fbFetch_x4b4g4r4,	fbFetch_x4b4g4r4,	fbStore_x4b4g4r4 },
 | |
| 
 | |
|     /* 8bpp formats */
 | |
|     { PICT_a8,		fbFetch_a8,		fbFetcha_a8,		fbStore_a8 },
 | |
|     { PICT_r3g3b2,	fbFetch_r3g3b2,		fbFetch_r3g3b2,		fbStore_r3g3b2 },
 | |
|     { PICT_b2g3r3,	fbFetch_b2g3r3,		fbFetch_b2g3r3,		fbStore_b2g3r3 },
 | |
|     { PICT_a2r2g2b2,	fbFetch_a2r2g2b2,	fbFetch_a2r2g2b2,	fbStore_a2r2g2b2 },
 | |
|     { PICT_c8,		fbFetch_c8,		fbFetch_c8,		fbStore_c8 },
 | |
|     { PICT_g8,		fbFetch_c8,		fbFetch_c8,		fbStore_g8 },
 | |
| 
 | |
|     /* 4bpp formats */
 | |
|     { PICT_a4,		fbFetch_a4,		fbFetcha_a4,		fbStore_a4 },
 | |
|     { PICT_r1g2b1,	fbFetch_r1g2b1,		fbFetch_r1g2b1,		fbStore_r1g2b1 },
 | |
|     { PICT_b1g2r1,	fbFetch_b1g2r1,		fbFetch_b1g2r1,		fbStore_b1g2r1 },
 | |
|     { PICT_a1r1g1b1,	fbFetch_a1r1g1b1,	fbFetch_a1r1g1b1,	fbStore_a1r1g1b1 },
 | |
|     { PICT_a1b1g1r1,	fbFetch_a1b1g1r1,	fbFetch_a1b1g1r1,	fbStore_a1b1g1r1 },
 | |
|     { PICT_c4,		fbFetch_c4,		fbFetch_c4,		fbStore_c4 },
 | |
|     { PICT_g4,		fbFetch_c4,		fbFetch_c4,		fbStore_g4 },
 | |
| 
 | |
|     /* 1bpp formats */
 | |
|     { PICT_a1,		fbFetch_a1,		fbFetcha_a1,		fbStore_a1 },
 | |
|     { PICT_g1,		fbFetch_g1,		fbFetch_g1,		fbStore_g1 },
 | |
| };
 | |
| #define NumAccessMap (sizeof fbAccessMap / sizeof fbAccessMap[0])
 | |
| 
 | |
| static void
 | |
| fbStepOver (FbCompositeOperand *op)
 | |
| {
 | |
|     op->u.drawable.offset += op->u.drawable.bpp;
 | |
| }
 | |
| 
 | |
| static void
 | |
| fbStepDown (FbCompositeOperand *op)
 | |
| {
 | |
|     op->u.drawable.line += op->u.drawable.stride;
 | |
|     op->u.drawable.offset = op->u.drawable.start_offset;
 | |
| }
 | |
| 
 | |
| static void
 | |
| fbSet (FbCompositeOperand *op, int x, int y)
 | |
| {
 | |
|     op->u.drawable.line = op->u.drawable.top_line + y * op->u.drawable.stride;
 | |
|     op->u.drawable.offset = op->u.drawable.left_offset + x * op->u.drawable.bpp;
 | |
| }
 | |
| 
 | |
| static void
 | |
| fbStepOver_external (FbCompositeOperand *op)
 | |
| {
 | |
|     (*op[1].over) (&op[1]);
 | |
|     (*op[2].over) (&op[2]);
 | |
| }
 | |
| 
 | |
| static void
 | |
| fbStepDown_external (FbCompositeOperand *op)
 | |
| {
 | |
|     (*op[1].down) (&op[1]);
 | |
|     (*op[2].down) (&op[2]);
 | |
| }
 | |
| 
 | |
| static void
 | |
| fbSet_external (FbCompositeOperand *op, int x, int y)
 | |
| {
 | |
|     (*op[1].set) (&op[1], x, y);
 | |
|     (*op[2].set) (&op[2], 
 | |
| 		  x - op->u.external.alpha_dx,
 | |
| 		  y - op->u.external.alpha_dy);
 | |
| }
 | |
| 
 | |
| static void
 | |
| fbStepOver_transform (FbCompositeOperand *op)
 | |
| {
 | |
|     op->u.transform.x++;   
 | |
| }
 | |
| 
 | |
| static void
 | |
| fbStepDown_transform (FbCompositeOperand *op)
 | |
| {
 | |
|     op->u.transform.y++;
 | |
|     op->u.transform.x = op->u.transform.start_x;
 | |
| }
 | |
| 
 | |
| static void
 | |
| fbSet_transform (FbCompositeOperand *op, int x, int y)
 | |
| {
 | |
|     op->u.transform.x = x - op->u.transform.left_x;
 | |
|     op->u.transform.y = y - op->u.transform.top_y;
 | |
| }
 | |
| 
 | |
| 
 | |
| Bool
 | |
| fbBuildCompositeOperand (PicturePtr	    pPict,
 | |
| 			 FbCompositeOperand op[4],
 | |
| 			 INT16		    x,
 | |
| 			 INT16		    y,
 | |
| 			 Bool		    transform,
 | |
| 			 Bool		    alpha)
 | |
| {
 | |
|     /* Check for transform */
 | |
|     if (transform && pPict->transform)
 | |
|     {
 | |
| 	if (!fbBuildCompositeOperand (pPict, &op[1], 0, 0, FALSE, alpha))
 | |
| 	    return FALSE;
 | |
| 	
 | |
| 	op->u.transform.top_y = pPict->pDrawable->y;
 | |
| 	op->u.transform.left_x = pPict->pDrawable->x;
 | |
| 	
 | |
| 	op->u.transform.start_x = x - op->u.transform.left_x;
 | |
| 	op->u.transform.x = op->u.transform.start_x;
 | |
| 	op->u.transform.y = y - op->u.transform.top_y;
 | |
| 	op->u.transform.transform = pPict->transform;
 | |
| 	op->u.transform.filter = pPict->filter;
 | |
| 	
 | |
| 	op->fetch = fbFetch_transform;
 | |
| 	op->fetcha = fbFetcha_transform;
 | |
| 	op->store = 0;
 | |
| 	op->over = fbStepOver_transform;
 | |
| 	op->down = fbStepDown_transform;
 | |
| 	op->set = fbSet_transform;
 | |
|         op->indexed = (miIndexedPtr) pPict->pFormat->index.devPrivate;
 | |
| 	op->clip = op[1].clip;
 | |
| 	
 | |
| 	return TRUE;
 | |
|     }
 | |
|     /* Check for external alpha */
 | |
|     else if (alpha && pPict->alphaMap)
 | |
|     {
 | |
| 	if (!fbBuildCompositeOperand (pPict, &op[1], x, y, FALSE, FALSE))
 | |
| 	    return FALSE;
 | |
| 	if (!fbBuildCompositeOperand (pPict->alphaMap, &op[2],
 | |
| 				      x - pPict->alphaOrigin.x,
 | |
| 				      y - pPict->alphaOrigin.y,
 | |
| 				      FALSE, FALSE))
 | |
| 	    return FALSE;
 | |
| 	op->u.external.alpha_dx = pPict->alphaOrigin.x;
 | |
| 	op->u.external.alpha_dy = pPict->alphaOrigin.y;
 | |
| 
 | |
| 	op->fetch = fbFetch_external;
 | |
| 	op->fetcha = fbFetcha_external;
 | |
| 	op->store = fbStore_external;
 | |
| 	op->over = fbStepOver_external;
 | |
| 	op->down = fbStepDown_external;
 | |
| 	op->set = fbSet_external;
 | |
|         op->indexed = (miIndexedPtr) pPict->pFormat->index.devPrivate;
 | |
| 	/* XXX doesn't handle external alpha clips yet */
 | |
| 	op->clip = op[1].clip;
 | |
| 	
 | |
| 	return TRUE;
 | |
|     }
 | |
|     /* Build simple operand */
 | |
|     else
 | |
|     {
 | |
| 	int	    i;
 | |
| 	int	    xoff, yoff;
 | |
| 
 | |
| 	for (i = 0; i < NumAccessMap; i++)
 | |
| 	    if (fbAccessMap[i].format == pPict->format)
 | |
| 	    {
 | |
| 		FbBits	*bits;
 | |
| 		FbStride	stride;
 | |
| 		int		bpp;
 | |
| 
 | |
| 		op->fetch = fbAccessMap[i].fetch;
 | |
| 		op->fetcha = fbAccessMap[i].fetcha;
 | |
| 		op->store = fbAccessMap[i].store;
 | |
| 		op->over = fbStepOver;
 | |
| 		op->down = fbStepDown;
 | |
| 		op->set = fbSet;
 | |
| 		op->indexed = (miIndexedPtr) pPict->pFormat->index.devPrivate;
 | |
| 		op->clip = pPict->pCompositeClip;
 | |
| 
 | |
| 		fbGetDrawable (pPict->pDrawable, bits, stride, bpp,
 | |
| 			       xoff, yoff);
 | |
| 		if (pPict->repeat && pPict->pDrawable->width == 1 && 
 | |
| 		    pPict->pDrawable->height == 1)
 | |
| 		{
 | |
| 		    bpp = 0;
 | |
| 		    stride = 0;
 | |
| 		}
 | |
| 		/*
 | |
| 		 * Coordinates of upper left corner of drawable
 | |
| 		 */
 | |
| 		op->u.drawable.top_line = bits + yoff * stride;
 | |
| 		op->u.drawable.left_offset = xoff * bpp;
 | |
| 
 | |
| 		/*
 | |
| 		 * Starting position within drawable
 | |
| 		 */
 | |
| 		op->u.drawable.start_offset = op->u.drawable.left_offset + x * bpp;
 | |
| 		op->u.drawable.line = op->u.drawable.top_line + y * stride;
 | |
| 		op->u.drawable.offset = op->u.drawable.start_offset;
 | |
| 
 | |
| 		op->u.drawable.stride = stride;
 | |
| 		op->u.drawable.bpp = bpp;
 | |
| 		return TRUE;
 | |
| 	    }
 | |
| 	return FALSE;
 | |
|     }
 | |
| }
 | |
| 
 | |
| void
 | |
| fbCompositeGeneral (CARD8	op,
 | |
| 		    PicturePtr	pSrc,
 | |
| 		    PicturePtr	pMask,
 | |
| 		    PicturePtr	pDst,
 | |
| 		    INT16	xSrc,
 | |
| 		    INT16	ySrc,
 | |
| 		    INT16	xMask,
 | |
| 		    INT16	yMask,
 | |
| 		    INT16	xDst,
 | |
| 		    INT16	yDst,
 | |
| 		    CARD16	width,
 | |
| 		    CARD16	height)
 | |
| {
 | |
|     FbCompositeOperand	src[4],msk[4],dst[4],*pmsk;
 | |
|     FbCombineFunc	f;
 | |
|     int			w;
 | |
| 
 | |
|     if (!fbBuildCompositeOperand (pSrc, src, xSrc, ySrc, TRUE, TRUE))
 | |
| 	return;
 | |
|     if (!fbBuildCompositeOperand (pDst, dst, xDst, yDst, FALSE, TRUE))
 | |
| 	return;
 | |
|     f = fbCombineFuncU[op];
 | |
|     if (pMask)
 | |
|     {
 | |
| 	if (!fbBuildCompositeOperand (pMask, msk, xMask, yMask, TRUE, TRUE))
 | |
| 	    return;
 | |
| 	pmsk = msk;
 | |
| 	if (pMask->componentAlpha)
 | |
| 	    f = fbCombineFuncC[op];
 | |
|     }
 | |
|     else
 | |
| 	pmsk = 0;
 | |
|     while (height--)
 | |
|     {
 | |
| 	w = width;
 | |
| 	
 | |
| 	while (w--)
 | |
| 	{
 | |
| 	    (*f) (src, pmsk, dst);
 | |
| 	    (*src->over) (src);
 | |
| 	    (*dst->over) (dst);
 | |
| 	    if (pmsk)
 | |
| 		(*pmsk->over) (pmsk);
 | |
| 	}
 | |
| 	(*src->down) (src);
 | |
| 	(*dst->down) (dst);
 | |
| 	if (pmsk)
 | |
| 	    (*pmsk->down) (pmsk);
 | |
|     }
 | |
| }
 |