Commit in reactos/subsys/win32k on MAIN
dib/dib.h+12-61.21 -> 1.22
   /dib16bpp.c+109-371.31 -> 1.32
   /dib1bpp.c+3-21.27 -> 1.28
   /dib24bpp.c+3-21.26 -> 1.27
   /dib32bpp.c+108-351.26 -> 1.27
   /dib4bpp.c+3-21.34 -> 1.35
   /dib8bpp.c+108-361.25 -> 1.26
eng/bitblt.c+38-1621.54 -> 1.55
   /clip.c+120-11.20 -> 1.21
   /clip.h+91.6 -> 1.7
   /surface.c+3-21.38 -> 1.39
include/tags.h+11.2 -> 1.3
+517-285
12 modified files
Implement complex clipping for StretchBlt

reactos/subsys/win32k/dib
dib.h 1.21 -> 1.22
diff -u -r1.21 -r1.22
--- dib.h	10 May 2004 17:07:17 -0000	1.21
+++ dib.h	14 May 2004 22:56:17 -0000	1.22
@@ -21,7 +21,8 @@
                             SURFGDI *DestGDI, SURFGDI *SourceGDI,
                             RECTL* DestRect, RECTL *SourceRect,
                             POINTL* MaskOrigin, POINTL BrushOrigin,
-                            XLATEOBJ *ColorTranslation, ULONG Mode);
+                            CLIPOBJ *ClipRegion, XLATEOBJ *ColorTranslation,
+                            ULONG Mode);
 BOOLEAN DIB_1BPP_TransparentBlt(SURFOBJ *DestSurf, SURFOBJ *SourceSurf,
                                 PSURFGDI DestGDI,  PSURFGDI SourceGDI,
                                 RECTL*  DestRect,  POINTL  *SourcePoint,
@@ -40,7 +41,8 @@
                             SURFGDI *DestGDI, SURFGDI *SourceGDI,
                             RECTL* DestRect, RECTL *SourceRect,
                             POINTL* MaskOrigin, POINTL BrushOrigin,
-                            XLATEOBJ *ColorTranslation, ULONG Mode);
+                            CLIPOBJ *ClipRegion, XLATEOBJ *ColorTranslation,
+                            ULONG Mode);
 BOOLEAN DIB_4BPP_TransparentBlt(SURFOBJ *DestSurf, SURFOBJ *SourceSurf,
                                 PSURFGDI DestGDI,  PSURFGDI SourceGDI,
                                 RECTL*  DestRect,  POINTL  *SourcePoint,
@@ -59,7 +61,8 @@
                             SURFGDI *DestGDI, SURFGDI *SourceGDI,
                             RECTL* DestRect, RECTL *SourceRect,
                             POINTL* MaskOrigin, POINTL BrushOrigin,
-                            XLATEOBJ *ColorTranslation, ULONG Mode);
+                            CLIPOBJ *ClipRegion, XLATEOBJ *ColorTranslation,
+                            ULONG Mode);
 BOOLEAN DIB_8BPP_TransparentBlt(SURFOBJ *DestSurf, SURFOBJ *SourceSurf,
                                 PSURFGDI DestGDI,  PSURFGDI SourceGDI,
                                 RECTL*  DestRect,  POINTL  *SourcePoint,
@@ -78,7 +81,8 @@
                              SURFGDI *DestGDI, SURFGDI *SourceGDI,
                              RECTL* DestRect, RECTL *SourceRect,
                              POINTL* MaskOrigin, POINTL BrushOrigin,
-                             XLATEOBJ *ColorTranslation, ULONG Mode);
+                             CLIPOBJ *ClipRegion, XLATEOBJ *ColorTranslation,
+                             ULONG Mode);
 BOOLEAN DIB_16BPP_TransparentBlt(SURFOBJ *DestSurf, SURFOBJ *SourceSurf,
                                  PSURFGDI DestGDI,  PSURFGDI SourceGDI,
                                  RECTL*  DestRect,  POINTL  *SourcePoint,
@@ -97,7 +101,8 @@
                              SURFGDI *DestGDI, SURFGDI *SourceGDI,
                              RECTL* DestRect, RECTL *SourceRect,
                              POINTL* MaskOrigin, POINTL BrushOrigin,
-                             XLATEOBJ *ColorTranslation, ULONG Mode);
+                             CLIPOBJ *ClipRegion, XLATEOBJ *ColorTranslation,
+                             ULONG Mode);
 BOOLEAN DIB_24BPP_TransparentBlt(SURFOBJ *DestSurf, SURFOBJ *SourceSurf,
                                  PSURFGDI DestGDI,  PSURFGDI SourceGDI,
                                  RECTL*  DestRect,  POINTL  *SourcePoint,
@@ -116,7 +121,8 @@
                              SURFGDI *DestGDI, SURFGDI *SourceGDI,
                              RECTL* DestRect, RECTL *SourceRect,
                              POINTL* MaskOrigin, POINTL BrushOrigin,
-                             XLATEOBJ *ColorTranslation, ULONG Mode);			             
+                             CLIPOBJ *ClipRegion, XLATEOBJ *ColorTranslation,
+                             ULONG Mode);
 BOOLEAN DIB_32BPP_TransparentBlt(SURFOBJ *DestSurf, SURFOBJ *SourceSurf,
                                  PSURFGDI DestGDI,  PSURFGDI SourceGDI,
                                  RECTL*  DestRect,  POINTL  *SourcePoint,

reactos/subsys/win32k/dib
dib16bpp.c 1.31 -> 1.32
diff -u -r1.31 -r1.32
--- dib16bpp.c	10 May 2004 17:07:17 -0000	1.31
+++ dib16bpp.c	14 May 2004 22:56:17 -0000	1.32
@@ -16,7 +16,7 @@
  *  along with this program; if not, write to the Free Software
  *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
-/* $Id: dib16bpp.c,v 1.31 2004/05/10 17:07:17 weiden Exp $ */
+/* $Id: dib16bpp.c,v 1.32 2004/05/14 22:56:17 gvg Exp $ */
 #include <w32k.h>
 
 VOID
@@ -256,7 +256,7 @@
       break;
 
     default:
-      DbgPrint("DIB_16BPP_Bitblt: Unhandled Source BPP: %u\n", SourceGDI->BitsPerPixel);
+      DPRINT1("DIB_16BPP_Bitblt: Unhandled Source BPP: %u\n", SourceGDI->BitsPerPixel);
       return FALSE;
   }
 
@@ -468,26 +468,84 @@
     *Target++ = *Source;
 }
 
+static BOOLEAN
+FinalCopy16(PIXEL *Target, PIXEL *Source, PSPAN ClipSpans, UINT ClipSpansCount, UINT *SpanIndex,
+            UINT DestY, RECTL *DestRect)
+{
+  LONG Left, Right;
+  
+  while (ClipSpans[*SpanIndex].Y < DestY
+         || (ClipSpans[*SpanIndex].Y == DestY
+             && ClipSpans[*SpanIndex].X + ClipSpans[*SpanIndex].Width < DestRect->left))
+    {
+      (*SpanIndex)++;
+      if (ClipSpansCount <= *SpanIndex)
+        {
+          /* No more spans, everything else is clipped away, we're done */
+          return FALSE;
+        }
+    }
+  while (ClipSpans[*SpanIndex].Y == DestY)
+    {
+      if (ClipSpans[*SpanIndex].X < DestRect->right)
+        {
+          Left = max(ClipSpans[*SpanIndex].X, DestRect->left);
+          Right = min(ClipSpans[*SpanIndex].X + ClipSpans[*SpanIndex].Width, DestRect->right);
+          memcpy(Target + Left - DestRect->left, Source + Left - DestRect->left,
+                 (Right - Left) * sizeof(PIXEL));
+        }
+      (*SpanIndex)++;
+      if (ClipSpansCount <= *SpanIndex)
+        {
+          /* No more spans, everything else is clipped away, we're done */
+          return FALSE;
+        }
+    }
+
+  return TRUE;
+}
+
 //NOTE: If you change something here, please do the same in other dibXXbpp.c files!
