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 return IntGdiCombineRgn(dc
->dclevel
.prgnClip
, prgn
, NULL
, RGN_COPY
);
68 if (!dc
->dclevel
.prgnClip
)
72 REGION_GetRgnBox(dc
->prgnVis
, &rect
);
73 dc
->dclevel
.prgnClip
= IntSysCreateRectpRgnIndirect(&rect
);
76 dc
->fs
|= DC_FLAG_DIRTY_RAO
;
78 return IntGdiCombineRgn(dc
->dclevel
.prgnClip
, dc
->dclevel
.prgnClip
, prgn
, fnMode
);
84 NtGdiExtSelectClipRgn(
93 if (!(dc
= DC_LockDc(hDC
)))
95 EngSetLastError(ERROR_INVALID_HANDLE
);
99 prgn
= REGION_LockRgn(hrgn
);
101 if ((prgn
== NULL
) && (fnMode
!= RGN_COPY
))
103 EngSetLastError(ERROR_INVALID_HANDLE
);
108 retval
= IntGdiExtSelectClipRgn(dc
, prgn
, fnMode
);
112 REGION_UnlockRgn(prgn
);
119 GdiGetClipBox(HDC hDC
, PRECTL rc
)
123 PROSRGNDATA pRgnNew
, pRgn
= NULL
;
125 if (!(dc
= DC_LockDc(hDC
)))
130 if (dc
->fs
& DC_FLAG_DIRTY_RAO
)
131 CLIPPING_UpdateGCRegion(dc
);
133 /* FIXME: Rao and Vis only! */
134 if (dc
->prgnAPI
) // APIRGN
138 else if (dc
->dclevel
.prgnMeta
) // METARGN
140 pRgn
= dc
->dclevel
.prgnMeta
;
142 else if (dc
->dclevel
.prgnClip
) // CLIPRGN
144 pRgn
= dc
->dclevel
.prgnClip
;
149 pRgnNew
= IntSysCreateRectpRgn( 0, 0, 0, 0 );
157 IntGdiCombineRgn(pRgnNew
, dc
->prgnVis
, pRgn
, RGN_AND
);
159 retval
= REGION_GetRgnBox(pRgnNew
, rc
);
161 REGION_Delete(pRgnNew
);
167 retval
= REGION_GetRgnBox(dc
->prgnVis
, rc
);
175 NtGdiGetAppClipBox(HDC hDC
, PRECTL rc
)
178 NTSTATUS Status
= STATUS_SUCCESS
;
181 Ret
= GdiGetClipBox(hDC
, &Saferect
);
190 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER
)
192 Status
= _SEH2_GetExceptionCode();
196 if(!NT_SUCCESS(Status
))
198 SetLastNtError(Status
);
205 int APIENTRY
NtGdiExcludeClipRect(HDC hDC
,
214 PDC dc
= DC_LockDc(hDC
);
218 EngSetLastError(ERROR_INVALID_HANDLE
);
222 Rect
.left
= LeftRect
;
224 Rect
.right
= RightRect
;
225 Rect
.bottom
= BottomRect
;
227 IntLPtoDP(dc
, (LPPOINT
)&Rect
, 2);
229 prgnNew
= IntSysCreateRectpRgnIndirect(&Rect
);
236 if (!dc
->dclevel
.prgnClip
)
238 dc
->dclevel
.prgnClip
= IntSysCreateRectpRgn(0, 0, 0, 0);
239 IntGdiCombineRgn(dc
->dclevel
.prgnClip
, dc
->prgnVis
, prgnNew
, RGN_DIFF
);
240 Result
= SIMPLEREGION
;
244 Result
= IntGdiCombineRgn(dc
->dclevel
.prgnClip
, dc
->dclevel
.prgnClip
, prgnNew
, RGN_DIFF
);
246 REGION_Delete(prgnNew
);
249 dc
->fs
|= DC_FLAG_DIRTY_RAO
;
256 int APIENTRY
NtGdiIntersectClipRect(HDC hDC
,
265 PDC dc
= DC_LockDc(hDC
);
267 DPRINT("NtGdiIntersectClipRect(%p, %d,%d-%d,%d)\n",
268 hDC
, LeftRect
, TopRect
, RightRect
, BottomRect
);
272 EngSetLastError(ERROR_INVALID_HANDLE
);
276 Rect
.left
= LeftRect
;
278 Rect
.right
= RightRect
;
279 Rect
.bottom
= BottomRect
;
281 IntLPtoDP(dc
, (LPPOINT
)&Rect
, 2);
283 pNewRgn
= IntSysCreateRectpRgnIndirect(&Rect
);
288 else if (!dc
->dclevel
.prgnClip
)
290 dc
->dclevel
.prgnClip
= pNewRgn
;
291 Result
= SIMPLEREGION
;
295 Result
= IntGdiCombineRgn(dc
->dclevel
.prgnClip
, dc
->dclevel
.prgnClip
, pNewRgn
, RGN_AND
);
296 REGION_Delete(pNewRgn
);
299 dc
->fs
|= DC_FLAG_DIRTY_RAO
;
306 int APIENTRY
NtGdiOffsetClipRgn(HDC hDC
,
313 if(!(dc
= DC_LockDc(hDC
)))
315 EngSetLastError(ERROR_INVALID_HANDLE
);
319 if(dc
->dclevel
.prgnClip
!= NULL
)
321 Result
= IntGdiOffsetRgn(dc
->dclevel
.prgnClip
,
324 dc
->fs
|= DC_FLAG_DIRTY_RAO
;
335 BOOL APIENTRY
NtGdiPtVisible(HDC hDC
,
342 if(!(dc
= DC_LockDc(hDC
)))
344 EngSetLastError(ERROR_INVALID_HANDLE
);
351 IntLPtoDP(dc
, &pt
, 1);
352 ret
= REGION_PtInRegion(dc
->prgnRao
, pt
.x
, pt
.y
);
366 NTSTATUS Status
= STATUS_SUCCESS
;
367 PDC dc
= DC_LockDc(hDC
);
373 EngSetLastError(ERROR_INVALID_HANDLE
);
379 ProbeForRead(UnsafeRect
,
384 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER
)
386 Status
= _SEH2_GetExceptionCode();
390 if(!NT_SUCCESS(Status
))
393 SetLastNtError(Status
);
397 if (dc
->fs
& DC_FLAG_DIRTY_RAO
)
398 CLIPPING_UpdateGCRegion(dc
);
402 IntLPtoDP(dc
, (LPPOINT
)&Rect
, 2);
403 Result
= REGION_RectInRegion(dc
->prgnRao
, &Rect
);
412 IntGdiSetMetaRgn(PDC pDC
)
416 if ( pDC
->dclevel
.prgnMeta
)
418 if ( pDC
->dclevel
.prgnClip
)
420 Ret
= IntGdiCombineRgn(pDC
->dclevel
.prgnMeta
, pDC
->dclevel
.prgnMeta
, pDC
->dclevel
.prgnClip
, RGN_AND
);
423 REGION_Delete(pDC
->dclevel
.prgnClip
);
424 pDC
->dclevel
.prgnClip
= NULL
;
425 IntGdiReleaseRaoRgn(pDC
);
429 Ret
= REGION_Complexity(pDC
->dclevel
.prgnMeta
);
433 if ( pDC
->dclevel
.prgnClip
)
435 Ret
= REGION_Complexity(pDC
->dclevel
.prgnClip
);
436 pDC
->dclevel
.prgnMeta
= pDC
->dclevel
.prgnClip
;
437 pDC
->dclevel
.prgnClip
= NULL
;
444 pDC
->fs
|= DC_FLAG_DIRTY_RAO
;
450 int APIENTRY
NtGdiSetMetaRgn(HDC hDC
)
453 PDC pDC
= DC_LockDc(hDC
);
457 EngSetLastError(ERROR_INVALID_PARAMETER
);
460 Ret
= IntGdiSetMetaRgn(pDC
);
468 CLIPPING_UpdateGCRegion(PDC pDC
)
470 /* Must have VisRgn set to a valid state! */
471 ASSERT (pDC
->prgnVis
);
475 REGION_Delete(pDC
->prgnAPI
);
480 REGION_Delete(pDC
->prgnRao
);
482 pDC
->prgnRao
= IntSysCreateRectpRgn(0,0,0,0);
484 ASSERT(pDC
->prgnRao
);
486 if (pDC
->dclevel
.prgnMeta
|| pDC
->dclevel
.prgnClip
)
488 pDC
->prgnAPI
= IntSysCreateRectpRgn(0,0,0,0);
489 if (!pDC
->dclevel
.prgnMeta
)
491 IntGdiCombineRgn(pDC
->prgnAPI
,
492 pDC
->dclevel
.prgnClip
,
496 else if (!pDC
->dclevel
.prgnClip
)
498 IntGdiCombineRgn(pDC
->prgnAPI
,
499 pDC
->dclevel
.prgnMeta
,
505 IntGdiCombineRgn(pDC
->prgnAPI
,
506 pDC
->dclevel
.prgnClip
,
507 pDC
->dclevel
.prgnMeta
,
514 IntGdiCombineRgn(pDC
->prgnRao
,
521 IntGdiCombineRgn(pDC
->prgnRao
,
528 IntGdiOffsetRgn(pDC
->prgnRao
, pDC
->ptlDCOrig
.x
, pDC
->ptlDCOrig
.y
);
530 RtlCopyMemory(&pDC
->erclClip
,
531 &pDC
->prgnRao
->rdh
.rcBound
,
534 pDC
->fs
&= ~DC_FLAG_DIRTY_RAO
;
536 // pDC->co should be used. Example, CLIPOBJ_cEnumStart uses XCLIPOBJ to build
537 // the rects from region objects rects in pClipRgn->Buffer.
538 // With pDC->co.pClipRgn->Buffer,
539 // pDC->co.pClipRgn = pDC->prgnRao ? pDC->prgnRao : pDC->prgnVis;
541 IntEngUpdateClipRegion(&pDC
->co
,
542 pDC
->prgnRao
->rdh
.nCount
,
543 pDC
->prgnRao
->Buffer
,
546 IntGdiOffsetRgn(pDC
->prgnRao
, -pDC
->ptlDCOrig
.x
, -pDC
->ptlDCOrig
.y
);