1c2c66affSColin Finck /*
2c2c66affSColin Finck * COPYRIGHT: GNU GPL, See COPYING in the top level directory
3c2c66affSColin Finck * PROJECT: ReactOS Win32k subsystem
4c2c66affSColin Finck * PURPOSE: Clip region functions
5c2c66affSColin Finck * FILE: win32ss/gdi/ntgdi/cliprgn.c
6c2c66affSColin Finck * PROGRAMER: Unknown
7c2c66affSColin Finck */
8c2c66affSColin Finck
9c2c66affSColin Finck #include <win32k.h>
10c2c66affSColin Finck
11c2c66affSColin Finck #define NDEBUG
12c2c66affSColin Finck #include <debug.h>
13c2c66affSColin Finck
14*9414fb6bSTimo Kreuzer DBG_DEFAULT_CHANNEL(GdiClipRgn);
15*9414fb6bSTimo Kreuzer
16c2c66affSColin Finck VOID
17c2c66affSColin Finck FASTCALL
IntGdiReleaseRaoRgn(PDC pDC)18c2c66affSColin Finck IntGdiReleaseRaoRgn(PDC pDC)
19c2c66affSColin Finck {
20c2c66affSColin Finck INT Index = GDI_HANDLE_GET_INDEX(pDC->BaseObject.hHmgr);
21c2c66affSColin Finck PGDI_TABLE_ENTRY Entry = &GdiHandleTable->Entries[Index];
225e93daa9SHermès Bélusca-Maïto pDC->fs |= DC_DIRTY_RAO;
2394b4b5c1Sjimtabor Entry->Flags |= GDI_ENTRY_VALIDATE_VIS; // Need to validate Vis.
24c2c66affSColin Finck }
25c2c66affSColin Finck
26c2c66affSColin Finck VOID
27c2c66affSColin Finck FASTCALL
IntGdiReleaseVisRgn(PDC pDC)28c2c66affSColin Finck IntGdiReleaseVisRgn(PDC pDC)
29c2c66affSColin Finck {
3094b4b5c1Sjimtabor IntGdiReleaseRaoRgn(pDC);
31c2c66affSColin Finck REGION_Delete(pDC->prgnVis);
3294b4b5c1Sjimtabor pDC->prgnVis = prgnDefault; // Vis can not be NULL!!!
33c2c66affSColin Finck }
34c2c66affSColin Finck
3594b4b5c1Sjimtabor //
3602db01f3Sjimtabor // Updating Vis Region Attribute for DC Attributes.
3794b4b5c1Sjimtabor // BTW: This system region has an user attribute for it.
3894b4b5c1Sjimtabor //
3994b4b5c1Sjimtabor VOID
4094b4b5c1Sjimtabor FASTCALL
UpdateVisRgn(PDC pdc)4194b4b5c1Sjimtabor UpdateVisRgn(
4294b4b5c1Sjimtabor PDC pdc)
4394b4b5c1Sjimtabor {
4494b4b5c1Sjimtabor INT Index = GDI_HANDLE_GET_INDEX(pdc->BaseObject.hHmgr);
4594b4b5c1Sjimtabor PGDI_TABLE_ENTRY pEntry = &GdiHandleTable->Entries[Index];
4694b4b5c1Sjimtabor
4794b4b5c1Sjimtabor /* Setup Vis Region Attribute information to User side */
4894b4b5c1Sjimtabor pEntry->Flags |= GDI_ENTRY_VALIDATE_VIS;
4994b4b5c1Sjimtabor pdc->pdcattr->VisRectRegion.iComplexity = REGION_GetRgnBox(pdc->prgnVis, &pdc->pdcattr->VisRectRegion.Rect);
5094b4b5c1Sjimtabor pdc->pdcattr->VisRectRegion.AttrFlags = ATTR_RGN_VALID;
5194b4b5c1Sjimtabor pEntry->Flags &= ~GDI_ENTRY_VALIDATE_VIS;
5294b4b5c1Sjimtabor }
5394b4b5c1Sjimtabor
5494b4b5c1Sjimtabor //
5594b4b5c1Sjimtabor // Selecting Vis Region.
5694b4b5c1Sjimtabor //
57c2c66affSColin Finck VOID
58c2c66affSColin Finck FASTCALL
GdiSelectVisRgn(HDC hdc,PREGION prgn)59c2c66affSColin Finck GdiSelectVisRgn(
60c2c66affSColin Finck HDC hdc,
61c2c66affSColin Finck PREGION prgn)
62c2c66affSColin Finck {
63c2c66affSColin Finck DC *dc;
64c2c66affSColin Finck
65c2c66affSColin Finck if (!(dc = DC_LockDc(hdc)))
66c2c66affSColin Finck {
67c2c66affSColin Finck EngSetLastError(ERROR_INVALID_HANDLE);
68c2c66affSColin Finck return;
69c2c66affSColin Finck }
70c2c66affSColin Finck
7194b4b5c1Sjimtabor if (!prgn)
7294b4b5c1Sjimtabor {
7394b4b5c1Sjimtabor DPRINT1("SVR: Setting NULL Region\n");
7494b4b5c1Sjimtabor IntGdiReleaseVisRgn(dc);
7594b4b5c1Sjimtabor IntSetDefaultRegion(dc);
7694b4b5c1Sjimtabor DC_UnlockDc(dc);
7794b4b5c1Sjimtabor return;
7894b4b5c1Sjimtabor }
7994b4b5c1Sjimtabor
805e93daa9SHermès Bélusca-Maïto dc->fs |= DC_DIRTY_RAO;
81c2c66affSColin Finck
82c2c66affSColin Finck ASSERT(dc->prgnVis != NULL);
83c2c66affSColin Finck ASSERT(prgn != NULL);
84c2c66affSColin Finck
8594b4b5c1Sjimtabor REGION_bCopy(dc->prgnVis, prgn);
86c2c66affSColin Finck REGION_bOffsetRgn(dc->prgnVis, -dc->ptlDCOrig.x, -dc->ptlDCOrig.y);
87c2c66affSColin Finck
88c2c66affSColin Finck DC_UnlockDc(dc);
89c2c66affSColin Finck }
90c2c66affSColin Finck
9194b4b5c1Sjimtabor _Success_(return!=ERROR)
92c2c66affSColin Finck int
93c2c66affSColin Finck FASTCALL
IntSelectClipRgn(_In_ PDC dc,_In_ PREGION prgn,_In_ int fnMode)9494b4b5c1Sjimtabor IntSelectClipRgn(
9594b4b5c1Sjimtabor _In_ PDC dc,
9694b4b5c1Sjimtabor _In_ PREGION prgn,
9794b4b5c1Sjimtabor _In_ int fnMode)
98c2c66affSColin Finck {
9994b4b5c1Sjimtabor int Ret = ERROR;
10094b4b5c1Sjimtabor PREGION prgnNClip, prgnOrigClip = dc->dclevel.prgnClip;
10194b4b5c1Sjimtabor
10294b4b5c1Sjimtabor //
10394b4b5c1Sjimtabor // No Coping Regions and no intersecting Regions or an User calling w NULL Region or have the Original Clip Region.
10494b4b5c1Sjimtabor //
10594b4b5c1Sjimtabor if (fnMode != RGN_COPY && (fnMode != RGN_AND || !prgn || prgnOrigClip))
106c2c66affSColin Finck {
10794b4b5c1Sjimtabor prgnNClip = IntSysCreateRectpRgn(0, 0, 0, 0);
10894b4b5c1Sjimtabor
10994b4b5c1Sjimtabor // Have Original Clip Region.
11094b4b5c1Sjimtabor if (prgnOrigClip)
11194b4b5c1Sjimtabor {
11294b4b5c1Sjimtabor // This will fail on NULL prgn.
11394b4b5c1Sjimtabor Ret = IntGdiCombineRgn(prgnNClip, prgnOrigClip, prgn, fnMode);
11494b4b5c1Sjimtabor
11594b4b5c1Sjimtabor if (Ret)
11694b4b5c1Sjimtabor {
11794b4b5c1Sjimtabor REGION_Delete(prgnOrigClip);
11894b4b5c1Sjimtabor dc->dclevel.prgnClip = prgnNClip;
11994b4b5c1Sjimtabor IntGdiReleaseRaoRgn(dc);
12094b4b5c1Sjimtabor }
12194b4b5c1Sjimtabor else
12294b4b5c1Sjimtabor REGION_Delete(prgnNClip);
12394b4b5c1Sjimtabor }
12494b4b5c1Sjimtabor else // NULL Original Clip Region, setup a new one and process mode.
12594b4b5c1Sjimtabor {
12694b4b5c1Sjimtabor PREGION prgnClip;
12794b4b5c1Sjimtabor RECTL rcl;
12829030221Sjimtabor #if 0
12994b4b5c1Sjimtabor PSURFACE pSurface;
13094b4b5c1Sjimtabor
13194b4b5c1Sjimtabor // See IntSetDefaultRegion.
13294b4b5c1Sjimtabor
13394b4b5c1Sjimtabor rcl.left = 0;
13494b4b5c1Sjimtabor rcl.top = 0;
13594b4b5c1Sjimtabor rcl.right = dc->dclevel.sizl.cx;
13694b4b5c1Sjimtabor rcl.bottom = dc->dclevel.sizl.cy;
13794b4b5c1Sjimtabor
13894b4b5c1Sjimtabor //EngAcquireSemaphoreShared(pdc->ppdev->hsemDevLock);
13994b4b5c1Sjimtabor if (dc->ppdev->flFlags & PDEV_META_DEVICE)
14094b4b5c1Sjimtabor {
14194b4b5c1Sjimtabor pSurface = dc->dclevel.pSurface;
14294b4b5c1Sjimtabor if (pSurface && pSurface->flags & PDEV_SURFACE)
14394b4b5c1Sjimtabor {
14494b4b5c1Sjimtabor rcl.left += dc->ppdev->ptlOrigion.x;
14594b4b5c1Sjimtabor rcl.top += dc->ppdev->ptlOrigion.y;
14694b4b5c1Sjimtabor rcl.right += dc->ppdev->ptlOrigion.x;
14794b4b5c1Sjimtabor rcl.bottom += dc->ppdev->ptlOrigion.y;
14894b4b5c1Sjimtabor }
14994b4b5c1Sjimtabor }
15094b4b5c1Sjimtabor //EngReleaseSemaphore(pdc->ppdev->hsemDevLock);
15129030221Sjimtabor //#if 0
15294b4b5c1Sjimtabor rcl.left += dc->ptlDCOrig.x;
15394b4b5c1Sjimtabor rcl.top += dc->ptlDCOrig.y;
15494b4b5c1Sjimtabor rcl.right += dc->ptlDCOrig.x;
15594b4b5c1Sjimtabor rcl.bottom += dc->ptlDCOrig.y;
1564927905eSJames Tabor #endif
15729030221Sjimtabor REGION_GetRgnBox(dc->prgnVis, &rcl);
15829030221Sjimtabor
15994b4b5c1Sjimtabor prgnClip = IntSysCreateRectpRgnIndirect(&rcl);
16094b4b5c1Sjimtabor
16194b4b5c1Sjimtabor Ret = IntGdiCombineRgn(prgnNClip, prgnClip, prgn, fnMode);
16294b4b5c1Sjimtabor
16394b4b5c1Sjimtabor if (Ret)
16494b4b5c1Sjimtabor {
16594b4b5c1Sjimtabor dc->dclevel.prgnClip = prgnNClip;
16694b4b5c1Sjimtabor IntGdiReleaseRaoRgn(dc);
16794b4b5c1Sjimtabor }
16894b4b5c1Sjimtabor else
16994b4b5c1Sjimtabor REGION_Delete(prgnNClip);
17094b4b5c1Sjimtabor
17194b4b5c1Sjimtabor REGION_Delete(prgnClip);
17294b4b5c1Sjimtabor }
17394b4b5c1Sjimtabor return Ret;
17494b4b5c1Sjimtabor }
17594b4b5c1Sjimtabor
17694b4b5c1Sjimtabor // Fall through to normal RectOS mode.
17794b4b5c1Sjimtabor
17894b4b5c1Sjimtabor //
17994b4b5c1Sjimtabor // Handle NULL Region and Original Clip Region.
18094b4b5c1Sjimtabor //
181c2c66affSColin Finck if (!prgn)
182c2c66affSColin Finck {
18394b4b5c1Sjimtabor if (prgnOrigClip)
184c2c66affSColin Finck {
185c2c66affSColin Finck REGION_Delete(dc->dclevel.prgnClip);
186c2c66affSColin Finck dc->dclevel.prgnClip = NULL;
18794b4b5c1Sjimtabor IntGdiReleaseRaoRgn(dc);
188c2c66affSColin Finck }
189c2c66affSColin Finck return SIMPLEREGION;
190c2c66affSColin Finck }
191c2c66affSColin Finck
19294b4b5c1Sjimtabor //
19394b4b5c1Sjimtabor // Combine the new Clip region with original Clip and caller Region.
19494b4b5c1Sjimtabor //
19594b4b5c1Sjimtabor if ( prgnOrigClip &&
19694b4b5c1Sjimtabor (Ret = IntGdiCombineRgn(prgnOrigClip, prgn, NULL, RGN_COPY)) ) // Clip could fail.
197c2c66affSColin Finck {
19894b4b5c1Sjimtabor IntGdiReleaseRaoRgn(dc);
19994b4b5c1Sjimtabor }
20094b4b5c1Sjimtabor else // NULL original Clip, just copy caller region to new.
20194b4b5c1Sjimtabor {
20294b4b5c1Sjimtabor prgnNClip = IntSysCreateRectpRgn(0, 0, 0, 0);
20394b4b5c1Sjimtabor REGION_bCopy(prgnNClip, prgn);
20494b4b5c1Sjimtabor Ret = REGION_Complexity(prgnNClip);
20594b4b5c1Sjimtabor dc->dclevel.prgnClip = prgnNClip;
20694b4b5c1Sjimtabor IntGdiReleaseRaoRgn(dc);
20794b4b5c1Sjimtabor }
20894b4b5c1Sjimtabor return Ret;
20994b4b5c1Sjimtabor }
21094b4b5c1Sjimtabor
21194b4b5c1Sjimtabor //
21294b4b5c1Sjimtabor // Call from Gdi Batch Subsystem.
21394b4b5c1Sjimtabor //
21494b4b5c1Sjimtabor // Was setup to just handle RGN_COPY only and return VOID, since this was called from Gdi32.
21594b4b5c1Sjimtabor // Tested in place of the other, complexity aside.
21694b4b5c1Sjimtabor //
21794b4b5c1Sjimtabor
21894b4b5c1Sjimtabor _Success_(return!=ERROR)
21994b4b5c1Sjimtabor int
22094b4b5c1Sjimtabor FASTCALL
IntGdiExtSelectClipRect(_In_ PDC dc,_In_ PRECTL prcl,_In_ int fnMode)22194b4b5c1Sjimtabor IntGdiExtSelectClipRect(
22294b4b5c1Sjimtabor _In_ PDC dc,
22394b4b5c1Sjimtabor _In_ PRECTL prcl,
22494b4b5c1Sjimtabor _In_ int fnMode)
22594b4b5c1Sjimtabor {
22694b4b5c1Sjimtabor int Ret = ERROR;
22794b4b5c1Sjimtabor PREGION prgn;
228c2c66affSColin Finck RECTL rect;
22994b4b5c1Sjimtabor BOOL NoRegion = fnMode & GDIBS_NORECT;
230c2c66affSColin Finck
23194b4b5c1Sjimtabor fnMode &= ~GDIBS_NORECT;
23294b4b5c1Sjimtabor
23394b4b5c1Sjimtabor if (NoRegion) // NULL Region.
23494b4b5c1Sjimtabor {
23594b4b5c1Sjimtabor if (fnMode == RGN_COPY)
23694b4b5c1Sjimtabor {
23794b4b5c1Sjimtabor Ret = IntSelectClipRgn( dc, NULL, RGN_COPY);
23894b4b5c1Sjimtabor
2395e93daa9SHermès Bélusca-Maïto if (dc->fs & DC_DIRTY_RAO)
24094b4b5c1Sjimtabor CLIPPING_UpdateGCRegion(dc);
24194b4b5c1Sjimtabor
24294b4b5c1Sjimtabor if (Ret) // Copy? Return Vis complexity.
24394b4b5c1Sjimtabor Ret = REGION_Complexity(dc->prgnVis);
24494b4b5c1Sjimtabor }
24594b4b5c1Sjimtabor }
24694b4b5c1Sjimtabor else // Have a box to build a region with.
24702db01f3Sjimtabor { // See CORE-16246 : Needs to be a one box Clip Region.
24802db01f3Sjimtabor if ( dc->dclevel.prgnClip && (REGION_Complexity(dc->dclevel.prgnClip) == SIMPLEREGION) )
24994b4b5c1Sjimtabor {
25094b4b5c1Sjimtabor REGION_GetRgnBox(dc->dclevel.prgnClip, &rect);
25194b4b5c1Sjimtabor
25294b4b5c1Sjimtabor if (prcl->left == rect.left &&
25394b4b5c1Sjimtabor prcl->top == rect.top &&
25494b4b5c1Sjimtabor prcl->right == rect.right &&
25594b4b5c1Sjimtabor prcl->bottom == rect.bottom)
25694b4b5c1Sjimtabor {
25794b4b5c1Sjimtabor return REGION_Complexity( dc->prgnRao ? dc->prgnRao : dc->prgnVis );
25894b4b5c1Sjimtabor }
259c2c66affSColin Finck }
260c2c66affSColin Finck
26194b4b5c1Sjimtabor prgn = IntSysCreateRectpRgnIndirect(prcl);
262c2c66affSColin Finck
26394b4b5c1Sjimtabor Ret = IntSelectClipRgn( dc, prgn, fnMode);
26494b4b5c1Sjimtabor
2655e93daa9SHermès Bélusca-Maïto if (dc->fs & DC_DIRTY_RAO)
26694b4b5c1Sjimtabor CLIPPING_UpdateGCRegion(dc);
26794b4b5c1Sjimtabor
26894b4b5c1Sjimtabor if (Ret) // In this case NtGdiExtSelectClipRgn tests pass.
26994b4b5c1Sjimtabor Ret = REGION_Complexity( dc->prgnRao ? dc->prgnRao : dc->prgnVis );
27094b4b5c1Sjimtabor
27194b4b5c1Sjimtabor REGION_Delete(prgn);
27294b4b5c1Sjimtabor }
27394b4b5c1Sjimtabor return Ret;
274c2c66affSColin Finck }
275c2c66affSColin Finck
27694b4b5c1Sjimtabor _Success_(return!=ERROR)
27794b4b5c1Sjimtabor int
27894b4b5c1Sjimtabor FASTCALL
IntGdiExtSelectClipRgn(_In_ PDC dc,_In_ PREGION prgn,_In_ int fnMode)27994b4b5c1Sjimtabor IntGdiExtSelectClipRgn(
28094b4b5c1Sjimtabor _In_ PDC dc,
28194b4b5c1Sjimtabor _In_ PREGION prgn,
28294b4b5c1Sjimtabor _In_ int fnMode)
28394b4b5c1Sjimtabor {
28494b4b5c1Sjimtabor int Ret = ERROR;
28594b4b5c1Sjimtabor
28694b4b5c1Sjimtabor if (!prgn)
28794b4b5c1Sjimtabor {
28894b4b5c1Sjimtabor if (fnMode == RGN_COPY)
28994b4b5c1Sjimtabor {
29094b4b5c1Sjimtabor if ((Ret = IntSelectClipRgn( dc, NULL, RGN_COPY)))
29194b4b5c1Sjimtabor Ret = REGION_Complexity(dc->prgnVis);
29294b4b5c1Sjimtabor }
29394b4b5c1Sjimtabor }
29494b4b5c1Sjimtabor else
29594b4b5c1Sjimtabor {
29694b4b5c1Sjimtabor if ((Ret = IntSelectClipRgn( dc, prgn, fnMode)))
29794b4b5c1Sjimtabor {
29894b4b5c1Sjimtabor DPRINT("IntGdiExtSelectClipRgn A %d\n",Ret);
29994b4b5c1Sjimtabor // Update the Rao, it must be this way for now.
3005e93daa9SHermès Bélusca-Maïto if (dc->fs & DC_DIRTY_RAO)
30194b4b5c1Sjimtabor CLIPPING_UpdateGCRegion(dc);
30294b4b5c1Sjimtabor
30394b4b5c1Sjimtabor Ret = REGION_Complexity( dc->prgnRao ? dc->prgnRao : dc->prgnVis );
30494b4b5c1Sjimtabor DPRINT("IntGdiExtSelectClipRgn B %d\n",Ret);
30594b4b5c1Sjimtabor }
30694b4b5c1Sjimtabor }
30794b4b5c1Sjimtabor return Ret;
30894b4b5c1Sjimtabor }
309c2c66affSColin Finck
310c2c66affSColin Finck int
311c2c66affSColin Finck APIENTRY
NtGdiExtSelectClipRgn(HDC hDC,HRGN hrgn,int fnMode)312c2c66affSColin Finck NtGdiExtSelectClipRgn(
313c2c66affSColin Finck HDC hDC,
314c2c66affSColin Finck HRGN hrgn,
315c2c66affSColin Finck int fnMode)
316c2c66affSColin Finck {
317c2c66affSColin Finck int retval;
318c2c66affSColin Finck DC *dc;
319c2c66affSColin Finck PREGION prgn;
320c2c66affSColin Finck
32194b4b5c1Sjimtabor if ( fnMode < RGN_AND || fnMode > RGN_COPY )
32294b4b5c1Sjimtabor {
32394b4b5c1Sjimtabor EngSetLastError(ERROR_INVALID_PARAMETER);
32494b4b5c1Sjimtabor return ERROR;
32594b4b5c1Sjimtabor }
32694b4b5c1Sjimtabor
327c2c66affSColin Finck if (!(dc = DC_LockDc(hDC)))
328c2c66affSColin Finck {
329c2c66affSColin Finck EngSetLastError(ERROR_INVALID_HANDLE);
330c2c66affSColin Finck return ERROR;
331c2c66affSColin Finck }
332c2c66affSColin Finck
333c2c66affSColin Finck prgn = REGION_LockRgn(hrgn);
334c2c66affSColin Finck
335c2c66affSColin Finck if ((prgn == NULL) && (fnMode != RGN_COPY))
336c2c66affSColin Finck {
33794b4b5c1Sjimtabor //EngSetLastError(ERROR_INVALID_HANDLE); doesn't set this.
338c2c66affSColin Finck retval = ERROR;
339c2c66affSColin Finck }
340c2c66affSColin Finck else
341c2c66affSColin Finck {
34294b4b5c1Sjimtabor #if 0 // Testing GDI Batch.
34394b4b5c1Sjimtabor {
34494b4b5c1Sjimtabor RECTL rcl;
34594b4b5c1Sjimtabor if (prgn)
34694b4b5c1Sjimtabor REGION_GetRgnBox(prgn, &rcl);
34794b4b5c1Sjimtabor else
34894b4b5c1Sjimtabor fnMode |= GDIBS_NORECT;
34994b4b5c1Sjimtabor retval = IntGdiExtSelectClipRect(dc, &rcl, fnMode);
35094b4b5c1Sjimtabor }
35194b4b5c1Sjimtabor #else
352c2c66affSColin Finck retval = IntGdiExtSelectClipRgn(dc, prgn, fnMode);
35394b4b5c1Sjimtabor #endif
354c2c66affSColin Finck }
355c2c66affSColin Finck
356c2c66affSColin Finck if (prgn)
357c2c66affSColin Finck REGION_UnlockRgn(prgn);
358c2c66affSColin Finck
359c2c66affSColin Finck DC_UnlockDc(dc);
360c2c66affSColin Finck return retval;
361c2c66affSColin Finck }
362c2c66affSColin Finck
363c2c66affSColin Finck _Success_(return!=ERROR)
364c2c66affSColin Finck INT
365c2c66affSColin Finck FASTCALL
GdiGetClipBox(_In_ HDC hdc,_Out_ LPRECT prc)366c2c66affSColin Finck GdiGetClipBox(
367c2c66affSColin Finck _In_ HDC hdc,
368c2c66affSColin Finck _Out_ LPRECT prc)
369c2c66affSColin Finck {
370c2c66affSColin Finck PDC pdc;
371c2c66affSColin Finck INT iComplexity;
372c2c66affSColin Finck
373c2c66affSColin Finck /* Lock the DC */
374c2c66affSColin Finck pdc = DC_LockDc(hdc);
375c2c66affSColin Finck if (!pdc)
376c2c66affSColin Finck {
377c2c66affSColin Finck return ERROR;
378c2c66affSColin Finck }
379c2c66affSColin Finck
380c2c66affSColin Finck /* Update RAO region if necessary */
3815e93daa9SHermès Bélusca-Maïto if (pdc->fs & DC_DIRTY_RAO)
382c2c66affSColin Finck CLIPPING_UpdateGCRegion(pdc);
383c2c66affSColin Finck
384c2c66affSColin Finck /* Check if we have a RAO region (intersection of API and VIS region) */
385c2c66affSColin Finck if (pdc->prgnRao)
386c2c66affSColin Finck {
387c2c66affSColin Finck /* We have a RAO region, use it */
388c2c66affSColin Finck iComplexity = REGION_GetRgnBox(pdc->prgnRao, prc);
389c2c66affSColin Finck }
390c2c66affSColin Finck else
391c2c66affSColin Finck {
392c2c66affSColin Finck /* No RAO region means no API region, so use the VIS region */
393c2c66affSColin Finck ASSERT(pdc->prgnVis);
394c2c66affSColin Finck iComplexity = REGION_GetRgnBox(pdc->prgnVis, prc);
395c2c66affSColin Finck }
396c2c66affSColin Finck
397c2c66affSColin Finck /* Unlock the DC */
398c2c66affSColin Finck DC_UnlockDc(pdc);
399c2c66affSColin Finck
400c2c66affSColin Finck /* Convert the rect to logical coordinates */
401c2c66affSColin Finck IntDPtoLP(pdc, (LPPOINT)prc, 2);
402c2c66affSColin Finck
403c2c66affSColin Finck /* Return the complexity */
404c2c66affSColin Finck return iComplexity;
405c2c66affSColin Finck }
406c2c66affSColin Finck
407c2c66affSColin Finck _Success_(return!=ERROR)
408c2c66affSColin Finck INT
409c2c66affSColin Finck APIENTRY
NtGdiGetAppClipBox(_In_ HDC hdc,_Out_ LPRECT prc)410c2c66affSColin Finck NtGdiGetAppClipBox(
411c2c66affSColin Finck _In_ HDC hdc,
412c2c66affSColin Finck _Out_ LPRECT prc)
413c2c66affSColin Finck {
414c2c66affSColin Finck RECT rect;
415c2c66affSColin Finck INT iComplexity;
416c2c66affSColin Finck
417c2c66affSColin Finck /* Call the internal function */
418c2c66affSColin Finck iComplexity = GdiGetClipBox(hdc, &rect);
419c2c66affSColin Finck
420c2c66affSColin Finck if (iComplexity != ERROR)
421c2c66affSColin Finck {
422c2c66affSColin Finck _SEH2_TRY
423c2c66affSColin Finck {
424c2c66affSColin Finck ProbeForWrite(prc, sizeof(RECT), 1);
425c2c66affSColin Finck *prc = rect;
426c2c66affSColin Finck }
427c2c66affSColin Finck _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
428c2c66affSColin Finck {
429c2c66affSColin Finck iComplexity = ERROR;
430c2c66affSColin Finck }
431c2c66affSColin Finck _SEH2_END
432c2c66affSColin Finck }
433c2c66affSColin Finck
434c2c66affSColin Finck /* Return the complexity */
435c2c66affSColin Finck return iComplexity;
436c2c66affSColin Finck }
437c2c66affSColin Finck
438c2c66affSColin Finck INT
439c2c66affSColin Finck APIENTRY
NtGdiExcludeClipRect(_In_ HDC hdc,_In_ INT xLeft,_In_ INT yTop,_In_ INT xRight,_In_ INT yBottom)440c2c66affSColin Finck NtGdiExcludeClipRect(
441c2c66affSColin Finck _In_ HDC hdc,
442c2c66affSColin Finck _In_ INT xLeft,
443c2c66affSColin Finck _In_ INT yTop,
444c2c66affSColin Finck _In_ INT xRight,
445c2c66affSColin Finck _In_ INT yBottom)
446c2c66affSColin Finck {
4474927905eSJames Tabor INT iComplexity = ERROR;
448c2c66affSColin Finck RECTL rect;
449c2c66affSColin Finck PDC pdc;
4504927905eSJames Tabor PREGION prgn;
451c2c66affSColin Finck
452c2c66affSColin Finck /* Lock the DC */
453c2c66affSColin Finck pdc = DC_LockDc(hdc);
454c2c66affSColin Finck if (pdc == NULL)
455c2c66affSColin Finck {
456c2c66affSColin Finck EngSetLastError(ERROR_INVALID_HANDLE);
457c2c66affSColin Finck return ERROR;
458c2c66affSColin Finck }
459c2c66affSColin Finck
460c2c66affSColin Finck /* Convert coordinates to device space */
461c2c66affSColin Finck rect.left = xLeft;
462c2c66affSColin Finck rect.top = yTop;
463c2c66affSColin Finck rect.right = xRight;
464c2c66affSColin Finck rect.bottom = yBottom;
465c2c66affSColin Finck RECTL_vMakeWellOrdered(&rect);
466c2c66affSColin Finck IntLPtoDP(pdc, (LPPOINT)&rect, 2);
467c2c66affSColin Finck
4684927905eSJames Tabor prgn = IntSysCreateRectpRgnIndirect(&rect);
4694927905eSJames Tabor if ( prgn )
470c2c66affSColin Finck {
4714927905eSJames Tabor iComplexity = IntSelectClipRgn( pdc, prgn, RGN_DIFF );
4724927905eSJames Tabor
4734927905eSJames Tabor REGION_Delete(prgn);
474c2c66affSColin Finck }
475c2c66affSColin Finck
476c2c66affSColin Finck /* Emulate Windows behavior */
477c2c66affSColin Finck if (iComplexity == SIMPLEREGION)
478c2c66affSColin Finck iComplexity = COMPLEXREGION;
479c2c66affSColin Finck
480c2c66affSColin Finck /* Unlock the DC */
481c2c66affSColin Finck DC_UnlockDc(pdc);
482c2c66affSColin Finck
483c2c66affSColin Finck return iComplexity;
484c2c66affSColin Finck }
485c2c66affSColin Finck
486c2c66affSColin Finck INT
487c2c66affSColin Finck APIENTRY
NtGdiIntersectClipRect(_In_ HDC hdc,_In_ INT xLeft,_In_ INT yTop,_In_ INT xRight,_In_ INT yBottom)488c2c66affSColin Finck NtGdiIntersectClipRect(
489c2c66affSColin Finck _In_ HDC hdc,
490c2c66affSColin Finck _In_ INT xLeft,
491c2c66affSColin Finck _In_ INT yTop,
492c2c66affSColin Finck _In_ INT xRight,
493c2c66affSColin Finck _In_ INT yBottom)
494c2c66affSColin Finck {
4954927905eSJames Tabor INT iComplexity = ERROR;
496c2c66affSColin Finck RECTL rect;
497c2c66affSColin Finck PDC pdc;
4984927905eSJames Tabor PREGION prgn;
499c2c66affSColin Finck
500c2c66affSColin Finck DPRINT("NtGdiIntersectClipRect(%p, %d,%d-%d,%d)\n",
501c2c66affSColin Finck hdc, xLeft, yTop, xRight, yBottom);
502c2c66affSColin Finck
503c2c66affSColin Finck /* Lock the DC */
504c2c66affSColin Finck pdc = DC_LockDc(hdc);
505c2c66affSColin Finck if (!pdc)
506c2c66affSColin Finck {
507c2c66affSColin Finck EngSetLastError(ERROR_INVALID_HANDLE);
508c2c66affSColin Finck return ERROR;
509c2c66affSColin Finck }
510c2c66affSColin Finck
511c2c66affSColin Finck /* Convert coordinates to device space */
512c2c66affSColin Finck rect.left = xLeft;
513c2c66affSColin Finck rect.top = yTop;
514c2c66affSColin Finck rect.right = xRight;
515c2c66affSColin Finck rect.bottom = yBottom;
5164927905eSJames Tabor RECTL_vMakeWellOrdered(&rect);
517c2c66affSColin Finck IntLPtoDP(pdc, (LPPOINT)&rect, 2);
518c2c66affSColin Finck
5194927905eSJames Tabor prgn = IntSysCreateRectpRgnIndirect(&rect);
5204927905eSJames Tabor if ( prgn )
521c2c66affSColin Finck {
5224927905eSJames Tabor iComplexity = IntSelectClipRgn( pdc, prgn, RGN_AND );
5234927905eSJames Tabor
5244927905eSJames Tabor REGION_Delete(prgn);
525c2c66affSColin Finck }
526c2c66affSColin Finck
5274927905eSJames Tabor /* Emulate Windows behavior */
5284927905eSJames Tabor if ( iComplexity == SIMPLEREGION )
5294927905eSJames Tabor iComplexity = COMPLEXREGION;
530c2c66affSColin Finck
531c2c66affSColin Finck /* Unlock the DC */
532c2c66affSColin Finck DC_UnlockDc(pdc);
533c2c66affSColin Finck
534c2c66affSColin Finck return iComplexity;
535c2c66affSColin Finck }
536c2c66affSColin Finck
537c2c66affSColin Finck INT
538c2c66affSColin Finck APIENTRY
NtGdiOffsetClipRgn(_In_ HDC hdc,_In_ INT xOffset,_In_ INT yOffset)539c2c66affSColin Finck NtGdiOffsetClipRgn(
540c2c66affSColin Finck _In_ HDC hdc,
541c2c66affSColin Finck _In_ INT xOffset,
542c2c66affSColin Finck _In_ INT yOffset)
543c2c66affSColin Finck {
544c2c66affSColin Finck INT iComplexity;
545c2c66affSColin Finck PDC pdc;
546c2c66affSColin Finck POINTL apt[2];
547c2c66affSColin Finck
548c2c66affSColin Finck /* Lock the DC */
549c2c66affSColin Finck pdc = DC_LockDc(hdc);
550c2c66affSColin Finck if (pdc == NULL)
551c2c66affSColin Finck {
55294b4b5c1Sjimtabor if (!hdc) EngSetLastError(ERROR_INVALID_HANDLE);
553c2c66affSColin Finck return ERROR;
554c2c66affSColin Finck }
555c2c66affSColin Finck
556c2c66affSColin Finck /* Check if we have a clip region */
557c2c66affSColin Finck if (pdc->dclevel.prgnClip != NULL)
558c2c66affSColin Finck {
559c2c66affSColin Finck /* Convert coordinates into device space. Note that we need to convert
560c2c66affSColin Finck 2 coordinates to account for rotation / shear / offset */
561c2c66affSColin Finck apt[0].x = 0;
562c2c66affSColin Finck apt[0].y = 0;
563c2c66affSColin Finck apt[1].x = xOffset;
564c2c66affSColin Finck apt[1].y = yOffset;
5653bad3c49SJérôme Gardou IntLPtoDP(pdc, apt, 2);
566c2c66affSColin Finck
567c2c66affSColin Finck /* Offset the clip region */
568c2c66affSColin Finck if (!REGION_bOffsetRgn(pdc->dclevel.prgnClip,
569c2c66affSColin Finck apt[1].x - apt[0].x,
570c2c66affSColin Finck apt[1].y - apt[0].y))
571c2c66affSColin Finck {
572c2c66affSColin Finck iComplexity = ERROR;
573c2c66affSColin Finck }
574c2c66affSColin Finck else
575c2c66affSColin Finck {
57694b4b5c1Sjimtabor IntGdiReleaseRaoRgn(pdc);
57794b4b5c1Sjimtabor UpdateVisRgn(pdc);
578c2c66affSColin Finck iComplexity = REGION_Complexity(pdc->dclevel.prgnClip);
579c2c66affSColin Finck }
580c2c66affSColin Finck
581c2c66affSColin Finck /* Mark the RAO region as dirty */
5825e93daa9SHermès Bélusca-Maïto pdc->fs |= DC_DIRTY_RAO;
583c2c66affSColin Finck }
584c2c66affSColin Finck else
585c2c66affSColin Finck {
586c2c66affSColin Finck /* NULL means no clipping, i.e. the "whole" region */
587c2c66affSColin Finck iComplexity = SIMPLEREGION;
588c2c66affSColin Finck }
589c2c66affSColin Finck
590c2c66affSColin Finck /* Unlock the DC and return the complexity */
591c2c66affSColin Finck DC_UnlockDc(pdc);
592c2c66affSColin Finck return iComplexity;
593c2c66affSColin Finck }
594c2c66affSColin Finck
NtGdiPtVisible(HDC hDC,int X,int Y)595c2c66affSColin Finck BOOL APIENTRY NtGdiPtVisible(HDC hDC,
596c2c66affSColin Finck int X,
597c2c66affSColin Finck int Y)
598c2c66affSColin Finck {
599c2c66affSColin Finck BOOL ret = FALSE;
600c2c66affSColin Finck PDC dc;
60194b4b5c1Sjimtabor PREGION prgn;
602c2c66affSColin Finck
603c2c66affSColin Finck if(!(dc = DC_LockDc(hDC)))
604c2c66affSColin Finck {
605c2c66affSColin Finck EngSetLastError(ERROR_INVALID_HANDLE);
606c2c66affSColin Finck return FALSE;
607c2c66affSColin Finck }
608c2c66affSColin Finck
60994b4b5c1Sjimtabor prgn = dc->prgnRao ? dc->prgnRao : dc->prgnVis;
61094b4b5c1Sjimtabor
61194b4b5c1Sjimtabor if (prgn)
612c2c66affSColin Finck {
613c2c66affSColin Finck POINT pt = {X, Y};
614c2c66affSColin Finck IntLPtoDP(dc, &pt, 1);
61594b4b5c1Sjimtabor ret = REGION_PtInRegion(prgn, pt.x, pt.y);
616c2c66affSColin Finck }
617c2c66affSColin Finck
618c2c66affSColin Finck DC_UnlockDc(dc);
619c2c66affSColin Finck
620c2c66affSColin Finck return ret;
621c2c66affSColin Finck }
622c2c66affSColin Finck
623c2c66affSColin Finck BOOL
624c2c66affSColin Finck APIENTRY
NtGdiRectVisible(HDC hDC,LPRECT UnsafeRect)625c2c66affSColin Finck NtGdiRectVisible(
626c2c66affSColin Finck HDC hDC,
627c2c66affSColin Finck LPRECT UnsafeRect)
628c2c66affSColin Finck {
629c2c66affSColin Finck NTSTATUS Status = STATUS_SUCCESS;
630c2c66affSColin Finck PDC dc = DC_LockDc(hDC);
631c2c66affSColin Finck BOOL Result = FALSE;
632c2c66affSColin Finck RECTL Rect;
63394b4b5c1Sjimtabor PREGION prgn;
634c2c66affSColin Finck
635c2c66affSColin Finck if (!dc)
636c2c66affSColin Finck {
637c2c66affSColin Finck EngSetLastError(ERROR_INVALID_HANDLE);
638c2c66affSColin Finck return FALSE;
639c2c66affSColin Finck }
640c2c66affSColin Finck
641c2c66affSColin Finck _SEH2_TRY
642c2c66affSColin Finck {
643c2c66affSColin Finck ProbeForRead(UnsafeRect,
644c2c66affSColin Finck sizeof(RECT),
645c2c66affSColin Finck 1);
646c2c66affSColin Finck Rect = *UnsafeRect;
647c2c66affSColin Finck }
648c2c66affSColin Finck _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
649c2c66affSColin Finck {
650c2c66affSColin Finck Status = _SEH2_GetExceptionCode();
651c2c66affSColin Finck }
652c2c66affSColin Finck _SEH2_END;
653c2c66affSColin Finck
654c2c66affSColin Finck if(!NT_SUCCESS(Status))
655c2c66affSColin Finck {
656c2c66affSColin Finck DC_UnlockDc(dc);
657c2c66affSColin Finck SetLastNtError(Status);
658c2c66affSColin Finck return FALSE;
659c2c66affSColin Finck }
660c2c66affSColin Finck
6615e93daa9SHermès Bélusca-Maïto if (dc->fs & DC_DIRTY_RAO)
662c2c66affSColin Finck CLIPPING_UpdateGCRegion(dc);
663c2c66affSColin Finck
66494b4b5c1Sjimtabor prgn = dc->prgnRao ? dc->prgnRao : dc->prgnVis;
66594b4b5c1Sjimtabor if (prgn)
666c2c66affSColin Finck {
667c2c66affSColin Finck IntLPtoDP(dc, (LPPOINT)&Rect, 2);
66894b4b5c1Sjimtabor Result = REGION_RectInRegion(prgn, &Rect);
669c2c66affSColin Finck }
670c2c66affSColin Finck DC_UnlockDc(dc);
671c2c66affSColin Finck
672c2c66affSColin Finck return Result;
673c2c66affSColin Finck }
674c2c66affSColin Finck
675c2c66affSColin Finck int
676c2c66affSColin Finck FASTCALL
IntGdiSetMetaRgn(PDC pDC)677c2c66affSColin Finck IntGdiSetMetaRgn(PDC pDC)
678c2c66affSColin Finck {
679c2c66affSColin Finck INT Ret = ERROR;
680c2c66affSColin Finck
681c2c66affSColin Finck if ( pDC->dclevel.prgnMeta )
682c2c66affSColin Finck {
683c2c66affSColin Finck if ( pDC->dclevel.prgnClip )
684c2c66affSColin Finck {
68594b4b5c1Sjimtabor PREGION prgn = IntSysCreateRectpRgn(0,0,0,0);
68694b4b5c1Sjimtabor if ( prgn )
687c2c66affSColin Finck {
68894b4b5c1Sjimtabor if (REGION_bIntersectRegion(prgn, pDC->dclevel.prgnMeta, pDC->dclevel.prgnClip))
68994b4b5c1Sjimtabor {
69094b4b5c1Sjimtabor // See Restore/SaveDC
69194b4b5c1Sjimtabor REGION_Delete(pDC->dclevel.prgnMeta);
69294b4b5c1Sjimtabor pDC->dclevel.prgnMeta = prgn;
69394b4b5c1Sjimtabor
694c2c66affSColin Finck REGION_Delete(pDC->dclevel.prgnClip);
695c2c66affSColin Finck pDC->dclevel.prgnClip = NULL;
696c2c66affSColin Finck IntGdiReleaseRaoRgn(pDC);
69794b4b5c1Sjimtabor
69894b4b5c1Sjimtabor Ret = REGION_Complexity(pDC->dclevel.prgnMeta);
69994b4b5c1Sjimtabor }
70094b4b5c1Sjimtabor else
70194b4b5c1Sjimtabor REGION_Delete(prgn);
702c2c66affSColin Finck }
703c2c66affSColin Finck }
704c2c66affSColin Finck else
705c2c66affSColin Finck Ret = REGION_Complexity(pDC->dclevel.prgnMeta);
706c2c66affSColin Finck }
707c2c66affSColin Finck else
708c2c66affSColin Finck {
709c2c66affSColin Finck if ( pDC->dclevel.prgnClip )
710c2c66affSColin Finck {
711c2c66affSColin Finck Ret = REGION_Complexity(pDC->dclevel.prgnClip);
712c2c66affSColin Finck pDC->dclevel.prgnMeta = pDC->dclevel.prgnClip;
713c2c66affSColin Finck pDC->dclevel.prgnClip = NULL;
714c2c66affSColin Finck }
715c2c66affSColin Finck else
716c2c66affSColin Finck Ret = SIMPLEREGION;
717c2c66affSColin Finck }
718c2c66affSColin Finck
719c2c66affSColin Finck return Ret;
720c2c66affSColin Finck }
721c2c66affSColin Finck
722c2c66affSColin Finck
NtGdiSetMetaRgn(HDC hDC)723c2c66affSColin Finck int APIENTRY NtGdiSetMetaRgn(HDC hDC)
724c2c66affSColin Finck {
725c2c66affSColin Finck INT Ret;
726c2c66affSColin Finck PDC pDC = DC_LockDc(hDC);
727c2c66affSColin Finck
728c2c66affSColin Finck if (!pDC)
729c2c66affSColin Finck {
730c2c66affSColin Finck EngSetLastError(ERROR_INVALID_PARAMETER);
731c2c66affSColin Finck return ERROR;
732c2c66affSColin Finck }
733c2c66affSColin Finck Ret = IntGdiSetMetaRgn(pDC);
734c2c66affSColin Finck
735c2c66affSColin Finck DC_UnlockDc(pDC);
736c2c66affSColin Finck return Ret;
737c2c66affSColin Finck }
738c2c66affSColin Finck
739c2c66affSColin Finck VOID
740c2c66affSColin Finck FASTCALL
CLIPPING_UpdateGCRegion(PDC pDC)741c2c66affSColin Finck CLIPPING_UpdateGCRegion(PDC pDC)
742c2c66affSColin Finck {
74394b4b5c1Sjimtabor // Moved from Release Rao. Though it still gets over written.
74494b4b5c1Sjimtabor RECTL_vSetEmptyRect(&pDC->erclClip);
74594b4b5c1Sjimtabor
746c2c66affSColin Finck /* Must have VisRgn set to a valid state! */
747c2c66affSColin Finck ASSERT (pDC->prgnVis);
74894b4b5c1Sjimtabor #if 0 // (w2k3) This works with limitations. (w7u) ReactOS relies on Rao.
74994b4b5c1Sjimtabor if ( !pDC->dclevel.prgnClip &&
75094b4b5c1Sjimtabor !pDC->dclevel.prgnMeta &&
75194b4b5c1Sjimtabor !pDC->prgnAPI)
75294b4b5c1Sjimtabor {
75394b4b5c1Sjimtabor if (pDC->prgnRao)
75494b4b5c1Sjimtabor REGION_Delete(pDC->prgnRao);
75594b4b5c1Sjimtabor pDC->prgnRao = NULL;
756c2c66affSColin Finck
75794b4b5c1Sjimtabor REGION_bOffsetRgn(pDC->prgnVis, pDC->ptlDCOrig.x, pDC->ptlDCOrig.y);
75894b4b5c1Sjimtabor
75994b4b5c1Sjimtabor RtlCopyMemory(&pDC->erclClip,
76094b4b5c1Sjimtabor &pDC->prgnVis->rdh.rcBound,
76194b4b5c1Sjimtabor sizeof(RECTL));
76294b4b5c1Sjimtabor
76394b4b5c1Sjimtabor IntEngUpdateClipRegion(&pDC->co,
76494b4b5c1Sjimtabor pDC->prgnVis->rdh.nCount,
76594b4b5c1Sjimtabor pDC->prgnVis->Buffer,
76694b4b5c1Sjimtabor &pDC->erclClip);
76794b4b5c1Sjimtabor
76894b4b5c1Sjimtabor REGION_bOffsetRgn(pDC->prgnVis, -pDC->ptlDCOrig.x, -pDC->ptlDCOrig.y);
76994b4b5c1Sjimtabor
7705e93daa9SHermès Bélusca-Maïto pDC->fs &= ~DC_DIRTY_RAO;
77194b4b5c1Sjimtabor UpdateVisRgn(pDC);
77294b4b5c1Sjimtabor return;
77394b4b5c1Sjimtabor }
77494b4b5c1Sjimtabor #endif
775c2c66affSColin Finck if (pDC->prgnAPI)
776c2c66affSColin Finck {
777c2c66affSColin Finck REGION_Delete(pDC->prgnAPI);
778c2c66affSColin Finck pDC->prgnAPI = NULL;
779c2c66affSColin Finck }
780c2c66affSColin Finck
781c2c66affSColin Finck if (pDC->dclevel.prgnMeta || pDC->dclevel.prgnClip)
782c2c66affSColin Finck {
783c2c66affSColin Finck pDC->prgnAPI = IntSysCreateRectpRgn(0,0,0,0);
784*9414fb6bSTimo Kreuzer if (!pDC->prgnAPI)
785*9414fb6bSTimo Kreuzer {
786*9414fb6bSTimo Kreuzer /* Best we can do here. Better than crashing. */
787*9414fb6bSTimo Kreuzer ERR("Failed to allocate prgnAPI! Expect drawing issues!\n");
788*9414fb6bSTimo Kreuzer return;
789*9414fb6bSTimo Kreuzer }
790*9414fb6bSTimo Kreuzer
791c2c66affSColin Finck if (!pDC->dclevel.prgnMeta)
792c2c66affSColin Finck {
79394b4b5c1Sjimtabor REGION_bCopy(pDC->prgnAPI,
79494b4b5c1Sjimtabor pDC->dclevel.prgnClip);
795c2c66affSColin Finck }
796c2c66affSColin Finck else if (!pDC->dclevel.prgnClip)
797c2c66affSColin Finck {
79894b4b5c1Sjimtabor REGION_bCopy(pDC->prgnAPI,
79994b4b5c1Sjimtabor pDC->dclevel.prgnMeta);
800c2c66affSColin Finck }
801c2c66affSColin Finck else
802c2c66affSColin Finck {
80394b4b5c1Sjimtabor REGION_bIntersectRegion(pDC->prgnAPI,
804c2c66affSColin Finck pDC->dclevel.prgnClip,
80594b4b5c1Sjimtabor pDC->dclevel.prgnMeta);
806c2c66affSColin Finck }
807c2c66affSColin Finck }
808c2c66affSColin Finck
809*9414fb6bSTimo Kreuzer if (pDC->prgnRao)
810*9414fb6bSTimo Kreuzer REGION_Delete(pDC->prgnRao);
811*9414fb6bSTimo Kreuzer
812*9414fb6bSTimo Kreuzer pDC->prgnRao = IntSysCreateRectpRgn(0,0,0,0);
813*9414fb6bSTimo Kreuzer if (!pDC->prgnRao)
814*9414fb6bSTimo Kreuzer {
815*9414fb6bSTimo Kreuzer /* Best we can do here. Better than crashing. */
816*9414fb6bSTimo Kreuzer ERR("Failed to allocate prgnRao! Expect drawing issues!\n");
817*9414fb6bSTimo Kreuzer return;
818*9414fb6bSTimo Kreuzer }
819*9414fb6bSTimo Kreuzer
820c2c66affSColin Finck if (pDC->prgnAPI)
821c2c66affSColin Finck {
82294b4b5c1Sjimtabor REGION_bIntersectRegion(pDC->prgnRao,
823c2c66affSColin Finck pDC->prgnVis,
82494b4b5c1Sjimtabor pDC->prgnAPI);
825c2c66affSColin Finck }
826c2c66affSColin Finck else
827c2c66affSColin Finck {
82894b4b5c1Sjimtabor REGION_bCopy(pDC->prgnRao,
82994b4b5c1Sjimtabor pDC->prgnVis);
830c2c66affSColin Finck }
831c2c66affSColin Finck
832c2c66affSColin Finck
833c2c66affSColin Finck REGION_bOffsetRgn(pDC->prgnRao, pDC->ptlDCOrig.x, pDC->ptlDCOrig.y);
834c2c66affSColin Finck
835c2c66affSColin Finck RtlCopyMemory(&pDC->erclClip,
836c2c66affSColin Finck &pDC->prgnRao->rdh.rcBound,
837c2c66affSColin Finck sizeof(RECTL));
838c2c66affSColin Finck
8395e93daa9SHermès Bélusca-Maïto pDC->fs &= ~DC_DIRTY_RAO;
84094b4b5c1Sjimtabor UpdateVisRgn(pDC);
841c2c66affSColin Finck
842c2c66affSColin Finck // pDC->co should be used. Example, CLIPOBJ_cEnumStart uses XCLIPOBJ to build
843c2c66affSColin Finck // the rects from region objects rects in pClipRgn->Buffer.
844c2c66affSColin Finck // With pDC->co.pClipRgn->Buffer,
845c2c66affSColin Finck // pDC->co.pClipRgn = pDC->prgnRao ? pDC->prgnRao : pDC->prgnVis;
846c2c66affSColin Finck
847c2c66affSColin Finck IntEngUpdateClipRegion(&pDC->co,
848c2c66affSColin Finck pDC->prgnRao->rdh.nCount,
849c2c66affSColin Finck pDC->prgnRao->Buffer,
850c2c66affSColin Finck &pDC->erclClip);
851c2c66affSColin Finck
852c2c66affSColin Finck REGION_bOffsetRgn(pDC->prgnRao, -pDC->ptlDCOrig.x, -pDC->ptlDCOrig.y);
853c2c66affSColin Finck }
854c2c66affSColin Finck
855c2c66affSColin Finck /* EOF */
856