-void ScaleRectAvg16(PIXEL *Target, PIXEL *Source, int SrcWidth, int SrcHeight,
-                  int TgtWidth, int TgtHeight, int srcPitch, int dstPitch)
-{
-  int NumPixels = TgtHeight;
-  int IntPart = ((SrcHeight / TgtHeight) * srcPitch) >> 1; //(SrcHeight / TgtHeight) * SrcWidth;
-  int FractPart = SrcHeight % TgtHeight;
-  int Mid = TgtHeight >> 1;
+BOOLEAN ScaleRectAvg16(SURFGDI *DestGDI, SURFGDI *SourceGDI,
+                       RECTL* DestRect, RECTL *SourceRect,
+                       POINTL* MaskOrigin, POINTL BrushOrigin,
+                       CLIPOBJ *ClipRegion, XLATEOBJ *ColorTranslation,
+                       ULONG Mode)
+{
+  int NumPixels = DestRect->bottom - DestRect->top;
+  int IntPart = (((SourceRect->bottom - SourceRect->top) / (DestRect->bottom - DestRect->top)) * SourceGDI->SurfObj.lDelta) >> 1; /* ((SourceRect->bottom - SourceRect->top) / (DestRect->bottom - DestRect->top)) * (SourceRect->right - SourceRect->left); */
+  int FractPart = (SourceRect->bottom - SourceRect->top) % (DestRect->bottom - DestRect->top);
+  int Mid = (DestRect->bottom - DestRect->top) >> 1;
   int E = 0;
   int skip;
   PIXEL *ScanLine, *ScanLineAhead;
   PIXEL *PrevSource = NULL;
   PIXEL *PrevSourceAhead = NULL;
+  PIXEL *Target = (PIXEL *) (DestGDI->SurfObj.pvScan0 + (DestRect->top * DestGDI->SurfObj.lDelta) + 2 * DestRect->left);
+  PIXEL *Source = (PIXEL *) (SourceGDI->SurfObj.pvScan0 + (SourceRect->top * SourceGDI->SurfObj.lDelta) + 2 * SourceRect->left);
+  PSPAN ClipSpans;
+  UINT ClipSpansCount;
+  UINT SpanIndex;
+  LONG DestY;
 
-  skip = (TgtHeight < SrcHeight) ? 0 : (TgtHeight / (2*SrcHeight) + 1);
+  if (! ClipobjToSpans(&ClipSpans, &ClipSpansCount, ClipRegion, DestRect))
+    {
+      return FALSE;
+    }
+  if (0 == ClipSpansCount)
+    {
+      /* No clip spans == empty clipping region, everything clipped away */
+      ASSERT(NULL == ClipSpans);
+      return TRUE;
+    }
+  skip = (DestRect->bottom - DestRect->top < SourceRect->bottom - SourceRect->top) ? 0 : ((DestRect->bottom - DestRect->top) / (2 * (SourceRect->bottom - SourceRect->top)) + 1);
   NumPixels -= skip;
 
-  ScanLine = (PIXEL*)ExAllocatePool(NonPagedPool, TgtWidth*sizeof(PIXEL)); // FIXME: Should we use PagedPool here?
-  ScanLineAhead = (PIXEL *)ExAllocatePool(NonPagedPool, TgtWidth*sizeof(PIXEL));
+  ScanLine = (PIXEL*)ExAllocatePool(PagedPool, (DestRect->right - DestRect->left) * sizeof(PIXEL));
+  ScanLineAhead = (PIXEL *)ExAllocatePool(PagedPool, (DestRect->right - DestRect->left) * sizeof(PIXEL));
 
+  DestY = DestRect->top;
+  SpanIndex = 0;
   while (NumPixels-- > 0) {
     if (Source != PrevSource) {
       if (Source == PrevSourceAhead) {
@@ -499,38 +557,57 @@
         ScanLine = ScanLineAhead;
         ScanLineAhead = tmp;
       } else {
-        ScaleLineAvg16(ScanLine, Source, SrcWidth, TgtWidth);
+        ScaleLineAvg16(ScanLine, Source, SourceRect->right - SourceRect->left, DestRect->right - DestRect->left);
       } /* if */
       PrevSource = Source;
     } /* if */
     
-    if (E >= Mid && PrevSourceAhead != (PIXEL *)((BYTE *)Source + srcPitch)) {
+    if (E >= Mid && PrevSourceAhead != (PIXEL *)((BYTE *)Source + SourceGDI->SurfObj.lDelta)) {
       int x;
-      ScaleLineAvg16(ScanLineAhead, (PIXEL *)((BYTE *)Source + srcPitch), SrcWidth, TgtWidth);
-      for (x = 0; x < TgtWidth; x++)
+      ScaleLineAvg16(ScanLineAhead, (PIXEL *)((BYTE *)Source + SourceGDI->SurfObj.lDelta), SourceRect->right - SourceRect->left, DestRect->right - DestRect->left);
+      for (x = 0; x < DestRect->right - DestRect->left; x++)
         ScanLine[x] = average16(ScanLine[x], ScanLineAhead[x]);
-      PrevSourceAhead = (PIXEL *)((BYTE *)Source + srcPitch);
+      PrevSourceAhead = (PIXEL *)((BYTE *)Source + SourceGDI->SurfObj.lDelta);
     } /* if */
-    
-    memcpy(Target, ScanLine, TgtWidth*sizeof(PIXEL));
-    Target = (PIXEL *)((BYTE *)Target + dstPitch);
+
+    if (! FinalCopy16(Target, ScanLine, ClipSpans, ClipSpansCount, &SpanIndex, DestY, DestRect))
+      {
+        /* No more spans, everything else is clipped away, we're done */
+        ExFreePool(ClipSpans);
+        ExFreePool(ScanLine);
+        ExFreePool(ScanLineAhead);
+        return TRUE;
+      }
+    DestY++;
+    Target = (PIXEL *)((BYTE *)Target + DestGDI->SurfObj.lDelta);
     Source += IntPart;
     E += FractPart;
-    if (E >= TgtHeight) {
-      E -= TgtHeight;
-      Source = (PIXEL *)((BYTE *)Source + srcPitch);
+    if (E >= DestRect->bottom - DestRect->top) {
+      E -= DestRect->bottom - DestRect->top;
+      Source = (PIXEL *)((BYTE *)Source + SourceGDI->SurfObj.lDelta);
     } /* if */
   } /* while */
 
   if (skip > 0 && Source != PrevSource)
-    ScaleLineAvg16(ScanLine, Source, SrcWidth, TgtWidth);
+    ScaleLineAvg16(ScanLine, Source, SourceRect->right - SourceRect->left, DestRect->right - DestRect->left);
   while (skip-- > 0) {
-    memcpy(Target, ScanLine, TgtWidth*sizeof(PIXEL));
-    Target = (PIXEL *)((BYTE *)Target + dstPitch);
+    if (! FinalCopy16(Target, ScanLine, ClipSpans, ClipSpansCount, &SpanIndex, DestY, DestRect))
+      {
+        /* No more spans, everything else is clipped away, we're done */
+        ExFreePool(ClipSpans);
+        ExFreePool(ScanLine);
+        ExFreePool(ScanLineAhead);
+        return TRUE;
+      }
+    DestY++;
+    Target = (PIXEL *)((BYTE *)Target + DestGDI->SurfObj.lDelta);
   } /* while */
 
+  ExFreePool(ClipSpans);
   ExFreePool(ScanLine);
   ExFreePool(ScanLineAhead);
+
+  return TRUE;
 }
 
 //NOTE: If you change something here, please do the same in other dibXXbpp.c files!
@@ -538,11 +615,10 @@
                              SURFGDI *DestGDI, SURFGDI *SourceGDI,
                              RECTL* DestRect, RECTL *SourceRect,
                              POINTL* MaskOrigin, POINTL BrushOrigin,
-                             XLATEOBJ *ColorTranslation, ULONG Mode)
+                             CLIPOBJ *ClipRegion, XLATEOBJ *ColorTranslation,
+                             ULONG Mode)
 {
-  BYTE *SourceLine, *DestLine;
-  
-  DbgPrint("DIB_16BPP_StretchBlt: Source BPP: %u, srcRect: (%d,%d)-(%d,%d), dstRect: (%d,%d)-(%d,%d)\n",
+  DPRINT("DIB_16BPP_StretchBlt: Source BPP: %u, srcRect: (%d,%d)-(%d,%d), dstRect: (%d,%d)-(%d,%d)\n",
      SourceGDI->BitsPerPixel, SourceRect->left, SourceRect->top, SourceRect->right, SourceRect->bottom,
      DestRect->left, DestRect->top, DestRect->right, DestRect->bottom);
 
@@ -561,12 +637,8 @@
       break;
 
       case 16:
-	    SourceLine = SourceSurf->pvScan0 + (SourceRect->top * SourceSurf->lDelta) + 2 * SourceRect->left;
-	    DestLine = DestSurf->pvScan0 + (DestRect->top * DestSurf->lDelta) + 2 * DestRect->left;
-
-        ScaleRectAvg16((PIXEL *)DestLine, (PIXEL *)SourceLine,
-           SourceRect->right-SourceRect->left, SourceRect->bottom-SourceRect->top, 
-           DestRect->right-DestRect->left, DestRect->bottom-DestRect->top, SourceSurf->lDelta, DestSurf->lDelta);
+        return ScaleRectAvg16(DestGDI, SourceGDI, DestRect, SourceRect, MaskOrigin, BrushOrigin,
+                              ClipRegion, ColorTranslation, Mode);
       break;
     
       case 24:
@@ -578,7 +650,7 @@
       break;
       
       default:
-         DbgPrint("DIB_16BPP_StretchBlt: Unhandled Source BPP: %u\n", SourceGDI->BitsPerPixel);
+         DPRINT1("DIB_16BPP_StretchBlt: Unhandled Source BPP: %u\n", SourceGDI->BitsPerPixel);
       return FALSE;
     }
 

reactos/subsys/win32k/dib
dib1bpp.c 1.27 -> 1.28
diff -u -r1.27 -r1.28
--- dib1bpp.c	10 May 2004 17:07:17 -0000	1.27
+++ dib1bpp.c	14 May 2004 22:56:17 -0000	1.28
@@ -16,7 +16,7 @@
  *  along with this program; if not, write to the Free Software
  *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
-/* $Id: dib1bpp.c,v 1.27 2004/05/10 17:07:17 weiden Exp $ */
+/* $Id: dib1bpp.c,v 1.28 2004/05/14 22:56:17 gvg Exp $ */
 #include <w32k.h>
 
 VOID
@@ -515,7 +515,8 @@
 	SURFGDI *DestGDI, SURFGDI *SourceGDI,
 	RECTL* DestRect, RECTL *SourceRect,
 	POINTL* MaskOrigin, POINTL BrushOrigin,
-	XLATEOBJ *ColorTranslation, ULONG Mode)
+	CLIPOBJ *ClipRegion, XLATEOBJ *ColorTranslation,
+        ULONG Mode)
 {
 	DbgPrint("DIB_1BPP_StretchBlt: Source BPP: %u\n", SourceGDI->BitsPerPixel);
 	return FALSE;

reactos/subsys/win32k/dib
dib24bpp.c 1.26 -> 1.27
diff -u -r1.26 -r1.27
--- dib24bpp.c	10 May 2004 17:07:17 -0000	1.26
+++ dib24bpp.c	14 May 2004 22:56:17 -0000	1.27
@@ -16,7 +16,7 @@
  *  along with this program; if not, write to the Free Software
  *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
-/* $Id: dib24bpp.c,v 1.26 2004/05/10 17:07:17 weiden Exp $ */
+/* $Id: dib24bpp.c,v 1.27 2004/05/14 22:56:17 gvg Exp $ */
 #include <w32k.h>
 
 VOID
@@ -345,7 +345,8 @@
                             SURFGDI *DestGDI, SURFGDI *SourceGDI,
                             RECTL* DestRect, RECTL *SourceRect,
                             POINTL* MaskOrigin, POINTL BrushOrigin,
-			                XLATEOBJ *ColorTranslation, ULONG Mode)
+                            CLIPOBJ *ClipRegion, XLATEOBJ *ColorTranslation,
+                            ULONG Mode)
 {
   DbgPrint("DIB_24BPP_StretchBlt: Source BPP: %u\n", SourceGDI->BitsPerPixel);
   return FALSE;

reactos/subsys/win32k/dib
dib32bpp.c 1.26 -> 1.27
diff -u -r1.26 -r1.27
--- dib32bpp.c	10 May 2004 17:07:17 -0000	1.26
+++ dib32bpp.c	14 May 2004 22:56:17 -0000	1.27
@@ -16,7 +16,7 @@
  *  along with this program; if not, write to the Free Software
  *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
-/* $Id: dib32bpp.c,v 1.26 2004/05/10 17:07:17 weiden Exp $ */
+/* $Id: dib32bpp.c,v 1.27 2004/05/14 22:56:17 gvg Exp $ */
 #include <w32k.h>
 
 VOID
@@ -278,7 +278,7 @@
       break;
 
     default:
-      DbgPrint("DIB_32BPP_Bitblt: Unhandled Source BPP: %u\n", SourceGDI->BitsPerPixel);
+      DPRINT1("DIB_32BPP_Bitblt: Unhandled Source BPP: %u\n", SourceGDI->BitsPerPixel);
       return FALSE;
   }
 
