2 * ReactOS W32 Subsystem
3 * Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003 ReactOS Team
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License along
16 * with this program; if not, write to the Free Software Foundation, Inc.,
17 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
26 CLIPPING_UpdateGCRegion(DC
* Dc
)
28 PROSRGNDATA CombinedRegion
;
31 // would prefer this, but the rest of the code sucks
32 // ASSERT(Dc->rosdc.hGCClipRgn);
33 // ASSERT(Dc->rosdc.hClipRgn);
35 hRgnVis
= Dc
->prgnVis
->BaseObject
.hHmgr
;
37 if (Dc
->rosdc
.hGCClipRgn
== NULL
)
38 Dc
->rosdc
.hGCClipRgn
= IntSysCreateRectRgn(0, 0, 0, 0);
40 if (Dc
->rosdc
.hClipRgn
== NULL
)
41 NtGdiCombineRgn(Dc
->rosdc
.hGCClipRgn
, hRgnVis
, 0, RGN_COPY
);
43 NtGdiCombineRgn(Dc
->rosdc
.hGCClipRgn
, Dc
->rosdc
.hClipRgn
, hRgnVis
, RGN_AND
);
45 NtGdiOffsetRgn(Dc
->rosdc
.hGCClipRgn
, Dc
->ptlDCOrig
.x
, Dc
->ptlDCOrig
.y
);
47 if((CombinedRegion
= RGNOBJAPI_Lock(Dc
->rosdc
.hGCClipRgn
, NULL
)))
49 CLIPOBJ
*CombinedClip
;
51 CombinedClip
= IntEngCreateClipRegion(CombinedRegion
->rdh
.nCount
,
52 CombinedRegion
->Buffer
,
53 &CombinedRegion
->rdh
.rcBound
);
55 RGNOBJAPI_Unlock(CombinedRegion
);
59 DPRINT1("IntEngCreateClipRegion() failed\n");
63 if(Dc
->rosdc
.CombinedClip
!= NULL
)
64 IntEngDeleteClipRegion(Dc
->rosdc
.CombinedClip
);
66 Dc
->rosdc
.CombinedClip
= CombinedClip
;
69 return NtGdiOffsetRgn(Dc
->rosdc
.hGCClipRgn
, -Dc
->ptlDCOrig
.x
, -Dc
->ptlDCOrig
.y
);
73 GdiSelectVisRgn(HDC hdc
, HRGN hrgn
)
80 EngSetLastError(ERROR_INVALID_PARAMETER
);
83 if (!(dc
= DC_LockDc(hdc
)))
85 EngSetLastError(ERROR_INVALID_HANDLE
);
89 dc
->fs
&= ~DC_FLAG_DIRTY_RAO
;
91 ASSERT (dc
->prgnVis
!= NULL
);
93 retval
= NtGdiCombineRgn(dc
->prgnVis
->BaseObject
.hHmgr
, hrgn
, 0, RGN_COPY
);
94 if ( retval
!= ERROR
)
96 NtGdiOffsetRgn(dc
->prgnVis
->BaseObject
.hHmgr
, -dc
->ptlDCOrig
.x
, -dc
->ptlDCOrig
.y
);
97 CLIPPING_UpdateGCRegion(dc
);
105 int FASTCALL
GdiExtSelectClipRgn(PDC dc
,
109 // dc->fs &= ~DC_FLAG_DIRTY_RAO;
113 if (fnMode
== RGN_COPY
)
115 if (dc
->rosdc
.hClipRgn
!= NULL
)
117 REGION_FreeRgnByHandle(dc
->rosdc
.hClipRgn
);
118 dc
->rosdc
.hClipRgn
= NULL
;
123 EngSetLastError(ERROR_INVALID_PARAMETER
);
129 if (!dc
->rosdc
.hClipRgn
)
134 REGION_GetRgnBox(dc
->prgnVis
, &rect
);
135 dc
->rosdc
.hClipRgn
= IntSysCreateRectRgnIndirect(&rect
);
139 dc
->rosdc
.hClipRgn
= IntSysCreateRectRgn(0, 0, 0, 0);
142 if(fnMode
== RGN_COPY
)
144 NtGdiCombineRgn(dc
->rosdc
.hClipRgn
, hrgn
, 0, fnMode
);
147 NtGdiCombineRgn(dc
->rosdc
.hClipRgn
, dc
->rosdc
.hClipRgn
, hrgn
, fnMode
);
150 return CLIPPING_UpdateGCRegion(dc
);
154 int APIENTRY
NtGdiExtSelectClipRgn(HDC hDC
,
161 if (!(dc
= DC_LockDc(hDC
)))
163 EngSetLastError(ERROR_INVALID_HANDLE
);
167 retval
= GdiExtSelectClipRgn ( dc
, hrgn
, fnMode
);
174 GdiGetClipBox(HDC hDC
, PRECTL rc
)
178 PROSRGNDATA pRgnNew
, pRgn
= NULL
;
179 BOOL Unlock
= FALSE
; //Small hack
181 if (!(dc
= DC_LockDc(hDC
)))
186 /* FIXME! Rao and Vis only! */
187 if (dc
->prgnAPI
) // APIRGN
191 else if (dc
->dclevel
.prgnMeta
) // METARGN
193 pRgn
= dc
->dclevel
.prgnMeta
;
198 pRgn
= REGION_LockRgn(dc
->rosdc
.hClipRgn
); // CLIPRGN
203 pRgnNew
= IntSysCreateRectpRgn( 0, 0, 0, 0 );
208 if(Unlock
) REGION_UnlockRgn(pRgn
);
212 IntGdiCombineRgn(pRgnNew
, dc
->prgnVis
, pRgn
, RGN_AND
);
214 retval
= REGION_GetRgnBox(pRgnNew
, rc
);
216 REGION_FreeRgnByHandle(pRgnNew
->BaseObject
.hHmgr
);
219 if(Unlock
) REGION_UnlockRgn(pRgn
);
223 retval
= REGION_GetRgnBox(dc
->prgnVis
, rc
);
224 IntDPtoLP(dc
, (LPPOINT
)rc
, 2);
231 NtGdiGetAppClipBox(HDC hDC
, PRECTL rc
)
234 NTSTATUS Status
= STATUS_SUCCESS
;
237 Ret
= GdiGetClipBox(hDC
, &Saferect
);
246 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER
)
248 Status
= _SEH2_GetExceptionCode();
252 if(!NT_SUCCESS(Status
))
254 SetLastNtError(Status
);
261 int APIENTRY
NtGdiExcludeClipRect(HDC hDC
,
270 PDC dc
= DC_LockDc(hDC
);
274 EngSetLastError(ERROR_INVALID_HANDLE
);
278 Rect
.left
= LeftRect
;
280 Rect
.right
= RightRect
;
281 Rect
.bottom
= BottomRect
;
283 IntLPtoDP(dc
, (LPPOINT
)&Rect
, 2);
285 NewRgn
= IntSysCreateRectRgnIndirect(&Rect
);
292 if (!dc
->rosdc
.hClipRgn
)
294 dc
->rosdc
.hClipRgn
= IntSysCreateRectRgn(0, 0, 0, 0);
295 NtGdiCombineRgn(dc
->rosdc
.hClipRgn
, dc
->prgnVis
->BaseObject
.hHmgr
, NewRgn
, RGN_DIFF
);
296 Result
= SIMPLEREGION
;
300 Result
= NtGdiCombineRgn(dc
->rosdc
.hClipRgn
, dc
->rosdc
.hClipRgn
, NewRgn
, RGN_DIFF
);
302 REGION_FreeRgnByHandle(NewRgn
);
305 CLIPPING_UpdateGCRegion(dc
);
312 int APIENTRY
NtGdiIntersectClipRect(HDC hDC
,
321 PDC dc
= DC_LockDc(hDC
);
323 DPRINT("NtGdiIntersectClipRect(%x, %d,%d-%d,%d)\n",
324 hDC
, LeftRect
, TopRect
, RightRect
, BottomRect
);
328 EngSetLastError(ERROR_INVALID_HANDLE
);
332 Rect
.left
= LeftRect
;
334 Rect
.right
= RightRect
;
335 Rect
.bottom
= BottomRect
;
337 IntLPtoDP(dc
, (LPPOINT
)&Rect
, 2);
339 NewRgn
= IntSysCreateRectRgnIndirect(&Rect
);
344 else if (!dc
->rosdc
.hClipRgn
)
346 dc
->rosdc
.hClipRgn
= NewRgn
;
347 Result
= SIMPLEREGION
;
351 Result
= NtGdiCombineRgn(dc
->rosdc
.hClipRgn
, dc
->rosdc
.hClipRgn
, NewRgn
, RGN_AND
);
352 REGION_FreeRgnByHandle(NewRgn
);
355 CLIPPING_UpdateGCRegion(dc
);
362 int APIENTRY
NtGdiOffsetClipRgn(HDC hDC
,
369 if(!(dc
= DC_LockDc(hDC
)))
371 EngSetLastError(ERROR_INVALID_HANDLE
);
375 if(dc
->rosdc
.hClipRgn
!= NULL
)
377 Result
= NtGdiOffsetRgn(dc
->rosdc
.hClipRgn
,
380 CLIPPING_UpdateGCRegion(dc
);
391 BOOL APIENTRY
NtGdiPtVisible(HDC hDC
,
398 if(!(dc
= DC_LockDc(hDC
)))
400 EngSetLastError(ERROR_INVALID_HANDLE
);
404 rgn
= dc
->rosdc
.hGCClipRgn
;
407 return (rgn
? NtGdiPtInRegion(rgn
, X
, Y
) : FALSE
);
410 BOOL APIENTRY
NtGdiRectVisible(HDC hDC
,
413 NTSTATUS Status
= STATUS_SUCCESS
;
415 PDC dc
= DC_LockDc(hDC
);
421 EngSetLastError(ERROR_INVALID_HANDLE
);
427 ProbeForRead(UnsafeRect
,
432 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER
)
434 Status
= _SEH2_GetExceptionCode();
438 if(!NT_SUCCESS(Status
))
441 SetLastNtError(Status
);
445 if (dc
->rosdc
.hGCClipRgn
)
447 if((Rgn
= (PROSRGNDATA
)RGNOBJAPI_Lock(dc
->rosdc
.hGCClipRgn
, NULL
)))
449 IntLPtoDP(dc
, (LPPOINT
)&Rect
, 2);
450 Result
= REGION_RectInRegion(Rgn
, &Rect
);
451 RGNOBJAPI_Unlock(Rgn
);
461 IntGdiSetMetaRgn(PDC pDC
)
466 if ( pDC
->dclevel
.prgnMeta
)
468 if ( pDC
->dclevel
.prgnClip
)
470 TempRgn
= IntSysCreateRectpRgn(0,0,0,0);
473 Ret
= IntGdiCombineRgn( TempRgn
,
474 pDC
->dclevel
.prgnMeta
,
475 pDC
->dclevel
.prgnClip
,
479 GDIOBJ_ShareUnlockObjByPtr(&pDC
->dclevel
.prgnMeta
->BaseObject
);
480 if (!((PROSRGNDATA
)pDC
->dclevel
.prgnMeta
)->BaseObject
.ulShareCount
)
481 REGION_Delete(pDC
->dclevel
.prgnMeta
);
483 pDC
->dclevel
.prgnMeta
= TempRgn
;
485 GDIOBJ_ShareUnlockObjByPtr(&pDC
->dclevel
.prgnClip
->BaseObject
);
486 if (!((PROSRGNDATA
)pDC
->dclevel
.prgnClip
)->BaseObject
.ulShareCount
)
487 REGION_Delete(pDC
->dclevel
.prgnClip
);
489 pDC
->dclevel
.prgnClip
= NULL
;
491 IntGdiReleaseRaoRgn(pDC
);
494 REGION_Delete(TempRgn
);
498 Ret
= REGION_Complexity(pDC
->dclevel
.prgnMeta
);
502 if ( pDC
->dclevel
.prgnClip
)
504 Ret
= REGION_Complexity(pDC
->dclevel
.prgnClip
);
505 pDC
->dclevel
.prgnMeta
= pDC
->dclevel
.prgnClip
;
506 pDC
->dclevel
.prgnClip
= NULL
;
515 int APIENTRY
NtGdiSetMetaRgn(HDC hDC
)
518 PDC pDC
= DC_LockDc(hDC
);
522 EngSetLastError(ERROR_INVALID_PARAMETER
);
525 Ret
= IntGdiSetMetaRgn(pDC
);
532 NEW_CLIPPING_UpdateGCRegion(PDC pDC
)
536 /* Must have VisRgn set to a valid state! */
537 ASSERT (pDC
->prgnVis
);
541 REGION_Delete(pDC
->prgnAPI
);
542 pDC
->prgnAPI
= IntSysCreateRectpRgn(0,0,0,0);
547 REGION_Delete(pDC
->prgnRao
);
548 pDC
->prgnRao
= IntSysCreateRectpRgn(0,0,0,0);
551 if (pDC
->dclevel
.prgnMeta
&& pDC
->dclevel
.prgnClip
)
553 IntGdiCombineRgn( pDC
->prgnAPI
,
554 pDC
->dclevel
.prgnClip
,
555 pDC
->dclevel
.prgnMeta
,
560 if (pDC
->dclevel
.prgnClip
)
562 IntGdiCombineRgn( pDC
->prgnAPI
,
563 pDC
->dclevel
.prgnClip
,
567 else if (pDC
->dclevel
.prgnMeta
)
569 IntGdiCombineRgn( pDC
->prgnAPI
,
570 pDC
->dclevel
.prgnMeta
,
576 IntGdiCombineRgn( pDC
->prgnRao
,
581 RtlCopyMemory(&pDC
->erclClip
,
582 &((PROSRGNDATA
)pDC
->prgnRao
)->rdh
.rcBound
,
585 pDC
->fs
&= ~DC_FLAG_DIRTY_RAO
;
587 IntGdiOffsetRgn(pDC
->prgnRao
, pDC
->ptlDCOrig
.x
, pDC
->ptlDCOrig
.y
);
589 // pDC->co should be used. Example, CLIPOBJ_cEnumStart uses XCLIPOBJ to build
590 // the rects from region objects rects in pClipRgn->Buffer.
591 // With pDC->co.pClipRgn->Buffer,
592 // pDC->co.pClipRgn = pDC->prgnRao ? pDC->prgnRao : pDC->prgnVis;
594 co
= IntEngCreateClipRegion( ((PROSRGNDATA
)pDC
->prgnRao
)->rdh
.nCount
,
595 ((PROSRGNDATA
)pDC
->prgnRao
)->Buffer
,
599 if (pDC
->rosdc
.CombinedClip
!= NULL
)
600 IntEngDeleteClipRegion(pDC
->rosdc
.CombinedClip
);
602 pDC
->rosdc
.CombinedClip
= co
;
605 return IntGdiOffsetRgn(pDC
->prgnRao
, -pDC
->ptlDCOrig
.x
, -pDC
->ptlDCOrig
.y
);