* COPYRIGHT: GNU GPL, See COPYING in the top level directory
* PROJECT: ReactOS Win32k subsystem
* PURPOSE: Clip region functions
- * FILE: subsystems/win32/win32k/objects/cliprgn.c
+ * FILE: win32ss/gdi/ntgdi/cliprgn.c
* PROGRAMER: Unknown
*/
#define NDEBUG
#include <debug.h>
+VOID
+FASTCALL
+IntGdiReleaseRaoRgn(PDC pDC)
+{
+ INT Index = GDI_HANDLE_GET_INDEX(pDC->BaseObject.hHmgr);
+ PGDI_TABLE_ENTRY Entry = &GdiHandleTable->Entries[Index];
+ pDC->fs |= DC_FLAG_DIRTY_RAO;
+ Entry->Flags |= GDI_ENTRY_VALIDATE_VIS; // Need to validate Vis.
+}
+
+VOID
+FASTCALL
+IntGdiReleaseVisRgn(PDC pDC)
+{
+ IntGdiReleaseRaoRgn(pDC);
+ REGION_Delete(pDC->prgnVis);
+ pDC->prgnVis = prgnDefault; // Vis can not be NULL!!!
+}
+
+//
+// Updating Vis Region Attribute the for DC Attributes.
+// BTW: This system region has an user attribute for it.
+//
+VOID
+FASTCALL
+UpdateVisRgn(
+ PDC pdc)
+{
+ INT Index = GDI_HANDLE_GET_INDEX(pdc->BaseObject.hHmgr);
+ PGDI_TABLE_ENTRY pEntry = &GdiHandleTable->Entries[Index];
+
+ /* Setup Vis Region Attribute information to User side */
+ pEntry->Flags |= GDI_ENTRY_VALIDATE_VIS;
+ pdc->pdcattr->VisRectRegion.iComplexity = REGION_GetRgnBox(pdc->prgnVis, &pdc->pdcattr->VisRectRegion.Rect);
+ pdc->pdcattr->VisRectRegion.AttrFlags = ATTR_RGN_VALID;
+ pEntry->Flags &= ~GDI_ENTRY_VALIDATE_VIS;
+}
+
+//
+// Selecting Vis Region.
+//
VOID
FASTCALL
GdiSelectVisRgn(
return;
}
+ if (!prgn)
+ {
+ DPRINT1("SVR: Setting NULL Region\n");
+ IntGdiReleaseVisRgn(dc);
+ IntSetDefaultRegion(dc);
+ DC_UnlockDc(dc);
+ return;
+ }
+
dc->fs |= DC_FLAG_DIRTY_RAO;
ASSERT(dc->prgnVis != NULL);
ASSERT(prgn != NULL);
- IntGdiCombineRgn(dc->prgnVis, prgn, NULL, RGN_COPY);
- IntGdiOffsetRgn(dc->prgnVis, -dc->ptlDCOrig.x, -dc->ptlDCOrig.y);
+ REGION_bCopy(dc->prgnVis, prgn);
+ REGION_bOffsetRgn(dc->prgnVis, -dc->ptlDCOrig.x, -dc->ptlDCOrig.y);
DC_UnlockDc(dc);
}
-
+_Success_(return!=ERROR)
int
FASTCALL
-IntGdiExtSelectClipRgn(
- PDC dc,
- PREGION prgn,
- int fnMode)
+IntSelectClipRgn(
+ _In_ PDC dc,
+ _In_ PREGION prgn,
+ _In_ int fnMode)
{
- if (fnMode == RGN_COPY)
+ int Ret = ERROR;
+ PREGION prgnNClip, prgnOrigClip = dc->dclevel.prgnClip;
+
+ //
+ // No Coping Regions and no intersecting Regions or an User calling w NULL Region or have the Original Clip Region.
+ //
+ if (fnMode != RGN_COPY && (fnMode != RGN_AND || !prgn || prgnOrigClip))
{
- if (!prgn)
+ prgnNClip = IntSysCreateRectpRgn(0, 0, 0, 0);
+
+ // Have Original Clip Region.
+ if (prgnOrigClip)
{
- if (dc->dclevel.prgnClip != NULL)
+ // This will fail on NULL prgn.
+ Ret = IntGdiCombineRgn(prgnNClip, prgnOrigClip, prgn, fnMode);
+
+ if (Ret)
+ {
+ REGION_Delete(prgnOrigClip);
+ dc->dclevel.prgnClip = prgnNClip;
+ IntGdiReleaseRaoRgn(dc);
+ }
+ else
+ REGION_Delete(prgnNClip);
+ }
+ else // NULL Original Clip Region, setup a new one and process mode.
+ {
+ PREGION prgnClip;
+ RECTL rcl;
+ PSURFACE pSurface;
+
+ // See IntSetDefaultRegion.
+
+ rcl.left = 0;
+ rcl.top = 0;
+ rcl.right = dc->dclevel.sizl.cx;
+ rcl.bottom = dc->dclevel.sizl.cy;
+
+ //EngAcquireSemaphoreShared(pdc->ppdev->hsemDevLock);
+ if (dc->ppdev->flFlags & PDEV_META_DEVICE)
+ {
+ pSurface = dc->dclevel.pSurface;
+ if (pSurface && pSurface->flags & PDEV_SURFACE)
+ {
+ rcl.left += dc->ppdev->ptlOrigion.x;
+ rcl.top += dc->ppdev->ptlOrigion.y;
+ rcl.right += dc->ppdev->ptlOrigion.x;
+ rcl.bottom += dc->ppdev->ptlOrigion.y;
+ }
+ }
+ //EngReleaseSemaphore(pdc->ppdev->hsemDevLock);
+
+ rcl.left += dc->ptlDCOrig.x;
+ rcl.top += dc->ptlDCOrig.y;
+ rcl.right += dc->ptlDCOrig.x;
+ rcl.bottom += dc->ptlDCOrig.y;
+
+ prgnClip = IntSysCreateRectpRgnIndirect(&rcl);
+
+ Ret = IntGdiCombineRgn(prgnNClip, prgnClip, prgn, fnMode);
+
+ if (Ret)
{
- REGION_Delete(dc->dclevel.prgnClip);
- dc->dclevel.prgnClip = NULL;
- dc->fs |= DC_FLAG_DIRTY_RAO;
+ dc->dclevel.prgnClip = prgnNClip;
+ IntGdiReleaseRaoRgn(dc);
}
- return SIMPLEREGION;
+ else
+ REGION_Delete(prgnNClip);
+
+ REGION_Delete(prgnClip);
}
+ return Ret;
+ }
- if (!dc->dclevel.prgnClip)
- dc->dclevel.prgnClip = IntSysCreateRectpRgn(0, 0, 0, 0);
+ // Fall through to normal RectOS mode.
- return IntGdiCombineRgn(dc->dclevel.prgnClip, prgn, NULL, RGN_COPY);
+ //
+ // Handle NULL Region and Original Clip Region.
+ //
+ if (!prgn)
+ {
+ if (prgnOrigClip)
+ {
+ REGION_Delete(dc->dclevel.prgnClip);
+ dc->dclevel.prgnClip = NULL;
+ IntGdiReleaseRaoRgn(dc);
+ }
+ return SIMPLEREGION;
}
- ASSERT(prgn != NULL);
+ //
+ // Combine the new Clip region with original Clip and caller Region.
+ //
+ if ( prgnOrigClip &&
+ (Ret = IntGdiCombineRgn(prgnOrigClip, prgn, NULL, RGN_COPY)) ) // Clip could fail.
+ {
+ IntGdiReleaseRaoRgn(dc);
+ }
+ else // NULL original Clip, just copy caller region to new.
+ {
+ prgnNClip = IntSysCreateRectpRgn(0, 0, 0, 0);
+ REGION_bCopy(prgnNClip, prgn);
+ Ret = REGION_Complexity(prgnNClip);
+ dc->dclevel.prgnClip = prgnNClip;
+ IntGdiReleaseRaoRgn(dc);
+ }
+ return Ret;
+}
+
+//
+// Call from Gdi Batch Subsystem.
+//
+// Was setup to just handle RGN_COPY only and return VOID, since this was called from Gdi32.
+// Tested in place of the other, complexity aside.
+//
- if (!dc->dclevel.prgnClip)
+_Success_(return!=ERROR)
+int
+FASTCALL
+IntGdiExtSelectClipRect(
+ _In_ PDC dc,
+ _In_ PRECTL prcl,
+ _In_ int fnMode)
+{
+ int Ret = ERROR;
+ PREGION prgn;
+ RECTL rect;
+ BOOL NoRegion = fnMode & GDIBS_NORECT;
+
+ fnMode &= ~GDIBS_NORECT;
+
+ if (NoRegion) // NULL Region.
{
- RECTL rect;
+ if (fnMode == RGN_COPY)
+ {
+ Ret = IntSelectClipRgn( dc, NULL, RGN_COPY);
- REGION_GetRgnBox(dc->prgnVis, &rect);
- dc->dclevel.prgnClip = IntSysCreateRectpRgnIndirect(&rect);
+ if (dc->fs & DC_FLAG_DIRTY_RAO)
+ CLIPPING_UpdateGCRegion(dc);
+
+ if (Ret) // Copy? Return Vis complexity.
+ Ret = REGION_Complexity(dc->prgnVis);
+ }
}
+ else // Have a box to build a region with.
+ {
+ if (dc->dclevel.prgnClip)
+ {
+ REGION_GetRgnBox(dc->dclevel.prgnClip, &rect);
- dc->fs |= DC_FLAG_DIRTY_RAO;
+ if (prcl->left == rect.left &&
+ prcl->top == rect.top &&
+ prcl->right == rect.right &&
+ prcl->bottom == rect.bottom)
+ {
+ return REGION_Complexity( dc->prgnRao ? dc->prgnRao : dc->prgnVis );
+ }
+ }
- return IntGdiCombineRgn(dc->dclevel.prgnClip, dc->dclevel.prgnClip, prgn, fnMode);
+ prgn = IntSysCreateRectpRgnIndirect(prcl);
+
+ Ret = IntSelectClipRgn( dc, prgn, fnMode);
+
+ if (dc->fs & DC_FLAG_DIRTY_RAO)
+ CLIPPING_UpdateGCRegion(dc);
+
+ if (Ret) // In this case NtGdiExtSelectClipRgn tests pass.
+ Ret = REGION_Complexity( dc->prgnRao ? dc->prgnRao : dc->prgnVis );
+
+ REGION_Delete(prgn);
+ }
+ return Ret;
}
+_Success_(return!=ERROR)
+int
+FASTCALL
+IntGdiExtSelectClipRgn(
+ _In_ PDC dc,
+ _In_ PREGION prgn,
+ _In_ int fnMode)
+{
+ int Ret = ERROR;
+
+ if (!prgn)
+ {
+ if (fnMode == RGN_COPY)
+ {
+ if ((Ret = IntSelectClipRgn( dc, NULL, RGN_COPY)))
+ Ret = REGION_Complexity(dc->prgnVis);
+ }
+ }
+ else
+ {
+ if ((Ret = IntSelectClipRgn( dc, prgn, fnMode)))
+ {
+ DPRINT("IntGdiExtSelectClipRgn A %d\n",Ret);
+ // Update the Rao, it must be this way for now.
+ if (dc->fs & DC_FLAG_DIRTY_RAO)
+ CLIPPING_UpdateGCRegion(dc);
+
+ Ret = REGION_Complexity( dc->prgnRao ? dc->prgnRao : dc->prgnVis );
+ DPRINT("IntGdiExtSelectClipRgn B %d\n",Ret);
+ }
+ }
+ return Ret;
+}
int
APIENTRY
DC *dc;
PREGION prgn;
+ if ( fnMode < RGN_AND || fnMode > RGN_COPY )
+ {
+ EngSetLastError(ERROR_INVALID_PARAMETER);
+ return ERROR;
+ }
+
if (!(dc = DC_LockDc(hDC)))
{
EngSetLastError(ERROR_INVALID_HANDLE);
if ((prgn == NULL) && (fnMode != RGN_COPY))
{
- EngSetLastError(ERROR_INVALID_HANDLE);
+ //EngSetLastError(ERROR_INVALID_HANDLE); doesn't set this.
retval = ERROR;
}
else
{
+#if 0 // Testing GDI Batch.
+ {
+ RECTL rcl;
+ if (prgn)
+ REGION_GetRgnBox(prgn, &rcl);
+ else
+ fnMode |= GDIBS_NORECT;
+ retval = IntGdiExtSelectClipRect(dc, &rcl, fnMode);
+ }
+#else
retval = IntGdiExtSelectClipRgn(dc, prgn, fnMode);
+#endif
}
if (prgn)
return retval;
}
-INT FASTCALL
-GdiGetClipBox(HDC hDC, PRECTL rc)
+_Success_(return!=ERROR)
+INT
+FASTCALL
+GdiGetClipBox(
+ _In_ HDC hdc,
+ _Out_ LPRECT prc)
{
- INT retval;
- PDC dc;
- PROSRGNDATA pRgnNew, pRgn = NULL;
-
- if (!(dc = DC_LockDc(hDC)))
- {
- return ERROR;
- }
-
- if (dc->fs & DC_FLAG_DIRTY_RAO)
- CLIPPING_UpdateGCRegion(dc);
-
- /* FIXME: Rao and Vis only! */
- if (dc->prgnAPI) // APIRGN
- {
- pRgn = dc->prgnAPI;
- }
- else if (dc->dclevel.prgnMeta) // METARGN
- {
- pRgn = dc->dclevel.prgnMeta;
- }
- else if (dc->dclevel.prgnClip) // CLIPRGN
- {
- pRgn = dc->dclevel.prgnClip;
- }
-
- if (pRgn)
- {
- pRgnNew = IntSysCreateRectpRgn( 0, 0, 0, 0 );
-
- if (!pRgnNew)
- {
- DC_UnlockDc(dc);
- return ERROR;
- }
-
- IntGdiCombineRgn(pRgnNew, dc->prgnVis, pRgn, RGN_AND);
+ PDC pdc;
+ INT iComplexity;
- retval = REGION_GetRgnBox(pRgnNew, rc);
+ /* Lock the DC */
+ pdc = DC_LockDc(hdc);
+ if (!pdc)
+ {
+ return ERROR;
+ }
- REGION_Delete(pRgnNew);
+ /* Update RAO region if necessary */
+ if (pdc->fs & DC_FLAG_DIRTY_RAO)
+ CLIPPING_UpdateGCRegion(pdc);
- DC_UnlockDc(dc);
- return retval;
- }
+ /* Check if we have a RAO region (intersection of API and VIS region) */
+ if (pdc->prgnRao)
+ {
+ /* We have a RAO region, use it */
+ iComplexity = REGION_GetRgnBox(pdc->prgnRao, prc);
+ }
+ else
+ {
+ /* No RAO region means no API region, so use the VIS region */
+ ASSERT(pdc->prgnVis);
+ iComplexity = REGION_GetRgnBox(pdc->prgnVis, prc);
+ }
- retval = REGION_GetRgnBox(dc->prgnVis, rc);
+ /* Unlock the DC */
+ DC_UnlockDc(pdc);
- DC_UnlockDc(dc);
+ /* Convert the rect to logical coordinates */
+ IntDPtoLP(pdc, (LPPOINT)prc, 2);
- return retval;
+ /* Return the complexity */
+ return iComplexity;
}
-INT APIENTRY
-NtGdiGetAppClipBox(HDC hDC, PRECTL rc)
+_Success_(return!=ERROR)
+INT
+APIENTRY
+NtGdiGetAppClipBox(
+ _In_ HDC hdc,
+ _Out_ LPRECT prc)
{
- INT Ret;
- NTSTATUS Status = STATUS_SUCCESS;
- RECTL Saferect;
-
- Ret = GdiGetClipBox(hDC, &Saferect);
+ RECT rect;
+ INT iComplexity;
- _SEH2_TRY
- {
- ProbeForWrite(rc,
- sizeof(RECT),
- 1);
- *rc = Saferect;
- }
- _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
- {
- Status = _SEH2_GetExceptionCode();
- }
- _SEH2_END;
+ /* Call the internal function */
+ iComplexity = GdiGetClipBox(hdc, &rect);
- if(!NT_SUCCESS(Status))
- {
- SetLastNtError(Status);
- return ERROR;
- }
+ if (iComplexity != ERROR)
+ {
+ _SEH2_TRY
+ {
+ ProbeForWrite(prc, sizeof(RECT), 1);
+ *prc = rect;
+ }
+ _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
+ {
+ iComplexity = ERROR;
+ }
+ _SEH2_END
+ }
- return Ret;
+ /* Return the complexity */
+ return iComplexity;
}
-int APIENTRY NtGdiExcludeClipRect(HDC hDC,
- int LeftRect,
- int TopRect,
- int RightRect,
- int BottomRect)
+INT
+APIENTRY
+NtGdiExcludeClipRect(
+ _In_ HDC hdc,
+ _In_ INT xLeft,
+ _In_ INT yTop,
+ _In_ INT xRight,
+ _In_ INT yBottom)
{
- INT Result;
- RECTL Rect;
- PREGION prgnNew;
- PDC dc = DC_LockDc(hDC);
+ INT iComplexity;
+ RECTL rect;
+ PDC pdc;
- if (!dc)
+ /* Lock the DC */
+ pdc = DC_LockDc(hdc);
+ if (pdc == NULL)
{
EngSetLastError(ERROR_INVALID_HANDLE);
return ERROR;
}
- Rect.left = LeftRect;
- Rect.top = TopRect;
- Rect.right = RightRect;
- Rect.bottom = BottomRect;
-
- IntLPtoDP(dc, (LPPOINT)&Rect, 2);
+ /* Convert coordinates to device space */
+ rect.left = xLeft;
+ rect.top = yTop;
+ rect.right = xRight;
+ rect.bottom = yBottom;
+ RECTL_vMakeWellOrdered(&rect);
+ IntLPtoDP(pdc, (LPPOINT)&rect, 2);
- prgnNew = IntSysCreateRectpRgnIndirect(&Rect);
- if (!prgnNew)
+ /* Check if we already have a clip region */
+ if (pdc->dclevel.prgnClip != NULL)
{
- Result = ERROR;
+ /* We have a region, subtract the rect */
+ iComplexity = REGION_SubtractRectFromRgn(pdc->dclevel.prgnClip,
+ pdc->dclevel.prgnClip,
+ &rect);
}
else
{
- if (!dc->dclevel.prgnClip)
+ /* We don't have a clip region yet, create an empty region */
+ pdc->dclevel.prgnClip = IntSysCreateRectpRgn(0, 0, 0, 0);
+ if (pdc->dclevel.prgnClip == NULL)
{
- dc->dclevel.prgnClip = IntSysCreateRectpRgn(0, 0, 0, 0);
- IntGdiCombineRgn(dc->dclevel.prgnClip, dc->prgnVis, prgnNew, RGN_DIFF);
- Result = SIMPLEREGION;
+ iComplexity = ERROR;
}
else
{
- Result = IntGdiCombineRgn(dc->dclevel.prgnClip, dc->dclevel.prgnClip, prgnNew, RGN_DIFF);
+ /* Subtract the rect from the VIS region */
+ iComplexity = REGION_SubtractRectFromRgn(pdc->dclevel.prgnClip,
+ pdc->prgnVis,
+ &rect);
}
- REGION_Delete(prgnNew);
}
- if (Result != ERROR)
- dc->fs |= DC_FLAG_DIRTY_RAO;
- DC_UnlockDc(dc);
+ /* Emulate Windows behavior */
+ if (iComplexity == SIMPLEREGION)
+ iComplexity = COMPLEXREGION;
- return Result;
+ /* If we succeeded, mark the RAO region as dirty */
+ if (iComplexity != ERROR)
+ pdc->fs |= DC_FLAG_DIRTY_RAO;
+
+ /* Unlock the DC */
+ DC_UnlockDc(pdc);
+
+ return iComplexity;
}
-int APIENTRY NtGdiIntersectClipRect(HDC hDC,
- int LeftRect,
- int TopRect,
- int RightRect,
- int BottomRect)
+INT
+APIENTRY
+NtGdiIntersectClipRect(
+ _In_ HDC hdc,
+ _In_ INT xLeft,
+ _In_ INT yTop,
+ _In_ INT xRight,
+ _In_ INT yBottom)
{
- INT Result;
- RECTL Rect;
- PREGION pNewRgn;
- PDC dc = DC_LockDc(hDC);
+ INT iComplexity;
+ RECTL rect;
+ PREGION prgnNew;
+ PDC pdc;
DPRINT("NtGdiIntersectClipRect(%p, %d,%d-%d,%d)\n",
- hDC, LeftRect, TopRect, RightRect, BottomRect);
+ hdc, xLeft, yTop, xRight, yBottom);
- if (!dc)
+ /* Lock the DC */
+ pdc = DC_LockDc(hdc);
+ if (!pdc)
{
EngSetLastError(ERROR_INVALID_HANDLE);
return ERROR;
}
- Rect.left = LeftRect;
- Rect.top = TopRect;
- Rect.right = RightRect;
- Rect.bottom = BottomRect;
+ /* Convert coordinates to device space */
+ rect.left = xLeft;
+ rect.top = yTop;
+ rect.right = xRight;
+ rect.bottom = yBottom;
+ IntLPtoDP(pdc, (LPPOINT)&rect, 2);
- IntLPtoDP(dc, (LPPOINT)&Rect, 2);
-
- pNewRgn = IntSysCreateRectpRgnIndirect(&Rect);
- if (!pNewRgn)
- {
- Result = ERROR;
- }
- else if (!dc->dclevel.prgnClip)
+ /* Check if we already have a clip region */
+ if (pdc->dclevel.prgnClip != NULL)
{
- dc->dclevel.prgnClip = pNewRgn;
- Result = SIMPLEREGION;
+ /* We have a region, crop it */
+ iComplexity = REGION_CropRegion(pdc->dclevel.prgnClip,
+ pdc->dclevel.prgnClip,
+ &rect);
}
else
{
- Result = IntGdiCombineRgn(dc->dclevel.prgnClip, dc->dclevel.prgnClip, pNewRgn, RGN_AND);
- REGION_Delete(pNewRgn);
+ /* We don't have a region yet, allocate a new one */
+ prgnNew = IntSysCreateRectpRgnIndirect(&rect);
+ if (prgnNew == NULL)
+ {
+ iComplexity = ERROR;
+ }
+ else
+ {
+ /* Set the new region */
+ pdc->dclevel.prgnClip = prgnNew;
+ iComplexity = SIMPLEREGION;
+ }
}
- if (Result != ERROR)
- dc->fs |= DC_FLAG_DIRTY_RAO;
- DC_UnlockDc(dc);
+ /* If we succeeded, mark the RAO region as dirty */
+ if (iComplexity != ERROR)
+ pdc->fs |= DC_FLAG_DIRTY_RAO;
- return Result;
+ /* Unlock the DC */
+ DC_UnlockDc(pdc);
+
+ return iComplexity;
}
-int APIENTRY NtGdiOffsetClipRgn(HDC hDC,
- int XOffset,
- int YOffset)
+INT
+APIENTRY
+NtGdiOffsetClipRgn(
+ _In_ HDC hdc,
+ _In_ INT xOffset,
+ _In_ INT yOffset)
{
- INT Result;
- DC *dc;
+ INT iComplexity;
+ PDC pdc;
+ POINTL apt[2];
- if(!(dc = DC_LockDc(hDC)))
+ /* Lock the DC */
+ pdc = DC_LockDc(hdc);
+ if (pdc == NULL)
{
- EngSetLastError(ERROR_INVALID_HANDLE);
+ if (!hdc) EngSetLastError(ERROR_INVALID_HANDLE);
return ERROR;
}
- if(dc->dclevel.prgnClip != NULL)
+ /* Check if we have a clip region */
+ if (pdc->dclevel.prgnClip != NULL)
{
- Result = IntGdiOffsetRgn(dc->dclevel.prgnClip,
- XOffset,
- YOffset);
- dc->fs |= DC_FLAG_DIRTY_RAO;
+ /* Convert coordinates into device space. Note that we need to convert
+ 2 coordinates to account for rotation / shear / offset */
+ apt[0].x = 0;
+ apt[0].y = 0;
+ apt[1].x = xOffset;
+ apt[1].y = yOffset;
+ IntLPtoDP(pdc, &apt, 2);
+
+ /* Offset the clip region */
+ if (!REGION_bOffsetRgn(pdc->dclevel.prgnClip,
+ apt[1].x - apt[0].x,
+ apt[1].y - apt[0].y))
+ {
+ iComplexity = ERROR;
+ }
+ else
+ {
+ IntGdiReleaseRaoRgn(pdc);
+ UpdateVisRgn(pdc);
+ iComplexity = REGION_Complexity(pdc->dclevel.prgnClip);
+ }
+
+ /* Mark the RAO region as dirty */
+ pdc->fs |= DC_FLAG_DIRTY_RAO;
}
else
{
- Result = NULLREGION;
+ /* NULL means no clipping, i.e. the "whole" region */
+ iComplexity = SIMPLEREGION;
}
- DC_UnlockDc(dc);
- return Result;
+ /* Unlock the DC and return the complexity */
+ DC_UnlockDc(pdc);
+ return iComplexity;
}
BOOL APIENTRY NtGdiPtVisible(HDC hDC,
{
BOOL ret = FALSE;
PDC dc;
+ PREGION prgn;
if(!(dc = DC_LockDc(hDC)))
{
return FALSE;
}
- if (dc->prgnRao)
+ prgn = dc->prgnRao ? dc->prgnRao : dc->prgnVis;
+
+ if (prgn)
{
POINT pt = {X, Y};
IntLPtoDP(dc, &pt, 1);
- ret = REGION_PtInRegion(dc->prgnRao, pt.x, pt.y);
+ ret = REGION_PtInRegion(prgn, pt.x, pt.y);
}
DC_UnlockDc(dc);
PDC dc = DC_LockDc(hDC);
BOOL Result = FALSE;
RECTL Rect;
+ PREGION prgn;
if (!dc)
{
if (dc->fs & DC_FLAG_DIRTY_RAO)
CLIPPING_UpdateGCRegion(dc);
- if (dc->prgnRao)
+ prgn = dc->prgnRao ? dc->prgnRao : dc->prgnVis;
+ if (prgn)
{
IntLPtoDP(dc, (LPPOINT)&Rect, 2);
- Result = REGION_RectInRegion(dc->prgnRao, &Rect);
+ Result = REGION_RectInRegion(prgn, &Rect);
}
DC_UnlockDc(dc);
{
if ( pDC->dclevel.prgnClip )
{
- Ret = IntGdiCombineRgn(pDC->dclevel.prgnMeta, pDC->dclevel.prgnMeta, pDC->dclevel.prgnClip, RGN_AND);
- if (Ret != ERROR)
+ PREGION prgn = IntSysCreateRectpRgn(0,0,0,0);
+ if ( prgn )
{
- REGION_Delete(pDC->dclevel.prgnClip);
- pDC->dclevel.prgnClip = NULL;
- IntGdiReleaseRaoRgn(pDC);
+ if (REGION_bIntersectRegion(prgn, pDC->dclevel.prgnMeta, pDC->dclevel.prgnClip))
+ {
+ // See Restore/SaveDC
+ REGION_Delete(pDC->dclevel.prgnMeta);
+ pDC->dclevel.prgnMeta = prgn;
+
+ REGION_Delete(pDC->dclevel.prgnClip);
+ pDC->dclevel.prgnClip = NULL;
+ IntGdiReleaseRaoRgn(pDC);
+
+ Ret = REGION_Complexity(pDC->dclevel.prgnMeta);
+ }
+ else
+ REGION_Delete(prgn);
}
}
else
Ret = SIMPLEREGION;
}
- if (Ret != ERROR)
- pDC->fs |= DC_FLAG_DIRTY_RAO;
-
return Ret;
}
FASTCALL
CLIPPING_UpdateGCRegion(PDC pDC)
{
+ // Moved from Release Rao. Though it still gets over written.
+ RECTL_vSetEmptyRect(&pDC->erclClip);
+
/* Must have VisRgn set to a valid state! */
ASSERT (pDC->prgnVis);
+#if 0 // (w2k3) This works with limitations. (w7u) ReactOS relies on Rao.
+ if ( !pDC->dclevel.prgnClip &&
+ !pDC->dclevel.prgnMeta &&
+ !pDC->prgnAPI)
+ {
+ if (pDC->prgnRao)
+ REGION_Delete(pDC->prgnRao);
+ pDC->prgnRao = NULL;
+
+ REGION_bOffsetRgn(pDC->prgnVis, pDC->ptlDCOrig.x, pDC->ptlDCOrig.y);
+ RtlCopyMemory(&pDC->erclClip,
+ &pDC->prgnVis->rdh.rcBound,
+ sizeof(RECTL));
+
+ IntEngUpdateClipRegion(&pDC->co,
+ pDC->prgnVis->rdh.nCount,
+ pDC->prgnVis->Buffer,
+ &pDC->erclClip);
+
+ REGION_bOffsetRgn(pDC->prgnVis, -pDC->ptlDCOrig.x, -pDC->ptlDCOrig.y);
+
+ pDC->fs &= ~DC_FLAG_DIRTY_RAO;
+ UpdateVisRgn(pDC);
+ return;
+ }
+#endif
if (pDC->prgnAPI)
{
REGION_Delete(pDC->prgnAPI);
pDC->prgnAPI = IntSysCreateRectpRgn(0,0,0,0);
if (!pDC->dclevel.prgnMeta)
{
- IntGdiCombineRgn(pDC->prgnAPI,
- pDC->dclevel.prgnClip,
- NULL,
- RGN_COPY);
+ REGION_bCopy(pDC->prgnAPI,
+ pDC->dclevel.prgnClip);
}
else if (!pDC->dclevel.prgnClip)
{
- IntGdiCombineRgn(pDC->prgnAPI,
- pDC->dclevel.prgnMeta,
- NULL,
- RGN_COPY);
+ REGION_bCopy(pDC->prgnAPI,
+ pDC->dclevel.prgnMeta);
}
else
{
- IntGdiCombineRgn(pDC->prgnAPI,
- pDC->dclevel.prgnClip,
- pDC->dclevel.prgnMeta,
- RGN_AND);
+ REGION_bIntersectRegion(pDC->prgnAPI,
+ pDC->dclevel.prgnClip,
+ pDC->dclevel.prgnMeta);
}
}
if (pDC->prgnAPI)
{
- IntGdiCombineRgn(pDC->prgnRao,
- pDC->prgnVis,
- pDC->prgnAPI,
- RGN_AND);
+ REGION_bIntersectRegion(pDC->prgnRao,
+ pDC->prgnVis,
+ pDC->prgnAPI);
}
else
{
- IntGdiCombineRgn(pDC->prgnRao,
- pDC->prgnVis,
- NULL,
- RGN_COPY);
+ REGION_bCopy(pDC->prgnRao,
+ pDC->prgnVis);
}
- IntGdiOffsetRgn(pDC->prgnRao, pDC->ptlDCOrig.x, pDC->ptlDCOrig.y);
+ REGION_bOffsetRgn(pDC->prgnRao, pDC->ptlDCOrig.x, pDC->ptlDCOrig.y);
RtlCopyMemory(&pDC->erclClip,
- &pDC->prgnRao->rdh.rcBound,
- sizeof(RECTL));
+ &pDC->prgnRao->rdh.rcBound,
+ sizeof(RECTL));
pDC->fs &= ~DC_FLAG_DIRTY_RAO;
+ UpdateVisRgn(pDC);
// pDC->co should be used. Example, CLIPOBJ_cEnumStart uses XCLIPOBJ to build
// the rects from region objects rects in pClipRgn->Buffer.
pDC->prgnRao->Buffer,
&pDC->erclClip);
- IntGdiOffsetRgn(pDC->prgnRao, -pDC->ptlDCOrig.x, -pDC->ptlDCOrig.y);
+ REGION_bOffsetRgn(pDC->prgnRao, -pDC->ptlDCOrig.x, -pDC->ptlDCOrig.y);
}
/* EOF */