@@ -437,27 +437,85 @@
   while (skip-- > 0)
     *Target++ = *Source;
 }
+ 
+static BOOLEAN
+FinalCopy32(PIXEL *Target, PIXEL *Source, PSPAN ClipSpans, UINT ClipSpansCount, UINT *SpanIndex,
+            UINT DestY, RECTL *DestRect)
+{
+  LONG Left, Right;
+  
+  while (ClipSpans[*SpanIndex].Y < DestY
+         || (ClipSpans[*SpanIndex].Y == DestY
+             && ClipSpans[*SpanIndex].X + ClipSpans[*SpanIndex].Width < DestRect->left))
+    {
+      (*SpanIndex)++;
+      if (ClipSpansCount <= *SpanIndex)
+        {
+          /* No more spans, everything else is clipped away, we're done */
+          return FALSE;
+        }
+    }
+  while (ClipSpans[*SpanIndex].Y == DestY)
+    {
+      if (ClipSpans[*SpanIndex].X < DestRect->right)
+        {
+          Left = max(ClipSpans[*SpanIndex].X, DestRect->left);
+          Right = min(ClipSpans[*SpanIndex].X + ClipSpans[*SpanIndex].Width, DestRect->right);
+          memcpy(Target + Left - DestRect->left, Source + Left - DestRect->left,
+                 (Right - Left) * sizeof(PIXEL));
+        }
+      (*SpanIndex)++;
+      if (ClipSpansCount <= *SpanIndex)
+        {
+          /* No more spans, everything else is clipped away, we're done */
+          return FALSE;
+        }
+    }
+
+  return TRUE;
+}
 
 //NOTE: If you change something here, please do the same in other dibXXbpp.c files!
