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
,
207 PRGN_ATTR pRgn_Attr_Dest
= NULL
;
208 PRGN_ATTR pRgn_Attr_Src1
= NULL
;
209 PRGN_ATTR pRgn_Attr_Src2
= NULL
;
213 Ret
= GdiGetHandleUserData((HGDIOBJ
) hDest
, GDI_OBJECT_TYPE_REGION
, (PVOID
) &pRgn_Attr_Dest
);
214 Ret
= GdiGetHandleUserData((HGDIOBJ
) hSrc1
, GDI_OBJECT_TYPE_REGION
, (PVOID
) &pRgn_Attr_Src1
);
219 pRgn_Attr_Src1
->Flags
> SIMPLEREGION
)
220 return NtGdiCombineRgn(hDest
, hSrc1
, hSrc2
, CombineMode
);
222 /* Handle COPY and use only src1. */
223 if ( CombineMode
== RGN_COPY
)
225 switch (pRgn_Attr_Src1
->Flags
)
228 Ret
= SetRectRgn( hDest
, 0, 0, 0, 0);
234 Ret
= SetRectRgn( hDest
,
235 pRgn_Attr_Src1
->Rect
.left
,
236 pRgn_Attr_Src1
->Rect
.top
,
237 pRgn_Attr_Src1
->Rect
.right
,
238 pRgn_Attr_Src1
->Rect
.bottom
);
245 return NtGdiCombineRgn(hDest
, hSrc1
, hSrc2
, CombineMode
);
249 Ret
= GdiGetHandleUserData((HGDIOBJ
) hSrc2
, GDI_OBJECT_TYPE_REGION
, (PVOID
) &pRgn_Attr_Src2
);
252 pRgn_Attr_Src2
->Flags
> SIMPLEREGION
)
253 return NtGdiCombineRgn(hDest
, hSrc1
, hSrc2
, CombineMode
);
256 if ( CombineMode
!= RGN_AND
)
258 if ( CombineMode
<= RGN_AND
)
261 There might be some type of junk in the call, so go K.
262 If this becomes a problem, need to setup parameter check at the top.
264 DPRINT1("Might be junk! CombineMode %d\n",CombineMode
);
265 return NtGdiCombineRgn(hDest
, hSrc1
, hSrc2
, CombineMode
);
268 if ( CombineMode
> RGN_XOR
) /* Handle DIFF. */
270 if ( CombineMode
!= RGN_DIFF
)
271 { /* Filter check! Well, must be junk?, so go K. */
272 DPRINT1("RGN_COPY was handled! CombineMode %d\n",CombineMode
);
273 return NtGdiCombineRgn(hDest
, hSrc1
, hSrc2
, CombineMode
);
275 /* Now handle DIFF. */
276 if ( pRgn_Attr_Src1
->Flags
== NULLREGION
)
278 if (SetRectRgn( hDest
, 0, 0, 0, 0))
283 if ( pRgn_Attr_Src2
->Flags
!= NULLREGION
)
285 Complexity
= ComplexityFromRects( &pRgn_Attr_Src1
->Rect
, &pRgn_Attr_Src2
->Rect
);
287 if ( Complexity
!= DIFF_RGN
)
289 if ( Complexity
!= INVERTED_RGN
)
290 /* If same or overlapping and norm just go K. */
291 return NtGdiCombineRgn(hDest
, hSrc1
, hSrc2
, CombineMode
);
293 if (SetRectRgn( hDest
, 0, 0, 0, 0))
299 else /* Handle OR or XOR. */
301 if ( pRgn_Attr_Src1
->Flags
== NULLREGION
)
303 if ( pRgn_Attr_Src2
->Flags
!= NULLREGION
)
304 { /* Src1 null and not NULL, set from src2. */
305 Ret
= SetRectRgn( hDest
,
306 pRgn_Attr_Src2
->Rect
.left
,
307 pRgn_Attr_Src2
->Rect
.top
,
308 pRgn_Attr_Src2
->Rect
.right
,
309 pRgn_Attr_Src2
->Rect
.bottom
);
315 if (SetRectRgn( hDest
, 0, 0, 0, 0))
319 /* Src1 is not NULL. */
320 if ( pRgn_Attr_Src2
->Flags
!= NULLREGION
)
322 if ( CombineMode
!= RGN_OR
) /* Filter XOR, so go K. */
323 return NtGdiCombineRgn(hDest
, hSrc1
, hSrc2
, CombineMode
);
325 Complexity
= ComplexityFromRects( &pRgn_Attr_Src1
->Rect
, &pRgn_Attr_Src2
->Rect
);
326 /* If inverted use Src2. */
327 if ( Complexity
== INVERTED_RGN
)
329 Ret
= SetRectRgn( hDest
,
330 pRgn_Attr_Src2
->Rect
.left
,
331 pRgn_Attr_Src2
->Rect
.top
,
332 pRgn_Attr_Src2
->Rect
.right
,
333 pRgn_Attr_Src2
->Rect
.bottom
);
338 /* Not NULL or overlapping or differentiated, go to K. */
339 if ( Complexity
!= SAME_RGN
)
340 return NtGdiCombineRgn(hDest
, hSrc1
, hSrc2
, CombineMode
);
341 /* If same, just fall through. */
344 Ret
= SetRectRgn( hDest
,
345 pRgn_Attr_Src1
->Rect
.left
,
346 pRgn_Attr_Src1
->Rect
.top
,
347 pRgn_Attr_Src1
->Rect
.right
,
348 pRgn_Attr_Src1
->Rect
.bottom
);
355 if ( pRgn_Attr_Src1
->Flags
!= NULLREGION
&&
356 pRgn_Attr_Src2
->Flags
!= NULLREGION
)
358 Complexity
= ComplexityFromRects( &pRgn_Attr_Src1
->Rect
, &pRgn_Attr_Src2
->Rect
);
360 if ( Complexity
== DIFF_RGN
) /* Differentiated in anyway just NULL rgn. */
362 if (SetRectRgn( hDest
, 0, 0, 0, 0))
367 if ( Complexity
!= INVERTED_RGN
) /* Not inverted and overlapping. */
369 if ( Complexity
!= SAME_RGN
) /* Must be norm and overlapping. */
370 return NtGdiCombineRgn(hDest
, hSrc1
, hSrc2
, CombineMode
);
371 /* Merge from src2. */
372 Ret
= SetRectRgn( hDest
,
373 pRgn_Attr_Src2
->Rect
.left
,
374 pRgn_Attr_Src2
->Rect
.top
,
375 pRgn_Attr_Src2
->Rect
.right
,
376 pRgn_Attr_Src2
->Rect
.bottom
);
381 /* Inverted so merge from src1. */
382 Ret
= SetRectRgn( hDest
,
383 pRgn_Attr_Src1
->Rect
.left
,
384 pRgn_Attr_Src1
->Rect
.top
,
385 pRgn_Attr_Src1
->Rect
.right
,
386 pRgn_Attr_Src1
->Rect
.bottom
);
393 if (SetRectRgn( hDest
, 0, 0, 0, 0))
397 /* Even on error the flag is set dirty and force server side to redraw. */
398 pRgn_Attr_Dest
->AttrFlags
|= ATTR_RGN_DIRTY
;
407 CreateEllipticRgnIndirect(
411 /* Notes if prc is NULL it will crash on All Windows NT I checked 2000/XP/VISTA */
412 return NtGdiCreateEllipticRgn(prc
->left
, prc
->top
, prc
->right
, prc
->bottom
);
421 CreatePolygonRgn( const POINT
* lppt
, int cPoints
, int fnPolyFillMode
)
423 return (HRGN
) NtGdiPolyPolyDraw( (HDC
) fnPolyFillMode
, (PPOINT
) lppt
, (PULONG
) &cPoints
, 1, GdiPolyPolyRgn
);
431 CreatePolyPolygonRgn( const POINT
* lppt
,
432 const INT
* lpPolyCounts
,
436 return (HRGN
) NtGdiPolyPolyDraw( (HDC
) fnPolyFillMode
, (PPOINT
) lppt
, (PULONG
) lpPolyCounts
, (ULONG
) nCount
, GdiPolyPolyRgn
);
444 CreateRectRgn(int x1
, int y1
, int x2
, int y2
)
450 /* Normalize points */
464 /* Check outside 24 bit limit for universal set. Chp 9 Areas, pg 560.*/
465 if ( x1
< -(1<<27) ||
470 SetLastError(ERROR_INVALID_PARAMETER
);
474 hrgn
= hGetPEBHandle(hctRegionHandle
, 0);
477 hrgn
= NtGdiCreateRectRgn(0, 0, 1, 1);
482 if (!GdiGetHandleUserData((HGDIOBJ
) hrgn
, GDI_OBJECT_TYPE_REGION
, (PVOID
) &pRgn_Attr
))
484 DPRINT1("No Attr for Region handle!!!\n");
489 if (( x1
== x2
) || (y1
== y2
))
491 pRgn_Attr
->Flags
= NULLREGION
;
492 pRgn_Attr
->Rect
.left
= pRgn_Attr
->Rect
.top
=
493 pRgn_Attr
->Rect
.right
= pRgn_Attr
->Rect
.bottom
= 0;
497 pRgn_Attr
->Flags
= SIMPLEREGION
;
498 pRgn_Attr
->Rect
.left
= x1
;
499 pRgn_Attr
->Rect
.top
= y1
;
500 pRgn_Attr
->Rect
.right
= x2
;
501 pRgn_Attr
->Rect
.bottom
= y2
;
504 pRgn_Attr
->AttrFlags
= (ATTR_RGN_DIRTY
|ATTR_RGN_VALID
);
514 CreateRectRgnIndirect(
518 /* Notes if prc is NULL it will crash on All Windows NT I checked 2000/XP/VISTA */
519 return CreateRectRgn(prc
->left
, prc
->top
, prc
->right
, prc
->bottom
);
528 ExcludeClipRect(IN HDC hdc
, IN INT xLeft
, IN INT yTop
, IN INT xRight
, IN INT yBottom
)
531 // Handle something other than a normal dc object.
532 if (GDI_HANDLE_GET_TYPE(hdc
) != GDI_OBJECT_TYPE_DC
)
534 if (GDI_HANDLE_GET_TYPE(hdc
) == GDI_OBJECT_TYPE_METADC
)
535 return MFDRV_ExcludeClipRect( hdc
, xLeft
, yTop
, xRight
, yBottom
);
538 PLDC pLDC
= GdiGetLDC(hdc
);
541 if (pLDC
->iType
!= LDC_EMFLDC
|| EMFDRV_ExcludeClipRect( hdc
, xLeft
, yTop
, xRight
, yBottom
))
542 return NtGdiExcludeClipRect(hdc
, xLeft
, yTop
, xRight
, yBottom
);
545 SetLastError(ERROR_INVALID_HANDLE
);
550 return NtGdiExcludeClipRect(hdc
, xLeft
, yTop
, xRight
, yBottom
);
559 CONST XFORM
* lpXform
,
561 CONST RGNDATA
* lpRgnData
566 if ((!lpXform
) && (lpRgnData
->rdh
.nCount
== 1))
568 PRECT pRect
= (PRECT
)&lpRgnData
->Buffer
[0];
569 return CreateRectRgn(pRect
->left
, pRect
->top
, pRect
->right
, pRect
->bottom
);
571 return NtGdiExtCreateRegion((LPXFORM
) lpXform
, nCount
,(LPRGNDATA
) lpRgnData
);
573 SetLastError(ERROR_INVALID_PARAMETER
);
582 ExtSelectClipRgn( IN HDC hdc
, IN HRGN hrgn
, IN INT iMode
)
584 /* FIXME some part need be done on user mode size */
585 return NtGdiExtSelectClipRgn(hdc
,hrgn
, iMode
);
598 INT Ret
= NtGdiGetRandomRgn(hdc
, hrgn
, CLIPRGN
);
601 // if(GetLayout(hdc) & LAYOUT_RTL) MirrorRgnDC(hdc,(HRGN)Ret, NULL);
614 return NtGdiGetRandomRgn(hdc
, hrgn
, METARGN
);
623 GetRegionData(HRGN hrgn
,
632 return NtGdiGetRegionData(hrgn
,nCount
,lpRgnData
);
646 if (!GdiGetHandleUserData((HGDIOBJ
) hrgn
, GDI_OBJECT_TYPE_REGION
, (PVOID
) &Rgn_Attr
))
647 return NtGdiGetRgnBox(hrgn
, prcOut
);
649 if (Rgn_Attr
->Flags
== NULLREGION
)
658 if (Rgn_Attr
->Flags
!= SIMPLEREGION
)
659 return NtGdiGetRgnBox(hrgn
, prcOut
);
660 /* WARNING! prcOut is never checked newbies! */
661 RtlCopyMemory( prcOut
, &Rgn_Attr
->Rect
, sizeof(RECT
));
663 return Rgn_Attr
->Flags
;
671 IntersectClipRect(HDC hdc
,
678 // Handle something other than a normal dc object.
679 if (GDI_HANDLE_GET_TYPE(hdc
) != GDI_OBJECT_TYPE_DC
)
681 if (GDI_HANDLE_GET_TYPE(hdc
) == GDI_OBJECT_TYPE_METADC
)
682 return MFDRV_IntersectClipRect( hdc
, nLeftRect
, nTopRect
, nRightRect
, nBottomRect
);
685 PLDC pLDC
= GdiGetLDC(hdc
);
688 if (pLDC
->iType
!= LDC_EMFLDC
|| EMFDRV_IntersectClipRect( hdc
, nLeftRect
, nTopRect
, nRightRect
, nBottomRect
))
689 return NtGdiIntersectClipRect(hdc
, nLeftRect
, nTopRect
, nRightRect
, nBottomRect
);
692 SetLastError(ERROR_INVALID_HANDLE
);
697 return NtGdiIntersectClipRect(hdc
, nLeftRect
, nTopRect
, nRightRect
, nBottomRect
);
705 MirrorRgn(HWND hwnd
, HRGN hrgn
)
708 GetWindowRect(hwnd
, &Rect
);
709 return MirrorRgnByWidth(hrgn
, Rect
.right
- Rect
.left
, NULL
);
717 OffsetClipRgn(HDC hdc
,
722 // Handle something other than a normal dc object.
723 if (GDI_HANDLE_GET_TYPE(hdc
) != GDI_OBJECT_TYPE_DC
)
725 if (GDI_HANDLE_GET_TYPE(hdc
) == GDI_OBJECT_TYPE_METADC
)
726 return MFDRV_OffsetClipRgn( hdc
, nXOffset
, nYOffset
);
729 PLDC pLDC
= GdiGetLDC(hdc
);
732 SetLastError(ERROR_INVALID_HANDLE
);
735 if (pLDC
->iType
== LDC_EMFLDC
&& !EMFDRV_OffsetClipRgn( hdc
, nXOffset
, nYOffset
))
737 return NtGdiOffsetClipRgn( hdc
, nXOffset
, nYOffset
);
741 return NtGdiOffsetClipRgn( hdc
, nXOffset
, nYOffset
);
750 OffsetRgn( HRGN hrgn
,
755 int nLeftRect
, nTopRect
, nRightRect
, nBottomRect
;
757 if (!GdiGetHandleUserData((HGDIOBJ
) hrgn
, GDI_OBJECT_TYPE_REGION
, (PVOID
) &pRgn_Attr
))
758 return NtGdiOffsetRgn(hrgn
,nXOffset
,nYOffset
);
760 if ( pRgn_Attr
->Flags
== NULLREGION
)
761 return pRgn_Attr
->Flags
;
763 if ( pRgn_Attr
->Flags
!= SIMPLEREGION
)
764 return NtGdiOffsetRgn(hrgn
,nXOffset
,nYOffset
);
766 nLeftRect
= pRgn_Attr
->Rect
.left
;
767 nTopRect
= pRgn_Attr
->Rect
.top
;
768 nRightRect
= pRgn_Attr
->Rect
.right
;
769 nBottomRect
= pRgn_Attr
->Rect
.bottom
;
771 if (nLeftRect
< nRightRect
)
773 if (nTopRect
< nBottomRect
)
775 nLeftRect
= nXOffset
+ nLeftRect
;
776 nTopRect
= nYOffset
+ nTopRect
;
777 nRightRect
= nXOffset
+ nRightRect
;
778 nBottomRect
= nYOffset
+ nBottomRect
;
780 /* Check 28 bit limit. Chp 9 Areas, pg 560. */
781 if ( nLeftRect
< -(1<<27) ||
782 nTopRect
< -(1<<27) ||
783 nRightRect
> (1<<27)-1 ||
784 nBottomRect
> (1<<27)-1 )
789 pRgn_Attr
->Rect
.top
= nTopRect
;
790 pRgn_Attr
->Rect
.left
= nLeftRect
;
791 pRgn_Attr
->Rect
.right
= nRightRect
;
792 pRgn_Attr
->Rect
.bottom
= nBottomRect
;
793 pRgn_Attr
->AttrFlags
|= ATTR_RGN_DIRTY
;
796 return pRgn_Attr
->Flags
;
804 PtInRegion(IN HRGN hrgn
,
810 if (!GdiGetHandleUserData((HGDIOBJ
) hrgn
, GDI_OBJECT_TYPE_REGION
, (PVOID
) &pRgn_Attr
))
811 return NtGdiPtInRegion(hrgn
,x
,y
);
813 if ( pRgn_Attr
->Flags
== NULLREGION
)
816 if ( pRgn_Attr
->Flags
!= SIMPLEREGION
)
817 return NtGdiPtInRegion(hrgn
,x
,y
);
819 return INRECT( pRgn_Attr
->Rect
, x
, y
);
827 RectInRegion(HRGN hrgn
,
833 if (!GdiGetHandleUserData((HGDIOBJ
) hrgn
, GDI_OBJECT_TYPE_REGION
, (PVOID
) &pRgn_Attr
))
834 return NtGdiRectInRegion(hrgn
, (LPRECT
) prcl
);
836 if ( pRgn_Attr
->Flags
== NULLREGION
)
839 if ( pRgn_Attr
->Flags
!= SIMPLEREGION
)
840 return NtGdiRectInRegion(hrgn
, (LPRECT
) prcl
);
842 /* swap the coordinates to make right >= left and bottom >= top */
843 /* (region building rectangles are normalized the same way) */
844 if ( prcl
->top
> prcl
->bottom
)
846 rc
.top
= prcl
->bottom
;
847 rc
.bottom
= prcl
->top
;
852 rc
.bottom
= prcl
->bottom
;
854 if ( prcl
->right
< prcl
->left
)
856 rc
.right
= prcl
->left
;
857 rc
.left
= prcl
->right
;
861 rc
.right
= prcl
->right
;
862 rc
.left
= prcl
->left
;
865 if ( ComplexityFromRects( &pRgn_Attr
->Rect
, &rc
) != DIFF_RGN
)
880 return ExtSelectClipRgn(hdc
, hrgn
, RGN_COPY
);
888 SetRectRgn(HRGN hrgn
,
896 if (!GdiGetHandleUserData((HGDIOBJ
) hrgn
, GDI_OBJECT_TYPE_REGION
, (PVOID
) &Rgn_Attr
))
897 return NtGdiSetRectRgn(hrgn
, nLeftRect
, nTopRect
, nRightRect
, nBottomRect
);
899 if ((nLeftRect
== nRightRect
) || (nTopRect
== nBottomRect
))
901 Rgn_Attr
->AttrFlags
|= ATTR_RGN_DIRTY
;
902 Rgn_Attr
->Flags
= NULLREGION
;
903 Rgn_Attr
->Rect
.left
= Rgn_Attr
->Rect
.top
=
904 Rgn_Attr
->Rect
.right
= Rgn_Attr
->Rect
.bottom
= 0;
908 Rgn_Attr
->Rect
.left
= nLeftRect
;
909 Rgn_Attr
->Rect
.top
= nTopRect
;
910 Rgn_Attr
->Rect
.right
= nRightRect
;
911 Rgn_Attr
->Rect
.bottom
= nBottomRect
;
913 if(nLeftRect
> nRightRect
)
915 Rgn_Attr
->Rect
.left
= nRightRect
;
916 Rgn_Attr
->Rect
.right
= nLeftRect
;
918 if(nTopRect
> nBottomRect
)
920 Rgn_Attr
->Rect
.top
= nBottomRect
;
921 Rgn_Attr
->Rect
.bottom
= nTopRect
;
924 Rgn_Attr
->AttrFlags
|= ATTR_RGN_DIRTY
;
925 Rgn_Attr
->Flags
= SIMPLEREGION
;
934 SetMetaRgn( HDC hDC
)
936 if (GDI_HANDLE_GET_TYPE(hDC
) == GDI_OBJECT_TYPE_DC
)
937 return NtGdiSetMetaRgn(hDC
);
939 PLDC pLDC
= GdiGetLDC(hDC
);
940 if ( pLDC
&& GDI_HANDLE_GET_TYPE(hDC
) != GDI_OBJECT_TYPE_METADC
)
942 if (pLDC
->iType
== LDC_EMFLDC
|| EMFDRV_SetMetaRgn(hDC
))
944 return NtGdiSetMetaRgn(hDC
);
947 SetLastError(ERROR_INVALID_HANDLE
);