fixed working strechblt for all dibxx now. do not say it does not take offset of...
[reactos.git] / reactos / subsys / win32k / dib / dib24bpp.c
index 52728e8..30493e1 100644 (file)
  *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
 /* $Id$ */
+
 #include <w32k.h>
 
+#define NDEBUG
+#include <debug.h>
+
 VOID
 DIB_24BPP_PutPixel(SURFOBJ *SurfObj, LONG x, LONG y, ULONG c)
 {
-  PBYTE addr = SurfObj->pvScan0 + (y * SurfObj->lDelta) + (x << 1) + x;
+  PBYTE addr = (PBYTE)SurfObj->pvScan0 + (y * SurfObj->lDelta) + (x << 1) + x;
   *(PUSHORT)(addr) = c & 0xFFFF;
   *(addr + 2) = (c >> 16) & 0xFF;
 }
@@ -30,14 +34,14 @@ DIB_24BPP_PutPixel(SURFOBJ *SurfObj, LONG x, LONG y, ULONG c)
 ULONG
 DIB_24BPP_GetPixel(SURFOBJ *SurfObj, LONG x, LONG y)
 {
-  PBYTE addr = SurfObj->pvScan0 + y * SurfObj->lDelta + (x << 1) + x;
+  PBYTE addr = (PBYTE)SurfObj->pvScan0 + y * SurfObj->lDelta + (x << 1) + x;
   return *(PUSHORT)(addr) + (*(addr + 2) << 16);
 }
 
 VOID
 DIB_24BPP_HLine(SURFOBJ *SurfObj, LONG x1, LONG x2, LONG y, ULONG c)
 {
-  PBYTE addr = SurfObj->pvScan0 + y * SurfObj->lDelta + (x1 << 1) + x1;
+  PBYTE addr = (PBYTE)SurfObj->pvScan0 + y * SurfObj->lDelta + (x1 << 1) + x1;
   ULONG Count = x2 - x1;
 #ifndef _M_IX86
   ULONG MultiCount;
@@ -95,13 +99,13 @@ DIB_24BPP_HLine(SURFOBJ *SurfObj, LONG x1, LONG x2, LONG y, ULONG c)
 "      movl %2, %%ecx\n"                /* Load count */
 "      shr  $2, %%ecx\n"
 "      movl %3, %%edi\n"                /* Load dest */
-".L1:\n"
+"0:\n"
 "      movl %%eax, (%%edi)\n"           /* Store 4 pixels, 12 bytes */
 "      movl %%ebx, 4(%%edi)\n"
 "      movl %%edx, 8(%%edi)\n"
 "      addl $12, %%edi\n"
 "      dec  %%ecx\n"
-"      jnz  .L1\n"
+"      jnz  0b\n"
 "      movl %%edi, %0\n"
   : "=m"(addr)
   : "m"(c), "m"(Count), "m"(addr)
@@ -137,7 +141,7 @@ DIB_24BPP_HLine(SURFOBJ *SurfObj, LONG x1, LONG x2, LONG y, ULONG c)
 VOID
 DIB_24BPP_VLine(SURFOBJ *SurfObj, LONG x, LONG y1, LONG y2, ULONG c)
 {
-  PBYTE addr = SurfObj->pvScan0 + y1 * SurfObj->lDelta + (x << 1) + x;
+  PBYTE addr = (PBYTE)SurfObj->pvScan0 + y1 * SurfObj->lDelta + (x << 1) + x;
   LONG lDelta = SurfObj->lDelta;
 
   c &= 0xFFFFFF;
@@ -157,7 +161,7 @@ DIB_24BPP_BitBltSrcCopy(PBLTINFO BltInfo)
   PBYTE    SourceBits_4BPP, SourceLine_4BPP;
   PWORD    SourceBits_16BPP, SourceLine_16BPP;
 
-  DestBits = BltInfo->DestSurface->pvScan0 + (BltInfo->DestRect.top * BltInfo->DestSurface->lDelta) + BltInfo->DestRect.left * 3;
+  DestBits = (PBYTE)BltInfo->DestSurface->pvScan0 + (BltInfo->DestRect.top * BltInfo->DestSurface->lDelta) + BltInfo->DestRect.left * 3;
 
   switch(BltInfo->SourceSurface->iBitmapFormat)
   {
@@ -183,7 +187,7 @@ DIB_24BPP_BitBltSrcCopy(PBLTINFO BltInfo)
       break;
 
     case BMF_4BPP:
-      SourceBits_4BPP = BltInfo->SourceSurface->pvScan0 + (BltInfo->SourcePoint.y * BltInfo->SourceSurface->lDelta) + (BltInfo->SourcePoint.x >> 1);
+      SourceBits_4BPP = (PBYTE)BltInfo->SourceSurface->pvScan0 + (BltInfo->SourcePoint.y * BltInfo->SourceSurface->lDelta) + (BltInfo->SourcePoint.x >> 1);
 
       for (j=BltInfo->DestRect.top; j<BltInfo->DestRect.bottom; j++)
       {
@@ -209,7 +213,7 @@ DIB_24BPP_BitBltSrcCopy(PBLTINFO BltInfo)
       break;
 
     case BMF_8BPP:
-      SourceLine = BltInfo->SourceSurface->pvScan0 + (BltInfo->SourcePoint.y * BltInfo->SourceSurface->lDelta) + BltInfo->SourcePoint.x;
+      SourceLine = (PBYTE)BltInfo->SourceSurface->pvScan0 + (BltInfo->SourcePoint.y * BltInfo->SourceSurface->lDelta) + BltInfo->SourcePoint.x;
       DestLine = DestBits;
 
       for (j = BltInfo->DestRect.top; j < BltInfo->DestRect.bottom; j++)
@@ -232,7 +236,7 @@ DIB_24BPP_BitBltSrcCopy(PBLTINFO BltInfo)
       break;
 
     case BMF_16BPP:
-      SourceBits_16BPP = BltInfo->SourceSurface->pvScan0 + (BltInfo->SourcePoint.y * BltInfo->SourceSurface->lDelta) + 2 * BltInfo->SourcePoint.x;
+      SourceBits_16BPP = (PWORD)((PBYTE)BltInfo->SourceSurface->pvScan0 + (BltInfo->SourcePoint.y * BltInfo->SourceSurface->lDelta) + 2 * BltInfo->SourcePoint.x);
 
       for (j=BltInfo->DestRect.top; j<BltInfo->DestRect.bottom; j++)
       {
@@ -258,7 +262,7 @@ DIB_24BPP_BitBltSrcCopy(PBLTINFO BltInfo)
       {
        if (BltInfo->DestRect.top < BltInfo->SourcePoint.y)
          {
-           SourceBits = BltInfo->SourceSurface->pvScan0 + (BltInfo->SourcePoint.y * BltInfo->SourceSurface->lDelta) + 3 * BltInfo->SourcePoint.x;
+           SourceBits = (PBYTE)BltInfo->SourceSurface->pvScan0 + (BltInfo->SourcePoint.y * BltInfo->SourceSurface->lDelta) + 3 * BltInfo->SourcePoint.x;
            for (j = BltInfo->DestRect.top; j < BltInfo->DestRect.bottom; j++)
              {
                RtlMoveMemory(DestBits, SourceBits, 3 * (BltInfo->DestRect.right - BltInfo->DestRect.left));
@@ -268,8 +272,8 @@ DIB_24BPP_BitBltSrcCopy(PBLTINFO BltInfo)
          }
        else
          {
-           SourceBits = BltInfo->SourceSurface->pvScan0 + ((BltInfo->SourcePoint.y + BltInfo->DestRect.bottom - BltInfo->DestRect.top - 1) * BltInfo->SourceSurface->lDelta) + 3 * BltInfo->SourcePoint.x;
-           DestBits = BltInfo->DestSurface->pvScan0 + ((BltInfo->DestRect.bottom - 1) * BltInfo->DestSurface->lDelta) + 3 * BltInfo->DestRect.left;
+           SourceBits = (PBYTE)BltInfo->SourceSurface->pvScan0 + ((BltInfo->SourcePoint.y + BltInfo->DestRect.bottom - BltInfo->DestRect.top - 1) * BltInfo->SourceSurface->lDelta) + 3 * BltInfo->SourcePoint.x;
+           DestBits = (PBYTE)BltInfo->DestSurface->pvScan0 + ((BltInfo->DestRect.bottom - 1) * BltInfo->DestSurface->lDelta) + 3 * BltInfo->DestRect.left;
            for (j = BltInfo->DestRect.bottom - 1; BltInfo->DestRect.top <= j; j--)
              {
                RtlMoveMemory(DestBits, SourceBits, 3 * (BltInfo->DestRect.right - BltInfo->DestRect.left));
@@ -287,7 +291,7 @@ DIB_24BPP_BitBltSrcCopy(PBLTINFO BltInfo)
       break;
 
     case BMF_32BPP:
-      SourceLine = BltInfo->SourceSurface->pvScan0 + (BltInfo->SourcePoint.y * BltInfo->SourceSurface->lDelta) + 4 * BltInfo->SourcePoint.x;
+      SourceLine = (PBYTE)BltInfo->SourceSurface->pvScan0 + (BltInfo->SourcePoint.y * BltInfo->SourceSurface->lDelta) + 4 * BltInfo->SourcePoint.x;
       DestLine = DestBits;
 
       for (j = BltInfo->DestRect.top; j < BltInfo->DestRect.bottom; j++)
@@ -333,7 +337,7 @@ DIB_24BPP_BitBlt(PBLTINFO BltInfo)
 
    SourceY = BltInfo->SourcePoint.y;
    DestBits = (PBYTE)(
-      BltInfo->DestSurface->pvScan0 +
+      (PBYTE)BltInfo->DestSurface->pvScan0 +
       (BltInfo->DestRect.left << 1) + BltInfo->DestRect.left +
       BltInfo->DestRect.top * BltInfo->DestSurface->lDelta);
 
@@ -392,11 +396,97 @@ DIB_24BPP_ColorFill(SURFOBJ* DestSurface, RECTL* DestRect, ULONG color)
 {
   ULONG DestY; 
 
+#ifdef _M_IX86
+  PBYTE xaddr = (PBYTE)DestSurface->pvScan0 + DestRect->top * DestSurface->lDelta + (DestRect->left << 1) + DestRect->left;
+  PBYTE addr;
+  ULONG Count;
+  ULONG xCount=DestRect->right - DestRect->left;
+
+  for (DestY = DestRect->top; DestY< DestRect->bottom; DestY++)
+  {
+    Count = xCount;
+    addr = xaddr;    
+    xaddr = (PBYTE)((ULONG_PTR)addr + DestSurface->lDelta);
+
+    if (Count < 8)
+    {
+      /* For small fills, don't bother doing anything fancy */
+      while (Count--)
+        {
+          *(PUSHORT)(addr) = color;
+          addr += 2;
+          *(addr) = color >> 16;
+          addr += 1;
+        }
+    }
+  else
+    {
+      /* Align to 4-byte address */
+      while (0 != ((ULONG_PTR) addr & 0x3))
+        {
+          *(PUSHORT)(addr) = color;
+          addr += 2;
+          *(addr) = color >> 16;
+          addr += 1;
+          Count--;
+        }
+      /* If the color we need to fill with is 0ABC, then the final mem pattern
+       * (note little-endianness) would be:
+       *
+       * |C.B.A|C.B.A|C.B.A|C.B.A|   <- pixel borders
+       * |C.B.A.C|B.A.C.B|A.C.B.A|   <- ULONG borders
+       *
+       * So, taking endianness into account again, we need to fill with these
+       * ULONGs: CABC BCAB ABCA */
+
+       /* This is about 30% faster than the generic C code below */
+       __asm__ __volatile__ (
+"      movl %1, %%ecx\n"
+"      andl $0xffffff, %%ecx\n"         /* 0ABC */
+"      movl %%ecx, %%ebx\n"             /* Construct BCAB in ebx */
+"      shrl $8, %%ebx\n"
+"      movl %%ecx, %%eax\n"
+"      shll $16, %%eax\n"
+"      orl  %%eax, %%ebx\n"
+"      movl %%ecx, %%edx\n"             /* Construct ABCA in edx */
+"      shll $8, %%edx\n"
+"      movl %%ecx, %%eax\n"
+"      shrl $16, %%eax\n"
+"      orl  %%eax, %%edx\n"
+"      movl %%ecx, %%eax\n"             /* Construct CABC in eax */
+"      shll $24, %%eax\n"
+"      orl  %%ecx, %%eax\n"
+"      movl %2, %%ecx\n"                /* Load count */
+"      shr  $2, %%ecx\n"
+"      movl %3, %%edi\n"                /* Load dest */
+".FL1:\n"
+"      movl %%eax, (%%edi)\n"           /* Store 4 pixels, 12 bytes */
+"      movl %%ebx, 4(%%edi)\n"
+"      movl %%edx, 8(%%edi)\n"
+"      addl $12, %%edi\n"
+"      dec  %%ecx\n"
+"      jnz  .FL1\n"
+"      movl %%edi, %0\n"
+  : "=m"(addr)
+  : "m"(color), "m"(Count), "m"(addr)
+  : "%eax", "%ebx", "%ecx", "%edx", "%edi");
+   Count = Count & 0x03;
+      while (0 != Count--)
+        {
+          *(PUSHORT)(addr) = color;
+          addr += 2;
+          *(addr) = color >> 16;
+          addr += 1;
+        }
+    }
+  }
+#else
+
   for (DestY = DestRect->top; DestY< DestRect->bottom; DestY++)
     {                                                  
       DIB_24BPP_HLine(DestSurface, DestRect->left, DestRect->right, DestY, color);                                                     
     }
-
+#endif
   return TRUE;
 }
 
@@ -407,796 +497,133 @@ BOOLEAN DIB_24BPP_StretchBlt(SURFOBJ *DestSurf, SURFOBJ *SourceSurf,
                             CLIPOBJ *ClipRegion, XLATEOBJ *ColorTranslation,
                             ULONG Mode)
 {
-   int SrcSizeY;
-   int SrcSizeX;
-   int DesSizeY;
-   int DesSizeX;      
-   int sx;
-   int sy;
-   int DesX;
-   int DesY;
-   int color;
-   int zoomX;
-   int zoomY;
-   int count;
-   int saveX;
-   int saveY;
-   BOOLEAN DesIsBiggerY=FALSE;
-
-   SrcSizeY = SourceRect->bottom;
-   SrcSizeX = SourceRect->right;
+   LONG SrcSizeY;
+   LONG SrcSizeX;
+   LONG DesSizeY;
+   LONG DesSizeX;      
+   LONG sx;
+   LONG sy;
+   LONG DesX;
+   LONG DesY;
+   LONG color;
   
-   DesSizeY = DestRect->bottom;
-   DesSizeX = DestRect->right;
-
-   zoomX = DesSizeX / SrcSizeX;
-   if (zoomX==0) zoomX=1;
-
-   zoomY = DesSizeY / SrcSizeY;
-   if (zoomY==0) zoomY=1;
-
-   if (DesSizeY>SrcSizeY)
-      DesIsBiggerY = TRUE;  
+   SrcSizeY = SourceRect->bottom - SourceRect->top;
+   SrcSizeX = SourceRect->right - SourceRect->left;
+  
+   DesSizeY = DestRect->bottom - DestRect->top;
+   DesSizeX = DestRect->right - DestRect->left;
 
-    switch(SourceSurf->iBitmapFormat)
-    {
-            case BMF_1BPP:             
-                  /* FIXME :  MaskOrigin, BrushOrigin, ClipRegion, Mode ? */
-                  /* This is a reference implementation, it hasn't been optimized for speed */
-           if (zoomX>1)
-                  {
-                    /* Draw one Hline on X - Led to the Des Zoom In*/
-                    if (DesSizeX>SrcSizeX)
-                        {
-                               for (DesY=DestRect->bottom-zoomY; DesY>=0; DesY-=zoomY)
-                               {
-                                       if (DesIsBiggerY)
-                                               sy = (int) ((ULONG) SrcSizeY * (ULONG) DesY) / ((ULONG) DesSizeY);
-                                       else
-                                               sy = (int) ((ULONG) DesSizeY * (ULONG) DesY) / ((ULONG) SrcSizeY); 
-                                               
-                                       if (sy > SourceRect->bottom) break;
-
-                                       saveY = DesY+zoomY;
-
-                                       for (DesX=DestRect->right-zoomX; DesX>=0; DesX-=zoomX)                          
-                                       {                                               
-                                               sx = (int) ((ULONG) SrcSizeX * (ULONG) DesX) / ((ULONG) DesSizeX);
-                                               
-                                               if (sx > SourceRect->right) break;
-                                       
-                                               saveX = DesX + zoomX;
-
-                                               if (DIB_1BPP_GetPixel(SourceSurf, sx, sy) == 0) 
-                                                  for (count=DesY;count<saveY;count++)
-                                                       DIB_24BPP_HLine(DestSurf, DesX, saveX, count, 0);
-                                               else
-                                                       for (count=DesY;count<saveY;count++)
-                                                       DIB_24BPP_HLine(DestSurf, DesX, saveX, count, 1);
-                                                                                                                                                                                               
-                                         }                                                                             
-                                 }
-                           }
-                        else
-                        {
-                          /* Draw one Hline on X - Led to the Des Zoom Out*/
-
-               for (DesY=DestRect->bottom-zoomY; DesY>=0; DesY-=zoomY)
-                               {
-                                       if (DesIsBiggerY)
-                                               sy = (int) ((ULONG) SrcSizeY * (ULONG) DesY) / ((ULONG) DesSizeY);
-                                       else
-                                               sy = (int) ((ULONG) DesSizeY * (ULONG) DesY) / ((ULONG) SrcSizeY); 
-                                               
-                                       if (sy > SourceRect->bottom) break;
-
-                                       saveY = DesY+zoomY;
-
-                                       for (DesX=DestRect->right-zoomX; DesX>=0; DesX-=zoomX)                          
-                                       {
-                                               sx = (int) ((ULONG) DesSizeX * (ULONG) DesX) / ((ULONG) SrcSizeX);                                                                  
-                                       
-                                               if (sx > SourceRect->right) break;
-                                       
-                                               saveX = DesX + zoomX;
-
-                                               if (DIB_1BPP_GetPixel(SourceSurf, sx, sy) == 0) 
-                                                  for (count=DesY;count<saveY;count++)
-                                                       DIB_24BPP_HLine(DestSurf, DesX, saveX, count, 0);
-                                               else
-                                                       for (count=DesY;count<saveY;count++)
-                                                       DIB_24BPP_HLine(DestSurf, DesX, saveX, count, 1);
-                                                                                                                                                                                               
-                                         }                                                                             
-                                 }
-                        }
-                  }                    
-                  else
-                  {
-                   
-                   if (DesSizeX>SrcSizeX)
-                       {
-                               /* Draw one pixel on X - Led to the Des Zoom In*/
-                               for (DesY=DestRect->bottom-zoomY; DesY>=0; DesY-=zoomY)
-                               {
-                                       if (DesIsBiggerY)
-                                               sy = (int) ((ULONG) SrcSizeY * (ULONG) DesY) / ((ULONG) DesSizeY);
-                                       else
-                                               sy = (int) ((ULONG) DesSizeY * (ULONG) DesY) / ((ULONG) SrcSizeY); 
-                                               
-                                       if (sy > SourceRect->bottom) break;
-
-                                       saveY = DesY+zoomY;
-
-                                       for (DesX=DestRect->right-zoomX; DesX>=0; DesX-=zoomX)                          
-                                       {                                               
-                                               sx = (int) ((ULONG) SrcSizeX * (ULONG) DesX) / ((ULONG) DesSizeX);
-                                               
-                                               if (sx > SourceRect->right) break;
-                                       
-                                               if (DIB_1BPP_GetPixel(SourceSurf, sx, sy) == 0) 
-                                                  for (count=DesY;count<saveY;count++)
-                                                       DIB_24BPP_PutPixel(DestSurf, DesX, count, 0);                                                                           
-                                               else
-                                                       for (count=DesY;count<saveY;count++)
-                                                       DIB_24BPP_PutPixel(DestSurf, DesX, count, 1);                                                                           
-                                                           
-                                               
-                                        }
-                         }
-                        }
-                       else
-                       {
-                               /* Draw one pixel on X - Led to the Des Zoom Out*/
-                               for (DesY=DestRect->bottom-zoomY; DesY>=0; DesY-=zoomY)
-                               {
-                                       if (DesIsBiggerY)
-                                               sy = (int) ((ULONG) SrcSizeY * (ULONG) DesY) / ((ULONG) DesSizeY);
-                                       else
-                                               sy = (int) ((ULONG) DesSizeY * (ULONG) DesY) / ((ULONG) SrcSizeY); 
-                                               
-                                       if (sy > SourceRect->bottom) break;
-
-                                       saveY = DesY+zoomY;
-
-                                       for (DesX=DestRect->right-zoomX; DesX>=0; DesX-=zoomX)                          
-                                       {
-                                               sx = (int) ((ULONG) DesSizeX * (ULONG) DesX) / ((ULONG) SrcSizeX);                                                                  
-                                       
-                                               if (sx > SourceRect->right) break;
-                                       
-                                               if (DIB_1BPP_GetPixel(SourceSurf, sx, sy) == 0) 
-                                                  for (count=DesY;count<saveY;count++)
-                                                       DIB_24BPP_PutPixel(DestSurf, DesX, count, 0);                                                                           
-                                               else
-                                                       for (count=DesY;count<saveY;count++)
-                                                       DIB_24BPP_PutPixel(DestSurf, DesX, count, 1);                                                                           
-                                                                                                       
-                                        }
-                         }
-                       }
-                  }
-               break;
+   switch(SourceSurf->iBitmapFormat)
+   {
+      case BMF_1BPP:
+         /* FIXME :  MaskOrigin, BrushOrigin, ClipRegion, Mode ? */
+      /* This is a reference implementation, it hasn't been optimized for speed */
+                      
+       for (DesY=DestRect->top; DesY<DestRect->bottom; DesY++)
+       {                        
+           sy = (((DesY - DestRect->top) * SrcSizeY) / DesSizeY) + SourceRect->top;
+                     
+            for (DesX=DestRect->left; DesX<DestRect->right; DesX++)
+            {                  
+                  sx = (((DesX - DestRect->left) * SrcSizeX) / DesSizeX) + SourceRect->left;
+                               
+                  if(DIB_1BPP_GetPixel(SourceSurf, sx, sy) == 0)
+                                 {
+                                       DIB_24BPP_PutPixel(DestSurf, DesX, DesY, XLATEOBJ_iXlate(ColorTranslation, 0));
+                  } 
+                                 else 
+                                 {
+                    DIB_24BPP_PutPixel(DestSurf, DesX, DesY, XLATEOBJ_iXlate(ColorTranslation, 1));
+                  }
+            }
+       }               
+
+         break;
 
       case BMF_4BPP:           
-                  /* FIXME :  MaskOrigin, BrushOrigin, ClipRegion, Mode ? */
-                  /* This is a reference implementation, it hasn't been optimized for speed */
-           if (zoomX>1)
-                  {
-                    /* Draw one Hline on X - Led to the Des Zoom In*/
-                    if (DesSizeX>SrcSizeX)
-                        {
-                               for (DesY=DestRect->bottom-zoomY; DesY>=0; DesY-=zoomY)
-                               {
-                                       if (DesIsBiggerY)
-                                               sy = (int) ((ULONG) SrcSizeY * (ULONG) DesY) / ((ULONG) DesSizeY);
-                                       else
-                                               sy = (int) ((ULONG) DesSizeY * (ULONG) DesY) / ((ULONG) SrcSizeY); 
-                                               
-                                       if (sy > SourceRect->bottom) break;
-
-                                       saveY = DesY+zoomY;
-
-                                       for (DesX=DestRect->right-zoomX; DesX>=0; DesX-=zoomX)                          
-                                       {                                               
-                                               sx = (int) ((ULONG) SrcSizeX * (ULONG) DesX) / ((ULONG) DesSizeX);
-                                               
-                                               if (sx > SourceRect->right) break;
-                                       
-                                               color =  XLATEOBJ_iXlate(ColorTranslation, DIB_4BPP_GetPixel(SourceSurf, sx, sy));
-                                                                                               
-                                               saveX = DesX + zoomX;
-                                               for (count=DesY;count<saveY;count++)
-                                                       DIB_24BPP_HLine(DestSurf, DesX, saveX, count, color);
-                                         }                                                                             
-                                 }
-                           }
-                        else
-                        {
-                          /* Draw one Hline on X - Led to the Des Zoom Out*/
-
-               for (DesY=DestRect->bottom-zoomY; DesY>=0; DesY-=zoomY)
-                               {
-                                       if (DesIsBiggerY)
-                                               sy = (int) ((ULONG) SrcSizeY * (ULONG) DesY) / ((ULONG) DesSizeY);
-                                       else
-                                               sy = (int) ((ULONG) DesSizeY * (ULONG) DesY) / ((ULONG) SrcSizeY); 
-                                               
-                                       if (sy > SourceRect->bottom) break;
-
-                                       saveY = DesY+zoomY;
-
-                                       for (DesX=DestRect->right-zoomX; DesX>=0; DesX-=zoomX)                          
-                                       {
-                                               sx = (int) ((ULONG) DesSizeX * (ULONG) DesX) / ((ULONG) SrcSizeX);                                                                  
-                                       
-                                               if (sx > SourceRect->right) break;
-                                       
-                                               color =  XLATEOBJ_iXlate(ColorTranslation, DIB_4BPP_GetPixel(SourceSurf, sx, sy));
-                                                                                               
-                                               saveX = DesX + zoomX;
-                                               for (count=DesY;count<saveY;count++)
-                                                       DIB_24BPP_HLine(DestSurf, DesX, saveX, count, color);
-                                         }                                                                             
-                                 }
-                        }
-                  }
-                       
-                  else
-                  {
-                   
-                   if (DesSizeX>SrcSizeX)
-                       {
-                               /* Draw one pixel on X - Led to the Des Zoom In*/
-                               for (DesY=DestRect->bottom-zoomY; DesY>=0; DesY-=zoomY)
-                               {
-                                       if (DesIsBiggerY)
-                                               sy = (int) ((ULONG) SrcSizeY * (ULONG) DesY) / ((ULONG) DesSizeY);
-                                       else
-                                               sy = (int) ((ULONG) DesSizeY * (ULONG) DesY) / ((ULONG) SrcSizeY); 
-                                               
-                                       if (sy > SourceRect->bottom) break;
-
-                                       saveY = DesY+zoomY;
-
-                                       for (DesX=DestRect->right-zoomX; DesX>=0; DesX-=zoomX)                          
-                                       {                                               
-                                               sx = (int) ((ULONG) SrcSizeX * (ULONG) DesX) / ((ULONG) DesSizeX);
-                                               
-                                               if (sx > SourceRect->right) break;
-                                       
-                                               color =  XLATEOBJ_iXlate(ColorTranslation, DIB_4BPP_GetPixel(SourceSurf, sx, sy));
-                                                           
-                                               for (count=DesY;count<saveY;count++)
-                                                       DIB_24BPP_PutPixel(DestSurf, DesX, count, color);                                                                               
-                                        }
-                         }
-                        }
-                       else
-                       {
-                               /* Draw one pixel on X - Led to the Des Zoom Out*/
-                               for (DesY=DestRect->bottom-zoomY; DesY>=0; DesY-=zoomY)
-                               {
-                                       if (DesIsBiggerY)
-                                               sy = (int) ((ULONG) SrcSizeY * (ULONG) DesY) / ((ULONG) DesSizeY);
-                                       else
-                                               sy = (int) ((ULONG) DesSizeY * (ULONG) DesY) / ((ULONG) SrcSizeY); 
-                                               
-                                       if (sy > SourceRect->bottom) break;
-
-                                       saveY = DesY+zoomY;
-
-                                       for (DesX=DestRect->right-zoomX; DesX>=0; DesX-=zoomX)                          
-                                       {
-                                               sx = (int) ((ULONG) DesSizeX * (ULONG) DesX) / ((ULONG) SrcSizeX);                                                                  
-                                       
-                                               if (sx > SourceRect->right) break;
-                                       
-                                               color =  XLATEOBJ_iXlate(ColorTranslation, DIB_4BPP_GetPixel(SourceSurf, sx, sy));
-                                                           
-                                               for (count=DesY;count<saveY;count++)
-                                                       DIB_24BPP_PutPixel(DestSurf, DesX, count, color);                                                                               
-                                        }
-                         }
-                       }
-                  }
-               break;
+      /* FIXME :  MaskOrigin, BrushOrigin, ClipRegion, Mode ? */
+      /* This is a reference implementation, it hasn't been optimized for speed */
+                      
+       for (DesY=DestRect->top; DesY<DestRect->bottom; DesY++)
+       {                        
+           sy = (((DesY - DestRect->top) * SrcSizeY) / DesSizeY) + SourceRect->top;
+                     
+            for (DesX=DestRect->left; DesX<DestRect->right; DesX++)
+            {                  
+                 sx = (((DesX - DestRect->left) * SrcSizeX) / DesSizeX) + SourceRect->left;            
+                 color = DIB_4BPP_GetPixel(SourceSurf, sx, sy);
+                 DIB_24BPP_PutPixel(DestSurf, DesX, DesY, XLATEOBJ_iXlate(ColorTranslation, color));
+            }
+       }                  
+      break;
 
       case BMF_8BPP:           
-                  /* FIXME :  MaskOrigin, BrushOrigin, ClipRegion, Mode ? */
-                  /* This is a reference implementation, it hasn't been optimized for speed */
-           if (zoomX>1)
-                  {
-                    /* Draw one Hline on X - Led to the Des Zoom In*/
-                    if (DesSizeX>SrcSizeX)
-                        {
-                               for (DesY=DestRect->bottom-zoomY; DesY>=0; DesY-=zoomY)
-                               {
-                                       if (DesIsBiggerY)
-                                               sy = (int) ((ULONG) SrcSizeY * (ULONG) DesY) / ((ULONG) DesSizeY);
-                                       else
-                                               sy = (int) ((ULONG) DesSizeY * (ULONG) DesY) / ((ULONG) SrcSizeY); 
-                                               
-                                       if (sy > SourceRect->bottom) break;
-
-                                       saveY = DesY+zoomY;
-
-                                       for (DesX=DestRect->right-zoomX; DesX>=0; DesX-=zoomX)                          
-                                       {                                               
-                                               sx = (int) ((ULONG) SrcSizeX * (ULONG) DesX) / ((ULONG) DesSizeX);
-                                               
-                                               if (sx > SourceRect->right) break;
-                                       
-                                               color =  XLATEOBJ_iXlate(ColorTranslation, DIB_8BPP_GetPixel(SourceSurf, sx, sy));
-                                                                                               
-                                               saveX = DesX + zoomX;
-                                               for (count=DesY;count<saveY;count++)
-                                                       DIB_24BPP_HLine(DestSurf, DesX, saveX, count, color);
-                                         }                                                                             
-                                 }
-                           }
-                        else
-                        {
-                          /* Draw one Hline on X - Led to the Des Zoom Out*/
-
-               for (DesY=DestRect->bottom-zoomY; DesY>=0; DesY-=zoomY)
-                               {
-                                       if (DesIsBiggerY)
-                                               sy = (int) ((ULONG) SrcSizeY * (ULONG) DesY) / ((ULONG) DesSizeY);
-                                       else
-                                               sy = (int) ((ULONG) DesSizeY * (ULONG) DesY) / ((ULONG) SrcSizeY); 
-                                               
-                                       if (sy > SourceRect->bottom) break;
-
-                                       saveY = DesY+zoomY;
-
-                                       for (DesX=DestRect->right-zoomX; DesX>=0; DesX-=zoomX)                          
-                                       {
-                                               sx = (int) ((ULONG) DesSizeX * (ULONG) DesX) / ((ULONG) SrcSizeX);                                                                  
-                                       
-                                               if (sx > SourceRect->right) break;
-                                       
-                                               color =  XLATEOBJ_iXlate(ColorTranslation, DIB_8BPP_GetPixel(SourceSurf, sx, sy));
-                                                                                               
-                                               saveX = DesX + zoomX;
-                                               for (count=DesY;count<saveY;count++)
-                                                       DIB_24BPP_HLine(DestSurf, DesX, saveX, count, color);
-                                         }                                                                             
-                                 }
-                        }
-                  }
-                       
-                  else
-                  {
-                   
-                   if (DesSizeX>SrcSizeX)
-                       {
-                               /* Draw one pixel on X - Led to the Des Zoom In*/
-                               for (DesY=DestRect->bottom-zoomY; DesY>=0; DesY-=zoomY)
-                               {
-                                       if (DesIsBiggerY)
-                                               sy = (int) ((ULONG) SrcSizeY * (ULONG) DesY) / ((ULONG) DesSizeY);
-                                       else
-                                               sy = (int) ((ULONG) DesSizeY * (ULONG) DesY) / ((ULONG) SrcSizeY); 
-                                               
-                                       if (sy > SourceRect->bottom) break;
-
-                                       saveY = DesY+zoomY;
-
-                                       for (DesX=DestRect->right-zoomX; DesX>=0; DesX-=zoomX)                          
-                                       {                                               
-                                               sx = (int) ((ULONG) SrcSizeX * (ULONG) DesX) / ((ULONG) DesSizeX);
-                                               
-                                               if (sx > SourceRect->right) break;
-                                       
-                                               color =  XLATEOBJ_iXlate(ColorTranslation, DIB_8BPP_GetPixel(SourceSurf, sx, sy));
-                                                           
-                                               for (count=DesY;count<saveY;count++)
-                                                       DIB_24BPP_PutPixel(DestSurf, DesX, count, color);                                                                               
-                                        }
-                         }
-                        }
-                       else
-                       {
-                               /* Draw one pixel on X - Led to the Des Zoom Out*/
-                               for (DesY=DestRect->bottom-zoomY; DesY>=0; DesY-=zoomY)
-                               {
-                                       if (DesIsBiggerY)
-                                               sy = (int) ((ULONG) SrcSizeY * (ULONG) DesY) / ((ULONG) DesSizeY);
-                                       else
-                                               sy = (int) ((ULONG) DesSizeY * (ULONG) DesY) / ((ULONG) SrcSizeY); 
-                                               
-                                       if (sy > SourceRect->bottom) break;
-
-                                       saveY = DesY+zoomY;
-
-                                       for (DesX=DestRect->right-zoomX; DesX>=0; DesX-=zoomX)                          
-                                       {
-                                               sx = (int) ((ULONG) DesSizeX * (ULONG) DesX) / ((ULONG) SrcSizeX);                                                                  
-                                       
-                                               if (sx > SourceRect->right) break;
-                                       
-                                               color =  XLATEOBJ_iXlate(ColorTranslation, DIB_8BPP_GetPixel(SourceSurf, sx, sy));
-                                                           
-                                               for (count=DesY;count<saveY;count++)
-                                                       DIB_24BPP_PutPixel(DestSurf, DesX, count, color);                                                                               
-                                        }
-                         }
-                       }
-                  }
-               break;
+      /* FIXME :  MaskOrigin, BrushOrigin, ClipRegion, Mode ? */
+      /* This is a reference implementation, it hasn't been optimized for speed */
+                      
+       for (DesY=DestRect->top; DesY<DestRect->bottom; DesY++)
+       {                        
+           sy = (((DesY - DestRect->top) * SrcSizeY) / DesSizeY) + SourceRect->top;
+                     
+            for (DesX=DestRect->left; DesX<DestRect->right; DesX++)
+            {                  
+                 sx = (((DesX - DestRect->left) * SrcSizeX) / DesSizeX) + SourceRect->left;            
+                 color = DIB_8BPP_GetPixel(SourceSurf, sx, sy);
+                 DIB_24BPP_PutPixel(DestSurf, DesX, DesY, XLATEOBJ_iXlate(ColorTranslation, color));
+            }
+       }                  
+      break;
 
       case BMF_16BPP:          
-                  /* FIXME :  MaskOrigin, BrushOrigin, ClipRegion, Mode ? */
-                  /* This is a reference implementation, it hasn't been optimized for speed */
-           if (zoomX>1)
-                  {
-                    /* Draw one Hline on X - Led to the Des Zoom In*/
-                    if (DesSizeX>SrcSizeX)
-                        {
-                               for (DesY=DestRect->bottom-zoomY; DesY>=0; DesY-=zoomY)
-                               {
-                                       if (DesIsBiggerY)
-                                               sy = (int) ((ULONG) SrcSizeY * (ULONG) DesY) / ((ULONG) DesSizeY);
-                                       else
-                                               sy = (int) ((ULONG) DesSizeY * (ULONG) DesY) / ((ULONG) SrcSizeY); 
-                                               
-                                       if (sy > SourceRect->bottom) break;
-
-                                       saveY = DesY+zoomY;
-
-                                       for (DesX=DestRect->right-zoomX; DesX>=0; DesX-=zoomX)                          
-                                       {                                               
-                                               sx = (int) ((ULONG) SrcSizeX * (ULONG) DesX) / ((ULONG) DesSizeX);
-                                               
-                                               if (sx > SourceRect->right) break;
-                                       
-                                               color =  XLATEOBJ_iXlate(ColorTranslation, DIB_16BPP_GetPixel(SourceSurf, sx, sy));
-                                                                                               
-                                               saveX = DesX + zoomX;
-                                               for (count=DesY;count<saveY;count++)
-                                                       DIB_24BPP_HLine(DestSurf, DesX, saveX, count, color);
-                                         }                                                                             
-                                 }
-                           }
-                        else
-                        {
-                          /* Draw one Hline on X - Led to the Des Zoom Out*/
-
-               for (DesY=DestRect->bottom-zoomY; DesY>=0; DesY-=zoomY)
-                               {
-                                       if (DesIsBiggerY)
-                                               sy = (int) ((ULONG) SrcSizeY * (ULONG) DesY) / ((ULONG) DesSizeY);
-                                       else
-                                               sy = (int) ((ULONG) DesSizeY * (ULONG) DesY) / ((ULONG) SrcSizeY); 
-                                               
-                                       if (sy > SourceRect->bottom) break;
-
-                                       saveY = DesY+zoomY;
-
-                                       for (DesX=DestRect->right-zoomX; DesX>=0; DesX-=zoomX)                          
-                                       {
-                                               sx = (int) ((ULONG) DesSizeX * (ULONG) DesX) / ((ULONG) SrcSizeX);                                                                  
-                                       
-                                               if (sx > SourceRect->right) break;
-                                       
-                                               color =  XLATEOBJ_iXlate(ColorTranslation, DIB_16BPP_GetPixel(SourceSurf, sx, sy));
-                                                                                               
-                                               saveX = DesX + zoomX;
-                                               for (count=DesY;count<saveY;count++)
-                                                       DIB_24BPP_HLine(DestSurf, DesX, saveX, count, color);
-                                         }                                                                             
-                                 }
-                        }
-                  }
-                       
-                  else
-                  {
-                   
-                   if (DesSizeX>SrcSizeX)
-                       {
-                               /* Draw one pixel on X - Led to the Des Zoom In*/
-                               for (DesY=DestRect->bottom-zoomY; DesY>=0; DesY-=zoomY)
-                               {
-                                       if (DesIsBiggerY)
-                                               sy = (int) ((ULONG) SrcSizeY * (ULONG) DesY) / ((ULONG) DesSizeY);
-                                       else
-                                               sy = (int) ((ULONG) DesSizeY * (ULONG) DesY) / ((ULONG) SrcSizeY); 
-                                               
-                                       if (sy > SourceRect->bottom) break;
-
-                                       saveY = DesY+zoomY;
-
-                                       for (DesX=DestRect->right-zoomX; DesX>=0; DesX-=zoomX)                          
-                                       {                                               
-                                               sx = (int) ((ULONG) SrcSizeX * (ULONG) DesX) / ((ULONG) DesSizeX);
-                                               
-                                               if (sx > SourceRect->right) break;
-                                       
-                                               color =  XLATEOBJ_iXlate(ColorTranslation, DIB_16BPP_GetPixel(SourceSurf, sx, sy));
-                                                           
-                                               for (count=DesY;count<saveY;count++)
-                                                       DIB_24BPP_PutPixel(DestSurf, DesX, count, color);                                                                               
-                                        }
-                         }
-                        }
-                       else
-                       {
-                               /* Draw one pixel on X - Led to the Des Zoom Out*/
-                               for (DesY=DestRect->bottom-zoomY; DesY>=0; DesY-=zoomY)
-                               {
-                                       if (DesIsBiggerY)
-                                               sy = (int) ((ULONG) SrcSizeY * (ULONG) DesY) / ((ULONG) DesSizeY);
-                                       else
-                                               sy = (int) ((ULONG) DesSizeY * (ULONG) DesY) / ((ULONG) SrcSizeY); 
-                                               
-                                       if (sy > SourceRect->bottom) break;
-
-                                       saveY = DesY+zoomY;
-
-                                       for (DesX=DestRect->right-zoomX; DesX>=0; DesX-=zoomX)                          
-                                       {
-                                               sx = (int) ((ULONG) DesSizeX * (ULONG) DesX) / ((ULONG) SrcSizeX);                                                                  
-                                       
-                                               if (sx > SourceRect->right) break;
-                                       
-                                               color =  XLATEOBJ_iXlate(ColorTranslation, DIB_16BPP_GetPixel(SourceSurf, sx, sy));
-                                                           
-                                               for (count=DesY;count<saveY;count++)
-                                                       DIB_24BPP_PutPixel(DestSurf, DesX, count, color);                                                                               
-                                        }
-                         }
-                       }
-                  }
-               break;
+      /* FIXME :  MaskOrigin, BrushOrigin, ClipRegion, Mode ? */
+      /* This is a reference implementation, it hasn't been optimized for speed */
+                      
+       for (DesY=DestRect->top; DesY<DestRect->bottom; DesY++)
+       {                        
+           sy = (((DesY - DestRect->top) * SrcSizeY) / DesSizeY) + SourceRect->top;
+                     
+            for (DesX=DestRect->left; DesX<DestRect->right; DesX++)
+            {                  
+                 sx = (((DesX - DestRect->left) * SrcSizeX) / DesSizeX) + SourceRect->left;            
+                 color = DIB_16BPP_GetPixel(SourceSurf, sx, sy);
+                 DIB_24BPP_PutPixel(DestSurf, DesX, DesY, XLATEOBJ_iXlate(ColorTranslation, color));
+            }
+       }                  
+      break;
 
       case BMF_24BPP:          
-                  /* FIXME :  MaskOrigin, BrushOrigin, ClipRegion, Mode ? */
-                  /* This is a reference implementation, it hasn't been optimized for speed */
-           if (zoomX>1)
-                  {
-                    /* Draw one Hline on X - Led to the Des Zoom In*/
-                    if (DesSizeX>SrcSizeX)
-                        {
-                               for (DesY=DestRect->bottom-zoomY; DesY>=0; DesY-=zoomY)
-                               {
-                                       if (DesIsBiggerY)
-                                               sy = (int) ((ULONG) SrcSizeY * (ULONG) DesY) / ((ULONG) DesSizeY);
-                                       else
-                                               sy = (int) ((ULONG) DesSizeY * (ULONG) DesY) / ((ULONG) SrcSizeY); 
-                                               
-                                       if (sy > SourceRect->bottom) break;
-
-                                       saveY = DesY+zoomY;
-
-                                       for (DesX=DestRect->right-zoomX; DesX>=0; DesX-=zoomX)                          
-                                       {                                               
-                                               sx = (int) ((ULONG) SrcSizeX * (ULONG) DesX) / ((ULONG) DesSizeX);
-                                               
-                                               if (sx > SourceRect->right) break;
-                                       
-                                               color =  DIB_24BPP_GetPixel(SourceSurf, sx, sy);
-                                                                                               
-                                               saveX = DesX + zoomX;
-                                               for (count=DesY;count<saveY;count++)
-                                                       DIB_24BPP_HLine(DestSurf, DesX, saveX, count, color);
-                                         }                                                                             
-                                 }
-                           }
-                        else
-                        {
-                          /* Draw one Hline on X - Led to the Des Zoom Out*/
-
-               for (DesY=DestRect->bottom-zoomY; DesY>=0; DesY-=zoomY)
-                               {
-                                       if (DesIsBiggerY)
-                                               sy = (int) ((ULONG) SrcSizeY * (ULONG) DesY) / ((ULONG) DesSizeY);
-                                       else
-                                               sy = (int) ((ULONG) DesSizeY * (ULONG) DesY) / ((ULONG) SrcSizeY); 
-                                               
-                                       if (sy > SourceRect->bottom) break;
-
-                                       saveY = DesY+zoomY;
-
-                                       for (DesX=DestRect->right-zoomX; DesX>=0; DesX-=zoomX)                          
-                                       {
-                                               sx = (int) ((ULONG) DesSizeX * (ULONG) DesX) / ((ULONG) SrcSizeX);                                                                  
-                                       
-                                               if (sx > SourceRect->right) break;
-                                       
-                                               color =  DIB_24BPP_GetPixel(SourceSurf, sx, sy);
-                                                                                               
-                                               saveX = DesX + zoomX;
-                                               for (count=DesY;count<saveY;count++)
-                                                       DIB_24BPP_HLine(DestSurf, DesX, saveX, count, color);
-                                         }                                                                             
-                                 }
-                        }
-                  }
-                       
-                  else
-                  {
-                   
-                   if (DesSizeX>SrcSizeX)
-                       {
-                               /* Draw one pixel on X - Led to the Des Zoom In*/
-                               for (DesY=DestRect->bottom-zoomY; DesY>=0; DesY-=zoomY)
-                               {
-                                       if (DesIsBiggerY)
-                                               sy = (int) ((ULONG) SrcSizeY * (ULONG) DesY) / ((ULONG) DesSizeY);
-                                       else
-                                               sy = (int) ((ULONG) DesSizeY * (ULONG) DesY) / ((ULONG) SrcSizeY); 
-                                               
-                                       if (sy > SourceRect->bottom) break;
-
-                                       saveY = DesY+zoomY;
-
-                                       for (DesX=DestRect->right-zoomX; DesX>=0; DesX-=zoomX)                          
-                                       {                                               
-                                               sx = (int) ((ULONG) SrcSizeX * (ULONG) DesX) / ((ULONG) DesSizeX);
-                                               
-                                               if (sx > SourceRect->right) break;
-                                       
-                                               color =  DIB_24BPP_GetPixel(SourceSurf, sx, sy);
-                                                           
-                                               for (count=DesY;count<saveY;count++)
-                                                       DIB_24BPP_PutPixel(DestSurf, DesX, count, color);                                                                               
-                                        }
-                         }
-                        }
-                       else
-                       {
-                               /* Draw one pixel on X - Led to the Des Zoom Out*/
-                               for (DesY=DestRect->bottom-zoomY; DesY>=0; DesY-=zoomY)
-                               {
-                                       if (DesIsBiggerY)
-                                               sy = (int) ((ULONG) SrcSizeY * (ULONG) DesY) / ((ULONG) DesSizeY);
-                                       else
-                                               sy = (int) ((ULONG) DesSizeY * (ULONG) DesY) / ((ULONG) SrcSizeY); 
-                                               
-                                       if (sy > SourceRect->bottom) break;
-
-                                       saveY = DesY+zoomY;
-
-                                       for (DesX=DestRect->right-zoomX; DesX>=0; DesX-=zoomX)                          
-                                       {
-                                               sx = (int) ((ULONG) DesSizeX * (ULONG) DesX) / ((ULONG) SrcSizeX);                                                                  
-                                       
-                                               if (sx > SourceRect->right) break;
-                                       
-                                               color =  DIB_24BPP_GetPixel(SourceSurf, sx, sy);
-                                                           
-                                               for (count=DesY;count<saveY;count++)
-                                                       DIB_24BPP_PutPixel(DestSurf, DesX, count, color);                                                                               
-                                        }
-                         }
-                       }
-                  }
-               break;
+      /* FIXME :  MaskOrigin, BrushOrigin, ClipRegion, Mode ? */
+      /* This is a reference implementation, it hasn't been optimized for speed */
+                      
+       for (DesY=DestRect->top; DesY<DestRect->bottom; DesY++)
+       {                        
+           sy = (((DesY - DestRect->top) * SrcSizeY) / DesSizeY) + SourceRect->top;
+                     
+            for (DesX=DestRect->left; DesX<DestRect->right; DesX++)
+            {                  
+                 sx = (((DesX - DestRect->left) * SrcSizeX) / DesSizeX) + SourceRect->left;            
+                 color = DIB_24BPP_GetPixel(SourceSurf, sx, sy);
+                 DIB_24BPP_PutPixel(DestSurf, DesX, DesY, XLATEOBJ_iXlate(ColorTranslation, color));
+            }
+       }                  
+      break;
 
       case BMF_32BPP:          
-                  /* FIXME :  MaskOrigin, BrushOrigin, ClipRegion, Mode ? */
-                  /* This is a reference implementation, it hasn't been optimized for speed */
-           if (zoomX>1)
-                  {
-                    /* Draw one Hline on X - Led to the Des Zoom In*/
-                    if (DesSizeX>SrcSizeX)
-                        {
-                               for (DesY=DestRect->bottom-zoomY; DesY>=0; DesY-=zoomY)
-                               {
-                                       if (DesIsBiggerY)
-                                               sy = (int) ((ULONG) SrcSizeY * (ULONG) DesY) / ((ULONG) DesSizeY);
-                                       else
-                                               sy = (int) ((ULONG) DesSizeY * (ULONG) DesY) / ((ULONG) SrcSizeY); 
-                                               
-                                       if (sy > SourceRect->bottom) break;
-
-                                       saveY = DesY+zoomY;
-
-                                       for (DesX=DestRect->right-zoomX; DesX>=0; DesX-=zoomX)                          
-                                       {                                               
-                                               sx = (int) ((ULONG) SrcSizeX * (ULONG) DesX) / ((ULONG) DesSizeX);
-                                               
-                                               if (sx > SourceRect->right) break;
-                                       
-                                               color =  XLATEOBJ_iXlate(ColorTranslation, DIB_32BPP_GetPixel(SourceSurf, sx, sy));
-                                                                                               
-                                               saveX = DesX + zoomX;
-                                               for (count=DesY;count<saveY;count++)
-                                                       DIB_24BPP_HLine(DestSurf, DesX, saveX, count, color);
-                                         }                                                                             
-                                 }
-                           }
-                        else
-                        {
-                          /* Draw one Hline on X - Led to the Des Zoom Out*/
-
-               for (DesY=DestRect->bottom-zoomY; DesY>=0; DesY-=zoomY)
-                               {
-                                       if (DesIsBiggerY)
-                                               sy = (int) ((ULONG) SrcSizeY * (ULONG) DesY) / ((ULONG) DesSizeY);
-                                       else
-                                               sy = (int) ((ULONG) DesSizeY * (ULONG) DesY) / ((ULONG) SrcSizeY); 
-                                               
-                                       if (sy > SourceRect->bottom) break;
-
-                                       saveY = DesY+zoomY;
-
-                                       for (DesX=DestRect->right-zoomX; DesX>=0; DesX-=zoomX)                          
-                                       {
-                                               sx = (int) ((ULONG) DesSizeX * (ULONG) DesX) / ((ULONG) SrcSizeX);                                                                  
-                                       
-                                               if (sx > SourceRect->right) break;
-                                       
-                                               color =  XLATEOBJ_iXlate(ColorTranslation, DIB_32BPP_GetPixel(SourceSurf, sx, sy));
-                                                                                               
-                                               saveX = DesX + zoomX;
-                                               for (count=DesY;count<saveY;count++)
-                                                       DIB_24BPP_HLine(DestSurf, DesX, saveX, count, color);
-                                         }                                                                             
-                                 }
-                        }
-                  }
-                       
-                  else
-                  {
-                   
-                   if (DesSizeX>SrcSizeX)
-                       {
-                               /* Draw one pixel on X - Led to the Des Zoom In*/
-                               for (DesY=DestRect->bottom-zoomY; DesY>=0; DesY-=zoomY)
-                               {
-                                       if (DesIsBiggerY)
-                                               sy = (int) ((ULONG) SrcSizeY * (ULONG) DesY) / ((ULONG) DesSizeY);
-                                       else
-                                               sy = (int) ((ULONG) DesSizeY * (ULONG) DesY) / ((ULONG) SrcSizeY); 
-                                               
-                                       if (sy > SourceRect->bottom) break;
-
-                                       saveY = DesY+zoomY;
-
-                                       for (DesX=DestRect->right-zoomX; DesX>=0; DesX-=zoomX)                          
-                                       {                                               
-                                               sx = (int) ((ULONG) SrcSizeX * (ULONG) DesX) / ((ULONG) DesSizeX);
-                                               
-                                               if (sx > SourceRect->right) break;
-                                       
-                                               color =  XLATEOBJ_iXlate(ColorTranslation, DIB_32BPP_GetPixel(SourceSurf, sx, sy));
-                                                           
-                                               for (count=DesY;count<saveY;count++)
-                                                       DIB_24BPP_PutPixel(DestSurf, DesX, count, color);                                                                               
-                                        }
-                         }
-                        }
-                       else
-                       {
-                               /* Draw one pixel on X - Led to the Des Zoom Out*/
-                               for (DesY=DestRect->bottom-zoomY; DesY>=0; DesY-=zoomY)
-                               {
-                                       if (DesIsBiggerY)
-                                               sy = (int) ((ULONG) SrcSizeY * (ULONG) DesY) / ((ULONG) DesSizeY);
-                                       else
-                                               sy = (int) ((ULONG) DesSizeY * (ULONG) DesY) / ((ULONG) SrcSizeY); 
-                                               
-                                       if (sy > SourceRect->bottom) break;
-
-                                       saveY = DesY+zoomY;
-
-                                       for (DesX=DestRect->right-zoomX; DesX>=0; DesX-=zoomX)                          
-                                       {
-                                               sx = (int) ((ULONG) DesSizeX * (ULONG) DesX) / ((ULONG) SrcSizeX);                                                                  
-                                       
-                                               if (sx > SourceRect->right) break;
-                                       
-                                               color =  XLATEOBJ_iXlate(ColorTranslation, DIB_32BPP_GetPixel(SourceSurf, sx, sy));
-                                                           
-                                               for (count=DesY;count<saveY;count++)
-                                                       DIB_24BPP_PutPixel(DestSurf, DesX, count, color);                                                                               
-                                        }
-                         }
-                       }
-                  }
-               break;
+      /* FIXME :  MaskOrigin, BrushOrigin, ClipRegion, Mode ? */
+      /* This is a reference implementation, it hasn't been optimized for speed */
+                      
+       for (DesY=DestRect->top; DesY<DestRect->bottom; DesY++)
+       {                        
+           sy = (((DesY - DestRect->top) * SrcSizeY) / DesSizeY) + SourceRect->top;
+                     
+            for (DesX=DestRect->left; DesX<DestRect->right; DesX++)
+            {                  
+                 sx = (((DesX - DestRect->left) * SrcSizeX) / DesSizeX) + SourceRect->left;            
+                 color = DIB_32BPP_GetPixel(SourceSurf, sx, sy);
+                 DIB_24BPP_PutPixel(DestSurf, DesX, DesY, XLATEOBJ_iXlate(ColorTranslation, color));
+            }
+       }                  
+      break;
 
       default:
       //DPRINT1("DIB_24BPP_StretchBlt: Unhandled Source BPP: %u\n", BitsPerFormat(SourceSurf->iBitmapFormat));
@@ -1215,7 +642,7 @@ DIB_24BPP_TransparentBlt(SURFOBJ *DestSurf, SURFOBJ *SourceSurf,
   BYTE *DestBits;
 
   SourceY = SourcePoint->y;
-  DestBits = (BYTE*)(DestSurf->pvScan0 +
+  DestBits = (BYTE*)((PBYTE)DestSurf->pvScan0 +
                       (DestRect->left << 2) +
                       DestRect->top * DestSurf->lDelta);
   wd = DestSurf->lDelta - ((DestRect->right - DestRect->left) << 2);
@@ -1241,4 +668,98 @@ DIB_24BPP_TransparentBlt(SURFOBJ *DestSurf, SURFOBJ *SourceSurf,
   return TRUE;
 }
 
+typedef union {
+   ULONG ul;
+   struct {
+      UCHAR red;
+      UCHAR green;
+      UCHAR blue;
+      UCHAR alpha;
+   } col;
+} NICEPIXEL32;
+
+STATIC inline UCHAR
+Clamp8(ULONG val)
+{
+   return (val > 255) ? 255 : val;
+}
+
+BOOLEAN
+DIB_24BPP_AlphaBlend(SURFOBJ* Dest, SURFOBJ* Source, RECTL* DestRect,
+                     RECTL* SourceRect, CLIPOBJ* ClipRegion,
+                     XLATEOBJ* ColorTranslation, BLENDOBJ* BlendObj)
+{
+   INT Rows, Cols, SrcX, SrcY;
+   register PUCHAR Dst;
+   ULONG DstDelta;
+   BLENDFUNCTION BlendFunc;
+   register NICEPIXEL32 DstPixel, SrcPixel;
+   UCHAR Alpha, SrcBpp;
+
+   DPRINT("DIB_24BPP_AlphaBlend: srcRect: (%d,%d)-(%d,%d), dstRect: (%d,%d)-(%d,%d)\n",
+          SourceRect->left, SourceRect->top, SourceRect->right, SourceRect->bottom,
+          DestRect->left, DestRect->top, DestRect->right, DestRect->bottom);
+
+   ASSERT(DestRect->bottom - DestRect->top == SourceRect->bottom - SourceRect->top &&
+          DestRect->right - DestRect->left == SourceRect->right - SourceRect->left);
+
+   BlendFunc = BlendObj->BlendFunction;
+   if (BlendFunc.BlendOp != AC_SRC_OVER)
+   {
+      DPRINT1("BlendOp != AC_SRC_OVER\n");
+      return FALSE;
+   }
+   if (BlendFunc.BlendFlags != 0)
+   {
+      DPRINT1("BlendFlags != 0\n");
+      return FALSE;
+   }
+   if ((BlendFunc.AlphaFormat & ~AC_SRC_ALPHA) != 0)
+   {
+      DPRINT1("Unsupported AlphaFormat (0x%x)\n", BlendFunc.AlphaFormat);
+      return FALSE;
+   }
+   if ((BlendFunc.AlphaFormat & AC_SRC_ALPHA) != 0 &&
+       BitsPerFormat(Source->iBitmapFormat) != 32)
+   {
+      DPRINT1("Source bitmap must be 32bpp when AC_SRC_ALPHA is set\n");
+      return FALSE;
+   }
+
+   Dst = (PUCHAR)((ULONG_PTR)Dest->pvScan0 + (DestRect->top * Dest->lDelta) +
+                             (DestRect->left * 3));
+   DstDelta = Dest->lDelta - ((DestRect->right - DestRect->left) * 3);
+   SrcBpp = BitsPerFormat(Source->iBitmapFormat);
+
+   Rows = DestRect->bottom - DestRect->top;
+   SrcY = SourceRect->top;
+   while (--Rows >= 0)
+   {
+      Cols = DestRect->right - DestRect->left;
+      SrcX = SourceRect->left;
+      while (--Cols >= 0)
+      {
+         SrcPixel.ul = DIB_GetSource(Source, SrcX++, SrcY, ColorTranslation);
+         SrcPixel.col.red = SrcPixel.col.red * BlendFunc.SourceConstantAlpha / 255;
+         SrcPixel.col.green = SrcPixel.col.green * BlendFunc.SourceConstantAlpha / 255;
+         SrcPixel.col.blue = SrcPixel.col.blue * BlendFunc.SourceConstantAlpha / 255;
+         SrcPixel.col.alpha = (SrcBpp == 32) ? (SrcPixel.col.alpha * BlendFunc.SourceConstantAlpha / 255) : BlendFunc.SourceConstantAlpha;
+
+         Alpha = ((BlendFunc.AlphaFormat & AC_SRC_ALPHA) != 0) ?
+                 SrcPixel.col.alpha : BlendFunc.SourceConstantAlpha;
+
+         DstPixel.ul = *Dst;
+         DstPixel.col.red = Clamp8(DstPixel.col.red * (255 - Alpha) / 255 + SrcPixel.col.red);
+         DstPixel.col.green = Clamp8(DstPixel.col.green * (255 - Alpha) / 255 + SrcPixel.col.green);
+         DstPixel.col.blue = Clamp8(DstPixel.col.blue * (255 - Alpha) / 255 + SrcPixel.col.blue);
+         *Dst = DstPixel.ul;
+         Dst = (PUCHAR)((ULONG_PTR)Dst + 3);
+      }
+      Dst = (PUCHAR)((ULONG_PTR)Dst + DstDelta);
+      SrcY++;
+   }
+
+   return TRUE;
+}
+
 /* EOF */