-void ScaleRectAvg32(PIXEL *Target, PIXEL *Source, int SrcWidth, int SrcHeight,
-                  int TgtWidth, int TgtHeight, int srcPitch, int dstPitch)
-{
-  int NumPixels = TgtHeight;
-  int IntPart = ((SrcHeight / TgtHeight) * srcPitch) / 4; //(SrcHeight / TgtHeight) * SrcWidth;
-  int FractPart = SrcHeight % TgtHeight;
-  int Mid = TgtHeight >> 1;
+BOOLEAN ScaleRectAvg32(SURFGDI *DestGDI, SURFGDI *SourceGDI,
+                       RECTL* DestRect, RECTL *SourceRect,
+                       POINTL* MaskOrigin, POINTL BrushOrigin,
+                       CLIPOBJ *ClipRegion, XLATEOBJ *ColorTranslation,
+                       ULONG Mode)
+{
+  int NumPixels = DestRect->bottom - DestRect->top;
+  int IntPart = (((SourceRect->bottom - SourceRect->top) / (DestRect->bottom - DestRect->top)) * SourceGDI->SurfObj.lDelta) / 4; //((SourceRect->bottom - SourceRect->top) / (DestRect->bottom - DestRect->top)) * (SourceRect->right - SourceRect->left);
+  int FractPart = (SourceRect->bottom - SourceRect->top) % (DestRect->bottom - DestRect->top);
+  int Mid = (DestRect->bottom - DestRect->top) >> 1;
   int E = 0;
   int skip;
   PIXEL *ScanLine, *ScanLineAhead;
   PIXEL *PrevSource = NULL;
   PIXEL *PrevSourceAhead = NULL;
+  PIXEL *Target = (PIXEL *) (DestGDI->SurfObj.pvScan0 + (DestRect->top * DestGDI->SurfObj.lDelta) + 4 * DestRect->left);
+  PIXEL *Source = (PIXEL *) (SourceGDI->SurfObj.pvScan0 + (SourceRect->top * SourceGDI->SurfObj.lDelta) + 4 * SourceRect->left);
+  PSPAN ClipSpans;
+  UINT ClipSpansCount;
+  UINT SpanIndex;
+  LONG DestY;
   
-  skip = (TgtHeight < SrcHeight) ? 0 : (TgtHeight / (2*SrcHeight) + 1);
+  if (! ClipobjToSpans(&ClipSpans, &ClipSpansCount, ClipRegion, DestRect))
+    {
+      return FALSE;
+    }
+  if (0 == ClipSpansCount)
+    {
+      /* No clip spans == empty clipping region, everything clipped away */
+      ASSERT(NULL == ClipSpans);
+      return TRUE;
+    }
+  skip = (DestRect->bottom - DestRect->top < SourceRect->bottom - SourceRect->top) ? 0 : ((DestRect->bottom - DestRect->top) / (2 * (SourceRect->bottom - SourceRect->top)) + 1);
   NumPixels -= skip;
 
-  ScanLine = (PIXEL*)ExAllocatePool(NonPagedPool, TgtWidth*sizeof(PIXEL)); // FIXME: Should we use PagedPool here?
-  ScanLineAhead = (PIXEL *)ExAllocatePool(NonPagedPool, TgtWidth*sizeof(PIXEL));
+  ScanLine = (PIXEL*)ExAllocatePool(PagedPool, (DestRect->right - DestRect->left) * sizeof(PIXEL));
+  ScanLineAhead = (PIXEL *)ExAllocatePool(PagedPool, (DestRect->right - DestRect->left) * sizeof(PIXEL));
 
+  DestY = DestRect->top;
+  SpanIndex = 0;
   while (NumPixels-- > 0) {
     if (Source != PrevSource) {
       if (Source == PrevSourceAhead) {
@@ -469,38 +527,57 @@
         ScanLine = ScanLineAhead;
         ScanLineAhead = tmp;
       } else {
-        ScaleLineAvg32(ScanLine, Source, SrcWidth, TgtWidth);
+        ScaleLineAvg32(ScanLine, Source, SourceRect->right - SourceRect->left, DestRect->right - DestRect->left);
       } /* if */
       PrevSource = Source;
     } /* if */
     
-    if (E >= Mid && PrevSourceAhead != (PIXEL *)((BYTE *)Source + srcPitch)) {
+    if (E >= Mid && PrevSourceAhead != (PIXEL *)((BYTE *)Source + SourceGDI->SurfObj.lDelta)) {
       int x;
-      ScaleLineAvg32(ScanLineAhead, (PIXEL *)((BYTE *)Source + srcPitch), SrcWidth, TgtWidth);
-      for (x = 0; x < TgtWidth; x++)
+      ScaleLineAvg32(ScanLineAhead, (PIXEL *)((BYTE *)Source + SourceGDI->SurfObj.lDelta), SourceRect->right - SourceRect->left, DestRect->right - DestRect->left);
+      for (x = 0; x < DestRect->right - DestRect->left; x++)
         ScanLine[x] = average32(ScanLine[x], ScanLineAhead[x]);
-      PrevSourceAhead = (PIXEL *)((BYTE *)Source + srcPitch);
+      PrevSourceAhead = (PIXEL *)((BYTE *)Source + SourceGDI->SurfObj.lDelta);
     } /* if */
     
-    memcpy(Target, ScanLine, TgtWidth*sizeof(PIXEL));
-    Target = (PIXEL *)((BYTE *)Target + dstPitch);
+    if (! FinalCopy32(Target, ScanLine, ClipSpans, ClipSpansCount, &SpanIndex, DestY, DestRect))
+      {
+        /* No more spans, everything else is clipped away, we're done */
+        ExFreePool(ClipSpans);
+        ExFreePool(ScanLine);
+        ExFreePool(ScanLineAhead);
+        return TRUE;
+      }
+    DestY++;
+    Target = (PIXEL *)((BYTE *)Target + DestGDI->SurfObj.lDelta);
     Source += IntPart;
     E += FractPart;
-    if (E >= TgtHeight) {
-      E -= TgtHeight;
-      Source = (PIXEL *)((BYTE *)Source + srcPitch);
+    if (E >= DestRect->bottom - DestRect->top) {
+      E -= DestRect->bottom - DestRect->top;
+      Source = (PIXEL *)((BYTE *)Source + SourceGDI->SurfObj.lDelta);
     } /* if */
   } /* while */
 
   if (skip > 0 && Source != PrevSource)
-    ScaleLineAvg32(ScanLine, Source, SrcWidth, TgtWidth);
+    ScaleLineAvg32(ScanLine, Source, SourceRect->right - SourceRect->left, DestRect->right - DestRect->left);
   while (skip-- > 0) {
-    memcpy(Target, ScanLine, TgtWidth*sizeof(PIXEL));
-    Target = (PIXEL *)((BYTE *)Target + dstPitch);
+    if (! FinalCopy32(Target, ScanLine, ClipSpans, ClipSpansCount, &SpanIndex, DestY, DestRect))
+      {
+        /* No more spans, everything else is clipped away, we're done */
+        ExFreePool(ClipSpans);
+        ExFreePool(ScanLine);
+        ExFreePool(ScanLineAhead);
+        return TRUE;
+      }
+    DestY++;
+    Target = (PIXEL *)((BYTE *)Target + DestGDI->SurfObj.lDelta);
   } /* while */
 
+  ExFreePool(ClipSpans);
   ExFreePool(ScanLine);
   ExFreePool(ScanLineAhead);
+
+  return TRUE;
 }
 
 //NOTE: If you change something here, please do the same in other dibXXbpp.c files!
@@ -508,11 +585,10 @@
                             SURFGDI *DestGDI, SURFGDI *SourceGDI,
                             RECTL* DestRect, RECTL *SourceRect,
                             POINTL* MaskOrigin, POINTL BrushOrigin,
-			                XLATEOBJ *ColorTranslation, ULONG Mode)
+                            CLIPOBJ *ClipRegion, XLATEOBJ *ColorTranslation,
+                            ULONG Mode)
 {
-  BYTE *SourceLine, *DestLine;
-  
-  DbgPrint("DIB_32BPP_StretchBlt: Source BPP: %u, srcRect: (%d,%d)-(%d,%d), dstRect: (%d,%d)-(%d,%d)\n",
+  DPRINT("DIB_32BPP_StretchBlt: Source BPP: %u, srcRect: (%d,%d)-(%d,%d), dstRect: (%d,%d)-(%d,%d)\n",
      SourceGDI->BitsPerPixel, SourceRect->left, SourceRect->top, SourceRect->right, SourceRect->bottom,
      DestRect->left, DestRect->top, DestRect->right, DestRect->bottom);
 
@@ -539,15 +615,12 @@
       break;
       
       case 32:
-	    SourceLine = SourceSurf->pvScan0 + (SourceRect->top * SourceSurf->lDelta) + 4 * SourceRect->left;
-	    DestLine = DestSurf->pvScan0 + (DestRect->top * DestSurf->lDelta) + 4 * DestRect->left;
-        ScaleRectAvg32((PIXEL *)DestLine, (PIXEL *)SourceLine,
-           SourceRect->right-SourceRect->left, SourceRect->bottom-SourceRect->top, 
-           DestRect->right-DestRect->left, DestRect->bottom-DestRect->top, SourceSurf->lDelta, DestSurf->lDelta);
+        return ScaleRectAvg32(DestGDI, SourceGDI, DestRect, SourceRect, MaskOrigin, BrushOrigin,
+                              ClipRegion, ColorTranslation, Mode);
       break;
       
       default:
-      //DbgPrint("DIB_32BPP_StretchBlt: Unhandled Source BPP: %u\n", SourceGDI->BitsPerPixel);
+      //DPRINT1("DIB_32BPP_StretchBlt: Unhandled Source BPP: %u\n", SourceGDI->BitsPerPixel);
       return FALSE;
     }
 

reactos/subsys/win32k/dib
dib4bpp.c 1.34 -> 1.35
diff -u -r1.34 -r1.35
--- dib4bpp.c	10 May 2004 17:07:17 -0000	1.34
+++ dib4bpp.c	14 May 2004 22:56:17 -0000	1.35
@@ -16,7 +16,7 @@
  *  along with this program; if not, write to the Free Software
  *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
-/* $Id: dib4bpp.c,v 1.34 2004/05/10 17:07:17 weiden Exp $ */
+/* $Id: dib4bpp.c,v 1.35 2004/05/14 22:56:17 gvg Exp $ */
 #include <w32k.h>
 
 VOID
@@ -390,7 +390,8 @@
                             SURFGDI *DestGDI, SURFGDI *SourceGDI,
                             RECTL* DestRect, RECTL *SourceRect,
                             POINTL* MaskOrigin, POINTL BrushOrigin,
-			                XLATEOBJ *ColorTranslation, ULONG Mode)
+                            CLIPOBJ *ClipRegion, XLATEOBJ *ColorTranslation,
+                            ULONG Mode)
 {
   DbgPrint("DIB_4BPP_StretchBlt: Source BPP: %u\n", SourceGDI->BitsPerPixel);
   return FALSE;

reactos/subsys/win32k/dib
dib8bpp.c 1.25 -> 1.26
diff -u -r1.25 -r1.26
--- dib8bpp.c	10 May 2004 17:07:17 -0000	1.25
+++ dib8bpp.c	14 May 2004 22:56:17 -0000	1.26
@@ -16,7 +16,7 @@
  *  along with this program; if not, write to the Free Software
  *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
-/* $Id: dib8bpp.c,v 1.25 2004/05/10 17:07:17 weiden Exp $ */
+/* $Id: dib8bpp.c,v 1.26 2004/05/14 22:56:17 gvg Exp $ */
 #include <w32k.h>
 
 VOID
@@ -252,7 +252,7 @@
       break;
 
     default:
-      DbgPrint("DIB_8BPP_Bitblt: Unhandled Source BPP: %u\n", SourceGDI->BitsPerPixel);
+      DPRINT1("DIB_8BPP_Bitblt: Unhandled Source BPP: %u\n", SourceGDI->BitsPerPixel);
       return FALSE;
   }
 
