6 #define INRECT(r, x, y) \
7 ( ( ((r).right > x)) && \
8 ( ((r).left <= x)) && \
9 ( ((r).bottom > y)) && \
12 #define OVERLAPPING_RGN 0
13 #define INVERTED_RGN 1
17 From tests, there are four results based on normalized coordinates.
18 If the rects are overlapping and normalized, it's OVERLAPPING_RGN.
19 If the rects are overlapping in anyway or same in dimension and one is inverted,
21 If the rects are same in dimension or NULL, it's SAME_RGN.
22 If the rects are overlapping and not normalized or displace in different areas,
28 ComplexityFromRects( PRECTL prc1
, PRECTL prc2
)
30 if ( prc2
->left
>= prc1
->left
)
32 if ( ( prc1
->right
>= prc2
->right
) &&
33 ( prc1
->top
<= prc2
->top
) &&
34 ( prc1
->bottom
>= prc2
->bottom
) )
37 if ( prc2
->left
> prc1
->left
)
39 if ( ( prc1
->left
>= prc2
->right
) ||
40 ( prc1
->right
<= prc2
->left
) ||
41 ( prc1
->top
>= prc2
->bottom
) ||
42 ( prc1
->bottom
<= prc2
->top
) )
47 if ( ( prc2
->right
< prc1
->right
) ||
48 ( prc2
->top
> prc1
->top
) ||
49 ( prc2
->bottom
< prc1
->bottom
) )
51 if ( ( prc1
->left
>= prc2
->right
) ||
52 ( prc1
->right
<= prc2
->left
) ||
53 ( prc1
->top
>= prc2
->bottom
) ||
54 ( prc1
->bottom
<= prc2
->top
) )
61 return OVERLAPPING_RGN
;
67 SortRects(PRECT pRect
, INT nCount
)
69 INT i
= 0, a
= 0, b
= 0, c
, s
;
74 i
= 1; // set index point
75 c
= nCount
; // set inverse count
78 s
= i
; // set sort count
85 if(pRect
[b
].top
!= pRect
[i
].bottom
) break;
86 if(pRect
[b
].left
< pRect
[a
].left
)
94 } while ( s
< nCount
);
102 * I thought it was okay to have this in DeleteObject but~ Speed. (jt)
106 DeleteRegion( HRGN hRgn
)
111 if ((GdiGetHandleUserData((HGDIOBJ
) hRgn
, GDI_OBJECT_TYPE_REGION
, (PVOID
) &Rgn_Attr
)) &&
112 ( Rgn_Attr
!= NULL
))
114 PTEB pTeb
= NtCurrentTeb();
115 if (pTeb
->Win32ThreadInfo
!= NULL
)
117 if ((pTeb
->GdiTebBatch
.Offset
+ sizeof(GDIBSOBJECT
)) <= GDIBATCHBUFSIZE
)
119 PGDIBSOBJECT pgO
= (PGDIBSOBJECT
)(&pTeb
->GdiTebBatch
.Buffer
[0] +
120 pTeb
->GdiTebBatch
.Offset
);
121 pgO
->gbHdr
.Cmd
= GdiBCDelRgn
;
122 pgO
->gbHdr
.Size
= sizeof(GDIBSOBJECT
);
123 pgO
->hgdiobj
= (HGDIOBJ
)hRgn
;
125 pTeb
->GdiTebBatch
.Offset
+= sizeof(GDIBSOBJECT
);
126 pTeb
->GdiBatchCount
++;
127 if (pTeb
->GdiBatchCount
>= GDI_BatchLimit
) NtGdiFlush();
133 return NtGdiDeleteObjectApp((HGDIOBJ
) hRgn
);
138 MirrorRgnByWidth(HRGN hRgn
, INT Width
, HRGN
*phRgn
)
140 INT cRgnDSize
, Ret
= 0;
143 cRgnDSize
= NtGdiGetRegionData(hRgn
, 0, NULL
);
147 pRgnData
= LocalAlloc(LMEM_FIXED
, cRgnDSize
* sizeof(LONG
));
150 if ( GetRegionData(hRgn
, cRgnDSize
, pRgnData
) )
154 INT SaveL
= pRgnData
->rdh
.rcBound
.left
;
155 pRgnData
->rdh
.rcBound
.left
= Width
- pRgnData
->rdh
.rcBound
.right
;
156 pRgnData
->rdh
.rcBound
.right
= Width
- SaveL
;
157 if (pRgnData
->rdh
.nCount
> 0)
159 PRECT pRect
= (PRECT
)&pRgnData
->Buffer
;
160 for (i
= 0; i
< pRgnData
->rdh
.nCount
; i
++)
162 SaveL
= pRect
[i
].left
;
163 pRect
[i
].left
= Width
- pRect
[i
].right
;
164 pRect
[i
].right
= Width
- SaveL
;
167 SortRects((PRECT
)&pRgnData
->Buffer
, pRgnData
->rdh
.nCount
);
168 hRgnex
= ExtCreateRegion(NULL
, cRgnDSize
, pRgnData
);
171 if (phRgn
) phRgn
= (HRGN
*)hRgnex
;
174 CombineRgn(hRgn
, hRgnex
, 0, RGN_COPY
);
175 DeleteObject(hRgnex
);
188 MirrorRgnDC(HDC hdc
, HRGN hRgn
, HRGN
*phRgn
)
190 if (!GdiIsHandleValid((HGDIOBJ
) hdc
) ||
191 (GDI_HANDLE_GET_TYPE(hdc
) != GDI_OBJECT_TYPE_DC
)) return 0;
193 return MirrorRgnByWidth(hRgn
, NtGdiGetDeviceWidth(hdc
), phRgn
);
196 /* FUNCTIONS *****************************************************************/
203 CombineRgn(HRGN hDest
,
208 PRGN_ATTR pRgn_Attr_Dest
= NULL
;
209 PRGN_ATTR pRgn_Attr_Src1
= NULL
;
210 PRGN_ATTR pRgn_Attr_Src2
= NULL
;
214 Ret
= GdiGetHandleUserData((HGDIOBJ
) hDest
, GDI_OBJECT_TYPE_REGION
, (PVOID
) &pRgn_Attr_Dest
);
215 Ret
= GdiGetHandleUserData((HGDIOBJ
) hSrc1
, GDI_OBJECT_TYPE_REGION
, (PVOID
) &pRgn_Attr_Src1
);
220 pRgn_Attr_Src1
->Flags
> SIMPLEREGION
)
221 return NtGdiCombineRgn(hDest
, hSrc1
, hSrc2
, CombineMode
);
223 /* Handle COPY and use only src1. */
224 if ( CombineMode
== RGN_COPY
)
226 switch (pRgn_Attr_Src1
->Flags
)
229 Ret
= SetRectRgn( hDest
, 0, 0, 0, 0);
235 Ret
= SetRectRgn( hDest
,
236 pRgn_Attr_Src1
->Rect
.left
,
237 pRgn_Attr_Src1
->Rect
.top
,
238 pRgn_Attr_Src1
->Rect
.right
,
239 pRgn_Attr_Src1
->Rect
.bottom
);
246 return NtGdiCombineRgn(hDest
, hSrc1
, hSrc2
, CombineMode
);
250 Ret
= GdiGetHandleUserData((HGDIOBJ
) hSrc2
, GDI_OBJECT_TYPE_REGION
, (PVOID
) &pRgn_Attr_Src2
);
253 pRgn_Attr_Src2
->Flags
> SIMPLEREGION
)
254 return NtGdiCombineRgn(hDest
, hSrc1
, hSrc2
, CombineMode
);
257 if ( CombineMode
!= RGN_AND
)
259 if ( CombineMode
<= RGN_AND
)
262 There might be some type of junk in the call, so go K.
263 If this becomes a problem, need to setup parameter check at the top.
265 DPRINT1("Might be junk! CombineMode %d\n",CombineMode
);
266 return NtGdiCombineRgn(hDest
, hSrc1
, hSrc2
, CombineMode
);
269 if ( CombineMode
> RGN_XOR
) /* Handle DIFF. */
271 if ( CombineMode
!= RGN_DIFF
)
272 { /* Filter check! Well, must be junk?, so go K. */
273 DPRINT1("RGN_COPY was handled! CombineMode %d\n",CombineMode
);
274 return NtGdiCombineRgn(hDest
, hSrc1
, hSrc2
, CombineMode
);
277 if ( pRgn_Attr_Src1
->Flags
!= NULLREGION
&&
278 pRgn_Attr_Src2
->Flags
!= NULLREGION
)
280 Complexity
= ComplexityFromRects( &pRgn_Attr_Src1
->Rect
, &pRgn_Attr_Src2
->Rect
);
281 /* If same or overlapping and norm just go K. */
282 if (Complexity
== SAME_RGN
|| Complexity
== OVERLAPPING_RGN
)
283 return NtGdiCombineRgn(hDest
, hSrc1
, hSrc2
, CombineMode
);
286 if (SetRectRgn( hDest
, 0, 0, 0, 0))
290 else /* Handle OR or XOR. */
292 if ( pRgn_Attr_Src1
->Flags
== NULLREGION
)
294 if ( pRgn_Attr_Src2
->Flags
!= NULLREGION
)
295 { /* Src1 null and not NULL, set from src2. */
296 Ret
= SetRectRgn( hDest
,
297 pRgn_Attr_Src2
->Rect
.left
,
298 pRgn_Attr_Src2
->Rect
.top
,
299 pRgn_Attr_Src2
->Rect
.right
,
300 pRgn_Attr_Src2
->Rect
.bottom
);
306 if (SetRectRgn( hDest
, 0, 0, 0, 0))
310 /* Src1 is not NULL. */
311 if ( pRgn_Attr_Src2
->Flags
!= NULLREGION
)
313 if ( CombineMode
!= RGN_OR
) /* Filter XOR, so go K. */
314 return NtGdiCombineRgn(hDest
, hSrc1
, hSrc2
, CombineMode
);
316 Complexity
= ComplexityFromRects( &pRgn_Attr_Src1
->Rect
, &pRgn_Attr_Src2
->Rect
);
317 /* If inverted use Src2. */
318 if ( Complexity
== INVERTED_RGN
)
320 Ret
= SetRectRgn( hDest
,
321 pRgn_Attr_Src2
->Rect
.left
,
322 pRgn_Attr_Src2
->Rect
.top
,
323 pRgn_Attr_Src2
->Rect
.right
,
324 pRgn_Attr_Src2
->Rect
.bottom
);
329 /* Not NULL or overlapping or differentiated, go to K. */
330 if ( Complexity
!= SAME_RGN
)
331 return NtGdiCombineRgn(hDest
, hSrc1
, hSrc2
, CombineMode
);
332 /* If same, just fall through. */
335 Ret
= SetRectRgn( hDest
,
336 pRgn_Attr_Src1
->Rect
.left
,
337 pRgn_Attr_Src1
->Rect
.top
,
338 pRgn_Attr_Src1
->Rect
.right
,
339 pRgn_Attr_Src1
->Rect
.bottom
);
346 if ( pRgn_Attr_Src1
->Flags
!= NULLREGION
&&
347 pRgn_Attr_Src2
->Flags
!= NULLREGION
)
349 Complexity
= ComplexityFromRects( &pRgn_Attr_Src1
->Rect
, &pRgn_Attr_Src2
->Rect
);
351 if ( Complexity
== DIFF_RGN
) /* Differentiated in anyway just NULL rgn. */
353 if (SetRectRgn( hDest
, 0, 0, 0, 0))
358 if ( Complexity
!= INVERTED_RGN
) /* Not inverted and overlapping. */
360 if ( Complexity
!= SAME_RGN
) /* Must be norm and overlapping. */
361 return NtGdiCombineRgn(hDest
, hSrc1
, hSrc2
, CombineMode
);
362 /* Merge from src2. */
363 Ret
= SetRectRgn( hDest
,
364 pRgn_Attr_Src2
->Rect
.left
,
365 pRgn_Attr_Src2
->Rect
.top
,
366 pRgn_Attr_Src2
->Rect
.right
,
367 pRgn_Attr_Src2
->Rect
.bottom
);
372 /* Inverted so merge from src1. */
373 Ret
= SetRectRgn( hDest
,
374 pRgn_Attr_Src1
->Rect
.left
,
375 pRgn_Attr_Src1
->Rect
.top
,
376 pRgn_Attr_Src1
->Rect
.right
,
377 pRgn_Attr_Src1
->Rect
.bottom
);
384 if (SetRectRgn( hDest
, 0, 0, 0, 0))
388 /* Even on error the flag is set dirty and force server side to redraw. */
389 pRgn_Attr_Dest
->AttrFlags
|= ATTR_RGN_DIRTY
;
398 CreateEllipticRgnIndirect(
402 /* Notes if prc is NULL it will crash on All Windows NT I checked 2000/XP/VISTA */
403 return NtGdiCreateEllipticRgn(prc
->left
, prc
->top
, prc
->right
, prc
->bottom
);
412 CreatePolygonRgn( const POINT
* lppt
, int cPoints
, int fnPolyFillMode
)
414 return (HRGN
) NtGdiPolyPolyDraw( (HDC
) fnPolyFillMode
, (PPOINT
) lppt
, (PULONG
) &cPoints
, 1, GdiPolyPolyRgn
);
422 CreatePolyPolygonRgn( const POINT
* lppt
,
423 const INT
* lpPolyCounts
,
427 return (HRGN
) NtGdiPolyPolyDraw( (HDC
) fnPolyFillMode
, (PPOINT
) lppt
, (PULONG
) lpPolyCounts
, (ULONG
) nCount
, GdiPolyPolyRgn
);
435 CreateRectRgn(int x1
, int y1
, int x2
, int y2
)
441 /* Normalize points */
456 if ( (UINT
)x1
< 0x80000000 ||
457 (UINT
)y1
< 0x80000000 ||
458 (UINT
)x2
> 0x7FFFFFFF ||
459 (UINT
)y2
> 0x7FFFFFFF )
461 SetLastError(ERROR_INVALID_PARAMETER
);
464 //// Remove when Brush/Pen/Rgn Attr is ready!
465 return NtGdiCreateRectRgn(x1
,y1
,x2
,y2
);
467 hrgn
= hGetPEBHandle(hctRegionHandle
, 0);
470 hrgn
= NtGdiCreateRectRgn(0, 0, 1, 1);
475 if (!GdiGetHandleUserData((HGDIOBJ
) hrgn
, GDI_OBJECT_TYPE_REGION
, (PVOID
) &pRgn_Attr
))
481 if (( x1
== x2
) || (y1
== y2
))
483 pRgn_Attr
->Flags
= NULLREGION
;
484 pRgn_Attr
->Rect
.left
= pRgn_Attr
->Rect
.top
=
485 pRgn_Attr
->Rect
.right
= pRgn_Attr
->Rect
.bottom
= 0;
489 pRgn_Attr
->Flags
= SIMPLEREGION
;
490 pRgn_Attr
->Rect
.left
= x1
;
491 pRgn_Attr
->Rect
.top
= y1
;
492 pRgn_Attr
->Rect
.right
= x2
;
493 pRgn_Attr
->Rect
.bottom
= y2
;
496 pRgn_Attr
->AttrFlags
= (ATTR_RGN_DIRTY
|ATTR_RGN_VALID
);
506 CreateRectRgnIndirect(
510 /* Notes if prc is NULL it will crash on All Windows NT I checked 2000/XP/VISTA */
511 return CreateRectRgn(prc
->left
, prc
->top
, prc
->right
, prc
->bottom
);
520 ExcludeClipRect(IN HDC hdc
, IN INT xLeft
, IN INT yTop
, IN INT xRight
, IN INT yBottom
)
523 // Handle something other than a normal dc object.
524 if (GDI_HANDLE_GET_TYPE(hdc
) != GDI_OBJECT_TYPE_DC
)
526 if (GDI_HANDLE_GET_TYPE(hdc
) == GDI_OBJECT_TYPE_METADC
)
527 return MFDRV_ExcludeClipRect( hdc
, xLeft
, yTop
, xRight
, yBottom
);
530 PLDC pLDC
= GdiGetLDC(hdc
);
533 if (pLDC
->iType
!= LDC_EMFLDC
|| EMFDRV_ExcludeClipRect( hdc
, xLeft
, yTop
, xRight
, yBottom
))
534 return NtGdiExcludeClipRect(hdc
, xLeft
, yTop
, xRight
, yBottom
);
537 SetLastError(ERROR_INVALID_HANDLE
);
542 return NtGdiExcludeClipRect(hdc
, xLeft
, yTop
, xRight
, yBottom
);
551 CONST XFORM
* lpXform
,
553 CONST RGNDATA
* lpRgnData
558 if ((!lpXform
) && (lpRgnData
->rdh
.nCount
== 1))
560 PRECT pRect
= (PRECT
)&lpRgnData
->Buffer
[0];
561 return CreateRectRgn(pRect
->left
, pRect
->top
, pRect
->right
, pRect
->bottom
);
563 return NtGdiExtCreateRegion((LPXFORM
) lpXform
, nCount
,(LPRGNDATA
) lpRgnData
);
565 SetLastError(ERROR_INVALID_PARAMETER
);
574 ExtSelectClipRgn( IN HDC hdc
, IN HRGN hrgn
, IN INT iMode
)
576 /* FIXME some part need be done on user mode size */
577 return NtGdiExtSelectClipRgn(hdc
,hrgn
, iMode
);
590 INT Ret
= NtGdiGetRandomRgn(hdc
, hrgn
, CLIPRGN
);
593 // if(GetLayout(hdc) & LAYOUT_RTL) MirrorRgnDC(hdc,(HRGN)Ret, NULL);
606 return NtGdiGetRandomRgn(hdc
, hrgn
, METARGN
);
615 GetRegionData(HRGN hrgn
,
624 return NtGdiGetRegionData(hrgn
,nCount
,lpRgnData
);
638 if (!GdiGetHandleUserData((HGDIOBJ
) hrgn
, GDI_OBJECT_TYPE_REGION
, (PVOID
) &Rgn_Attr
))
639 return NtGdiGetRgnBox(hrgn
, prcOut
);
641 if (Rgn_Attr
->Flags
== NULLREGION
)
650 if (Rgn_Attr
->Flags
!= SIMPLEREGION
)
651 return NtGdiGetRgnBox(hrgn
, prcOut
);
652 /* WARNING! prcOut is never checked newbies! */
653 RtlCopyMemory( prcOut
, &Rgn_Attr
->Rect
, sizeof(RECT
));
655 return Rgn_Attr
->Flags
;
663 IntersectClipRect(HDC hdc
,
670 // Handle something other than a normal dc object.
671 if (GDI_HANDLE_GET_TYPE(hdc
) != GDI_OBJECT_TYPE_DC
)
673 if (GDI_HANDLE_GET_TYPE(hdc
) == GDI_OBJECT_TYPE_METADC
)
674 return MFDRV_IntersectClipRect( hdc
, nLeftRect
, nTopRect
, nRightRect
, nBottomRect
);
677 PLDC pLDC
= GdiGetLDC(hdc
);
680 if (pLDC
->iType
!= LDC_EMFLDC
|| EMFDRV_IntersectClipRect( hdc
, nLeftRect
, nTopRect
, nRightRect
, nBottomRect
))
681 return NtGdiIntersectClipRect(hdc
, nLeftRect
, nTopRect
, nRightRect
, nBottomRect
);
684 SetLastError(ERROR_INVALID_HANDLE
);
689 return NtGdiIntersectClipRect(hdc
, nLeftRect
, nTopRect
, nRightRect
, nBottomRect
);
697 MirrorRgn(HWND hwnd
, HRGN hrgn
)
700 GetWindowRect(hwnd
, &Rect
);
701 return MirrorRgnByWidth(hrgn
, Rect
.right
- Rect
.left
, NULL
);
709 OffsetClipRgn(HDC hdc
,
714 // Handle something other than a normal dc object.
715 if (GDI_HANDLE_GET_TYPE(hdc
) != GDI_OBJECT_TYPE_DC
)
717 if (GDI_HANDLE_GET_TYPE(hdc
) == GDI_OBJECT_TYPE_METADC
)
718 return MFDRV_OffsetClipRgn( hdc
, nXOffset
, nYOffset
);
721 PLDC pLDC
= GdiGetLDC(hdc
);
724 SetLastError(ERROR_INVALID_HANDLE
);
727 if (pLDC
->iType
== LDC_EMFLDC
&& !EMFDRV_OffsetClipRgn( hdc
, nXOffset
, nYOffset
))
729 return NtGdiOffsetClipRgn( hdc
, nXOffset
, nYOffset
);
733 return NtGdiOffsetClipRgn( hdc
, nXOffset
, nYOffset
);
742 OffsetRgn( HRGN hrgn
,
747 int nLeftRect
, nTopRect
, nRightRect
, nBottomRect
;
749 if (!GdiGetHandleUserData((HGDIOBJ
) hrgn
, GDI_OBJECT_TYPE_REGION
, (PVOID
) &pRgn_Attr
))
750 return NtGdiOffsetRgn(hrgn
,nXOffset
,nYOffset
);
752 if ( pRgn_Attr
->Flags
== NULLREGION
)
753 return pRgn_Attr
->Flags
;
755 if ( pRgn_Attr
->Flags
!= SIMPLEREGION
)
756 return NtGdiOffsetRgn(hrgn
,nXOffset
,nYOffset
);
758 nLeftRect
= pRgn_Attr
->Rect
.left
;
759 nTopRect
= pRgn_Attr
->Rect
.top
;
760 nRightRect
= pRgn_Attr
->Rect
.right
;
761 nBottomRect
= pRgn_Attr
->Rect
.bottom
;
763 if (nLeftRect
< nRightRect
)
765 if (nTopRect
< nBottomRect
)
767 nLeftRect
= nXOffset
+ nLeftRect
;
768 nTopRect
= nYOffset
+ nTopRect
;
769 nRightRect
= nXOffset
+ nRightRect
;
770 nBottomRect
= nYOffset
+ nBottomRect
;
772 /* Mask and bit test. */
773 if ( ( nLeftRect
& 0xF8000000 &&
774 (nLeftRect
& 0xF8000000) != 0x80000000 ) ||
775 ( nTopRect
& 0xF8000000 &&
776 (nTopRect
& 0xF8000000) != 0x80000000 ) ||
777 ( nRightRect
& 0xF8000000 &&
778 (nRightRect
& 0xF8000000) != 0x80000000 ) ||
779 ( nBottomRect
& 0xF8000000 &&
780 (nBottomRect
& 0xF8000000) != 0x80000000 ) )
785 pRgn_Attr
->Rect
.top
= nTopRect
;
786 pRgn_Attr
->Rect
.left
= nLeftRect
;
787 pRgn_Attr
->Rect
.right
= nRightRect
;
788 pRgn_Attr
->Rect
.bottom
= nBottomRect
;
789 pRgn_Attr
->AttrFlags
|= ATTR_RGN_DIRTY
;
792 return pRgn_Attr
->Flags
;
800 PtInRegion(IN HRGN hrgn
,
806 if (!GdiGetHandleUserData((HGDIOBJ
) hrgn
, GDI_OBJECT_TYPE_REGION
, (PVOID
) &pRgn_Attr
))
807 return NtGdiPtInRegion(hrgn
,x
,y
);
809 if ( pRgn_Attr
->Flags
== NULLREGION
)
812 if ( pRgn_Attr
->Flags
!= SIMPLEREGION
)
813 return NtGdiPtInRegion(hrgn
,x
,y
);
815 return INRECT( pRgn_Attr
->Rect
, x
, y
);
823 RectInRegion(HRGN hrgn
,
829 if (!GdiGetHandleUserData((HGDIOBJ
) hrgn
, GDI_OBJECT_TYPE_REGION
, (PVOID
) &pRgn_Attr
))
830 return NtGdiRectInRegion(hrgn
, (LPRECT
) prcl
);
832 if ( pRgn_Attr
->Flags
== NULLREGION
)
835 if ( pRgn_Attr
->Flags
!= SIMPLEREGION
)
836 return NtGdiRectInRegion(hrgn
, (LPRECT
) prcl
);
838 /* swap the coordinates to make right >= left and bottom >= top */
839 /* (region building rectangles are normalized the same way) */
840 if ( prcl
->top
> prcl
->bottom
)
842 rc
.top
= prcl
->bottom
;
843 rc
.bottom
= prcl
->top
;
848 rc
.bottom
= prcl
->bottom
;
850 if ( prcl
->right
< prcl
->left
)
852 rc
.right
= prcl
->left
;
853 rc
.left
= prcl
->right
;
857 rc
.right
= prcl
->right
;
858 rc
.left
= prcl
->left
;
861 if ( ComplexityFromRects( &pRgn_Attr
->Rect
, &rc
) != DIFF_RGN
)
876 return ExtSelectClipRgn(hdc
, hrgn
, RGN_COPY
);
884 SetRectRgn(HRGN hrgn
,
892 if (!GdiGetHandleUserData((HGDIOBJ
) hrgn
, GDI_OBJECT_TYPE_REGION
, (PVOID
) &Rgn_Attr
))
893 return NtGdiSetRectRgn(hrgn
, nLeftRect
, nTopRect
, nRightRect
, nBottomRect
);
895 if ((nLeftRect
== nRightRect
) || (nTopRect
== nBottomRect
))
897 Rgn_Attr
->AttrFlags
|= ATTR_RGN_DIRTY
;
898 Rgn_Attr
->Flags
= NULLREGION
;
899 Rgn_Attr
->Rect
.left
= Rgn_Attr
->Rect
.top
=
900 Rgn_Attr
->Rect
.right
= Rgn_Attr
->Rect
.bottom
= 0;
904 Rgn_Attr
->Rect
.left
= nLeftRect
;
905 Rgn_Attr
->Rect
.top
= nTopRect
;
906 Rgn_Attr
->Rect
.right
= nRightRect
;
907 Rgn_Attr
->Rect
.bottom
= nBottomRect
;
909 if(nLeftRect
> nRightRect
)
911 Rgn_Attr
->Rect
.left
= nRightRect
;
912 Rgn_Attr
->Rect
.right
= nLeftRect
;
914 if(nTopRect
> nBottomRect
)
916 Rgn_Attr
->Rect
.top
= nBottomRect
;
917 Rgn_Attr
->Rect
.bottom
= nTopRect
;
920 Rgn_Attr
->AttrFlags
|= ATTR_RGN_DIRTY
;
921 Rgn_Attr
->Flags
= SIMPLEREGION
;
930 SetMetaRgn( HDC hDC
)
932 if (GDI_HANDLE_GET_TYPE(hDC
) == GDI_OBJECT_TYPE_DC
)
933 return NtGdiSetMetaRgn(hDC
);
935 PLDC pLDC
= GdiGetLDC(hDC
);
936 if ( pLDC
&& GDI_HANDLE_GET_TYPE(hDC
) != GDI_OBJECT_TYPE_METADC
)
938 if (pLDC
->iType
== LDC_EMFLDC
|| EMFDRV_SetMetaRgn(hDC
))
940 return NtGdiSetMetaRgn(hDC
);
943 SetLastError(ERROR_INVALID_HANDLE
);