2000-03-17 21:44:02 +00:00
|
|
|
/*
|
2003-05-18 17:16:18 +00:00
|
|
|
* ReactOS W32 Subsystem
|
|
|
|
* Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003 ReactOS Team
|
|
|
|
*
|
|
|
|
* This program is free software; you can redistribute it and/or modify
|
|
|
|
* it under the terms of the GNU General Public License as published by
|
|
|
|
* the Free Software Foundation; either version 2 of the License, or
|
|
|
|
* (at your option) any later version.
|
|
|
|
*
|
|
|
|
* This program is distributed in the hope that it will be useful,
|
|
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
* GNU General Public License for more details.
|
|
|
|
*
|
|
|
|
* You should have received a copy of the GNU General Public License
|
|
|
|
* along with this program; if not, write to the Free Software
|
|
|
|
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
|
|
|
*/
|
2003-12-08 11:11:11 +00:00
|
|
|
/* $Id: bitblt.c,v 1.30 2003/12/08 11:11:11 fireball Exp $
|
2003-05-18 17:16:18 +00:00
|
|
|
*
|
2000-03-17 21:44:02 +00:00
|
|
|
* COPYRIGHT: See COPYING in the top level directory
|
|
|
|
* PROJECT: ReactOS kernel
|
|
|
|
* PURPOSE: GDI BitBlt Functions
|
|
|
|
* FILE: subsys/win32k/eng/bitblt.c
|
|
|
|
* PROGRAMER: Jason Filby
|
|
|
|
* REVISION HISTORY:
|
|
|
|
* 2/10/1999: Created
|
|
|
|
*/
|
2002-09-08 10:23:54 +00:00
|
|
|
|
2000-03-17 21:44:02 +00:00
|
|
|
#include <ddk/winddi.h>
|
|
|
|
#include <ddk/ntddk.h>
|
2003-05-18 17:16:18 +00:00
|
|
|
#include <ddk/ntddmou.h>
|
2000-06-29 23:35:53 +00:00
|
|
|
#include <ntos/minmax.h>
|
2000-03-17 21:44:02 +00:00
|
|
|
#include "brush.h"
|
2002-08-18 13:55:11 +00:00
|
|
|
#include "clip.h"
|
2000-03-17 21:44:02 +00:00
|
|
|
#include "objects.h"
|
2003-02-15 19:16:34 +00:00
|
|
|
#include "../dib/dib.h"
|
2003-02-25 23:08:54 +00:00
|
|
|
#include "misc.h"
|
2002-01-13 22:52:08 +00:00
|
|
|
#include <include/mouse.h>
|
|
|
|
#include <include/object.h>
|
|
|
|
#include <include/dib.h>
|
|
|
|
#include <include/surface.h>
|
2003-02-25 23:08:54 +00:00
|
|
|
#include <include/inteng.h>
|
2000-03-17 21:44:02 +00:00
|
|
|
|
2003-08-17 17:32:58 +00:00
|
|
|
//#define NDEBUG
|
2003-02-15 19:16:34 +00:00
|
|
|
#include <win32k/debug1.h>
|
|
|
|
|
2003-10-29 08:38:55 +00:00
|
|
|
typedef BOOLEAN STDCALL (*PBLTRECTFUNC)(SURFOBJ* OutputObj,
|
|
|
|
SURFGDI* OutputGDI,
|
|
|
|
SURFOBJ* InputObj,
|
|
|
|
SURFGDI* InputGDI,
|
|
|
|
SURFOBJ* Mask,
|
|
|
|
XLATEOBJ* ColorTranslation,
|
|
|
|
RECTL* OutputRect,
|
|
|
|
POINTL* InputPoint,
|
|
|
|
POINTL* MaskOrigin,
|
|
|
|
BRUSHOBJ* Brush,
|
|
|
|
POINTL* BrushOrigin,
|
2003-06-28 08:39:18 +00:00
|
|
|
ROP4 Rop4);
|
|
|
|
|
2003-10-29 08:38:55 +00:00
|
|
|
BOOL STDCALL EngIntersectRect(RECTL* prcDst, RECTL* prcSrc1, RECTL* prcSrc2)
|
2000-03-17 21:44:02 +00:00
|
|
|
{
|
2001-03-31 15:35:08 +00:00
|
|
|
static const RECTL rclEmpty = { 0, 0, 0, 0 };
|
2000-03-17 21:44:02 +00:00
|
|
|
|
2001-03-31 15:35:08 +00:00
|
|
|
prcDst->left = max(prcSrc1->left, prcSrc2->left);
|
|
|
|
prcDst->right = min(prcSrc1->right, prcSrc2->right);
|
2000-03-17 21:44:02 +00:00
|
|
|
|
2001-03-31 15:35:08 +00:00
|
|
|
if (prcDst->left < prcDst->right)
|
2003-07-09 07:00:00 +00:00
|
|
|
{
|
|
|
|
prcDst->top = max(prcSrc1->top, prcSrc2->top);
|
|
|
|
prcDst->bottom = min(prcSrc1->bottom, prcSrc2->bottom);
|
2000-03-17 21:44:02 +00:00
|
|
|
|
2003-07-09 07:00:00 +00:00
|
|
|
if (prcDst->top < prcDst->bottom)
|
|
|
|
{
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
}
|
2000-03-17 21:44:02 +00:00
|
|
|
|
2001-03-31 15:35:08 +00:00
|
|
|
*prcDst = rclEmpty;
|
2000-03-17 21:44:02 +00:00
|
|
|
|
2003-07-09 07:00:00 +00:00
|
|
|
return FALSE;
|
2000-03-17 21:44:02 +00:00
|
|
|
}
|
|
|
|
|
2003-06-28 08:39:18 +00:00
|
|
|
static BOOLEAN STDCALL
|
2003-10-29 08:38:55 +00:00
|
|
|
BltMask(SURFOBJ* Dest,
|
|
|
|
SURFGDI* DestGDI,
|
|
|
|
SURFOBJ* Source,
|
|
|
|
SURFGDI* SourceGDI,
|
|
|
|
SURFOBJ* Mask,
|
|
|
|
XLATEOBJ* ColorTranslation,
|
|
|
|
RECTL* DestRect,
|
|
|
|
POINTL* SourcePoint,
|
|
|
|
POINTL* MaskPoint,
|
|
|
|
BRUSHOBJ* Brush,
|
|
|
|
POINTL* BrushPoint,
|
2003-08-17 17:32:58 +00:00
|
|
|
ROP4 Rop4)
|
2003-02-15 19:16:34 +00:00
|
|
|
{
|
|
|
|
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)
|
|
|
|
{
|
2003-09-09 09:39:21 +00:00
|
|
|
tMask = Mask->pvBits + SourcePoint->y * Mask->lDelta + (SourcePoint->x >> 3);
|
2003-02-15 19:16:34 +00:00
|
|
|
for (j = 0; j < dy; j++)
|
|
|
|
{
|
|
|
|
lMask = tMask;
|
2003-09-09 09:39:21 +00:00
|
|
|
c8 = SourcePoint->x & 0x07;
|
2003-02-15 19:16:34 +00:00
|
|
|
for (i = 0; i < dx; i++)
|
|
|
|
{
|
|
|
|
if (0 != (*lMask & maskbit[c8]))
|
|
|
|
{
|
2003-03-04 10:09:01 +00:00
|
|
|
DestGDI->DIB_PutPixel(Dest, DestRect->left + i, DestRect->top + j, Brush->iSolidColor);
|
2003-02-15 19:16:34 +00:00
|
|
|
}
|
|
|
|
c8++;
|
|
|
|
if (8 == c8)
|
|
|
|
{
|
|
|
|
lMask++;
|
|
|
|
c8=0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
tMask += Mask->lDelta;
|
|
|
|
}
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2003-06-28 08:39:18 +00:00
|
|
|
static BOOLEAN STDCALL
|
2003-10-29 08:38:55 +00:00
|
|
|
BltPatCopy(SURFOBJ* Dest,
|
|
|
|
SURFGDI* DestGDI,
|
|
|
|
SURFOBJ* Source,
|
|
|
|
SURFGDI* SourceGDI,
|
|
|
|
SURFOBJ* Mask,
|
|
|
|
XLATEOBJ* ColorTranslation,
|
|
|
|
RECTL* DestRect,
|
|
|
|
POINTL* SourcePoint,
|
|
|
|
POINTL* MaskPoint,
|
|
|
|
BRUSHOBJ* Brush,
|
|
|
|
POINTL* BrushPoint,
|
2003-08-17 17:32:58 +00:00
|
|
|
ROP4 Rop4)
|
2003-02-15 19:16:34 +00:00
|
|
|
{
|
|
|
|
// 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++)
|
|
|
|
{
|
2003-03-04 10:09:01 +00:00
|
|
|
DestGDI->DIB_HLine(Dest, DestRect->left, DestRect->right, y, Brush->iSolidColor);
|
2003-02-15 19:16:34 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
|
2003-06-28 08:39:18 +00:00
|
|
|
static BOOLEAN STDCALL
|
2003-10-29 08:38:55 +00:00
|
|
|
CallDibBitBlt(SURFOBJ* OutputObj,
|
|
|
|
SURFGDI* OutputGDI,
|
|
|
|
SURFOBJ* InputObj,
|
|
|
|
SURFGDI* InputGDI,
|
|
|
|
SURFOBJ* Mask,
|
|
|
|
XLATEOBJ* ColorTranslation,
|
|
|
|
RECTL* OutputRect,
|
|
|
|
POINTL* InputPoint,
|
|
|
|
POINTL* MaskOrigin,
|
|
|
|
BRUSHOBJ* Brush,
|
|
|
|
POINTL* BrushOrigin,
|
2003-06-28 08:39:18 +00:00
|
|
|
ROP4 Rop4)
|
|
|
|
{
|
2003-07-27 18:37:23 +00:00
|
|
|
return OutputGDI->DIB_BitBlt(OutputObj, InputObj, OutputGDI, InputGDI, OutputRect, InputPoint, Brush, BrushOrigin, ColorTranslation, Rop4);
|
2003-06-28 08:39:18 +00:00
|
|
|
}
|
|
|
|
|
2001-06-03 10:47:29 +00:00
|
|
|
INT abs(INT nm);
|
2001-03-31 15:35:08 +00:00
|
|
|
|
2003-07-11 15:59:37 +00:00
|
|
|
/*
|
2003-08-04 19:57:05 +00:00
|
|
|
* @implemented
|
2003-07-11 15:59:37 +00:00
|
|
|
*/
|
2002-06-15 21:44:08 +00:00
|
|
|
BOOL STDCALL
|
2003-02-25 23:08:54 +00:00
|
|
|
EngBitBlt(SURFOBJ *DestObj,
|
|
|
|
SURFOBJ *SourceObj,
|
2002-06-15 21:44:08 +00:00
|
|
|
SURFOBJ *Mask,
|
|
|
|
CLIPOBJ *ClipRegion,
|
|
|
|
XLATEOBJ *ColorTranslation,
|
|
|
|
RECTL *DestRect,
|
|
|
|
POINTL *SourcePoint,
|
2003-02-15 19:16:34 +00:00
|
|
|
POINTL *MaskOrigin,
|
2002-09-08 10:23:54 +00:00
|
|
|
BRUSHOBJ *Brush,
|
2002-06-15 21:44:08 +00:00
|
|
|
POINTL *BrushOrigin,
|
2003-06-28 08:39:18 +00:00
|
|
|
ROP4 Rop4)
|
2000-03-17 21:44:02 +00:00
|
|
|
{
|
2003-02-25 23:08:54 +00:00
|
|
|
BYTE clippingType;
|
2003-06-28 08:39:18 +00:00
|
|
|
RECTL CombinedRect;
|
2003-02-25 23:08:54 +00:00
|
|
|
RECT_ENUM RectEnum;
|
|
|
|
BOOL EnumMore;
|
2003-10-29 08:38:55 +00:00
|
|
|
SURFGDI* OutputGDI;
|
|
|
|
SURFGDI* InputGDI;
|
2003-02-25 23:08:54 +00:00
|
|
|
POINTL InputPoint;
|
|
|
|
RECTL InputRect;
|
|
|
|
RECTL OutputRect;
|
|
|
|
POINTL Translate;
|
|
|
|
INTENG_ENTER_LEAVE EnterLeaveSource;
|
|
|
|
INTENG_ENTER_LEAVE EnterLeaveDest;
|
2003-10-29 08:38:55 +00:00
|
|
|
SURFOBJ* InputObj;
|
|
|
|
SURFOBJ* OutputObj;
|
2003-06-28 08:39:18 +00:00
|
|
|
PBLTRECTFUNC BltRectFunc;
|
|
|
|
BOOLEAN Ret;
|
|
|
|
RECTL ClipRect;
|
|
|
|
unsigned i;
|
2003-09-09 09:39:21 +00:00
|
|
|
POINTL Pt;
|
|
|
|
ULONG Direction;
|
2003-02-25 23:08:54 +00:00
|
|
|
|
|
|
|
if (NULL != SourcePoint)
|
2001-03-31 15:35:08 +00:00
|
|
|
{
|
2003-02-25 23:08:54 +00:00
|
|
|
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;
|
2001-03-31 15:35:08 +00:00
|
|
|
}
|
|
|
|
|
2003-02-25 23:08:54 +00:00
|
|
|
if (! IntEngEnter(&EnterLeaveSource, SourceObj, &InputRect, TRUE, &Translate, &InputObj))
|
|
|
|
{
|
2002-09-21 10:39:54 +00:00
|
|
|
return FALSE;
|
2003-02-25 23:08:54 +00:00
|
|
|
}
|
2002-09-21 10:39:54 +00:00
|
|
|
|
2003-02-25 23:08:54 +00:00
|
|
|
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)
|
|
|
|
{
|
2003-10-29 08:38:55 +00:00
|
|
|
InputGDI = (SURFGDI*) AccessInternalObjectFromUserObject(InputObj);
|
2003-02-25 23:08:54 +00:00
|
|
|
}
|
2003-07-27 18:37:23 +00:00
|
|
|
else
|
|
|
|
{
|
|
|
|
InputGDI = NULL;
|
|
|
|
}
|
2003-02-25 23:08:54 +00:00
|
|
|
|
|
|
|
OutputRect = *DestRect;
|
2003-07-09 07:00:00 +00:00
|
|
|
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;
|
|
|
|
}
|
2003-02-25 23:08:54 +00:00
|
|
|
|
|
|
|
if (! IntEngEnter(&EnterLeaveDest, DestObj, &OutputRect, FALSE, &Translate, &OutputObj))
|
2001-03-31 15:35:08 +00:00
|
|
|
{
|
2003-02-25 23:08:54 +00:00
|
|
|
IntEngLeave(&EnterLeaveSource);
|
|
|
|
return FALSE;
|
|
|
|
}
|
2001-06-03 10:47:29 +00:00
|
|
|
|
2003-02-25 23:08:54 +00:00
|
|
|
OutputRect.left = DestRect->left + Translate.x;
|
|
|
|
OutputRect.right = DestRect->right + Translate.x;
|
|
|
|
OutputRect.top = DestRect->top + Translate.y;
|
|
|
|
OutputRect.bottom = DestRect->bottom + Translate.y;
|
2001-06-03 10:47:29 +00:00
|
|
|
|
2003-02-25 23:08:54 +00:00
|
|
|
if (NULL != OutputObj)
|
|
|
|
{
|
2003-10-29 08:38:55 +00:00
|
|
|
OutputGDI = (SURFGDI*)AccessInternalObjectFromUserObject(OutputObj);
|
2001-03-31 15:35:08 +00:00
|
|
|
}
|
2003-02-25 23:08:54 +00:00
|
|
|
|
2001-03-31 15:35:08 +00:00
|
|
|
// Determine clipping type
|
|
|
|
if (ClipRegion == (CLIPOBJ *) NULL)
|
|
|
|
{
|
|
|
|
clippingType = DC_TRIVIAL;
|
|
|
|
} else {
|
|
|
|
clippingType = ClipRegion->iDComplexity;
|
|
|
|
}
|
|
|
|
|
2003-06-28 08:39:18 +00:00
|
|
|
if (0xaacc == Rop4)
|
|
|
|
{
|
|
|
|
BltRectFunc = BltMask;
|
|
|
|
}
|
|
|
|
else if (PATCOPY == Rop4)
|
|
|
|
{
|
|
|
|
BltRectFunc = BltPatCopy;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
BltRectFunc = CallDibBitBlt;
|
|
|
|
}
|
2003-02-15 19:16:34 +00:00
|
|
|
|
|
|
|
|
2001-03-31 15:35:08 +00:00
|
|
|
switch(clippingType)
|
|
|
|
{
|
|
|
|
case DC_TRIVIAL:
|
2003-06-28 08:39:18 +00:00
|
|
|
Ret = (*BltRectFunc)(OutputObj, OutputGDI, InputObj, InputGDI, Mask, ColorTranslation,
|
|
|
|
&OutputRect, &InputPoint, MaskOrigin, Brush, BrushOrigin, Rop4);
|
|
|
|
break;
|
2001-03-31 15:35:08 +00:00
|
|
|
case DC_RECT:
|
|
|
|
// Clip the blt to the clip rectangle
|
2003-06-28 08:39:18 +00:00
|
|
|
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);
|
2003-09-09 09:39:21 +00:00
|
|
|
Pt.x = InputPoint.x + CombinedRect.left - OutputRect.left;
|
|
|
|
Pt.y = InputPoint.y + CombinedRect.top - OutputRect.top;
|
2003-06-28 08:39:18 +00:00
|
|
|
Ret = (*BltRectFunc)(OutputObj, OutputGDI, InputObj, InputGDI, Mask, ColorTranslation,
|
2003-09-09 09:39:21 +00:00
|
|
|
&CombinedRect, &Pt, MaskOrigin, Brush, BrushOrigin, Rop4);
|
2003-06-28 08:39:18 +00:00
|
|
|
break;
|
2001-03-31 15:35:08 +00:00
|
|
|
case DC_COMPLEX:
|
2003-06-28 08:39:18 +00:00
|
|
|
Ret = TRUE;
|
2003-09-09 09:39:21 +00:00
|
|
|
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, ENUM_RECT_LIMIT);
|
2003-06-28 08:39:18 +00:00
|
|
|
do
|
|
|
|
{
|
|
|
|
EnumMore = CLIPOBJ_bEnum(ClipRegion,(ULONG) sizeof(RectEnum), (PVOID) &RectEnum);
|
2001-03-31 15:35:08 +00:00
|
|
|
|
2003-06-28 08:39:18 +00:00
|
|
|
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);
|
2003-09-09 09:39:21 +00:00
|
|
|
Pt.x = InputPoint.x + CombinedRect.left - OutputRect.left;
|
|
|
|
Pt.y = InputPoint.y + CombinedRect.top - OutputRect.top;
|
2003-06-28 08:39:18 +00:00
|
|
|
Ret = (*BltRectFunc)(OutputObj, OutputGDI, InputObj, InputGDI, Mask, ColorTranslation,
|
2003-09-09 09:39:21 +00:00
|
|
|
&CombinedRect, &Pt, MaskOrigin, Brush, BrushOrigin, Rop4) &&
|
2003-06-28 08:39:18 +00:00
|
|
|
Ret;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
while(EnumMore);
|
|
|
|
break;
|
2001-03-31 15:35:08 +00:00
|
|
|
}
|
|
|
|
|
2003-06-28 08:39:18 +00:00
|
|
|
|
2003-02-25 23:08:54 +00:00
|
|
|
IntEngLeave(&EnterLeaveDest);
|
|
|
|
IntEngLeave(&EnterLeaveSource);
|
2001-06-03 10:47:29 +00:00
|
|
|
|
2003-06-28 08:39:18 +00:00
|
|
|
return Ret;
|
2000-03-17 21:44:02 +00:00
|
|
|
}
|
2003-02-25 23:08:54 +00:00
|
|
|
|
|
|
|
BOOL STDCALL
|
|
|
|
IntEngBitBlt(SURFOBJ *DestObj,
|
|
|
|
SURFOBJ *SourceObj,
|
|
|
|
SURFOBJ *Mask,
|
|
|
|
CLIPOBJ *ClipRegion,
|
|
|
|
XLATEOBJ *ColorTranslation,
|
|
|
|
RECTL *DestRect,
|
|
|
|
POINTL *SourcePoint,
|
|
|
|
POINTL *MaskOrigin,
|
|
|
|
BRUSHOBJ *Brush,
|
|
|
|
POINTL *BrushOrigin,
|
2003-06-28 08:39:18 +00:00
|
|
|
ROP4 Rop4)
|
2003-02-25 23:08:54 +00:00
|
|
|
{
|
|
|
|
BOOLEAN ret;
|
|
|
|
SURFGDI *DestGDI;
|
|
|
|
SURFGDI *SourceGDI;
|
2003-07-09 07:00:00 +00:00
|
|
|
RECTL OutputRect;
|
|
|
|
POINTL InputPoint;
|
|
|
|
|
|
|
|
if (NULL != SourcePoint)
|
|
|
|
{
|
|
|
|
InputPoint = *SourcePoint;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* 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;
|
|
|
|
}
|
|
|
|
InputPoint.x += OutputRect.left - DestRect->left;
|
|
|
|
InputPoint.y += OutputRect.top - DestRect->top;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
OutputRect = *DestRect;
|
|
|
|
}
|
2003-02-25 23:08:54 +00:00
|
|
|
|
|
|
|
if (NULL != SourceObj)
|
|
|
|
{
|
2003-10-29 08:38:55 +00:00
|
|
|
SourceGDI = (SURFGDI*) AccessInternalObjectFromUserObject(SourceObj);
|
2003-07-09 07:00:00 +00:00
|
|
|
MouseSafetyOnDrawStart(SourceObj, SourceGDI, InputPoint.x, InputPoint.y,
|
|
|
|
(InputPoint.x + abs(DestRect->right - DestRect->left)),
|
|
|
|
(InputPoint.y + abs(DestRect->bottom - DestRect->top)));
|
2003-02-25 23:08:54 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/* No success yet */
|
|
|
|
ret = FALSE;
|
|
|
|
DestGDI = (SURFGDI*)AccessInternalObjectFromUserObject(DestObj);
|
2003-07-09 07:00:00 +00:00
|
|
|
MouseSafetyOnDrawStart(DestObj, DestGDI, OutputRect.left, OutputRect.top,
|
|
|
|
OutputRect.right, OutputRect.bottom);
|
2003-02-25 23:08:54 +00:00
|
|
|
|
|
|
|
/* Call the driver's DrvBitBlt if available */
|
2003-07-09 07:00:00 +00:00
|
|
|
if (NULL != DestGDI->BitBlt)
|
|
|
|
{
|
|
|
|
ret = DestGDI->BitBlt(DestObj, SourceObj, Mask, ClipRegion, ColorTranslation,
|
|
|
|
&OutputRect, &InputPoint, MaskOrigin, Brush, BrushOrigin,
|
|
|
|
Rop4);
|
|
|
|
}
|
2003-02-25 23:08:54 +00:00
|
|
|
|
2003-07-09 07:00:00 +00:00
|
|
|
if (! ret)
|
|
|
|
{
|
|
|
|
ret = EngBitBlt(DestObj, SourceObj, Mask, ClipRegion, ColorTranslation,
|
|
|
|
&OutputRect, &InputPoint, MaskOrigin, Brush, BrushOrigin,
|
|
|
|
Rop4);
|
|
|
|
}
|
2003-02-25 23:08:54 +00:00
|
|
|
|
|
|
|
MouseSafetyOnDrawEnd(DestObj, DestGDI);
|
|
|
|
if (NULL != SourceObj)
|
|
|
|
{
|
|
|
|
MouseSafetyOnDrawEnd(SourceObj, SourceGDI);
|
|
|
|
}
|
|
|
|
|
|
|
|
return ret;
|
|
|
|
}
|
2003-12-08 11:11:11 +00:00
|
|
|
|
|
|
|
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)
|
|
|
|
{
|
|
|
|
BOOLEAN ret;
|
|
|
|
SURFGDI *DestGDI;
|
|
|
|
SURFGDI *SourceGDI;
|
|
|
|
RECTL OutputRect;
|
|
|
|
RECTL InputRect;
|
|
|
|
COLORADJUSTMENT ca;
|
|
|
|
POINT MaskOrigin;
|
|
|
|
|
|
|
|
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)
|
|
|
|
{
|
|
|
|
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)));
|
|
|
|
}
|
|
|
|
|
|
|
|
/* No success yet */
|
|
|
|
ret = FALSE;
|
|
|
|
DestGDI = (SURFGDI*)AccessInternalObjectFromUserObject(DestObj);
|
|
|
|
MouseSafetyOnDrawStart(DestObj, DestGDI, OutputRect.left, OutputRect.top,
|
|
|
|
OutputRect.right, OutputRect.bottom);
|
|
|
|
|
|
|
|
/* Prepare color adjustment */
|
|
|
|
|
|
|
|
/* Call the driver's DrvStretchBlt if available */
|
|
|
|
if (NULL != DestGDI->StretchBlt)
|
|
|
|
{
|
|
|
|
/* Drv->StretchBlt params: (look at http://www.osr.com/ddk/graphics/ddifncs_3ew7.htm )
|
|
|
|
SURFOBJ *psoDest
|
|
|
|
SURFOBJ *psoSrc
|
|
|
|
SURFOBJ *psoMask // optional, if it exists, then rop4=0xCCAA, otherwise rop4=0xCCCC
|
|
|
|
CLIPOBJ *pco
|
|
|
|
XLATEOBJ *pxlo
|
|
|
|
COLORADJUSTMENT *pca
|
|
|
|
POINTL *pptlHTOrg
|
|
|
|
RECTL *prclDest
|
|
|
|
RECTL *prclSrc
|
|
|
|
POINTL *pptlMask // is it * or not?!
|
|
|
|
ULONG iMode
|
|
|
|
*/
|
|
|
|
//DPRINT1("Calling DrvStretchBlt(%x, %x, %x, %x, %x, ca, %x)...\n", DestObj, SourceObj, Mask, ClipRegion, ColorTranslation, BrushOrigin);
|
|
|
|
ret = DestGDI->StretchBlt(DestObj, SourceObj, Mask, ClipRegion, ColorTranslation,
|
|
|
|
&ca, BrushOrigin, &OutputRect, &InputRect, NULL, Mode); // FIXME: MaskOrigin is NULL !
|
|
|
|
}
|
|
|
|
|
|
|
|
if (! ret)
|
|
|
|
{
|
|
|
|
ret = FALSE;
|
|
|
|
//ret = EngBitBlt(DestObj, SourceObj, Mask, ClipRegion, ColorTranslation,
|
|
|
|
// &OutputRect, &InputPoint, MaskOrigin, Brush, BrushOrigin,
|
|
|
|
// Rop4);
|
|
|
|
}
|
|
|
|
|
|
|
|
MouseSafetyOnDrawEnd(DestObj, DestGDI);
|
|
|
|
if (NULL != SourceObj)
|
|
|
|
{
|
|
|
|
MouseSafetyOnDrawEnd(SourceObj, SourceGDI);
|
|
|
|
}
|
|
|
|
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
2003-05-18 17:16:18 +00:00
|
|
|
/* EOF */
|