@@ -432,26 +432,84 @@
     *Target++ = *Source;
 }
 
-//NOTE: If you change something here, please do the same in other dibXXbpp.c files!
-void ScaleRectAvg8(PIXEL *Target, PIXEL *Source, int SrcWidth, int SrcHeight,
-                  int TgtWidth, int TgtHeight, int srcPitch, int dstPitch)
+static BOOLEAN
+FinalCopy8(PIXEL *Target, PIXEL *Source, PSPAN ClipSpans, UINT ClipSpansCount, UINT *SpanIndex,
+           UINT DestY, RECTL *DestRect)
 {
-  int NumPixels = TgtHeight;
-  int IntPart = ((SrcHeight / TgtHeight) * srcPitch); //(SrcHeight / TgtHeight) * SrcWidth;
-  int FractPart = SrcHeight % TgtHeight;
-  int Mid = TgtHeight >> 1;
+  LONG Left, Right;
+  
+  while (ClipSpans[*SpanIndex].Y < DestY
+         || (ClipSpans[*SpanIndex].Y == DestY
+             && ClipSpans[*SpanIndex].X + ClipSpans[*SpanIndex].Width < DestRect->left))
+    {
+      (*SpanIndex)++;
+      if (ClipSpansCount <= *SpanIndex)
+        {
+          /* No more spans, everything else is clipped away, we're done */
+          return FALSE;
+        }
+    }
+  while (ClipSpans[*SpanIndex].Y == DestY)
+    {
+      if (ClipSpans[*SpanIndex].X < DestRect->right)
+        {
+          Left = max(ClipSpans[*SpanIndex].X, DestRect->left);
+          Right = min(ClipSpans[*SpanIndex].X + ClipSpans[*SpanIndex].Width, DestRect->right);
+          memcpy(Target + Left - DestRect->left, Source + Left - DestRect->left,
+                 (Right - Left) * sizeof(PIXEL));
+        }
+      (*SpanIndex)++;
+      if (ClipSpansCount <= *SpanIndex)
+        {
+          /* No more spans, everything else is clipped away, we're done */
+          return FALSE;
+        }
+    }
+
+  return TRUE;
+}
+
+//NOTE: If you change something here, please do the same in other dibXXbpp.c files!
+BOOLEAN ScaleRectAvg8(SURFGDI *DestGDI, SURFGDI *SourceGDI,
+                      RECTL* DestRect, RECTL *SourceRect,
+                      POINTL* MaskOrigin, POINTL BrushOrigin,
+                      CLIPOBJ *ClipRegion, XLATEOBJ *ColorTranslation,
+                      ULONG Mode)
+{
+  int NumPixels = DestRect->bottom - DestRect->top;
+  int IntPart = (((SourceRect->bottom - SourceRect->top) / (DestRect->bottom - DestRect->top)) * SourceGDI->SurfObj.lDelta); //((SourceRect->bottom - SourceRect->top) / (DestRect->bottom - DestRect->top)) * (SourceRect->right - SourceRect->left);
+  int FractPart = (SourceRect->bottom - SourceRect->top) % (DestRect->bottom - DestRect->top);
+  int Mid = (DestRect->bottom - DestRect->top) >> 1;
   int E = 0;
   int skip;
   PIXEL *ScanLine, *ScanLineAhead;
   PIXEL *PrevSource = NULL;
   PIXEL *PrevSourceAhead = NULL;
+  PIXEL *Target = (PIXEL *) (DestGDI->SurfObj.pvScan0 + (DestRect->top * DestGDI->SurfObj.lDelta) + DestRect->left);
+  PIXEL *Source = (PIXEL *) (SourceGDI->SurfObj.pvScan0 + (SourceRect->top * SourceGDI->SurfObj.lDelta) + SourceRect->left);
+  PSPAN ClipSpans;
+  UINT ClipSpansCount;
+  UINT SpanIndex;
+  LONG DestY;
 
-  skip = (TgtHeight < SrcHeight) ? 0 : (TgtHeight / (2*SrcHeight) + 1);
+  if (! ClipobjToSpans(&ClipSpans, &ClipSpansCount, ClipRegion, DestRect))
+    {
+      return FALSE;
+    }
+  if (0 == ClipSpansCount)
+    {
+      /* No clip spans == empty clipping region, everything clipped away */
+      ASSERT(NULL == ClipSpans);
+      return TRUE;
+    }
+  skip = (DestRect->bottom - DestRect->top < SourceRect->bottom - SourceRect->top) ? 0 : ((DestRect->bottom - DestRect->top) / (2 * (SourceRect->bottom - SourceRect->top)) + 1);
   NumPixels -= skip;
 
-  ScanLine = (PIXEL*)ExAllocatePool(NonPagedPool, TgtWidth*sizeof(PIXEL)); // FIXME: Should we use PagedPool here?
-  ScanLineAhead = (PIXEL *)ExAllocatePool(NonPagedPool, TgtWidth*sizeof(PIXEL));
+  ScanLine = (PIXEL*)ExAllocatePool(PagedPool, (DestRect->right - DestRect->left) * sizeof(PIXEL));
+  ScanLineAhead = (PIXEL *)ExAllocatePool(PagedPool, (DestRect->right - DestRect->left) * sizeof(PIXEL));
 
+  DestY = DestRect->top;
+  SpanIndex = 0;
   while (NumPixels-- > 0) {
     if (Source != PrevSource) {
       if (Source == PrevSourceAhead) {
@@ -463,49 +521,67 @@
         ScanLine = ScanLineAhead;
         ScanLineAhead = tmp;
       } else {
-        ScaleLineAvg8(ScanLine, Source, SrcWidth, TgtWidth);
+        ScaleLineAvg8(ScanLine, Source, SourceRect->right - SourceRect->left, DestRect->right - DestRect->left);
       } /* if */
       PrevSource = Source;
     } /* if */
     
-    if (E >= Mid && PrevSourceAhead != (PIXEL *)((BYTE *)Source + srcPitch)) {
+    if (E >= Mid && PrevSourceAhead != (PIXEL *)((BYTE *)Source + SourceGDI->SurfObj.lDelta)) {
       int x;
-      ScaleLineAvg8(ScanLineAhead, (PIXEL *)((BYTE *)Source + srcPitch), SrcWidth, TgtWidth);
-      for (x = 0; x < TgtWidth; x++)
+      ScaleLineAvg8(ScanLineAhead, (PIXEL *)((BYTE *)Source + SourceGDI->SurfObj.lDelta), SourceRect->right - SourceRect->left, DestRect->right - DestRect->left);
+      for (x = 0; x < DestRect->right - DestRect->left; x++)
         ScanLine[x] = average8(ScanLine[x], ScanLineAhead[x]);
-      PrevSourceAhead = (PIXEL *)((BYTE *)Source + srcPitch);
+      PrevSourceAhead = (PIXEL *)((BYTE *)Source + SourceGDI->SurfObj.lDelta);
     } /* if */
     
-    memcpy(Target, ScanLine, TgtWidth*sizeof(PIXEL));
-    Target = (PIXEL *)((BYTE *)Target + dstPitch);
+    if (! FinalCopy8(Target, ScanLine, ClipSpans, ClipSpansCount, &SpanIndex, DestY, DestRect))
+      {
+        /* No more spans, everything else is clipped away, we're done */
+        ExFreePool(ClipSpans);
+        ExFreePool(ScanLine);
+        ExFreePool(ScanLineAhead);
+        return TRUE;
+      }
+    DestY++;
+    Target = (PIXEL *)((BYTE *)Target + DestGDI->SurfObj.lDelta);
     Source += IntPart;
     E += FractPart;
-    if (E >= TgtHeight) {
-      E -= TgtHeight;
-      Source = (PIXEL *)((BYTE *)Source + srcPitch);
+    if (E >= DestRect->bottom - DestRect->top) {
+      E -= DestRect->bottom - DestRect->top;
+      Source = (PIXEL *)((BYTE *)Source + SourceGDI->SurfObj.lDelta);
     } /* if */
   } /* while */
 
   if (skip > 0 && Source != PrevSource)
-    ScaleLineAvg8(ScanLine, Source, SrcWidth, TgtWidth);
+    ScaleLineAvg8(ScanLine, Source, SourceRect->right - SourceRect->left, DestRect->right - DestRect->left);
   while (skip-- > 0) {
-    memcpy(Target, ScanLine, TgtWidth*sizeof(PIXEL));
-    Target = (PIXEL *)((BYTE *)Target + dstPitch);
+    if (! FinalCopy8(Target, ScanLine, ClipSpans, ClipSpansCount, &SpanIndex, DestY, DestRect))
+      {
+        /* No more spans, everything else is clipped away, we're done */
+        ExFreePool(ClipSpans);
+        ExFreePool(ScanLine);
+        ExFreePool(ScanLineAhead);
+        return TRUE;
+      }
+    DestY++;
+    Target = (PIXEL *)((BYTE *)Target + DestGDI->SurfObj.lDelta);
   } /* while */
 
+  ExFreePool(ClipSpans);
   ExFreePool(ScanLine);
   ExFreePool(ScanLineAhead);
+
+  return TRUE;
 }
 
 BOOLEAN DIB_8BPP_StretchBlt(SURFOBJ *DestSurf, SURFOBJ *SourceSurf,
                             SURFGDI *DestGDI, SURFGDI *SourceGDI,
                             RECTL* DestRect, RECTL *SourceRect,
                             POINTL* MaskOrigin, POINTL BrushOrigin,
-			                XLATEOBJ *ColorTranslation, ULONG Mode)
+                            CLIPOBJ *ClipRegion, XLATEOBJ *ColorTranslation,
+                            ULONG Mode)
 {
-  BYTE *SourceLine, *DestLine;
-  
-  DbgPrint("DIB_8BPP_StretchBlt: Source BPP: %u, srcRect: (%d,%d)-(%d,%d), dstRect: (%d,%d)-(%d,%d)\n",
+  DPRINT("DIB_8BPP_StretchBlt: Source BPP: %u, srcRect: (%d,%d)-(%d,%d), dstRect: (%d,%d)-(%d,%d)\n",
      SourceGDI->BitsPerPixel, SourceRect->left, SourceRect->top, SourceRect->right, SourceRect->bottom,
      DestRect->left, DestRect->top, DestRect->right, DestRect->bottom);
 
@@ -520,12 +596,8 @@
       break;
   
       case 8:
-	    SourceLine = SourceSurf->pvScan0 + (SourceRect->top * SourceSurf->lDelta) + SourceRect->left;
-	    DestLine = DestSurf->pvScan0 + (DestRect->top * DestSurf->lDelta) + DestRect->left;
-
-        ScaleRectAvg8((PIXEL *)DestLine, (PIXEL *)SourceLine,
-           SourceRect->right-SourceRect->left, SourceRect->bottom-SourceRect->top, 
-           DestRect->right-DestRect->left, DestRect->bottom-DestRect->top, SourceSurf->lDelta, DestSurf->lDelta);
+        return ScaleRectAvg8(DestGDI, SourceGDI, DestRect, SourceRect, MaskOrigin, BrushOrigin,
+                             ClipRegion, ColorTranslation, Mode);
       break;
 
       case 16:
@@ -541,7 +613,7 @@
       break;
       
       default:
-         DbgPrint("DIB_8BPP_StretchBlt: Unhandled Source BPP: %u\n", SourceGDI->BitsPerPixel);
+         DPRINT1("DIB_8BPP_StretchBlt: Unhandled Source BPP: %u\n", SourceGDI->BitsPerPixel);
       return FALSE;
     }
     

reactos/subsys/win32k/eng
bitblt.c 1.54 -> 1.55
diff -u -r1.54 -r1.55
--- bitblt.c	10 May 2004 17:07:17 -0000	1.54
+++ bitblt.c	14 May 2004 22:56:18 -0000	1.55
@@ -16,7 +16,7 @@
  *  along with this program; if not, write to the Free Software
  *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
-/* $Id: bitblt.c,v 1.54 2004/05/10 17:07:17 weiden Exp $
+/* $Id: bitblt.c,v 1.55 2004/05/14 22:56:18 gvg Exp $
  *
  * COPYRIGHT:        See COPYING in the top level directory
  * PROJECT:          ReactOS kernel
@@ -45,6 +45,7 @@
                                             SURFOBJ* InputObj,
                                             SURFGDI* InputGDI,
                                             SURFOBJ* Mask,
+                                            CLIPOBJ* ClipRegion,
                                             XLATEOBJ* ColorTranslation,
                                             RECTL* OutputRect,
                                             RECTL* InputRect,
@@ -593,6 +594,7 @@
                   SURFOBJ* InputObj,
                   SURFGDI* InputGDI,
                   SURFOBJ* Mask,
+	          CLIPOBJ* ClipRegion,
                   XLATEOBJ* ColorTranslation,
                   RECTL* OutputRect,
                   RECTL* InputRect,
@@ -609,7 +611,7 @@
     {
       RealBrushOrigin = *BrushOrigin;
     }
-  return OutputGDI->DIB_StretchBlt(OutputObj, InputObj, OutputGDI, InputGDI, OutputRect, InputRect, MaskOrigin, RealBrushOrigin, ColorTranslation, Mode);
+  return OutputGDI->DIB_StretchBlt(OutputObj, InputObj, OutputGDI, InputGDI, OutputRect, InputRect, MaskOrigin, RealBrushOrigin, ClipRegion, ColorTranslation, Mode);
 }
 
 
@@ -631,10 +633,6 @@
 {
   // www.osr.com/ddk/graphics/gdifncs_0bs7.htm
   
-  BYTE               clippingType;
-  RECTL              CombinedRect;
-//  RECT_ENUM          RectEnum;
-//  BOOL               EnumMore;
   SURFGDI*           OutputGDI;
   SURFGDI*           InputGDI;
   POINTL             InputPoint;
@@ -645,30 +643,26 @@
   INTENG_ENTER_LEAVE EnterLeaveDest;
   SURFOBJ*           InputObj;
   SURFOBJ*           OutputObj;
-  PSTRETCHRECTFUNC       BltRectFunc;
+  PSTRETCHRECTFUNC   BltRectFunc;
   BOOLEAN            Ret;
-  RECTL              ClipRect;
-//  unsigned           i;
-  POINTL             Pt;
-//  ULONG              Direction;
-  POINTL AdjustedBrushOrigin;
+  POINTL             AdjustedBrushOrigin;
 
-    InputRect.left = prclSrc->left;
-    InputRect.right = prclSrc->right;
-    InputRect.top = prclSrc->top;
-    InputRect.bottom = prclSrc->bottom;
+  InputRect.left = prclSrc->left;
+  InputRect.right = prclSrc->right;
+  InputRect.top = prclSrc->top;
+  InputRect.bottom = prclSrc->bottom;
 
   if (! IntEngEnter(&EnterLeaveSource, SourceObj, &InputRect, TRUE, &Translate, &InputObj))
     {
-    return FALSE;
+      return FALSE;
     }
 
-   InputPoint.x = InputRect.left + Translate.x;
-   InputPoint.y = InputRect.top + Translate.y;
+  InputPoint.x = InputRect.left + Translate.x;
+  InputPoint.y = InputRect.top + Translate.y;
  
   if (NULL != InputObj)
     {
-    InputGDI = (SURFGDI*) AccessInternalObjectFromUserObject(InputObj);
+      InputGDI = (SURFGDI*) AccessInternalObjectFromUserObject(InputObj);
     }
   else
     {
@@ -676,44 +670,19 @@
     }
 
   OutputRect = *prclDest;
-  if (NULL != ClipRegion)
-    {
-      if (OutputRect.left < ClipRegion->rclBounds.left)
-	{
-	  InputRect.left += ClipRegion->rclBounds.left - OutputRect.left;
-	  InputPoint.x += ClipRegion->rclBounds.left - OutputRect.left;
-	  OutputRect.left = ClipRegion->rclBounds.left;
-	}
-      if (ClipRegion->rclBounds.right < OutputRect.right)
-	{
-	  InputRect.right -=  OutputRect.right - ClipRegion->rclBounds.right;
-	  OutputRect.right = ClipRegion->rclBounds.right;
-	}
-      if (OutputRect.top < ClipRegion->rclBounds.top)
-	{
-	  InputRect.top += ClipRegion->rclBounds.top - OutputRect.top;
-	  InputPoint.y += ClipRegion->rclBounds.top - OutputRect.top;
-	  OutputRect.top = ClipRegion->rclBounds.top;
-	}
-      if (ClipRegion->rclBounds.bottom < OutputRect.bottom)
-	{
-	  InputRect.bottom -=  OutputRect.bottom - ClipRegion->rclBounds.bottom;
-	  OutputRect.bottom = ClipRegion->rclBounds.bottom;
-	}
-    }
 
   /* Check for degenerate case: if height or width of OutputRect is 0 pixels there's
      nothing to do */
   if (OutputRect.right <= OutputRect.left || OutputRect.bottom <= OutputRect.top)
     {
-    IntEngLeave(&EnterLeaveSource);
-    return TRUE;
+      IntEngLeave(&EnterLeaveSource);
+      return TRUE;
     }
 
   if (! IntEngEnter(&EnterLeaveDest, DestObj, &OutputRect, FALSE, &Translate, &OutputObj))
     {
-    IntEngLeave(&EnterLeaveSource);
-    return FALSE;
+      IntEngLeave(&EnterLeaveSource);
+      return FALSE;
     }
 
   OutputRect.left = prclDest->left + Translate.x;
@@ -721,28 +690,22 @@
   OutputRect.top = prclDest->top + Translate.y;
   OutputRect.bottom = prclDest->bottom + Translate.y;
   
-  if(BrushOrigin)
-  {
-    AdjustedBrushOrigin.x = BrushOrigin->x + Translate.x;
-    AdjustedBrushOrigin.y = BrushOrigin->y + Translate.y;
-  }
+  if (NULL != BrushOrigin)
+    {
+      AdjustedBrushOrigin.x = BrushOrigin->x + Translate.x;
+      AdjustedBrushOrigin.y = BrushOrigin->y + Translate.y;
+    }
   else
-    AdjustedBrushOrigin = Translate;
+    {
+      AdjustedBrushOrigin = Translate;
+    }
 
   if (NULL != OutputObj)
     {
-    OutputGDI = (SURFGDI*)AccessInternalObjectFromUserObject(OutputObj);
+      OutputGDI = (SURFGDI*)AccessInternalObjectFromUserObject(OutputObj);
     }
 
-  // Determine clipping type
-  if (ClipRegion == (CLIPOBJ *) NULL)
-  {
-    clippingType = DC_TRIVIAL;
-  } else {
-    clippingType = ClipRegion->iDComplexity;
-  }
-
-  if (Mask != NULL)//(0xaacc == Rop4)
+  if (Mask != NULL)
     {
       //BltRectFunc = BltMask;
       DPRINT("EngStretchBlt isn't capable of handling mask yet.\n");
@@ -757,70 +720,9 @@
     }
 
 
-  switch(clippingType)
-  {
-    case DC_TRIVIAL:
-      Ret = (*BltRectFunc)(OutputObj, OutputGDI, InputObj, InputGDI, Mask, ColorTranslation,
-                          &OutputRect, &InputRect, MaskOrigin, &AdjustedBrushOrigin, Mode);
-      break;
-    case DC_RECT:
-      // Clip the blt to the clip rectangle
-      ClipRect.left = ClipRegion->rclBounds.left + Translate.x;
-      ClipRect.right = ClipRegion->rclBounds.right + Translate.x;
-      ClipRect.top = ClipRegion->rclBounds.top + Translate.y;
-      ClipRect.bottom = ClipRegion->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 = (*BltRectFunc)(OutputObj, OutputGDI, InputObj, InputGDI, Mask, ColorTranslation,
-                           &OutputRect, &InputRect, MaskOrigin, &AdjustedBrushOrigin, Mode);
-      //Ret = (*BltRectFunc)(OutputObj, OutputGDI, InputObj, InputGDI, Mask, ColorTranslation,
-      //                     &CombinedRect, &Pt, MaskOrigin, Brush, BrushOrigin, Rop4);
-      DPRINT("EngStretchBlt() doesn't support DC_RECT clipping yet, so blitting w/o clip.\n");
-      break;
-      // TODO: Complex clipping
-    /*
-    case DC_COMPLEX:
-      Ret = TRUE;
-      if (OutputObj == InputObj)
-	{
-	  if (OutputRect.top < InputPoint.y)
-	    {
-	      Direction = OutputRect.left < InputPoint.x ? CD_RIGHTDOWN : CD_LEFTDOWN;
-	    }
-	  else
-	    {
-	      Direction = OutputRect.left < InputPoint.x ? CD_RIGHTUP : CD_LEFTUP;
-	    }
-	}
-      else
-	{
-	  Direction = CD_ANY;
-	}
-      CLIPOBJ_cEnumStart(ClipRegion, FALSE, CT_RECTANGLES, Direction, 0);
-      do
-	{
-	  EnumMore = CLIPOBJ_bEnum(ClipRegion,(ULONG) sizeof(RectEnum), (PVOID) &RectEnum);
-
-	  for (i = 0; i < RectEnum.c; i++)
-	    {
-	      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 = (*BltRectFunc)(OutputObj, OutputGDI, InputObj, InputGDI, Mask, ColorTranslation,
-	                           &CombinedRect, &Pt, MaskOrigin, Brush, &AdjustedBrushOrigin, Rop4) &&
-	            Ret;
-	    }
-	}
-      while(EnumMore);
-      break;
-      */
-  }
-
+  Ret = (*BltRectFunc)(OutputObj, OutputGDI, InputObj, InputGDI, Mask, ClipRegion,
+                       ColorTranslation, &OutputRect, &InputRect, MaskOrigin,
+                       &AdjustedBrushOrigin, Mode);
 
   IntEngLeave(&EnterLeaveDest);
   IntEngLeave(&EnterLeaveSource);
@@ -844,8 +746,6 @@
   BOOLEAN ret;
   SURFGDI *DestGDI;
   SURFGDI *SourceGDI;
-  RECTL OutputRect;
-  RECTL InputRect;
   COLORADJUSTMENT ca;
   POINT MaskOrigin;
 
@@ -854,43 +754,19 @@
       MaskOrigin.x = pMaskOrigin->x; MaskOrigin.y = pMaskOrigin->y;
     }
 
-  if (NULL != SourceRect)
-    {
-      InputRect = *SourceRect;
-    }
-
-  // FIXME: Clipping is taken from IntEngBitBlt w/o modifications!
-  
-  /* Clip against the bounds of the clipping region so we won't try to write
-   * outside the surface */
-  if (NULL != ClipRegion)
-    {
-      if (! EngIntersectRect(&OutputRect, DestRect, &ClipRegion->rclBounds))
-	{
-	  return TRUE;
-	}
-	  DPRINT("Clipping isn't handled in IntEngStretchBlt() correctly yet\n");
-      //InputPoint.x += OutputRect.left - DestRect->left;
-      //InputPoint.y += OutputRect.top - DestRect->top;
-    }
-  else
-    {
-      OutputRect = *DestRect;
-    }
-
   if (NULL != SourceObj)
     {
     SourceGDI = (SURFGDI*) AccessInternalObjectFromUserObject(SourceObj);
-    MouseSafetyOnDrawStart(SourceObj, SourceGDI, InputRect.left, InputRect.top,
-                           (InputRect.left + abs(InputRect.right - InputRect.left)),
-			   (InputRect.top + abs(InputRect.bottom - InputRect.top)));
+    MouseSafetyOnDrawStart(SourceObj, SourceGDI, SourceRect->left, SourceRect->top,
+                           (SourceRect->left + abs(SourceRect->right - SourceRect->left)),
+			   (SourceRect->top + abs(SourceRect->bottom - SourceRect->top)));
     }
 
   /* No success yet */
   ret = FALSE;
   DestGDI = (SURFGDI*)AccessInternalObjectFromUserObject(DestObj);
-  MouseSafetyOnDrawStart(DestObj, DestGDI, OutputRect.left, OutputRect.top,
-                         OutputRect.right, OutputRect.bottom);
+  MouseSafetyOnDrawStart(DestObj, DestGDI, DestRect->left, DestRect->top,
+                         DestRect->right, DestRect->bottom);
 
   /* Prepare color adjustment */
 
@@ -902,7 +778,7 @@
       // FIXME: MaskOrigin is always NULL !
       IntLockGDIDriver(DestGDI);
       ret = DestGDI->StretchBlt(DestObj, SourceObj, Mask, ClipRegion, ColorTranslation,
-                            &ca, BrushOrigin, &OutputRect, &InputRect, NULL, Mode);
+                            &ca, BrushOrigin, DestRect, SourceRect, NULL, Mode);
       IntUnLockGDIDriver(DestGDI);
     }
 
