Author: tkreuzer
Date: Sat Apr 11 03:53:09 2009
New Revision: 40451
URL:
http://svn.reactos.org/svn/reactos?rev=40451&view=rev
Log:
Divide eng/bitblt.c into bitblt.c, alphablend.c and stretchblt.c. Remove EngIntersectRect
and replace it with RECTL_bIntersectRect, which is changed to the code of
EngIntersectRect, that was better.
Added:
trunk/reactos/subsystems/win32/win32k/eng/alphablend.c (with props)
trunk/reactos/subsystems/win32/win32k/eng/stretchblt.c (with props)
Modified:
trunk/reactos/subsystems/win32/win32k/eng/bitblt.c
trunk/reactos/subsystems/win32/win32k/eng/copybits.c
trunk/reactos/subsystems/win32/win32k/eng/transblt.c
trunk/reactos/subsystems/win32/win32k/objects/rect.c
trunk/reactos/subsystems/win32/win32k/win32k.rbuild
Added: trunk/reactos/subsystems/win32/win32k/eng/alphablend.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/subsystems/win32/win32k/en…
==============================================================================
--- trunk/reactos/subsystems/win32/win32k/eng/alphablend.c (added)
+++ trunk/reactos/subsystems/win32/win32k/eng/alphablend.c [iso-8859-1] Sat Apr 11
03:53:09 2009
@@ -1,0 +1,376 @@
+/*
+ * COPYRIGHT: See COPYING in the top level directory
+ * PROJECT: ReactOS kernel
+ * PURPOSE: GDI alpha blending functions
+ * FILE: subsystems/win32/win32k/eng/alphablend.c
+ * PROGRAMER: Jason Filby
+ */
+
+#include <w32k.h>
+
+#define NDEBUG
+#include <debug.h>
+
+
+/*
+ * @implemented
+ */
+BOOL
+APIENTRY
+EngAlphaBlend(IN SURFOBJ *psoDest,
+ IN SURFOBJ *psoSource,
+ IN CLIPOBJ *ClipRegion,
+ IN XLATEOBJ *ColorTranslation,
+ IN PRECTL DestRect,
+ IN PRECTL SourceRect,
+ IN BLENDOBJ *BlendObj)
+{
+ RECTL SourceStretchedRect;
+ SIZEL SourceStretchedSize;
+ HBITMAP SourceStretchedBitmap = 0;
+ SURFOBJ* SourceStretchedObj = NULL;
+ RECTL InputRect;
+ RECTL OutputRect;
+ RECTL ClipRect;
+ RECTL CombinedRect;
+ RECTL Rect;
+ POINTL Translate;
+ INTENG_ENTER_LEAVE EnterLeaveSource;
+ INTENG_ENTER_LEAVE EnterLeaveDest;
+ SURFOBJ* InputObj;
+ SURFOBJ* OutputObj;
+ LONG Width;
+ LONG ClippingType;
+ RECT_ENUM RectEnum;
+ BOOL EnumMore;
+ INT i;
+ BOOLEAN Ret;
+
+ DPRINT("EngAlphaBlend(psoDest:0x%p, psoSource:0x%p, ClipRegion:0x%p,
ColorTranslation:0x%p,\n", psoDest, psoSource, ClipRegion, ColorTranslation);
+ DPRINT(" DestRect:{0x%x, 0x%x, 0x%x, 0x%x}, SourceRect:{0x%x, 0x%x,
0x%x, 0x%x},\n",
+ DestRect->left, DestRect->top, DestRect->right, DestRect->bottom,
+ SourceRect->left, SourceRect->top, SourceRect->right,
SourceRect->bottom);
+ DPRINT(" BlendObj:{0x%x, 0x%x, 0x%x, 0x%x}\n",
BlendObj->BlendFunction.BlendOp,
+ BlendObj->BlendFunction.BlendFlags,
BlendObj->BlendFunction.SourceConstantAlpha,
+ BlendObj->BlendFunction.AlphaFormat);
+
+
+ /* Validate output */
+ OutputRect = *DestRect;
+ if (OutputRect.right < OutputRect.left)
+ {
+ OutputRect.left = DestRect->right;
+ OutputRect.right = DestRect->left;
+ }
+ if (OutputRect.bottom < OutputRect.top)
+ {
+ OutputRect.left = DestRect->right;
+ OutputRect.right = DestRect->left;
+ }
+
+
+ /* Validate input */
+
+ /* FIXME when WindowOrg.x or .y are negitve this check are not vaild,
+ * we need convert the inputRect to the windows org and do it right */
+ InputRect = *SourceRect;
+ if ( (InputRect.top < 0) || (InputRect.bottom < 0) ||
+ (InputRect.left < 0) || (InputRect.right < 0) )
+ {
+ SetLastWin32Error(ERROR_INVALID_PARAMETER);
+ return FALSE;
+ }
+
+ if (psoDest == psoSource &&
+ !(OutputRect.left >= SourceRect->right || InputRect.left >=
OutputRect.right ||
+ OutputRect.top >= SourceRect->bottom || InputRect.top >=
OutputRect.bottom))
+ {
+ DPRINT1("Source and destination rectangles overlap!\n");
+ return FALSE;
+ }
+
+ if (BlendObj->BlendFunction.BlendOp != AC_SRC_OVER)
+ {
+ DPRINT1("BlendOp != AC_SRC_OVER (0x%x)\n",
BlendObj->BlendFunction.BlendOp);
+ return FALSE;
+ }
+ if (BlendObj->BlendFunction.BlendFlags != 0)
+ {
+ DPRINT1("BlendFlags != 0 (0x%x)\n",
BlendObj->BlendFunction.BlendFlags);
+ return FALSE;
+ }
+ if ((BlendObj->BlendFunction.AlphaFormat & ~AC_SRC_ALPHA) != 0)
+ {
+ DPRINT1("Unsupported AlphaFormat (0x%x)\n",
BlendObj->BlendFunction.AlphaFormat);
+ return FALSE;
+ }
+
+ /* Check if there is anything to draw */
+ if (ClipRegion != NULL &&
+ (ClipRegion->rclBounds.left >= ClipRegion->rclBounds.right ||
+ ClipRegion->rclBounds.top >= ClipRegion->rclBounds.bottom))
+ {
+ /* Nothing to do */
+ return TRUE;
+ }
+
+ /* Stretch source if needed */
+ if (OutputRect.right - OutputRect.left != InputRect.right - InputRect.left ||
+ OutputRect.bottom - OutputRect.top != InputRect.bottom - InputRect.top)
+ {
+ SourceStretchedSize.cx = OutputRect.right - OutputRect.left;
+ SourceStretchedSize.cy = OutputRect.bottom - OutputRect.top;
+ Width = DIB_GetDIBWidthBytes(SourceStretchedSize.cx,
BitsPerFormat(psoSource->iBitmapFormat));
+ /* FIXME: Maybe it is a good idea to use EngCreateDeviceBitmap and
IntEngStretchBlt
+ if possible to get a HW accelerated stretch. */
+ SourceStretchedBitmap = EngCreateBitmap(SourceStretchedSize, Width,
psoSource->iBitmapFormat,
+ BMF_TOPDOWN | BMF_NOZEROINIT, NULL);
+ if (SourceStretchedBitmap == 0)
+ {
+ DPRINT1("EngCreateBitmap failed!\n");
+ return FALSE;
+ }
+ SourceStretchedObj = EngLockSurface((HSURF)SourceStretchedBitmap);
+ if (SourceStretchedObj == NULL)
+ {
+ DPRINT1("EngLockSurface failed!\n");
+ EngDeleteSurface((HSURF)SourceStretchedBitmap);
+ return FALSE;
+ }
+
+ SourceStretchedRect.left = 0;
+ SourceStretchedRect.right = SourceStretchedSize.cx;
+ SourceStretchedRect.top = 0;
+ SourceStretchedRect.bottom = SourceStretchedSize.cy;
+ /* FIXME: IntEngStretchBlt isn't used here atm because it results in a
+ try to acquire an already acquired mutex (lock the already locked
source surface) */
+ /*if (!IntEngStretchBlt(SourceStretchedObj, psoSource, NULL, NULL,
+ NULL, &SourceStretchedRect, SourceRect, NULL,
+ NULL, NULL, COLORONCOLOR))*/
+ if (!EngStretchBlt(SourceStretchedObj, psoSource, NULL, NULL, NULL,
+ NULL, NULL, &SourceStretchedRect, &InputRect,
+ NULL, COLORONCOLOR))
+ {
+ DPRINT1("EngStretchBlt failed!\n");
+ EngFreeMem(SourceStretchedObj->pvBits);
+ EngUnlockSurface(SourceStretchedObj);
+ EngDeleteSurface((HSURF)SourceStretchedBitmap);
+ return FALSE;
+ }
+ InputRect.top = SourceStretchedRect.top;
+ InputRect.bottom = SourceStretchedRect.bottom;
+ InputRect.left = SourceStretchedRect.left;
+ InputRect.right = SourceStretchedRect.right;
+ psoSource = SourceStretchedObj;
+ }
+
+ /* Now call the DIB function */
+ if (!IntEngEnter(&EnterLeaveSource, psoSource, &InputRect, TRUE,
&Translate, &InputObj))
+ {
+ if (SourceStretchedObj != NULL)
+ {
+ EngFreeMem(SourceStretchedObj->pvBits);
+ EngUnlockSurface(SourceStretchedObj);
+ }
+ if (SourceStretchedBitmap != 0)
+ {
+ EngDeleteSurface((HSURF)SourceStretchedBitmap);
+ }
+ return FALSE;
+ }
+ InputRect.left += Translate.x;
+ InputRect.right += Translate.x;
+ InputRect.top += Translate.y;
+ InputRect.bottom += Translate.y;
+
+ if (!IntEngEnter(&EnterLeaveDest, psoDest, &OutputRect, FALSE,
&Translate, &OutputObj))
+ {
+ IntEngLeave(&EnterLeaveSource);
+ if (SourceStretchedObj != NULL)
+ {
+ EngFreeMem(SourceStretchedObj->pvBits);
+ EngUnlockSurface(SourceStretchedObj);
+ }
+ if (SourceStretchedBitmap != 0)
+ {
+ EngDeleteSurface((HSURF)SourceStretchedBitmap);
+ }
+ return FALSE;
+ }
+ OutputRect.left += Translate.x;
+ OutputRect.right += Translate.x;
+ OutputRect.top += Translate.y;
+ OutputRect.bottom += Translate.y;
+
+ Ret = FALSE;
+ ClippingType = (ClipRegion == NULL) ? DC_TRIVIAL : ClipRegion->iDComplexity;
+ switch (ClippingType)
+ {
+ case DC_TRIVIAL:
+ Ret =
DibFunctionsForBitmapFormat[OutputObj->iBitmapFormat].DIB_AlphaBlend(
+ OutputObj, InputObj, &OutputRect, &InputRect, ClipRegion,
ColorTranslation, BlendObj);
+ break;
+
+ case DC_RECT:
+ 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;
+ if (RECTL_bIntersectRect(&CombinedRect, &OutputRect, &ClipRect))
+ {
+ Rect.left = InputRect.left + CombinedRect.left - OutputRect.left;
+ Rect.right = InputRect.right + CombinedRect.right - OutputRect.right;
+ Rect.top = InputRect.top + CombinedRect.top - OutputRect.top;
+ Rect.bottom = InputRect.bottom + CombinedRect.bottom -
OutputRect.bottom;
+ Ret =
DibFunctionsForBitmapFormat[OutputObj->iBitmapFormat].DIB_AlphaBlend(
+ OutputObj, InputObj, &CombinedRect, &Rect, ClipRegion,
ColorTranslation, BlendObj);
+ }
+ break;
+
+ case DC_COMPLEX:
+ Ret = TRUE;
+ CLIPOBJ_cEnumStart(ClipRegion, FALSE, CT_RECTANGLES, CD_ANY, 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;
+ if (RECTL_bIntersectRect(&CombinedRect, &OutputRect,
&ClipRect))
+ {
+ Rect.left = InputRect.left + CombinedRect.left -
OutputRect.left;
+ Rect.right = InputRect.right + CombinedRect.right -
OutputRect.right;
+ Rect.top = InputRect.top + CombinedRect.top - OutputRect.top;
+ Rect.bottom = InputRect.bottom + CombinedRect.bottom -
OutputRect.bottom;
+ Ret =
DibFunctionsForBitmapFormat[OutputObj->iBitmapFormat].DIB_AlphaBlend(
+ OutputObj, InputObj, &CombinedRect, &Rect,
ClipRegion, ColorTranslation, BlendObj) && Ret;
+ }
+ }
+ }
+ while (EnumMore);
+ break;
+
+ default:
+ UNIMPLEMENTED;
+ ASSERT(FALSE);
+ break;
+ }
+
+ IntEngLeave(&EnterLeaveDest);
+ IntEngLeave(&EnterLeaveSource);
+
+ if (SourceStretchedObj != NULL)
+ {
+ EngFreeMem(SourceStretchedObj->pvBits);
+ EngUnlockSurface(SourceStretchedObj);
+ }
+ if (SourceStretchedBitmap != 0)
+ {
+ EngDeleteSurface((HSURF)SourceStretchedBitmap);
+ }
+
+ return Ret;
+}
+
+BOOL APIENTRY
+IntEngAlphaBlend(IN SURFOBJ *psoDest,
+ IN SURFOBJ *psoSource,
+ IN CLIPOBJ *ClipRegion,
+ IN XLATEOBJ *ColorTranslation,
+ IN PRECTL DestRect,
+ IN PRECTL SourceRect,
+ IN BLENDOBJ *BlendObj)
+{
+ BOOL ret = FALSE;
+ SURFACE *psurfDest;
+ SURFACE *psurfSource;
+
+ ASSERT(psoDest);
+ psurfDest = CONTAINING_RECORD(psoDest, SURFACE, SurfObj);
+
+ ASSERT(psoSource);
+ psurfSource = CONTAINING_RECORD(psoSource, SURFACE, SurfObj);
+
+ ASSERT(DestRect);
+ ASSERT(SourceRect);
+
+ /* Check if there is anything to draw */
+ if (ClipRegion != NULL &&
+ (ClipRegion->rclBounds.left >= ClipRegion->rclBounds.right ||
+ ClipRegion->rclBounds.top >= ClipRegion->rclBounds.bottom))
+ {
+ /* Nothing to do */
+ return TRUE;
+ }
+
+ SURFACE_LockBitmapBits(psurfDest);
+ MouseSafetyOnDrawStart(psoDest, DestRect->left, DestRect->top,
+ DestRect->right, DestRect->bottom);
+
+ if (psoSource != psoDest)
+ SURFACE_LockBitmapBits(psurfSource);
+ MouseSafetyOnDrawStart(psoSource, SourceRect->left, SourceRect->top,
+ SourceRect->right, SourceRect->bottom);
+
+ /* Call the driver's DrvAlphaBlend if available */
+ if (psurfDest->flHooks & HOOK_ALPHABLEND)
+ {
+ ret = GDIDEVFUNCS(psoDest).AlphaBlend(
+ psoDest, psoSource, ClipRegion, ColorTranslation,
+ DestRect, SourceRect, BlendObj);
+ }
+
+ if (! ret)
+ {
+ ret = EngAlphaBlend(psoDest, psoSource, ClipRegion, ColorTranslation,
+ DestRect, SourceRect, BlendObj);
+ }
+
+ MouseSafetyOnDrawEnd(psoSource);
+ if (psoSource != psoDest)
+ SURFACE_UnlockBitmapBits(psurfSource);
+ MouseSafetyOnDrawEnd(psoDest);
+ SURFACE_UnlockBitmapBits(psurfDest);
+
+ return ret;
+}
+
+/*
+ * @implemented
+ */
+BOOL
+APIENTRY
+NtGdiEngAlphaBlend(IN SURFOBJ *psoDest,
+ IN SURFOBJ *psoSource,
+ IN CLIPOBJ *ClipRegion,
+ IN XLATEOBJ *ColorTranslation,
+ IN PRECTL upDestRect,
+ IN PRECTL upSourceRect,
+ IN BLENDOBJ *BlendObj)
+{
+ RECTL DestRect;
+ RECTL SourceRect;
+
+ _SEH2_TRY
+ {
+ ProbeForRead(upDestRect, sizeof(RECTL), 1);
+ RtlCopyMemory(&DestRect,upDestRect, sizeof(RECTL));
+
+ ProbeForRead(upSourceRect, sizeof(RECTL), 1);
+ RtlCopyMemory(&SourceRect, upSourceRect, sizeof(RECTL));
+
+ }
+ _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
+ {
+ _SEH2_YIELD(return FALSE);
+ }
+ _SEH2_END;
+
+ return EngAlphaBlend(psoDest, psoSource, ClipRegion, ColorTranslation, &DestRect,
&SourceRect, BlendObj);
+}
+
Propchange: trunk/reactos/subsystems/win32/win32k/eng/alphablend.c
------------------------------------------------------------------------------
svn:eol-style = native
Modified: trunk/reactos/subsystems/win32/win32k/eng/bitblt.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/subsystems/win32/win32k/en…
==============================================================================
--- trunk/reactos/subsystems/win32/win32k/eng/bitblt.c [iso-8859-1] (original)
+++ trunk/reactos/subsystems/win32/win32k/eng/bitblt.c [iso-8859-1] Sat Apr 11 03:53:09
2009
@@ -1,23 +1,4 @@
/*
- * 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.
- */
-/* $Id$
- *
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
* PURPOSE: GDI BitBlt Functions
@@ -42,39 +23,6 @@
BRUSHOBJ* pbo,
POINTL* BrushOrigin,
ROP4 Rop4);
-typedef BOOLEAN (APIENTRY *PSTRETCHRECTFUNC)(SURFOBJ* OutputObj,
- SURFOBJ* InputObj,
- SURFOBJ* Mask,
- XLATEOBJ* ColorTranslation,
- RECTL* OutputRect,
- RECTL* InputRect,
- POINTL* MaskOrigin,
- BRUSHOBJ* pbo,
- POINTL* BrushOrigin,
- ROP4 Rop4);
-
-BOOL APIENTRY EngIntersectRect(RECTL* prcDst, RECTL* prcSrc1, RECTL* prcSrc2)
-{
- static const RECTL rclEmpty = { 0, 0, 0, 0 };
-
- prcDst->left = max(prcSrc1->left, prcSrc2->left);
- prcDst->right = min(prcSrc1->right, prcSrc2->right);
-
- if (prcDst->left < prcDst->right)
- {
- prcDst->top = max(prcSrc1->top, prcSrc2->top);
- prcDst->bottom = min(prcSrc1->bottom, prcSrc2->bottom);
-
- if (prcDst->top < prcDst->bottom)
- {
- return TRUE;
- }
- }
-
- *prcDst = rclEmpty;
-
- return FALSE;
-}
static BOOLEAN APIENTRY
BltMask(SURFOBJ* psoDest,
@@ -539,7 +487,7 @@
ClipRect.right = ClipRegion->rclBounds.right + Translate.x;
ClipRect.top = ClipRegion->rclBounds.top + Translate.y;
ClipRect.bottom = ClipRegion->rclBounds.bottom + Translate.y;
- if (EngIntersectRect(&CombinedRect, &OutputRect, &ClipRect))
+ if (RECTL_bIntersectRect(&CombinedRect, &OutputRect, &ClipRect))
{
Pt.x = InputPoint.x + CombinedRect.left - OutputRect.left;
Pt.y = InputPoint.y + CombinedRect.top - OutputRect.top;
@@ -579,7 +527,7 @@
ClipRect.right = RectEnum.arcl[i].right + Translate.x;
ClipRect.top = RectEnum.arcl[i].top + Translate.y;
ClipRect.bottom = RectEnum.arcl[i].bottom + Translate.y;
- if (EngIntersectRect(&CombinedRect, &OutputRect,
&ClipRect))
+ if (RECTL_bIntersectRect(&CombinedRect, &OutputRect,
&ClipRect))
{
Pt.x = InputPoint.x + CombinedRect.left - OutputRect.left;
Pt.y = InputPoint.y + CombinedRect.top - OutputRect.top;
@@ -691,7 +639,7 @@
* outside the surface */
if (NULL != ClipRegion)
{
- if (! EngIntersectRect(&OutputRect, &InputClippedRect,
+ if (!RECTL_bIntersectRect(&OutputRect, &InputClippedRect,
&ClipRegion->rclBounds))
{
return TRUE;
@@ -760,891 +708,6 @@
return ret;
}
-static BOOLEAN APIENTRY
-CallDibStretchBlt(SURFOBJ* psoDest,
- SURFOBJ* psoSource,
- SURFOBJ* Mask,
- XLATEOBJ* ColorTranslation,
- RECTL* OutputRect,
- RECTL* InputRect,
- POINTL* MaskOrigin,
- BRUSHOBJ* pbo,
- POINTL* BrushOrigin,
- ROP4 Rop4)
-{
- POINTL RealBrushOrigin;
- SURFACE* psurfPattern;
- PEBRUSHOBJ GdiBrush = NULL;
- SURFOBJ* PatternSurface = NULL;
- XLATEOBJ* XlatePatternToDest = NULL;
-
- if (BrushOrigin == NULL)
- {
- RealBrushOrigin.x = RealBrushOrigin.y = 0;
- }
- else
- {
- RealBrushOrigin = *BrushOrigin;
- }
-
- /* Pattern brush */
- if (ROP4_USES_PATTERN(Rop4) && pbo && pbo->iSolidColor ==
0xFFFFFFFF)
- {
- GdiBrush = CONTAINING_RECORD(pbo, EBRUSHOBJ, BrushObject);
- psurfPattern = SURFACE_LockSurface(GdiBrush->pbrush->hbmPattern);
- if (psurfPattern)
- {
- PatternSurface = &psurfPattern->SurfObj;
- }
- else
- {
- /* FIXME - What to do here? */
- }
- XlatePatternToDest = GdiBrush->XlateObject;
- }
- else
- {
- psurfPattern = NULL;
- }
-
- return DibFunctionsForBitmapFormat[psoDest->iBitmapFormat].DIB_StretchBlt(
- psoDest, psoSource, Mask, PatternSurface,
- OutputRect, InputRect, MaskOrigin, pbo, &RealBrushOrigin,
- ColorTranslation, XlatePatternToDest, Rop4);
-
- /* Pattern brush */
- if (psurfPattern)
- {
- SURFACE_UnlockSurface(psurfPattern);
- }
-}
-
-
-BOOL
-APIENTRY
-NtGdiEngStretchBlt(
- IN SURFOBJ *psoDest,
- IN SURFOBJ *psoSource,
- IN SURFOBJ *Mask,
- IN CLIPOBJ *ClipRegion,
- IN XLATEOBJ *ColorTranslation,
- IN COLORADJUSTMENT *pca,
- IN POINTL *BrushOrigin,
- IN RECTL *prclDest,
- IN RECTL *prclSrc,
- IN POINTL *MaskOrigin,
- IN ULONG Mode)
-{
- COLORADJUSTMENT ca;
- POINTL lBrushOrigin;
- RECTL rclDest;
- RECTL rclSrc;
- POINTL lMaskOrigin;
-
- _SEH2_TRY
- {
- ProbeForRead(pca, sizeof(COLORADJUSTMENT), 1);
- RtlCopyMemory(&ca,pca, sizeof(COLORADJUSTMENT));
-
- ProbeForRead(BrushOrigin, sizeof(POINTL), 1);
- RtlCopyMemory(&lBrushOrigin, BrushOrigin, sizeof(POINTL));
-
- ProbeForRead(prclDest, sizeof(RECTL), 1);
- RtlCopyMemory(&rclDest, prclDest, sizeof(RECTL));
-
- ProbeForRead(prclSrc, sizeof(RECTL), 1);
- RtlCopyMemory(&rclSrc, prclSrc, sizeof(RECTL));
-
- ProbeForRead(MaskOrigin, sizeof(POINTL), 1);
- RtlCopyMemory(&lMaskOrigin, MaskOrigin, sizeof(POINTL));
-
- }
- _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
- {
- _SEH2_YIELD(return FALSE);
- }
- _SEH2_END;
-
- return EngStretchBlt(psoDest, psoSource, Mask, ClipRegion, ColorTranslation, &ca,
&lBrushOrigin, &rclDest, &rclSrc, &lMaskOrigin, Mode);
-}
-
-/*
- * @implemented
- */
-BOOL
-APIENTRY
-EngStretchBltROP(
- IN SURFOBJ *psoDest,
- IN SURFOBJ *psoSource,
- IN SURFOBJ *Mask,
- IN CLIPOBJ *ClipRegion,
- IN XLATEOBJ *ColorTranslation,
- IN COLORADJUSTMENT *pca,
- IN POINTL *BrushOrigin,
- IN RECTL *prclDest,
- IN RECTL *prclSrc,
- IN POINTL *MaskOrigin,
- IN ULONG Mode,
- IN BRUSHOBJ *pbo,
- IN DWORD ROP4)
-{
- RECTL InputRect;
- RECTL OutputRect;
- POINTL Translate;
- INTENG_ENTER_LEAVE EnterLeaveSource;
- INTENG_ENTER_LEAVE EnterLeaveDest;
- SURFOBJ* psoInput;
- SURFOBJ* psoOutput;
- PSTRETCHRECTFUNC BltRectFunc;
- BOOLEAN Ret = TRUE;
- POINTL AdjustedBrushOrigin;
- BOOL UsesSource = ROP4_USES_SOURCE(ROP4);
-
- BYTE clippingType;
- RECTL ClipRect;
- RECT_ENUM RectEnum;
- BOOL EnumMore;
- ULONG Direction;
- RECTL CombinedRect;
- RECTL InputToCombinedRect;
- unsigned i;
-
- LONG DstHeight;
- LONG DstWidth;
- LONG SrcHeight;
- LONG SrcWidth;
-
- /* Determine clipping type */
- if (ClipRegion == (CLIPOBJ *) NULL)
- {
- clippingType = DC_TRIVIAL;
- }
- else
- {
- clippingType = ClipRegion->iDComplexity;
- }
-
- if (ROP4 == R4_NOOP)
- {
- /* Copy destination onto itself: nop */
- return TRUE;
- }
-
- OutputRect = *prclDest;
- if (OutputRect.right < OutputRect.left)
- {
- OutputRect.left = prclDest->right;
- OutputRect.right = prclDest->left;
- }
- if (OutputRect.bottom < OutputRect.top)
- {
- OutputRect.top = prclDest->bottom;
- OutputRect.bottom = prclDest->top;
- }
-
- InputRect = *prclSrc;
- if (UsesSource)
- {
- if (NULL == prclSrc)
- {
- return FALSE;
- }
-
- if (! IntEngEnter(&EnterLeaveSource, psoSource, &InputRect, TRUE,
- &Translate, &psoInput))
- {
- return FALSE;
- }
-
- InputRect.left += Translate.x;
- InputRect.right += Translate.x;
- InputRect.top += Translate.y;
- InputRect.bottom += Translate.y;
- }
-
- if (NULL != ClipRegion)
- {
- if (OutputRect.left < ClipRegion->rclBounds.left)
- {
- InputRect.left += 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;
- 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)
- {
- if (UsesSource)
- {
- IntEngLeave(&EnterLeaveSource);
- }
- return TRUE;
- }
-
- if (! IntEngEnter(&EnterLeaveDest, psoDest, &OutputRect, FALSE,
&Translate, &psoOutput))
- {
- if (UsesSource)
- {
- IntEngLeave(&EnterLeaveSource);
- }
- return FALSE;
- }
-
- OutputRect.left += Translate.x;
- OutputRect.right += Translate.x;
- OutputRect.top += Translate.y;
- OutputRect.bottom += Translate.y;
-
- if (BrushOrigin)
- {
- AdjustedBrushOrigin.x = BrushOrigin->x + Translate.x;
- AdjustedBrushOrigin.y = BrushOrigin->y + Translate.y;
- }
- else
- {
- AdjustedBrushOrigin = Translate;
- }
-
- BltRectFunc = CallDibStretchBlt;
-
- DstHeight = OutputRect.bottom - OutputRect.top;
- DstWidth = OutputRect.right - OutputRect.left;
- SrcHeight = InputRect.bottom - InputRect.top;
- SrcWidth = InputRect.right - InputRect.left;
- switch (clippingType)
- {
- case DC_TRIVIAL:
- Ret = (*BltRectFunc)(psoOutput, psoInput, Mask,
- ColorTranslation, &OutputRect, &InputRect, MaskOrigin,
- pbo, &AdjustedBrushOrigin, ROP4);
- 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;
- if (EngIntersectRect(&CombinedRect, &OutputRect, &ClipRect))
- {
- InputToCombinedRect.top = InputRect.top + (CombinedRect.top -
OutputRect.top) * SrcHeight / DstHeight;
- InputToCombinedRect.bottom = InputRect.top + (CombinedRect.bottom -
OutputRect.top) * SrcHeight / DstHeight;
- InputToCombinedRect.left = InputRect.left + (CombinedRect.left -
OutputRect.left) * SrcWidth / DstWidth;
- InputToCombinedRect.right = InputRect.left + (CombinedRect.right -
OutputRect.left) * SrcWidth / DstWidth;
- Ret = (*BltRectFunc)(psoOutput, psoInput, Mask,
- ColorTranslation,
- &CombinedRect,
- &InputToCombinedRect,
- MaskOrigin,
- pbo,
- &AdjustedBrushOrigin,
- ROP4);
- }
- break;
- case DC_COMPLEX:
- if (psoOutput == psoInput)
- {
- if (OutputRect.top < InputRect.top)
- {
- Direction = OutputRect.left < InputRect.left ?
- CD_RIGHTDOWN : CD_LEFTDOWN;
- }
- else
- {
- Direction = OutputRect.left < InputRect.left ?
- 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;
- if (EngIntersectRect(&CombinedRect, &OutputRect,
&ClipRect))
- {
- InputToCombinedRect.top = InputRect.top + (CombinedRect.top -
OutputRect.top) * SrcHeight / DstHeight;
- InputToCombinedRect.bottom = InputRect.top + (CombinedRect.bottom
- OutputRect.top) * SrcHeight / DstHeight;
- InputToCombinedRect.left = InputRect.left + (CombinedRect.left -
OutputRect.left) * SrcWidth / DstWidth;
- InputToCombinedRect.right = InputRect.left + (CombinedRect.right
- OutputRect.left) * SrcWidth / DstWidth;
- Ret = (*BltRectFunc)(psoOutput, psoInput, Mask,
- ColorTranslation,
- &CombinedRect,
- &InputToCombinedRect,
- MaskOrigin,
- pbo,
- &AdjustedBrushOrigin,
- ROP4);
- }
- }
- }
- while (EnumMore);
- break;
- }
-
- IntEngLeave(&EnterLeaveDest);
- if (UsesSource)
- {
- IntEngLeave(&EnterLeaveSource);
- }
-
- return Ret;
-}
-
-/*
- * @implemented
- */
-BOOL
-APIENTRY
-EngStretchBlt(
- IN SURFOBJ *psoDest,
- IN SURFOBJ *psoSource,
- IN SURFOBJ *Mask,
- IN CLIPOBJ *ClipRegion,
- IN XLATEOBJ *ColorTranslation,
- IN COLORADJUSTMENT *pca,
- IN POINTL *BrushOrigin,
- IN RECTL *prclDest,
- IN RECTL *prclSrc,
- IN POINTL *MaskOrigin,
- IN ULONG Mode)
-{
- return EngStretchBltROP(
- psoDest,
- psoSource,
- Mask,
- ClipRegion,
- ColorTranslation,
- pca,
- BrushOrigin,
- prclDest,
- prclSrc,
- MaskOrigin,
- Mode,
- NULL,
- ROP3_TO_ROP4(SRCCOPY));
-}
-
-BOOL APIENTRY
-IntEngStretchBlt(SURFOBJ *psoDest,
- SURFOBJ *psoSource,
- SURFOBJ *MaskSurf,
- CLIPOBJ *ClipRegion,
- XLATEOBJ *ColorTranslation,
- RECTL *DestRect,
- RECTL *SourceRect,
- POINTL *pMaskOrigin,
- BRUSHOBJ *pbo,
- POINTL *BrushOrigin,
- ROP4 ROP)
-{
- BOOLEAN ret;
- COLORADJUSTMENT ca;
- POINT MaskOrigin;
- SURFACE *psurfDest;
- SURFACE *psurfSource = NULL;
- RECTL InputClippedRect;
- RECTL InputRect;
- RECTL OutputRect;
- BOOL UsesSource = ROP4_USES_SOURCE(ROP);
- LONG InputClWidth, InputClHeight, InputWidth, InputHeight;
-
- ASSERT(psoDest);
- psurfDest = CONTAINING_RECORD(psoDest, SURFACE, SurfObj);
- ASSERT(psurfDest);
- ASSERT(DestRect);
-
- InputClippedRect = *DestRect;
- if (InputClippedRect.right < InputClippedRect.left)
- {
- InputClippedRect.left = DestRect->right;
- InputClippedRect.right = DestRect->left;
- }
- if (InputClippedRect.bottom < InputClippedRect.top)
- {
- InputClippedRect.top = DestRect->bottom;
- InputClippedRect.bottom = DestRect->top;
- }
-
- if (UsesSource)
- {
- if (NULL == SourceRect || NULL == psoSource)
- {
- return FALSE;
- }
- InputRect = *SourceRect;
-
- if (InputRect.right < InputRect.left ||
- InputRect.bottom < InputRect.top)
- {
- /* Everything clipped away, nothing to do */
- return TRUE;
- }
- }
-
- if (ClipRegion)
- {
- if (! EngIntersectRect(&OutputRect, &InputClippedRect,
- &ClipRegion->rclBounds))
- {
- return TRUE;
- }
- /* Update source rect */
- InputClWidth = InputClippedRect.right - InputClippedRect.left;
- InputClHeight = InputClippedRect.bottom - InputClippedRect.top;
- InputWidth = InputRect.right - InputRect.left;
- InputHeight = InputRect.bottom - InputRect.top;
-
- InputRect.left += (InputWidth * (OutputRect.left - InputClippedRect.left)) /
InputClWidth;
- InputRect.right -= (InputWidth * (InputClippedRect.right - OutputRect.right)) /
InputClWidth;
- InputRect.top += (InputHeight * (OutputRect.top - InputClippedRect.top)) /
InputClHeight;
- InputRect.bottom -= (InputHeight * (InputClippedRect.bottom - OutputRect.bottom))
/ InputClHeight;
- }
- else
- {
- OutputRect = InputClippedRect;
- }
-
- if (pMaskOrigin != NULL)
- {
- MaskOrigin.x = pMaskOrigin->x; MaskOrigin.y = pMaskOrigin->y;
- }
-
- /* No success yet */
- ret = FALSE;
- SURFACE_LockBitmapBits(psurfDest);
- MouseSafetyOnDrawStart(psoDest, OutputRect.left, OutputRect.top,
- OutputRect.right, OutputRect.bottom);
-
- if (UsesSource)
- {
- psurfSource = CONTAINING_RECORD(psoSource, SURFACE, SurfObj);
- if (psoSource != psoDest)
- {
- SURFACE_LockBitmapBits(psurfSource);
- }
- MouseSafetyOnDrawStart(psoSource, InputRect.left, InputRect.top,
- InputRect.right, InputRect.bottom);
- }
-
- /* Prepare color adjustment */
-
- /* Call the driver's DrvStretchBlt if available */
- if (psurfDest->flHooks & HOOK_STRETCHBLTROP)
- {
- /* Drv->StretchBltROP (look at
http://www.osronline.com/ddkx/graphics/ddifncs_0z3b.htm ) */
- // FIXME: MaskOrigin is always NULL !
- ret = GDIDEVFUNCS(psoDest).StretchBltROP(psoDest, (UsesSource) ? psoSource :
NULL, MaskSurf, ClipRegion, ColorTranslation,
- &ca, BrushOrigin, &OutputRect, &InputRect, NULL,
COLORONCOLOR, pbo, ROP);
- }
-
- if (! ret)
- {
- // FIXME: see previous fixme
- ret = EngStretchBltROP(psoDest, (UsesSource) ? psoSource : NULL, MaskSurf,
ClipRegion, ColorTranslation,
- &ca, BrushOrigin, &OutputRect, &InputRect, NULL,
COLORONCOLOR, pbo, ROP);
- }
-
- if (UsesSource)
- {
- MouseSafetyOnDrawEnd(psoSource);
- if (psoSource != psoDest)
- {
- SURFACE_UnlockBitmapBits(psurfSource);
- }
- }
- MouseSafetyOnDrawEnd(psoDest);
- SURFACE_UnlockBitmapBits(psurfDest);
-
- return ret;
-}
-
-
-/*
- * @implemented
- */
-BOOL
-APIENTRY
-NtGdiEngAlphaBlend(IN SURFOBJ *psoDest,
- IN SURFOBJ *psoSource,
- IN CLIPOBJ *ClipRegion,
- IN XLATEOBJ *ColorTranslation,
- IN PRECTL upDestRect,
- IN PRECTL upSourceRect,
- IN BLENDOBJ *BlendObj)
-{
- RECTL DestRect;
- RECTL SourceRect;
-
- _SEH2_TRY
- {
- ProbeForRead(upDestRect, sizeof(RECTL), 1);
- RtlCopyMemory(&DestRect,upDestRect, sizeof(RECTL));
-
- ProbeForRead(upSourceRect, sizeof(RECTL), 1);
- RtlCopyMemory(&SourceRect, upSourceRect, sizeof(RECTL));
-
- }
- _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
- {
- _SEH2_YIELD(return FALSE);
- }
- _SEH2_END;
-
- return EngAlphaBlend(psoDest, psoSource, ClipRegion, ColorTranslation, &DestRect,
&SourceRect, BlendObj);
-}
-
-/*
- * @implemented
- */
-BOOL
-APIENTRY
-EngAlphaBlend(IN SURFOBJ *psoDest,
- IN SURFOBJ *psoSource,
- IN CLIPOBJ *ClipRegion,
- IN XLATEOBJ *ColorTranslation,
- IN PRECTL DestRect,
- IN PRECTL SourceRect,
- IN BLENDOBJ *BlendObj)
-{
- RECTL SourceStretchedRect;
- SIZEL SourceStretchedSize;
- HBITMAP SourceStretchedBitmap = 0;
- SURFOBJ* SourceStretchedObj = NULL;
- RECTL InputRect;
- RECTL OutputRect;
- RECTL ClipRect;
- RECTL CombinedRect;
- RECTL Rect;
- POINTL Translate;
- INTENG_ENTER_LEAVE EnterLeaveSource;
- INTENG_ENTER_LEAVE EnterLeaveDest;
- SURFOBJ* InputObj;
- SURFOBJ* OutputObj;
- LONG Width;
- LONG ClippingType;
- RECT_ENUM RectEnum;
- BOOL EnumMore;
- INT i;
- BOOLEAN Ret;
-
- DPRINT("EngAlphaBlend(psoDest:0x%p, psoSource:0x%p, ClipRegion:0x%p,
ColorTranslation:0x%p,\n", psoDest, psoSource, ClipRegion, ColorTranslation);
- DPRINT(" DestRect:{0x%x, 0x%x, 0x%x, 0x%x}, SourceRect:{0x%x, 0x%x,
0x%x, 0x%x},\n",
- DestRect->left, DestRect->top, DestRect->right, DestRect->bottom,
- SourceRect->left, SourceRect->top, SourceRect->right,
SourceRect->bottom);
- DPRINT(" BlendObj:{0x%x, 0x%x, 0x%x, 0x%x}\n",
BlendObj->BlendFunction.BlendOp,
- BlendObj->BlendFunction.BlendFlags,
BlendObj->BlendFunction.SourceConstantAlpha,
- BlendObj->BlendFunction.AlphaFormat);
-
-
- /* Validate output */
- OutputRect = *DestRect;
- if (OutputRect.right < OutputRect.left)
- {
- OutputRect.left = DestRect->right;
- OutputRect.right = DestRect->left;
- }
- if (OutputRect.bottom < OutputRect.top)
- {
- OutputRect.left = DestRect->right;
- OutputRect.right = DestRect->left;
- }
-
-
- /* Validate input */
-
- /* FIXME when WindowOrg.x or .y are negitve this check are not vaild,
- * we need convert the inputRect to the windows org and do it right */
- InputRect = *SourceRect;
- if ( (InputRect.top < 0) || (InputRect.bottom < 0) ||
- (InputRect.left < 0) || (InputRect.right < 0) )
- {
- SetLastWin32Error(ERROR_INVALID_PARAMETER);
- return FALSE;
- }
-
- if (psoDest == psoSource &&
- !(OutputRect.left >= SourceRect->right || InputRect.left >=
OutputRect.right ||
- OutputRect.top >= SourceRect->bottom || InputRect.top >=
OutputRect.bottom))
- {
- DPRINT1("Source and destination rectangles overlap!\n");
- return FALSE;
- }
-
- if (BlendObj->BlendFunction.BlendOp != AC_SRC_OVER)
- {
- DPRINT1("BlendOp != AC_SRC_OVER (0x%x)\n",
BlendObj->BlendFunction.BlendOp);
- return FALSE;
- }
- if (BlendObj->BlendFunction.BlendFlags != 0)
- {
- DPRINT1("BlendFlags != 0 (0x%x)\n",
BlendObj->BlendFunction.BlendFlags);
- return FALSE;
- }
- if ((BlendObj->BlendFunction.AlphaFormat & ~AC_SRC_ALPHA) != 0)
- {
- DPRINT1("Unsupported AlphaFormat (0x%x)\n",
BlendObj->BlendFunction.AlphaFormat);
- return FALSE;
- }
-
- /* Check if there is anything to draw */
- if (ClipRegion != NULL &&
- (ClipRegion->rclBounds.left >= ClipRegion->rclBounds.right ||
- ClipRegion->rclBounds.top >= ClipRegion->rclBounds.bottom))
- {
- /* Nothing to do */
- return TRUE;
- }
-
- /* Stretch source if needed */
- if (OutputRect.right - OutputRect.left != InputRect.right - InputRect.left ||
- OutputRect.bottom - OutputRect.top != InputRect.bottom - InputRect.top)
- {
- SourceStretchedSize.cx = OutputRect.right - OutputRect.left;
- SourceStretchedSize.cy = OutputRect.bottom - OutputRect.top;
- Width = DIB_GetDIBWidthBytes(SourceStretchedSize.cx,
BitsPerFormat(psoSource->iBitmapFormat));
- /* FIXME: Maybe it is a good idea to use EngCreateDeviceBitmap and
IntEngStretchBlt
- if possible to get a HW accelerated stretch. */
- SourceStretchedBitmap = EngCreateBitmap(SourceStretchedSize, Width,
psoSource->iBitmapFormat,
- BMF_TOPDOWN | BMF_NOZEROINIT, NULL);
- if (SourceStretchedBitmap == 0)
- {
- DPRINT1("EngCreateBitmap failed!\n");
- return FALSE;
- }
- SourceStretchedObj = EngLockSurface((HSURF)SourceStretchedBitmap);
- if (SourceStretchedObj == NULL)
- {
- DPRINT1("EngLockSurface failed!\n");
- EngDeleteSurface((HSURF)SourceStretchedBitmap);
- return FALSE;
- }
-
- SourceStretchedRect.left = 0;
- SourceStretchedRect.right = SourceStretchedSize.cx;
- SourceStretchedRect.top = 0;
- SourceStretchedRect.bottom = SourceStretchedSize.cy;
- /* FIXME: IntEngStretchBlt isn't used here atm because it results in a
- try to acquire an already acquired mutex (lock the already locked
source surface) */
- /*if (!IntEngStretchBlt(SourceStretchedObj, psoSource, NULL, NULL,
- NULL, &SourceStretchedRect, SourceRect, NULL,
- NULL, NULL, COLORONCOLOR))*/
- if (!EngStretchBlt(SourceStretchedObj, psoSource, NULL, NULL, NULL,
- NULL, NULL, &SourceStretchedRect, &InputRect,
- NULL, COLORONCOLOR))
- {
- DPRINT1("EngStretchBlt failed!\n");
- EngFreeMem(SourceStretchedObj->pvBits);
- EngUnlockSurface(SourceStretchedObj);
- EngDeleteSurface((HSURF)SourceStretchedBitmap);
- return FALSE;
- }
- InputRect.top = SourceStretchedRect.top;
- InputRect.bottom = SourceStretchedRect.bottom;
- InputRect.left = SourceStretchedRect.left;
- InputRect.right = SourceStretchedRect.right;
- psoSource = SourceStretchedObj;
- }
-
- /* Now call the DIB function */
- if (!IntEngEnter(&EnterLeaveSource, psoSource, &InputRect, TRUE,
&Translate, &InputObj))
- {
- if (SourceStretchedObj != NULL)
- {
- EngFreeMem(SourceStretchedObj->pvBits);
- EngUnlockSurface(SourceStretchedObj);
- }
- if (SourceStretchedBitmap != 0)
- {
- EngDeleteSurface((HSURF)SourceStretchedBitmap);
- }
- return FALSE;
- }
- InputRect.left += Translate.x;
- InputRect.right += Translate.x;
- InputRect.top += Translate.y;
- InputRect.bottom += Translate.y;
-
- if (!IntEngEnter(&EnterLeaveDest, psoDest, &OutputRect, FALSE,
&Translate, &OutputObj))
- {
- IntEngLeave(&EnterLeaveSource);
- if (SourceStretchedObj != NULL)
- {
- EngFreeMem(SourceStretchedObj->pvBits);
- EngUnlockSurface(SourceStretchedObj);
- }
- if (SourceStretchedBitmap != 0)
- {
- EngDeleteSurface((HSURF)SourceStretchedBitmap);
- }
- return FALSE;
- }
- OutputRect.left += Translate.x;
- OutputRect.right += Translate.x;
- OutputRect.top += Translate.y;
- OutputRect.bottom += Translate.y;
-
- Ret = FALSE;
- ClippingType = (ClipRegion == NULL) ? DC_TRIVIAL : ClipRegion->iDComplexity;
- switch (ClippingType)
- {
- case DC_TRIVIAL:
- Ret =
DibFunctionsForBitmapFormat[OutputObj->iBitmapFormat].DIB_AlphaBlend(
- OutputObj, InputObj, &OutputRect, &InputRect, ClipRegion,
ColorTranslation, BlendObj);
- break;
-
- case DC_RECT:
- 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;
- if (EngIntersectRect(&CombinedRect, &OutputRect, &ClipRect))
- {
- Rect.left = InputRect.left + CombinedRect.left - OutputRect.left;
- Rect.right = InputRect.right + CombinedRect.right - OutputRect.right;
- Rect.top = InputRect.top + CombinedRect.top - OutputRect.top;
- Rect.bottom = InputRect.bottom + CombinedRect.bottom -
OutputRect.bottom;
- Ret =
DibFunctionsForBitmapFormat[OutputObj->iBitmapFormat].DIB_AlphaBlend(
- OutputObj, InputObj, &CombinedRect, &Rect, ClipRegion,
ColorTranslation, BlendObj);
- }
- break;
-
- case DC_COMPLEX:
- Ret = TRUE;
- CLIPOBJ_cEnumStart(ClipRegion, FALSE, CT_RECTANGLES, CD_ANY, 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;
- if (EngIntersectRect(&CombinedRect, &OutputRect,
&ClipRect))
- {
- Rect.left = InputRect.left + CombinedRect.left -
OutputRect.left;
- Rect.right = InputRect.right + CombinedRect.right -
OutputRect.right;
- Rect.top = InputRect.top + CombinedRect.top - OutputRect.top;
- Rect.bottom = InputRect.bottom + CombinedRect.bottom -
OutputRect.bottom;
- Ret =
DibFunctionsForBitmapFormat[OutputObj->iBitmapFormat].DIB_AlphaBlend(
- OutputObj, InputObj, &CombinedRect, &Rect,
ClipRegion, ColorTranslation, BlendObj) && Ret;
- }
- }
- }
- while (EnumMore);
- break;
-
- default:
- UNIMPLEMENTED;
- ASSERT(FALSE);
- break;
- }
-
- IntEngLeave(&EnterLeaveDest);
- IntEngLeave(&EnterLeaveSource);
-
- if (SourceStretchedObj != NULL)
- {
- EngFreeMem(SourceStretchedObj->pvBits);
- EngUnlockSurface(SourceStretchedObj);
- }
- if (SourceStretchedBitmap != 0)
- {
- EngDeleteSurface((HSURF)SourceStretchedBitmap);
- }
-
- return Ret;
-}
-
-BOOL APIENTRY
-IntEngAlphaBlend(IN SURFOBJ *psoDest,
- IN SURFOBJ *psoSource,
- IN CLIPOBJ *ClipRegion,
- IN XLATEOBJ *ColorTranslation,
- IN PRECTL DestRect,
- IN PRECTL SourceRect,
- IN BLENDOBJ *BlendObj)
-{
- BOOL ret = FALSE;
- SURFACE *psurfDest;
- SURFACE *psurfSource;
-
- ASSERT(psoDest);
- psurfDest = CONTAINING_RECORD(psoDest, SURFACE, SurfObj);
-
- ASSERT(psoSource);
- psurfSource = CONTAINING_RECORD(psoSource, SURFACE, SurfObj);
-
- ASSERT(DestRect);
- ASSERT(SourceRect);
-
- /* Check if there is anything to draw */
- if (ClipRegion != NULL &&
- (ClipRegion->rclBounds.left >= ClipRegion->rclBounds.right ||
- ClipRegion->rclBounds.top >= ClipRegion->rclBounds.bottom))
- {
- /* Nothing to do */
- return TRUE;
- }
-
- SURFACE_LockBitmapBits(psurfDest);
- MouseSafetyOnDrawStart(psoDest, DestRect->left, DestRect->top,
- DestRect->right, DestRect->bottom);
-
- if (psoSource != psoDest)
- SURFACE_LockBitmapBits(psurfSource);
- MouseSafetyOnDrawStart(psoSource, SourceRect->left, SourceRect->top,
- SourceRect->right, SourceRect->bottom);
-
- /* Call the driver's DrvAlphaBlend if available */
- if (psurfDest->flHooks & HOOK_ALPHABLEND)
- {
- ret = GDIDEVFUNCS(psoDest).AlphaBlend(
- psoDest, psoSource, ClipRegion, ColorTranslation,
- DestRect, SourceRect, BlendObj);
- }
-
- if (! ret)
- {
- ret = EngAlphaBlend(psoDest, psoSource, ClipRegion, ColorTranslation,
- DestRect, SourceRect, BlendObj);
- }
-
- MouseSafetyOnDrawEnd(psoSource);
- if (psoSource != psoDest)
- SURFACE_UnlockBitmapBits(psurfSource);
- MouseSafetyOnDrawEnd(psoDest);
- SURFACE_UnlockBitmapBits(psurfDest);
-
- return ret;
-}
/**** REACTOS FONT RENDERING CODE *********************************************/
@@ -1849,7 +912,7 @@
ClipRect.right = ClipRegion->rclBounds.right + Translate.x;
ClipRect.top = ClipRegion->rclBounds.top + Translate.y;
ClipRect.bottom = ClipRegion->rclBounds.bottom + Translate.y;
- if (EngIntersectRect(&CombinedRect, &OutputRect, &ClipRect))
+ if (RECTL_bIntersectRect(&CombinedRect, &OutputRect, &ClipRect))
{
Pt.x = InputPoint.x + CombinedRect.left - OutputRect.left;
Pt.y = InputPoint.y + CombinedRect.top - OutputRect.top;
@@ -1893,7 +956,7 @@
ClipRect.right = RectEnum.arcl[i].right + Translate.x;
ClipRect.top = RectEnum.arcl[i].top + Translate.y;
ClipRect.bottom = RectEnum.arcl[i].bottom + Translate.y;
- if (EngIntersectRect(&CombinedRect, &OutputRect,
&ClipRect))
+ if (RECTL_bIntersectRect(&CombinedRect, &OutputRect,
&ClipRect))
{
Pt.x = InputPoint.x + CombinedRect.left - OutputRect.left;
Pt.y = InputPoint.y + CombinedRect.top - OutputRect.top;
@@ -1953,7 +1016,7 @@
* outside the surface */
if (NULL != ClipRegion)
{
- if (! EngIntersectRect(&OutputRect, DestRect,
&ClipRegion->rclBounds))
+ if (!RECTL_bIntersectRect(&OutputRect, DestRect,
&ClipRegion->rclBounds))
{
return TRUE;
}
Modified: trunk/reactos/subsystems/win32/win32k/eng/copybits.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/subsystems/win32/win32k/en…
==============================================================================
--- trunk/reactos/subsystems/win32/win32k/eng/copybits.c [iso-8859-1] (original)
+++ trunk/reactos/subsystems/win32/win32k/eng/copybits.c [iso-8859-1] Sat Apr 11 03:53:09
2009
@@ -155,7 +155,7 @@
case DC_RECT:
// Clip the blt to the clip rectangle
- EngIntersectRect(&BltInfo.DestRect, DestRect, &Clip->rclBounds);
+ RECTL_bIntersectRect(&BltInfo.DestRect, DestRect, &Clip->rclBounds);
BltInfo.SourcePoint.x = SourcePoint->x + BltInfo.DestRect.left -
DestRect->left;
BltInfo.SourcePoint.y = SourcePoint->y + BltInfo.DestRect.top -
DestRect->top;
@@ -183,7 +183,7 @@
RECTL* prcl = &RectEnum.arcl[0];
do {
- EngIntersectRect(&BltInfo.DestRect, prcl, DestRect);
+ RECTL_bIntersectRect(&BltInfo.DestRect, prcl, DestRect);
BltInfo.SourcePoint.x = SourcePoint->x + prcl->left -
DestRect->left;
BltInfo.SourcePoint.y = SourcePoint->y + prcl->top -
DestRect->top;
Added: trunk/reactos/subsystems/win32/win32k/eng/stretchblt.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/subsystems/win32/win32k/en…
==============================================================================
--- trunk/reactos/subsystems/win32/win32k/eng/stretchblt.c (added)
+++ trunk/reactos/subsystems/win32/win32k/eng/stretchblt.c [iso-8859-1] Sat Apr 11
03:53:09 2009
@@ -1,0 +1,548 @@
+/*
+ * COPYRIGHT: See COPYING in the top level directory
+ * PROJECT: ReactOS kernel
+ * PURPOSE: GDI stretch blt functions
+ * FILE: subsystems/win32/win32k/eng/stretchblt.c
+ * PROGRAMER: Jason Filby
+ */
+
+#include <w32k.h>
+
+#define NDEBUG
+#include <debug.h>
+
+typedef BOOLEAN (APIENTRY *PSTRETCHRECTFUNC)(SURFOBJ* OutputObj,
+ SURFOBJ* InputObj,
+ SURFOBJ* Mask,
+ XLATEOBJ* ColorTranslation,
+ RECTL* OutputRect,
+ RECTL* InputRect,
+ POINTL* MaskOrigin,
+ BRUSHOBJ* pbo,
+ POINTL* BrushOrigin,
+ ROP4 Rop4);
+
+static BOOLEAN APIENTRY
+CallDibStretchBlt(SURFOBJ* psoDest,
+ SURFOBJ* psoSource,
+ SURFOBJ* Mask,
+ XLATEOBJ* ColorTranslation,
+ RECTL* OutputRect,
+ RECTL* InputRect,
+ POINTL* MaskOrigin,
+ BRUSHOBJ* pbo,
+ POINTL* BrushOrigin,
+ ROP4 Rop4)
+{
+ POINTL RealBrushOrigin;
+ SURFACE* psurfPattern;
+ PEBRUSHOBJ GdiBrush = NULL;
+ SURFOBJ* PatternSurface = NULL;
+ XLATEOBJ* XlatePatternToDest = NULL;
+
+ if (BrushOrigin == NULL)
+ {
+ RealBrushOrigin.x = RealBrushOrigin.y = 0;
+ }
+ else
+ {
+ RealBrushOrigin = *BrushOrigin;
+ }
+
+ /* Pattern brush */
+ if (ROP4_USES_PATTERN(Rop4) && pbo && pbo->iSolidColor ==
0xFFFFFFFF)
+ {
+ GdiBrush = CONTAINING_RECORD(pbo, EBRUSHOBJ, BrushObject);
+ psurfPattern = SURFACE_LockSurface(GdiBrush->pbrush->hbmPattern);
+ if (psurfPattern)
+ {
+ PatternSurface = &psurfPattern->SurfObj;
+ }
+ else
+ {
+ /* FIXME - What to do here? */
+ }
+ XlatePatternToDest = GdiBrush->XlateObject;
+ }
+ else
+ {
+ psurfPattern = NULL;
+ }
+
+ return DibFunctionsForBitmapFormat[psoDest->iBitmapFormat].DIB_StretchBlt(
+ psoDest, psoSource, Mask, PatternSurface,
+ OutputRect, InputRect, MaskOrigin, pbo, &RealBrushOrigin,
+ ColorTranslation, XlatePatternToDest, Rop4);
+
+ /* Pattern brush */
+ if (psurfPattern)
+ {
+ SURFACE_UnlockSurface(psurfPattern);
+ }
+}
+
+
+
+/*
+ * @implemented
+ */
+BOOL
+APIENTRY
+EngStretchBltROP(
+ IN SURFOBJ *psoDest,
+ IN SURFOBJ *psoSource,
+ IN SURFOBJ *Mask,
+ IN CLIPOBJ *ClipRegion,
+ IN XLATEOBJ *ColorTranslation,
+ IN COLORADJUSTMENT *pca,
+ IN POINTL *BrushOrigin,
+ IN RECTL *prclDest,
+ IN RECTL *prclSrc,
+ IN POINTL *MaskOrigin,
+ IN ULONG Mode,
+ IN BRUSHOBJ *pbo,
+ IN DWORD ROP4)
+{
+ RECTL InputRect;
+ RECTL OutputRect;
+ POINTL Translate;
+ INTENG_ENTER_LEAVE EnterLeaveSource;
+ INTENG_ENTER_LEAVE EnterLeaveDest;
+ SURFOBJ* psoInput;
+ SURFOBJ* psoOutput;
+ PSTRETCHRECTFUNC BltRectFunc;
+ BOOLEAN Ret = TRUE;
+ POINTL AdjustedBrushOrigin;
+ BOOL UsesSource = ROP4_USES_SOURCE(ROP4);
+
+ BYTE clippingType;
+ RECTL ClipRect;
+ RECT_ENUM RectEnum;
+ BOOL EnumMore;
+ ULONG Direction;
+ RECTL CombinedRect;
+ RECTL InputToCombinedRect;
+ unsigned i;
+
+ LONG DstHeight;
+ LONG DstWidth;
+ LONG SrcHeight;
+ LONG SrcWidth;
+
+ /* Determine clipping type */
+ if (ClipRegion == (CLIPOBJ *) NULL)
+ {
+ clippingType = DC_TRIVIAL;
+ }
+ else
+ {
+ clippingType = ClipRegion->iDComplexity;
+ }
+
+ if (ROP4 == R4_NOOP)
+ {
+ /* Copy destination onto itself: nop */
+ return TRUE;
+ }
+
+ OutputRect = *prclDest;
+ if (OutputRect.right < OutputRect.left)
+ {
+ OutputRect.left = prclDest->right;
+ OutputRect.right = prclDest->left;
+ }
+ if (OutputRect.bottom < OutputRect.top)
+ {
+ OutputRect.top = prclDest->bottom;
+ OutputRect.bottom = prclDest->top;
+ }
+
+ InputRect = *prclSrc;
+ if (UsesSource)
+ {
+ if (NULL == prclSrc)
+ {
+ return FALSE;
+ }
+
+ if (! IntEngEnter(&EnterLeaveSource, psoSource, &InputRect, TRUE,
+ &Translate, &psoInput))
+ {
+ return FALSE;
+ }
+
+ InputRect.left += Translate.x;
+ InputRect.right += Translate.x;
+ InputRect.top += Translate.y;
+ InputRect.bottom += Translate.y;
+ }
+
+ if (NULL != ClipRegion)
+ {
+ if (OutputRect.left < ClipRegion->rclBounds.left)
+ {
+ InputRect.left += 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;
+ 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)
+ {
+ if (UsesSource)
+ {
+ IntEngLeave(&EnterLeaveSource);
+ }
+ return TRUE;
+ }
+
+ if (! IntEngEnter(&EnterLeaveDest, psoDest, &OutputRect, FALSE,
&Translate, &psoOutput))
+ {
+ if (UsesSource)
+ {
+ IntEngLeave(&EnterLeaveSource);
+ }
+ return FALSE;
+ }
+
+ OutputRect.left += Translate.x;
+ OutputRect.right += Translate.x;
+ OutputRect.top += Translate.y;
+ OutputRect.bottom += Translate.y;
+
+ if (BrushOrigin)
+ {
+ AdjustedBrushOrigin.x = BrushOrigin->x + Translate.x;
+ AdjustedBrushOrigin.y = BrushOrigin->y + Translate.y;
+ }
+ else
+ {
+ AdjustedBrushOrigin = Translate;
+ }
+
+ BltRectFunc = CallDibStretchBlt;
+
+ DstHeight = OutputRect.bottom - OutputRect.top;
+ DstWidth = OutputRect.right - OutputRect.left;
+ SrcHeight = InputRect.bottom - InputRect.top;
+ SrcWidth = InputRect.right - InputRect.left;
+ switch (clippingType)
+ {
+ case DC_TRIVIAL:
+ Ret = (*BltRectFunc)(psoOutput, psoInput, Mask,
+ ColorTranslation, &OutputRect, &InputRect, MaskOrigin,
+ pbo, &AdjustedBrushOrigin, ROP4);
+ 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;
+ if (RECTL_bIntersectRect(&CombinedRect, &OutputRect, &ClipRect))
+ {
+ InputToCombinedRect.top = InputRect.top + (CombinedRect.top -
OutputRect.top) * SrcHeight / DstHeight;
+ InputToCombinedRect.bottom = InputRect.top + (CombinedRect.bottom -
OutputRect.top) * SrcHeight / DstHeight;
+ InputToCombinedRect.left = InputRect.left + (CombinedRect.left -
OutputRect.left) * SrcWidth / DstWidth;
+ InputToCombinedRect.right = InputRect.left + (CombinedRect.right -
OutputRect.left) * SrcWidth / DstWidth;
+ Ret = (*BltRectFunc)(psoOutput, psoInput, Mask,
+ ColorTranslation,
+ &CombinedRect,
+ &InputToCombinedRect,
+ MaskOrigin,
+ pbo,
+ &AdjustedBrushOrigin,
+ ROP4);
+ }
+ break;
+ case DC_COMPLEX:
+ if (psoOutput == psoInput)
+ {
+ if (OutputRect.top < InputRect.top)
+ {
+ Direction = OutputRect.left < InputRect.left ?
+ CD_RIGHTDOWN : CD_LEFTDOWN;
+ }
+ else
+ {
+ Direction = OutputRect.left < InputRect.left ?
+ 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;
+ if (RECTL_bIntersectRect(&CombinedRect, &OutputRect,
&ClipRect))
+ {
+ InputToCombinedRect.top = InputRect.top + (CombinedRect.top -
OutputRect.top) * SrcHeight / DstHeight;
+ InputToCombinedRect.bottom = InputRect.top + (CombinedRect.bottom
- OutputRect.top) * SrcHeight / DstHeight;
+ InputToCombinedRect.left = InputRect.left + (CombinedRect.left -
OutputRect.left) * SrcWidth / DstWidth;
+ InputToCombinedRect.right = InputRect.left + (CombinedRect.right
- OutputRect.left) * SrcWidth / DstWidth;
+ Ret = (*BltRectFunc)(psoOutput, psoInput, Mask,
+ ColorTranslation,
+ &CombinedRect,
+ &InputToCombinedRect,
+ MaskOrigin,
+ pbo,
+ &AdjustedBrushOrigin,
+ ROP4);
+ }
+ }
+ }
+ while (EnumMore);
+ break;
+ }
+
+ IntEngLeave(&EnterLeaveDest);
+ if (UsesSource)
+ {
+ IntEngLeave(&EnterLeaveSource);
+ }
+
+ return Ret;
+}
+
+/*
+ * @implemented
+ */
+BOOL
+APIENTRY
+EngStretchBlt(
+ IN SURFOBJ *psoDest,
+ IN SURFOBJ *psoSource,
+ IN SURFOBJ *Mask,
+ IN CLIPOBJ *ClipRegion,
+ IN XLATEOBJ *ColorTranslation,
+ IN COLORADJUSTMENT *pca,
+ IN POINTL *BrushOrigin,
+ IN RECTL *prclDest,
+ IN RECTL *prclSrc,
+ IN POINTL *MaskOrigin,
+ IN ULONG Mode)
+{
+ return EngStretchBltROP(
+ psoDest,
+ psoSource,
+ Mask,
+ ClipRegion,
+ ColorTranslation,
+ pca,
+ BrushOrigin,
+ prclDest,
+ prclSrc,
+ MaskOrigin,
+ Mode,
+ NULL,
+ ROP3_TO_ROP4(SRCCOPY));
+}
+
+BOOL APIENTRY
+IntEngStretchBlt(SURFOBJ *psoDest,
+ SURFOBJ *psoSource,
+ SURFOBJ *MaskSurf,
+ CLIPOBJ *ClipRegion,
+ XLATEOBJ *ColorTranslation,
+ RECTL *DestRect,
+ RECTL *SourceRect,
+ POINTL *pMaskOrigin,
+ BRUSHOBJ *pbo,
+ POINTL *BrushOrigin,
+ ROP4 ROP)
+{
+ BOOLEAN ret;
+ COLORADJUSTMENT ca;
+ POINT MaskOrigin;
+ SURFACE *psurfDest;
+ SURFACE *psurfSource = NULL;
+ RECTL InputClippedRect;
+ RECTL InputRect;
+ RECTL OutputRect;
+ BOOL UsesSource = ROP4_USES_SOURCE(ROP);
+ LONG InputClWidth, InputClHeight, InputWidth, InputHeight;
+
+ ASSERT(psoDest);
+ psurfDest = CONTAINING_RECORD(psoDest, SURFACE, SurfObj);
+ ASSERT(psurfDest);
+ ASSERT(DestRect);
+
+ InputClippedRect = *DestRect;
+ if (InputClippedRect.right < InputClippedRect.left)
+ {
+ InputClippedRect.left = DestRect->right;
+ InputClippedRect.right = DestRect->left;
+ }
+ if (InputClippedRect.bottom < InputClippedRect.top)
+ {
+ InputClippedRect.top = DestRect->bottom;
+ InputClippedRect.bottom = DestRect->top;
+ }
+
+ if (UsesSource)
+ {
+ if (NULL == SourceRect || NULL == psoSource)
+ {
+ return FALSE;
+ }
+ InputRect = *SourceRect;
+
+ if (InputRect.right < InputRect.left ||
+ InputRect.bottom < InputRect.top)
+ {
+ /* Everything clipped away, nothing to do */
+ return TRUE;
+ }
+ }
+
+ if (ClipRegion)
+ {
+ if (!RECTL_bIntersectRect(&OutputRect, &InputClippedRect,
+ &ClipRegion->rclBounds))
+ {
+ return TRUE;
+ }
+ /* Update source rect */
+ InputClWidth = InputClippedRect.right - InputClippedRect.left;
+ InputClHeight = InputClippedRect.bottom - InputClippedRect.top;
+ InputWidth = InputRect.right - InputRect.left;
+ InputHeight = InputRect.bottom - InputRect.top;
+
+ InputRect.left += (InputWidth * (OutputRect.left - InputClippedRect.left)) /
InputClWidth;
+ InputRect.right -= (InputWidth * (InputClippedRect.right - OutputRect.right)) /
InputClWidth;
+ InputRect.top += (InputHeight * (OutputRect.top - InputClippedRect.top)) /
InputClHeight;
+ InputRect.bottom -= (InputHeight * (InputClippedRect.bottom - OutputRect.bottom))
/ InputClHeight;
+ }
+ else
+ {
+ OutputRect = InputClippedRect;
+ }
+
+ if (pMaskOrigin != NULL)
+ {
+ MaskOrigin.x = pMaskOrigin->x; MaskOrigin.y = pMaskOrigin->y;
+ }
+
+ /* No success yet */
+ ret = FALSE;
+ SURFACE_LockBitmapBits(psurfDest);
+ MouseSafetyOnDrawStart(psoDest, OutputRect.left, OutputRect.top,
+ OutputRect.right, OutputRect.bottom);
+
+ if (UsesSource)
+ {
+ psurfSource = CONTAINING_RECORD(psoSource, SURFACE, SurfObj);
+ if (psoSource != psoDest)
+ {
+ SURFACE_LockBitmapBits(psurfSource);
+ }
+ MouseSafetyOnDrawStart(psoSource, InputRect.left, InputRect.top,
+ InputRect.right, InputRect.bottom);
+ }
+
+ /* Prepare color adjustment */
+
+ /* Call the driver's DrvStretchBlt if available */
+ if (psurfDest->flHooks & HOOK_STRETCHBLTROP)
+ {
+ /* Drv->StretchBltROP (look at
http://www.osronline.com/ddkx/graphics/ddifncs_0z3b.htm ) */
+ // FIXME: MaskOrigin is always NULL !
+ ret = GDIDEVFUNCS(psoDest).StretchBltROP(psoDest, (UsesSource) ? psoSource :
NULL, MaskSurf, ClipRegion, ColorTranslation,
+ &ca, BrushOrigin, &OutputRect, &InputRect, NULL,
COLORONCOLOR, pbo, ROP);
+ }
+
+ if (! ret)
+ {
+ // FIXME: see previous fixme
+ ret = EngStretchBltROP(psoDest, (UsesSource) ? psoSource : NULL, MaskSurf,
ClipRegion, ColorTranslation,
+ &ca, BrushOrigin, &OutputRect, &InputRect, NULL,
COLORONCOLOR, pbo, ROP);
+ }
+
+ if (UsesSource)
+ {
+ MouseSafetyOnDrawEnd(psoSource);
+ if (psoSource != psoDest)
+ {
+ SURFACE_UnlockBitmapBits(psurfSource);
+ }
+ }
+ MouseSafetyOnDrawEnd(psoDest);
+ SURFACE_UnlockBitmapBits(psurfDest);
+
+ return ret;
+}
+
+BOOL
+APIENTRY
+NtGdiEngStretchBlt(
+ IN SURFOBJ *psoDest,
+ IN SURFOBJ *psoSource,
+ IN SURFOBJ *Mask,
+ IN CLIPOBJ *ClipRegion,
+ IN XLATEOBJ *ColorTranslation,
+ IN COLORADJUSTMENT *pca,
+ IN POINTL *BrushOrigin,
+ IN RECTL *prclDest,
+ IN RECTL *prclSrc,
+ IN POINTL *MaskOrigin,
+ IN ULONG Mode)
+{
+ COLORADJUSTMENT ca;
+ POINTL lBrushOrigin;
+ RECTL rclDest;
+ RECTL rclSrc;
+ POINTL lMaskOrigin;
+
+ _SEH2_TRY
+ {
+ ProbeForRead(pca, sizeof(COLORADJUSTMENT), 1);
+ RtlCopyMemory(&ca,pca, sizeof(COLORADJUSTMENT));
+
+ ProbeForRead(BrushOrigin, sizeof(POINTL), 1);
+ RtlCopyMemory(&lBrushOrigin, BrushOrigin, sizeof(POINTL));
+
+ ProbeForRead(prclDest, sizeof(RECTL), 1);
+ RtlCopyMemory(&rclDest, prclDest, sizeof(RECTL));
+
+ ProbeForRead(prclSrc, sizeof(RECTL), 1);
+ RtlCopyMemory(&rclSrc, prclSrc, sizeof(RECTL));
+
+ ProbeForRead(MaskOrigin, sizeof(POINTL), 1);
+ RtlCopyMemory(&lMaskOrigin, MaskOrigin, sizeof(POINTL));
+
+ }
+ _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
+ {
+ _SEH2_YIELD(return FALSE);
+ }
+ _SEH2_END;
+
+ return EngStretchBlt(psoDest, psoSource, Mask, ClipRegion, ColorTranslation, &ca,
&lBrushOrigin, &rclDest, &rclSrc, &lMaskOrigin, Mode);
+}
+
Propchange: trunk/reactos/subsystems/win32/win32k/eng/stretchblt.c
------------------------------------------------------------------------------
svn:eol-style = native
Modified: trunk/reactos/subsystems/win32/win32k/eng/transblt.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/subsystems/win32/win32k/en…
==============================================================================
--- trunk/reactos/subsystems/win32/win32k/eng/transblt.c [iso-8859-1] (original)
+++ trunk/reactos/subsystems/win32/win32k/eng/transblt.c [iso-8859-1] Sat Apr 11 03:53:09
2009
@@ -143,7 +143,7 @@
ClipRect.right = Clip->rclBounds.right + Translate.x;
ClipRect.top = Clip->rclBounds.top + Translate.y;
ClipRect.bottom = Clip->rclBounds.bottom + Translate.y;
- if (EngIntersectRect(&CombinedRect, &OutputRect, &ClipRect))
+ if (RECTL_bIntersectRect(&CombinedRect, &OutputRect, &ClipRect))
{
InputToCombinedRect.top = InputRect.top + (CombinedRect.top - OutputRect.top) *
SrcHeight / DstHeight;
InputToCombinedRect.bottom = InputRect.top + (CombinedRect.bottom -
OutputRect.top) * SrcHeight / DstHeight;
@@ -189,7 +189,7 @@
ClipRect.right = RectEnum.arcl[i].right + Translate.x;
ClipRect.top = RectEnum.arcl[i].top + Translate.y;
ClipRect.bottom = RectEnum.arcl[i].bottom + Translate.y;
- if (EngIntersectRect(&CombinedRect, &OutputRect, &ClipRect))
+ if (RECTL_bIntersectRect(&CombinedRect, &OutputRect, &ClipRect))
{
InputToCombinedRect.top = InputRect.top + (CombinedRect.top - OutputRect.top)
* SrcHeight / DstHeight;
InputToCombinedRect.bottom = InputRect.top + (CombinedRect.bottom -
OutputRect.top) * SrcHeight / DstHeight;
@@ -264,7 +264,7 @@
* outside the surface */
if(Clip)
{
- if(!EngIntersectRect(&OutputRect, &InputClippedRect,
&Clip->rclBounds))
+ if(!RECTL_bIntersectRect(&OutputRect, &InputClippedRect,
&Clip->rclBounds))
{
return TRUE;
}
Modified: trunk/reactos/subsystems/win32/win32k/objects/rect.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/subsystems/win32/win32k/ob…
==============================================================================
--- trunk/reactos/subsystems/win32/win32k/objects/rect.c [iso-8859-1] (original)
+++ trunk/reactos/subsystems/win32/win32k/objects/rect.c [iso-8859-1] Sat Apr 11 03:53:09
2009
@@ -62,22 +62,25 @@
BOOL
FASTCALL
-RECTL_bIntersectRect(RECTL *prclDst, const RECTL *prcl1, const RECTL *prcl2)
+RECTL_bIntersectRect(RECTL* prclDst, const RECTL* prcl1, const RECTL* prcl2)
{
- if (RECTL_bIsEmptyRect(prcl1) || RECTL_bIsEmptyRect(prcl2) ||
- prcl1->left >= prcl2->right || prcl2->left >= prcl1->right ||
- prcl1->top >= prcl2->bottom || prcl2->top >= prcl1->bottom)
+ prclDst->left = max(prcl1->left, prcl2->left);
+ prclDst->right = min(prcl1->right, prcl2->right);
+
+ if (prclDst->left < prclDst->right)
{
- RECTL_vSetEmptyRect(prclDst);
- return FALSE;
+ prclDst->top = max(prcl1->top, prcl2->top);
+ prclDst->bottom = min(prcl1->bottom, prcl2->bottom);
+
+ if (prclDst->top < prclDst->bottom)
+ {
+ return TRUE;
+ }
}
- prclDst->left = max(prcl1->left, prcl2->left);
- prclDst->right = min(prcl1->right, prcl2->right);
- prclDst->top = max(prcl1->top, prcl2->top);
- prclDst->bottom = min(prcl1->bottom, prcl2->bottom);
+ RECTL_vSetEmptyRect(prclDst);
- return TRUE;
+ return FALSE;
}
Modified: trunk/reactos/subsystems/win32/win32k/win32k.rbuild
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/subsystems/win32/win32k/wi…
==============================================================================
--- trunk/reactos/subsystems/win32/win32k/win32k.rbuild [iso-8859-1] (original)
+++ trunk/reactos/subsystems/win32/win32k/win32k.rbuild [iso-8859-1] Sat Apr 11 03:53:09
2009
@@ -44,6 +44,7 @@
</ifnot>
</directory>
<directory name="eng">
+ <file>alphablend.c</file>
<file>bitblt.c</file>
<file>engbrush.c</file>
<file>clip.c</file>
@@ -70,6 +71,7 @@
<file>semaphor.c</file>
<file>sort.c</file>
<file>string.c</file>
+ <file>stretchblt.c</file>
<file>surface.c</file>
<file>transblt.c</file>
<file>engwindow.c</file>