1*c2c66affSColin Finck /*
2*c2c66affSColin Finck * COPYRIGHT: See COPYING in the top level directory
3*c2c66affSColin Finck * PROJECT: ReactOS kernel
4*c2c66affSColin Finck * PURPOSE: GDI Clipping Functions
5*c2c66affSColin Finck * FILE: win32ss/gdi/eng/clip.c
6*c2c66affSColin Finck * PROGRAMER: Jason Filby
7*c2c66affSColin Finck */
8*c2c66affSColin Finck
9*c2c66affSColin Finck #include <win32k.h>
10*c2c66affSColin Finck DBG_DEFAULT_CHANNEL(EngClip);
11*c2c66affSColin Finck
12*c2c66affSColin Finck
13*c2c66affSColin Finck static __inline int
CompareRightDown(const RECTL * r1,const RECTL * r2)14*c2c66affSColin Finck CompareRightDown(
15*c2c66affSColin Finck const RECTL *r1,
16*c2c66affSColin Finck const RECTL *r2)
17*c2c66affSColin Finck {
18*c2c66affSColin Finck int Cmp;
19*c2c66affSColin Finck
20*c2c66affSColin Finck if (r1->top < r2->top)
21*c2c66affSColin Finck {
22*c2c66affSColin Finck Cmp = -1;
23*c2c66affSColin Finck }
24*c2c66affSColin Finck else if (r2->top < r1->top)
25*c2c66affSColin Finck {
26*c2c66affSColin Finck Cmp = +1;
27*c2c66affSColin Finck }
28*c2c66affSColin Finck else
29*c2c66affSColin Finck {
30*c2c66affSColin Finck ASSERT(r1->bottom == r2->bottom);
31*c2c66affSColin Finck if (r1->left < r2->left)
32*c2c66affSColin Finck {
33*c2c66affSColin Finck Cmp = -1;
34*c2c66affSColin Finck }
35*c2c66affSColin Finck else if (r2->left < r1->left)
36*c2c66affSColin Finck {
37*c2c66affSColin Finck Cmp = +1;
38*c2c66affSColin Finck }
39*c2c66affSColin Finck else
40*c2c66affSColin Finck {
41*c2c66affSColin Finck ASSERT(r1->right == r2->right);
42*c2c66affSColin Finck Cmp = 0;
43*c2c66affSColin Finck }
44*c2c66affSColin Finck }
45*c2c66affSColin Finck
46*c2c66affSColin Finck return Cmp;
47*c2c66affSColin Finck }
48*c2c66affSColin Finck
49*c2c66affSColin Finck static __inline int
CompareRightUp(const RECTL * r1,const RECTL * r2)50*c2c66affSColin Finck CompareRightUp(
51*c2c66affSColin Finck const RECTL *r1,
52*c2c66affSColin Finck const RECTL *r2)
53*c2c66affSColin Finck {
54*c2c66affSColin Finck int Cmp;
55*c2c66affSColin Finck
56*c2c66affSColin Finck if (r1->bottom < r2->bottom)
57*c2c66affSColin Finck {
58*c2c66affSColin Finck Cmp = +1;
59*c2c66affSColin Finck }
60*c2c66affSColin Finck else if (r2->bottom < r1->bottom)
61*c2c66affSColin Finck {
62*c2c66affSColin Finck Cmp = -1;
63*c2c66affSColin Finck }
64*c2c66affSColin Finck else
65*c2c66affSColin Finck {
66*c2c66affSColin Finck ASSERT(r1->top == r2->top);
67*c2c66affSColin Finck if (r1->left < r2->left)
68*c2c66affSColin Finck {
69*c2c66affSColin Finck Cmp = -1;
70*c2c66affSColin Finck }
71*c2c66affSColin Finck else if (r2->left < r1->left)
72*c2c66affSColin Finck {
73*c2c66affSColin Finck Cmp = +1;
74*c2c66affSColin Finck }
75*c2c66affSColin Finck else
76*c2c66affSColin Finck {
77*c2c66affSColin Finck ASSERT(r1->right == r2->right);
78*c2c66affSColin Finck Cmp = 0;
79*c2c66affSColin Finck }
80*c2c66affSColin Finck }
81*c2c66affSColin Finck
82*c2c66affSColin Finck return Cmp;
83*c2c66affSColin Finck }
84*c2c66affSColin Finck
85*c2c66affSColin Finck static __inline int
CompareLeftDown(const RECTL * r1,const RECTL * r2)86*c2c66affSColin Finck CompareLeftDown(
87*c2c66affSColin Finck const RECTL *r1,
88*c2c66affSColin Finck const RECTL *r2)
89*c2c66affSColin Finck {
90*c2c66affSColin Finck int Cmp;
91*c2c66affSColin Finck
92*c2c66affSColin Finck if (r1->top < r2->top)
93*c2c66affSColin Finck {
94*c2c66affSColin Finck Cmp = -1;
95*c2c66affSColin Finck }
96*c2c66affSColin Finck else if (r2->top < r1->top)
97*c2c66affSColin Finck {
98*c2c66affSColin Finck Cmp = +1;
99*c2c66affSColin Finck }
100*c2c66affSColin Finck else
101*c2c66affSColin Finck {
102*c2c66affSColin Finck ASSERT(r1->bottom == r2->bottom);
103*c2c66affSColin Finck if (r1->right < r2->right)
104*c2c66affSColin Finck {
105*c2c66affSColin Finck Cmp = +1;
106*c2c66affSColin Finck }
107*c2c66affSColin Finck else if (r2->right < r1->right)
108*c2c66affSColin Finck {
109*c2c66affSColin Finck Cmp = -1;
110*c2c66affSColin Finck }
111*c2c66affSColin Finck else
112*c2c66affSColin Finck {
113*c2c66affSColin Finck ASSERT(r1->left == r2->left);
114*c2c66affSColin Finck Cmp = 0;
115*c2c66affSColin Finck }
116*c2c66affSColin Finck }
117*c2c66affSColin Finck
118*c2c66affSColin Finck return Cmp;
119*c2c66affSColin Finck }
120*c2c66affSColin Finck
121*c2c66affSColin Finck static __inline int
CompareLeftUp(const RECTL * r1,const RECTL * r2)122*c2c66affSColin Finck CompareLeftUp(
123*c2c66affSColin Finck const RECTL *r1,
124*c2c66affSColin Finck const RECTL *r2)
125*c2c66affSColin Finck {
126*c2c66affSColin Finck int Cmp;
127*c2c66affSColin Finck
128*c2c66affSColin Finck if (r1->bottom < r2->bottom)
129*c2c66affSColin Finck {
130*c2c66affSColin Finck Cmp = +1;
131*c2c66affSColin Finck }
132*c2c66affSColin Finck else if (r2->bottom < r1->bottom)
133*c2c66affSColin Finck {
134*c2c66affSColin Finck Cmp = -1;
135*c2c66affSColin Finck }
136*c2c66affSColin Finck else
137*c2c66affSColin Finck {
138*c2c66affSColin Finck ASSERT(r1->top == r2->top);
139*c2c66affSColin Finck if (r1->right < r2->right)
140*c2c66affSColin Finck {
141*c2c66affSColin Finck Cmp = +1;
142*c2c66affSColin Finck }
143*c2c66affSColin Finck else if (r2->right < r1->right)
144*c2c66affSColin Finck {
145*c2c66affSColin Finck Cmp = -1;
146*c2c66affSColin Finck }
147*c2c66affSColin Finck else
148*c2c66affSColin Finck {
149*c2c66affSColin Finck ASSERT(r1->left == r2->left);
150*c2c66affSColin Finck Cmp = 0;
151*c2c66affSColin Finck }
152*c2c66affSColin Finck }
153*c2c66affSColin Finck return Cmp;
154*c2c66affSColin Finck }
155*c2c66affSColin Finck
156*c2c66affSColin Finck VOID
157*c2c66affSColin Finck FASTCALL
IntEngInitClipObj(XCLIPOBJ * Clip)158*c2c66affSColin Finck IntEngInitClipObj(XCLIPOBJ *Clip)
159*c2c66affSColin Finck {
160*c2c66affSColin Finck Clip->Rects = &Clip->rclBounds;
161*c2c66affSColin Finck }
162*c2c66affSColin Finck
163*c2c66affSColin Finck VOID FASTCALL
IntEngFreeClipResources(XCLIPOBJ * Clip)164*c2c66affSColin Finck IntEngFreeClipResources(XCLIPOBJ *Clip)
165*c2c66affSColin Finck {
166*c2c66affSColin Finck if (Clip->Rects != &Clip->rclBounds)
167*c2c66affSColin Finck EngFreeMem(Clip->Rects);
168*c2c66affSColin Finck }
169*c2c66affSColin Finck
170*c2c66affSColin Finck
171*c2c66affSColin Finck VOID
172*c2c66affSColin Finck FASTCALL
IntEngUpdateClipRegion(XCLIPOBJ * Clip,ULONG count,const RECTL * pRect,const RECTL * rcBounds)173*c2c66affSColin Finck IntEngUpdateClipRegion(
174*c2c66affSColin Finck XCLIPOBJ* Clip,
175*c2c66affSColin Finck ULONG count,
176*c2c66affSColin Finck const RECTL* pRect,
177*c2c66affSColin Finck const RECTL* rcBounds)
178*c2c66affSColin Finck {
179*c2c66affSColin Finck if(count > 1)
180*c2c66affSColin Finck {
181*c2c66affSColin Finck RECTL* NewRects = EngAllocMem(0, FIELD_OFFSET(ENUMRECTS, arcl[count]), GDITAG_CLIPOBJ);
182*c2c66affSColin Finck
183*c2c66affSColin Finck if(NewRects != NULL)
184*c2c66affSColin Finck {
185*c2c66affSColin Finck Clip->RectCount = count;
186*c2c66affSColin Finck Clip->iDirection = CD_ANY;
187*c2c66affSColin Finck RtlCopyMemory(NewRects, pRect, count * sizeof(RECTL));
188*c2c66affSColin Finck
189*c2c66affSColin Finck Clip->iDComplexity = DC_COMPLEX;
190*c2c66affSColin Finck Clip->iFComplexity = ((Clip->RectCount <= 4) ? FC_RECT4 : FC_COMPLEX);
191*c2c66affSColin Finck Clip->iMode = TC_RECTANGLES;
192*c2c66affSColin Finck Clip->rclBounds = *rcBounds;
193*c2c66affSColin Finck
194*c2c66affSColin Finck if (Clip->Rects != &Clip->rclBounds)
195*c2c66affSColin Finck EngFreeMem(Clip->Rects);
196*c2c66affSColin Finck Clip->Rects = NewRects;
197*c2c66affSColin Finck }
198*c2c66affSColin Finck }
199*c2c66affSColin Finck else
200*c2c66affSColin Finck {
201*c2c66affSColin Finck Clip->iDirection = CD_ANY;
202*c2c66affSColin Finck
203*c2c66affSColin Finck Clip->iDComplexity = (((rcBounds->top == rcBounds->bottom) &&
204*c2c66affSColin Finck (rcBounds->left == rcBounds->right))
205*c2c66affSColin Finck ? DC_TRIVIAL : DC_RECT);
206*c2c66affSColin Finck
207*c2c66affSColin Finck Clip->iFComplexity = FC_RECT;
208*c2c66affSColin Finck Clip->iMode = TC_RECTANGLES;
209*c2c66affSColin Finck Clip->rclBounds = *rcBounds;
210*c2c66affSColin Finck Clip->RectCount = 1;
211*c2c66affSColin Finck if (Clip->Rects != &Clip->rclBounds)
212*c2c66affSColin Finck EngFreeMem(Clip->Rects);
213*c2c66affSColin Finck Clip->Rects = &Clip->rclBounds;
214*c2c66affSColin Finck }
215*c2c66affSColin Finck }
216*c2c66affSColin Finck
217*c2c66affSColin Finck /*
218*c2c66affSColin Finck * @implemented
219*c2c66affSColin Finck */
220*c2c66affSColin Finck CLIPOBJ *
221*c2c66affSColin Finck APIENTRY
EngCreateClip(VOID)222*c2c66affSColin Finck EngCreateClip(VOID)
223*c2c66affSColin Finck {
224*c2c66affSColin Finck XCLIPOBJ *Clip = EngAllocMem(FL_ZERO_MEMORY, sizeof(XCLIPOBJ), GDITAG_CLIPOBJ);
225*c2c66affSColin Finck if(Clip != NULL)
226*c2c66affSColin Finck {
227*c2c66affSColin Finck IntEngInitClipObj(Clip);
228*c2c66affSColin Finck TRACE("Created Clip Obj %p.\n", Clip);
229*c2c66affSColin Finck return (CLIPOBJ *)Clip;
230*c2c66affSColin Finck }
231*c2c66affSColin Finck
232*c2c66affSColin Finck ERR("Clip object allocation failed!\n");
233*c2c66affSColin Finck return NULL;
234*c2c66affSColin Finck }
235*c2c66affSColin Finck
236*c2c66affSColin Finck /*
237*c2c66affSColin Finck * @implemented
238*c2c66affSColin Finck */
239*c2c66affSColin Finck VOID
240*c2c66affSColin Finck APIENTRY
EngDeleteClip(_In_ _Post_ptr_invalid_ CLIPOBJ * pco)241*c2c66affSColin Finck EngDeleteClip(
242*c2c66affSColin Finck _In_ _Post_ptr_invalid_ CLIPOBJ *pco)
243*c2c66affSColin Finck {
244*c2c66affSColin Finck XCLIPOBJ* pxco = (XCLIPOBJ *)pco;
245*c2c66affSColin Finck TRACE("Deleting %p.\n", pco);
246*c2c66affSColin Finck IntEngFreeClipResources(pxco);
247*c2c66affSColin Finck EngFreeMem(pxco);
248*c2c66affSColin Finck }
249*c2c66affSColin Finck
250*c2c66affSColin Finck /*
251*c2c66affSColin Finck * @implemented
252*c2c66affSColin Finck */
253*c2c66affSColin Finck ULONG
254*c2c66affSColin Finck APIENTRY
CLIPOBJ_cEnumStart(_Inout_ CLIPOBJ * pco,_In_ BOOL bAll,_In_ ULONG iType,_In_ ULONG iDirection,_In_ ULONG cMaxRects)255*c2c66affSColin Finck CLIPOBJ_cEnumStart(
256*c2c66affSColin Finck _Inout_ CLIPOBJ *pco,
257*c2c66affSColin Finck _In_ BOOL bAll,
258*c2c66affSColin Finck _In_ ULONG iType,
259*c2c66affSColin Finck _In_ ULONG iDirection,
260*c2c66affSColin Finck _In_ ULONG cMaxRects)
261*c2c66affSColin Finck {
262*c2c66affSColin Finck XCLIPOBJ* Clip = (XCLIPOBJ *)pco;
263*c2c66affSColin Finck SORTCOMP CompareFunc;
264*c2c66affSColin Finck
265*c2c66affSColin Finck Clip->bAll = bAll;
266*c2c66affSColin Finck Clip->iType = iType;
267*c2c66affSColin Finck Clip->EnumPos = 0;
268*c2c66affSColin Finck Clip->EnumMax = (cMaxRects > 0) ? cMaxRects : Clip->RectCount;
269*c2c66affSColin Finck
270*c2c66affSColin Finck if (CD_ANY != iDirection && Clip->iDirection != iDirection)
271*c2c66affSColin Finck {
272*c2c66affSColin Finck switch (iDirection)
273*c2c66affSColin Finck {
274*c2c66affSColin Finck case CD_RIGHTDOWN:
275*c2c66affSColin Finck CompareFunc = (SORTCOMP) CompareRightDown;
276*c2c66affSColin Finck break;
277*c2c66affSColin Finck
278*c2c66affSColin Finck case CD_RIGHTUP:
279*c2c66affSColin Finck CompareFunc = (SORTCOMP) CompareRightUp;
280*c2c66affSColin Finck break;
281*c2c66affSColin Finck
282*c2c66affSColin Finck case CD_LEFTDOWN:
283*c2c66affSColin Finck CompareFunc = (SORTCOMP) CompareLeftDown;
284*c2c66affSColin Finck break;
285*c2c66affSColin Finck
286*c2c66affSColin Finck case CD_LEFTUP:
287*c2c66affSColin Finck CompareFunc = (SORTCOMP) CompareLeftUp;
288*c2c66affSColin Finck break;
289*c2c66affSColin Finck
290*c2c66affSColin Finck default:
291*c2c66affSColin Finck ERR("Invalid iDirection %lu\n", iDirection);
292*c2c66affSColin Finck iDirection = Clip->iDirection;
293*c2c66affSColin Finck CompareFunc = NULL;
294*c2c66affSColin Finck break;
295*c2c66affSColin Finck }
296*c2c66affSColin Finck
297*c2c66affSColin Finck if (NULL != CompareFunc)
298*c2c66affSColin Finck {
299*c2c66affSColin Finck EngSort((PBYTE) Clip->Rects, sizeof(RECTL), Clip->RectCount, CompareFunc);
300*c2c66affSColin Finck }
301*c2c66affSColin Finck
302*c2c66affSColin Finck Clip->iDirection = iDirection;
303*c2c66affSColin Finck }
304*c2c66affSColin Finck
305*c2c66affSColin Finck /* Return the number of rectangles enumerated */
306*c2c66affSColin Finck if ((cMaxRects > 0) && (Clip->RectCount > cMaxRects))
307*c2c66affSColin Finck {
308*c2c66affSColin Finck return 0xFFFFFFFF;
309*c2c66affSColin Finck }
310*c2c66affSColin Finck
311*c2c66affSColin Finck return Clip->RectCount;
312*c2c66affSColin Finck }
313*c2c66affSColin Finck
314*c2c66affSColin Finck /*
315*c2c66affSColin Finck * @implemented
316*c2c66affSColin Finck */
317*c2c66affSColin Finck BOOL
318*c2c66affSColin Finck APIENTRY
CLIPOBJ_bEnum(_In_ CLIPOBJ * pco,_In_ ULONG cj,_Out_bytecap_ (cj)ULONG * pulEnumRects)319*c2c66affSColin Finck CLIPOBJ_bEnum(
320*c2c66affSColin Finck _In_ CLIPOBJ *pco,
321*c2c66affSColin Finck _In_ ULONG cj,
322*c2c66affSColin Finck _Out_bytecap_(cj) ULONG *pulEnumRects)
323*c2c66affSColin Finck {
324*c2c66affSColin Finck const RECTL* src;
325*c2c66affSColin Finck XCLIPOBJ* Clip = (XCLIPOBJ *)pco;
326*c2c66affSColin Finck ULONG nCopy;
327*c2c66affSColin Finck ENUMRECTS* pERects = (ENUMRECTS*)pulEnumRects;
328*c2c66affSColin Finck
329*c2c66affSColin Finck // Calculate how many rectangles we should copy
330*c2c66affSColin Finck nCopy = min( Clip->EnumMax - Clip->EnumPos,
331*c2c66affSColin Finck min( Clip->RectCount - Clip->EnumPos,
332*c2c66affSColin Finck (cj - sizeof(ULONG)) / sizeof(RECTL)));
333*c2c66affSColin Finck
334*c2c66affSColin Finck if(nCopy == 0)
335*c2c66affSColin Finck {
336*c2c66affSColin Finck return FALSE;
337*c2c66affSColin Finck }
338*c2c66affSColin Finck
339*c2c66affSColin Finck /* Copy rectangles */
340*c2c66affSColin Finck src = &Clip->Rects[Clip->EnumPos];
341*c2c66affSColin Finck RtlCopyMemory(pERects->arcl, src, nCopy * sizeof(RECTL));
342*c2c66affSColin Finck
343*c2c66affSColin Finck pERects->c = nCopy;
344*c2c66affSColin Finck
345*c2c66affSColin Finck Clip->EnumPos+=nCopy;
346*c2c66affSColin Finck
347*c2c66affSColin Finck return Clip->EnumPos < Clip->RectCount;
348*c2c66affSColin Finck }
349*c2c66affSColin Finck
350*c2c66affSColin Finck /* EOF */
351