2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: ReactOS kernel
4 * PURPOSE: GDI Clipping Functions
5 * FILE: win32ss/gdi/eng/clip.c
6 * PROGRAMER: Jason Filby
10 DBG_DEFAULT_CHANNEL(EngClip
);
20 if (r1
->top
< r2
->top
)
24 else if (r2
->top
< r1
->top
)
30 ASSERT(r1
->bottom
== r2
->bottom
);
31 if (r1
->left
< r2
->left
)
35 else if (r2
->left
< r1
->left
)
41 ASSERT(r1
->right
== r2
->right
);
56 if (r1
->bottom
< r2
->bottom
)
60 else if (r2
->bottom
< r1
->bottom
)
66 ASSERT(r1
->top
== r2
->top
);
67 if (r1
->left
< r2
->left
)
71 else if (r2
->left
< r1
->left
)
77 ASSERT(r1
->right
== r2
->right
);
92 if (r1
->top
< r2
->top
)
96 else if (r2
->top
< r1
->top
)
102 ASSERT(r1
->bottom
== r2
->bottom
);
103 if (r1
->right
< r2
->right
)
107 else if (r2
->right
< r1
->right
)
113 ASSERT(r1
->left
== r2
->left
);
128 if (r1
->bottom
< r2
->bottom
)
132 else if (r2
->bottom
< r1
->bottom
)
138 ASSERT(r1
->top
== r2
->top
);
139 if (r1
->right
< r2
->right
)
143 else if (r2
->right
< r1
->right
)
149 ASSERT(r1
->left
== r2
->left
);
158 IntEngInitClipObj(XCLIPOBJ
*Clip
)
160 Clip
->Rects
= &Clip
->rclBounds
;
164 IntEngFreeClipResources(XCLIPOBJ
*Clip
)
166 if (Clip
->Rects
!= &Clip
->rclBounds
)
167 EngFreeMem(Clip
->Rects
);
173 IntEngUpdateClipRegion(
177 const RECTL
* rcBounds
)
181 RECTL
* NewRects
= EngAllocMem(0, FIELD_OFFSET(ENUMRECTS
, arcl
[count
]), GDITAG_CLIPOBJ
);
185 Clip
->RectCount
= count
;
186 Clip
->iDirection
= CD_ANY
;
187 RtlCopyMemory(NewRects
, pRect
, count
* sizeof(RECTL
));
189 Clip
->iDComplexity
= DC_COMPLEX
;
190 Clip
->iFComplexity
= ((Clip
->RectCount
<= 4) ? FC_RECT4
: FC_COMPLEX
);
191 Clip
->iMode
= TC_RECTANGLES
;
192 Clip
->rclBounds
= *rcBounds
;
194 if (Clip
->Rects
!= &Clip
->rclBounds
)
195 EngFreeMem(Clip
->Rects
);
196 Clip
->Rects
= NewRects
;
201 Clip
->iDirection
= CD_ANY
;
203 Clip
->iDComplexity
= (((rcBounds
->top
== rcBounds
->bottom
) &&
204 (rcBounds
->left
== rcBounds
->right
))
205 ? DC_TRIVIAL
: DC_RECT
);
207 Clip
->iFComplexity
= FC_RECT
;
208 Clip
->iMode
= TC_RECTANGLES
;
209 Clip
->rclBounds
= *rcBounds
;
211 if (Clip
->Rects
!= &Clip
->rclBounds
)
212 EngFreeMem(Clip
->Rects
);
213 Clip
->Rects
= &Clip
->rclBounds
;
224 XCLIPOBJ
*Clip
= EngAllocMem(FL_ZERO_MEMORY
, sizeof(XCLIPOBJ
), GDITAG_CLIPOBJ
);
227 IntEngInitClipObj(Clip
);
228 TRACE("Created Clip Obj %p.\n", Clip
);
229 return (CLIPOBJ
*)Clip
;
232 ERR("Clip object allocation failed!\n");
242 _In_ _Post_ptr_invalid_ CLIPOBJ
*pco
)
244 XCLIPOBJ
* pxco
= (XCLIPOBJ
*)pco
;
245 TRACE("Deleting %p.\n", pco
);
246 IntEngFreeClipResources(pxco
);
256 _Inout_ CLIPOBJ
*pco
,
259 _In_ ULONG iDirection
,
260 _In_ ULONG cMaxRects
)
262 XCLIPOBJ
* Clip
= (XCLIPOBJ
*)pco
;
263 SORTCOMP CompareFunc
;
268 Clip
->EnumMax
= (cMaxRects
> 0) ? cMaxRects
: Clip
->RectCount
;
270 if (CD_ANY
!= iDirection
&& Clip
->iDirection
!= iDirection
)
275 CompareFunc
= (SORTCOMP
) CompareRightDown
;
279 CompareFunc
= (SORTCOMP
) CompareRightUp
;
283 CompareFunc
= (SORTCOMP
) CompareLeftDown
;
287 CompareFunc
= (SORTCOMP
) CompareLeftUp
;
291 ERR("Invalid iDirection %lu\n", iDirection
);
292 iDirection
= Clip
->iDirection
;
297 if (NULL
!= CompareFunc
)
299 EngSort((PBYTE
) Clip
->Rects
, sizeof(RECTL
), Clip
->RectCount
, CompareFunc
);
302 Clip
->iDirection
= iDirection
;
305 /* Return the number of rectangles enumerated */
306 if ((cMaxRects
> 0) && (Clip
->RectCount
> cMaxRects
))
311 return Clip
->RectCount
;
322 _Out_bytecap_(cj
) ULONG
*pulEnumRects
)
325 XCLIPOBJ
* Clip
= (XCLIPOBJ
*)pco
;
327 ENUMRECTS
* pERects
= (ENUMRECTS
*)pulEnumRects
;
329 // Calculate how many rectangles we should copy
330 nCopy
= min( Clip
->EnumMax
- Clip
->EnumPos
,
331 min( Clip
->RectCount
- Clip
->EnumPos
,
332 (cj
- sizeof(ULONG
)) / sizeof(RECTL
)));
339 /* Copy rectangles */
340 src
= &Clip
->Rects
[Clip
->EnumPos
];
341 RtlCopyMemory(pERects
->arcl
, src
, nCopy
* sizeof(RECTL
));
345 Clip
->EnumPos
+=nCopy
;
347 return Clip
->EnumPos
< Clip
->RectCount
;