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
)
109 if ((GdiGetHandleUserData((HGDIOBJ
) hRgn
, GDI_OBJECT_TYPE_REGION
, (PVOID
) &Rgn_Attr
)) &&
110 ( Rgn_Attr
!= NULL
))
112 PTEB pTeb
= NtCurrentTeb();
113 if (pTeb
->Win32ThreadInfo
!= NULL
)
115 if ((pTeb
->GdiTebBatch
.Offset
+ sizeof(GDIBSOBJECT
)) <= GDIBATCHBUFSIZE
)
117 PGDIBSOBJECT pgO
= (PGDIBSOBJECT
)(&pTeb
->GdiTebBatch
.Buffer
[0] +
118 pTeb
->GdiTebBatch
.Offset
);
119 pgO
->gbHdr
.Cmd
= GdiBCDelRgn
;
120 pgO
->gbHdr
.Size
= sizeof(GDIBSOBJECT
);
121 pgO
->hgdiobj
= (HGDIOBJ
)hRgn
;
123 pTeb
->GdiTebBatch
.Offset
+= sizeof(GDIBSOBJECT
);
124 pTeb
->GdiBatchCount
++;
125 if (pTeb
->GdiBatchCount
>= GDI_BatchLimit
) NtGdiFlush();
130 return NtGdiDeleteObjectApp((HGDIOBJ
) hRgn
);
135 MirrorRgnByWidth(HRGN hRgn
, INT Width
, HRGN
*phRgn
)
137 INT cRgnDSize
, Ret
= 0;
140 cRgnDSize
= NtGdiGetRegionData(hRgn
, 0, NULL
);
144 pRgnData
= LocalAlloc(LMEM_FIXED
, cRgnDSize
* sizeof(LONG
));
147 if ( GetRegionData(hRgn
, cRgnDSize
, pRgnData
) )
151 INT SaveL
= pRgnData
->rdh
.rcBound
.left
;
152 pRgnData
->rdh
.rcBound
.left
= Width
- pRgnData
->rdh
.rcBound
.right
;
153 pRgnData
->rdh
.rcBound
.right
= Width
- SaveL
;
154 if (pRgnData
->rdh
.nCount
> 0)
156 PRECT pRect
= (PRECT
)&pRgnData
->Buffer
;
157 for (i
= 0; i
< pRgnData
->rdh
.nCount
; i
++)
159 SaveL
= pRect
[i
].left
;
160 pRect
[i
].left
= Width
- pRect
[i
].right
;
161 pRect
[i
].right
= Width
- SaveL
;
164 SortRects((PRECT
)&pRgnData
->Buffer
, pRgnData
->rdh
.nCount
);
165 hRgnex
= ExtCreateRegion(NULL
, cRgnDSize
, pRgnData
);
168 if (phRgn
) phRgn
= (HRGN
*)hRgnex
;
171 CombineRgn(hRgn
, hRgnex
, 0, RGN_COPY
);
172 DeleteObject(hRgnex
);
185 MirrorRgnDC(HDC hdc
, HRGN hRgn
, HRGN
*phRgn
)
187 if (!GdiIsHandleValid((HGDIOBJ
) hdc
) ||
188 (GDI_HANDLE_GET_TYPE(hdc
) != GDI_OBJECT_TYPE_DC
)) return 0;
190 return MirrorRgnByWidth(hRgn
, NtGdiGetDeviceWidth(hdc
), phRgn
);
193 /* FUNCTIONS *****************************************************************/
200 CombineRgn(HRGN hDest
,
205 PRGN_ATTR pRgn_Attr_Dest
= NULL
;
206 PRGN_ATTR pRgn_Attr_Src1
= NULL
;
207 PRGN_ATTR pRgn_Attr_Src2
= NULL
;
211 Ret
= GdiGetHandleUserData((HGDIOBJ
) hDest
, GDI_OBJECT_TYPE_REGION
, (PVOID
) &pRgn_Attr_Dest
);
212 Ret
= GdiGetHandleUserData((HGDIOBJ
) hSrc1
, GDI_OBJECT_TYPE_REGION
, (PVOID
) &pRgn_Attr_Src1
);
217 pRgn_Attr_Src1
->Flags
> SIMPLEREGION
)
218 return NtGdiCombineRgn(hDest
, hSrc1
, hSrc2
, CombineMode
);
220 /* Handle COPY and use only src1. */
221 if ( CombineMode
== RGN_COPY
)
223 switch (pRgn_Attr_Src1
->Flags
)
226 Ret
= SetRectRgn( hDest
, 0, 0, 0, 0);
232 Ret
= SetRectRgn( hDest
,
233 pRgn_Attr_Src1
->Rect
.left
,
234 pRgn_Attr_Src1
->Rect
.top
,
235 pRgn_Attr_Src1
->Rect
.right
,
236 pRgn_Attr_Src1
->Rect
.bottom
);
243 return NtGdiCombineRgn(hDest
, hSrc1
, hSrc2
, CombineMode
);
247 Ret
= GdiGetHandleUserData((HGDIOBJ
) hSrc2
, GDI_OBJECT_TYPE_REGION
, (PVOID
) &pRgn_Attr_Src2
);
250 pRgn_Attr_Src2
->Flags
> SIMPLEREGION
)
251 return NtGdiCombineRgn(hDest
, hSrc1
, hSrc2
, CombineMode
);
254 if ( CombineMode
!= RGN_AND
)
256 if ( CombineMode
<= RGN_AND
)
259 There might be some type of junk in the call, so go K.
260 If this becomes a problem, need to setup parameter check at the top.
262 DPRINT1("Might be junk! CombineMode %d\n",CombineMode
);
263 return NtGdiCombineRgn(hDest
, hSrc1
, hSrc2
, CombineMode
);
266 if ( CombineMode
> RGN_XOR
) /* Handle DIFF. */
268 if ( CombineMode
!= RGN_DIFF
)
269 { /* Filter check! Well, must be junk?, so go K. */
270 DPRINT1("RGN_COPY was handled! CombineMode %d\n",CombineMode
);
271 return NtGdiCombineRgn(hDest
, hSrc1
, hSrc2
, CombineMode
);
273 /* Now handle DIFF. */
274 if ( pRgn_Attr_Src1
->Flags
== NULLREGION
)
276 if (SetRectRgn( hDest
, 0, 0, 0, 0))
281 if ( pRgn_Attr_Src2
->Flags
!= NULLREGION
)
283 Complexity
= ComplexityFromRects( &pRgn_Attr_Src1
->Rect
, &pRgn_Attr_Src2
->Rect
);
285 if ( Complexity
!= DIFF_RGN
)
287 if ( Complexity
!= INVERTED_RGN
)
288 /* If same or overlapping and norm just go K. */
289 return NtGdiCombineRgn(hDest
, hSrc1
, hSrc2
, CombineMode
);
291 if (SetRectRgn( hDest
, 0, 0, 0, 0))
297 else /* Handle OR or XOR. */
299 if ( pRgn_Attr_Src1
->Flags
== NULLREGION
)
301 if ( pRgn_Attr_Src2
->Flags
!= NULLREGION
)
302 { /* Src1 null and not NULL, set from src2. */
303 Ret
= SetRectRgn( hDest
,
304 pRgn_Attr_Src2
->Rect
.left
,
305 pRgn_Attr_Src2
->Rect
.top
,
306 pRgn_Attr_Src2
->Rect
.right
,
307 pRgn_Attr_Src2
->Rect
.bottom
);
313 if (SetRectRgn( hDest
, 0, 0, 0, 0))
317 /* Src1 is not NULL. */
318 if ( pRgn_Attr_Src2
->Flags
!= NULLREGION
)
320 if ( CombineMode
!= RGN_OR
) /* Filter XOR, so go K. */
321 return NtGdiCombineRgn(hDest
, hSrc1
, hSrc2
, CombineMode
);
323 Complexity
= ComplexityFromRects( &pRgn_Attr_Src1
->Rect
, &pRgn_Attr_Src2
->Rect
);
324 /* If inverted use Src2. */
325 if ( Complexity
== INVERTED_RGN
)
327 Ret
= SetRectRgn( hDest
,
328 pRgn_Attr_Src2
->Rect
.left
,
329 pRgn_Attr_Src2
->Rect
.top
,
330 pRgn_Attr_Src2
->Rect
.right
,
331 pRgn_Attr_Src2
->Rect
.bottom
);
336 /* Not NULL or overlapping or differentiated, go to K. */
337 if ( Complexity
!= SAME_RGN
)
338 return NtGdiCombineRgn(hDest
, hSrc1
, hSrc2
, CombineMode
);
339 /* If same, just fall through. */
342 Ret
= SetRectRgn( hDest
,
343 pRgn_Attr_Src1
->Rect
.left
,
344 pRgn_Attr_Src1
->Rect
.top
,
345 pRgn_Attr_Src1
->Rect
.right
,
346 pRgn_Attr_Src1
->Rect
.bottom
);
353 if ( pRgn_Attr_Src1
->Flags
!= NULLREGION
&&
354 pRgn_Attr_Src2
->Flags
!= NULLREGION
)
356 Complexity
= ComplexityFromRects( &pRgn_Attr_Src1
->Rect
, &pRgn_Attr_Src2
->Rect
);
358 if ( Complexity
== DIFF_RGN
) /* Differentiated in anyway just NULL rgn. */
360 if (SetRectRgn( hDest
, 0, 0, 0, 0))
365 if ( Complexity
!= INVERTED_RGN
) /* Not inverted and overlapping. */
367 if ( Complexity
!= SAME_RGN
) /* Must be norm and overlapping. */
368 return NtGdiCombineRgn(hDest
, hSrc1
, hSrc2
, CombineMode
);
369 /* Merge from src2. */
370 Ret
= SetRectRgn( hDest
,
371 pRgn_Attr_Src2
->Rect
.left
,
372 pRgn_Attr_Src2
->Rect
.top
,
373 pRgn_Attr_Src2
->Rect
.right
,
374 pRgn_Attr_Src2
->Rect
.bottom
);
379 /* Inverted so merge from src1. */
380 Ret
= SetRectRgn( hDest
,
381 pRgn_Attr_Src1
->Rect
.left
,
382 pRgn_Attr_Src1
->Rect
.top
,
383 pRgn_Attr_Src1
->Rect
.right
,
384 pRgn_Attr_Src1
->Rect
.bottom
);
391 if (SetRectRgn( hDest
, 0, 0, 0, 0))
395 /* Even on error the flag is set dirty and force server side to redraw. */
396 pRgn_Attr_Dest
->AttrFlags
|= ATTR_RGN_DIRTY
;
405 CreateEllipticRgnIndirect(
409 /* Notes if prc is NULL it will crash on All Windows NT I checked 2000/XP/VISTA */
410 return NtGdiCreateEllipticRgn(prc
->left
, prc
->top
, prc
->right
, prc
->bottom
);
419 CreatePolygonRgn( const POINT
* lppt
, int cPoints
, int fnPolyFillMode
)
421 return (HRGN
) NtGdiPolyPolyDraw(ULongToHandle(fnPolyFillMode
), (PPOINT
) lppt
, (PULONG
) &cPoints
, 1, GdiPolyPolyRgn
);
429 CreatePolyPolygonRgn( const POINT
* lppt
,
430 const INT
* lpPolyCounts
,
434 return (HRGN
) NtGdiPolyPolyDraw( (HDC
) fnPolyFillMode
, (PPOINT
) lppt
, (PULONG
) lpPolyCounts
, (ULONG
) nCount
, GdiPolyPolyRgn
);
442 CreateRectRgn(int x1
, int y1
, int x2
, int y2
)
448 /* Normalize points */
462 /* Check outside 24 bit limit for universal set. Chp 9 Areas, pg 560.*/
463 if ( x1
< -(1<<27) ||
468 SetLastError(ERROR_INVALID_PARAMETER
);
472 hrgn
= hGetPEBHandle(hctRegionHandle
, 0);
475 hrgn
= NtGdiCreateRectRgn(0, 0, 1, 1);
480 if (!GdiGetHandleUserData((HGDIOBJ
) hrgn
, GDI_OBJECT_TYPE_REGION
, (PVOID
) &pRgn_Attr
))
482 DPRINT1("No Attr for Region handle!!!\n");
487 if (( x1
== x2
) || (y1
== y2
))
489 pRgn_Attr
->Flags
= NULLREGION
;
490 pRgn_Attr
->Rect
.left
= pRgn_Attr
->Rect
.top
=
491 pRgn_Attr
->Rect
.right
= pRgn_Attr
->Rect
.bottom
= 0;
495 pRgn_Attr
->Flags
= SIMPLEREGION
;
496 pRgn_Attr
->Rect
.left
= x1
;
497 pRgn_Attr
->Rect
.top
= y1
;
498 pRgn_Attr
->Rect
.right
= x2
;
499 pRgn_Attr
->Rect
.bottom
= y2
;
502 pRgn_Attr
->AttrFlags
= (ATTR_RGN_DIRTY
|ATTR_RGN_VALID
);
512 CreateRectRgnIndirect(
516 /* Notes if prc is NULL it will crash on All Windows NT I checked 2000/XP/VISTA */
517 return CreateRectRgn(prc
->left
, prc
->top
, prc
->right
, prc
->bottom
);
526 ExcludeClipRect(IN HDC hdc
, IN INT xLeft
, IN INT yTop
, IN INT xRight
, IN INT yBottom
)
529 // Handle something other than a normal dc object.
530 if (GDI_HANDLE_GET_TYPE(hdc
) != GDI_OBJECT_TYPE_DC
)
532 if (GDI_HANDLE_GET_TYPE(hdc
) == GDI_OBJECT_TYPE_METADC
)
533 return MFDRV_ExcludeClipRect( hdc
, xLeft
, yTop
, xRight
, yBottom
);
536 PLDC pLDC
= GdiGetLDC(hdc
);
539 if (pLDC
->iType
!= LDC_EMFLDC
|| EMFDRV_ExcludeClipRect( hdc
, xLeft
, yTop
, xRight
, yBottom
))
540 return NtGdiExcludeClipRect(hdc
, xLeft
, yTop
, xRight
, yBottom
);
543 SetLastError(ERROR_INVALID_HANDLE
);
548 return NtGdiExcludeClipRect(hdc
, xLeft
, yTop
, xRight
, yBottom
);
557 CONST XFORM
* lpXform
,
559 CONST RGNDATA
* lpRgnData
564 if ((!lpXform
) && (lpRgnData
->rdh
.nCount
== 1))
566 PRECT pRect
= (PRECT
)&lpRgnData
->Buffer
[0];
567 return CreateRectRgn(pRect
->left
, pRect
->top
, pRect
->right
, pRect
->bottom
);
569 return NtGdiExtCreateRegion((LPXFORM
) lpXform
, nCount
,(LPRGNDATA
) lpRgnData
);
571 SetLastError(ERROR_INVALID_PARAMETER
);
580 ExtSelectClipRgn( IN HDC hdc
, IN HRGN hrgn
, IN INT iMode
)
582 /* FIXME some part need be done on user mode size */
583 return NtGdiExtSelectClipRgn(hdc
,hrgn
, iMode
);
596 INT Ret
= NtGdiGetRandomRgn(hdc
, hrgn
, CLIPRGN
);
599 // if(GetLayout(hdc) & LAYOUT_RTL) MirrorRgnDC(hdc,(HRGN)Ret, NULL);
612 return NtGdiGetRandomRgn(hdc
, hrgn
, METARGN
);
621 GetRegionData(HRGN hrgn
,
630 return NtGdiGetRegionData(hrgn
,nCount
,lpRgnData
);
644 if (!GdiGetHandleUserData((HGDIOBJ
) hrgn
, GDI_OBJECT_TYPE_REGION
, (PVOID
) &Rgn_Attr
))
645 return NtGdiGetRgnBox(hrgn
, prcOut
);
647 if (Rgn_Attr
->Flags
== NULLREGION
)
656 if (Rgn_Attr
->Flags
!= SIMPLEREGION
)
657 return NtGdiGetRgnBox(hrgn
, prcOut
);
658 /* WARNING! prcOut is never checked newbies! */
659 RtlCopyMemory( prcOut
, &Rgn_Attr
->Rect
, sizeof(RECT
));
661 return Rgn_Attr
->Flags
;
669 IntersectClipRect(HDC hdc
,
676 // Handle something other than a normal dc object.
677 if (GDI_HANDLE_GET_TYPE(hdc
) != GDI_OBJECT_TYPE_DC
)
679 if (GDI_HANDLE_GET_TYPE(hdc
) == GDI_OBJECT_TYPE_METADC
)
680 return MFDRV_IntersectClipRect( hdc
, nLeftRect
, nTopRect
, nRightRect
, nBottomRect
);
683 PLDC pLDC
= GdiGetLDC(hdc
);
686 if (pLDC
->iType
!= LDC_EMFLDC
|| EMFDRV_IntersectClipRect( hdc
, nLeftRect
, nTopRect
, nRightRect
, nBottomRect
))
687 return NtGdiIntersectClipRect(hdc
, nLeftRect
, nTopRect
, nRightRect
, nBottomRect
);
690 SetLastError(ERROR_INVALID_HANDLE
);
695 return NtGdiIntersectClipRect(hdc
, nLeftRect
, nTopRect
, nRightRect
, nBottomRect
);
703 MirrorRgn(HWND hwnd
, HRGN hrgn
)
706 GetWindowRect(hwnd
, &Rect
);
707 return MirrorRgnByWidth(hrgn
, Rect
.right
- Rect
.left
, NULL
);
715 OffsetClipRgn(HDC hdc
,
720 // Handle something other than a normal dc object.
721 if (GDI_HANDLE_GET_TYPE(hdc
) != GDI_OBJECT_TYPE_DC
)
723 if (GDI_HANDLE_GET_TYPE(hdc
) == GDI_OBJECT_TYPE_METADC
)
724 return MFDRV_OffsetClipRgn( hdc
, nXOffset
, nYOffset
);
727 PLDC pLDC
= GdiGetLDC(hdc
);
730 SetLastError(ERROR_INVALID_HANDLE
);
733 if (pLDC
->iType
== LDC_EMFLDC
&& !EMFDRV_OffsetClipRgn( hdc
, nXOffset
, nYOffset
))
735 return NtGdiOffsetClipRgn( hdc
, nXOffset
, nYOffset
);
739 return NtGdiOffsetClipRgn( hdc
, nXOffset
, nYOffset
);
748 OffsetRgn( HRGN hrgn
,
753 int nLeftRect
, nTopRect
, nRightRect
, nBottomRect
;
755 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
;
802 PtInRegion(IN HRGN hrgn
,
808 if (!GdiGetHandleUserData((HGDIOBJ
) hrgn
, GDI_OBJECT_TYPE_REGION
, (PVOID
) &pRgn_Attr
))
809 return NtGdiPtInRegion(hrgn
,x
,y
);
811 if ( pRgn_Attr
->Flags
== NULLREGION
)
814 if ( pRgn_Attr
->Flags
!= SIMPLEREGION
)
815 return NtGdiPtInRegion(hrgn
,x
,y
);
817 return INRECT( pRgn_Attr
->Rect
, x
, y
);
825 RectInRegion(HRGN hrgn
,
831 if (!GdiGetHandleUserData((HGDIOBJ
) hrgn
, GDI_OBJECT_TYPE_REGION
, (PVOID
) &pRgn_Attr
))
832 return NtGdiRectInRegion(hrgn
, (LPRECT
) prcl
);
834 if ( pRgn_Attr
->Flags
== NULLREGION
)
837 if ( pRgn_Attr
->Flags
!= SIMPLEREGION
)
838 return NtGdiRectInRegion(hrgn
, (LPRECT
) prcl
);
840 /* swap the coordinates to make right >= left and bottom >= top */
841 /* (region building rectangles are normalized the same way) */
842 if ( prcl
->top
> prcl
->bottom
)
844 rc
.top
= prcl
->bottom
;
845 rc
.bottom
= prcl
->top
;
850 rc
.bottom
= prcl
->bottom
;
852 if ( prcl
->right
< prcl
->left
)
854 rc
.right
= prcl
->left
;
855 rc
.left
= prcl
->right
;
859 rc
.right
= prcl
->right
;
860 rc
.left
= prcl
->left
;
863 if ( ComplexityFromRects( &pRgn_Attr
->Rect
, &rc
) != DIFF_RGN
)
878 return ExtSelectClipRgn(hdc
, hrgn
, RGN_COPY
);
886 SetRectRgn(HRGN hrgn
,
894 if (!GdiGetHandleUserData((HGDIOBJ
) hrgn
, GDI_OBJECT_TYPE_REGION
, (PVOID
) &Rgn_Attr
))
895 return NtGdiSetRectRgn(hrgn
, nLeftRect
, nTopRect
, nRightRect
, nBottomRect
);
897 if ((nLeftRect
== nRightRect
) || (nTopRect
== nBottomRect
))
899 Rgn_Attr
->AttrFlags
|= ATTR_RGN_DIRTY
;
900 Rgn_Attr
->Flags
= NULLREGION
;
901 Rgn_Attr
->Rect
.left
= Rgn_Attr
->Rect
.top
=
902 Rgn_Attr
->Rect
.right
= Rgn_Attr
->Rect
.bottom
= 0;
906 Rgn_Attr
->Rect
.left
= nLeftRect
;
907 Rgn_Attr
->Rect
.top
= nTopRect
;
908 Rgn_Attr
->Rect
.right
= nRightRect
;
909 Rgn_Attr
->Rect
.bottom
= nBottomRect
;
911 if(nLeftRect
> nRightRect
)
913 Rgn_Attr
->Rect
.left
= nRightRect
;
914 Rgn_Attr
->Rect
.right
= nLeftRect
;
916 if(nTopRect
> nBottomRect
)
918 Rgn_Attr
->Rect
.top
= nBottomRect
;
919 Rgn_Attr
->Rect
.bottom
= nTopRect
;
922 Rgn_Attr
->AttrFlags
|= ATTR_RGN_DIRTY
;
923 Rgn_Attr
->Flags
= SIMPLEREGION
;
932 SetMetaRgn( HDC hDC
)
934 if (GDI_HANDLE_GET_TYPE(hDC
) == GDI_OBJECT_TYPE_DC
)
935 return NtGdiSetMetaRgn(hDC
);
937 PLDC pLDC
= GdiGetLDC(hDC
);
938 if ( pLDC
&& GDI_HANDLE_GET_TYPE(hDC
) != GDI_OBJECT_TYPE_METADC
)
940 if (pLDC
->iType
== LDC_EMFLDC
|| EMFDRV_SetMetaRgn(hDC
))
942 return NtGdiSetMetaRgn(hDC
);
945 SetLastError(ERROR_INVALID_HANDLE
);