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(
49 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
;
61 EngSetLastError(ERROR_INVALID_PARAMETER
);
66 if (!dc
->dclevel
.prgnClip
)
70 REGION_GetRgnBox(dc
->prgnVis
, &rect
);
71 dc
->dclevel
.prgnClip
= IntSysCreateRectpRgnIndirect(&rect
);
74 dc
->fs
|= DC_FLAG_DIRTY_RAO
;
76 if(fnMode
== RGN_COPY
)
77 return IntGdiCombineRgn(dc
->dclevel
.prgnClip
, prgn
, 0, fnMode
);
79 return IntGdiCombineRgn(dc
->dclevel
.prgnClip
, dc
->dclevel
.prgnClip
, prgn
, fnMode
);
85 NtGdiExtSelectClipRgn(
94 if (!(dc
= DC_LockDc(hDC
)))
96 EngSetLastError(ERROR_INVALID_HANDLE
);
100 prgn
= REGION_LockRgn(hrgn
);
102 /* IntGdiExtSelectClipRgn takes care of checking for NULL region */
103 retval
= IntGdiExtSelectClipRgn(dc
, prgn
, fnMode
);
106 REGION_UnlockRgn(prgn
);
113 GdiGetClipBox(HDC hDC
, PRECTL rc
)
117 PROSRGNDATA pRgnNew
, pRgn
= NULL
;
119 if (!(dc
= DC_LockDc(hDC
)))
124 /* FIXME: Rao and Vis only! */
125 if (dc
->prgnAPI
) // APIRGN
129 else if (dc
->dclevel
.prgnMeta
) // METARGN
131 pRgn
= dc
->dclevel
.prgnMeta
;
133 else if (dc
->dclevel
.prgnClip
) // CLIPRGN
135 pRgn
= dc
->dclevel
.prgnClip
;
140 pRgnNew
= IntSysCreateRectpRgn( 0, 0, 0, 0 );
148 IntGdiCombineRgn(pRgnNew
, dc
->prgnVis
, pRgn
, RGN_AND
);
150 retval
= REGION_GetRgnBox(pRgnNew
, rc
);
152 REGION_Delete(pRgnNew
);
158 retval
= REGION_GetRgnBox(dc
->prgnVis
, rc
);
166 NtGdiGetAppClipBox(HDC hDC
, PRECTL rc
)
169 NTSTATUS Status
= STATUS_SUCCESS
;
172 Ret
= GdiGetClipBox(hDC
, &Saferect
);
181 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER
)
183 Status
= _SEH2_GetExceptionCode();
187 if(!NT_SUCCESS(Status
))
189 SetLastNtError(Status
);
196 int APIENTRY
NtGdiExcludeClipRect(HDC hDC
,
205 PDC dc
= DC_LockDc(hDC
);
209 EngSetLastError(ERROR_INVALID_HANDLE
);
213 Rect
.left
= LeftRect
;
215 Rect
.right
= RightRect
;
216 Rect
.bottom
= BottomRect
;
218 IntLPtoDP(dc
, (LPPOINT
)&Rect
, 2);
220 prgnNew
= IntSysCreateRectpRgnIndirect(&Rect
);
227 if (!dc
->dclevel
.prgnClip
)
229 dc
->dclevel
.prgnClip
= IntSysCreateRectpRgn(0, 0, 0, 0);
230 IntGdiCombineRgn(dc
->dclevel
.prgnClip
, dc
->prgnVis
, prgnNew
, RGN_DIFF
);
231 Result
= SIMPLEREGION
;
235 Result
= IntGdiCombineRgn(dc
->dclevel
.prgnClip
, dc
->dclevel
.prgnClip
, prgnNew
, RGN_DIFF
);
237 REGION_Delete(prgnNew
);
240 dc
->fs
|= DC_FLAG_DIRTY_RAO
;
247 int APIENTRY
NtGdiIntersectClipRect(HDC hDC
,
256 PDC dc
= DC_LockDc(hDC
);
258 DPRINT("NtGdiIntersectClipRect(%p, %d,%d-%d,%d)\n",
259 hDC
, LeftRect
, TopRect
, RightRect
, BottomRect
);
263 EngSetLastError(ERROR_INVALID_HANDLE
);
267 Rect
.left
= LeftRect
;
269 Rect
.right
= RightRect
;
270 Rect
.bottom
= BottomRect
;
272 IntLPtoDP(dc
, (LPPOINT
)&Rect
, 2);
274 pNewRgn
= IntSysCreateRectpRgnIndirect(&Rect
);
279 else if (!dc
->dclevel
.prgnClip
)
281 dc
->dclevel
.prgnClip
= pNewRgn
;
282 Result
= SIMPLEREGION
;
286 Result
= IntGdiCombineRgn(dc
->dclevel
.prgnClip
, dc
->dclevel
.prgnClip
, pNewRgn
, RGN_AND
);
287 REGION_Delete(pNewRgn
);
290 dc
->fs
|= DC_FLAG_DIRTY_RAO
;
297 int APIENTRY
NtGdiOffsetClipRgn(HDC hDC
,
304 if(!(dc
= DC_LockDc(hDC
)))
306 EngSetLastError(ERROR_INVALID_HANDLE
);
310 if(dc
->dclevel
.prgnClip
!= NULL
)
312 Result
= IntGdiOffsetRgn(dc
->dclevel
.prgnClip
,
315 dc
->fs
|= DC_FLAG_DIRTY_RAO
;
326 BOOL APIENTRY
NtGdiPtVisible(HDC hDC
,
333 if(!(dc
= DC_LockDc(hDC
)))
335 EngSetLastError(ERROR_INVALID_HANDLE
);
342 IntLPtoDP(dc
, &pt
, 1);
343 ret
= REGION_PtInRegion(dc
->prgnRao
, pt
.x
, pt
.y
);
357 NTSTATUS Status
= STATUS_SUCCESS
;
358 PDC dc
= DC_LockDc(hDC
);
364 EngSetLastError(ERROR_INVALID_HANDLE
);
370 ProbeForRead(UnsafeRect
,
375 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER
)
377 Status
= _SEH2_GetExceptionCode();
381 if(!NT_SUCCESS(Status
))
384 SetLastNtError(Status
);
388 if (dc
->fs
& DC_FLAG_DIRTY_RAO
)
389 CLIPPING_UpdateGCRegion(dc
);
393 IntLPtoDP(dc
, (LPPOINT
)&Rect
, 2);
394 Result
= REGION_RectInRegion(dc
->prgnRao
, &Rect
);
403 IntGdiSetMetaRgn(PDC pDC
)
407 if ( pDC
->dclevel
.prgnMeta
)
409 if ( pDC
->dclevel
.prgnClip
)
411 Ret
= IntGdiCombineRgn(pDC
->dclevel
.prgnMeta
, pDC
->dclevel
.prgnMeta
, pDC
->dclevel
.prgnClip
, RGN_AND
);
414 REGION_Delete(pDC
->dclevel
.prgnClip
);
415 pDC
->dclevel
.prgnClip
= NULL
;
416 IntGdiReleaseRaoRgn(pDC
);
420 Ret
= REGION_Complexity(pDC
->dclevel
.prgnMeta
);
424 if ( pDC
->dclevel
.prgnClip
)
426 Ret
= REGION_Complexity(pDC
->dclevel
.prgnClip
);
427 pDC
->dclevel
.prgnMeta
= pDC
->dclevel
.prgnClip
;
428 pDC
->dclevel
.prgnClip
= NULL
;
435 pDC
->fs
|= DC_FLAG_DIRTY_RAO
;
441 int APIENTRY
NtGdiSetMetaRgn(HDC hDC
)
444 PDC pDC
= DC_LockDc(hDC
);
448 EngSetLastError(ERROR_INVALID_PARAMETER
);
451 Ret
= IntGdiSetMetaRgn(pDC
);
459 CLIPPING_UpdateGCRegion(PDC pDC
)
463 /* Must have VisRgn set to a valid state! */
464 ASSERT (pDC
->prgnVis
);
468 REGION_Delete(pDC
->prgnAPI
);
473 REGION_Delete(pDC
->prgnRao
);
475 pDC
->prgnRao
= IntSysCreateRectpRgn(0,0,0,0);
477 ASSERT(pDC
->prgnRao
);
479 if (pDC
->dclevel
.prgnMeta
|| pDC
->dclevel
.prgnClip
)
481 pDC
->prgnAPI
= IntSysCreateRectpRgn(0,0,0,0);
482 if (!pDC
->dclevel
.prgnMeta
)
484 IntGdiCombineRgn(pDC
->prgnAPI
,
485 pDC
->dclevel
.prgnClip
,
489 else if (!pDC
->dclevel
.prgnClip
)
491 IntGdiCombineRgn(pDC
->prgnAPI
,
492 pDC
->dclevel
.prgnMeta
,
498 IntGdiCombineRgn(pDC
->prgnAPI
,
499 pDC
->dclevel
.prgnClip
,
500 pDC
->dclevel
.prgnMeta
,
507 IntGdiCombineRgn(pDC
->prgnRao
,
514 IntGdiCombineRgn(pDC
->prgnRao
,
521 IntGdiOffsetRgn(pDC
->prgnRao
, pDC
->ptlDCOrig
.x
, pDC
->ptlDCOrig
.y
);
523 RtlCopyMemory(&pDC
->erclClip
,
524 &pDC
->prgnRao
->rdh
.rcBound
,
527 pDC
->fs
&= ~DC_FLAG_DIRTY_RAO
;
529 // pDC->co should be used. Example, CLIPOBJ_cEnumStart uses XCLIPOBJ to build
530 // the rects from region objects rects in pClipRgn->Buffer.
531 // With pDC->co.pClipRgn->Buffer,
532 // pDC->co.pClipRgn = pDC->prgnRao ? pDC->prgnRao : pDC->prgnVis;
534 co
= IntEngCreateClipRegion(pDC
->prgnRao
->rdh
.nCount
,
535 pDC
->prgnRao
->Buffer
,
539 if (pDC
->rosdc
.CombinedClip
!= NULL
)
540 IntEngDeleteClipRegion(pDC
->rosdc
.CombinedClip
);
542 pDC
->rosdc
.CombinedClip
= co
;
545 IntGdiOffsetRgn(pDC
->prgnRao
, -pDC
->ptlDCOrig
.x
, -pDC
->ptlDCOrig
.y
);