1 /* 2 * PROJECT: Win32 subsystem 3 * LICENSE: See COPYING in the top level directory 4 * FILE: win32ss/gdi/dib/alphablend.c 5 * PURPOSE: AlphaBlend implementation suitable for all bit depths 6 * PROGRAMMERS: Jérôme Gardou 7 */ 8 9 #include <win32k.h> 10 11 #define NDEBUG 12 #include <debug.h> 13 14 typedef union 15 { 16 ULONG ul; 17 struct 18 { 19 UCHAR red; 20 UCHAR green; 21 UCHAR blue; 22 UCHAR alpha; 23 } col; 24 } NICEPIXEL32; 25 26 static __inline UCHAR 27 Clamp8(ULONG val) 28 { 29 return (val > 255) ? 255 : (UCHAR)val; 30 } 31 32 BOOLEAN 33 DIB_XXBPP_AlphaBlend(SURFOBJ* Dest, SURFOBJ* Source, RECTL* DestRect, 34 RECTL* SourceRect, CLIPOBJ* ClipRegion, 35 XLATEOBJ* ColorTranslation, BLENDOBJ* BlendObj) 36 { 37 INT DstX, DstY, SrcX, SrcY; 38 BLENDFUNCTION BlendFunc; 39 register NICEPIXEL32 DstPixel32; 40 register NICEPIXEL32 SrcPixel32; 41 UCHAR Alpha, SrcBpp = BitsPerFormat(Source->iBitmapFormat); 42 EXLATEOBJ* pexlo; 43 EXLATEOBJ exloSrcRGB, exloDstRGB, exloRGBSrc; 44 PFN_DIB_PutPixel pfnDibPutPixel = DibFunctionsForBitmapFormat[Dest->iBitmapFormat].DIB_PutPixel; 45 46 DPRINT("DIB_16BPP_AlphaBlend: srcRect: (%d,%d)-(%d,%d), dstRect: (%d,%d)-(%d,%d)\n", 47 SourceRect->left, SourceRect->top, SourceRect->right, SourceRect->bottom, 48 DestRect->left, DestRect->top, DestRect->right, DestRect->bottom); 49 50 BlendFunc = BlendObj->BlendFunction; 51 if (BlendFunc.BlendOp != AC_SRC_OVER) 52 { 53 DPRINT1("BlendOp != AC_SRC_OVER\n"); 54 return FALSE; 55 } 56 if (BlendFunc.BlendFlags != 0) 57 { 58 DPRINT1("BlendFlags != 0\n"); 59 return FALSE; 60 } 61 if ((BlendFunc.AlphaFormat & ~AC_SRC_ALPHA) != 0) 62 { 63 DPRINT1("Unsupported AlphaFormat (0x%x)\n", BlendFunc.AlphaFormat); 64 return FALSE; 65 } 66 if ((BlendFunc.AlphaFormat & AC_SRC_ALPHA) != 0 && 67 SrcBpp != 32) 68 { 69 DPRINT1("Source bitmap must be 32bpp when AC_SRC_ALPHA is set\n"); 70 return FALSE; 71 } 72 73 if (!ColorTranslation) 74 { 75 DPRINT1("ColorTranslation must not be NULL!\n"); 76 return FALSE; 77 } 78 79 pexlo = CONTAINING_RECORD(ColorTranslation, EXLATEOBJ, xlo); 80 EXLATEOBJ_vInitialize(&exloSrcRGB, pexlo->ppalSrc, &gpalRGB, 0, 0, 0); 81 EXLATEOBJ_vInitialize(&exloDstRGB, pexlo->ppalDst, &gpalRGB, 0, 0, 0); 82 EXLATEOBJ_vInitialize(&exloRGBSrc, &gpalRGB, pexlo->ppalSrc, 0, 0, 0); 83 84 SrcY = SourceRect->top; 85 DstY = DestRect->top; 86 while ( DstY < DestRect->bottom ) 87 { 88 SrcX = SourceRect->left; 89 DstX = DestRect->left; 90 while(DstX < DestRect->right) 91 { 92 SrcPixel32.ul = DIB_GetSource(Source, SrcX, SrcY, &exloSrcRGB.xlo); 93 SrcPixel32.col.red = (SrcPixel32.col.red * BlendFunc.SourceConstantAlpha) / 255; 94 SrcPixel32.col.green = (SrcPixel32.col.green * BlendFunc.SourceConstantAlpha) / 255; 95 SrcPixel32.col.blue = (SrcPixel32.col.blue * BlendFunc.SourceConstantAlpha) / 255; 96 97 Alpha = ((BlendFunc.AlphaFormat & AC_SRC_ALPHA) != 0) ? 98 (SrcPixel32.col.alpha * BlendFunc.SourceConstantAlpha) / 255 : 99 BlendFunc.SourceConstantAlpha ; 100 101 DstPixel32.ul = DIB_GetSource(Dest, DstX, DstY, &exloDstRGB.xlo); 102 DstPixel32.col.red = Clamp8((DstPixel32.col.red * (255 - Alpha)) / 255 + SrcPixel32.col.red) ; 103 DstPixel32.col.green = Clamp8((DstPixel32.col.green * (255 - Alpha)) / 255 + SrcPixel32.col.green) ; 104 DstPixel32.col.blue = Clamp8((DstPixel32.col.blue * (255 - Alpha)) / 255 + SrcPixel32.col.blue) ; 105 DstPixel32.ul = XLATEOBJ_iXlate(&exloRGBSrc.xlo, DstPixel32.ul); 106 pfnDibPutPixel(Dest, DstX, DstY, XLATEOBJ_iXlate(ColorTranslation, DstPixel32.ul)); 107 108 DstX++; 109 SrcX = SourceRect->left + ((DstX-DestRect->left)*(SourceRect->right - SourceRect->left)) 110 /(DestRect->right-DestRect->left); 111 } 112 DstY++; 113 SrcY = SourceRect->top + ((DstY-DestRect->top)*(SourceRect->bottom - SourceRect->top)) 114 /(DestRect->bottom-DestRect->top); 115 } 116 117 EXLATEOBJ_vCleanup(&exloDstRGB); 118 EXLATEOBJ_vCleanup(&exloRGBSrc); 119 EXLATEOBJ_vCleanup(&exloSrcRGB); 120 121 return TRUE; 122 } 123 124