- Evgeny Boltik, <BSTSoft AT narod DOT ru>: Add stretching support to TransparentBlt

- This should improve themes support & probably show some bitmaps that were hidden before in certain applications
- See bug #4337 for more information

svn path=/trunk/; revision=40380
This commit is contained in:
Gregor Schneider 2009-04-05 23:13:09 +00:00
parent feca367754
commit 07a533fe02
10 changed files with 224 additions and 114 deletions

View file

@ -235,7 +235,7 @@ BOOLEAN Dummy_StretchBlt(SURFOBJ *DestSurf, SURFOBJ *SourceSurf,
} }
BOOLEAN Dummy_TransparentBlt(SURFOBJ *DestSurf, SURFOBJ *SourceSurf, BOOLEAN Dummy_TransparentBlt(SURFOBJ *DestSurf, SURFOBJ *SourceSurf,
RECTL* DestRect, POINTL *SourcePoint, RECTL* DestRect, RECTL *SourceRect,
XLATEOBJ *ColorTranslation, ULONG iTransColor) XLATEOBJ *ColorTranslation, ULONG iTransColor)
{ {
return FALSE; return FALSE;

View file

@ -42,7 +42,7 @@ typedef VOID (*PFN_DIB_HLine)(SURFOBJ*,LONG,LONG,LONG,ULONG);
typedef VOID (*PFN_DIB_VLine)(SURFOBJ*,LONG,LONG,LONG,ULONG); typedef VOID (*PFN_DIB_VLine)(SURFOBJ*,LONG,LONG,LONG,ULONG);
typedef BOOLEAN (*PFN_DIB_BitBlt)(PBLTINFO); typedef BOOLEAN (*PFN_DIB_BitBlt)(PBLTINFO);
typedef BOOLEAN (*PFN_DIB_StretchBlt)(SURFOBJ*,SURFOBJ*,SURFOBJ*,SURFOBJ*,RECTL*,RECTL*,POINTL*,BRUSHOBJ*,POINTL*,XLATEOBJ*,XLATEOBJ*,ROP4); typedef BOOLEAN (*PFN_DIB_StretchBlt)(SURFOBJ*,SURFOBJ*,SURFOBJ*,SURFOBJ*,RECTL*,RECTL*,POINTL*,BRUSHOBJ*,POINTL*,XLATEOBJ*,XLATEOBJ*,ROP4);
typedef BOOLEAN (*PFN_DIB_TransparentBlt)(SURFOBJ*,SURFOBJ*,RECTL*,POINTL*,XLATEOBJ*,ULONG); typedef BOOLEAN (*PFN_DIB_TransparentBlt)(SURFOBJ*,SURFOBJ*,RECTL*,RECTL*,XLATEOBJ*,ULONG);
typedef BOOLEAN (*PFN_DIB_ColorFill)(SURFOBJ*, RECTL*, ULONG); typedef BOOLEAN (*PFN_DIB_ColorFill)(SURFOBJ*, RECTL*, ULONG);
typedef BOOLEAN (*PFN_DIB_AlphaBlend)(SURFOBJ*, SURFOBJ*, RECTL*, RECTL*, CLIPOBJ*, XLATEOBJ*, BLENDOBJ*); typedef BOOLEAN (*PFN_DIB_AlphaBlend)(SURFOBJ*, SURFOBJ*, RECTL*, RECTL*, CLIPOBJ*, XLATEOBJ*, BLENDOBJ*);
@ -68,7 +68,7 @@ VOID Dummy_HLine(SURFOBJ*,LONG,LONG,LONG,ULONG);
VOID Dummy_VLine(SURFOBJ*,LONG,LONG,LONG,ULONG); VOID Dummy_VLine(SURFOBJ*,LONG,LONG,LONG,ULONG);
BOOLEAN Dummy_BitBlt(PBLTINFO); BOOLEAN Dummy_BitBlt(PBLTINFO);
BOOLEAN Dummy_StretchBlt(SURFOBJ*,SURFOBJ*,SURFOBJ*,SURFOBJ*,RECTL*,RECTL*,POINTL*,BRUSHOBJ*,POINTL*,XLATEOBJ*,XLATEOBJ*,ROP4); BOOLEAN Dummy_StretchBlt(SURFOBJ*,SURFOBJ*,SURFOBJ*,SURFOBJ*,RECTL*,RECTL*,POINTL*,BRUSHOBJ*,POINTL*,XLATEOBJ*,XLATEOBJ*,ROP4);
BOOLEAN Dummy_TransparentBlt(SURFOBJ*,SURFOBJ*,RECTL*,POINTL*,XLATEOBJ*,ULONG); BOOLEAN Dummy_TransparentBlt(SURFOBJ*,SURFOBJ*,RECTL*,RECTL*,XLATEOBJ*,ULONG);
BOOLEAN Dummy_ColorFill(SURFOBJ*, RECTL*, ULONG); BOOLEAN Dummy_ColorFill(SURFOBJ*, RECTL*, ULONG);
BOOLEAN Dummy_AlphaBlend(SURFOBJ*, SURFOBJ*, RECTL*, RECTL*, CLIPOBJ*, XLATEOBJ*, BLENDOBJ*); BOOLEAN Dummy_AlphaBlend(SURFOBJ*, SURFOBJ*, RECTL*, RECTL*, CLIPOBJ*, XLATEOBJ*, BLENDOBJ*);
@ -78,7 +78,7 @@ VOID DIB_1BPP_HLine(SURFOBJ*,LONG,LONG,LONG,ULONG);
VOID DIB_1BPP_VLine(SURFOBJ*,LONG,LONG,LONG,ULONG); VOID DIB_1BPP_VLine(SURFOBJ*,LONG,LONG,LONG,ULONG);
BOOLEAN DIB_1BPP_BitBlt(PBLTINFO); BOOLEAN DIB_1BPP_BitBlt(PBLTINFO);
BOOLEAN DIB_1BPP_BitBltSrcCopy(PBLTINFO); BOOLEAN DIB_1BPP_BitBltSrcCopy(PBLTINFO);
BOOLEAN DIB_1BPP_TransparentBlt(SURFOBJ*,SURFOBJ*,RECTL*,POINTL*,XLATEOBJ*,ULONG); BOOLEAN DIB_1BPP_TransparentBlt(SURFOBJ*,SURFOBJ*,RECTL*,RECTL*,XLATEOBJ*,ULONG);
BOOLEAN DIB_1BPP_ColorFill(SURFOBJ*, RECTL*, ULONG); BOOLEAN DIB_1BPP_ColorFill(SURFOBJ*, RECTL*, ULONG);
BOOLEAN DIB_1BPP_AlphaBlend(SURFOBJ*, SURFOBJ*, RECTL*, RECTL*, CLIPOBJ*, XLATEOBJ*, BLENDOBJ*); BOOLEAN DIB_1BPP_AlphaBlend(SURFOBJ*, SURFOBJ*, RECTL*, RECTL*, CLIPOBJ*, XLATEOBJ*, BLENDOBJ*);
@ -88,7 +88,7 @@ VOID DIB_4BPP_HLine(SURFOBJ*,LONG,LONG,LONG,ULONG);
VOID DIB_4BPP_VLine(SURFOBJ*,LONG,LONG,LONG,ULONG); VOID DIB_4BPP_VLine(SURFOBJ*,LONG,LONG,LONG,ULONG);
BOOLEAN DIB_4BPP_BitBlt(PBLTINFO); BOOLEAN DIB_4BPP_BitBlt(PBLTINFO);
BOOLEAN DIB_4BPP_BitBltSrcCopy(PBLTINFO); BOOLEAN DIB_4BPP_BitBltSrcCopy(PBLTINFO);
BOOLEAN DIB_4BPP_TransparentBlt(SURFOBJ*,SURFOBJ*,RECTL*,POINTL*,XLATEOBJ*,ULONG); BOOLEAN DIB_4BPP_TransparentBlt(SURFOBJ*,SURFOBJ*,RECTL*,RECTL*,XLATEOBJ*,ULONG);
BOOLEAN DIB_4BPP_ColorFill(SURFOBJ*, RECTL*, ULONG); BOOLEAN DIB_4BPP_ColorFill(SURFOBJ*, RECTL*, ULONG);
BOOLEAN DIB_4BPP_AlphaBlend(SURFOBJ*, SURFOBJ*, RECTL*, RECTL*, CLIPOBJ*, XLATEOBJ*, BLENDOBJ*); BOOLEAN DIB_4BPP_AlphaBlend(SURFOBJ*, SURFOBJ*, RECTL*, RECTL*, CLIPOBJ*, XLATEOBJ*, BLENDOBJ*);
@ -98,7 +98,7 @@ VOID DIB_8BPP_HLine(SURFOBJ*,LONG,LONG,LONG,ULONG);
VOID DIB_8BPP_VLine(SURFOBJ*,LONG,LONG,LONG,ULONG); VOID DIB_8BPP_VLine(SURFOBJ*,LONG,LONG,LONG,ULONG);
BOOLEAN DIB_8BPP_BitBlt(PBLTINFO); BOOLEAN DIB_8BPP_BitBlt(PBLTINFO);
BOOLEAN DIB_8BPP_BitBltSrcCopy(PBLTINFO); BOOLEAN DIB_8BPP_BitBltSrcCopy(PBLTINFO);
BOOLEAN DIB_8BPP_TransparentBlt(SURFOBJ*,SURFOBJ*,RECTL*,POINTL*,XLATEOBJ*,ULONG); BOOLEAN DIB_8BPP_TransparentBlt(SURFOBJ*,SURFOBJ*,RECTL*,RECTL*,XLATEOBJ*,ULONG);
BOOLEAN DIB_8BPP_ColorFill(SURFOBJ*, RECTL*, ULONG); BOOLEAN DIB_8BPP_ColorFill(SURFOBJ*, RECTL*, ULONG);
BOOLEAN DIB_8BPP_AlphaBlend(SURFOBJ*, SURFOBJ*, RECTL*, RECTL*, CLIPOBJ*, XLATEOBJ*, BLENDOBJ*); BOOLEAN DIB_8BPP_AlphaBlend(SURFOBJ*, SURFOBJ*, RECTL*, RECTL*, CLIPOBJ*, XLATEOBJ*, BLENDOBJ*);
@ -108,7 +108,7 @@ VOID DIB_16BPP_HLine(SURFOBJ*,LONG,LONG,LONG,ULONG);
VOID DIB_16BPP_VLine(SURFOBJ*,LONG,LONG,LONG,ULONG); VOID DIB_16BPP_VLine(SURFOBJ*,LONG,LONG,LONG,ULONG);
BOOLEAN DIB_16BPP_BitBlt(PBLTINFO); BOOLEAN DIB_16BPP_BitBlt(PBLTINFO);
BOOLEAN DIB_16BPP_BitBltSrcCopy(PBLTINFO); BOOLEAN DIB_16BPP_BitBltSrcCopy(PBLTINFO);
BOOLEAN DIB_16BPP_TransparentBlt(SURFOBJ*,SURFOBJ*,RECTL*,POINTL*,XLATEOBJ*,ULONG); BOOLEAN DIB_16BPP_TransparentBlt(SURFOBJ*,SURFOBJ*,RECTL*,RECTL*,XLATEOBJ*,ULONG);
BOOLEAN DIB_16BPP_ColorFill(SURFOBJ*, RECTL*, ULONG); BOOLEAN DIB_16BPP_ColorFill(SURFOBJ*, RECTL*, ULONG);
BOOLEAN DIB_16BPP_AlphaBlend(SURFOBJ*, SURFOBJ*, RECTL*, RECTL*, CLIPOBJ*, XLATEOBJ*, BLENDOBJ*); BOOLEAN DIB_16BPP_AlphaBlend(SURFOBJ*, SURFOBJ*, RECTL*, RECTL*, CLIPOBJ*, XLATEOBJ*, BLENDOBJ*);
@ -118,7 +118,7 @@ VOID DIB_24BPP_HLine(SURFOBJ*,LONG,LONG,LONG,ULONG);
VOID DIB_24BPP_VLine(SURFOBJ*,LONG,LONG,LONG,ULONG); VOID DIB_24BPP_VLine(SURFOBJ*,LONG,LONG,LONG,ULONG);
BOOLEAN DIB_24BPP_BitBlt(PBLTINFO); BOOLEAN DIB_24BPP_BitBlt(PBLTINFO);
BOOLEAN DIB_24BPP_BitBltSrcCopy(PBLTINFO); BOOLEAN DIB_24BPP_BitBltSrcCopy(PBLTINFO);
BOOLEAN DIB_24BPP_TransparentBlt(SURFOBJ*,SURFOBJ*,RECTL*,POINTL*,XLATEOBJ*,ULONG); BOOLEAN DIB_24BPP_TransparentBlt(SURFOBJ*,SURFOBJ*,RECTL*,RECTL*,XLATEOBJ*,ULONG);
BOOLEAN DIB_24BPP_ColorFill(SURFOBJ*, RECTL*, ULONG); BOOLEAN DIB_24BPP_ColorFill(SURFOBJ*, RECTL*, ULONG);
BOOLEAN DIB_24BPP_AlphaBlend(SURFOBJ*, SURFOBJ*, RECTL*, RECTL*, CLIPOBJ*, XLATEOBJ*, BLENDOBJ*); BOOLEAN DIB_24BPP_AlphaBlend(SURFOBJ*, SURFOBJ*, RECTL*, RECTL*, CLIPOBJ*, XLATEOBJ*, BLENDOBJ*);
@ -128,7 +128,7 @@ VOID DIB_32BPP_HLine(SURFOBJ*,LONG,LONG,LONG,ULONG);
VOID DIB_32BPP_VLine(SURFOBJ*,LONG,LONG,LONG,ULONG); VOID DIB_32BPP_VLine(SURFOBJ*,LONG,LONG,LONG,ULONG);
BOOLEAN DIB_32BPP_BitBlt(PBLTINFO); BOOLEAN DIB_32BPP_BitBlt(PBLTINFO);
BOOLEAN DIB_32BPP_BitBltSrcCopy(PBLTINFO); BOOLEAN DIB_32BPP_BitBltSrcCopy(PBLTINFO);
BOOLEAN DIB_32BPP_TransparentBlt(SURFOBJ*,SURFOBJ*,RECTL*,POINTL*,XLATEOBJ*,ULONG); BOOLEAN DIB_32BPP_TransparentBlt(SURFOBJ*,SURFOBJ*,RECTL*,RECTL*,XLATEOBJ*,ULONG);
BOOLEAN DIB_32BPP_ColorFill(SURFOBJ*, RECTL*, ULONG); BOOLEAN DIB_32BPP_ColorFill(SURFOBJ*, RECTL*, ULONG);
BOOLEAN DIB_32BPP_AlphaBlend(SURFOBJ*, SURFOBJ*, RECTL*, RECTL*, CLIPOBJ*, XLATEOBJ*, BLENDOBJ*); BOOLEAN DIB_32BPP_AlphaBlend(SURFOBJ*, SURFOBJ*, RECTL*, RECTL*, CLIPOBJ*, XLATEOBJ*, BLENDOBJ*);

View file

@ -455,14 +455,23 @@ DIB_16BPP_ColorFill(SURFOBJ* DestSurface, RECTL* DestRect, ULONG color)
BOOLEAN BOOLEAN
DIB_16BPP_TransparentBlt(SURFOBJ *DestSurf, SURFOBJ *SourceSurf, DIB_16BPP_TransparentBlt(SURFOBJ *DestSurf, SURFOBJ *SourceSurf,
RECTL* DestRect, POINTL *SourcePoint, RECTL* DestRect, RECTL *SourceRect,
XLATEOBJ *ColorTranslation, ULONG iTransColor) XLATEOBJ *ColorTranslation, ULONG iTransColor)
{ {
ULONG RoundedRight, X, Y, SourceX, SourceY, Source, wd, Dest; ULONG RoundedRight, X, Y, SourceX = 0, SourceY = 0, Source, wd, Dest;
ULONG *DestBits; ULONG *DestBits;
LONG DstHeight;
LONG DstWidth;
LONG SrcHeight;
LONG SrcWidth;
DstHeight = DestRect->bottom - DestRect->top;
DstWidth = DestRect->right - DestRect->left;
SrcHeight = SourceRect->bottom - SourceRect->top;
SrcWidth = SourceRect->right - SourceRect->left;
RoundedRight = DestRect->right - ((DestRect->right - DestRect->left) & 0x1); RoundedRight = DestRect->right - ((DestRect->right - DestRect->left) & 0x1);
SourceY = SourcePoint->y;
DestBits = (ULONG*)((PBYTE)DestSurf->pvScan0 + DestBits = (ULONG*)((PBYTE)DestSurf->pvScan0 +
(DestRect->left << 1) + (DestRect->left << 1) +
DestRect->top * DestSurf->lDelta); DestRect->top * DestSurf->lDelta);
@ -470,23 +479,33 @@ DIB_16BPP_TransparentBlt(SURFOBJ *DestSurf, SURFOBJ *SourceSurf,
for(Y = DestRect->top; Y < DestRect->bottom; Y++) for(Y = DestRect->top; Y < DestRect->bottom; Y++)
{ {
SourceX = SourcePoint->x; SourceY = SourceRect->top+(Y - DestRect->top) * SrcHeight / DstHeight;
for(X = DestRect->left; X < RoundedRight; X += 2, DestBits++, SourceX += 2) for(X = DestRect->left; X < RoundedRight; X += 2, DestBits++, SourceX += 2)
{ {
Dest = *DestBits; Dest = *DestBits;
Source = DIB_GetSourceIndex(SourceSurf, SourceX, SourceY);
if(Source != iTransColor) SourceX = SourceRect->left+(X - DestRect->left) * SrcWidth / DstWidth;
if (SourceX >= 0 && SourceY >= 0 &&
SourceSurf->sizlBitmap.cx > SourceX && SourceSurf->sizlBitmap.cy > SourceY)
{ {
Dest &= 0xFFFF0000; Source = DIB_GetSourceIndex(SourceSurf, SourceX, SourceY);
Dest |= (XLATEOBJ_iXlate(ColorTranslation, Source) & 0xFFFF); if(Source != iTransColor)
{
Dest &= 0xFFFF0000;
Dest |= (XLATEOBJ_iXlate(ColorTranslation, Source) & 0xFFFF);
}
} }
Source = DIB_GetSourceIndex(SourceSurf, SourceX + 1, SourceY); SourceX = SourceRect->left+(X+1 - DestRect->left) * SrcWidth / DstWidth;
if(Source != iTransColor) if (SourceX >= 0 && SourceY >= 0 &&
SourceSurf->sizlBitmap.cx > SourceX && SourceSurf->sizlBitmap.cy > SourceY)
{ {
Dest &= 0xFFFF; Source = DIB_GetSourceIndex(SourceSurf, SourceX, SourceY);
Dest |= (XLATEOBJ_iXlate(ColorTranslation, Source) << 16); if(Source != iTransColor)
{
Dest &= 0xFFFF;
Dest |= (XLATEOBJ_iXlate(ColorTranslation, Source) << 16);
}
} }
*DestBits = Dest; *DestBits = Dest;
@ -494,17 +513,21 @@ DIB_16BPP_TransparentBlt(SURFOBJ *DestSurf, SURFOBJ *SourceSurf,
if(X < DestRect->right) if(X < DestRect->right)
{ {
Source = DIB_GetSourceIndex(SourceSurf, SourceX, SourceY); SourceX = SourceRect->left+(X - DestRect->left) * SrcWidth / DstWidth;
if(Source != iTransColor) if (SourceX >= 0 && SourceY >= 0 &&
SourceSurf->sizlBitmap.cx > SourceX && SourceSurf->sizlBitmap.cy > SourceY)
{ {
*((USHORT*)DestBits) = (USHORT)XLATEOBJ_iXlate(ColorTranslation, Source = DIB_GetSourceIndex(SourceSurf, SourceX, SourceY);
if(Source != iTransColor)
{
*((USHORT*)DestBits) = (USHORT)XLATEOBJ_iXlate(ColorTranslation,
Source); Source);
}
} }
DestBits = (PULONG)((ULONG_PTR)DestBits + 2); DestBits = (PULONG)((ULONG_PTR)DestBits + 2);
} }
SourceY++;
DestBits = (ULONG*)((ULONG_PTR)DestBits + wd); DestBits = (ULONG*)((ULONG_PTR)DestBits + wd);
} }

View file

@ -481,7 +481,7 @@ return TRUE;
BOOLEAN BOOLEAN
DIB_1BPP_TransparentBlt(SURFOBJ *DestSurf, SURFOBJ *SourceSurf, DIB_1BPP_TransparentBlt(SURFOBJ *DestSurf, SURFOBJ *SourceSurf,
RECTL* DestRect, POINTL *SourcePoint, RECTL* DestRect, RECTL *SourceRect,
XLATEOBJ *ColorTranslation, ULONG iTransColor) XLATEOBJ *ColorTranslation, ULONG iTransColor)
{ {
return FALSE; return FALSE;

View file

@ -406,13 +406,22 @@ DIB_24BPP_ColorFill(SURFOBJ* DestSurface, RECTL* DestRect, ULONG color)
BOOLEAN BOOLEAN
DIB_24BPP_TransparentBlt(SURFOBJ *DestSurf, SURFOBJ *SourceSurf, DIB_24BPP_TransparentBlt(SURFOBJ *DestSurf, SURFOBJ *SourceSurf,
RECTL* DestRect, POINTL *SourcePoint, RECTL* DestRect, RECTL *SourceRect,
XLATEOBJ *ColorTranslation, ULONG iTransColor) XLATEOBJ *ColorTranslation, ULONG iTransColor)
{ {
ULONG X, Y, SourceX, SourceY, Source, wd, Dest; ULONG X, Y, SourceX, SourceY = 0, Source = 0, wd, Dest;
BYTE *DestBits; BYTE *DestBits;
SourceY = SourcePoint->y; LONG DstHeight;
LONG DstWidth;
LONG SrcHeight;
LONG SrcWidth;
DstHeight = DestRect->bottom - DestRect->top;
DstWidth = DestRect->right - DestRect->left;
SrcHeight = SourceRect->bottom - SourceRect->top;
SrcWidth = SourceRect->right - SourceRect->left;
DestBits = (BYTE*)((PBYTE)DestSurf->pvScan0 + DestBits = (BYTE*)((PBYTE)DestSurf->pvScan0 +
(DestRect->left * 3) + (DestRect->left * 3) +
DestRect->top * DestSurf->lDelta); DestRect->top * DestSurf->lDelta);
@ -420,19 +429,23 @@ DIB_24BPP_TransparentBlt(SURFOBJ *DestSurf, SURFOBJ *SourceSurf,
for(Y = DestRect->top; Y < DestRect->bottom; Y++) for(Y = DestRect->top; Y < DestRect->bottom; Y++)
{ {
SourceX = SourcePoint->x; SourceY = SourceRect->top+(Y - DestRect->top) * SrcHeight / DstHeight;
for(X = DestRect->left; X < DestRect->right; X++, DestBits += 3, SourceX++) for(X = DestRect->left; X < DestRect->right; X++, DestBits += 3)
{ {
Source = DIB_GetSourceIndex(SourceSurf, SourceX, SourceY); SourceX = SourceRect->left+(X - DestRect->left) * SrcWidth / DstWidth;
if(Source != iTransColor) if (SourceX >= 0 && SourceY >= 0 &&
SourceSurf->sizlBitmap.cx > SourceX && SourceSurf->sizlBitmap.cy > SourceY)
{ {
Dest = XLATEOBJ_iXlate(ColorTranslation, Source) & 0xFFFFFF; Source = DIB_GetSourceIndex(SourceSurf, SourceX, SourceY);
*(PUSHORT)(DestBits) = Dest & 0xFFFF; if(Source != iTransColor)
*(DestBits + 2) = Dest >> 16; {
Dest = XLATEOBJ_iXlate(ColorTranslation, Source) & 0xFFFFFF;
*(PUSHORT)(DestBits) = Dest & 0xFFFF;
*(DestBits + 2) = Dest >> 16;
}
} }
} }
SourceY++;
DestBits = (BYTE*)((ULONG_PTR)DestBits + wd); DestBits = (BYTE*)((ULONG_PTR)DestBits + wd);
} }

View file

@ -279,13 +279,22 @@ DIB_32BPP_BitBltSrcCopy(PBLTINFO BltInfo)
BOOLEAN BOOLEAN
DIB_32BPP_TransparentBlt(SURFOBJ *DestSurf, SURFOBJ *SourceSurf, DIB_32BPP_TransparentBlt(SURFOBJ *DestSurf, SURFOBJ *SourceSurf,
RECTL* DestRect, POINTL *SourcePoint, RECTL* DestRect, RECTL *SourceRect,
XLATEOBJ *ColorTranslation, ULONG iTransColor) XLATEOBJ *ColorTranslation, ULONG iTransColor)
{ {
ULONG X, Y, SourceX, SourceY, Source, wd; ULONG X, Y, SourceX, SourceY = 0, Source = 0, wd;
ULONG *DestBits; ULONG *DestBits;
SourceY = SourcePoint->y; LONG DstHeight;
LONG DstWidth;
LONG SrcHeight;
LONG SrcWidth;
DstHeight = DestRect->bottom - DestRect->top;
DstWidth = DestRect->right - DestRect->left;
SrcHeight = SourceRect->bottom - SourceRect->top;
SrcWidth = SourceRect->right - SourceRect->left;
DestBits = (ULONG*)((PBYTE)DestSurf->pvScan0 + DestBits = (ULONG*)((PBYTE)DestSurf->pvScan0 +
(DestRect->left << 2) + (DestRect->left << 2) +
DestRect->top * DestSurf->lDelta); DestRect->top * DestSurf->lDelta);
@ -293,17 +302,21 @@ DIB_32BPP_TransparentBlt(SURFOBJ *DestSurf, SURFOBJ *SourceSurf,
for(Y = DestRect->top; Y < DestRect->bottom; Y++) for(Y = DestRect->top; Y < DestRect->bottom; Y++)
{ {
SourceX = SourcePoint->x; SourceY = SourceRect->top+(Y - DestRect->top) * SrcHeight / DstHeight;
for(X = DestRect->left; X < DestRect->right; X++, DestBits++, SourceX++) for(X = DestRect->left; X < DestRect->right; X++, DestBits++)
{ {
Source = DIB_GetSourceIndex(SourceSurf, SourceX, SourceY); SourceX = SourceRect->left+(X - DestRect->left) * SrcWidth / DstWidth;
if(Source != iTransColor) if (SourceX >= 0 && SourceY >= 0 &&
SourceSurf->sizlBitmap.cx > SourceX && SourceSurf->sizlBitmap.cy > SourceY)
{ {
*DestBits = XLATEOBJ_iXlate(ColorTranslation, Source); Source = DIB_GetSourceIndex(SourceSurf, SourceX, SourceY);
if(Source != iTransColor)
{
*DestBits = XLATEOBJ_iXlate(ColorTranslation, Source);
}
} }
} }
SourceY++;
DestBits = (ULONG*)((ULONG_PTR)DestBits + wd); DestBits = (ULONG*)((ULONG_PTR)DestBits + wd);
} }

View file

@ -377,7 +377,7 @@ return TRUE;
BOOLEAN BOOLEAN
DIB_4BPP_TransparentBlt(SURFOBJ *DestSurf, SURFOBJ *SourceSurf, DIB_4BPP_TransparentBlt(SURFOBJ *DestSurf, SURFOBJ *SourceSurf,
RECTL* DestRect, POINTL *SourcePoint, RECTL* DestRect, RECTL *SourceRect,
XLATEOBJ *ColorTranslation, ULONG iTransColor) XLATEOBJ *ColorTranslation, ULONG iTransColor)
{ {
return FALSE; return FALSE;

View file

@ -268,14 +268,23 @@ DIB_8BPP_ColorFill(SURFOBJ* DestSurface, RECTL* DestRect, ULONG color)
BOOLEAN BOOLEAN
DIB_8BPP_TransparentBlt(SURFOBJ *DestSurf, SURFOBJ *SourceSurf, DIB_8BPP_TransparentBlt(SURFOBJ *DestSurf, SURFOBJ *SourceSurf,
RECTL* DestRect, POINTL *SourcePoint, RECTL* DestRect, RECTL *SourceRect,
XLATEOBJ *ColorTranslation, ULONG iTransColor) XLATEOBJ *ColorTranslation, ULONG iTransColor)
{ {
ULONG RoundedRight, X, Y, SourceX, SourceY, Source, wd, Dest; ULONG RoundedRight, X, Y, SourceX = 0, SourceY = 0, Source, wd, Dest;
ULONG *DestBits; ULONG *DestBits;
LONG DstHeight;
LONG DstWidth;
LONG SrcHeight;
LONG SrcWidth;
DstHeight = DestRect->bottom - DestRect->top;
DstWidth = DestRect->right - DestRect->left;
SrcHeight = SourceRect->bottom - SourceRect->top;
SrcWidth = SourceRect->right - SourceRect->left;
RoundedRight = DestRect->right - ((DestRect->right - DestRect->left) & 0x3); RoundedRight = DestRect->right - ((DestRect->right - DestRect->left) & 0x3);
SourceY = SourcePoint->y;
DestBits = (ULONG*)((PBYTE)DestSurf->pvScan0 + DestRect->left + DestBits = (ULONG*)((PBYTE)DestSurf->pvScan0 + DestRect->left +
(DestRect->top * DestSurf->lDelta)); (DestRect->top * DestSurf->lDelta));
wd = DestSurf->lDelta - (DestRect->right - DestRect->left); wd = DestSurf->lDelta - (DestRect->right - DestRect->left);
@ -284,37 +293,57 @@ DIB_8BPP_TransparentBlt(SURFOBJ *DestSurf, SURFOBJ *SourceSurf,
{ {
DestBits = (ULONG*)((PBYTE)DestSurf->pvScan0 + DestRect->left + DestBits = (ULONG*)((PBYTE)DestSurf->pvScan0 + DestRect->left +
(Y * DestSurf->lDelta)); (Y * DestSurf->lDelta));
SourceX = SourcePoint->x; SourceY = SourceRect->top+(Y - DestRect->top) * SrcHeight / DstHeight;
for (X = DestRect->left; X < RoundedRight; X += 4, DestBits++) for (X = DestRect->left; X < RoundedRight; X += 4, DestBits++)
{ {
Dest = *DestBits; Dest = *DestBits;
Source = DIB_GetSourceIndex(SourceSurf, SourceX++, SourceY); SourceX = SourceRect->left+(X - DestRect->left) * SrcWidth / DstWidth;
if(Source != iTransColor) if (SourceX >= 0 && SourceY >= 0 &&
SourceSurf->sizlBitmap.cx > SourceX && SourceSurf->sizlBitmap.cy > SourceY)
{ {
Dest &= 0xFFFFFF00; Source = DIB_GetSourceIndex(SourceSurf, SourceX, SourceY);
Dest |= (XLATEOBJ_iXlate(ColorTranslation, Source) & 0xFF); if(Source != iTransColor)
{
Dest &= 0xFFFFFF00;
Dest |= (XLATEOBJ_iXlate(ColorTranslation, Source) & 0xFF);
}
} }
Source = DIB_GetSourceIndex(SourceSurf, SourceX++, SourceY); SourceX = SourceRect->left+(X+1 - DestRect->left) * SrcWidth / DstWidth;
if(Source != iTransColor) if (SourceX >= 0 && SourceY >= 0 &&
SourceSurf->sizlBitmap.cx > SourceX && SourceSurf->sizlBitmap.cy > SourceY)
{ {
Dest &= 0xFFFF00FF; Source = DIB_GetSourceIndex(SourceSurf, SourceX, SourceY);
Dest |= ((XLATEOBJ_iXlate(ColorTranslation, Source) << 8) & 0xFF00); if(Source != iTransColor)
{
Dest &= 0xFFFF00FF;
Dest |= ((XLATEOBJ_iXlate(ColorTranslation, Source) << 8) & 0xFF00);
}
} }
Source = DIB_GetSourceIndex(SourceSurf, SourceX++, SourceY); SourceX = SourceRect->left+(X+2 - DestRect->left) * SrcWidth / DstWidth;
if(Source != iTransColor) if (SourceX >= 0 && SourceY >= 0 &&
SourceSurf->sizlBitmap.cx > SourceX && SourceSurf->sizlBitmap.cy > SourceY)
{ {
Dest &= 0xFF00FFFF; Source = DIB_GetSourceIndex(SourceSurf, SourceX, SourceY);
Dest |= ((XLATEOBJ_iXlate(ColorTranslation, Source) << 16) & 0xFF0000); if(Source != iTransColor)
{
Dest &= 0xFF00FFFF;
Dest |= ((XLATEOBJ_iXlate(ColorTranslation, Source) << 16) & 0xFF0000);
}
} }
Source = DIB_GetSourceIndex(SourceSurf, SourceX++, SourceY); SourceX = SourceRect->left+(X+3 - DestRect->left) * SrcWidth / DstWidth;
if(Source != iTransColor) if (SourceX >= 0 && SourceY >= 0 &&
SourceSurf->sizlBitmap.cx > SourceX && SourceSurf->sizlBitmap.cy > SourceY)
{ {
Dest &= 0x00FFFFFF; Source = DIB_GetSourceIndex(SourceSurf, SourceX, SourceY);
Dest |= ((XLATEOBJ_iXlate(ColorTranslation, Source) << 24) & 0xFF000000); if(Source != iTransColor)
{
Dest &= 0x00FFFFFF;
Dest |= ((XLATEOBJ_iXlate(ColorTranslation, Source) << 24) & 0xFF000000);
}
} }
*DestBits = Dest; *DestBits = Dest;
@ -324,15 +353,19 @@ DIB_8BPP_TransparentBlt(SURFOBJ *DestSurf, SURFOBJ *SourceSurf,
{ {
for (; X < DestRect->right; X++) for (; X < DestRect->right; X++)
{ {
Source = DIB_GetSourceIndex(SourceSurf, SourceX++, SourceY); SourceX = SourceRect->left+(X - DestRect->left) * SrcWidth / DstWidth;
if(Source != iTransColor) if (SourceX >= 0 && SourceY >= 0 &&
SourceSurf->sizlBitmap.cx > SourceX && SourceSurf->sizlBitmap.cy > SourceY)
{ {
*((BYTE*)DestBits) = (BYTE)(XLATEOBJ_iXlate(ColorTranslation, Source) & 0xFF); Source = DIB_GetSourceIndex(SourceSurf, SourceX, SourceY);
if(Source != iTransColor)
{
*((BYTE*)DestBits) = (BYTE)(XLATEOBJ_iXlate(ColorTranslation, Source) & 0xFF);
}
} }
DestBits = (PULONG)((ULONG_PTR)DestBits + 1); DestBits = (PULONG)((ULONG_PTR)DestBits + 1);
} }
} }
SourceY++;
} }
return TRUE; return TRUE;

View file

@ -47,28 +47,41 @@ EngTransparentBlt(SURFOBJ *psoDest,
INTENG_ENTER_LEAVE EnterLeaveSource, EnterLeaveDest; INTENG_ENTER_LEAVE EnterLeaveSource, EnterLeaveDest;
SURFOBJ *InputObj, *OutputObj; SURFOBJ *InputObj, *OutputObj;
RECTL OutputRect, InputRect; RECTL OutputRect, InputRect;
POINTL Translate, InputPoint; POINTL Translate;
InputRect.left = 0; LONG DstHeight;
InputRect.right = DestRect->right - DestRect->left; LONG DstWidth;
InputRect.top = 0; LONG SrcHeight;
InputRect.bottom = DestRect->bottom - DestRect->top; LONG SrcWidth;
InputRect = *SourceRect;
if(!IntEngEnter(&EnterLeaveSource, psoSource, &InputRect, TRUE, &Translate, &InputObj)) if(!IntEngEnter(&EnterLeaveSource, psoSource, &InputRect, TRUE, &Translate, &InputObj))
{ {
return FALSE; return FALSE;
} }
InputRect.left += Translate.x;
InputPoint.x = SourceRect->left + Translate.x; InputRect.right += Translate.x;
InputPoint.y = SourceRect->top + Translate.y; InputRect.top += Translate.y;
InputRect.bottom += Translate.y;
OutputRect = *DestRect; OutputRect = *DestRect;
if (OutputRect.right < OutputRect.left)
{
OutputRect.left = DestRect->right;
OutputRect.right = DestRect->left;
}
if (OutputRect.bottom < OutputRect.top)
{
OutputRect.top = DestRect->bottom;
OutputRect.bottom = DestRect->top;
}
if(Clip) if(Clip)
{ {
if(OutputRect.left < Clip->rclBounds.left) if(OutputRect.left < Clip->rclBounds.left)
{ {
InputRect.left += Clip->rclBounds.left - OutputRect.left; InputRect.left += Clip->rclBounds.left - OutputRect.left;
InputPoint.x += Clip->rclBounds.left - OutputRect.left;
OutputRect.left = Clip->rclBounds.left; OutputRect.left = Clip->rclBounds.left;
} }
if(Clip->rclBounds.right < OutputRect.right) if(Clip->rclBounds.right < OutputRect.right)
@ -79,7 +92,6 @@ EngTransparentBlt(SURFOBJ *psoDest,
if(OutputRect.top < Clip->rclBounds.top) if(OutputRect.top < Clip->rclBounds.top)
{ {
InputRect.top += Clip->rclBounds.top - OutputRect.top; InputRect.top += Clip->rclBounds.top - OutputRect.top;
InputPoint.y += Clip->rclBounds.top - OutputRect.top;
OutputRect.top = Clip->rclBounds.top; OutputRect.top = Clip->rclBounds.top;
} }
if(Clip->rclBounds.bottom < OutputRect.bottom) if(Clip->rclBounds.bottom < OutputRect.bottom)
@ -110,28 +122,36 @@ EngTransparentBlt(SURFOBJ *psoDest,
ClippingType = (Clip ? Clip->iDComplexity : DC_TRIVIAL); ClippingType = (Clip ? Clip->iDComplexity : DC_TRIVIAL);
DstHeight = OutputRect.bottom - OutputRect.top;
DstWidth = OutputRect.right - OutputRect.left;
SrcHeight = InputRect.bottom - InputRect.top;
SrcWidth = InputRect.right - InputRect.left;
switch(ClippingType) switch(ClippingType)
{ {
case DC_TRIVIAL: case DC_TRIVIAL:
{ {
Ret = DibFunctionsForBitmapFormat[psoDest->iBitmapFormat].DIB_TransparentBlt( Ret = DibFunctionsForBitmapFormat[psoDest->iBitmapFormat].DIB_TransparentBlt(
OutputObj, InputObj, &OutputRect, &InputPoint, ColorTranslation, iTransColor); OutputObj, InputObj, &OutputRect, &InputRect, ColorTranslation, iTransColor);
break; break;
} }
case DC_RECT: case DC_RECT:
{ {
RECTL ClipRect, CombinedRect; RECTL ClipRect, CombinedRect;
POINTL Pt; RECTL InputToCombinedRect;
ClipRect.left = Clip->rclBounds.left + Translate.x; ClipRect.left = Clip->rclBounds.left + Translate.x;
ClipRect.right = Clip->rclBounds.right + Translate.x; ClipRect.right = Clip->rclBounds.right + Translate.x;
ClipRect.top = Clip->rclBounds.top + Translate.y; ClipRect.top = Clip->rclBounds.top + Translate.y;
ClipRect.bottom = Clip->rclBounds.bottom + Translate.y; ClipRect.bottom = Clip->rclBounds.bottom + Translate.y;
EngIntersectRect(&CombinedRect, &OutputRect, &ClipRect); if (EngIntersectRect(&CombinedRect, &OutputRect, &ClipRect))
Pt.x = InputPoint.x + CombinedRect.left - OutputRect.left; {
Pt.y = InputPoint.y + CombinedRect.top - OutputRect.top; InputToCombinedRect.top = InputRect.top + (CombinedRect.top - OutputRect.top) * SrcHeight / DstHeight;
Ret = DibFunctionsForBitmapFormat[psoDest->iBitmapFormat].DIB_TransparentBlt( InputToCombinedRect.bottom = InputRect.top + (CombinedRect.bottom - OutputRect.top) * SrcHeight / DstHeight;
OutputObj, InputObj, &CombinedRect, &Pt, ColorTranslation, iTransColor); InputToCombinedRect.left = InputRect.left + (CombinedRect.left - OutputRect.left) * SrcWidth / DstWidth;
InputToCombinedRect.right = InputRect.left + (CombinedRect.right - OutputRect.left) * SrcWidth / DstWidth;
Ret = DibFunctionsForBitmapFormat[psoDest->iBitmapFormat].DIB_TransparentBlt(
OutputObj, InputObj, &CombinedRect, &InputToCombinedRect, ColorTranslation, iTransColor);
}
break; break;
} }
case DC_COMPLEX: case DC_COMPLEX:
@ -139,17 +159,16 @@ EngTransparentBlt(SURFOBJ *psoDest,
ULONG Direction, i; ULONG Direction, i;
RECT_ENUM RectEnum; RECT_ENUM RectEnum;
BOOL EnumMore; BOOL EnumMore;
POINTL Pt;
if(OutputObj == InputObj) if(OutputObj == InputObj)
{ {
if(OutputRect.top < InputPoint.y) if(OutputRect.top < InputRect.top)
{ {
Direction = OutputRect.left < (InputPoint.x ? CD_RIGHTDOWN : CD_LEFTDOWN); Direction = OutputRect.left < (InputRect.left ? CD_RIGHTDOWN : CD_LEFTDOWN);
} }
else else
{ {
Direction = OutputRect.left < (InputPoint.x ? CD_RIGHTUP : CD_LEFTUP); Direction = OutputRect.left < (InputRect.left ? CD_RIGHTUP : CD_LEFTUP);
} }
} }
else else
@ -164,19 +183,25 @@ EngTransparentBlt(SURFOBJ *psoDest,
for (i = 0; i < RectEnum.c; i++) for (i = 0; i < RectEnum.c; i++)
{ {
RECTL ClipRect, CombinedRect; RECTL ClipRect, CombinedRect;
RECTL InputToCombinedRect;
ClipRect.left = RectEnum.arcl[i].left + Translate.x; ClipRect.left = RectEnum.arcl[i].left + Translate.x;
ClipRect.right = RectEnum.arcl[i].right + Translate.x; ClipRect.right = RectEnum.arcl[i].right + Translate.x;
ClipRect.top = RectEnum.arcl[i].top + Translate.y; ClipRect.top = RectEnum.arcl[i].top + Translate.y;
ClipRect.bottom = RectEnum.arcl[i].bottom + Translate.y; ClipRect.bottom = RectEnum.arcl[i].bottom + Translate.y;
EngIntersectRect(&CombinedRect, &OutputRect, &ClipRect); if (EngIntersectRect(&CombinedRect, &OutputRect, &ClipRect))
Pt.x = InputPoint.x + CombinedRect.left - OutputRect.left;
Pt.y = InputPoint.y + CombinedRect.top - OutputRect.top;
Ret = DibFunctionsForBitmapFormat[psoDest->iBitmapFormat].DIB_TransparentBlt(
OutputObj, InputObj, &CombinedRect, &Pt, ColorTranslation, iTransColor);
if(!Ret)
{ {
break; InputToCombinedRect.top = InputRect.top + (CombinedRect.top - OutputRect.top) * SrcHeight / DstHeight;
InputToCombinedRect.bottom = InputRect.top + (CombinedRect.bottom - OutputRect.top) * SrcHeight / DstHeight;
InputToCombinedRect.left = InputRect.left + (CombinedRect.left - OutputRect.left) * SrcWidth / DstWidth;
InputToCombinedRect.right = InputRect.left + (CombinedRect.right - OutputRect.left) * SrcWidth / DstWidth;
Ret = DibFunctionsForBitmapFormat[psoDest->iBitmapFormat].DIB_TransparentBlt(
OutputObj, InputObj, &CombinedRect, &InputToCombinedRect, ColorTranslation, iTransColor);
if(!Ret)
{
break;
}
} }
} }
} while(EnumMore && Ret); } while(EnumMore && Ret);
@ -209,6 +234,8 @@ IntEngTransparentBlt(SURFOBJ *psoDest,
RECTL OutputRect, InputClippedRect; RECTL OutputRect, InputClippedRect;
SURFACE *psurfDest; SURFACE *psurfDest;
SURFACE *psurfSource; SURFACE *psurfSource;
RECTL InputRect;
LONG InputClWidth, InputClHeight, InputWidth, InputHeight;
ASSERT(psoDest); ASSERT(psoDest);
ASSERT(psoSource); ASSERT(psoSource);
@ -232,6 +259,7 @@ IntEngTransparentBlt(SURFOBJ *psoDest,
InputClippedRect.bottom = DestRect->top; InputClippedRect.bottom = DestRect->top;
} }
InputRect = *SourceRect;
/* Clip against the bounds of the clipping region so we won't try to write /* Clip against the bounds of the clipping region so we won't try to write
* outside the surface */ * outside the surface */
if(Clip) if(Clip)
@ -240,21 +268,27 @@ IntEngTransparentBlt(SURFOBJ *psoDest,
{ {
return TRUE; return TRUE;
} }
SourceRect->left += OutputRect.left - DestRect->left; /* Update source rect */
SourceRect->top += OutputRect.top - DestRect->top; InputClWidth = InputClippedRect.right - InputClippedRect.left;
SourceRect->right += OutputRect.left - DestRect->left; InputClHeight = InputClippedRect.bottom - InputClippedRect.top;
SourceRect->bottom += OutputRect.top - DestRect->top; InputWidth = InputRect.right - InputRect.left;
InputHeight = InputRect.bottom - InputRect.top;
InputRect.left += (InputWidth * (OutputRect.left - InputClippedRect.left)) / InputClWidth;
InputRect.right -= (InputWidth * (InputClippedRect.right - OutputRect.right)) / InputClWidth;
InputRect.top += (InputHeight * (OutputRect.top - InputClippedRect.top)) / InputClHeight;
InputRect.bottom -= (InputHeight * (InputClippedRect.bottom - OutputRect.bottom)) / InputClHeight;
} }
else else
{ {
OutputRect = *DestRect; OutputRect = InputClippedRect;
} }
if(psoSource != psoDest) if(psoSource != psoDest)
{ {
SURFACE_LockBitmapBits(psurfSource); SURFACE_LockBitmapBits(psurfSource);
MouseSafetyOnDrawStart(psoSource, SourceRect->left, SourceRect->top, MouseSafetyOnDrawStart(psoSource, InputRect.left, InputRect.top,
SourceRect->right, SourceRect->bottom); InputRect.right, InputRect.bottom);
} }
SURFACE_LockBitmapBits(psurfDest); SURFACE_LockBitmapBits(psurfDest);
MouseSafetyOnDrawStart(psoDest, OutputRect.left, OutputRect.top, MouseSafetyOnDrawStart(psoDest, OutputRect.left, OutputRect.top,
@ -264,7 +298,7 @@ IntEngTransparentBlt(SURFOBJ *psoDest,
{ {
Ret = GDIDEVFUNCS(psoDest).TransparentBlt( Ret = GDIDEVFUNCS(psoDest).TransparentBlt(
psoDest, psoSource, Clip, ColorTranslation, &OutputRect, psoDest, psoSource, Clip, ColorTranslation, &OutputRect,
SourceRect, iTransColor, Reserved); &InputRect, iTransColor, Reserved);
} }
else else
Ret = FALSE; Ret = FALSE;
@ -272,7 +306,7 @@ IntEngTransparentBlt(SURFOBJ *psoDest,
if(!Ret) if(!Ret)
{ {
Ret = EngTransparentBlt(psoDest, psoSource, Clip, ColorTranslation, Ret = EngTransparentBlt(psoDest, psoSource, Clip, ColorTranslation,
&OutputRect, SourceRect, iTransColor, Reserved); &OutputRect, &InputRect, iTransColor, Reserved);
} }
MouseSafetyOnDrawEnd(psoDest); MouseSafetyOnDrawEnd(psoDest);

View file

@ -456,12 +456,6 @@ NtGdiTransparentBlt(
rcSrc.bottom = rcSrc.top + cySrc; rcSrc.bottom = rcSrc.top + cySrc;
IntLPtoDP(DCSrc, (LPPOINT)&rcSrc, 2); IntLPtoDP(DCSrc, (LPPOINT)&rcSrc, 2);
if((cxDst != cxSrc) || (cyDst != cySrc))
{
DPRINT1("TransparentBlt() does not support stretching at the moment!\n");
goto done;
}
Ret = IntEngTransparentBlt(&BitmapDest->SurfObj, &BitmapSrc->SurfObj, Ret = IntEngTransparentBlt(&BitmapDest->SurfObj, &BitmapSrc->SurfObj,
DCDest->rosdc.CombinedClip, XlateObj, &rcDest, &rcSrc, DCDest->rosdc.CombinedClip, XlateObj, &rcDest, &rcSrc,
TransparentColor, 0); TransparentColor, 0);