- Evgeny Boltik, <BSTSoft AT narod DOT ru>: Add stretching support to TransparentBlt
authorGregor Schneider <grschneider@gmail.com>
Sun, 5 Apr 2009 23:13:09 +0000 (23:13 +0000)
committerGregor Schneider <grschneider@gmail.com>
Sun, 5 Apr 2009 23:13:09 +0000 (23:13 +0000)
- 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

reactos/subsystems/win32/win32k/dib/dib.c
reactos/subsystems/win32/win32k/dib/dib.h
reactos/subsystems/win32/win32k/dib/dib16bpp.c
reactos/subsystems/win32/win32k/dib/dib1bpp.c
reactos/subsystems/win32/win32k/dib/dib24bpp.c
reactos/subsystems/win32/win32k/dib/dib32bpp.c
reactos/subsystems/win32/win32k/dib/dib4bpp.c
reactos/subsystems/win32/win32k/dib/dib8bpp.c
reactos/subsystems/win32/win32k/eng/transblt.c
reactos/subsystems/win32/win32k/objects/bitblt.c

index eaa9566..c6189da 100644 (file)
@@ -235,7 +235,7 @@ BOOLEAN Dummy_StretchBlt(SURFOBJ *DestSurf, SURFOBJ *SourceSurf,
 }
 
 BOOLEAN Dummy_TransparentBlt(SURFOBJ *DestSurf, SURFOBJ *SourceSurf,
-                             RECTL*  DestRect,  POINTL  *SourcePoint,
+                             RECTL*  DestRect,  RECTL  *SourceRect,
                              XLATEOBJ *ColorTranslation, ULONG iTransColor)
 {
   return FALSE;
index 5c2549e..5a7b36e 100644 (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 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_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_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);
 BOOLEAN Dummy_BitBlt(PBLTINFO);
 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_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);
 BOOLEAN DIB_1BPP_BitBlt(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_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);
 BOOLEAN DIB_4BPP_BitBlt(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_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);
 BOOLEAN DIB_8BPP_BitBlt(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_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);
 BOOLEAN DIB_16BPP_BitBlt(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_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);
 BOOLEAN DIB_24BPP_BitBlt(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_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);
 BOOLEAN DIB_32BPP_BitBlt(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_AlphaBlend(SURFOBJ*, SURFOBJ*, RECTL*, RECTL*, CLIPOBJ*, XLATEOBJ*, BLENDOBJ*);
 
index 61f0506..8b1bad0 100644 (file)
@@ -455,14 +455,23 @@ DIB_16BPP_ColorFill(SURFOBJ* DestSurface, RECTL* DestRect, ULONG color)
 
 BOOLEAN
 DIB_16BPP_TransparentBlt(SURFOBJ *DestSurf, SURFOBJ *SourceSurf,
-                         RECTL*  DestRect,  POINTL  *SourcePoint,
+                         RECTL*  DestRect,  RECTL *SourceRect,
                          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;
 
+    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);
-    SourceY = SourcePoint->y;
     DestBits = (ULONG*)((PBYTE)DestSurf->pvScan0 +
                       (DestRect->left << 1) +
                       DestRect->top * DestSurf->lDelta);
@@ -470,23 +479,33 @@ DIB_16BPP_TransparentBlt(SURFOBJ *DestSurf, SURFOBJ *SourceSurf,
 
     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)
         {
             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;
-                Dest |= (XLATEOBJ_iXlate(ColorTranslation, Source) & 0xFFFF);
+                Source = DIB_GetSourceIndex(SourceSurf, SourceX, SourceY);
+                if(Source != iTransColor)
+                {
+                    Dest &= 0xFFFF0000;
+                    Dest |= (XLATEOBJ_iXlate(ColorTranslation, Source) & 0xFFFF);
+                }
             }
 
-            Source = DIB_GetSourceIndex(SourceSurf, SourceX + 1, SourceY);
-            if(Source != iTransColor)
+            SourceX = SourceRect->left+(X+1 - DestRect->left) * SrcWidth / DstWidth;
+            if (SourceX >= 0 && SourceY >= 0 &&
+                SourceSurf->sizlBitmap.cx > SourceX && SourceSurf->sizlBitmap.cy > SourceY)
             {
-                Dest &= 0xFFFF;
-                Dest |= (XLATEOBJ_iXlate(ColorTranslation, Source) << 16);
+                Source = DIB_GetSourceIndex(SourceSurf, SourceX, SourceY);
+                if(Source != iTransColor)
+                {
+                    Dest &= 0xFFFF;
+                    Dest |= (XLATEOBJ_iXlate(ColorTranslation, Source) << 16);
+                }
             }
 
             *DestBits = Dest;
@@ -494,17 +513,21 @@ DIB_16BPP_TransparentBlt(SURFOBJ *DestSurf, SURFOBJ *SourceSurf,
 
             if(X < DestRect->right)
             {
-                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)
                 {
-                    *((USHORT*)DestBits) = (USHORT)XLATEOBJ_iXlate(ColorTranslation,
+                    Source = DIB_GetSourceIndex(SourceSurf, SourceX, SourceY);
+                    if(Source != iTransColor)
+                    {
+                        *((USHORT*)DestBits) = (USHORT)XLATEOBJ_iXlate(ColorTranslation,
                                                                    Source);
+                    }
                 }
 
                 DestBits = (PULONG)((ULONG_PTR)DestBits + 2);
             }
 
-            SourceY++;
             DestBits = (ULONG*)((ULONG_PTR)DestBits + wd);
         }
 
index fcdd919..50a4a7d 100644 (file)
@@ -481,7 +481,7 @@ return TRUE;
 
 BOOLEAN
 DIB_1BPP_TransparentBlt(SURFOBJ *DestSurf, SURFOBJ *SourceSurf,
-                        RECTL*  DestRect,  POINTL  *SourcePoint,
+                        RECTL*  DestRect,  RECTL *SourceRect,
                         XLATEOBJ *ColorTranslation, ULONG iTransColor)
 {
   return FALSE;
index a574004..308e0da 100644 (file)
@@ -406,13 +406,22 @@ DIB_24BPP_ColorFill(SURFOBJ* DestSurface, RECTL* DestRect, ULONG color)
 
 BOOLEAN
 DIB_24BPP_TransparentBlt(SURFOBJ *DestSurf, SURFOBJ *SourceSurf,
-                         RECTL*  DestRect,  POINTL  *SourcePoint,
+                         RECTL*  DestRect,  RECTL *SourceRect,
                          XLATEOBJ *ColorTranslation, ULONG iTransColor)
 {
-  ULONG X, Y, SourceX, SourceY, Source, wd, Dest;
+  ULONG X, Y, SourceX, SourceY = 0, Source = 0, wd, Dest;
   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 +
                       (DestRect->left * 3) +
                       DestRect->top * DestSurf->lDelta);
@@ -420,19 +429,23 @@ DIB_24BPP_TransparentBlt(SURFOBJ *DestSurf, SURFOBJ *SourceSurf,
 
   for(Y = DestRect->top; Y < DestRect->bottom; Y++)
   {
-    SourceX = SourcePoint->x;
-    for(X = DestRect->left; X < DestRect->right; X++, DestBits += 3, SourceX++)
+    SourceY = SourceRect->top+(Y - DestRect->top) * SrcHeight / DstHeight;
+    for(X = DestRect->left; X < DestRect->right; X++, DestBits += 3)
     {
-      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 = XLATEOBJ_iXlate(ColorTranslation, Source) & 0xFFFFFF;
-         *(PUSHORT)(DestBits) = Dest & 0xFFFF;
-         *(DestBits + 2) = Dest >> 16;
+        Source = DIB_GetSourceIndex(SourceSurf, SourceX, SourceY);
+        if(Source != iTransColor)
+        {
+          Dest = XLATEOBJ_iXlate(ColorTranslation, Source) & 0xFFFFFF;
+           *(PUSHORT)(DestBits) = Dest & 0xFFFF;
+           *(DestBits + 2) = Dest >> 16;
+        }
       }
     }
 
-    SourceY++;
     DestBits = (BYTE*)((ULONG_PTR)DestBits + wd);
   }
 
index dc88c29..b18248d 100644 (file)
@@ -279,13 +279,22 @@ DIB_32BPP_BitBltSrcCopy(PBLTINFO BltInfo)
 
 BOOLEAN
 DIB_32BPP_TransparentBlt(SURFOBJ *DestSurf, SURFOBJ *SourceSurf,
-                         RECTL*  DestRect,  POINTL  *SourcePoint,
+                         RECTL*  DestRect,  RECTL *SourceRect,
                          XLATEOBJ *ColorTranslation, ULONG iTransColor)
 {
-  ULONG X, Y, SourceX, SourceY, Source, wd;
+  ULONG X, Y, SourceX, SourceY = 0, Source = 0, wd;
   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 +
                       (DestRect->left << 2) +
                       DestRect->top * DestSurf->lDelta);
@@ -293,17 +302,21 @@ DIB_32BPP_TransparentBlt(SURFOBJ *DestSurf, SURFOBJ *SourceSurf,
 
   for(Y = DestRect->top; Y < DestRect->bottom; Y++)
   {
-    SourceX = SourcePoint->x;
-    for(X = DestRect->left; X < DestRect->right; X++, DestBits++, SourceX++)
+    SourceY = SourceRect->top+(Y - DestRect->top) * SrcHeight / DstHeight;
+    for(X = DestRect->left; X < DestRect->right; X++, 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)
       {
-        *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);
   }
 
index 420648f..cfd0f7f 100644 (file)
@@ -377,7 +377,7 @@ return TRUE;
 
 BOOLEAN
 DIB_4BPP_TransparentBlt(SURFOBJ *DestSurf, SURFOBJ *SourceSurf,
-                        RECTL*  DestRect,  POINTL  *SourcePoint,
+                        RECTL*  DestRect,  RECTL *SourceRect,
                         XLATEOBJ *ColorTranslation, ULONG iTransColor)
 {
   return FALSE;
index 4ebe15c..d8c277c 100644 (file)
@@ -268,14 +268,23 @@ DIB_8BPP_ColorFill(SURFOBJ* DestSurface, RECTL* DestRect, ULONG color)
 
 BOOLEAN
 DIB_8BPP_TransparentBlt(SURFOBJ *DestSurf, SURFOBJ *SourceSurf,
-                        RECTL*  DestRect,  POINTL  *SourcePoint,
+                        RECTL*  DestRect,  RECTL *SourceRect,
                         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;
 
+  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);
-  SourceY = SourcePoint->y;
   DestBits = (ULONG*)((PBYTE)DestSurf->pvScan0 + DestRect->left +
                       (DestRect->top * DestSurf->lDelta));
   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 +
                         (Y * DestSurf->lDelta));
-    SourceX = SourcePoint->x;
+    SourceY = SourceRect->top+(Y - DestRect->top) * SrcHeight / DstHeight;
     for (X = DestRect->left; X < RoundedRight; X += 4, 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 &= 0xFFFFFF00;
-        Dest |= (XLATEOBJ_iXlate(ColorTranslation, Source) & 0xFF);
+        Source = DIB_GetSourceIndex(SourceSurf, SourceX, SourceY);
+        if(Source != iTransColor)
+        {
+          Dest &= 0xFFFFFF00;
+          Dest |= (XLATEOBJ_iXlate(ColorTranslation, Source) & 0xFF);
+        }
       }
 
-      Source = DIB_GetSourceIndex(SourceSurf, SourceX++, SourceY);
-      if(Source != iTransColor)
+      SourceX = SourceRect->left+(X+1 - DestRect->left) * SrcWidth / DstWidth;
+      if (SourceX >= 0 && SourceY >= 0 &&
+          SourceSurf->sizlBitmap.cx > SourceX && SourceSurf->sizlBitmap.cy > SourceY)
       {
-        Dest &= 0xFFFF00FF;
-        Dest |= ((XLATEOBJ_iXlate(ColorTranslation, Source) << 8) & 0xFF00);
+        Source = DIB_GetSourceIndex(SourceSurf, SourceX, SourceY);
+        if(Source != iTransColor)
+        {
+          Dest &= 0xFFFF00FF;
+          Dest |= ((XLATEOBJ_iXlate(ColorTranslation, Source) << 8) & 0xFF00);
+        }
       }
 
-      Source = DIB_GetSourceIndex(SourceSurf, SourceX++, SourceY);
-      if(Source != iTransColor)
+      SourceX = SourceRect->left+(X+2 - DestRect->left) * SrcWidth / DstWidth;
+      if (SourceX >= 0 && SourceY >= 0 &&
+          SourceSurf->sizlBitmap.cx > SourceX && SourceSurf->sizlBitmap.cy > SourceY)
       {
-        Dest &= 0xFF00FFFF;
-        Dest |= ((XLATEOBJ_iXlate(ColorTranslation, Source) << 16) & 0xFF0000);
+        Source = DIB_GetSourceIndex(SourceSurf, SourceX, SourceY);
+        if(Source != iTransColor)
+        {
+          Dest &= 0xFF00FFFF;
+          Dest |= ((XLATEOBJ_iXlate(ColorTranslation, Source) << 16) & 0xFF0000);
+        }
       }
 
-      Source = DIB_GetSourceIndex(SourceSurf, SourceX++, SourceY);
-      if(Source != iTransColor)
+      SourceX = SourceRect->left+(X+3 - DestRect->left) * SrcWidth / DstWidth;
+      if (SourceX >= 0 && SourceY >= 0 &&
+          SourceSurf->sizlBitmap.cx > SourceX && SourceSurf->sizlBitmap.cy > SourceY)
       {
-        Dest &= 0x00FFFFFF;
-        Dest |= ((XLATEOBJ_iXlate(ColorTranslation, Source) << 24) & 0xFF000000);
+        Source = DIB_GetSourceIndex(SourceSurf, SourceX, SourceY);
+        if(Source != iTransColor)
+        {
+          Dest &= 0x00FFFFFF;
+          Dest |= ((XLATEOBJ_iXlate(ColorTranslation, Source) << 24) & 0xFF000000);
+        }
       }
 
       *DestBits = Dest;
@@ -324,15 +353,19 @@ DIB_8BPP_TransparentBlt(SURFOBJ *DestSurf, SURFOBJ *SourceSurf,
     {
       for (; X < DestRect->right; X++)
       {
-        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)
         {
-          *((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);
       }
     }
-    SourceY++;
   }
 
   return TRUE;
index 87b57ec..b00c948 100644 (file)
@@ -47,28 +47,41 @@ EngTransparentBlt(SURFOBJ *psoDest,
   INTENG_ENTER_LEAVE EnterLeaveSource, EnterLeaveDest;
   SURFOBJ *InputObj, *OutputObj;
   RECTL OutputRect, InputRect;
-  POINTL Translate, InputPoint;
+  POINTL Translate;
 
-  InputRect.left = 0;
-  InputRect.right = DestRect->right - DestRect->left;
-  InputRect.top = 0;
-  InputRect.bottom = DestRect->bottom - DestRect->top;
+  LONG DstHeight;
+  LONG DstWidth;
+  LONG SrcHeight;
+  LONG SrcWidth;
+
+  InputRect = *SourceRect;
 
   if(!IntEngEnter(&EnterLeaveSource, psoSource, &InputRect, TRUE, &Translate, &InputObj))
   {
     return FALSE;
   }
-
-  InputPoint.x = SourceRect->left + Translate.x;
-  InputPoint.y = SourceRect->top + Translate.y;
+  InputRect.left += Translate.x;
+  InputRect.right += Translate.x;
+  InputRect.top += Translate.y;
+  InputRect.bottom += Translate.y;
 
   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(OutputRect.left < Clip->rclBounds.left)
     {
       InputRect.left += Clip->rclBounds.left - OutputRect.left;
-      InputPoint.x += Clip->rclBounds.left - OutputRect.left;
       OutputRect.left = Clip->rclBounds.left;
     }
     if(Clip->rclBounds.right < OutputRect.right)
@@ -79,7 +92,6 @@ EngTransparentBlt(SURFOBJ *psoDest,
     if(OutputRect.top < Clip->rclBounds.top)
     {
       InputRect.top += Clip->rclBounds.top - OutputRect.top;
-      InputPoint.y += Clip->rclBounds.top - OutputRect.top;
       OutputRect.top = Clip->rclBounds.top;
     }
     if(Clip->rclBounds.bottom < OutputRect.bottom)
@@ -110,28 +122,36 @@ EngTransparentBlt(SURFOBJ *psoDest,
 
   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)
   {
     case DC_TRIVIAL:
     {
       Ret = DibFunctionsForBitmapFormat[psoDest->iBitmapFormat].DIB_TransparentBlt(
-        OutputObj, InputObj, &OutputRect, &InputPoint, ColorTranslation, iTransColor);
+        OutputObj, InputObj, &OutputRect, &InputRect, ColorTranslation, iTransColor);
       break;
     }
     case DC_RECT:
     {
       RECTL ClipRect, CombinedRect;
-      POINTL Pt;
+      RECTL InputToCombinedRect;
 
       ClipRect.left = Clip->rclBounds.left + Translate.x;
       ClipRect.right = Clip->rclBounds.right + Translate.x;
       ClipRect.top = Clip->rclBounds.top + Translate.y;
       ClipRect.bottom = Clip->rclBounds.bottom + Translate.y;
-      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 (EngIntersectRect(&CombinedRect, &OutputRect, &ClipRect))
+      {
+        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);
+      }
       break;
     }
     case DC_COMPLEX:
@@ -139,17 +159,16 @@ EngTransparentBlt(SURFOBJ *psoDest,
       ULONG Direction, i;
       RECT_ENUM RectEnum;
       BOOL EnumMore;
-      POINTL Pt;
 
       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
         {
-          Direction = OutputRect.left < (InputPoint.x ? CD_RIGHTUP : CD_LEFTUP);
+          Direction = OutputRect.left < (InputRect.left ? CD_RIGHTUP : CD_LEFTUP);
         }
       }
       else
@@ -164,19 +183,25 @@ EngTransparentBlt(SURFOBJ *psoDest,
         for (i = 0; i < RectEnum.c; i++)
         {
           RECTL ClipRect, CombinedRect;
+          RECTL InputToCombinedRect;
 
           ClipRect.left = RectEnum.arcl[i].left + Translate.x;
           ClipRect.right = RectEnum.arcl[i].right + Translate.x;
           ClipRect.top = RectEnum.arcl[i].top + Translate.y;
           ClipRect.bottom = RectEnum.arcl[i].bottom + Translate.y;
-          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)
+          if (EngIntersectRect(&CombinedRect, &OutputRect, &ClipRect))
           {
-            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);
@@ -209,6 +234,8 @@ IntEngTransparentBlt(SURFOBJ *psoDest,
   RECTL OutputRect, InputClippedRect;
   SURFACE *psurfDest;
   SURFACE *psurfSource;
+  RECTL InputRect;
+  LONG InputClWidth, InputClHeight, InputWidth, InputHeight;
 
   ASSERT(psoDest);
   ASSERT(psoSource);
@@ -232,6 +259,7 @@ IntEngTransparentBlt(SURFOBJ *psoDest,
     InputClippedRect.bottom = DestRect->top;
   }
 
+  InputRect = *SourceRect;
   /* Clip against the bounds of the clipping region so we won't try to write
    * outside the surface */
   if(Clip)
@@ -240,21 +268,27 @@ IntEngTransparentBlt(SURFOBJ *psoDest,
     {
       return TRUE;
     }
-    SourceRect->left += OutputRect.left - DestRect->left;
-    SourceRect->top += OutputRect.top - DestRect->top;
-    SourceRect->right += OutputRect.left - DestRect->left;
-    SourceRect->bottom += OutputRect.top - DestRect->top;
+    /* Update source rect */
+    InputClWidth = InputClippedRect.right - InputClippedRect.left;
+    InputClHeight = InputClippedRect.bottom - InputClippedRect.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
   {
-    OutputRect = *DestRect;
+    OutputRect = InputClippedRect;
   }
 
   if(psoSource != psoDest)
   {
     SURFACE_LockBitmapBits(psurfSource);
-    MouseSafetyOnDrawStart(psoSource, SourceRect->left, SourceRect->top,
-                           SourceRect->right, SourceRect->bottom);
+    MouseSafetyOnDrawStart(psoSource, InputRect.left, InputRect.top,
+                           InputRect.right, InputRect.bottom);
   }
   SURFACE_LockBitmapBits(psurfDest);
   MouseSafetyOnDrawStart(psoDest, OutputRect.left, OutputRect.top,
@@ -264,7 +298,7 @@ IntEngTransparentBlt(SURFOBJ *psoDest,
   {
     Ret = GDIDEVFUNCS(psoDest).TransparentBlt(
       psoDest, psoSource, Clip, ColorTranslation, &OutputRect,
-      SourceRect, iTransColor, Reserved);
+      &InputRect, iTransColor, Reserved);
   }
   else
     Ret = FALSE;
@@ -272,7 +306,7 @@ IntEngTransparentBlt(SURFOBJ *psoDest,
   if(!Ret)
   {
     Ret = EngTransparentBlt(psoDest, psoSource, Clip, ColorTranslation,
-                            &OutputRect, SourceRect, iTransColor, Reserved);
+                            &OutputRect, &InputRect, iTransColor, Reserved);
   }
 
   MouseSafetyOnDrawEnd(psoDest);
index 6f10ec2..7cb7300 100644 (file)
@@ -456,12 +456,6 @@ NtGdiTransparentBlt(
     rcSrc.bottom = rcSrc.top + cySrc;
     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,
         DCDest->rosdc.CombinedClip, XlateObj, &rcDest, &rcSrc,
         TransparentColor, 0);