@@ -910,7 +786,7 @@
     {
       // FIXME: see previous fixme
       ret = EngStretchBlt(DestObj, SourceObj, Mask, ClipRegion, ColorTranslation,
-                          &ca, BrushOrigin, &OutputRect, &InputRect, NULL, Mode);
+                          &ca, BrushOrigin, DestRect, SourceRect, NULL, Mode);
     }
 
   MouseSafetyOnDrawEnd(DestObj, DestGDI);

reactos/subsys/win32k/eng
clip.c 1.20 -> 1.21
diff -u -r1.20 -r1.21
--- clip.c	10 May 2004 17:07:17 -0000	1.20
+++ clip.c	14 May 2004 22:56:18 -0000	1.21
@@ -16,7 +16,7 @@
  *  along with this program; if not, write to the Free Software
  *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
-/* $Id: clip.c,v 1.20 2004/05/10 17:07:17 weiden Exp $
+/* $Id: clip.c,v 1.21 2004/05/14 22:56:18 gvg Exp $
  * 
  * COPYRIGHT:         See COPYING in the top level directory
  * PROJECT:           ReactOS kernel
@@ -333,4 +333,123 @@
   return ClipGDI->EnumPos < ClipGDI->EnumRects.c;
 }
 
+static int 
+CompareSpans(const PSPAN Span1, const PSPAN Span2)
+{
+  int Cmp;
+
+  if (Span1->Y < Span2->Y)
+    {
+      Cmp = -1;
+    }
+  else if (Span2->Y < Span1->Y)
+    {
+      Cmp = +1;
+    }
+  else 
+    {
+      if (Span1->X < Span2->X)
+	{
+	  Cmp = -1;
+	}
+      else if (Span2->X < Span1->X)
+	{
+	  Cmp = +1;
+	}
+      else
+	{
+	  Cmp = 0;
+	}
+    }
+
+  return Cmp;
+}
+
+BOOLEAN FASTCALL
+ClipobjToSpans(PSPAN *Spans, UINT *Count, CLIPOBJ *ClipRegion, PRECTL Boundary)
+{
+  BOOL EnumMore;
+  UINT i, NewCount;
+  RECT_ENUM RectEnum;
+  PSPAN NewSpans;
+  RECTL *Rect;
+
+  ASSERT(Boundary->top <= Boundary->bottom && Boundary->left <= Boundary->right);
+
+  *Spans = NULL;
+  if (NULL == ClipRegion || DC_TRIVIAL == ClipRegion->iDComplexity)
+    {
+      *Count = Boundary->bottom - Boundary->top;
+      if (0 != *Count)
+        {
+          *Spans = ExAllocatePoolWithTag(PagedPool, *Count * sizeof(SPAN), TAG_CLIP);
+          if (NULL == *Spans)
+            {
+              *Count = 0;
+              return FALSE;
+            }
+          for (i = 0; i < Boundary->bottom - Boundary->top; i++)
+            {
+              (*Spans)[i].X = Boundary->left;
+              (*Spans)[i].Y = Boundary->top + i;
+              (*Spans)[i].Width = Boundary->right - Boundary->left;
+            }
+        }
+
+      return TRUE;
+    }
+
+  *Count = 0;
+  CLIPOBJ_cEnumStart(ClipRegion, FALSE, CT_RECTANGLES, CD_ANY, 0);
+  do
+    {
+      EnumMore = CLIPOBJ_bEnum(ClipRegion, (ULONG) sizeof(RECT_ENUM), (PVOID) &RectEnum);
+
+      NewCount = *Count;
+      for (i = 0; i < RectEnum.c; i++)
+        {
+          NewCount += RectEnum.arcl[i].bottom - RectEnum.arcl[i].top;
+        }
+      if (NewCount != *Count)
+        {
+          NewSpans = ExAllocatePoolWithTag(PagedPool, NewCount * sizeof(SPAN), TAG_CLIP);
+          if (NULL == NewSpans)
+            {
+              if (NULL != *Spans)
+                {
+                  ExFreePool(*Spans);
+                  *Spans = NULL;
+                }
+              *Count = 0;
+              return FALSE;
+            }
+          if (0 != *Count)
+            {
+              RtlCopyMemory(NewSpans, *Spans, *Count * sizeof(SPAN));
+              ExFreePool(*Spans);
+            }
+          *Spans = NewSpans;
+        }
+      for (Rect = RectEnum.arcl; Rect < RectEnum.arcl + RectEnum.c; Rect++)
+        {
+          for (i = 0; i < Rect->bottom - Rect->top; i++)
+            {
+              (*Spans)[*Count].X = Rect->left;
+              (*Spans)[*Count].Y = Rect->top + i;
+              (*Spans)[*Count].Width = Rect->right - Rect->left;
+              (*Count)++;
+            }
+        }
+      ASSERT(*Count == NewCount);
+    }
+  while (EnumMore);
+
+  if (0 != *Count)
+    {
+      EngSort((PBYTE) *Spans, sizeof(SPAN), *Count, (SORTCOMP) CompareSpans);
+    }
+
+  return TRUE;
+}
+
 /* EOF */

