2 * COPYRIGHT: GNU GPL, See COPYING in the top level directory
3 * PROJECT: ReactOS Win32k subsystem
4 * PURPOSE: Clip region functions
5 * FILE: subsystems/win32/win32k/objects/cliprgn.c
22 if (!(dc
= DC_LockDc(hdc
)))
24 EngSetLastError(ERROR_INVALID_HANDLE
);
28 dc
->fs
|= DC_FLAG_DIRTY_RAO
;
30 ASSERT(dc
->prgnVis
!= NULL
);
33 IntGdiCombineRgn(dc
->prgnVis
, prgn
, NULL
, RGN_COPY
);
34 IntGdiOffsetRgn(dc
->prgnVis
, -dc
->ptlDCOrig
.x
, -dc
->ptlDCOrig
.y
);
42 IntGdiExtSelectClipRgn(
47 if (fnMode
== RGN_COPY
)
51 if (dc
->dclevel
.prgnClip
!= NULL
)
53 REGION_Delete(dc
->dclevel
.prgnClip
);
54 dc
->dclevel
.prgnClip
= NULL
;
55 dc
->fs
|= DC_FLAG_DIRTY_RAO
;
60 if (!dc
->dclevel
.prgnClip
)
61 dc
->dclevel
.prgnClip
= IntSysCreateRectpRgn(0, 0, 0, 0);
63 dc
->fs
|= DC_FLAG_DIRTY_RAO
;
65 return IntGdiCombineRgn(dc
->dclevel
.prgnClip
, prgn
, NULL
, RGN_COPY
);
70 if (!dc
->dclevel
.prgnClip
)
74 REGION_GetRgnBox(dc
->prgnVis
, &rect
);
75 dc
->dclevel
.prgnClip
= IntSysCreateRectpRgnIndirect(&rect
);
78 dc
->fs
|= DC_FLAG_DIRTY_RAO
;
80 return IntGdiCombineRgn(dc
->dclevel
.prgnClip
, dc
->dclevel
.prgnClip
, prgn
, fnMode
);
86 NtGdiExtSelectClipRgn(
95 if (!(dc
= DC_LockDc(hDC
)))
97 EngSetLastError(ERROR_INVALID_HANDLE
);
101 prgn
= REGION_LockRgn(hrgn
);
103 if ((prgn
== NULL
) && (fnMode
!= RGN_COPY
))
105 EngSetLastError(ERROR_INVALID_HANDLE
);
110 retval
= IntGdiExtSelectClipRgn(dc
, prgn
, fnMode
);
114 REGION_UnlockRgn(prgn
);
121 GdiGetClipBox(HDC hDC
, PRECTL rc
)
125 PROSRGNDATA pRgnNew
, pRgn
= NULL
;
127 if (!(dc
= DC_LockDc(hDC
)))
132 if (dc
->fs
& DC_FLAG_DIRTY_RAO
)
133 CLIPPING_UpdateGCRegion(dc
);
135 /* FIXME: Rao and Vis only! */
136 if (dc
->prgnAPI
) // APIRGN
140 else if (dc
->dclevel
.prgnMeta
) // METARGN
142 pRgn
= dc
->dclevel
.prgnMeta
;
144 else if (dc
->dclevel
.prgnClip
) // CLIPRGN
146 pRgn
= dc
->dclevel
.prgnClip
;
151 pRgnNew
= IntSysCreateRectpRgn( 0, 0, 0, 0 );
159 IntGdiCombineRgn(pRgnNew
, dc
->prgnVis
, pRgn
, RGN_AND
);
161 retval
= REGION_GetRgnBox(pRgnNew
, rc
);
163 REGION_Delete(pRgnNew
);
169 retval
= REGION_GetRgnBox(dc
->prgnVis
, rc
);
177 NtGdiGetAppClipBox(HDC hDC
, PRECTL rc
)
180 NTSTATUS Status
= STATUS_SUCCESS
;
183 Ret
= GdiGetClipBox(hDC
, &Saferect
);
192 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER
)
194 Status
= _SEH2_GetExceptionCode();
198 if(!NT_SUCCESS(Status
))
200 SetLastNtError(Status
);
207 int APIENTRY
NtGdiExcludeClipRect(HDC hDC
,
216 PDC dc
= DC_LockDc(hDC
);
220 EngSetLastError(ERROR_INVALID_HANDLE
);
224 Rect
.left
= LeftRect
;
226 Rect
.right
= RightRect
;
227 Rect
.bottom
= BottomRect
;
229 IntLPtoDP(dc
, (LPPOINT
)&Rect
, 2);
231 prgnNew
= IntSysCreateRectpRgnIndirect(&Rect
);
238 if (!dc
->dclevel
.prgnClip
)
240 dc
->dclevel
.prgnClip
= IntSysCreateRectpRgn(0, 0, 0, 0);
241 IntGdiCombineRgn(dc
->dclevel
.prgnClip
, dc
->prgnVis
, prgnNew
, RGN_DIFF
);
242 Result
= SIMPLEREGION
;
246 Result
= IntGdiCombineRgn(dc
->dclevel
.prgnClip
, dc
->dclevel
.prgnClip
, prgnNew
, RGN_DIFF
);
248 REGION_Delete(prgnNew
);
251 dc
->fs
|= DC_FLAG_DIRTY_RAO
;
258 int APIENTRY
NtGdiIntersectClipRect(HDC hDC
,
267 PDC dc
= DC_LockDc(hDC
);
269 DPRINT("NtGdiIntersectClipRect(%p, %d,%d-%d,%d)\n",
270 hDC
, LeftRect
, TopRect
, RightRect
, BottomRect
);
274 EngSetLastError(ERROR_INVALID_HANDLE
);
278 Rect
.left
= LeftRect
;
280 Rect
.right
= RightRect
;
281 Rect
.bottom
= BottomRect
;
283 IntLPtoDP(dc
, (LPPOINT
)&Rect
, 2);
285 pNewRgn
= IntSysCreateRectpRgnIndirect(&Rect
);
290 else if (!dc
->dclevel
.prgnClip
)
292 dc
->dclevel
.prgnClip
= pNewRgn
;
293 Result
= SIMPLEREGION
;
297 Result
= IntGdiCombineRgn(dc
->dclevel
.prgnClip
, dc
->dclevel
.prgnClip
, pNewRgn
, RGN_AND
);
298 REGION_Delete(pNewRgn
);
301 dc
->fs
|= DC_FLAG_DIRTY_RAO
;
308 int APIENTRY
NtGdiOffsetClipRgn(HDC hDC
,
315 if(!(dc
= DC_LockDc(hDC
)))
317 EngSetLastError(ERROR_INVALID_HANDLE
);
321 if(dc
->dclevel
.prgnClip
!= NULL
)
323 Result
= IntGdiOffsetRgn(dc
->dclevel
.prgnClip
,
326 dc
->fs
|= DC_FLAG_DIRTY_RAO
;
337 BOOL APIENTRY
NtGdiPtVisible(HDC hDC
,
344 if(!(dc
= DC_LockDc(hDC
)))
346 EngSetLastError(ERROR_INVALID_HANDLE
);
353 IntLPtoDP(dc
, &pt
, 1);
354 ret
= REGION_PtInRegion(dc
->prgnRao
, pt
.x
, pt
.y
);
368 NTSTATUS Status
= STATUS_SUCCESS
;
369 PDC dc
= DC_LockDc(hDC
);
375 EngSetLastError(ERROR_INVALID_HANDLE
);
381 ProbeForRead(UnsafeRect
,
386 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER
)
388 Status
= _SEH2_GetExceptionCode();
392 if(!NT_SUCCESS(Status
))
395 SetLastNtError(Status
);
399 if (dc
->fs
& DC_FLAG_DIRTY_RAO
)
400 CLIPPING_UpdateGCRegion(dc
);
404 IntLPtoDP(dc
, (LPPOINT
)&Rect
, 2);
405 Result
= REGION_RectInRegion(dc
->prgnRao
, &Rect
);
414 IntGdiSetMetaRgn(PDC pDC
)
418 if ( pDC
->dclevel
.prgnMeta
)
420 if ( pDC
->dclevel
.prgnClip
)
422 Ret
= IntGdiCombineRgn(pDC
->dclevel
.prgnMeta
, pDC
->dclevel
.prgnMeta
, pDC
->dclevel
.prgnClip
, RGN_AND
);
425 REGION_Delete(pDC
->dclevel
.prgnClip
);
426 pDC
->dclevel
.prgnClip
= NULL
;
427 IntGdiReleaseRaoRgn(pDC
);
431 Ret
= REGION_Complexity(pDC
->dclevel
.prgnMeta
);
435 if ( pDC
->dclevel
.prgnClip
)
437 Ret
= REGION_Complexity(pDC
->dclevel
.prgnClip
);
438 pDC
->dclevel
.prgnMeta
= pDC
->dclevel
.prgnClip
;
439 pDC
->dclevel
.prgnClip
= NULL
;
446 pDC
->fs
|= DC_FLAG_DIRTY_RAO
;
452 int APIENTRY
NtGdiSetMetaRgn(HDC hDC
)
455 PDC pDC
= DC_LockDc(hDC
);
459 EngSetLastError(ERROR_INVALID_PARAMETER
);
462 Ret
= IntGdiSetMetaRgn(pDC
);
470 CLIPPING_UpdateGCRegion(PDC pDC
)
472 /* Must have VisRgn set to a valid state! */
473 ASSERT (pDC
->prgnVis
);
477 REGION_Delete(pDC
->prgnAPI
);
482 REGION_Delete(pDC
->prgnRao
);
484 pDC
->prgnRao
= IntSysCreateRectpRgn(0,0,0,0);
486 ASSERT(pDC
->prgnRao
);
488 if (pDC
->dclevel
.prgnMeta
|| pDC
->dclevel
.prgnClip
)
490 pDC
->prgnAPI
= IntSysCreateRectpRgn(0,0,0,0);
491 if (!pDC
->dclevel
.prgnMeta
)
493 IntGdiCombineRgn(pDC
->prgnAPI
,
494 pDC
->dclevel
.prgnClip
,
498 else if (!pDC
->dclevel
.prgnClip
)
500 IntGdiCombineRgn(pDC
->prgnAPI
,
501 pDC
->dclevel
.prgnMeta
,
507 IntGdiCombineRgn(pDC
->prgnAPI
,
508 pDC
->dclevel
.prgnClip
,
509 pDC
->dclevel
.prgnMeta
,
516 IntGdiCombineRgn(pDC
->prgnRao
,
523 IntGdiCombineRgn(pDC
->prgnRao
,
530 IntGdiOffsetRgn(pDC
->prgnRao
, pDC
->ptlDCOrig
.x
, pDC
->ptlDCOrig
.y
);
532 RtlCopyMemory(&pDC
->erclClip
,
533 &pDC
->prgnRao
->rdh
.rcBound
,
536 pDC
->fs
&= ~DC_FLAG_DIRTY_RAO
;
538 // pDC->co should be used. Example, CLIPOBJ_cEnumStart uses XCLIPOBJ to build
539 // the rects from region objects rects in pClipRgn->Buffer.
540 // With pDC->co.pClipRgn->Buffer,
541 // pDC->co.pClipRgn = pDC->prgnRao ? pDC->prgnRao : pDC->prgnVis;
543 IntEngUpdateClipRegion(&pDC
->co
,
544 pDC
->prgnRao
->rdh
.nCount
,
545 pDC
->prgnRao
->Buffer
,
548 IntGdiOffsetRgn(pDC
->prgnRao
, -pDC
->ptlDCOrig
.x
, -pDC
->ptlDCOrig
.y
);