* 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.47 2004/04/07 19:57:43 navaraf Exp $
+/* $Id$
*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
* REVISION HISTORY:
* 2/10/1999: Created
*/
-
-#include <ddk/winddi.h>
-#include <ddk/ntddk.h>
-#include <ddk/ntddmou.h>
-#include <ntos/minmax.h>
-#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/eng.h>
-#include <include/inteng.h>
-
-#define NDEBUG
-#include <win32k/debug1.h>
+#include <w32k.h>
typedef BOOLEAN STDCALL (*PBLTRECTFUNC)(SURFOBJ* OutputObj,
- SURFGDI* OutputGDI,
SURFOBJ* InputObj,
- SURFGDI* InputGDI,
SURFOBJ* Mask,
XLATEOBJ* ColorTranslation,
RECTL* OutputRect,
POINTL* BrushOrigin,
ROP4 Rop4);
typedef BOOLEAN STDCALL (*PSTRETCHRECTFUNC)(SURFOBJ* OutputObj,
- SURFGDI* OutputGDI,
SURFOBJ* InputObj,
- SURFGDI* InputGDI,
SURFOBJ* Mask,
+ CLIPOBJ* ClipRegion,
XLATEOBJ* ColorTranslation,
RECTL* OutputRect,
RECTL* InputRect,
static BOOLEAN STDCALL
BltMask(SURFOBJ* Dest,
- SURFGDI* DestGDI,
SURFOBJ* Source,
- SURFGDI* SourceGDI,
- SURFOBJ* Mask,
+ SURFOBJ* Mask,
XLATEOBJ* ColorTranslation,
RECTL* DestRect,
POINTL* SourcePoint,
BYTE *tMask, *lMask;
static BYTE maskbit[8] = { 0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01 };
/* Pattern brushes */
- PGDIBRUSHOBJ GdiBrush;
- HBITMAP PatternSurface = NULL;
- PSURFOBJ PatternObj;
- ULONG PatternWidth, PatternHeight, PatternY;
-
+ PGDIBRUSHINST GdiBrush = NULL;
+ SURFOBJ *PatternObj = NULL;
+ PBITMAPOBJ PatternBitmap;
+ ULONG PatternWidth = 0, PatternHeight = 0, PatternY = 0;
+
if (Mask == NULL)
{
return FALSE;
if (Brush->iSolidColor == 0xFFFFFFFF)
{
- PBITMAPOBJ PatternBitmap;
-
GdiBrush = CONTAINING_RECORD(
Brush,
- GDIBRUSHOBJ,
+ GDIBRUSHINST,
BrushObject);
- PatternBitmap = BITMAPOBJ_LockBitmap(GdiBrush->hbmPattern);
- PatternSurface = BitmapToSurf(PatternBitmap, Dest->hdev);
- BITMAPOBJ_UnlockBitmap(GdiBrush->hbmPattern);
-
- PatternObj = (PSURFOBJ)AccessUserObject((ULONG)PatternSurface);
- PatternWidth = PatternObj->sizlBitmap.cx;
- PatternHeight = PatternObj->sizlBitmap.cy;
+ 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++)
{
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)
{
- DestGDI->DIB_PutPixel(Dest, DestRect->left + i, DestRect->top + j, Brush->iSolidColor);
+ DibFunctionsForBitmapFormat[Dest->iBitmapFormat].DIB_PutPixel(
+ Dest, DestRect->left + i, DestRect->top + j, Brush->iSolidColor);
}
else
{
- DestGDI->DIB_PutPixel(Dest, DestRect->left + i, DestRect->top + j,
- DIB_1BPP_GetPixel(PatternObj, (DestRect->left + i) % PatternWidth, PatternY) ? GdiBrush->crFore : GdiBrush->crBack);
+ DibFunctionsForBitmapFormat[Dest->iBitmapFormat].DIB_PutPixel(
+ Dest, DestRect->left + i, DestRect->top + j,
+ DIB_GetSource(PatternObj, (DestRect->left + i) % PatternWidth, PatternY, GdiBrush->XlateObject));
}
}
c8++;
tMask += Mask->lDelta;
}
- if (PatternSurface != NULL)
- EngDeleteSurface(PatternSurface);
+ if (PatternBitmap != NULL)
+ BITMAPOBJ_UnlockBitmap(PatternBitmap);
return TRUE;
}
static BOOLEAN STDCALL
BltPatCopy(SURFOBJ* Dest,
- SURFGDI* DestGDI,
SURFOBJ* Source,
- SURFGDI* SourceGDI,
- SURFOBJ* Mask,
+ SURFOBJ* Mask,
XLATEOBJ* ColorTranslation,
RECTL* DestRect,
POINTL* SourcePoint,
{
// 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);
- }
+ DibFunctionsForBitmapFormat[Dest->iBitmapFormat].DIB_ColorFill(Dest, DestRect, Brush->iSolidColor);
return TRUE;
}
static BOOLEAN STDCALL
CallDibBitBlt(SURFOBJ* OutputObj,
- SURFGDI* OutputGDI,
SURFOBJ* InputObj,
- SURFGDI* InputGDI,
SURFOBJ* Mask,
XLATEOBJ* ColorTranslation,
RECTL* OutputRect,
POINTL* BrushOrigin,
ROP4 Rop4)
{
- return OutputGDI->DIB_BitBlt(OutputObj, InputObj, OutputGDI, InputGDI, OutputRect, InputPoint, Brush, BrushOrigin, ColorTranslation, Rop4);
+ 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 (ROP3_TO_ROP4(SRCCOPY) == Rop4)
+ return DibFunctionsForBitmapFormat[OutputObj->iBitmapFormat].DIB_BitBltSrcCopy(&BltInfo);
+
+ BltInfo.XlatePatternToDest = NULL;
+ BltInfo.Brush = Brush;
+ BltInfo.BrushOrigin = *BrushOrigin;
+ BltInfo.Rop4 = Rop4;
+
+ /* Pattern brush */
+ if (ROP4_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(bmPattern);
+ }
+
+ return Result;
}
INT abs(INT nm);
RECTL CombinedRect;
RECT_ENUM RectEnum;
BOOL EnumMore;
- SURFGDI* OutputGDI;
- SURFGDI* InputGDI;
POINTL InputPoint;
RECTL InputRect;
RECTL OutputRect;
SURFOBJ* InputObj;
SURFOBJ* OutputObj;
PBLTRECTFUNC BltRectFunc;
- BOOLEAN Ret;
+ BOOLEAN Ret = TRUE;
RECTL ClipRect;
unsigned i;
POINTL Pt;
ULONG Direction;
BOOL UsesSource;
BOOL UsesPattern;
+ POINTL AdjustedBrushOrigin;
- UsesSource = ((Rop4 & 0xCC0000) >> 2) != (Rop4 & 0x330000);
- UsesPattern = ((Rop4 & 0xF00000) >> 4) != (Rop4 & 0x0F0000);
- if (ROP_NOOP == Rop4)
+ UsesSource = ROP4_USES_SOURCE(Rop4);
+ UsesPattern = ROP4_USES_PATTERN(Rop4);
+ if (R4_NOOP == Rop4)
{
/* Copy destination onto itself: nop */
return TRUE;
}
- if (NULL != SourcePoint)
+ if (UsesSource && NULL != SourcePoint)
{
InputRect.left = SourcePoint->x;
InputRect.right = SourcePoint->x + (DestRect->right - DestRect->left);
InputPoint.y = 0;
}
- if (NULL != InputObj)
- {
- InputGDI = (SURFGDI*) AccessInternalObjectFromUserObject(InputObj);
- }
- else
- {
- InputGDI = NULL;
- }
-
OutputRect = *DestRect;
if (NULL != ClipRegion)
{
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;
+ OutputRect.left += Translate.x;
+ OutputRect.right += Translate.x;
+ OutputRect.top += Translate.y;
+ OutputRect.bottom += Translate.y;
- if (NULL != OutputObj)
- {
- OutputGDI = (SURFGDI*)AccessInternalObjectFromUserObject(OutputObj);
- }
+ if(BrushOrigin)
+ {
+ AdjustedBrushOrigin.x = BrushOrigin->x + Translate.x;
+ AdjustedBrushOrigin.y = BrushOrigin->y + Translate.y;
+ }
+ else
+ AdjustedBrushOrigin = Translate;
// Determine clipping type
if (ClipRegion == (CLIPOBJ *) NULL)
clippingType = ClipRegion->iDComplexity;
}
- if (0xaacc == Rop4)
+ if (R4_MASK == Rop4)
{
BltRectFunc = BltMask;
}
- else if (PATCOPY == Rop4)
+ else if (ROP3_TO_ROP4(PATCOPY) == Rop4)
{
-#if 0
- BltRectFunc = BltPatCopy;
-#else
if (Brush->iSolidColor == 0xFFFFFFFF)
BltRectFunc = CallDibBitBlt;
else
BltRectFunc = BltPatCopy;
-#endif
}
else
{
switch(clippingType)
{
case DC_TRIVIAL:
- Ret = (*BltRectFunc)(OutputObj, OutputGDI, InputObj, InputGDI, Mask, ColorTranslation,
- &OutputRect, &InputPoint, MaskOrigin, Brush, BrushOrigin, Rop4);
+ Ret = (*BltRectFunc)(OutputObj, InputObj, Mask, ColorTranslation,
+ &OutputRect, &InputPoint, MaskOrigin, Brush, &AdjustedBrushOrigin, Rop4);
break;
case DC_RECT:
// Clip the blt to the clip rectangle
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,
- &CombinedRect, &Pt, MaskOrigin, Brush, BrushOrigin, Rop4);
+ if (EngIntersectRect(&CombinedRect, &OutputRect, &ClipRect))
+ {
+ Pt.x = InputPoint.x + CombinedRect.left - OutputRect.left;
+ Pt.y = InputPoint.y + CombinedRect.top - OutputRect.top;
+ Ret = (*BltRectFunc)(OutputObj, InputObj, Mask, ColorTranslation,
+ &CombinedRect, &Pt, MaskOrigin, Brush, &AdjustedBrushOrigin, Rop4);
+ }
break;
case DC_COMPLEX:
Ret = TRUE;
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, BrushOrigin, Rop4) &&
- Ret;
+ if (EngIntersectRect(&CombinedRect, &OutputRect, &ClipRect))
+ {
+ Pt.x = InputPoint.x + CombinedRect.left - OutputRect.left;
+ Pt.y = InputPoint.y + CombinedRect.top - OutputRect.top;
+ Ret = (*BltRectFunc)(OutputObj, InputObj, Mask,
+ ColorTranslation, &CombinedRect, &Pt,
+ MaskOrigin, Brush, &AdjustedBrushOrigin,
+ Rop4) && Ret;
+ }
}
}
while(EnumMore);
}
BOOL STDCALL
-IntEngBitBlt(SURFOBJ *DestObj,
- SURFOBJ *SourceObj,
- SURFOBJ *Mask,
+IntEngBitBlt(BITMAPOBJ *DestObj,
+ BITMAPOBJ *SourceObj,
+ BITMAPOBJ *MaskObj,
CLIPOBJ *ClipRegion,
XLATEOBJ *ColorTranslation,
RECTL *DestRect,
ROP4 Rop4)
{
BOOLEAN ret;
- SURFGDI *DestGDI;
- SURFGDI *SourceGDI;
RECTL InputClippedRect;
RECTL OutputRect;
POINTL InputPoint;
BOOLEAN UsesSource;
+ SURFOBJ *DestSurf;
+ SURFOBJ *SourceSurf = SourceObj ? &SourceObj->SurfObj : NULL;
+ SURFOBJ *MaskSurf = MaskObj ? &MaskObj->SurfObj : NULL;
+
+ ASSERT(DestObj);
+ DestSurf = &DestObj->SurfObj;
+ ASSERT(DestSurf);
InputClippedRect = *DestRect;
if (InputClippedRect.right < InputClippedRect.left)
InputClippedRect.top = DestRect->bottom;
InputClippedRect.bottom = DestRect->top;
}
- UsesSource = ((Rop4 & 0xCC0000) >> 2) != (Rop4 & 0x330000);
+ UsesSource = ROP4_USES_SOURCE(Rop4);
if (UsesSource)
{
- if (NULL == SourcePoint || NULL == SourceObj)
+ if (NULL == SourcePoint || NULL == SourceSurf)
{
return FALSE;
}
InputPoint = *SourcePoint;
- SourceGDI = (SURFGDI*) AccessInternalObjectFromUserObject(SourceObj);
/* Make sure we don't try to copy anything outside the valid source region */
if (InputPoint.x < 0)
InputClippedRect.top -= InputPoint.y;
InputPoint.y = 0;
}
- if (SourceObj->sizlBitmap.cx < InputPoint.x + InputClippedRect.right - InputClippedRect.left)
+ if (SourceSurf->sizlBitmap.cx < InputPoint.x + InputClippedRect.right - InputClippedRect.left)
{
- InputClippedRect.right = InputClippedRect.left + SourceObj->sizlBitmap.cx - InputPoint.x;
+ InputClippedRect.right = InputClippedRect.left + SourceSurf->sizlBitmap.cx - InputPoint.x;
}
- if (SourceObj->sizlBitmap.cy < InputPoint.y + InputClippedRect.bottom - InputClippedRect.top)
+ if (SourceSurf->sizlBitmap.cy < InputPoint.y + InputClippedRect.bottom - InputClippedRect.top)
{
- InputClippedRect.bottom = InputClippedRect.top + SourceObj->sizlBitmap.cy - InputPoint.y;
+ InputClippedRect.bottom = InputClippedRect.top + SourceSurf->sizlBitmap.cy - InputPoint.y;
}
if (InputClippedRect.right < InputClippedRect.left ||
if (UsesSource)
{
- MouseSafetyOnDrawStart(SourceObj, SourceGDI, InputPoint.x, InputPoint.y,
+ MouseSafetyOnDrawStart(SourceSurf, InputPoint.x, InputPoint.y,
(InputPoint.x + abs(DestRect->right - DestRect->left)),
(InputPoint.y + abs(DestRect->bottom - DestRect->top)));
}
/* No success yet */
ret = FALSE;
- DestGDI = (SURFGDI*)AccessInternalObjectFromUserObject(DestObj);
- MouseSafetyOnDrawStart(DestObj, DestGDI, OutputRect.left, OutputRect.top,
+ MouseSafetyOnDrawStart(DestSurf, OutputRect.left, OutputRect.top,
OutputRect.right, OutputRect.bottom);
/* Call the driver's DrvBitBlt if available */
- if (NULL != DestGDI->BitBlt)
+ if (DestObj->flHooks & HOOK_BITBLT)
{
- IntLockGDIDriver(DestGDI);
- ret = DestGDI->BitBlt(DestObj, SourceObj, Mask, ClipRegion, ColorTranslation,
+ ret = GDIDEVFUNCS(DestSurf).BitBlt(
+ DestSurf, SourceSurf, MaskSurf, ClipRegion, ColorTranslation,
&OutputRect, &InputPoint, MaskOrigin, Brush, BrushOrigin,
Rop4);
- IntUnLockGDIDriver(DestGDI);
}
if (! ret)
{
- IntLockGDIDriver(DestGDI);
- ret = EngBitBlt(DestObj, SourceObj, Mask, ClipRegion, ColorTranslation,
+ ret = EngBitBlt(DestSurf, SourceSurf, MaskSurf, ClipRegion, ColorTranslation,
&OutputRect, &InputPoint, MaskOrigin, Brush, BrushOrigin,
Rop4);
- IntUnLockGDIDriver(DestGDI);
}
- MouseSafetyOnDrawEnd(DestObj, DestGDI);
+ MouseSafetyOnDrawEnd(DestSurf);
if (UsesSource)
{
- MouseSafetyOnDrawEnd(SourceObj, SourceGDI);
+ MouseSafetyOnDrawEnd(SourceSurf);
}
return ret;
static BOOLEAN STDCALL
CallDibStretchBlt(SURFOBJ* OutputObj,
- SURFGDI* OutputGDI,
SURFOBJ* InputObj,
- SURFGDI* InputGDI,
SURFOBJ* Mask,
+ CLIPOBJ* ClipRegion,
XLATEOBJ* ColorTranslation,
RECTL* OutputRect,
RECTL* InputRect,
POINTL* BrushOrigin,
ULONG Mode)
{
- return OutputGDI->DIB_StretchBlt(OutputObj, InputObj, OutputGDI, InputGDI, OutputRect, InputRect, MaskOrigin, BrushOrigin, ColorTranslation, Mode);
+ POINTL RealBrushOrigin;
+ if (BrushOrigin == NULL)
+ {
+ RealBrushOrigin.x = RealBrushOrigin.y = 0;
+ }
+ else
+ {
+ RealBrushOrigin = *BrushOrigin;
+ }
+ return DibFunctionsForBitmapFormat[OutputObj->iBitmapFormat].DIB_StretchBlt(
+ OutputObj, InputObj, OutputRect, InputRect, MaskOrigin, RealBrushOrigin, ClipRegion, ColorTranslation, Mode);
}
)
{
// www.osr.com/ddk/graphics/gdifncs_0bs7.htm
-
- BYTE clippingType;
- RECTL CombinedRect;
-// RECT_ENUM RectEnum;
-// BOOL EnumMore;
- SURFGDI* OutputGDI;
- SURFGDI* InputGDI;
+
POINTL InputPoint;
RECTL InputRect;
RECTL OutputRect;
INTENG_ENTER_LEAVE EnterLeaveDest;
SURFOBJ* InputObj;
SURFOBJ* OutputObj;
- PSTRETCHRECTFUNC BltRectFunc;
+ PSTRETCHRECTFUNC BltRectFunc;
BOOLEAN Ret;
- RECTL ClipRect;
-// unsigned i;
- POINTL Pt;
-// ULONG Direction;
+ 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;
-
- if (NULL != InputObj)
- {
- InputGDI = (SURFGDI*) AccessInternalObjectFromUserObject(InputObj);
- }
- else
- {
- InputGDI = NULL;
- }
+ InputPoint.x = InputRect.left + Translate.x;
+ InputPoint.y = InputRect.top + Translate.y;
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;
OutputRect.top = prclDest->top + Translate.y;
OutputRect.bottom = prclDest->bottom + Translate.y;
- if (NULL != OutputObj)
+ if (NULL != BrushOrigin)
{
- OutputGDI = (SURFGDI*)AccessInternalObjectFromUserObject(OutputObj);
+ AdjustedBrushOrigin.x = BrushOrigin->x + Translate.x;
+ AdjustedBrushOrigin.y = BrushOrigin->y + Translate.y;
+ }
+ else
+ {
+ AdjustedBrushOrigin = Translate;
}
- // 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");
IntEngLeave(&EnterLeaveDest);
IntEngLeave(&EnterLeaveSource);
-
- return FALSE;
+
+ return FALSE;
}
else
{
}
- switch(clippingType)
- {
- case DC_TRIVIAL:
- Ret = (*BltRectFunc)(OutputObj, OutputGDI, InputObj, InputGDI, Mask, ColorTranslation,
- &OutputRect, &InputRect, MaskOrigin, BrushOrigin, 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, BrushOrigin, 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, BrushOrigin, Rop4) &&
- Ret;
- }
- }
- while(EnumMore);
- break;
- */
- }
-
+ Ret = (*BltRectFunc)(OutputObj, InputObj, Mask, ClipRegion,
+ ColorTranslation, &OutputRect, &InputRect, MaskOrigin,
+ &AdjustedBrushOrigin, Mode);
IntEngLeave(&EnterLeaveDest);
IntEngLeave(&EnterLeaveSource);
}
BOOL STDCALL
-IntEngStretchBlt(SURFOBJ *DestObj,
- SURFOBJ *SourceObj,
- SURFOBJ *Mask,
- CLIPOBJ *ClipRegion,
- XLATEOBJ *ColorTranslation,
- RECTL *DestRect,
- RECTL *SourceRect,
- POINTL *pMaskOrigin,
- BRUSHOBJ *Brush,
- POINTL *BrushOrigin,
- ULONG Mode)
+IntEngStretchBlt(BITMAPOBJ *DestObj,
+ BITMAPOBJ *SourceObj,
+ BITMAPOBJ *MaskObj,
+ CLIPOBJ *ClipRegion,
+ XLATEOBJ *ColorTranslation,
+ RECTL *DestRect,
+ RECTL *SourceRect,
+ POINTL *pMaskOrigin,
+ BRUSHOBJ *Brush,
+ POINTL *BrushOrigin,
+ ULONG Mode)
{
BOOLEAN ret;
- SURFGDI *DestGDI;
- SURFGDI *SourceGDI;
- RECTL OutputRect;
- RECTL InputRect;
COLORADJUSTMENT ca;
POINT MaskOrigin;
+ SURFOBJ *DestSurf;
+ SURFOBJ *SourceSurf = SourceObj ? &SourceObj->SurfObj : NULL;
+ SURFOBJ *MaskSurf = MaskObj ? &MaskObj->SurfObj : NULL;
+
+ ASSERT(DestObj);
+ DestSurf = &DestObj->SurfObj;
+ ASSERT(DestSurf);
if (pMaskOrigin != NULL)
{
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)
+ if (NULL != SourceSurf)
{
- 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)));
+ ASSERT(SourceRect);
+ MouseSafetyOnDrawStart(SourceSurf, SourceRect->left, SourceRect->top,
+ SourceRect->right, SourceRect->bottom);
}
/* No success yet */
ret = FALSE;
- DestGDI = (SURFGDI*)AccessInternalObjectFromUserObject(DestObj);
- MouseSafetyOnDrawStart(DestObj, DestGDI, OutputRect.left, OutputRect.top,
- OutputRect.right, OutputRect.bottom);
+ ASSERT(DestRect);
+ MouseSafetyOnDrawStart(DestSurf, DestRect->left, DestRect->top,
+ DestRect->right, DestRect->bottom);
/* Prepare color adjustment */
/* Call the driver's DrvStretchBlt if available */
- if (NULL != DestGDI->StretchBlt)
+ if (DestObj->flHooks & HOOK_STRETCHBLT)
{
/* Drv->StretchBlt (look at http://www.osr.com/ddk/graphics/ddifncs_3ew7.htm )
SURFOBJ *psoMask // optional, if it exists, then rop4=0xCCAA, otherwise rop4=0xCCCC */
// FIXME: MaskOrigin is always NULL !
- IntLockGDIDriver(DestGDI);
- ret = DestGDI->StretchBlt(DestObj, SourceObj, Mask, ClipRegion, ColorTranslation,
- &ca, BrushOrigin, &OutputRect, &InputRect, NULL, Mode);
- IntUnLockGDIDriver(DestGDI);
+ ret = GDIDEVFUNCS(DestSurf).StretchBlt(
+ DestSurf, SourceSurf, MaskSurf, ClipRegion, ColorTranslation,
+ &ca, BrushOrigin, DestRect, SourceRect, NULL, Mode);
}
if (! ret)
{
// FIXME: see previous fixme
- ret = EngStretchBlt(DestObj, SourceObj, Mask, ClipRegion, ColorTranslation,
- &ca, BrushOrigin, &OutputRect, &InputRect, NULL, Mode);
+ ret = EngStretchBlt(DestSurf, SourceSurf, MaskSurf, ClipRegion, ColorTranslation,
+ &ca, BrushOrigin, DestRect, SourceRect, NULL, Mode);
}
- MouseSafetyOnDrawEnd(DestObj, DestGDI);
- if (NULL != SourceObj)
+ MouseSafetyOnDrawEnd(DestSurf);
+ if (NULL != SourceSurf)
{
- MouseSafetyOnDrawEnd(SourceObj, SourceGDI);
+ MouseSafetyOnDrawEnd(SourceSurf);
}
return ret;
/* renders the alpha mask bitmap */
static BOOLEAN STDCALL
AlphaBltMask(SURFOBJ* Dest,
- SURFGDI* DestGDI,
SURFOBJ* Source,
- SURFGDI* SourceGDI,
- SURFOBJ* Mask,
+ SURFOBJ* Mask,
XLATEOBJ* ColorTranslation,
XLATEOBJ* SrcColorTranslation,
RECTL* DestRect,
r = (int)GetRValue(BrushColor);
g = (int)GetGValue(BrushColor);
b = (int)GetBValue(BrushColor);
-
- tMask = Mask->pvBits + (SourcePoint->y * Mask->lDelta) + SourcePoint->x;
+
+ tMask = Mask->pvScan0 + (SourcePoint->y * Mask->lDelta) + SourcePoint->x;
for (j = 0; j < dy; j++)
- {
- lMask = tMask;
- for (i = 0; i < dx; i++)
- {
- if (*lMask > 0)
- {
- if(*lMask == 0xff)
- {
- DestGDI->DIB_PutPixel(Dest, DestRect->left + i, DestRect->top + j, Brush->iSolidColor);
- }
- else
- {
- Background = DIB_GetSource(Dest, DestGDI, DestRect->left + i, DestRect->top + j, SrcColorTranslation);
-
- NewColor =
- RGB((*lMask * (r - GetRValue(Background)) >> 8) + GetRValue(Background),
- (*lMask * (g - GetGValue(Background)) >> 8) + GetGValue(Background),
- (*lMask * (b - GetBValue(Background)) >> 8) + GetBValue(Background));
-
- Background = XLATEOBJ_iXlate(ColorTranslation, NewColor);
- DestGDI->DIB_PutPixel(Dest, DestRect->left + i, DestRect->top + j, Background);
- }
- }
- lMask++;
- }
- tMask += Mask->lDelta;
- }
+ {
+ lMask = tMask;
+ for (i = 0; i < dx; i++)
+ {
+ if (*lMask > 0)
+ {
+ if (*lMask == 0xff)
+ {
+ DibFunctionsForBitmapFormat[Dest->iBitmapFormat].DIB_PutPixel(
+ Dest, DestRect->left + i, DestRect->top + j, Brush->iSolidColor);
+ }
+ else
+ {
+ Background = DIB_GetSource(Dest, DestRect->left + i, DestRect->top + j,
+ SrcColorTranslation);
+
+ NewColor =
+ RGB((*lMask * (r - GetRValue(Background)) >> 8) + GetRValue(Background),
+ (*lMask * (g - GetGValue(Background)) >> 8) + GetGValue(Background),
+ (*lMask * (b - GetBValue(Background)) >> 8) + GetBValue(Background));
+
+ Background = XLATEOBJ_iXlate(ColorTranslation, NewColor);
+ DibFunctionsForBitmapFormat[Dest->iBitmapFormat].DIB_PutPixel(
+ Dest, DestRect->left + i, DestRect->top + j, Background);
+ }
+ }
+ lMask++;
+ }
+ tMask += Mask->lDelta;
+ }
return TRUE;
}
else
{
- return FALSE;
+ return FALSE;
}
}
RECTL CombinedRect;
RECT_ENUM RectEnum;
BOOL EnumMore;
- SURFGDI* OutputGDI;
- SURFGDI* InputGDI;
POINTL InputPoint;
RECTL InputRect;
RECTL OutputRect;
INTENG_ENTER_LEAVE EnterLeaveDest;
SURFOBJ* InputObj;
SURFOBJ* OutputObj;
- BOOLEAN Ret;
+ BOOLEAN Ret = TRUE;
RECTL ClipRect;
unsigned i;
POINTL Pt;
ULONG Direction;
- SURFGDI* DestGDI;
+ POINTL AdjustedBrushOrigin;
+
+ ASSERT ( Mask );
if (NULL != SourcePoint)
{
InputRect.bottom = DestRect->bottom - DestRect->top;
}
- DestGDI = (SURFGDI*)AccessInternalObjectFromUserObject(DestObj);
- IntLockGDIDriver(DestGDI);
- if (! IntEngEnter(&EnterLeaveSource, NULL, &InputRect, TRUE, &Translate, &InputObj))
+ if (! IntEngEnter(&EnterLeaveSource, DestObj, &InputRect, TRUE, &Translate, &InputObj))
{
- IntUnLockGDIDriver(DestGDI);
return FALSE;
}
InputPoint.y = 0;
}
- if (NULL != InputObj)
- {
- InputGDI = (SURFGDI*) AccessInternalObjectFromUserObject(InputObj);
- }
- else
- {
- InputGDI = NULL;
- }
-
OutputRect = *DestRect;
if (NULL != ClipRegion)
{
if (OutputRect.right <= OutputRect.left || OutputRect.bottom <= OutputRect.top)
{
IntEngLeave(&EnterLeaveSource);
- IntUnLockGDIDriver(DestGDI);
return TRUE;
}
if (! IntEngEnter(&EnterLeaveDest, DestObj, &OutputRect, FALSE, &Translate, &OutputObj))
{
IntEngLeave(&EnterLeaveSource);
- IntUnLockGDIDriver(DestGDI);
return FALSE;
}
OutputRect.top = DestRect->top + Translate.y;
OutputRect.bottom = DestRect->bottom + Translate.y;
- if (NULL != OutputObj)
- {
- OutputGDI = (SURFGDI*)AccessInternalObjectFromUserObject(OutputObj);
- }
+ if(BrushOrigin)
+ {
+ AdjustedBrushOrigin.x = BrushOrigin->x + Translate.x;
+ AdjustedBrushOrigin.y = BrushOrigin->y + Translate.y;
+ }
+ else
+ AdjustedBrushOrigin = Translate;
// Determine clipping type
if (ClipRegion == (CLIPOBJ *) NULL)
{
case DC_TRIVIAL:
if(Mask->iBitmapFormat == BMF_8BPP)
- Ret = AlphaBltMask(OutputObj, OutputGDI, InputObj, InputGDI, Mask, DestColorTranslation, SourceColorTranslation,
- &OutputRect, &InputPoint, MaskOrigin, Brush, BrushOrigin);
+ Ret = AlphaBltMask(OutputObj, InputObj, Mask, DestColorTranslation, SourceColorTranslation,
+ &OutputRect, &InputPoint, MaskOrigin, Brush, &AdjustedBrushOrigin);
else
- Ret = BltMask(OutputObj, OutputGDI, InputObj, InputGDI, Mask, DestColorTranslation,
- &OutputRect, &InputPoint, MaskOrigin, Brush, BrushOrigin, 0xAACC);
+ Ret = BltMask(OutputObj, InputObj, Mask, DestColorTranslation,
+ &OutputRect, &InputPoint, MaskOrigin, Brush, &AdjustedBrushOrigin,
+ R4_MASK);
break;
case DC_RECT:
// Clip the blt to the clip rectangle
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;
- if(Mask->iBitmapFormat == BMF_8BPP)
- Ret = AlphaBltMask(OutputObj, OutputGDI, InputObj, InputGDI, Mask, DestColorTranslation, SourceColorTranslation,
- &CombinedRect, &Pt, MaskOrigin, Brush, BrushOrigin);
- else
- Ret = BltMask(OutputObj, OutputGDI, InputObj, InputGDI, Mask, DestColorTranslation,
- &CombinedRect, &Pt, MaskOrigin, Brush, BrushOrigin, 0xAACC);
+ if (EngIntersectRect(&CombinedRect, &OutputRect, &ClipRect))
+ {
+ Pt.x = InputPoint.x + CombinedRect.left - OutputRect.left;
+ Pt.y = InputPoint.y + CombinedRect.top - OutputRect.top;
+ if(Mask->iBitmapFormat == BMF_8BPP)
+ {
+ Ret = AlphaBltMask(OutputObj, InputObj, Mask, DestColorTranslation, SourceColorTranslation,
+ &CombinedRect, &Pt, MaskOrigin, Brush, &AdjustedBrushOrigin);
+ }
+ else
+ {
+ Ret = BltMask(OutputObj, InputObj, Mask, DestColorTranslation,
+ &CombinedRect, &Pt, MaskOrigin, Brush, &AdjustedBrushOrigin, R4_MASK);
+ }
+ }
break;
case DC_COMPLEX:
Ret = TRUE;
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;
- if(Mask->iBitmapFormat == BMF_8BPP)
- Ret = AlphaBltMask(OutputObj, OutputGDI, InputObj, InputGDI, Mask, DestColorTranslation, SourceColorTranslation,
- &CombinedRect, &Pt, MaskOrigin, Brush, BrushOrigin) && Ret;
- else
- Ret = BltMask(OutputObj, OutputGDI, InputObj, InputGDI, Mask, DestColorTranslation,
- &CombinedRect, &Pt, MaskOrigin, Brush, BrushOrigin, 0xAACC) && Ret;
+ if (EngIntersectRect(&CombinedRect, &OutputRect, &ClipRect))
+ {
+ Pt.x = InputPoint.x + CombinedRect.left - OutputRect.left;
+ Pt.y = InputPoint.y + CombinedRect.top - OutputRect.top;
+ if(Mask->iBitmapFormat == BMF_8BPP)
+ {
+ Ret = AlphaBltMask(OutputObj, InputObj, Mask,
+ DestColorTranslation,
+ SourceColorTranslation,
+ &CombinedRect, &Pt, MaskOrigin, Brush,
+ &AdjustedBrushOrigin) && Ret;
+ }
+ else
+ {
+ Ret = BltMask(OutputObj, InputObj, Mask,
+ DestColorTranslation, &CombinedRect, &Pt,
+ MaskOrigin, Brush, &AdjustedBrushOrigin,
+ R4_MASK) && Ret;
+ }
+ }
}
}
while(EnumMore);
IntEngLeave(&EnterLeaveDest);
IntEngLeave(&EnterLeaveSource);
- IntUnLockGDIDriver(DestGDI);
-
- /* Dummy BitBlt to let driver know that something has changed.
- 0x00AA0029 is the Rop for D (no-op) */
- IntEngBitBlt(DestObj, NULL, Mask, ClipRegion, DestColorTranslation,
- DestRect, SourcePoint, MaskOrigin, Brush, BrushOrigin, ROP_NOOP);
-
return Ret;
}
BOOL STDCALL
IntEngMaskBlt(SURFOBJ *DestObj,
- SURFOBJ *Mask,
- CLIPOBJ *ClipRegion,
- XLATEOBJ *DestColorTranslation,
- XLATEOBJ *SourceColorTranslation,
- RECTL *DestRect,
- POINTL *SourcePoint,
- POINTL *MaskOrigin,
- BRUSHOBJ *Brush,
- POINTL *BrushOrigin)
+ SURFOBJ *Mask,
+ CLIPOBJ *ClipRegion,
+ XLATEOBJ *DestColorTranslation,
+ XLATEOBJ *SourceColorTranslation,
+ RECTL *DestRect,
+ POINTL *SourcePoint,
+ POINTL *MaskOrigin,
+ BRUSHOBJ *Brush,
+ POINTL *BrushOrigin)
{
BOOLEAN ret;
- SURFGDI *DestGDI;
RECTL OutputRect;
POINTL InputPoint;
+ ASSERT(Mask);
+
if (NULL != SourcePoint)
{
InputPoint = *SourcePoint;
/* No success yet */
ret = FALSE;
- DestGDI = (SURFGDI*)AccessInternalObjectFromUserObject(DestObj);
- MouseSafetyOnDrawStart(DestObj, DestGDI, OutputRect.left, OutputRect.top,
+ ASSERT(DestObj);
+ MouseSafetyOnDrawStart(DestObj, OutputRect.left, OutputRect.top,
OutputRect.right, OutputRect.bottom);
+ /* Dummy BitBlt to let driver know that it should flush its changes.
+ This should really be done using a call to DrvSynchronizeSurface,
+ but the VMware driver doesn't hook that call. */
+ /* FIXME: Remove the typecast! */
+ IntEngBitBlt((BITMAPOBJ*)DestObj, NULL, (BITMAPOBJ*)Mask, ClipRegion, DestColorTranslation,
+ DestRect, SourcePoint, MaskOrigin, Brush, BrushOrigin, R4_NOOP);
+
ret = EngMaskBitBlt(DestObj, Mask, ClipRegion, DestColorTranslation, SourceColorTranslation,
&OutputRect, &InputPoint, MaskOrigin, Brush, BrushOrigin);
- MouseSafetyOnDrawEnd(DestObj, DestGDI);
+ /* Dummy BitBlt to let driver know that something has changed. */
+ /* FIXME: Remove the typecast! */
+ IntEngBitBlt((BITMAPOBJ*)DestObj, NULL, (BITMAPOBJ*)Mask, ClipRegion, DestColorTranslation,
+ DestRect, SourcePoint, MaskOrigin, Brush, BrushOrigin, R4_NOOP);
+
+ MouseSafetyOnDrawEnd(DestObj);
return ret;
}