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
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
);
163 if (Span1
->Y
< Span2
->Y
)
167 else if (Span2
->Y
< Span1
->Y
)
173 if (Span1
->X
< Span2
->X
)
177 else if (Span2
->X
< Span1
->X
)
192 IntEngInitClipObj(XCLIPOBJ
*Clip
)
194 Clip
->Rects
= &Clip
->ClipObj
.rclBounds
;
198 IntEngFreeClipResources(XCLIPOBJ
*Clip
)
200 if (Clip
->Rects
!= &Clip
->ClipObj
.rclBounds
)
201 EngFreeMem(Clip
->Rects
);
207 IntEngUpdateClipRegion(
211 const RECTL
* rcBounds
)
215 RECTL
* NewRects
= EngAllocMem(0, FIELD_OFFSET(ENUMRECTS
, arcl
[count
]), GDITAG_CLIPOBJ
);
219 Clip
->RectCount
= count
;
220 Clip
->EnumOrder
= CD_ANY
;
221 RtlCopyMemory(NewRects
, pRect
, count
* sizeof(RECTL
));
223 Clip
->ClipObj
.iDComplexity
= DC_COMPLEX
;
224 Clip
->ClipObj
.iFComplexity
= ((Clip
->RectCount
<= 4) ? FC_RECT4
: FC_COMPLEX
);
225 Clip
->ClipObj
.iMode
= TC_RECTANGLES
;
226 Clip
->ClipObj
.rclBounds
= *rcBounds
;
228 if (Clip
->Rects
!= &Clip
->ClipObj
.rclBounds
)
229 EngFreeMem(Clip
->Rects
);
230 Clip
->Rects
= NewRects
;
235 Clip
->EnumOrder
= CD_ANY
;
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 if (Clip
->Rects
!= &Clip
->ClipObj
.rclBounds
)
246 EngFreeMem(Clip
->Rects
);
247 Clip
->Rects
= &Clip
->ClipObj
.rclBounds
;
258 XCLIPOBJ
*Clip
= EngAllocMem(FL_ZERO_MEMORY
, sizeof(XCLIPOBJ
), GDITAG_CLIPOBJ
);
261 IntEngInitClipObj(Clip
);
262 TRACE("Created Clip Obj %p.\n", Clip
);
263 return &Clip
->ClipObj
;
266 ERR("Clip object allocation failed!\n");
276 _In_ _Post_ptr_invalid_ CLIPOBJ
*pco
)
278 XCLIPOBJ
* Clip
= CONTAINING_RECORD(pco
, XCLIPOBJ
, ClipObj
);
279 TRACE("Deleting %p.\n");
280 IntEngFreeClipResources(Clip
);
290 _Inout_ CLIPOBJ
*pco
,
293 _In_ ULONG iDirection
,
294 _In_ ULONG cMaxRects
)
296 XCLIPOBJ
* Clip
= CONTAINING_RECORD(pco
, XCLIPOBJ
, ClipObj
);
297 SORTCOMP CompareFunc
;
300 Clip
->EnumMax
= (cMaxRects
> 0) ? cMaxRects
: Clip
->RectCount
;
302 if (CD_ANY
!= iDirection
&& Clip
->EnumOrder
!= iDirection
)
307 CompareFunc
= (SORTCOMP
) CompareRightDown
;
311 CompareFunc
= (SORTCOMP
) CompareRightUp
;
315 CompareFunc
= (SORTCOMP
) CompareLeftDown
;
319 CompareFunc
= (SORTCOMP
) CompareLeftUp
;
323 ERR("Invalid iDirection %lu\n", iDirection
);
324 iDirection
= Clip
->EnumOrder
;
329 if (NULL
!= CompareFunc
)
331 EngSort((PBYTE
) Clip
->Rects
, sizeof(RECTL
), Clip
->RectCount
, CompareFunc
);
334 Clip
->EnumOrder
= iDirection
;
337 /* Return the number of rectangles enumerated */
338 if ((cMaxRects
> 0) && (Clip
->RectCount
> cMaxRects
))
343 return Clip
->RectCount
;
354 _Out_bytecap_(cj
) ULONG
*pulEnumRects
)
357 XCLIPOBJ
* Clip
= CONTAINING_RECORD(pco
, XCLIPOBJ
, ClipObj
);
359 ENUMRECTS
* pERects
= (ENUMRECTS
*)pulEnumRects
;
361 // Calculate how many rectangles we should copy
362 nCopy
= min( Clip
->EnumMax
- Clip
->EnumPos
,
363 min( Clip
->RectCount
- Clip
->EnumPos
,
364 (cj
- sizeof(ULONG
)) / sizeof(RECTL
)));
371 /* Copy rectangles */
372 src
= &Clip
->Rects
[Clip
->EnumPos
];
373 RtlCopyMemory(pERects
->arcl
, src
, nCopy
* sizeof(RECTL
));
377 Clip
->EnumPos
+=nCopy
;
379 return Clip
->EnumPos
< Clip
->RectCount
;