xref: /reactos/win32ss/gdi/ntgdi/cliprgn.c (revision 9414fb6b)
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