reactos/subsys/win32k/eng
clip.h 1.6 -> 1.7
diff -u -r1.6 -r1.7
--- clip.h	9 Apr 2004 20:03:16 -0000	1.6
+++ clip.h	14 May 2004 22:56:18 -0000	1.7
@@ -32,4 +32,13 @@
   RECTL arcl[ENUM_RECT_LIMIT];
 } RECT_ENUM;
 
+typedef struct tagSPAN
+{
+  LONG Y;
+  LONG X;
+  ULONG Width;
+} SPAN, *PSPAN;
+
+BOOLEAN FASTCALL ClipobjToSpans(PSPAN *Spans, UINT *Count, CLIPOBJ *ClipRegion, PRECTL Boundary);
+
 #endif

reactos/subsys/win32k/eng
surface.c 1.38 -> 1.39
diff -u -r1.38 -r1.39
--- surface.c	10 May 2004 17:07:17 -0000	1.38
+++ surface.c	14 May 2004 22:56:18 -0000	1.39
@@ -16,7 +16,7 @@
  *  along with this program; if not, write to the Free Software
  *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
-/* $Id: surface.c,v 1.38 2004/05/10 17:07:17 weiden Exp $
+/* $Id: surface.c,v 1.39 2004/05/14 22:56:18 gvg Exp $
  * 
  * COPYRIGHT:         See COPYING in the top level directory
  * PROJECT:           ReactOS kernel
@@ -110,7 +110,8 @@
                                 SURFGDI *DestGDI,  SURFGDI *SourceGDI,
                                 RECTL*  DestRect,  RECTL  *SourceRect,
                                 POINTL* MaskOrigin, POINTL BrushOrign,
-                                XLATEOBJ *ColorTranslation, ULONG Mode)
+                                CLIPOBJ *ClipRegion, XLATEOBJ *ColorTranslation,
+                                ULONG Mode)
 {
   return FALSE;
 }

reactos/subsys/win32k/include
tags.h 1.2 -> 1.3
diff -u -r1.2 -r1.3
--- tags.h	22 Feb 2004 12:06:42 -0000	1.2
+++ tags.h	14 May 2004 22:56:18 -0000	1.3
@@ -26,6 +26,7 @@
 #define TAG_BEZIER	TAG('B', 'E', 'Z', 'R') /* bezier */
 #define TAG_BITMAP	TAG('B', 'T', 'M', 'P') /* bitmap */
 #define TAG_PATBLT	TAG('P', 'B', 'L', 'T') /* patblt */
+#define TAG_CLIP	TAG('C', 'L', 'I', 'P') /* clipping */
 #define TAG_COORD	TAG('C', 'O', 'R', 'D') /* coords */
 #define TAG_DC		TAG('D', 'C', 'D', 'C') /* dc */
 #define TAG_GDIOBJ	TAG('G', 'D', 'I', 'O') /* gdi obj */
CVSspam 0.2.8