#include "brush.h"
#include "clip.h"
#include "objects.h"
+#include "../dib/dib.h"
+#include "misc.h"
#include <include/mouse.h>
#include <include/object.h>
#include <include/dib.h>
#include <include/surface.h>
#include <include/copybits.h>
+#include <include/inteng.h>
+
+#define NDEBUG
+#include <win32k/debug1.h>
BOOL EngIntersectRect(PRECTL prcDst, PRECTL prcSrc1, PRECTL prcSrc2)
{
return(FALSE);
}
+static BOOL STDCALL
+BltMask(SURFOBJ *Dest, PSURFGDI DestGDI, SURFOBJ *Mask,
+ RECTL *DestRect, POINTL *MaskPoint, BRUSHOBJ* Brush,
+ POINTL* BrushPoint)
+{
+ LONG i, j, dx, dy, c8;
+ BYTE *tMask, *lMask;
+ static BYTE maskbit[8] = { 0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01 };
+
+ dx = DestRect->right - DestRect->left;
+ dy = DestRect->bottom - DestRect->top;
+
+ if (Mask != NULL)
+ {
+ tMask = Mask->pvBits;
+ for (j = 0; j < dy; j++)
+ {
+ lMask = tMask;
+ c8 = 0;
+ for (i = 0; i < dx; i++)
+ {
+ if (0 != (*lMask & maskbit[c8]))
+ {
+ DestGDI->DIB_PutPixel(Dest, DestRect->left + i, DestRect->top + j, Brush->iSolidColor);
+ }
+ c8++;
+ if (8 == c8)
+ {
+ lMask++;
+ c8=0;
+ }
+ }
+ tMask += Mask->lDelta;
+ }
+ return TRUE;
+ }
+ else
+ {
+ return FALSE;
+ }
+}
+
+static BOOL STDCALL
+BltPatCopy(SURFOBJ *Dest, PSURFGDI DestGDI, SURFOBJ *Mask,
+ RECTL *DestRect, POINTL *MaskPoint, BRUSHOBJ* Brush,
+ POINTL* BrushPoint)
+{
+ // These functions are assigned if we're working with a DIB
+ // The assigned functions depend on the bitsPerPixel of the DIB
+ LONG y;
+ ULONG LineWidth;
+
+ LineWidth = DestRect->right - DestRect->left;
+ for (y = DestRect->top; y < DestRect->bottom; y++)
+ {
+ DestGDI->DIB_HLine(Dest, DestRect->left, DestRect->right, y, Brush->iSolidColor);
+ }
+
+ return TRUE;
+}
+
INT abs(INT nm);
BOOL STDCALL
-EngBitBlt(SURFOBJ *Dest,
- SURFOBJ *Source,
+EngBitBlt(SURFOBJ *DestObj,
+ SURFOBJ *SourceObj,
SURFOBJ *Mask,
CLIPOBJ *ClipRegion,
XLATEOBJ *ColorTranslation,
RECTL *DestRect,
POINTL *SourcePoint,
- POINTL *MaskRect,
+ POINTL *MaskOrigin,
BRUSHOBJ *Brush,
POINTL *BrushOrigin,
ROP4 rop4)
{
- BOOLEAN ret;
- BYTE clippingType;
- RECTL rclTmp;
- POINTL ptlTmp;
- RECT_ENUM RectEnum;
- BOOL EnumMore;
- PSURFGDI DestGDI, SourceGDI;
- HSURF hTemp;
- PSURFOBJ TempSurf = NULL;
- BOOLEAN canCopyBits;
- POINTL TempPoint;
- RECTL TempRect;
- SIZEL TempSize;
-
- if(Source != NULL) SourceGDI = (PSURFGDI)AccessInternalObjectFromUserObject(Source);
- if(Dest != NULL) DestGDI = (PSURFGDI)AccessInternalObjectFromUserObject(Dest);
-
- if (Source != NULL)
+ BOOLEAN ret;
+ BYTE clippingType;
+ RECTL rclTmp;
+ POINTL ptlTmp;
+ RECT_ENUM RectEnum;
+ BOOL EnumMore;
+ PSURFGDI OutputGDI, InputGDI;
+ POINTL InputPoint;
+ RECTL InputRect;
+ RECTL OutputRect;
+ POINTL Translate;
+ INTENG_ENTER_LEAVE EnterLeaveSource;
+ INTENG_ENTER_LEAVE EnterLeaveDest;
+ PSURFOBJ InputObj;
+ PSURFOBJ OutputObj;
+
+ /* Check for degenerate case: if height or width of DestRect is 0 pixels there's
+ nothing to do */
+ if (DestRect->right == DestRect->left || DestRect->bottom == DestRect->top)
{
- MouseSafetyOnDrawStart(Source, SourceGDI, SourcePoint->x, SourcePoint->y,
- (SourcePoint->x + abs(DestRect->right - DestRect->left)),
- (SourcePoint->y + abs(DestRect->bottom - DestRect->top)));
+ return TRUE;
}
- MouseSafetyOnDrawStart(Dest, DestGDI, DestRect->left, DestRect->top, DestRect->right, DestRect->bottom);
- // If we don't have to do anything special, we can punt to DrvCopyBits
- // if it exists
- if( (Mask == NULL) && (MaskRect == NULL) && (Brush == NULL) &&
- (BrushOrigin == NULL) && (rop4 == 0) )
- {
- canCopyBits = TRUE;
- } else
- canCopyBits = FALSE;
-
- // Check for CopyBits or BitBlt hooks if one is not a GDI managed bitmap, IF:
- // * The destination bitmap is not managed by the GDI OR
- if(Dest->iType != STYPE_BITMAP)
- {
- // Destination surface is device managed
- if (DestGDI->BitBlt!=NULL)
+ if (NULL != SourcePoint)
{
- if (Source!=NULL)
- {
- // Get the source into a format compatible surface
- TempPoint.x = 0;
- TempPoint.y = 0;
- TempRect.top = 0;
- TempRect.left = 0;
- TempRect.bottom = DestRect->bottom - DestRect->top;
- TempRect.right = DestRect->right - DestRect->left;
- TempSize.cx = TempRect.right;
- TempSize.cy = TempRect.bottom;
-
- hTemp = EngCreateBitmap(TempSize,
- DIB_GetDIBWidthBytes(DestRect->right - DestRect->left, BitsPerFormat(Dest->iBitmapFormat)),
- Dest->iBitmapFormat, 0, NULL);
- TempSurf = (PSURFOBJ)AccessUserObject((ULONG)hTemp);
-
- // FIXME: Skip creating a TempSurf if we have the same BPP and palette
- EngBitBlt(TempSurf, Source, NULL, NULL, ColorTranslation, &TempRect, SourcePoint, NULL, NULL, NULL, 0);
- }
-
- ret = DestGDI->BitBlt(Dest, TempSurf, Mask, ClipRegion,
- NULL, DestRect, &TempPoint,
- MaskRect, Brush, BrushOrigin, rop4);
-
- MouseSafetyOnDrawEnd(Source, SourceGDI);
- MouseSafetyOnDrawEnd(Dest, DestGDI);
-
- return ret;
+ InputRect.left = SourcePoint->x;
+ InputRect.right = SourcePoint->x + (DestRect->right - DestRect->left);
+ InputRect.top = SourcePoint->y;
+ InputRect.bottom = SourcePoint->y + (DestRect->bottom - DestRect->top);
+ }
+ else
+ {
+ InputRect.left = 0;
+ InputRect.right = DestRect->right - DestRect->left;
+ InputRect.top = 0;
+ InputRect.bottom = DestRect->bottom - DestRect->top;
}
- }
- /* The code currently assumes there will be a source bitmap. This is not true when, for example, using this function to
- * paint a brush pattern on the destination. */
- if(!Source)
- {
- DbgPrint("EngBitBlt: A source is currently required, even though not all operations require one (FIXME)\n");
+ if (! IntEngEnter(&EnterLeaveSource, SourceObj, &InputRect, TRUE, &Translate, &InputObj))
+ {
return FALSE;
- }
+ }
- // * The source bitmap is not managed by the GDI and we didn't already obtain it using EngCopyBits from the device
- if(Source->iType != STYPE_BITMAP && SourceGDI->CopyBits == NULL)
- {
- if (SourceGDI->BitBlt!=NULL)
+ if (NULL != SourcePoint)
+ {
+ InputPoint.x = SourcePoint->x + Translate.x;
+ InputPoint.y = SourcePoint->y + Translate.y;
+ }
+ else
+ {
+ InputPoint.x = 0;
+ InputPoint.y = 0;
+ }
+
+ if (NULL != InputObj)
{
- // Request the device driver to return the bitmap in a format compatible with the device
- ret = SourceGDI->BitBlt(Dest, Source, Mask, ClipRegion,
- NULL, DestRect, SourcePoint,
- MaskRect, Brush, BrushOrigin, rop4);
+ InputGDI = (PSURFGDI) AccessInternalObjectFromUserObject(InputObj);
+ }
- MouseSafetyOnDrawEnd(Source, SourceGDI);
- MouseSafetyOnDrawEnd(Dest, DestGDI);
+ OutputRect = *DestRect;
- return ret;
+ if (! IntEngEnter(&EnterLeaveDest, DestObj, &OutputRect, FALSE, &Translate, &OutputObj))
+ {
+ IntEngLeave(&EnterLeaveSource);
+ return FALSE;
+ }
+
+ OutputRect.left = DestRect->left + Translate.x;
+ OutputRect.right = DestRect->right + Translate.x;
+ OutputRect.top = DestRect->top + Translate.y;
+ OutputRect.bottom = DestRect->bottom + Translate.y;
- // Convert the surface from the driver into the required destination surface
+
+ if (NULL != OutputObj)
+ {
+ OutputGDI = (PSURFGDI)AccessInternalObjectFromUserObject(OutputObj);
}
+
+ /* The code currently assumes there will be a source bitmap. This is not true when, for example, using this function to
+ * paint a brush pattern on the destination. */
+ if (NULL == InputObj && 0xaacc != rop4 && PATCOPY != rop4)
+ {
+ DbgPrint("EngBitBlt: A source is currently required, even though not all operations require one (FIXME)\n");
+ return FALSE;
}
// Determine clipping type
clippingType = ClipRegion->iDComplexity;
}
+ if (0xaacc == rop4)
+ {
+ ret = BltMask(OutputObj, OutputGDI, Mask, &OutputRect, MaskOrigin, Brush, BrushOrigin);
+ IntEngLeave(&EnterLeaveDest);
+ IntEngLeave(&EnterLeaveSource);
+ return ret;
+ } else if (PATCOPY == rop4) {
+ ret = BltPatCopy(OutputObj, OutputGDI, Mask, &OutputRect, MaskOrigin, Brush, BrushOrigin);
+ IntEngLeave(&EnterLeaveDest);
+ IntEngLeave(&EnterLeaveSource);
+ return ret;
+ }
+
+
// We don't handle color translation just yet [we dont have to.. REMOVE REMOVE REMOVE]
switch(clippingType)
{
case DC_TRIVIAL:
- CopyBitsCopy(Dest, Source, DestGDI, SourceGDI, DestRect, SourcePoint, Source->lDelta, ColorTranslation);
+ OutputGDI->DIB_BitBlt(OutputObj, InputObj, OutputGDI, InputGDI, &OutputRect, &InputPoint, ColorTranslation);
- MouseSafetyOnDrawEnd(Source, SourceGDI);
- MouseSafetyOnDrawEnd(Dest, DestGDI);
+ IntEngLeave(&EnterLeaveDest);
+ IntEngLeave(&EnterLeaveSource);
return(TRUE);
case DC_RECT:
// Clip the blt to the clip rectangle
- EngIntersectRect(&rclTmp, DestRect, &ClipRegion->rclBounds);
+ EngIntersectRect(&rclTmp, &OutputRect, &ClipRegion->rclBounds);
- ptlTmp.x = SourcePoint->x + rclTmp.left - DestRect->left;
- ptlTmp.y = SourcePoint->y + rclTmp.top - DestRect->top;
+ ptlTmp.x = InputPoint.x + rclTmp.left - OutputRect.left;
+ ptlTmp.y = InputPoint.y + rclTmp.top - OutputRect.top;
- MouseSafetyOnDrawEnd(Source, SourceGDI);
- MouseSafetyOnDrawEnd(Dest, DestGDI);
+ IntEngLeave(&EnterLeaveDest);
+ IntEngLeave(&EnterLeaveSource);
return(TRUE);
RECTL* prcl = &RectEnum.arcl[0];
do {
- EngIntersectRect(prcl, prcl, DestRect);
+ EngIntersectRect(prcl, prcl, &OutputRect);
- ptlTmp.x = SourcePoint->x + prcl->left - DestRect->left;
- ptlTmp.y = SourcePoint->y + prcl->top - DestRect->top;
+ ptlTmp.x = InputPoint.x + prcl->left - OutputRect.left;
+ ptlTmp.y = InputPoint.y + prcl->top - OutputRect.top;
prcl++;
} while(EnumMore);
- MouseSafetyOnDrawEnd(Source, SourceGDI);
- MouseSafetyOnDrawEnd(Dest, DestGDI);
+ IntEngLeave(&EnterLeaveDest);
+ IntEngLeave(&EnterLeaveSource);
return(TRUE);
}
- MouseSafetyOnDrawEnd(Source, SourceGDI);
- MouseSafetyOnDrawEnd(Dest, DestGDI);
+ IntEngLeave(&EnterLeaveDest);
+ IntEngLeave(&EnterLeaveSource);
return(FALSE);
}
+
+BOOL STDCALL
+IntEngBitBlt(SURFOBJ *DestObj,
+ SURFOBJ *SourceObj,
+ SURFOBJ *Mask,
+ CLIPOBJ *ClipRegion,
+ XLATEOBJ *ColorTranslation,
+ RECTL *DestRect,
+ POINTL *SourcePoint,
+ POINTL *MaskOrigin,
+ BRUSHOBJ *Brush,
+ POINTL *BrushOrigin,
+ ROP4 rop4)
+{
+ BOOLEAN ret;
+ SURFGDI *DestGDI;
+ SURFGDI *SourceGDI;
+
+ if (NULL != SourceObj)
+ {
+ SourceGDI = (PSURFGDI) AccessInternalObjectFromUserObject(SourceObj);
+ MouseSafetyOnDrawStart(SourceObj, SourceGDI, SourcePoint->x, SourcePoint->y,
+ (SourcePoint->x + abs(DestRect->right - DestRect->left)),
+ (SourcePoint->y + abs(DestRect->bottom - DestRect->top)));
+ }
+
+ /* No success yet */
+ ret = FALSE;
+ DestGDI = (SURFGDI*)AccessInternalObjectFromUserObject(DestObj);
+ MouseSafetyOnDrawStart(DestObj, DestGDI, DestRect->left, DestRect->top,
+ DestRect->right, DestRect->bottom);
+
+ /* Call the driver's DrvBitBlt if available */
+ if (NULL != DestGDI->BitBlt) {
+ ret = DestGDI->BitBlt(DestObj, SourceObj, Mask, ClipRegion, ColorTranslation,
+ DestRect, SourcePoint, MaskOrigin, Brush, BrushOrigin, rop4);
+ }
+
+ if (! ret) {
+ ret = EngBitBlt(DestObj, SourceObj, Mask, ClipRegion, ColorTranslation,
+ DestRect, SourcePoint, MaskOrigin, Brush, BrushOrigin, rop4);
+ }
+
+ MouseSafetyOnDrawEnd(DestObj, DestGDI);
+ if (NULL != SourceObj)
+ {
+ MouseSafetyOnDrawEnd(SourceObj, SourceGDI);
+ }
+
+ return ret;
+}