2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: ReactOS kernel
4 * PURPOSE: GDI Clipping Functions
5 * FILE: subsystems/win32/win32k/eng/clip.c
6 * PROGRAMER: Jason Filby
21 if (r1
->top
< r2
->top
)
25 else if (r2
->top
< r1
->top
)
31 ASSERT(r1
->bottom
== r2
->bottom
);
32 if (r1
->left
< r2
->left
)
36 else if (r2
->left
< r1
->left
)
42 ASSERT(r1
->right
== r2
->right
);
57 if (r1
->bottom
< r2
->bottom
)
61 else if (r2
->bottom
< r1
->bottom
)
67 ASSERT(r1
->top
== r2
->top
);
68 if (r1
->left
< r2
->left
)
72 else if (r2
->left
< r1
->left
)
78 ASSERT(r1
->right
== r2
->right
);
93 if (r1
->top
< r2
->top
)
97 else if (r2
->top
< r1
->top
)
103 ASSERT(r1
->bottom
== r2
->bottom
);
104 if (r1
->right
< r2
->right
)
108 else if (r2
->right
< r1
->right
)
114 ASSERT(r1
->left
== r2
->left
);
129 if (r1
->bottom
< r2
->bottom
)
133 else if (r2
->bottom
< r1
->bottom
)
139 ASSERT(r1
->top
== r2
->top
);
140 if (r1
->right
< r2
->right
)
144 else if (r2
->right
< r1
->right
)
150 ASSERT(r1
->left
== r2
->left
);
164 if (Span1
->Y
< Span2
->Y
)
168 else if (Span2
->Y
< Span1
->Y
)
174 if (Span1
->X
< Span2
->X
)
178 else if (Span2
->X
< Span1
->X
)
193 IntEngDeleteClipRegion(CLIPOBJ
*ClipObj
)
195 EngFreeMem(ObjToGDI(ClipObj
, CLIP
));
200 IntEngCreateClipRegion(ULONG count
, PRECTL pRect
, PRECTL rcBounds
)
208 Clip
= EngAllocMem(0, sizeof(CLIPGDI
) + ((count
- 1) * sizeof(RECTL
)), GDITAG_CLIPOBJ
);
212 Clip
->EnumRects
.c
= count
;
213 Clip
->EnumOrder
= CD_ANY
;
214 for(dest
= Clip
->EnumRects
.arcl
;count
> 0; count
--, dest
++, pRect
++)
219 Clip
->ClipObj
.iDComplexity
= DC_COMPLEX
;
220 Clip
->ClipObj
.iFComplexity
= ((Clip
->EnumRects
.c
<= 4) ? FC_RECT4
: FC_COMPLEX
);
221 Clip
->ClipObj
.iMode
= TC_RECTANGLES
;
222 Clip
->ClipObj
.rclBounds
= *rcBounds
;
224 return GDIToObj(Clip
, CLIP
);
229 Clip
= EngAllocMem(0, sizeof(CLIPGDI
), GDITAG_CLIPOBJ
);
233 Clip
->EnumRects
.c
= 1;
234 Clip
->EnumOrder
= CD_ANY
;
235 Clip
->EnumRects
.arcl
[0] = *rcBounds
;
237 Clip
->ClipObj
.iDComplexity
= (((rcBounds
->top
== rcBounds
->bottom
) &&
238 (rcBounds
->left
== rcBounds
->right
))
239 ? DC_TRIVIAL
: DC_RECT
);
241 Clip
->ClipObj
.iFComplexity
= FC_RECT
;
242 Clip
->ClipObj
.iMode
= TC_RECTANGLES
;
243 Clip
->ClipObj
.rclBounds
= *rcBounds
;
245 return GDIToObj(Clip
, CLIP
);
259 CLIPGDI
*Clip
= EngAllocMem(FL_ZERO_MEMORY
, sizeof(CLIPGDI
), GDITAG_CLIPOBJ
);
262 return GDIToObj(Clip
, CLIP
);
274 _In_ _Post_ptr_invalid_ CLIPOBJ
*pco
)
276 EngFreeMem(ObjToGDI(pco
, CLIP
));
285 _Inout_ CLIPOBJ
*pco
,
288 _In_ ULONG iDirection
,
289 _In_ ULONG cMaxRects
)
291 CLIPGDI
*ClipGDI
= ObjToGDI(pco
, CLIP
);
292 SORTCOMP CompareFunc
;
294 ClipGDI
->EnumPos
= 0;
295 ClipGDI
->EnumMax
= (cMaxRects
> 0) ? cMaxRects
: ClipGDI
->EnumRects
.c
;
297 if (CD_ANY
!= iDirection
&& ClipGDI
->EnumOrder
!= iDirection
)
302 CompareFunc
= (SORTCOMP
) CompareRightDown
;
306 CompareFunc
= (SORTCOMP
) CompareRightUp
;
310 CompareFunc
= (SORTCOMP
) CompareLeftDown
;
314 CompareFunc
= (SORTCOMP
) CompareLeftUp
;
318 DPRINT1("Invalid iDirection %lu\n", iDirection
);
319 iDirection
= ClipGDI
->EnumOrder
;
324 if (NULL
!= CompareFunc
)
326 EngSort((PBYTE
) ClipGDI
->EnumRects
.arcl
, sizeof(RECTL
), ClipGDI
->EnumRects
.c
, CompareFunc
);
329 ClipGDI
->EnumOrder
= iDirection
;
332 /* Return the number of rectangles enumerated */
333 if ((cMaxRects
> 0) && (ClipGDI
->EnumRects
.c
> cMaxRects
))
338 return ClipGDI
->EnumRects
.c
;
349 _Out_bytecap_(cj
) ULONG
*pulEnumRects
)
352 CLIPGDI
*ClipGDI
= ObjToGDI(pco
, CLIP
);
354 ENUMRECTS
* pERects
= (ENUMRECTS
*)pulEnumRects
;
356 // Calculate how many rectangles we should copy
357 nCopy
= min( ClipGDI
->EnumMax
- ClipGDI
->EnumPos
,
358 min( ClipGDI
->EnumRects
.c
- ClipGDI
->EnumPos
,
359 (cj
- sizeof(ULONG
)) / sizeof(RECTL
)));
366 /* Copy rectangles */
367 src
= ClipGDI
->EnumRects
.arcl
+ ClipGDI
->EnumPos
;
368 for(i
= 0, dest
= pERects
->arcl
; i
< nCopy
; i
++, dest
++, src
++)
375 ClipGDI
->EnumPos
+=nCopy
;
377 return ClipGDI
->EnumPos
< ClipGDI
->EnumRects
.c
;