came across small potential kmode crash while researching another bug fix
[reactos.git] / reactos / subsys / win32k / eng / bitblt.c
index ae12887..ae50b2e 100644 (file)
@@ -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.57 2004/07/03 17:40:25 navaraf Exp $
+/* $Id: bitblt.c,v 1.62 2004/12/14 03:23:14 royce Exp $
  *
  * COPYRIGHT:        See COPYING in the top level directory
  * PROJECT:          ReactOS kernel
@@ -88,9 +88,10 @@ BltMask(SURFOBJ* Dest,
    BYTE *tMask, *lMask;
    static BYTE maskbit[8] = { 0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01 };
    /* Pattern brushes */
-   PGDIBRUSHOBJ GdiBrush = NULL;
+   PGDIBRUSHINST GdiBrush = NULL;
    HBITMAP PatternSurface = NULL;
    SURFOBJ *PatternObj = NULL;
+   PBITMAPOBJ PatternBitmap;
    ULONG PatternWidth = 0, PatternHeight = 0, PatternY = 0;
   
    if (Mask == NULL)
@@ -103,20 +104,22 @@ BltMask(SURFOBJ* Dest,
 
    if (Brush->iSolidColor == 0xFFFFFFFF)
    {
-      PBITMAPOBJ PatternBitmap;
-
       GdiBrush = CONTAINING_RECORD(
          Brush,
-         GDIBRUSHOBJ,
+         GDIBRUSHINST,
          BrushObject);
 
-      PatternSurface = GdiBrush->hbmPattern;
-      PatternBitmap = BITMAPOBJ_LockBitmap(GdiBrush->hbmPattern);
-
-      PatternObj = &PatternBitmap->SurfObj;
-      PatternWidth = PatternObj->sizlBitmap.cx;
-      PatternHeight = PatternObj->sizlBitmap.cy;
+      PatternSurface = GdiBrush->GdiBrushObject->hbmPattern;
+      PatternBitmap = BITMAPOBJ_LockBitmap(GdiBrush->GdiBrushObject->hbmPattern);
+      if(PatternBitmap != NULL)
+      {
+        PatternObj = &PatternBitmap->SurfObj;
+        PatternWidth = PatternObj->sizlBitmap.cx;
+        PatternHeight = PatternObj->sizlBitmap.cy;
+      }
    }
+   else
+     PatternBitmap = NULL;
 
    tMask = Mask->pvScan0 + SourcePoint->y * Mask->lDelta + (SourcePoint->x >> 3);
    for (j = 0; j < dy; j++)
@@ -124,14 +127,14 @@ BltMask(SURFOBJ* Dest,
       lMask = tMask;
       c8 = SourcePoint->x & 0x07;
       
-      if(PatternSurface)
+      if(PatternBitmap != NULL)
          PatternY = (DestRect->top + j) % PatternHeight;
       
       for (i = 0; i < dx; i++)
       {
          if (0 != (*lMask & maskbit[c8]))
          {
-            if (PatternSurface == NULL)
+            if (PatternBitmap == NULL)
             {
                DibFunctionsForBitmapFormat[Dest->iBitmapFormat].DIB_PutPixel(
                   Dest, DestRect->left + i, DestRect->top + j, Brush->iSolidColor);
@@ -140,7 +143,7 @@ BltMask(SURFOBJ* Dest,
             {
                DibFunctionsForBitmapFormat[Dest->iBitmapFormat].DIB_PutPixel(
                   Dest, DestRect->left + i, DestRect->top + j,
-                  DIB_1BPP_GetPixel(PatternObj, (DestRect->left + i) % PatternWidth, PatternY) ? GdiBrush->crFore : GdiBrush->crBack);
+                  DIB_GetSource(PatternObj, (DestRect->left + i) % PatternWidth, PatternY, GdiBrush->XlateObject));
             }
          }
          c8++;
@@ -153,7 +156,7 @@ BltMask(SURFOBJ* Dest,
       tMask += Mask->lDelta;
    }
 
-   if (PatternSurface != NULL)
+   if (PatternBitmap != NULL)
       BITMAPOBJ_UnlockBitmap(PatternSurface);
 
    return TRUE;
@@ -198,18 +201,54 @@ CallDibBitBlt(SURFOBJ* OutputObj,
               POINTL* BrushOrigin,
               ROP4 Rop4)
 {
-  POINTL RealBrushOrigin;
-  if (BrushOrigin == NULL)
-    {
-      RealBrushOrigin.x = RealBrushOrigin.y = 0;
-    }
-  else
-    {
-      RealBrushOrigin = *BrushOrigin;
-    }
+   BLTINFO BltInfo;
+   PGDIBRUSHINST GdiBrush = NULL;
+   BITMAPOBJ *bmPattern;
+   BOOLEAN Result;
+
+   BltInfo.DestSurface = OutputObj;
+   BltInfo.SourceSurface = InputObj;
+   BltInfo.PatternSurface = NULL;
+   BltInfo.XlateSourceToDest = ColorTranslation;
+   BltInfo.DestRect = *OutputRect;
+   BltInfo.SourcePoint = *InputPoint;
+
+   if (Rop4 == SRCCOPY)
+      return DibFunctionsForBitmapFormat[OutputObj->iBitmapFormat].DIB_BitBltSrcCopy(&BltInfo);
+
+   BltInfo.XlatePatternToDest = NULL;
+   BltInfo.Brush = Brush;
+   BltInfo.BrushOrigin = *BrushOrigin;
+   BltInfo.Rop4 = Rop4;
+
+   /* Pattern brush */
+   if (ROP_USES_PATTERN(Rop4) && Brush->iSolidColor == 0xFFFFFFFF)
+   {
+      GdiBrush = CONTAINING_RECORD(Brush, GDIBRUSHINST, BrushObject);
+      if((bmPattern = BITMAPOBJ_LockBitmap(GdiBrush->GdiBrushObject->hbmPattern)))
+      {
+        BltInfo.PatternSurface = &bmPattern->SurfObj;
+      }
+      else
+      {
+        /* FIXME - What to do here? */
+      }
+      BltInfo.XlatePatternToDest = GdiBrush->XlateObject;
+   }
+   else
+   {
+     bmPattern = NULL;
+   }
+
+   Result = DibFunctionsForBitmapFormat[OutputObj->iBitmapFormat].DIB_BitBlt(&BltInfo);
+
+   /* Pattern brush */
+   if (bmPattern != NULL)
+   {
+      BITMAPOBJ_UnlockBitmap(BltInfo.PatternSurface->hsurf);
+   }
 
-  return DibFunctionsForBitmapFormat[OutputObj->iBitmapFormat].DIB_BitBlt(
-    OutputObj, InputObj, OutputRect, InputPoint, Brush, RealBrushOrigin, ColorTranslation, Rop4);
+   return Result;
 }
 
 INT abs(INT nm);
@@ -475,7 +514,7 @@ IntEngBitBlt(BITMAPOBJ *DestObj,
   UsesSource = ((Rop4 & 0xCC0000) >> 2) != (Rop4 & 0x330000);
   if (UsesSource)
     {
-      if (NULL == SourcePoint || NULL == SourceObj)
+      if (NULL == SourcePoint || NULL == SourceSurf)
         {
           return FALSE;
         }
@@ -715,8 +754,7 @@ IntEngStretchBlt(BITMAPOBJ *DestObj,
   if (NULL != SourceObj)
     {
     MouseSafetyOnDrawStart(SourceSurf, SourceRect->left, SourceRect->top,
-                           (SourceRect->left + abs(SourceRect->right - SourceRect->left)),
-                          (SourceRect->top + abs(SourceRect->bottom - SourceRect->top)));
+                           SourceRect->right, SourceRect->bottom);
     }
 
   /* No success yet */