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
)
103 * I thought it was okay to have this in DeleteObject but~ Speed. (jt)
107 DeleteRegion( HRGN hRgn
)
112 if ((GdiGetHandleUserData((HGDIOBJ
) hRgn
, GDI_OBJECT_TYPE_REGION
, (PVOID
) &Rgn_Attr
)) &&
113 ( Rgn_Attr
!= NULL
))
117 pgO
= GdiAllocBatchCommand(NULL
, GdiBCDelRgn
);
120 pgO
->hgdiobj
= (HGDIOBJ
)hRgn
;
125 return NtGdiDeleteObjectApp((HGDIOBJ
) hRgn
);
130 MirrorRgnByWidth(HRGN hRgn
, INT Width
, HRGN
*phRgn
)
132 INT cRgnDSize
, Ret
= 0;
135 cRgnDSize
= NtGdiGetRegionData(hRgn
, 0, NULL
);
139 pRgnData
= LocalAlloc(LMEM_FIXED
, cRgnDSize
* sizeof(LONG
));
142 if ( GetRegionData(hRgn
, cRgnDSize
, pRgnData
) )
146 INT SaveL
= pRgnData
->rdh
.rcBound
.left
;
147 pRgnData
->rdh
.rcBound
.left
= Width
- pRgnData
->rdh
.rcBound
.right
;
148 pRgnData
->rdh
.rcBound
.right
= Width
- SaveL
;
149 if (pRgnData
->rdh
.nCount
> 0)
151 PRECT pRect
= (PRECT
)&pRgnData
->Buffer
;
152 for (i
= 0; i
< pRgnData
->rdh
.nCount
; i
++)
154 SaveL
= pRect
[i
].left
;
155 pRect
[i
].left
= Width
- pRect
[i
].right
;
156 pRect
[i
].right
= Width
- SaveL
;
159 SortRects((PRECT
)&pRgnData
->Buffer
, pRgnData
->rdh
.nCount
);
160 hRgnex
= ExtCreateRegion(NULL
, cRgnDSize
, pRgnData
);
163 if (phRgn
) phRgn
= (HRGN
*)hRgnex
;
166 CombineRgn(hRgn
, hRgnex
, 0, RGN_COPY
);
167 DeleteObject(hRgnex
);
180 MirrorRgnDC(HDC hdc
, HRGN hRgn
, HRGN
*phRgn
)
182 if (!GdiIsHandleValid((HGDIOBJ
) hdc
) ||
183 (GDI_HANDLE_GET_TYPE(hdc
) != GDI_OBJECT_TYPE_DC
)) return 0;
185 return MirrorRgnByWidth(hRgn
, NtGdiGetDeviceWidth(hdc
), phRgn
);
188 /* FUNCTIONS *****************************************************************/
195 CombineRgn(HRGN hDest
,
200 PRGN_ATTR pRgn_Attr_Dest
= NULL
;
201 PRGN_ATTR pRgn_Attr_Src1
= NULL
;
202 PRGN_ATTR pRgn_Attr_Src2
= NULL
;
207 return NtGdiCombineRgn(hDest
, hSrc1
, hSrc2
, CombineMode
);
209 Ret
= GdiGetHandleUserData((HGDIOBJ
) hDest
, GDI_OBJECT_TYPE_REGION
, (PVOID
) &pRgn_Attr_Dest
);
210 Ret
= GdiGetHandleUserData((HGDIOBJ
) hSrc1
, GDI_OBJECT_TYPE_REGION
, (PVOID
) &pRgn_Attr_Src1
);
215 pRgn_Attr_Src1
->Flags
> SIMPLEREGION
)
216 return NtGdiCombineRgn(hDest
, hSrc1
, hSrc2
, CombineMode
);
218 /* Handle COPY and use only src1. */
219 if ( CombineMode
== RGN_COPY
)
221 switch (pRgn_Attr_Src1
->Flags
)
224 Ret
= SetRectRgn( hDest
, 0, 0, 0, 0);
230 Ret
= SetRectRgn( hDest
,
231 pRgn_Attr_Src1
->Rect
.left
,
232 pRgn_Attr_Src1
->Rect
.top
,
233 pRgn_Attr_Src1
->Rect
.right
,
234 pRgn_Attr_Src1
->Rect
.bottom
);
241 return NtGdiCombineRgn(hDest
, hSrc1
, hSrc2
, CombineMode
);
245 Ret
= GdiGetHandleUserData((HGDIOBJ
) hSrc2
, GDI_OBJECT_TYPE_REGION
, (PVOID
) &pRgn_Attr_Src2
);
248 pRgn_Attr_Src2
->Flags
> SIMPLEREGION
)
249 return NtGdiCombineRgn(hDest
, hSrc1
, hSrc2
, CombineMode
);
252 if ( CombineMode
!= RGN_AND
)
254 if ( CombineMode
<= RGN_AND
)
257 There might be some type of junk in the call, so go K.
258 If this becomes a problem, need to setup parameter check at the top.
260 DPRINT1("Might be junk! CombineMode %d\n",CombineMode
);
261 return NtGdiCombineRgn(hDest
, hSrc1
, hSrc2
, CombineMode
);
264 if ( CombineMode
> RGN_XOR
) /* Handle DIFF. */
266 if ( CombineMode
!= RGN_DIFF
)
268 /* Filter check! Well, must be junk?, so go K. */
269 DPRINT1("RGN_COPY was handled! CombineMode %d\n",CombineMode
);
270 return NtGdiCombineRgn(hDest
, hSrc1
, hSrc2
, CombineMode
);
272 /* Now handle DIFF. */
273 if ( pRgn_Attr_Src1
->Flags
== NULLREGION
)
275 if (SetRectRgn( hDest
, 0, 0, 0, 0))
280 if ( pRgn_Attr_Src2
->Flags
!= NULLREGION
)
282 Complexity
= ComplexityFromRects( &pRgn_Attr_Src1
->Rect
, &pRgn_Attr_Src2
->Rect
);
284 if ( Complexity
!= DIFF_RGN
)
286 if ( Complexity
!= INVERTED_RGN
)
287 /* If same or overlapping and norm just go K. */
288 return NtGdiCombineRgn(hDest
, hSrc1
, hSrc2
, CombineMode
);
290 if (SetRectRgn( hDest
, 0, 0, 0, 0))
296 else /* Handle OR or XOR. */
298 if ( pRgn_Attr_Src1
->Flags
== NULLREGION
)
300 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( (HDC
) 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
)
449 //// Remove when Brush/Pen/Rgn Attr is ready!
450 return NtGdiCreateRectRgn(x1
,y1
,x2
,y2
);
453 /* Normalize points */
467 /* Check outside 24 bit limit for universal set. Chp 9 Areas, pg 560.*/
468 if ( x1
< -(1<<27) ||
473 SetLastError(ERROR_INVALID_PARAMETER
);
477 hrgn
= hGetPEBHandle(hctRegionHandle
, 0);
480 hrgn
= NtGdiCreateRectRgn(0, 0, 1, 1);
485 if (!GdiGetHandleUserData((HGDIOBJ
) hrgn
, GDI_OBJECT_TYPE_REGION
, (PVOID
) &pRgn_Attr
))
487 DPRINT1("No Attr for Region handle!!!\n");
492 if (( x1
== x2
) || (y1
== y2
))
494 pRgn_Attr
->Flags
= NULLREGION
;
495 pRgn_Attr
->Rect
.left
= pRgn_Attr
->Rect
.top
=
496 pRgn_Attr
->Rect
.right
= pRgn_Attr
->Rect
.bottom
= 0;
500 pRgn_Attr
->Flags
= SIMPLEREGION
;
501 pRgn_Attr
->Rect
.left
= x1
;
502 pRgn_Attr
->Rect
.top
= y1
;
503 pRgn_Attr
->Rect
.right
= x2
;
504 pRgn_Attr
->Rect
.bottom
= y2
;
507 pRgn_Attr
->AttrFlags
= (ATTR_RGN_DIRTY
|ATTR_RGN_VALID
);
517 CreateRectRgnIndirect(
521 /* Notes if prc is NULL it will crash on All Windows NT I checked 2000/XP/VISTA */
522 return CreateRectRgn(prc
->left
, prc
->top
, prc
->right
, prc
->bottom
);
531 ExcludeClipRect(IN HDC hdc
, IN INT xLeft
, IN INT yTop
, IN INT xRight
, IN INT yBottom
)
534 // Handle something other than a normal dc object.
535 if (GDI_HANDLE_GET_TYPE(hdc
) != GDI_OBJECT_TYPE_DC
)
537 if (GDI_HANDLE_GET_TYPE(hdc
) == GDI_OBJECT_TYPE_METADC
)
538 return MFDRV_ExcludeClipRect( hdc
, xLeft
, yTop
, xRight
, yBottom
);
541 PLDC pLDC
= GdiGetLDC(hdc
);
544 if (pLDC
->iType
!= LDC_EMFLDC
|| EMFDRV_ExcludeClipRect( hdc
, xLeft
, yTop
, xRight
, yBottom
))
545 return NtGdiExcludeClipRect(hdc
, xLeft
, yTop
, xRight
, yBottom
);
548 SetLastError(ERROR_INVALID_HANDLE
);
553 return NtGdiExcludeClipRect(hdc
, xLeft
, yTop
, xRight
, yBottom
);
562 CONST XFORM
* lpXform
,
564 CONST RGNDATA
* lpRgnData
569 if ((!lpXform
) && (lpRgnData
->rdh
.nCount
== 1))
571 PRECT pRect
= (PRECT
)&lpRgnData
->Buffer
[0];
572 return CreateRectRgn(pRect
->left
, pRect
->top
, pRect
->right
, pRect
->bottom
);
574 return NtGdiExtCreateRegion((LPXFORM
) lpXform
, nCount
,(LPRGNDATA
) lpRgnData
);
576 SetLastError(ERROR_INVALID_PARAMETER
);
585 ExtSelectClipRgn( IN HDC hdc
, IN HRGN hrgn
, IN INT iMode
)
591 // Handle something other than a normal dc object.
592 if (GDI_HANDLE_GET_TYPE(hdc
) != GDI_OBJECT_TYPE_DC
)
594 if (GDI_HANDLE_GET_TYPE(hdc
) == GDI_OBJECT_TYPE_METADC
)
595 return MFDRV_ExtSelectClipRgn( hdc
, );
598 PLDC pLDC
= GdiGetLDC(hdc
);
601 if (pLDC
->iType
!= LDC_EMFLDC
|| EMFDRV_ExtSelectClipRgn( hdc
, ))
602 return NtGdiExtSelectClipRgn(hdc
, );
605 SetLastError(ERROR_INVALID_HANDLE
);
613 if ( GetLayout(hdc
) & LAYOUT_RTL
)
615 if ( MirrorRgnDC(hdc
, hrgn
, &NewRgn
) )
617 if ( NewRgn
) hrgn
= NewRgn
;
622 /* Batch handles RGN_COPY only! */
623 if (iMode
== RGN_COPY
)
627 PRGN_ATTR pRgn_Attr
= NULL
;
629 /* hrgn can be NULL unless the RGN_COPY mode is specified. */
631 GdiGetHandleUserData((HGDIOBJ
) hrgn
, GDI_OBJECT_TYPE_REGION
, (PVOID
) &pRgn_Attr
);
633 if ( GdiGetHandleUserData((HGDIOBJ
) hdc
, GDI_OBJECT_TYPE_DC
, (PVOID
) &pDc_Attr
) &&
636 PGDI_TABLE_ENTRY pEntry
= GdiHandleTable
+ GDI_HANDLE_GET_INDEX(hdc
);
637 PTEB pTeb
= NtCurrentTeb();
639 if ( pTeb
->Win32ThreadInfo
!= NULL
&&
640 pTeb
->GdiTebBatch
.HDC
== hdc
&&
641 !(pDc_Attr
->ulDirty_
& DC_DIBSECTION
) &&
642 !(pEntry
->Flags
& GDI_ENTRY_VALIDATE_VIS
) )
645 (hrgn
&& pRgn_Attr
&& pRgn_Attr
->Flags
<= SIMPLEREGION
) )
647 if ((pTeb
->GdiTebBatch
.Offset
+ sizeof(GDIBSEXTSELCLPRGN
)) <= GDIBATCHBUFSIZE
)
649 PGDIBSEXTSELCLPRGN pgO
= (PGDIBSEXTSELCLPRGN
)(&pTeb
->GdiTebBatch
.Buffer
[0] +
650 pTeb
->GdiTebBatch
.Offset
);
651 pgO
->gbHdr
.Cmd
= GdiBCExtSelClipRgn
;
652 pgO
->gbHdr
.Size
= sizeof(GDIBSEXTSELCLPRGN
);
655 if ( hrgn
&& pRgn_Attr
)
657 Ret
= pRgn_Attr
->Flags
;
659 if ( pDc_Attr
->VisRectRegion
.Rect
.left
>= pRgn_Attr
->Rect
.right
||
660 pDc_Attr
->VisRectRegion
.Rect
.top
>= pRgn_Attr
->Rect
.bottom
||
661 pDc_Attr
->VisRectRegion
.Rect
.right
<= pRgn_Attr
->Rect
.left
||
662 pDc_Attr
->VisRectRegion
.Rect
.bottom
<= pRgn_Attr
->Rect
.top
)
665 pgO
->left
= pRgn_Attr
->Rect
.left
;
666 pgO
->top
= pRgn_Attr
->Rect
.top
;
667 pgO
->right
= pRgn_Attr
->Rect
.right
;
668 pgO
->bottom
= pRgn_Attr
->Rect
.bottom
;
672 Ret
= pDc_Attr
->VisRectRegion
.Flags
;
673 pgO
->fnMode
|= 0x80000000; // Set no hrgn mode.
675 pTeb
->GdiTebBatch
.Offset
+= sizeof(GDIBSEXTSELCLPRGN
);
676 pTeb
->GdiBatchCount
++;
677 if (pTeb
->GdiBatchCount
>= GDI_BatchLimit
) NtGdiFlush();
678 if ( NewRgn
) DeleteObject(NewRgn
);
686 Ret
= NtGdiExtSelectClipRgn(hdc
, hrgn
, iMode
);
688 if ( NewRgn
) DeleteObject(NewRgn
);
705 /* Check if DC handle is valid */
706 if (!GdiGetDcAttr(hdc
))
708 /* Last error code differs from what NtGdiGetRandomRgn returns */
709 SetLastError(ERROR_INVALID_PARAMETER
);
713 Ret
= NtGdiGetRandomRgn(hdc
, hrgn
, CLIPRGN
);
717 // if(GetLayout(hdc) & LAYOUT_RTL) MirrorRgnDC(hdc,(HRGN)Ret, NULL);
730 return NtGdiGetRandomRgn(hdc
, hrgn
, METARGN
);
739 GetRegionData(HRGN hrgn
,
748 return NtGdiGetRegionData(hrgn
,nCount
,lpRgnData
);
762 //if (!GdiGetHandleUserData((HGDIOBJ) hrgn, GDI_OBJECT_TYPE_REGION, (PVOID) &Rgn_Attr))
763 return NtGdiGetRgnBox(hrgn
, prcOut
);
765 if (Rgn_Attr
->Flags
== NULLREGION
)
774 if (Rgn_Attr
->Flags
!= SIMPLEREGION
)
775 return NtGdiGetRgnBox(hrgn
, prcOut
);
776 /* WARNING! prcOut is never checked newbies! */
777 RtlCopyMemory( prcOut
, &Rgn_Attr
->Rect
, sizeof(RECT
));
779 return Rgn_Attr
->Flags
;
787 IntersectClipRect(HDC hdc
,
794 // Handle something other than a normal dc object.
795 if (GDI_HANDLE_GET_TYPE(hdc
) != GDI_OBJECT_TYPE_DC
)
797 if (GDI_HANDLE_GET_TYPE(hdc
) == GDI_OBJECT_TYPE_METADC
)
798 return MFDRV_IntersectClipRect( hdc
, nLeftRect
, nTopRect
, nRightRect
, nBottomRect
);
801 PLDC pLDC
= GdiGetLDC(hdc
);
804 if (pLDC
->iType
!= LDC_EMFLDC
|| EMFDRV_IntersectClipRect( hdc
, nLeftRect
, nTopRect
, nRightRect
, nBottomRect
))
805 return NtGdiIntersectClipRect(hdc
, nLeftRect
, nTopRect
, nRightRect
, nBottomRect
);
808 SetLastError(ERROR_INVALID_HANDLE
);
813 return NtGdiIntersectClipRect(hdc
, nLeftRect
, nTopRect
, nRightRect
, nBottomRect
);
821 MirrorRgn(HWND hwnd
, HRGN hrgn
)
824 GetWindowRect(hwnd
, &Rect
);
825 return MirrorRgnByWidth(hrgn
, Rect
.right
- Rect
.left
, NULL
);
833 OffsetClipRgn(HDC hdc
,
838 // Handle something other than a normal dc object.
839 if (GDI_HANDLE_GET_TYPE(hdc
) != GDI_OBJECT_TYPE_DC
)
841 if (GDI_HANDLE_GET_TYPE(hdc
) == GDI_OBJECT_TYPE_METADC
)
842 return MFDRV_OffsetClipRgn( hdc
, nXOffset
, nYOffset
);
845 PLDC pLDC
= GdiGetLDC(hdc
);
848 SetLastError(ERROR_INVALID_HANDLE
);
851 if (pLDC
->iType
== LDC_EMFLDC
&& !EMFDRV_OffsetClipRgn( hdc
, nXOffset
, nYOffset
))
853 return NtGdiOffsetClipRgn( hdc
, nXOffset
, nYOffset
);
857 return NtGdiOffsetClipRgn( hdc
, nXOffset
, nYOffset
);
866 OffsetRgn( HRGN hrgn
,
871 int nLeftRect
, nTopRect
, nRightRect
, nBottomRect
;
874 // if (!GdiGetHandleUserData((HGDIOBJ) hrgn, GDI_OBJECT_TYPE_REGION, (PVOID) &pRgn_Attr))
875 return NtGdiOffsetRgn(hrgn
,nXOffset
,nYOffset
);
877 if ( pRgn_Attr
->Flags
== NULLREGION
)
878 return pRgn_Attr
->Flags
;
880 if ( pRgn_Attr
->Flags
!= SIMPLEREGION
)
881 return NtGdiOffsetRgn(hrgn
,nXOffset
,nYOffset
);
883 nLeftRect
= pRgn_Attr
->Rect
.left
;
884 nTopRect
= pRgn_Attr
->Rect
.top
;
885 nRightRect
= pRgn_Attr
->Rect
.right
;
886 nBottomRect
= pRgn_Attr
->Rect
.bottom
;
888 if (nLeftRect
< nRightRect
)
890 if (nTopRect
< nBottomRect
)
892 nLeftRect
= nXOffset
+ nLeftRect
;
893 nTopRect
= nYOffset
+ nTopRect
;
894 nRightRect
= nXOffset
+ nRightRect
;
895 nBottomRect
= nYOffset
+ nBottomRect
;
897 /* Check 28 bit limit. Chp 9 Areas, pg 560. */
898 if ( nLeftRect
< -(1<<27) ||
899 nTopRect
< -(1<<27) ||
900 nRightRect
> (1<<27)-1 ||
901 nBottomRect
> (1<<27)-1 )
906 pRgn_Attr
->Rect
.top
= nTopRect
;
907 pRgn_Attr
->Rect
.left
= nLeftRect
;
908 pRgn_Attr
->Rect
.right
= nRightRect
;
909 pRgn_Attr
->Rect
.bottom
= nBottomRect
;
910 pRgn_Attr
->AttrFlags
|= ATTR_RGN_DIRTY
;
913 return pRgn_Attr
->Flags
;
921 PtInRegion(IN HRGN hrgn
,
928 //if (!GdiGetHandleUserData((HGDIOBJ) hrgn, GDI_OBJECT_TYPE_REGION, (PVOID) &pRgn_Attr))
929 return NtGdiPtInRegion(hrgn
,x
,y
);
931 if ( pRgn_Attr
->Flags
== NULLREGION
)
934 if ( pRgn_Attr
->Flags
!= SIMPLEREGION
)
935 return NtGdiPtInRegion(hrgn
,x
,y
);
937 return INRECT( pRgn_Attr
->Rect
, x
, y
);
945 RectInRegion(HRGN hrgn
,
952 //if (!GdiGetHandleUserData((HGDIOBJ) hrgn, GDI_OBJECT_TYPE_REGION, (PVOID) &pRgn_Attr))
953 return NtGdiRectInRegion(hrgn
, (LPRECT
) prcl
);
955 if ( pRgn_Attr
->Flags
== NULLREGION
)
958 if ( pRgn_Attr
->Flags
!= SIMPLEREGION
)
959 return NtGdiRectInRegion(hrgn
, (LPRECT
) prcl
);
961 /* swap the coordinates to make right >= left and bottom >= top */
962 /* (region building rectangles are normalized the same way) */
963 if ( prcl
->top
> prcl
->bottom
)
965 rc
.top
= prcl
->bottom
;
966 rc
.bottom
= prcl
->top
;
971 rc
.bottom
= prcl
->bottom
;
973 if ( prcl
->right
< prcl
->left
)
975 rc
.right
= prcl
->left
;
976 rc
.left
= prcl
->right
;
980 rc
.right
= prcl
->right
;
981 rc
.left
= prcl
->left
;
984 if ( ComplexityFromRects( &pRgn_Attr
->Rect
, &rc
) != DIFF_RGN
)
999 return ExtSelectClipRgn(hdc
, hrgn
, RGN_COPY
);
1007 SetRectRgn(HRGN hrgn
,
1015 //if (!GdiGetHandleUserData((HGDIOBJ) hrgn, GDI_OBJECT_TYPE_REGION, (PVOID) &Rgn_Attr))
1016 return NtGdiSetRectRgn(hrgn
, nLeftRect
, nTopRect
, nRightRect
, nBottomRect
);
1018 if ((nLeftRect
== nRightRect
) || (nTopRect
== nBottomRect
))
1020 Rgn_Attr
->AttrFlags
|= ATTR_RGN_DIRTY
;
1021 Rgn_Attr
->Flags
= NULLREGION
;
1022 Rgn_Attr
->Rect
.left
= Rgn_Attr
->Rect
.top
=
1023 Rgn_Attr
->Rect
.right
= Rgn_Attr
->Rect
.bottom
= 0;
1027 Rgn_Attr
->Rect
.left
= nLeftRect
;
1028 Rgn_Attr
->Rect
.top
= nTopRect
;
1029 Rgn_Attr
->Rect
.right
= nRightRect
;
1030 Rgn_Attr
->Rect
.bottom
= nBottomRect
;
1032 if(nLeftRect
> nRightRect
)
1034 Rgn_Attr
->Rect
.left
= nRightRect
;
1035 Rgn_Attr
->Rect
.right
= nLeftRect
;
1037 if(nTopRect
> nBottomRect
)
1039 Rgn_Attr
->Rect
.top
= nBottomRect
;
1040 Rgn_Attr
->Rect
.bottom
= nTopRect
;
1043 Rgn_Attr
->AttrFlags
|= ATTR_RGN_DIRTY
;
1044 Rgn_Attr
->Flags
= SIMPLEREGION
;
1053 SetMetaRgn( HDC hDC
)
1055 if (GDI_HANDLE_GET_TYPE(hDC
) == GDI_OBJECT_TYPE_DC
)
1056 return NtGdiSetMetaRgn(hDC
);
1058 PLDC pLDC
= GdiGetLDC(hDC
);
1059 if ( pLDC
&& GDI_HANDLE_GET_TYPE(hDC
) != GDI_OBJECT_TYPE_METADC
)
1061 if (pLDC
->iType
== LDC_EMFLDC
|| EMFDRV_SetMetaRgn(hDC
))
1063 return NtGdiSetMetaRgn(hDC
);
1066 SetLastError(ERROR_INVALID_HANDLE
);