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,
27 ComplexityFromRects( PRECTL prc1
, PRECTL prc2
)
29 if ( prc2
->left
>= prc1
->left
)
31 if ( ( prc1
->right
>= prc2
->right
) &&
32 ( prc1
->top
<= prc2
->top
) &&
33 ( prc1
->bottom
>= prc2
->bottom
) )
36 if ( prc2
->left
> prc1
->left
)
38 if ( ( prc1
->left
>= prc2
->right
) ||
39 ( prc1
->right
<= prc2
->left
) ||
40 ( prc1
->top
>= prc2
->bottom
) ||
41 ( prc1
->bottom
<= prc2
->top
) )
46 if ( ( prc2
->right
< prc1
->right
) ||
47 ( prc2
->top
> prc1
->top
) ||
48 ( prc2
->bottom
< prc1
->bottom
) )
50 if ( ( prc1
->left
>= prc2
->right
) ||
51 ( prc1
->right
<= prc2
->left
) ||
52 ( prc1
->top
>= prc2
->bottom
) ||
53 ( prc1
->bottom
<= prc2
->top
) )
60 return OVERLAPPING_RGN
;
66 SortRects(PRECT pRect
, INT nCount
)
68 INT i
= 0, a
= 0, b
= 0, c
, s
;
73 i
= 1; // set index point
74 c
= nCount
; // set inverse count
77 s
= i
; // set sort count
84 if(pRect
[b
].top
!= pRect
[i
].bottom
) break;
85 if(pRect
[b
].left
< pRect
[a
].left
)
93 } while ( s
< nCount
);
101 * I thought it was okay to have this in DeleteObject but~ Speed. (jt)
105 DeleteRegion( HRGN hRgn
)
110 if ((GdiGetHandleUserData((HGDIOBJ
) hRgn
, GDI_OBJECT_TYPE_REGION
, (PVOID
) &Rgn_Attr
)) &&
111 ( Rgn_Attr
!= NULL
))
113 PTEB pTeb
= NtCurrentTeb();
114 if (pTeb
->Win32ThreadInfo
!= NULL
)
116 if ((pTeb
->GdiTebBatch
.Offset
+ sizeof(GDIBSOBJECT
)) <= GDIBATCHBUFSIZE
)
118 PGDIBSOBJECT pgO
= (PGDIBSOBJECT
)(&pTeb
->GdiTebBatch
.Buffer
[0] +
119 pTeb
->GdiTebBatch
.Offset
);
120 pgO
->gbHdr
.Cmd
= GdiBCDelRgn
;
121 pgO
->gbHdr
.Size
= sizeof(GDIBSOBJECT
);
122 pgO
->hgdiobj
= (HGDIOBJ
)hRgn
;
124 pTeb
->GdiTebBatch
.Offset
+= sizeof(GDIBSOBJECT
);
125 pTeb
->GdiBatchCount
++;
126 if (pTeb
->GdiBatchCount
>= GDI_BatchLimit
) NtGdiFlush();
132 return NtGdiDeleteObjectApp((HGDIOBJ
) hRgn
);
137 MirrorRgnByWidth(HRGN hRgn
, INT Width
, HRGN
*phRgn
)
139 INT cRgnDSize
, Ret
= 0;
142 cRgnDSize
= NtGdiGetRegionData(hRgn
, 0, NULL
);
146 pRgnData
= LocalAlloc(LMEM_FIXED
, cRgnDSize
* sizeof(LONG
));
149 if ( GetRegionData(hRgn
, cRgnDSize
, pRgnData
) )
153 INT SaveL
= pRgnData
->rdh
.rcBound
.left
;
154 pRgnData
->rdh
.rcBound
.left
= Width
- pRgnData
->rdh
.rcBound
.right
;
155 pRgnData
->rdh
.rcBound
.right
= Width
- SaveL
;
156 if (pRgnData
->rdh
.nCount
> 0)
158 PRECT pRect
= (PRECT
)&pRgnData
->Buffer
;
159 for (i
= 0; i
< pRgnData
->rdh
.nCount
; i
++)
161 SaveL
= pRect
[i
].left
;
162 pRect
[i
].left
= Width
- pRect
[i
].right
;
163 pRect
[i
].right
= Width
- SaveL
;
166 SortRects((PRECT
)&pRgnData
->Buffer
, pRgnData
->rdh
.nCount
);
167 hRgnex
= ExtCreateRegion(NULL
, cRgnDSize
, pRgnData
);
170 if (phRgn
) phRgn
= (HRGN
*)hRgnex
;
173 CombineRgn(hRgn
, hRgnex
, 0, RGN_COPY
);
174 DeleteObject(hRgnex
);
187 MirrorRgnDC(HDC hdc
, HRGN hRgn
, HRGN
*phRgn
)
189 if (!GdiIsHandleValid((HGDIOBJ
) hdc
) ||
190 (GDI_HANDLE_GET_TYPE(hdc
) != GDI_OBJECT_TYPE_DC
)) return 0;
192 return MirrorRgnByWidth(hRgn
, NtGdiGetDeviceWidth(hdc
), phRgn
);
195 /* FUNCTIONS *****************************************************************/
202 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
)
222 return NtGdiCombineRgn(hDest
, hSrc1
, hSrc2
, CombineMode
);
224 /* Handle COPY and use only src1. */
225 if ( CombineMode
== RGN_COPY
)
227 switch (pRgn_Attr_Src1
->Flags
)
230 Ret
= SetRectRgn( hDest
, 0, 0, 0, 0);
236 Ret
= SetRectRgn( hDest
,
237 pRgn_Attr_Src1
->Rect
.left
,
238 pRgn_Attr_Src1
->Rect
.top
,
239 pRgn_Attr_Src1
->Rect
.right
,
240 pRgn_Attr_Src1
->Rect
.bottom
);
247 return NtGdiCombineRgn(hDest
, hSrc1
, hSrc2
, CombineMode
);
251 Ret
= GdiGetHandleUserData((HGDIOBJ
) hSrc2
, GDI_OBJECT_TYPE_REGION
, (PVOID
) &pRgn_Attr_Src2
);
254 pRgn_Attr_Src2
->Flags
> SIMPLEREGION
)
255 return NtGdiCombineRgn(hDest
, hSrc1
, hSrc2
, CombineMode
);
258 if ( CombineMode
!= RGN_AND
)
260 if ( CombineMode
<= RGN_AND
)
263 There might be some type of junk in the call, so go K.
264 If this becomes a problem, need to setup parameter check at the top.
266 DPRINT1("Might be junk! CombineMode %d\n",CombineMode
);
267 return NtGdiCombineRgn(hDest
, hSrc1
, hSrc2
, CombineMode
);
270 if ( CombineMode
> RGN_XOR
) /* Handle DIFF. */
272 if ( CombineMode
!= RGN_DIFF
)
273 { /* Filter check! Well, must be junk?, so go K. */
274 DPRINT1("RGN_COPY was handled! CombineMode %d\n",CombineMode
);
275 return NtGdiCombineRgn(hDest
, hSrc1
, hSrc2
, CombineMode
);
278 if ( pRgn_Attr_Src1
->Flags
!= NULLREGION
&&
279 pRgn_Attr_Src2
->Flags
!= NULLREGION
)
281 Complexity
= ComplexityFromRects( &pRgn_Attr_Src1
->Rect
, &pRgn_Attr_Src2
->Rect
);
282 /* If same or overlapping and norm just go K. */
283 if (Complexity
== SAME_RGN
|| Complexity
== OVERLAPPING_RGN
)
284 return NtGdiCombineRgn(hDest
, hSrc1
, hSrc2
, CombineMode
);
287 if (SetRectRgn( hDest
, 0, 0, 0, 0))
291 else /* Handle OR or XOR. */
293 if ( pRgn_Attr_Src1
->Flags
== NULLREGION
)
295 if ( pRgn_Attr_Src2
->Flags
!= NULLREGION
)
296 { /* Src1 null and not NULL, set from src2. */
297 Ret
= SetRectRgn( hDest
,
298 pRgn_Attr_Src2
->Rect
.left
,
299 pRgn_Attr_Src2
->Rect
.top
,
300 pRgn_Attr_Src2
->Rect
.right
,
301 pRgn_Attr_Src2
->Rect
.bottom
);
307 if (SetRectRgn( hDest
, 0, 0, 0, 0))
311 /* Src1 is not NULL. */
312 if ( pRgn_Attr_Src2
->Flags
!= NULLREGION
)
314 if ( CombineMode
!= RGN_OR
) /* Filter XOR, so go K. */
315 return NtGdiCombineRgn(hDest
, hSrc1
, hSrc2
, CombineMode
);
317 Complexity
= ComplexityFromRects( &pRgn_Attr_Src1
->Rect
, &pRgn_Attr_Src2
->Rect
);
318 /* If inverted use Src2. */
319 if ( Complexity
== INVERTED_RGN
)
321 Ret
= SetRectRgn( hDest
,
322 pRgn_Attr_Src2
->Rect
.left
,
323 pRgn_Attr_Src2
->Rect
.top
,
324 pRgn_Attr_Src2
->Rect
.right
,
325 pRgn_Attr_Src2
->Rect
.bottom
);
330 /* Not NULL or overlapping or differentiated, go to K. */
331 if ( Complexity
!= SAME_RGN
)
332 return NtGdiCombineRgn(hDest
, hSrc1
, hSrc2
, CombineMode
);
333 /* If same, just fall through. */
336 Ret
= SetRectRgn( hDest
,
337 pRgn_Attr_Src1
->Rect
.left
,
338 pRgn_Attr_Src1
->Rect
.top
,
339 pRgn_Attr_Src1
->Rect
.right
,
340 pRgn_Attr_Src1
->Rect
.bottom
);
347 if ( pRgn_Attr_Src1
->Flags
!= NULLREGION
&&
348 pRgn_Attr_Src2
->Flags
!= NULLREGION
)
350 Complexity
= ComplexityFromRects( &pRgn_Attr_Src1
->Rect
, &pRgn_Attr_Src2
->Rect
);
352 if ( Complexity
== DIFF_RGN
) /* Differentiated in anyway just NULL rgn. */
354 if (SetRectRgn( hDest
, 0, 0, 0, 0))
359 if ( Complexity
!= INVERTED_RGN
) /* Not inverted and overlapping. */
361 if ( Complexity
!= SAME_RGN
) /* Must be norm and overlapping. */
362 return NtGdiCombineRgn(hDest
, hSrc1
, hSrc2
, CombineMode
);
363 /* Merge from src2. */
364 Ret
= SetRectRgn( hDest
,
365 pRgn_Attr_Src2
->Rect
.left
,
366 pRgn_Attr_Src2
->Rect
.top
,
367 pRgn_Attr_Src2
->Rect
.right
,
368 pRgn_Attr_Src2
->Rect
.bottom
);
373 /* Inverted so merge from src1. */
374 Ret
= SetRectRgn( hDest
,
375 pRgn_Attr_Src1
->Rect
.left
,
376 pRgn_Attr_Src1
->Rect
.top
,
377 pRgn_Attr_Src1
->Rect
.right
,
378 pRgn_Attr_Src1
->Rect
.bottom
);
385 if (SetRectRgn( hDest
, 0, 0, 0, 0))
389 /* Even on error the flag is set dirty and force server side to redraw. */
390 pRgn_Attr_Dest
->AttrFlags
|= ATTR_RGN_DIRTY
;
400 CreateEllipticRgnIndirect(
404 /* Notes if prc is NULL it will crash on All Windows NT I checked 2000/XP/VISTA */
405 return NtGdiCreateEllipticRgn(prc
->left
, prc
->top
, prc
->right
, prc
->bottom
);
414 CreatePolygonRgn( const POINT
* lppt
, int cPoints
, int fnPolyFillMode
)
416 return (HRGN
) NtGdiPolyPolyDraw(ULongToHandle(fnPolyFillMode
), (PPOINT
) lppt
, (PULONG
) &cPoints
, 1, GdiPolyPolyRgn
);
424 CreatePolyPolygonRgn( const POINT
* lppt
,
425 const INT
* lpPolyCounts
,
429 return (HRGN
) NtGdiPolyPolyDraw( (HDC
) fnPolyFillMode
, (PPOINT
) lppt
, (PULONG
) lpPolyCounts
, (ULONG
) nCount
, GdiPolyPolyRgn
);
437 CreateRectRgn(int x1
, int y1
, int x2
, int y2
)
443 /* Normalize points */
457 /* Check outside 24 bit limit for universal set. Chp 9 Areas, pg 560.*/
458 if ( x1
< -(1<<27) ||
463 SetLastError(ERROR_INVALID_PARAMETER
);
467 hrgn
= hGetPEBHandle(hctRegionHandle
, 0);
470 hrgn
= NtGdiCreateRectRgn(0, 0, 1, 1);
475 if (!GdiGetHandleUserData((HGDIOBJ
) hrgn
, GDI_OBJECT_TYPE_REGION
, (PVOID
) &pRgn_Attr
))
477 DPRINT1("No Attr for Region handle!!!\n");
482 if (( x1
== x2
) || (y1
== y2
))
484 pRgn_Attr
->Flags
= NULLREGION
;
485 pRgn_Attr
->Rect
.left
= pRgn_Attr
->Rect
.top
=
486 pRgn_Attr
->Rect
.right
= pRgn_Attr
->Rect
.bottom
= 0;
490 pRgn_Attr
->Flags
= SIMPLEREGION
;
491 pRgn_Attr
->Rect
.left
= x1
;
492 pRgn_Attr
->Rect
.top
= y1
;
493 pRgn_Attr
->Rect
.right
= x2
;
494 pRgn_Attr
->Rect
.bottom
= y2
;
497 pRgn_Attr
->AttrFlags
= (ATTR_RGN_DIRTY
|ATTR_RGN_VALID
);
507 CreateRectRgnIndirect(
511 /* Notes if prc is NULL it will crash on All Windows NT I checked 2000/XP/VISTA */
512 return CreateRectRgn(prc
->left
, prc
->top
, prc
->right
, prc
->bottom
);
521 ExcludeClipRect(IN HDC hdc
, IN INT xLeft
, IN INT yTop
, IN INT xRight
, IN INT yBottom
)
524 // Handle something other than a normal dc object.
525 if (GDI_HANDLE_GET_TYPE(hdc
) != GDI_OBJECT_TYPE_DC
)
527 if (GDI_HANDLE_GET_TYPE(hdc
) == GDI_OBJECT_TYPE_METADC
)
528 return MFDRV_ExcludeClipRect( hdc
, xLeft
, yTop
, xRight
, yBottom
);
531 PLDC pLDC
= GdiGetLDC(hdc
);
534 if (pLDC
->iType
!= LDC_EMFLDC
|| EMFDRV_ExcludeClipRect( hdc
, xLeft
, yTop
, xRight
, yBottom
))
535 return NtGdiExcludeClipRect(hdc
, xLeft
, yTop
, xRight
, yBottom
);
538 SetLastError(ERROR_INVALID_HANDLE
);
543 return NtGdiExcludeClipRect(hdc
, xLeft
, yTop
, xRight
, yBottom
);
552 CONST XFORM
* lpXform
,
554 CONST RGNDATA
* lpRgnData
559 if ((!lpXform
) && (lpRgnData
->rdh
.nCount
== 1))
561 PRECT pRect
= (PRECT
)&lpRgnData
->Buffer
[0];
562 return CreateRectRgn(pRect
->left
, pRect
->top
, pRect
->right
, pRect
->bottom
);
564 return NtGdiExtCreateRegion((LPXFORM
) lpXform
, nCount
,(LPRGNDATA
) lpRgnData
);
566 SetLastError(ERROR_INVALID_PARAMETER
);
575 ExtSelectClipRgn( IN HDC hdc
, IN HRGN hrgn
, IN INT iMode
)
577 /* FIXME some part need be done on user mode size */
578 return NtGdiExtSelectClipRgn(hdc
,hrgn
, iMode
);
591 INT Ret
= NtGdiGetRandomRgn(hdc
, hrgn
, CLIPRGN
);
594 // if(GetLayout(hdc) & LAYOUT_RTL) MirrorRgnDC(hdc,(HRGN)Ret, NULL);
607 return NtGdiGetRandomRgn(hdc
, hrgn
, METARGN
);
616 GetRegionData(HRGN hrgn
,
625 return NtGdiGetRegionData(hrgn
,nCount
,lpRgnData
);
640 if (!GdiGetHandleUserData((HGDIOBJ
) hrgn
, GDI_OBJECT_TYPE_REGION
, (PVOID
) &Rgn_Attr
))
642 return NtGdiGetRgnBox(hrgn
, prcOut
);
644 if (Rgn_Attr
->Flags
== NULLREGION
)
653 if (Rgn_Attr
->Flags
!= SIMPLEREGION
)
654 return NtGdiGetRgnBox(hrgn
, prcOut
);
655 /* WARNING! prcOut is never checked newbies! */
656 RtlCopyMemory( prcOut
, &Rgn_Attr
->Rect
, sizeof(RECT
));
658 return Rgn_Attr
->Flags
;
667 IntersectClipRect(HDC hdc
,
674 // Handle something other than a normal dc object.
675 if (GDI_HANDLE_GET_TYPE(hdc
) != GDI_OBJECT_TYPE_DC
)
677 if (GDI_HANDLE_GET_TYPE(hdc
) == GDI_OBJECT_TYPE_METADC
)
678 return MFDRV_IntersectClipRect( hdc
, nLeftRect
, nTopRect
, nRightRect
, nBottomRect
);
681 PLDC pLDC
= GdiGetLDC(hdc
);
684 if (pLDC
->iType
!= LDC_EMFLDC
|| EMFDRV_IntersectClipRect( hdc
, nLeftRect
, nTopRect
, nRightRect
, nBottomRect
))
685 return NtGdiIntersectClipRect(hdc
, nLeftRect
, nTopRect
, nRightRect
, nBottomRect
);
688 SetLastError(ERROR_INVALID_HANDLE
);
693 return NtGdiIntersectClipRect(hdc
, nLeftRect
, nTopRect
, nRightRect
, nBottomRect
);
701 MirrorRgn(HWND hwnd
, HRGN hrgn
)
704 GetWindowRect(hwnd
, &Rect
);
705 return MirrorRgnByWidth(hrgn
, Rect
.right
- Rect
.left
, NULL
);
713 OffsetClipRgn(HDC hdc
,
718 // Handle something other than a normal dc object.
719 if (GDI_HANDLE_GET_TYPE(hdc
) != GDI_OBJECT_TYPE_DC
)
721 if (GDI_HANDLE_GET_TYPE(hdc
) == GDI_OBJECT_TYPE_METADC
)
722 return MFDRV_OffsetClipRgn( hdc
, nXOffset
, nYOffset
);
725 PLDC pLDC
= GdiGetLDC(hdc
);
728 SetLastError(ERROR_INVALID_HANDLE
);
731 if (pLDC
->iType
== LDC_EMFLDC
&& !EMFDRV_OffsetClipRgn( hdc
, nXOffset
, nYOffset
))
733 return NtGdiOffsetClipRgn( hdc
, nXOffset
, nYOffset
);
737 return NtGdiOffsetClipRgn( hdc
, nXOffset
, nYOffset
);
746 OffsetRgn( HRGN hrgn
,
752 int nLeftRect
, nTopRect
, nRightRect
, nBottomRect
;
754 if (!GdiGetHandleUserData((HGDIOBJ
) hrgn
, GDI_OBJECT_TYPE_REGION
, (PVOID
) &pRgn_Attr
))
756 return NtGdiOffsetRgn(hrgn
,nXOffset
,nYOffset
);
758 if ( pRgn_Attr
->Flags
== NULLREGION
)
759 return pRgn_Attr
->Flags
;
761 if ( pRgn_Attr
->Flags
!= SIMPLEREGION
)
762 return NtGdiOffsetRgn(hrgn
,nXOffset
,nYOffset
);
764 nLeftRect
= pRgn_Attr
->Rect
.left
;
765 nTopRect
= pRgn_Attr
->Rect
.top
;
766 nRightRect
= pRgn_Attr
->Rect
.right
;
767 nBottomRect
= pRgn_Attr
->Rect
.bottom
;
769 if (nLeftRect
< nRightRect
)
771 if (nTopRect
< nBottomRect
)
773 nLeftRect
= nXOffset
+ nLeftRect
;
774 nTopRect
= nYOffset
+ nTopRect
;
775 nRightRect
= nXOffset
+ nRightRect
;
776 nBottomRect
= nYOffset
+ nBottomRect
;
778 /* Check 28 bit limit. Chp 9 Areas, pg 560. */
779 if ( nLeftRect
< -(1<<27) ||
780 nTopRect
< -(1<<27) ||
781 nRightRect
> (1<<27)-1 ||
782 nBottomRect
> (1<<27)-1 )
787 pRgn_Attr
->Rect
.top
= nTopRect
;
788 pRgn_Attr
->Rect
.left
= nLeftRect
;
789 pRgn_Attr
->Rect
.right
= nRightRect
;
790 pRgn_Attr
->Rect
.bottom
= nBottomRect
;
791 pRgn_Attr
->AttrFlags
|= ATTR_RGN_DIRTY
;
794 return pRgn_Attr
->Flags
;
803 PtInRegion(IN HRGN hrgn
,
810 if (!GdiGetHandleUserData((HGDIOBJ
) hrgn
, GDI_OBJECT_TYPE_REGION
, (PVOID
) &pRgn_Attr
))
812 return NtGdiPtInRegion(hrgn
,x
,y
);
814 if ( pRgn_Attr
->Flags
== NULLREGION
)
817 if ( pRgn_Attr
->Flags
!= SIMPLEREGION
)
818 return NtGdiPtInRegion(hrgn
,x
,y
);
820 return INRECT( pRgn_Attr
->Rect
, x
, y
);
829 RectInRegion(HRGN hrgn
,
836 if (!GdiGetHandleUserData((HGDIOBJ
) hrgn
, GDI_OBJECT_TYPE_REGION
, (PVOID
) &pRgn_Attr
))
838 return NtGdiRectInRegion(hrgn
, (LPRECT
) prcl
);
840 if ( pRgn_Attr
->Flags
== NULLREGION
)
843 if ( pRgn_Attr
->Flags
!= SIMPLEREGION
)
844 return NtGdiRectInRegion(hrgn
, (LPRECT
) prcl
);
846 /* swap the coordinates to make right >= left and bottom >= top */
847 /* (region building rectangles are normalized the same way) */
848 if ( prcl
->top
> prcl
->bottom
)
850 rc
.top
= prcl
->bottom
;
851 rc
.bottom
= prcl
->top
;
856 rc
.bottom
= prcl
->bottom
;
858 if ( prcl
->right
< prcl
->left
)
860 rc
.right
= prcl
->left
;
861 rc
.left
= prcl
->right
;
865 rc
.right
= prcl
->right
;
866 rc
.left
= prcl
->left
;
869 if ( ComplexityFromRects( &pRgn_Attr
->Rect
, &rc
) != DIFF_RGN
)
885 return ExtSelectClipRgn(hdc
, hrgn
, RGN_COPY
);
893 SetRectRgn(HRGN hrgn
,
902 if (!GdiGetHandleUserData((HGDIOBJ
) hrgn
, GDI_OBJECT_TYPE_REGION
, (PVOID
) &Rgn_Attr
))
904 return NtGdiSetRectRgn(hrgn
, nLeftRect
, nTopRect
, nRightRect
, nBottomRect
);
906 if ((nLeftRect
== nRightRect
) || (nTopRect
== nBottomRect
))
908 Rgn_Attr
->AttrFlags
|= ATTR_RGN_DIRTY
;
909 Rgn_Attr
->Flags
= NULLREGION
;
910 Rgn_Attr
->Rect
.left
= Rgn_Attr
->Rect
.top
=
911 Rgn_Attr
->Rect
.right
= Rgn_Attr
->Rect
.bottom
= 0;
915 Rgn_Attr
->Rect
.left
= nLeftRect
;
916 Rgn_Attr
->Rect
.top
= nTopRect
;
917 Rgn_Attr
->Rect
.right
= nRightRect
;
918 Rgn_Attr
->Rect
.bottom
= nBottomRect
;
920 if(nLeftRect
> nRightRect
)
922 Rgn_Attr
->Rect
.left
= nRightRect
;
923 Rgn_Attr
->Rect
.right
= nLeftRect
;
925 if(nTopRect
> nBottomRect
)
927 Rgn_Attr
->Rect
.top
= nBottomRect
;
928 Rgn_Attr
->Rect
.bottom
= nTopRect
;
931 Rgn_Attr
->AttrFlags
|= ATTR_RGN_DIRTY
;
932 Rgn_Attr
->Flags
= SIMPLEREGION
;
942 SetMetaRgn( HDC hDC
)
944 if (GDI_HANDLE_GET_TYPE(hDC
) == GDI_OBJECT_TYPE_DC
)
945 return NtGdiSetMetaRgn(hDC
);
947 PLDC pLDC
= GdiGetLDC(hDC
);
948 if ( pLDC
&& GDI_HANDLE_GET_TYPE(hDC
) != GDI_OBJECT_TYPE_METADC
)
950 if (pLDC
->iType
== LDC_EMFLDC
|| EMFDRV_SetMetaRgn(hDC
))
952 return NtGdiSetMetaRgn(hDC
);
955 SetLastError(ERROR_INVALID_HANDLE
);