23245f3322
git-svn-id: https://svn.disconnected-by-peer.at/svn/linamh/trunk/linamh@1438 6952d904-891a-0410-993b-d76249ca496b
513 lines
19 KiB
Diff
513 lines
19 KiB
Diff
DIB Engine: implement AlphaBlend
|
|
|
|
From: Massimo Del Fedele <max@veneto.com>
|
|
|
|
|
|
---
|
|
|
|
dlls/winedib.drv/bitblt.c | 88 ++++++++--
|
|
dlls/winedib.drv/dibdrv.h | 2
|
|
dlls/winedib.drv/primitives.c | 12 +
|
|
dlls/winedib.drv/primitives_bitblt.c | 287 ++++++++++++++++++++++++++++++++++
|
|
4 files changed, 370 insertions(+), 19 deletions(-)
|
|
|
|
|
|
diff --git a/dlls/winedib.drv/bitblt.c b/dlls/winedib.drv/bitblt.c
|
|
index 20cdcaa..c0227a0 100644
|
|
--- a/dlls/winedib.drv/bitblt.c
|
|
+++ b/dlls/winedib.drv/bitblt.c
|
|
@@ -150,34 +150,84 @@ BOOL DIBDRV_AlphaBlend( DIBDRVPHYSDEV *physDevDst, INT xDst, INT yDst, INT width
|
|
xDst, yDst, widthDst, heightDst,
|
|
physDevSrc, physDevSrc->hasDIB ? "DIB-" : "DDB", physDevSrc->hasDIB ? _DIBDRVBITMAP_GetFormatName(&physDevSrc->physBitmap) : "",
|
|
xSrc, ySrc, widthSrc, heightSrc));
|
|
+
|
|
|
|
- if(physDevDst->hasDIB && physDevSrc->hasDIB)
|
|
+ /* if sizes are null or negative, returns false */
|
|
+ if(widthSrc <= 0 || heightSrc <= 0 || widthDst <= 0 || heightDst <= 0)
|
|
{
|
|
- /* DIB section selected in both source and dest DC, use DIB Engine */
|
|
- ONCE(FIXME("STUB\n"));
|
|
- res = TRUE;
|
|
+ res = FALSE;
|
|
+ goto fin;
|
|
}
|
|
- else if(!physDevDst->hasDIB && !physDevSrc->hasDIB)
|
|
+
|
|
+ /* source sould be a 32 bit DIB */
|
|
+ if(!physDevSrc)
|
|
{
|
|
- /* DDB selected in noth source and dest DC, use X11 driver */
|
|
- res = _DIBDRV_GetDisplayDriver()->pAlphaBlend(physDevDst->X11PhysDev, xDst, yDst, widthDst, heightDst,
|
|
- physDevSrc->X11PhysDev, xSrc, ySrc, widthSrc, heightSrc,
|
|
- blendfn);
|
|
+ FIXME("Null source bitmap -- shouldn't happen\n");
|
|
+ res = FALSE;
|
|
+ goto fin;
|
|
}
|
|
- else if(physDevSrc->hasDIB)
|
|
+ else if(!physDevSrc->hasDIB)
|
|
{
|
|
- /* DIB on source, DDB on dest -- must convert source DIB to DDB and use X11 driver for blit */
|
|
- ONCE(FIXME("TEMPORARY - fallback to X11 driver\n"));
|
|
- res = _DIBDRV_GetDisplayDriver()->pAlphaBlend(physDevDst->X11PhysDev, xDst, yDst, widthDst, heightDst,
|
|
- physDevSrc->X11PhysDev, xSrc, ySrc, widthSrc, heightSrc,
|
|
- blendfn);
|
|
+ FIXME("DDB source bitmap -- shouldn't happen\n");
|
|
+ res = FALSE;
|
|
+ goto fin;
|
|
}
|
|
- else /* if(physDevDst->hasDIB) */
|
|
+
|
|
+ if(physDevDst->hasDIB)
|
|
{
|
|
- /* DDB on source, DIB on dest -- must convert source DDB to DIB and use the engine for blit */
|
|
- ONCE(FIXME("STUB\n"));
|
|
- res = TRUE;
|
|
+ /* DIB section selected in dest DC, use DIB Engine */
|
|
+ MAYBE(TRACE("Blending DIB->DIB\n"));
|
|
+ res = physDevDst->physBitmap.funcs->AlphaBlend(physDevDst, xDst, yDst, widthDst, heightDst,
|
|
+ physDevSrc, xSrc, ySrc, widthSrc, heightSrc, blendfn);
|
|
+ }
|
|
+ else
|
|
+ {
|
|
+ /* DDB selected on dest DC -- must double-convert */
|
|
+ HBITMAP tmpDIB, stock;
|
|
+ HDC tmpDC;
|
|
+ MAYBE(TRACE("Blending DIB->DDB\n"));
|
|
+
|
|
+ /* converts dest DDB onto a temporary DIB -- just the needed part */
|
|
+ tmpDIB = _DIBDRV_ConvertDevDDBtoDIB(physDevDst->hdc, physDevSrc->hdc, xDst, yDst, widthDst, heightDst);
|
|
+ if(!tmpDIB)
|
|
+ {
|
|
+ ERR("Couldn't convert dest DDB to DIB\n");
|
|
+ res = FALSE;
|
|
+ goto fin;
|
|
+ }
|
|
+
|
|
+ /* selects the temporary DIB into a temporary DC */
|
|
+ tmpDC = CreateCompatibleDC(physDevDst->hdc);
|
|
+ if(!tmpDC)
|
|
+ {
|
|
+ ERR("Couldn't create temporary DC\n");
|
|
+ DeleteObject(tmpDIB);
|
|
+ res = FALSE;
|
|
+ goto fin;
|
|
+ }
|
|
+ stock = SelectObject(tmpDC, tmpDIB);
|
|
+ if(!stock)
|
|
+ {
|
|
+ ERR("Couldn't select temporary DIB into temporary DC\n");
|
|
+ DeleteDC(tmpDC);
|
|
+ DeleteObject(tmpDIB);
|
|
+ res = FALSE;
|
|
+ goto fin;
|
|
+ }
|
|
+
|
|
+ /* blends source DIB onto temp DIB and re-blits onto dest DC */
|
|
+ res = GdiAlphaBlend(tmpDC, 0, 0, widthDst, heightDst, physDevSrc->hdc, xSrc, ySrc, widthSrc, heightSrc, blendfn);
|
|
+ if(!res)
|
|
+ MAYBE(TRACE("AlphaBlend failed\n"));
|
|
+ else
|
|
+ res = BitBlt(physDevDst->hdc, xDst, yDst, widthDst, heightDst, tmpDC, 0, 0, SRCCOPY);
|
|
+
|
|
+ /* frees resources */
|
|
+ SelectObject(tmpDC, stock);
|
|
+ DeleteDC(tmpDC);
|
|
+ DeleteObject(tmpDIB);
|
|
}
|
|
+fin:
|
|
return res;
|
|
}
|
|
|
|
diff --git a/dlls/winedib.drv/dibdrv.h b/dlls/winedib.drv/dibdrv.h
|
|
index 773941e..c801d96 100644
|
|
--- a/dlls/winedib.drv/dibdrv.h
|
|
+++ b/dlls/winedib.drv/dibdrv.h
|
|
@@ -94,6 +94,8 @@ typedef struct _DIBDRV_PRIMITIVE_FUNCS
|
|
BOOL (* PutLine) ( struct _DIBDRVBITMAP *bmp, int line, int startx, int width, void *buf);
|
|
|
|
/* BitBlt primitives */
|
|
+ BOOL (* AlphaBlend) ( struct _DIBDRVPHYSDEV *physDevDst, int xDst, int yDst, int widthDst, int heightDst,
|
|
+ const struct _DIBDRVPHYSDEV *physDevSrc, int xSrc, int ySrc, int widthSrc, int heightSrc, BLENDFUNCTION blendFn );
|
|
BOOL (* BitBlt) ( struct _DIBDRVPHYSDEV *physDevDst, int xDst, int yDst, int width, int height,
|
|
const struct _DIBDRVPHYSDEV *physDevSrc, int xSrc, int ySrc, DWORD rop );
|
|
BOOL (* StretchBlt) ( struct _DIBDRVPHYSDEV *physDevDst, int xDst, int yDst, int widthDst, int heightDst,
|
|
diff --git a/dlls/winedib.drv/primitives.c b/dlls/winedib.drv/primitives.c
|
|
index cbad239..a2fa04a 100644
|
|
--- a/dlls/winedib.drv/primitives.c
|
|
+++ b/dlls/winedib.drv/primitives.c
|
|
@@ -133,6 +133,10 @@ BOOL _DIBDRV_StretchBlt_generic(DIBDRVPHYSDEV *physDevDst, INT xDst, INT yDst,
|
|
INT widthDst, INT heightDst, const DIBDRVPHYSDEV *physDevSrc,
|
|
INT xSrc, INT ySrc, int widthSrc, int heightSrc, DWORD rop);
|
|
|
|
+BOOL _DIBDRV_AlphaBlend_generic(DIBDRVPHYSDEV *physDevDst, int xDst, int yDst,
|
|
+ int widthDst, int heightDst, const DIBDRVPHYSDEV *physDevSrc,
|
|
+ int xSrc, int ySrc, int widthSrc, int heightSrc, BLENDFUNCTION blendFn );
|
|
+
|
|
/* ------------------------------------------------------------*/
|
|
/* FREETYPE FONT BITMAP BLITTING */
|
|
void _DIBDRV_freetype_blit_8888 (DIBDRVPHYSDEV *dib, int x, int y, FT_Bitmap *bmp);
|
|
@@ -156,6 +160,7 @@ DIBDRV_PRIMITIVE_FUNCS DIBDRV_funcs_DIB32_RGB =
|
|
_DIBDRV_SolidVLine32,
|
|
_DIBDRV_GetLine32_RGB,
|
|
_DIBDRV_PutLine32_RGB,
|
|
+ _DIBDRV_AlphaBlend_generic,
|
|
_DIBDRV_BitBlt_generic,
|
|
_DIBDRV_StretchBlt_generic,
|
|
_DIBDRV_freetype_blit_32_RGB
|
|
@@ -172,6 +177,7 @@ DIBDRV_PRIMITIVE_FUNCS DIBDRV_funcs_DIB32_BITFIELDS =
|
|
_DIBDRV_SolidVLine32,
|
|
_DIBDRV_GetLine32_BITFIELDS,
|
|
_DIBDRV_PutLine32_BITFIELDS,
|
|
+ _DIBDRV_AlphaBlend_generic,
|
|
_DIBDRV_BitBlt_generic,
|
|
_DIBDRV_StretchBlt_generic,
|
|
_DIBDRV_freetype_blit_32_BITFIELDS
|
|
@@ -188,6 +194,7 @@ DIBDRV_PRIMITIVE_FUNCS DIBDRV_funcs_DIB24 =
|
|
_DIBDRV_SolidVLine24,
|
|
_DIBDRV_GetLine24,
|
|
_DIBDRV_PutLine24,
|
|
+ _DIBDRV_AlphaBlend_generic,
|
|
_DIBDRV_BitBlt_generic,
|
|
_DIBDRV_StretchBlt_generic,
|
|
_DIBDRV_freetype_blit_24
|
|
@@ -204,6 +211,7 @@ DIBDRV_PRIMITIVE_FUNCS DIBDRV_funcs_DIB16_RGB =
|
|
_DIBDRV_SolidVLine16,
|
|
_DIBDRV_GetLine16_RGB,
|
|
_DIBDRV_PutLine16_RGB,
|
|
+ _DIBDRV_AlphaBlend_generic,
|
|
_DIBDRV_BitBlt_generic,
|
|
_DIBDRV_StretchBlt_generic,
|
|
_DIBDRV_freetype_blit_16_RGB
|
|
@@ -220,6 +228,7 @@ DIBDRV_PRIMITIVE_FUNCS DIBDRV_funcs_DIB16_BITFIELDS =
|
|
_DIBDRV_SolidVLine16,
|
|
_DIBDRV_GetLine16_BITFIELDS,
|
|
_DIBDRV_PutLine16_BITFIELDS,
|
|
+ _DIBDRV_AlphaBlend_generic,
|
|
_DIBDRV_BitBlt_generic,
|
|
_DIBDRV_StretchBlt_generic,
|
|
_DIBDRV_freetype_blit_16_BITFIELDS
|
|
@@ -236,6 +245,7 @@ DIBDRV_PRIMITIVE_FUNCS DIBDRV_funcs_DIB8 =
|
|
_DIBDRV_SolidVLine8,
|
|
_DIBDRV_GetLine8,
|
|
_DIBDRV_PutLine8,
|
|
+ _DIBDRV_AlphaBlend_generic,
|
|
_DIBDRV_BitBlt_generic,
|
|
_DIBDRV_StretchBlt_generic,
|
|
_DIBDRV_freetype_blit_8
|
|
@@ -252,6 +262,7 @@ DIBDRV_PRIMITIVE_FUNCS DIBDRV_funcs_DIB4 =
|
|
_DIBDRV_SolidVLine4,
|
|
_DIBDRV_GetLine4,
|
|
_DIBDRV_PutLine4,
|
|
+ _DIBDRV_AlphaBlend_generic,
|
|
_DIBDRV_BitBlt_generic,
|
|
_DIBDRV_StretchBlt_generic,
|
|
_DIBDRV_freetype_blit_4
|
|
@@ -268,6 +279,7 @@ DIBDRV_PRIMITIVE_FUNCS DIBDRV_funcs_DIB1 =
|
|
_DIBDRV_SolidVLine1,
|
|
_DIBDRV_GetLine1,
|
|
_DIBDRV_PutLine1,
|
|
+ _DIBDRV_AlphaBlend_generic,
|
|
_DIBDRV_BitBlt_generic,
|
|
_DIBDRV_StretchBlt_generic,
|
|
_DIBDRV_freetype_blit_1
|
|
diff --git a/dlls/winedib.drv/primitives_bitblt.c b/dlls/winedib.drv/primitives_bitblt.c
|
|
index da48352..7540dad 100644
|
|
--- a/dlls/winedib.drv/primitives_bitblt.c
|
|
+++ b/dlls/winedib.drv/primitives_bitblt.c
|
|
@@ -80,6 +80,293 @@ static void StretchLine(DWORD *dst, int dstWidth, DWORD *src, int srcWidth)
|
|
memcpy(dst, src, 4 * srcWidth);
|
|
}
|
|
|
|
+/* premultiply alpha channel on a line by a constant alpha
|
|
+ note : it seems that pixels are already premultiplied
|
|
+ by alpha channel content */
|
|
+static void PemultiplyLine(DWORD *dst, int width, BYTE constAlpha)
|
|
+{
|
|
+ int i = width;
|
|
+ BYTE *alphaPnt = (BYTE *)dst + 3;
|
|
+
|
|
+ /* small optimization for 0 and 255 values of constAlpha */
|
|
+
|
|
+ /* fully transparent -- just sets all pix to 0 */
|
|
+ if(constAlpha == 0)
|
|
+ {
|
|
+ while(i--)
|
|
+ *dst++ = 0;
|
|
+ return;
|
|
+ }
|
|
+
|
|
+ /* fully opaque, just do nothing */
|
|
+ if(constAlpha == 255)
|
|
+ return;
|
|
+
|
|
+ /* intermediate -- premultiply alpha values */
|
|
+ while(i--)
|
|
+ {
|
|
+ *alphaPnt = MulDiv(*alphaPnt, constAlpha, 255);
|
|
+ alphaPnt += 4;
|
|
+ }
|
|
+ return;
|
|
+
|
|
+}
|
|
+
|
|
+/* alpha blends a source line onto a destination line
|
|
+ preconditions :
|
|
+ 1) source and dest widths must be the same
|
|
+ 2) source line should be already premultiplied by constant alpha */
|
|
+static void BlendLine(DWORD *dst, DWORD *src, int width)
|
|
+{
|
|
+ int i = width;
|
|
+ BYTE *blueDst = (BYTE *)dst;
|
|
+ BYTE *greenDst = blueDst + 1;
|
|
+ BYTE *redDst = greenDst + 1;
|
|
+ BYTE *blueSrc = (BYTE *)src;
|
|
+ BYTE *greenSrc = blueSrc + 1;
|
|
+ BYTE *redSrc = greenSrc + 1;
|
|
+ BYTE *alphaSrc = redSrc + 1;
|
|
+ BYTE alpha;
|
|
+
|
|
+ /* still don't know if it must take in account an eventual dest
|
|
+ alpha channel..... */
|
|
+ while(i--)
|
|
+ {
|
|
+ alpha = 255 - *alphaSrc;
|
|
+
|
|
+ *blueDst = *blueSrc + MulDiv(*blueDst, alpha, 255);
|
|
+ *greenDst = *greenSrc + MulDiv(*greenDst, alpha, 255);
|
|
+ *redDst = *redSrc + MulDiv(*redDst, alpha, 255);
|
|
+
|
|
+ blueSrc += 4;
|
|
+ greenSrc += 4;
|
|
+ redSrc += 4;
|
|
+ alphaSrc += 4;
|
|
+ blueDst += 4;
|
|
+ greenDst += 4;
|
|
+ redDst += 4;
|
|
+ }
|
|
+
|
|
+}
|
|
+
|
|
+/* ------------------------------------------------------------*/
|
|
+/* ALPHABLEND PRIMITIVES */
|
|
+BOOL _DIBDRV_AlphaBlend_generic(DIBDRVPHYSDEV *physDevDst, INT xDst, INT yDst,
|
|
+ INT widthDst, INT heightDst, const DIBDRVPHYSDEV *physDevSrc,
|
|
+ INT xSrc, INT ySrc, int widthSrc, int heightSrc, BLENDFUNCTION blendFn)
|
|
+{
|
|
+ /* flags indicating wether source should be stretched */
|
|
+ BOOL horStretch = (widthSrc != widthDst);
|
|
+ BOOL verStretch = (heightSrc != heightDst);
|
|
+
|
|
+ /* constant alpha value */
|
|
+ BYTE constAlpha = blendFn.SourceConstantAlpha;
|
|
+
|
|
+ /* source and dest bitmaps */
|
|
+ const DIBDRVBITMAP *srcBmp = &physDevSrc->physBitmap;
|
|
+ DIBDRVBITMAP *dstBmp = &physDevDst->physBitmap;
|
|
+
|
|
+ /* source and destination line buffers */
|
|
+ DWORD *sBuf = HeapAlloc(GetProcessHeap(), 0, abs(srcBmp->stride));
|
|
+ DWORD *dBuf = HeapAlloc(GetProcessHeap(), 0, abs(dstBmp->stride));
|
|
+
|
|
+ int ys = ySrc;
|
|
+ int yd = yDst;
|
|
+ int iLine;
|
|
+ int delta;
|
|
+
|
|
+ /* in order to optimize a bit, we divide the routine in 4 parts,
|
|
+ depending on stretching modes */
|
|
+ if(!horStretch && !verStretch)
|
|
+ {
|
|
+ /* simplest case, no stretching needed */
|
|
+ MAYBE(TRACE("No stretching\n"));
|
|
+ for(iLine = 0; iLine < heightSrc; iLine++, ys++, yd++)
|
|
+ {
|
|
+ /* load source and dest lines */
|
|
+ srcBmp->funcs->GetLine(srcBmp, ys, xSrc, widthSrc, sBuf);
|
|
+ dstBmp->funcs->GetLine(dstBmp, yd, xDst, widthDst, dBuf);
|
|
+
|
|
+ /* premultiply source by constant and pixel alpha */
|
|
+ PemultiplyLine(sBuf, widthSrc, constAlpha);
|
|
+
|
|
+ /* blends source on dest */
|
|
+ BlendLine(dBuf, sBuf, widthSrc);
|
|
+
|
|
+ /* puts dest line back */
|
|
+ dstBmp->funcs->PutLine(dstBmp, yd, xDst, widthDst, dBuf);
|
|
+ }
|
|
+ }
|
|
+ else if (horStretch && !verStretch)
|
|
+ {
|
|
+ /* just horizontal stretching needed */
|
|
+ DWORD *strBuf = HeapAlloc(GetProcessHeap(), 0, abs(dstBmp->stride));
|
|
+ MAYBE(TRACE("Horizontal stretching\n"));
|
|
+
|
|
+ for(iLine = 0; iLine < heightSrc; iLine++, ys++, yd++)
|
|
+ {
|
|
+ /* load source and dest lines */
|
|
+ srcBmp->funcs->GetLine(srcBmp, ys, xSrc, widthSrc, sBuf);
|
|
+ dstBmp->funcs->GetLine(dstBmp, yd, xDst, widthDst, dBuf);
|
|
+
|
|
+ /* stretch source line to match dest one */
|
|
+ StretchLine(strBuf, widthDst, sBuf, widthSrc);
|
|
+
|
|
+ /* premultiply source by constant and pixel alpha */
|
|
+ PemultiplyLine(strBuf, widthDst, constAlpha);
|
|
+
|
|
+ /* blends source on dest */
|
|
+ BlendLine(dBuf, sBuf, widthDst);
|
|
+
|
|
+ /* puts dest line back */
|
|
+ dstBmp->funcs->PutLine(dstBmp, yd, xDst, widthDst, dBuf);
|
|
+ }
|
|
+ HeapFree(GetProcessHeap(), 0, strBuf);
|
|
+ }
|
|
+ else if (!horStretch && verStretch)
|
|
+ {
|
|
+ /* just vertical stretching needed */
|
|
+ MAYBE(TRACE("Vertical stretching\n"));
|
|
+
|
|
+ if(heightSrc > heightDst)
|
|
+ {
|
|
+ iLine = 0;
|
|
+ delta = 0;
|
|
+ while(iLine < heightDst)
|
|
+ {
|
|
+ /* load source and dest lines */
|
|
+ srcBmp->funcs->GetLine(srcBmp, ys, xSrc, widthSrc, sBuf);
|
|
+ dstBmp->funcs->GetLine(dstBmp, yd, xDst, widthDst, dBuf);
|
|
+
|
|
+ /* premultiply source by constant and pixel alpha */
|
|
+ PemultiplyLine(sBuf, widthSrc, constAlpha);
|
|
+
|
|
+ /* blends source on dest */
|
|
+ BlendLine(dBuf, sBuf, widthDst);
|
|
+
|
|
+ /* puts dest line back */
|
|
+ dstBmp->funcs->PutLine(dstBmp, yd, xDst, widthDst, dBuf);
|
|
+
|
|
+ while(delta < heightSrc)
|
|
+ {
|
|
+ ys++;
|
|
+ delta += heightDst;
|
|
+ }
|
|
+ delta -= heightSrc;
|
|
+ yd++;
|
|
+ iLine++;
|
|
+ }
|
|
+ }
|
|
+ else if(heightSrc < heightDst)
|
|
+ {
|
|
+ iLine = 0;
|
|
+ delta = 0;
|
|
+ while(iLine < heightSrc)
|
|
+ {
|
|
+ /* load source line */
|
|
+ srcBmp->funcs->GetLine(srcBmp, ys, xSrc, widthSrc, sBuf);
|
|
+
|
|
+ /* premultiply source by constant and pixel alpha */
|
|
+ PemultiplyLine(sBuf, widthSrc, constAlpha);
|
|
+
|
|
+ while(delta < heightDst)
|
|
+ {
|
|
+ /* load dest line */
|
|
+ dstBmp->funcs->GetLine(dstBmp, yd, xDst, widthDst, dBuf);
|
|
+
|
|
+ /* blends source on dest */
|
|
+ BlendLine(dBuf, sBuf, widthDst);
|
|
+
|
|
+ /* puts dest line back */
|
|
+ dstBmp->funcs->PutLine(dstBmp, yd, xDst, widthDst, dBuf);
|
|
+ yd++;
|
|
+ delta += heightSrc;
|
|
+ }
|
|
+ delta -= heightDst;
|
|
+ ys++;
|
|
+ iLine++;
|
|
+ }
|
|
+ }
|
|
+ }
|
|
+ else
|
|
+ {
|
|
+ DWORD *strBuf = HeapAlloc(GetProcessHeap(), 0, abs(dstBmp->stride));
|
|
+ /* both stretching needed -- generic case */
|
|
+ MAYBE(TRACE("Horizontal and vertical stretching\n"));
|
|
+
|
|
+ if(heightSrc > heightDst)
|
|
+ {
|
|
+ iLine = 0;
|
|
+ delta = 0;
|
|
+ while(iLine < heightDst)
|
|
+ {
|
|
+ /* load source and dest lines */
|
|
+ srcBmp->funcs->GetLine(srcBmp, ys, xSrc, widthSrc, sBuf);
|
|
+ dstBmp->funcs->GetLine(dstBmp, yd, xDst, widthDst, dBuf);
|
|
+
|
|
+ /* stretch source line to match dest one */
|
|
+ StretchLine(strBuf, widthDst, sBuf, widthSrc);
|
|
+
|
|
+ /* premultiply source by constant and pixel alpha */
|
|
+ PemultiplyLine(strBuf, widthDst, constAlpha);
|
|
+
|
|
+ /* blends source on dest */
|
|
+ BlendLine(dBuf, strBuf, widthDst);
|
|
+
|
|
+ /* puts dest line back */
|
|
+ dstBmp->funcs->PutLine(dstBmp, yd, xDst, widthDst, dBuf);
|
|
+
|
|
+ while(delta < heightSrc)
|
|
+ {
|
|
+ ys++;
|
|
+ delta += heightDst;
|
|
+ }
|
|
+ delta -= heightSrc;
|
|
+ yd++;
|
|
+ iLine++;
|
|
+ }
|
|
+ }
|
|
+ else if(heightSrc < heightDst)
|
|
+ {
|
|
+ iLine = 0;
|
|
+ delta = 0;
|
|
+ while(iLine < heightSrc)
|
|
+ {
|
|
+ /* load source line */
|
|
+ srcBmp->funcs->GetLine(srcBmp, ys, xSrc, widthSrc, sBuf);
|
|
+
|
|
+ /* stretch source line to match dest one */
|
|
+ StretchLine(strBuf, widthDst, sBuf, widthSrc);
|
|
+
|
|
+ /* premultiply source by constant and pixel alpha */
|
|
+ PemultiplyLine(strBuf, widthDst, constAlpha);
|
|
+
|
|
+ while(delta < heightDst)
|
|
+ {
|
|
+ /* load dest line */
|
|
+ dstBmp->funcs->GetLine(dstBmp, yd, xDst, widthDst, dBuf);
|
|
+
|
|
+ /* blends source on dest */
|
|
+ BlendLine(dBuf, strBuf, widthDst);
|
|
+
|
|
+ /* puts dest line back */
|
|
+ dstBmp->funcs->PutLine(dstBmp, yd, xDst, widthDst, dBuf);
|
|
+ yd++;
|
|
+ delta += heightSrc;
|
|
+ }
|
|
+ delta -= heightDst;
|
|
+ ys++;
|
|
+ iLine++;
|
|
+ }
|
|
+ }
|
|
+ HeapFree(GetProcessHeap(), 0, strBuf);
|
|
+ }
|
|
+
|
|
+ HeapFree(GetProcessHeap(), 0, sBuf);
|
|
+ HeapFree(GetProcessHeap(), 0, dBuf);
|
|
+ return TRUE;
|
|
+}
|
|
+
|
|
/* ------------------------------------------------------------*/
|
|
/* BLITTING PRIMITIVES */
|
|
BOOL _DIBDRV_BitBlt_generic(DIBDRVPHYSDEV *physDevDst, INT xDst, INT yDst,
|