ReactOS  0.4.11-dev-195-gef016bf
clip.c
Go to the documentation of this file.
1 /*
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
7  */
8 
9 #include <win32k.h>
10 DBG_DEFAULT_CHANNEL(EngClip);
11 
12 
13 static __inline int
15  const RECTL *r1,
16  const RECTL *r2)
17 {
18  int Cmp;
19 
20  if (r1->top < r2->top)
21  {
22  Cmp = -1;
23  }
24  else if (r2->top < r1->top)
25  {
26  Cmp = +1;
27  }
28  else
29  {
30  ASSERT(r1->bottom == r2->bottom);
31  if (r1->left < r2->left)
32  {
33  Cmp = -1;
34  }
35  else if (r2->left < r1->left)
36  {
37  Cmp = +1;
38  }
39  else
40  {
41  ASSERT(r1->right == r2->right);
42  Cmp = 0;
43  }
44  }
45 
46  return Cmp;
47 }
48 
49 static __inline int
51  const RECTL *r1,
52  const RECTL *r2)
53 {
54  int Cmp;
55 
56  if (r1->bottom < r2->bottom)
57  {
58  Cmp = +1;
59  }
60  else if (r2->bottom < r1->bottom)
61  {
62  Cmp = -1;
63  }
64  else
65  {
66  ASSERT(r1->top == r2->top);
67  if (r1->left < r2->left)
68  {
69  Cmp = -1;
70  }
71  else if (r2->left < r1->left)
72  {
73  Cmp = +1;
74  }
75  else
76  {
77  ASSERT(r1->right == r2->right);
78  Cmp = 0;
79  }
80  }
81 
82  return Cmp;
83 }
84 
85 static __inline int
87  const RECTL *r1,
88  const RECTL *r2)
89 {
90  int Cmp;
91 
92  if (r1->top < r2->top)
93  {
94  Cmp = -1;
95  }
96  else if (r2->top < r1->top)
97  {
98  Cmp = +1;
99  }
100  else
101  {
102  ASSERT(r1->bottom == r2->bottom);
103  if (r1->right < r2->right)
104  {
105  Cmp = +1;
106  }
107  else if (r2->right < r1->right)
108  {
109  Cmp = -1;
110  }
111  else
112  {
113  ASSERT(r1->left == r2->left);
114  Cmp = 0;
115  }
116  }
117 
118  return Cmp;
119 }
120 
121 static __inline int
123  const RECTL *r1,
124  const RECTL *r2)
125 {
126  int Cmp;
127 
128  if (r1->bottom < r2->bottom)
129  {
130  Cmp = +1;
131  }
132  else if (r2->bottom < r1->bottom)
133  {
134  Cmp = -1;
135  }
136  else
137  {
138  ASSERT(r1->top == r2->top);
139  if (r1->right < r2->right)
140  {
141  Cmp = +1;
142  }
143  else if (r2->right < r1->right)
144  {
145  Cmp = -1;
146  }
147  else
148  {
149  ASSERT(r1->left == r2->left);
150  Cmp = 0;
151  }
152  }
153  return Cmp;
154 }
155 
156 VOID
157 FASTCALL
159 {
160  Clip->Rects = &Clip->rclBounds;
161 }
162 
165 {
166  if (Clip->Rects != &Clip->rclBounds)
167  EngFreeMem(Clip->Rects);
168 }
169 
170 
171 VOID
172 FASTCALL
174  XCLIPOBJ* Clip,
175  ULONG count,
176  const RECTL* pRect,
177  const RECTL* rcBounds)
178 {
179  if(count > 1)
180  {
181  RECTL* NewRects = EngAllocMem(0, FIELD_OFFSET(ENUMRECTS, arcl[count]), GDITAG_CLIPOBJ);
182 
183  if(NewRects != NULL)
184  {
185  Clip->RectCount = count;
186  Clip->iDirection = CD_ANY;
187  RtlCopyMemory(NewRects, pRect, count * sizeof(RECTL));
188 
189  Clip->iDComplexity = DC_COMPLEX;
190  Clip->iFComplexity = ((Clip->RectCount <= 4) ? FC_RECT4 : FC_COMPLEX);
191  Clip->iMode = TC_RECTANGLES;
192  Clip->rclBounds = *rcBounds;
193 
194  if (Clip->Rects != &Clip->rclBounds)
195  EngFreeMem(Clip->Rects);
196  Clip->Rects = NewRects;
197  }
198  }
199  else
200  {
201  Clip->iDirection = CD_ANY;
202 
203  Clip->iDComplexity = (((rcBounds->top == rcBounds->bottom) &&
204  (rcBounds->left == rcBounds->right))
205  ? DC_TRIVIAL : DC_RECT);
206 
207  Clip->iFComplexity = FC_RECT;
208  Clip->iMode = TC_RECTANGLES;
209  Clip->rclBounds = *rcBounds;
210  Clip->RectCount = 1;
211  if (Clip->Rects != &Clip->rclBounds)
212  EngFreeMem(Clip->Rects);
213  Clip->Rects = &Clip->rclBounds;
214  }
215 }
216 
217 /*
218  * @implemented
219  */
220 CLIPOBJ *
221 APIENTRY
223 {
225  if(Clip != NULL)
226  {
227  IntEngInitClipObj(Clip);
228  TRACE("Created Clip Obj %p.\n", Clip);
229  return (CLIPOBJ *)Clip;
230  }
231 
232  ERR("Clip object allocation failed!\n");
233  return NULL;
234 }
235 
236 /*
237  * @implemented
238  */
239 VOID
240 APIENTRY
243 {
244  XCLIPOBJ* pxco = (XCLIPOBJ *)pco;
245  TRACE("Deleting %p.\n", pco);
247  EngFreeMem(pxco);
248 }
249 
250 /*
251  * @implemented
252  */
253 ULONG
254 APIENTRY
257  _In_ BOOL bAll,
258  _In_ ULONG iType,
259  _In_ ULONG iDirection,
260  _In_ ULONG cMaxRects)
261 {
262  XCLIPOBJ* Clip = (XCLIPOBJ *)pco;
263  SORTCOMP CompareFunc;
264 
265  Clip->bAll = bAll;
266  Clip->iType = iType;
267  Clip->EnumPos = 0;
268  Clip->EnumMax = (cMaxRects > 0) ? cMaxRects : Clip->RectCount;
269 
270  if (CD_ANY != iDirection && Clip->iDirection != iDirection)
271  {
272  switch (iDirection)
273  {
274  case CD_RIGHTDOWN:
275  CompareFunc = (SORTCOMP) CompareRightDown;
276  break;
277 
278  case CD_RIGHTUP:
279  CompareFunc = (SORTCOMP) CompareRightUp;
280  break;
281 
282  case CD_LEFTDOWN:
283  CompareFunc = (SORTCOMP) CompareLeftDown;
284  break;
285 
286  case CD_LEFTUP:
287  CompareFunc = (SORTCOMP) CompareLeftUp;
288  break;
289 
290  default:
291  ERR("Invalid iDirection %lu\n", iDirection);
292  iDirection = Clip->iDirection;
293  CompareFunc = NULL;
294  break;
295  }
296 
297  if (NULL != CompareFunc)
298  {
299  EngSort((PBYTE) Clip->Rects, sizeof(RECTL), Clip->RectCount, CompareFunc);
300  }
301 
302  Clip->iDirection = iDirection;
303  }
304 
305  /* Return the number of rectangles enumerated */
306  if ((cMaxRects > 0) && (Clip->RectCount > cMaxRects))
307  {
308  return 0xFFFFFFFF;
309  }
310 
311  return Clip->RectCount;
312 }
313 
314 /*
315  * @implemented
316  */
317 BOOL
318 APIENTRY
320  _In_ CLIPOBJ *pco,
321  _In_ ULONG cj,
322  _Out_bytecap_(cj) ULONG *pulEnumRects)
323 {
324  const RECTL* src;
325  XCLIPOBJ* Clip = (XCLIPOBJ *)pco;
326  ULONG nCopy;
327  ENUMRECTS* pERects = (ENUMRECTS*)pulEnumRects;
328 
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)));
333 
334  if(nCopy == 0)
335  {
336  return FALSE;
337  }
338 
339  /* Copy rectangles */
340  src = &Clip->Rects[Clip->EnumPos];
341  RtlCopyMemory(pERects->arcl, src, nCopy * sizeof(RECTL));
342 
343  pERects->c = nCopy;
344 
345  Clip->EnumPos+=nCopy;
346 
347  return Clip->EnumPos < Clip->RectCount;
348 }
349 
350 /* EOF */
#define FC_RECT4
Definition: winddi.h:265
NTSYSAPI VOID NTAPI RtlCopyMemory(VOID UNALIGNED *Destination, CONST VOID UNALIGNED *Source, ULONG Length)
VOID FASTCALL IntEngInitClipObj(XCLIPOBJ *Clip)
Definition: clip.c:158
_In_ ULONG cj
Definition: winddi.h:3540
static __inline int CompareRightDown(const RECTL *r1, const RECTL *r2)
Definition: clip.c:14
ULONG APIENTRY CLIPOBJ_cEnumStart(_Inout_ CLIPOBJ *pco, _In_ BOOL bAll, _In_ ULONG iType, _In_ ULONG iDirection, _In_ ULONG cMaxRects)
Definition: clip.c:255
static __inline int CompareLeftDown(const RECTL *r1, const RECTL *r2)
Definition: clip.c:86
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel)?(CompletionRoutine!=NULL):TRUE)
ULONG iDirection
Definition: engobjects.h:68
#define EngFreeMem
Definition: polytest.cpp:56
_In_ ULONG iType
Definition: winddi.h:3748
#define TC_RECTANGLES
Definition: winddi.h:269
#define DC_TRIVIAL
Definition: winddi.h:259
static DNS_RECORDW r1
Definition: record.c:37
long bottom
Definition: polytest.cpp:53
DBG_DEFAULT_CHANNEL(EngClip)
ULONG c
Definition: winddi.h:576
#define FC_COMPLEX
Definition: winddi.h:266
#define FASTCALL
Definition: nt_native.h:50
GLuint const GLubyte GLvoid * src
Definition: s_context.h:57
long right
Definition: polytest.cpp:53
VOID FASTCALL IntEngFreeClipResources(XCLIPOBJ *Clip)
Definition: clip.c:164
RECTL arcl[1]
Definition: winddi.h:577
#define FALSE
Definition: types.h:117
#define CD_RIGHTDOWN
Definition: winddi.h:1320
long top
Definition: polytest.cpp:53
CLIPOBJ *APIENTRY EngCreateClip(VOID)
Definition: clip.c:222
#define APIENTRY
Definition: nt_native.h:48
smooth NULL
Definition: ftsmooth.c:416
long left
Definition: polytest.cpp:53
ULONG EnumMax
Definition: engobjects.h:67
#define DC_RECT
Definition: winddi.h:260
#define TRACE(s)
Definition: solgame.cpp:4
unsigned int BOOL
Definition: ntddk_ex.h:94
#define CD_RIGHTUP
Definition: winddi.h:1323
if(!(yy_init))
Definition: macro.lex.yy.c:717
ULONG EnumPos
Definition: engobjects.h:65
static DNS_RECORDW r2
Definition: record.c:38
static __inline int CompareLeftUp(const RECTL *r1, const RECTL *r2)
Definition: clip.c:122
BOOL bAll
Definition: engobjects.h:73
GLuint GLuint GLsizei count
Definition: gl.h:1545
ENGAPI VOID APIENTRY EngSort(_Inout_updates_bytes_(c *cjElem) PBYTE pjBuf, _In_ ULONG c, _In_ ULONG cjElem, _In_ SORTCOMP pfnComp)
#define _Inout_
Definition: no_sal2.h:244
void * EngAllocMem(int zero, unsigned long size, int tag=0)
Definition: polytest.cpp:70
#define CD_LEFTDOWN
Definition: winddi.h:1321
#define FL_ZERO_MEMORY
Definition: polytest.cpp:58
_In_ SURFOBJ _In_ CLIPOBJ * pco
Definition: winddi.h:3414
#define CD_LEFTUP
Definition: winddi.h:1325
VOID APIENTRY EngDeleteClip(_In_ _Post_ptr_invalid_ CLIPOBJ *pco)
Definition: clip.c:241
#define ERR(fmt,...)
Definition: debug.h:109
#define _In_
Definition: no_sal2.h:204
#define DC_COMPLEX
Definition: winddi.h:261
DWORD RectCount
Definition: engobjects.h:75
#define _Post_ptr_invalid_
Definition: no_sal2.h:462
static __inline int CompareRightUp(const RECTL *r1, const RECTL *r2)
Definition: clip.c:50
#define FC_RECT
Definition: winddi.h:264
#define GDITAG_CLIPOBJ
Definition: tags.h:77
RECTL * Rects
Definition: engobjects.h:62
BOOL APIENTRY CLIPOBJ_bEnum(_In_ CLIPOBJ *pco, _In_ ULONG cj, _Out_bytecap_(cj) ULONG *pulEnumRects)
Definition: clip.c:319
static INT CALLBACK CompareFunc(LPARAM lParam1, LPARAM lParam2, LPARAM lParamSort)
Definition: mainwnd.c:242
#define FIELD_OFFSET(t, f)
Definition: typedefs.h:254
#define min(a, b)
Definition: monoChain.cc:55
#define _Out_bytecap_(size)
Definition: no_sal2.h:325
VOID FASTCALL IntEngUpdateClipRegion(XCLIPOBJ *Clip, ULONG count, const RECTL *pRect, const RECTL *rcBounds)
Definition: clip.c:173
unsigned int ULONG
Definition: retypes.h:1
BYTE * PBYTE
Definition: pedump.c:66
ULONG iType
Definition: engobjects.h:69
#define CD_ANY
Definition: winddi.h:1326