xref: /reactos/win32ss/gdi/ntgdi/cliprgn.c (revision 4927905e)
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 
14c2c66affSColin Finck VOID
15c2c66affSColin Finck FASTCALL
16c2c66affSColin Finck IntGdiReleaseRaoRgn(PDC pDC)
17c2c66affSColin Finck {
18c2c66affSColin Finck     INT Index = GDI_HANDLE_GET_INDEX(pDC->BaseObject.hHmgr);
19c2c66affSColin Finck     PGDI_TABLE_ENTRY Entry = &GdiHandleTable->Entries[Index];
20c2c66affSColin Finck     pDC->fs |= DC_FLAG_DIRTY_RAO;
2194b4b5c1Sjimtabor     Entry->Flags |= GDI_ENTRY_VALIDATE_VIS; // Need to validate Vis.
22c2c66affSColin Finck }
23c2c66affSColin Finck 
24c2c66affSColin Finck VOID
25c2c66affSColin Finck FASTCALL
26c2c66affSColin Finck IntGdiReleaseVisRgn(PDC pDC)
27c2c66affSColin Finck {
2894b4b5c1Sjimtabor     IntGdiReleaseRaoRgn(pDC);
29c2c66affSColin Finck     REGION_Delete(pDC->prgnVis);
3094b4b5c1Sjimtabor     pDC->prgnVis = prgnDefault; // Vis can not be NULL!!!
31c2c66affSColin Finck }
32c2c66affSColin Finck 
3394b4b5c1Sjimtabor //
3402db01f3Sjimtabor // Updating Vis Region Attribute for DC Attributes.
3594b4b5c1Sjimtabor // BTW: This system region has an user attribute for it.
3694b4b5c1Sjimtabor //
3794b4b5c1Sjimtabor VOID
3894b4b5c1Sjimtabor FASTCALL
3994b4b5c1Sjimtabor UpdateVisRgn(
4094b4b5c1Sjimtabor     PDC pdc)
4194b4b5c1Sjimtabor {
4294b4b5c1Sjimtabor     INT Index = GDI_HANDLE_GET_INDEX(pdc->BaseObject.hHmgr);
4394b4b5c1Sjimtabor     PGDI_TABLE_ENTRY pEntry = &GdiHandleTable->Entries[Index];
4494b4b5c1Sjimtabor 
4594b4b5c1Sjimtabor     /* Setup Vis Region Attribute information to User side */
4694b4b5c1Sjimtabor     pEntry->Flags |= GDI_ENTRY_VALIDATE_VIS;
4794b4b5c1Sjimtabor     pdc->pdcattr->VisRectRegion.iComplexity = REGION_GetRgnBox(pdc->prgnVis, &pdc->pdcattr->VisRectRegion.Rect);
4894b4b5c1Sjimtabor     pdc->pdcattr->VisRectRegion.AttrFlags = ATTR_RGN_VALID;
4994b4b5c1Sjimtabor     pEntry->Flags &= ~GDI_ENTRY_VALIDATE_VIS;
5094b4b5c1Sjimtabor }
5194b4b5c1Sjimtabor 
5294b4b5c1Sjimtabor //
5394b4b5c1Sjimtabor //  Selecting Vis Region.
5494b4b5c1Sjimtabor //
55c2c66affSColin Finck VOID
56c2c66affSColin Finck FASTCALL
57c2c66affSColin Finck GdiSelectVisRgn(
58c2c66affSColin Finck     HDC hdc,
59c2c66affSColin Finck     PREGION prgn)
60c2c66affSColin Finck {
61c2c66affSColin Finck     DC *dc;
62c2c66affSColin Finck 
63c2c66affSColin Finck     if (!(dc = DC_LockDc(hdc)))
64c2c66affSColin Finck     {
65c2c66affSColin Finck         EngSetLastError(ERROR_INVALID_HANDLE);
66c2c66affSColin Finck         return;
67c2c66affSColin Finck     }
68c2c66affSColin Finck 
6994b4b5c1Sjimtabor     if (!prgn)
7094b4b5c1Sjimtabor     {
7194b4b5c1Sjimtabor        DPRINT1("SVR: Setting NULL Region\n");
7294b4b5c1Sjimtabor        IntGdiReleaseVisRgn(dc);
7394b4b5c1Sjimtabor        IntSetDefaultRegion(dc);
7494b4b5c1Sjimtabor        DC_UnlockDc(dc);
7594b4b5c1Sjimtabor        return;
7694b4b5c1Sjimtabor     }
7794b4b5c1Sjimtabor 
78c2c66affSColin Finck     dc->fs |= DC_FLAG_DIRTY_RAO;
79c2c66affSColin Finck 
80c2c66affSColin Finck     ASSERT(dc->prgnVis != NULL);
81c2c66affSColin Finck     ASSERT(prgn != NULL);
82c2c66affSColin Finck 
8394b4b5c1Sjimtabor     REGION_bCopy(dc->prgnVis, prgn);
84c2c66affSColin Finck     REGION_bOffsetRgn(dc->prgnVis, -dc->ptlDCOrig.x, -dc->ptlDCOrig.y);
85c2c66affSColin Finck 
86c2c66affSColin Finck     DC_UnlockDc(dc);
87c2c66affSColin Finck }
88c2c66affSColin Finck 
8994b4b5c1Sjimtabor _Success_(return!=ERROR)
90c2c66affSColin Finck int
91c2c66affSColin Finck FASTCALL
9294b4b5c1Sjimtabor IntSelectClipRgn(
9394b4b5c1Sjimtabor     _In_ PDC dc,
9494b4b5c1Sjimtabor     _In_ PREGION prgn,
9594b4b5c1Sjimtabor     _In_ int fnMode)
96c2c66affSColin Finck {
9794b4b5c1Sjimtabor     int Ret = ERROR;
9894b4b5c1Sjimtabor     PREGION prgnNClip, prgnOrigClip = dc->dclevel.prgnClip;
9994b4b5c1Sjimtabor 
10094b4b5c1Sjimtabor     //
10194b4b5c1Sjimtabor     // No Coping Regions and no intersecting Regions or an User calling w NULL Region or have the Original Clip Region.
10294b4b5c1Sjimtabor     //
10394b4b5c1Sjimtabor     if (fnMode != RGN_COPY && (fnMode != RGN_AND || !prgn || prgnOrigClip))
104c2c66affSColin Finck     {
10594b4b5c1Sjimtabor         prgnNClip = IntSysCreateRectpRgn(0, 0, 0, 0);
10694b4b5c1Sjimtabor 
10794b4b5c1Sjimtabor         // Have Original Clip Region.
10894b4b5c1Sjimtabor         if (prgnOrigClip)
10994b4b5c1Sjimtabor         {
11094b4b5c1Sjimtabor            // This will fail on NULL prgn.
11194b4b5c1Sjimtabor            Ret = IntGdiCombineRgn(prgnNClip, prgnOrigClip, prgn, fnMode);
11294b4b5c1Sjimtabor 
11394b4b5c1Sjimtabor            if (Ret)
11494b4b5c1Sjimtabor            {
11594b4b5c1Sjimtabor               REGION_Delete(prgnOrigClip);
11694b4b5c1Sjimtabor               dc->dclevel.prgnClip = prgnNClip;
11794b4b5c1Sjimtabor               IntGdiReleaseRaoRgn(dc);
11894b4b5c1Sjimtabor            }
11994b4b5c1Sjimtabor            else
12094b4b5c1Sjimtabor               REGION_Delete(prgnNClip);
12194b4b5c1Sjimtabor         }
12294b4b5c1Sjimtabor         else // NULL Original Clip Region, setup a new one and process mode.
12394b4b5c1Sjimtabor         {
12494b4b5c1Sjimtabor             PREGION prgnClip;
12594b4b5c1Sjimtabor             RECTL rcl;
12694b4b5c1Sjimtabor             PSURFACE pSurface;
12794b4b5c1Sjimtabor 
12894b4b5c1Sjimtabor             // See IntSetDefaultRegion.
12994b4b5c1Sjimtabor 
13094b4b5c1Sjimtabor             rcl.left   = 0;
13194b4b5c1Sjimtabor             rcl.top    = 0;
13294b4b5c1Sjimtabor             rcl.right  = dc->dclevel.sizl.cx;
13394b4b5c1Sjimtabor             rcl.bottom = dc->dclevel.sizl.cy;
13494b4b5c1Sjimtabor 
13594b4b5c1Sjimtabor             //EngAcquireSemaphoreShared(pdc->ppdev->hsemDevLock);
13694b4b5c1Sjimtabor             if (dc->ppdev->flFlags & PDEV_META_DEVICE)
13794b4b5c1Sjimtabor             {
13894b4b5c1Sjimtabor                 pSurface = dc->dclevel.pSurface;
13994b4b5c1Sjimtabor                 if (pSurface && pSurface->flags & PDEV_SURFACE)
14094b4b5c1Sjimtabor                 {
14194b4b5c1Sjimtabor                    rcl.left   += dc->ppdev->ptlOrigion.x;
14294b4b5c1Sjimtabor                    rcl.top    += dc->ppdev->ptlOrigion.y;
14394b4b5c1Sjimtabor                    rcl.right  += dc->ppdev->ptlOrigion.x;
14494b4b5c1Sjimtabor                    rcl.bottom += dc->ppdev->ptlOrigion.y;
14594b4b5c1Sjimtabor                 }
14694b4b5c1Sjimtabor             }
14794b4b5c1Sjimtabor             //EngReleaseSemaphore(pdc->ppdev->hsemDevLock);
148*4927905eSJames Tabor #if 0
14994b4b5c1Sjimtabor             rcl.left   += dc->ptlDCOrig.x;
15094b4b5c1Sjimtabor             rcl.top    += dc->ptlDCOrig.y;
15194b4b5c1Sjimtabor             rcl.right  += dc->ptlDCOrig.x;
15294b4b5c1Sjimtabor             rcl.bottom += dc->ptlDCOrig.y;
153*4927905eSJames Tabor #endif
15494b4b5c1Sjimtabor             prgnClip = IntSysCreateRectpRgnIndirect(&rcl);
15594b4b5c1Sjimtabor 
15694b4b5c1Sjimtabor             Ret = IntGdiCombineRgn(prgnNClip, prgnClip, prgn, fnMode);
15794b4b5c1Sjimtabor 
15894b4b5c1Sjimtabor             if (Ret)
15994b4b5c1Sjimtabor             {
16094b4b5c1Sjimtabor                 dc->dclevel.prgnClip = prgnNClip;
16194b4b5c1Sjimtabor                 IntGdiReleaseRaoRgn(dc);
16294b4b5c1Sjimtabor             }
16394b4b5c1Sjimtabor             else
16494b4b5c1Sjimtabor                 REGION_Delete(prgnNClip);
16594b4b5c1Sjimtabor 
16694b4b5c1Sjimtabor             REGION_Delete(prgnClip);
16794b4b5c1Sjimtabor         }
16894b4b5c1Sjimtabor         return Ret;
16994b4b5c1Sjimtabor     }
17094b4b5c1Sjimtabor 
17194b4b5c1Sjimtabor     // Fall through to normal RectOS mode.
17294b4b5c1Sjimtabor 
17394b4b5c1Sjimtabor     //
17494b4b5c1Sjimtabor     // Handle NULL Region and Original Clip Region.
17594b4b5c1Sjimtabor     //
176c2c66affSColin Finck     if (!prgn)
177c2c66affSColin Finck     {
17894b4b5c1Sjimtabor         if (prgnOrigClip)
179c2c66affSColin Finck         {
180c2c66affSColin Finck             REGION_Delete(dc->dclevel.prgnClip);
181c2c66affSColin Finck             dc->dclevel.prgnClip = NULL;
18294b4b5c1Sjimtabor             IntGdiReleaseRaoRgn(dc);
183c2c66affSColin Finck         }
184c2c66affSColin Finck         return SIMPLEREGION;
185c2c66affSColin Finck     }
186c2c66affSColin Finck 
18794b4b5c1Sjimtabor     //
18894b4b5c1Sjimtabor     // Combine the new Clip region with original Clip and caller Region.
18994b4b5c1Sjimtabor     //
19094b4b5c1Sjimtabor     if ( prgnOrigClip &&
19194b4b5c1Sjimtabor         (Ret = IntGdiCombineRgn(prgnOrigClip, prgn, NULL, RGN_COPY)) ) // Clip could fail.
192c2c66affSColin Finck     {
19394b4b5c1Sjimtabor         IntGdiReleaseRaoRgn(dc);
19494b4b5c1Sjimtabor     }
19594b4b5c1Sjimtabor     else // NULL original Clip, just copy caller region to new.
19694b4b5c1Sjimtabor     {
19794b4b5c1Sjimtabor        prgnNClip = IntSysCreateRectpRgn(0, 0, 0, 0);
19894b4b5c1Sjimtabor        REGION_bCopy(prgnNClip, prgn);
19994b4b5c1Sjimtabor        Ret = REGION_Complexity(prgnNClip);
20094b4b5c1Sjimtabor        dc->dclevel.prgnClip = prgnNClip;
20194b4b5c1Sjimtabor        IntGdiReleaseRaoRgn(dc);
20294b4b5c1Sjimtabor     }
20394b4b5c1Sjimtabor     return Ret;
20494b4b5c1Sjimtabor }
20594b4b5c1Sjimtabor 
20694b4b5c1Sjimtabor //
20794b4b5c1Sjimtabor // Call from Gdi Batch Subsystem.
20894b4b5c1Sjimtabor //
20994b4b5c1Sjimtabor // Was setup to just handle RGN_COPY only and return VOID, since this was called from Gdi32.
21094b4b5c1Sjimtabor // Tested in place of the other, complexity aside.
21194b4b5c1Sjimtabor //
21294b4b5c1Sjimtabor 
21394b4b5c1Sjimtabor _Success_(return!=ERROR)
21494b4b5c1Sjimtabor int
21594b4b5c1Sjimtabor FASTCALL
21694b4b5c1Sjimtabor IntGdiExtSelectClipRect(
21794b4b5c1Sjimtabor     _In_ PDC dc,
21894b4b5c1Sjimtabor     _In_ PRECTL prcl,
21994b4b5c1Sjimtabor     _In_ int fnMode)
22094b4b5c1Sjimtabor {
22194b4b5c1Sjimtabor     int Ret = ERROR;
22294b4b5c1Sjimtabor     PREGION prgn;
223c2c66affSColin Finck     RECTL rect;
22494b4b5c1Sjimtabor     BOOL NoRegion = fnMode & GDIBS_NORECT;
225c2c66affSColin Finck 
22694b4b5c1Sjimtabor     fnMode &= ~GDIBS_NORECT;
22794b4b5c1Sjimtabor 
22894b4b5c1Sjimtabor     if (NoRegion) // NULL Region.
22994b4b5c1Sjimtabor     {
23094b4b5c1Sjimtabor         if (fnMode == RGN_COPY)
23194b4b5c1Sjimtabor         {
23294b4b5c1Sjimtabor            Ret = IntSelectClipRgn( dc, NULL, RGN_COPY);
23394b4b5c1Sjimtabor 
23494b4b5c1Sjimtabor            if (dc->fs & DC_FLAG_DIRTY_RAO)
23594b4b5c1Sjimtabor                CLIPPING_UpdateGCRegion(dc);
23694b4b5c1Sjimtabor 
23794b4b5c1Sjimtabor            if (Ret) // Copy? Return Vis complexity.
23894b4b5c1Sjimtabor                Ret = REGION_Complexity(dc->prgnVis);
23994b4b5c1Sjimtabor         }
24094b4b5c1Sjimtabor     }
24194b4b5c1Sjimtabor     else // Have a box to build a region with.
24202db01f3Sjimtabor     {                             //       See CORE-16246 : Needs to be a one box Clip Region.
24302db01f3Sjimtabor         if ( dc->dclevel.prgnClip && (REGION_Complexity(dc->dclevel.prgnClip) == SIMPLEREGION) )
24494b4b5c1Sjimtabor         {
24594b4b5c1Sjimtabor             REGION_GetRgnBox(dc->dclevel.prgnClip, &rect);
24694b4b5c1Sjimtabor 
24794b4b5c1Sjimtabor             if (prcl->left   == rect.left  &&
24894b4b5c1Sjimtabor                 prcl->top    == rect.top   &&
24994b4b5c1Sjimtabor                 prcl->right  == rect.right &&
25094b4b5c1Sjimtabor                 prcl->bottom == rect.bottom)
25194b4b5c1Sjimtabor             {
25294b4b5c1Sjimtabor                 return REGION_Complexity( dc->prgnRao ? dc->prgnRao : dc->prgnVis );
25394b4b5c1Sjimtabor             }
254c2c66affSColin Finck         }
255c2c66affSColin Finck 
25694b4b5c1Sjimtabor         prgn = IntSysCreateRectpRgnIndirect(prcl);
257c2c66affSColin Finck 
25894b4b5c1Sjimtabor         Ret = IntSelectClipRgn( dc, prgn, fnMode);
25994b4b5c1Sjimtabor 
26094b4b5c1Sjimtabor         if (dc->fs & DC_FLAG_DIRTY_RAO)
26194b4b5c1Sjimtabor             CLIPPING_UpdateGCRegion(dc);
26294b4b5c1Sjimtabor 
26394b4b5c1Sjimtabor         if (Ret) // In this case NtGdiExtSelectClipRgn tests pass.
26494b4b5c1Sjimtabor             Ret = REGION_Complexity( dc->prgnRao ? dc->prgnRao : dc->prgnVis );
26594b4b5c1Sjimtabor 
26694b4b5c1Sjimtabor         REGION_Delete(prgn);
26794b4b5c1Sjimtabor     }
26894b4b5c1Sjimtabor     return Ret;
269c2c66affSColin Finck }
270c2c66affSColin Finck 
27194b4b5c1Sjimtabor _Success_(return!=ERROR)
27294b4b5c1Sjimtabor int
27394b4b5c1Sjimtabor FASTCALL
27494b4b5c1Sjimtabor IntGdiExtSelectClipRgn(
27594b4b5c1Sjimtabor     _In_ PDC dc,
27694b4b5c1Sjimtabor     _In_ PREGION prgn,
27794b4b5c1Sjimtabor     _In_ int fnMode)
27894b4b5c1Sjimtabor {
27994b4b5c1Sjimtabor     int Ret = ERROR;
28094b4b5c1Sjimtabor 
28194b4b5c1Sjimtabor     if (!prgn)
28294b4b5c1Sjimtabor     {
28394b4b5c1Sjimtabor         if (fnMode == RGN_COPY)
28494b4b5c1Sjimtabor         {
28594b4b5c1Sjimtabor            if ((Ret = IntSelectClipRgn( dc, NULL, RGN_COPY)))
28694b4b5c1Sjimtabor                Ret = REGION_Complexity(dc->prgnVis);
28794b4b5c1Sjimtabor         }
28894b4b5c1Sjimtabor     }
28994b4b5c1Sjimtabor     else
29094b4b5c1Sjimtabor     {
29194b4b5c1Sjimtabor         if ((Ret = IntSelectClipRgn( dc, prgn, fnMode)))
29294b4b5c1Sjimtabor         {
29394b4b5c1Sjimtabor             DPRINT("IntGdiExtSelectClipRgn A %d\n",Ret);
29494b4b5c1Sjimtabor             // Update the Rao, it must be this way for now.
29594b4b5c1Sjimtabor             if (dc->fs & DC_FLAG_DIRTY_RAO)
29694b4b5c1Sjimtabor                 CLIPPING_UpdateGCRegion(dc);
29794b4b5c1Sjimtabor 
29894b4b5c1Sjimtabor             Ret = REGION_Complexity( dc->prgnRao ? dc->prgnRao : dc->prgnVis );
29994b4b5c1Sjimtabor             DPRINT("IntGdiExtSelectClipRgn B %d\n",Ret);
30094b4b5c1Sjimtabor         }
30194b4b5c1Sjimtabor     }
30294b4b5c1Sjimtabor     return Ret;
30394b4b5c1Sjimtabor }
304c2c66affSColin Finck 
305c2c66affSColin Finck int
306c2c66affSColin Finck APIENTRY
307c2c66affSColin Finck NtGdiExtSelectClipRgn(
308c2c66affSColin Finck     HDC  hDC,
309c2c66affSColin Finck     HRGN  hrgn,
310c2c66affSColin Finck     int  fnMode)
311c2c66affSColin Finck {
312c2c66affSColin Finck     int retval;
313c2c66affSColin Finck     DC *dc;
314c2c66affSColin Finck     PREGION prgn;
315c2c66affSColin Finck 
31694b4b5c1Sjimtabor     if ( fnMode < RGN_AND || fnMode > RGN_COPY )
31794b4b5c1Sjimtabor     {
31894b4b5c1Sjimtabor         EngSetLastError(ERROR_INVALID_PARAMETER);
31994b4b5c1Sjimtabor         return ERROR;
32094b4b5c1Sjimtabor     }
32194b4b5c1Sjimtabor 
322c2c66affSColin Finck     if (!(dc = DC_LockDc(hDC)))
323c2c66affSColin Finck     {
324c2c66affSColin Finck         EngSetLastError(ERROR_INVALID_HANDLE);
325c2c66affSColin Finck         return ERROR;
326c2c66affSColin Finck     }
327c2c66affSColin Finck 
328c2c66affSColin Finck     prgn = REGION_LockRgn(hrgn);
329c2c66affSColin Finck 
330c2c66affSColin Finck     if ((prgn == NULL) && (fnMode != RGN_COPY))
331c2c66affSColin Finck     {
33294b4b5c1Sjimtabor         //EngSetLastError(ERROR_INVALID_HANDLE); doesn't set this.
333c2c66affSColin Finck         retval = ERROR;
334c2c66affSColin Finck     }
335c2c66affSColin Finck     else
336c2c66affSColin Finck     {
33794b4b5c1Sjimtabor #if 0   // Testing GDI Batch.
33894b4b5c1Sjimtabor         {
33994b4b5c1Sjimtabor             RECTL rcl;
34094b4b5c1Sjimtabor             if (prgn)
34194b4b5c1Sjimtabor                 REGION_GetRgnBox(prgn, &rcl);
34294b4b5c1Sjimtabor             else
34394b4b5c1Sjimtabor                 fnMode |= GDIBS_NORECT;
34494b4b5c1Sjimtabor             retval = IntGdiExtSelectClipRect(dc, &rcl, fnMode);
34594b4b5c1Sjimtabor         }
34694b4b5c1Sjimtabor #else
347c2c66affSColin Finck         retval = IntGdiExtSelectClipRgn(dc, prgn, fnMode);
34894b4b5c1Sjimtabor #endif
349c2c66affSColin Finck     }
350c2c66affSColin Finck 
351c2c66affSColin Finck     if (prgn)
352c2c66affSColin Finck         REGION_UnlockRgn(prgn);
353c2c66affSColin Finck 
354c2c66affSColin Finck     DC_UnlockDc(dc);
355c2c66affSColin Finck     return retval;
356c2c66affSColin Finck }
357c2c66affSColin Finck 
358c2c66affSColin Finck _Success_(return!=ERROR)
359c2c66affSColin Finck INT
360c2c66affSColin Finck FASTCALL
361c2c66affSColin Finck GdiGetClipBox(
362c2c66affSColin Finck     _In_ HDC hdc,
363c2c66affSColin Finck     _Out_ LPRECT prc)
364c2c66affSColin Finck {
365c2c66affSColin Finck     PDC pdc;
366c2c66affSColin Finck     INT iComplexity;
367c2c66affSColin Finck 
368c2c66affSColin Finck     /* Lock the DC */
369c2c66affSColin Finck     pdc = DC_LockDc(hdc);
370c2c66affSColin Finck     if (!pdc)
371c2c66affSColin Finck     {
372c2c66affSColin Finck         return ERROR;
373c2c66affSColin Finck     }
374c2c66affSColin Finck 
375c2c66affSColin Finck     /* Update RAO region if necessary */
376c2c66affSColin Finck     if (pdc->fs & DC_FLAG_DIRTY_RAO)
377c2c66affSColin Finck         CLIPPING_UpdateGCRegion(pdc);
378c2c66affSColin Finck 
379c2c66affSColin Finck     /* Check if we have a RAO region (intersection of API and VIS region) */
380c2c66affSColin Finck     if (pdc->prgnRao)
381c2c66affSColin Finck     {
382c2c66affSColin Finck         /* We have a RAO region, use it */
383c2c66affSColin Finck         iComplexity = REGION_GetRgnBox(pdc->prgnRao, prc);
384c2c66affSColin Finck     }
385c2c66affSColin Finck     else
386c2c66affSColin Finck     {
387c2c66affSColin Finck         /* No RAO region means no API region, so use the VIS region */
388c2c66affSColin Finck         ASSERT(pdc->prgnVis);
389c2c66affSColin Finck         iComplexity = REGION_GetRgnBox(pdc->prgnVis, prc);
390c2c66affSColin Finck     }
391c2c66affSColin Finck 
392c2c66affSColin Finck     /* Unlock the DC */
393c2c66affSColin Finck     DC_UnlockDc(pdc);
394c2c66affSColin Finck 
395c2c66affSColin Finck     /* Convert the rect to logical coordinates */
396c2c66affSColin Finck     IntDPtoLP(pdc, (LPPOINT)prc, 2);
397c2c66affSColin Finck 
398c2c66affSColin Finck     /* Return the complexity */
399c2c66affSColin Finck     return iComplexity;
400c2c66affSColin Finck }
401c2c66affSColin Finck 
402c2c66affSColin Finck _Success_(return!=ERROR)
403c2c66affSColin Finck INT
404c2c66affSColin Finck APIENTRY
405c2c66affSColin Finck NtGdiGetAppClipBox(
406c2c66affSColin Finck     _In_ HDC hdc,
407c2c66affSColin Finck     _Out_ LPRECT prc)
408c2c66affSColin Finck {
409c2c66affSColin Finck     RECT rect;
410c2c66affSColin Finck     INT iComplexity;
411c2c66affSColin Finck 
412c2c66affSColin Finck     /* Call the internal function */
413c2c66affSColin Finck     iComplexity = GdiGetClipBox(hdc, &rect);
414c2c66affSColin Finck 
415c2c66affSColin Finck     if (iComplexity != ERROR)
416c2c66affSColin Finck     {
417c2c66affSColin Finck         _SEH2_TRY
418c2c66affSColin Finck         {
419c2c66affSColin Finck             ProbeForWrite(prc, sizeof(RECT), 1);
420c2c66affSColin Finck             *prc = rect;
421c2c66affSColin Finck         }
422c2c66affSColin Finck         _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
423c2c66affSColin Finck         {
424c2c66affSColin Finck             iComplexity = ERROR;
425c2c66affSColin Finck         }
426c2c66affSColin Finck         _SEH2_END
427c2c66affSColin Finck     }
428c2c66affSColin Finck 
429c2c66affSColin Finck     /* Return the complexity */
430c2c66affSColin Finck     return iComplexity;
431c2c66affSColin Finck }
432c2c66affSColin Finck 
433c2c66affSColin Finck INT
434c2c66affSColin Finck APIENTRY
435c2c66affSColin Finck NtGdiExcludeClipRect(
436c2c66affSColin Finck     _In_ HDC hdc,
437c2c66affSColin Finck     _In_ INT xLeft,
438c2c66affSColin Finck     _In_ INT yTop,
439c2c66affSColin Finck     _In_ INT xRight,
440c2c66affSColin Finck     _In_ INT yBottom)
441c2c66affSColin Finck {
442*4927905eSJames Tabor     INT iComplexity = ERROR;
443c2c66affSColin Finck     RECTL rect;
444c2c66affSColin Finck     PDC pdc;
445*4927905eSJames Tabor     PREGION prgn;
446c2c66affSColin Finck 
447c2c66affSColin Finck     /* Lock the DC */
448c2c66affSColin Finck     pdc = DC_LockDc(hdc);
449c2c66affSColin Finck     if (pdc == NULL)
450c2c66affSColin Finck     {
451c2c66affSColin Finck         EngSetLastError(ERROR_INVALID_HANDLE);
452c2c66affSColin Finck         return ERROR;
453c2c66affSColin Finck     }
454c2c66affSColin Finck 
455c2c66affSColin Finck     /* Convert coordinates to device space */
456c2c66affSColin Finck     rect.left   = xLeft;
457c2c66affSColin Finck     rect.top    = yTop;
458c2c66affSColin Finck     rect.right  = xRight;
459c2c66affSColin Finck     rect.bottom = yBottom;
460c2c66affSColin Finck     RECTL_vMakeWellOrdered(&rect);
461c2c66affSColin Finck     IntLPtoDP(pdc, (LPPOINT)&rect, 2);
462c2c66affSColin Finck 
463*4927905eSJames Tabor     prgn = IntSysCreateRectpRgnIndirect(&rect);
464*4927905eSJames Tabor     if ( prgn )
465c2c66affSColin Finck     {
466*4927905eSJames Tabor         iComplexity = IntSelectClipRgn( pdc, prgn, RGN_DIFF );
467*4927905eSJames Tabor 
468*4927905eSJames Tabor         REGION_Delete(prgn);
469c2c66affSColin Finck     }
470c2c66affSColin Finck 
471c2c66affSColin Finck     /* Emulate Windows behavior */
472c2c66affSColin Finck     if (iComplexity == SIMPLEREGION)
473c2c66affSColin Finck         iComplexity = COMPLEXREGION;
474c2c66affSColin Finck 
475c2c66affSColin Finck     /* Unlock the DC */
476c2c66affSColin Finck     DC_UnlockDc(pdc);
477c2c66affSColin Finck 
478c2c66affSColin Finck     return iComplexity;
479c2c66affSColin Finck }
480c2c66affSColin Finck 
481c2c66affSColin Finck INT
482c2c66affSColin Finck APIENTRY
483c2c66affSColin Finck NtGdiIntersectClipRect(
484c2c66affSColin Finck     _In_ HDC hdc,
485c2c66affSColin Finck     _In_ INT xLeft,
486c2c66affSColin Finck     _In_ INT yTop,
487c2c66affSColin Finck     _In_ INT xRight,
488c2c66affSColin Finck     _In_ INT yBottom)
489c2c66affSColin Finck {
490*4927905eSJames Tabor     INT iComplexity = ERROR;
491c2c66affSColin Finck     RECTL rect;
492c2c66affSColin Finck     PDC pdc;
493*4927905eSJames Tabor     PREGION prgn;
494c2c66affSColin Finck 
495c2c66affSColin Finck     DPRINT("NtGdiIntersectClipRect(%p, %d,%d-%d,%d)\n",
496c2c66affSColin Finck             hdc, xLeft, yTop, xRight, yBottom);
497c2c66affSColin Finck 
498c2c66affSColin Finck     /* Lock the DC */
499c2c66affSColin Finck     pdc = DC_LockDc(hdc);
500c2c66affSColin Finck     if (!pdc)
501c2c66affSColin Finck     {
502c2c66affSColin Finck         EngSetLastError(ERROR_INVALID_HANDLE);
503c2c66affSColin Finck         return ERROR;
504c2c66affSColin Finck     }
505c2c66affSColin Finck 
506c2c66affSColin Finck     /* Convert coordinates to device space */
507c2c66affSColin Finck     rect.left   = xLeft;
508c2c66affSColin Finck     rect.top    = yTop;
509c2c66affSColin Finck     rect.right  = xRight;
510c2c66affSColin Finck     rect.bottom = yBottom;
511*4927905eSJames Tabor     RECTL_vMakeWellOrdered(&rect);
512c2c66affSColin Finck     IntLPtoDP(pdc, (LPPOINT)&rect, 2);
513c2c66affSColin Finck 
514*4927905eSJames Tabor     prgn = IntSysCreateRectpRgnIndirect(&rect);
515*4927905eSJames Tabor     if ( prgn )
516c2c66affSColin Finck     {
517*4927905eSJames Tabor         iComplexity = IntSelectClipRgn( pdc, prgn, RGN_AND );
518*4927905eSJames Tabor 
519*4927905eSJames Tabor         REGION_Delete(prgn);
520c2c66affSColin Finck     }
521c2c66affSColin Finck 
522*4927905eSJames Tabor     /* Emulate Windows behavior */
523*4927905eSJames Tabor     if ( iComplexity == SIMPLEREGION )
524*4927905eSJames Tabor         iComplexity = COMPLEXREGION;
525c2c66affSColin Finck 
526c2c66affSColin Finck     /* Unlock the DC */
527c2c66affSColin Finck     DC_UnlockDc(pdc);
528c2c66affSColin Finck 
529c2c66affSColin Finck     return iComplexity;
530c2c66affSColin Finck }
531c2c66affSColin Finck 
532c2c66affSColin Finck INT
533c2c66affSColin Finck APIENTRY
534c2c66affSColin Finck NtGdiOffsetClipRgn(
535c2c66affSColin Finck     _In_ HDC hdc,
536c2c66affSColin Finck     _In_ INT xOffset,
537c2c66affSColin Finck     _In_ INT yOffset)
538c2c66affSColin Finck {
539c2c66affSColin Finck     INT iComplexity;
540c2c66affSColin Finck     PDC pdc;
541c2c66affSColin Finck     POINTL apt[2];
542c2c66affSColin Finck 
543c2c66affSColin Finck     /* Lock the DC */
544c2c66affSColin Finck     pdc = DC_LockDc(hdc);
545c2c66affSColin Finck     if (pdc == NULL)
546c2c66affSColin Finck     {
54794b4b5c1Sjimtabor         if (!hdc) EngSetLastError(ERROR_INVALID_HANDLE);
548c2c66affSColin Finck         return ERROR;
549c2c66affSColin Finck     }
550c2c66affSColin Finck 
551c2c66affSColin Finck     /* Check if we have a clip region */
552c2c66affSColin Finck     if (pdc->dclevel.prgnClip != NULL)
553c2c66affSColin Finck     {
554c2c66affSColin Finck         /* Convert coordinates into device space. Note that we need to convert
555c2c66affSColin Finck            2 coordinates to account for rotation / shear / offset */
556c2c66affSColin Finck         apt[0].x = 0;
557c2c66affSColin Finck         apt[0].y = 0;
558c2c66affSColin Finck         apt[1].x = xOffset;
559c2c66affSColin Finck         apt[1].y = yOffset;
560c2c66affSColin Finck         IntLPtoDP(pdc, &apt, 2);
561c2c66affSColin Finck 
562c2c66affSColin Finck         /* Offset the clip region */
563c2c66affSColin Finck         if (!REGION_bOffsetRgn(pdc->dclevel.prgnClip,
564c2c66affSColin Finck                                apt[1].x - apt[0].x,
565c2c66affSColin Finck                                apt[1].y - apt[0].y))
566c2c66affSColin Finck         {
567c2c66affSColin Finck             iComplexity = ERROR;
568c2c66affSColin Finck         }
569c2c66affSColin Finck         else
570c2c66affSColin Finck         {
57194b4b5c1Sjimtabor             IntGdiReleaseRaoRgn(pdc);
57294b4b5c1Sjimtabor             UpdateVisRgn(pdc);
573c2c66affSColin Finck             iComplexity = REGION_Complexity(pdc->dclevel.prgnClip);
574c2c66affSColin Finck         }
575c2c66affSColin Finck 
576c2c66affSColin Finck         /* Mark the RAO region as dirty */
577c2c66affSColin Finck         pdc->fs |= DC_FLAG_DIRTY_RAO;
578c2c66affSColin Finck     }
579c2c66affSColin Finck     else
580c2c66affSColin Finck     {
581c2c66affSColin Finck         /* NULL means no clipping, i.e. the "whole" region */
582c2c66affSColin Finck         iComplexity = SIMPLEREGION;
583c2c66affSColin Finck     }
584c2c66affSColin Finck 
585c2c66affSColin Finck     /* Unlock the DC and return the complexity */
586c2c66affSColin Finck     DC_UnlockDc(pdc);
587c2c66affSColin Finck     return iComplexity;
588c2c66affSColin Finck }
589c2c66affSColin Finck 
590c2c66affSColin Finck BOOL APIENTRY NtGdiPtVisible(HDC  hDC,
591c2c66affSColin Finck                     int  X,
592c2c66affSColin Finck                     int  Y)
593c2c66affSColin Finck {
594c2c66affSColin Finck     BOOL ret = FALSE;
595c2c66affSColin Finck     PDC dc;
59694b4b5c1Sjimtabor     PREGION prgn;
597c2c66affSColin Finck 
598c2c66affSColin Finck     if(!(dc = DC_LockDc(hDC)))
599c2c66affSColin Finck     {
600c2c66affSColin Finck         EngSetLastError(ERROR_INVALID_HANDLE);
601c2c66affSColin Finck         return FALSE;
602c2c66affSColin Finck     }
603c2c66affSColin Finck 
60494b4b5c1Sjimtabor     prgn = dc->prgnRao ? dc->prgnRao : dc->prgnVis;
60594b4b5c1Sjimtabor 
60694b4b5c1Sjimtabor     if (prgn)
607c2c66affSColin Finck     {
608c2c66affSColin Finck         POINT pt = {X, Y};
609c2c66affSColin Finck         IntLPtoDP(dc, &pt, 1);
61094b4b5c1Sjimtabor         ret = REGION_PtInRegion(prgn, pt.x, pt.y);
611c2c66affSColin Finck     }
612c2c66affSColin Finck 
613c2c66affSColin Finck     DC_UnlockDc(dc);
614c2c66affSColin Finck 
615c2c66affSColin Finck     return ret;
616c2c66affSColin Finck }
617c2c66affSColin Finck 
618c2c66affSColin Finck BOOL
619c2c66affSColin Finck APIENTRY
620c2c66affSColin Finck NtGdiRectVisible(
621c2c66affSColin Finck     HDC hDC,
622c2c66affSColin Finck     LPRECT UnsafeRect)
623c2c66affSColin Finck {
624c2c66affSColin Finck     NTSTATUS Status = STATUS_SUCCESS;
625c2c66affSColin Finck     PDC dc = DC_LockDc(hDC);
626c2c66affSColin Finck     BOOL Result = FALSE;
627c2c66affSColin Finck     RECTL Rect;
62894b4b5c1Sjimtabor     PREGION prgn;
629c2c66affSColin Finck 
630c2c66affSColin Finck     if (!dc)
631c2c66affSColin Finck     {
632c2c66affSColin Finck         EngSetLastError(ERROR_INVALID_HANDLE);
633c2c66affSColin Finck         return FALSE;
634c2c66affSColin Finck     }
635c2c66affSColin Finck 
636c2c66affSColin Finck     _SEH2_TRY
637c2c66affSColin Finck     {
638c2c66affSColin Finck         ProbeForRead(UnsafeRect,
639c2c66affSColin Finck                    sizeof(RECT),
640c2c66affSColin Finck                    1);
641c2c66affSColin Finck         Rect = *UnsafeRect;
642c2c66affSColin Finck     }
643c2c66affSColin Finck     _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
644c2c66affSColin Finck     {
645c2c66affSColin Finck         Status = _SEH2_GetExceptionCode();
646c2c66affSColin Finck     }
647c2c66affSColin Finck     _SEH2_END;
648c2c66affSColin Finck 
649c2c66affSColin Finck     if(!NT_SUCCESS(Status))
650c2c66affSColin Finck     {
651c2c66affSColin Finck         DC_UnlockDc(dc);
652c2c66affSColin Finck         SetLastNtError(Status);
653c2c66affSColin Finck         return FALSE;
654c2c66affSColin Finck     }
655c2c66affSColin Finck 
656c2c66affSColin Finck     if (dc->fs & DC_FLAG_DIRTY_RAO)
657c2c66affSColin Finck         CLIPPING_UpdateGCRegion(dc);
658c2c66affSColin Finck 
65994b4b5c1Sjimtabor     prgn = dc->prgnRao ? dc->prgnRao : dc->prgnVis;
66094b4b5c1Sjimtabor     if (prgn)
661c2c66affSColin Finck     {
662c2c66affSColin Finck          IntLPtoDP(dc, (LPPOINT)&Rect, 2);
66394b4b5c1Sjimtabor          Result = REGION_RectInRegion(prgn, &Rect);
664c2c66affSColin Finck     }
665c2c66affSColin Finck     DC_UnlockDc(dc);
666c2c66affSColin Finck 
667c2c66affSColin Finck     return Result;
668c2c66affSColin Finck }
669c2c66affSColin Finck 
670c2c66affSColin Finck int
671c2c66affSColin Finck FASTCALL
672c2c66affSColin Finck IntGdiSetMetaRgn(PDC pDC)
673c2c66affSColin Finck {
674c2c66affSColin Finck     INT Ret = ERROR;
675c2c66affSColin Finck 
676c2c66affSColin Finck     if ( pDC->dclevel.prgnMeta )
677c2c66affSColin Finck     {
678c2c66affSColin Finck         if ( pDC->dclevel.prgnClip )
679c2c66affSColin Finck         {
68094b4b5c1Sjimtabor             PREGION prgn = IntSysCreateRectpRgn(0,0,0,0);
68194b4b5c1Sjimtabor             if ( prgn )
682c2c66affSColin Finck             {
68394b4b5c1Sjimtabor                 if (REGION_bIntersectRegion(prgn, pDC->dclevel.prgnMeta, pDC->dclevel.prgnClip))
68494b4b5c1Sjimtabor                 {
68594b4b5c1Sjimtabor                     // See Restore/SaveDC
68694b4b5c1Sjimtabor                     REGION_Delete(pDC->dclevel.prgnMeta);
68794b4b5c1Sjimtabor                     pDC->dclevel.prgnMeta = prgn;
68894b4b5c1Sjimtabor 
689c2c66affSColin Finck                     REGION_Delete(pDC->dclevel.prgnClip);
690c2c66affSColin Finck                     pDC->dclevel.prgnClip = NULL;
691c2c66affSColin Finck                     IntGdiReleaseRaoRgn(pDC);
69294b4b5c1Sjimtabor 
69394b4b5c1Sjimtabor                     Ret = REGION_Complexity(pDC->dclevel.prgnMeta);
69494b4b5c1Sjimtabor                 }
69594b4b5c1Sjimtabor                 else
69694b4b5c1Sjimtabor                     REGION_Delete(prgn);
697c2c66affSColin Finck             }
698c2c66affSColin Finck         }
699c2c66affSColin Finck         else
700c2c66affSColin Finck             Ret = REGION_Complexity(pDC->dclevel.prgnMeta);
701c2c66affSColin Finck     }
702c2c66affSColin Finck     else
703c2c66affSColin Finck     {
704c2c66affSColin Finck         if ( pDC->dclevel.prgnClip )
705c2c66affSColin Finck         {
706c2c66affSColin Finck             Ret = REGION_Complexity(pDC->dclevel.prgnClip);
707c2c66affSColin Finck             pDC->dclevel.prgnMeta = pDC->dclevel.prgnClip;
708c2c66affSColin Finck             pDC->dclevel.prgnClip = NULL;
709c2c66affSColin Finck         }
710c2c66affSColin Finck         else
711c2c66affSColin Finck             Ret = SIMPLEREGION;
712c2c66affSColin Finck     }
713c2c66affSColin Finck 
714c2c66affSColin Finck     return Ret;
715c2c66affSColin Finck }
716c2c66affSColin Finck 
717c2c66affSColin Finck 
718c2c66affSColin Finck int APIENTRY NtGdiSetMetaRgn(HDC  hDC)
719c2c66affSColin Finck {
720c2c66affSColin Finck   INT Ret;
721c2c66affSColin Finck   PDC pDC = DC_LockDc(hDC);
722c2c66affSColin Finck 
723c2c66affSColin Finck   if (!pDC)
724c2c66affSColin Finck   {
725c2c66affSColin Finck      EngSetLastError(ERROR_INVALID_PARAMETER);
726c2c66affSColin Finck      return ERROR;
727c2c66affSColin Finck   }
728c2c66affSColin Finck   Ret = IntGdiSetMetaRgn(pDC);
729c2c66affSColin Finck 
730c2c66affSColin Finck   DC_UnlockDc(pDC);
731c2c66affSColin Finck   return Ret;
732c2c66affSColin Finck }
733c2c66affSColin Finck 
734c2c66affSColin Finck VOID
735c2c66affSColin Finck FASTCALL
736c2c66affSColin Finck CLIPPING_UpdateGCRegion(PDC pDC)
737c2c66affSColin Finck {
73894b4b5c1Sjimtabor     // Moved from Release Rao. Though it still gets over written.
73994b4b5c1Sjimtabor     RECTL_vSetEmptyRect(&pDC->erclClip);
74094b4b5c1Sjimtabor 
741c2c66affSColin Finck     /* Must have VisRgn set to a valid state! */
742c2c66affSColin Finck     ASSERT (pDC->prgnVis);
74394b4b5c1Sjimtabor #if 0 // (w2k3) This works with limitations. (w7u) ReactOS relies on Rao.
74494b4b5c1Sjimtabor     if ( !pDC->dclevel.prgnClip &&
74594b4b5c1Sjimtabor          !pDC->dclevel.prgnMeta &&
74694b4b5c1Sjimtabor          !pDC->prgnAPI)
74794b4b5c1Sjimtabor     {
74894b4b5c1Sjimtabor         if (pDC->prgnRao)
74994b4b5c1Sjimtabor             REGION_Delete(pDC->prgnRao);
75094b4b5c1Sjimtabor         pDC->prgnRao = NULL;
751c2c66affSColin Finck 
75294b4b5c1Sjimtabor         REGION_bOffsetRgn(pDC->prgnVis, pDC->ptlDCOrig.x, pDC->ptlDCOrig.y);
75394b4b5c1Sjimtabor 
75494b4b5c1Sjimtabor         RtlCopyMemory(&pDC->erclClip,
75594b4b5c1Sjimtabor                       &pDC->prgnVis->rdh.rcBound,
75694b4b5c1Sjimtabor                        sizeof(RECTL));
75794b4b5c1Sjimtabor 
75894b4b5c1Sjimtabor         IntEngUpdateClipRegion(&pDC->co,
75994b4b5c1Sjimtabor                                 pDC->prgnVis->rdh.nCount,
76094b4b5c1Sjimtabor                                 pDC->prgnVis->Buffer,
76194b4b5c1Sjimtabor                                &pDC->erclClip);
76294b4b5c1Sjimtabor 
76394b4b5c1Sjimtabor         REGION_bOffsetRgn(pDC->prgnVis, -pDC->ptlDCOrig.x, -pDC->ptlDCOrig.y);
76494b4b5c1Sjimtabor 
76594b4b5c1Sjimtabor         pDC->fs &= ~DC_FLAG_DIRTY_RAO;
76694b4b5c1Sjimtabor         UpdateVisRgn(pDC);
76794b4b5c1Sjimtabor         return;
76894b4b5c1Sjimtabor     }
76994b4b5c1Sjimtabor #endif
770c2c66affSColin Finck     if (pDC->prgnAPI)
771c2c66affSColin Finck     {
772c2c66affSColin Finck         REGION_Delete(pDC->prgnAPI);
773c2c66affSColin Finck         pDC->prgnAPI = NULL;
774c2c66affSColin Finck     }
775c2c66affSColin Finck 
776c2c66affSColin Finck     if (pDC->prgnRao)
777c2c66affSColin Finck         REGION_Delete(pDC->prgnRao);
778c2c66affSColin Finck 
779c2c66affSColin Finck     pDC->prgnRao = IntSysCreateRectpRgn(0,0,0,0);
780c2c66affSColin Finck 
781c2c66affSColin Finck     ASSERT(pDC->prgnRao);
782c2c66affSColin Finck 
783c2c66affSColin Finck     if (pDC->dclevel.prgnMeta || pDC->dclevel.prgnClip)
784c2c66affSColin Finck     {
785c2c66affSColin Finck         pDC->prgnAPI = IntSysCreateRectpRgn(0,0,0,0);
786c2c66affSColin Finck         if (!pDC->dclevel.prgnMeta)
787c2c66affSColin Finck         {
78894b4b5c1Sjimtabor             REGION_bCopy(pDC->prgnAPI,
78994b4b5c1Sjimtabor                          pDC->dclevel.prgnClip);
790c2c66affSColin Finck         }
791c2c66affSColin Finck         else if (!pDC->dclevel.prgnClip)
792c2c66affSColin Finck         {
79394b4b5c1Sjimtabor             REGION_bCopy(pDC->prgnAPI,
79494b4b5c1Sjimtabor                          pDC->dclevel.prgnMeta);
795c2c66affSColin Finck         }
796c2c66affSColin Finck         else
797c2c66affSColin Finck         {
79894b4b5c1Sjimtabor             REGION_bIntersectRegion(pDC->prgnAPI,
799c2c66affSColin Finck                                     pDC->dclevel.prgnClip,
80094b4b5c1Sjimtabor                                     pDC->dclevel.prgnMeta);
801c2c66affSColin Finck         }
802c2c66affSColin Finck     }
803c2c66affSColin Finck 
804c2c66affSColin Finck     if (pDC->prgnAPI)
805c2c66affSColin Finck     {
80694b4b5c1Sjimtabor         REGION_bIntersectRegion(pDC->prgnRao,
807c2c66affSColin Finck                                 pDC->prgnVis,
80894b4b5c1Sjimtabor                                 pDC->prgnAPI);
809c2c66affSColin Finck     }
810c2c66affSColin Finck     else
811c2c66affSColin Finck     {
81294b4b5c1Sjimtabor         REGION_bCopy(pDC->prgnRao,
81394b4b5c1Sjimtabor                      pDC->prgnVis);
814c2c66affSColin Finck     }
815c2c66affSColin Finck 
816c2c66affSColin Finck 
817c2c66affSColin Finck     REGION_bOffsetRgn(pDC->prgnRao, pDC->ptlDCOrig.x, pDC->ptlDCOrig.y);
818c2c66affSColin Finck 
819c2c66affSColin Finck     RtlCopyMemory(&pDC->erclClip,
820c2c66affSColin Finck                   &pDC->prgnRao->rdh.rcBound,
821c2c66affSColin Finck                   sizeof(RECTL));
822c2c66affSColin Finck 
823c2c66affSColin Finck     pDC->fs &= ~DC_FLAG_DIRTY_RAO;
82494b4b5c1Sjimtabor     UpdateVisRgn(pDC);
825c2c66affSColin Finck 
826c2c66affSColin Finck     // pDC->co should be used. Example, CLIPOBJ_cEnumStart uses XCLIPOBJ to build
827c2c66affSColin Finck     // the rects from region objects rects in pClipRgn->Buffer.
828c2c66affSColin Finck     // With pDC->co.pClipRgn->Buffer,
829c2c66affSColin Finck     // pDC->co.pClipRgn = pDC->prgnRao ? pDC->prgnRao : pDC->prgnVis;
830c2c66affSColin Finck 
831c2c66affSColin Finck     IntEngUpdateClipRegion(&pDC->co,
832c2c66affSColin Finck                            pDC->prgnRao->rdh.nCount,
833c2c66affSColin Finck                            pDC->prgnRao->Buffer,
834c2c66affSColin Finck                            &pDC->erclClip);
835c2c66affSColin Finck 
836c2c66affSColin Finck     REGION_bOffsetRgn(pDC->prgnRao, -pDC->ptlDCOrig.x, -pDC->ptlDCOrig.y);
837c2c66affSColin Finck }
838c2c66affSColin Finck 
839c2c66affSColin Finck /* EOF */
840