2 * ReactOS W32 Subsystem
3 * Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003 ReactOS Team
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21 * COPYRIGHT: See COPYING in the top level directory
22 * PROJECT: ReactOS kernel
23 * PURPOSE: GDI Clipping Functions
24 * FILE: subsys/win32k/eng/clip.c
25 * PROGRAMER: Jason Filby
30 #include <ddk/winddi.h>
31 #include <ddk/ntddk.h>
34 #include <include/object.h>
37 #include <win32k/debug1.h>
39 VOID STDCALL IntEngDeleteClipRegion(CLIPOBJ *ClipObj)
41 HCLIP HClip = AccessHandleFromUserObject(ClipObj);
46 IntEngCreateClipRegion(ULONG count, PRECTL pRect, RECTL rcBounds)
52 DPRINT("IntEngCreateClipRegion count: %d\n", count);
55 hClip = (HCLIP) CreateGDIHandle(sizeof(CLIPGDI) + count * sizeof(RECTL),
60 clipInt = (CLIPGDI *) AccessInternalObject(hClip);
61 RtlCopyMemory(clipInt->EnumRects.arcl, pRect, count * sizeof(RECTL));
62 clipInt->EnumRects.c = count;
63 clipInt->EnumOrder = CD_ANY;
65 clipUser = (CLIPOBJ *) AccessUserObject(hClip);
66 ASSERT(NULL != clipUser);
68 clipUser->iDComplexity = DC_COMPLEX;
69 clipUser->iFComplexity = (count <= 4) ? FC_RECT4: FC_COMPLEX;
70 clipUser->iMode = TC_RECTANGLES;
71 RtlCopyMemory(&(clipUser->rclBounds), &rcBounds, sizeof(RECTL));
78 hClip = (HCLIP) CreateGDIHandle(sizeof(CLIPGDI),
82 clipInt = (CLIPGDI *) AccessInternalObject(hClip);
83 RtlCopyMemory(clipInt->EnumRects.arcl, &rcBounds, sizeof(RECTL));
84 clipInt->EnumRects.c = 1;
85 clipInt->EnumOrder = CD_ANY;
87 clipUser = (CLIPOBJ *) AccessUserObject(hClip);
88 ASSERT(NULL != clipUser);
90 clipUser->iDComplexity = ((rcBounds.top==rcBounds.bottom)
91 && (rcBounds.left==rcBounds.right))
92 ? DC_TRIVIAL : DC_RECT;
93 clipUser->iFComplexity = FC_RECT;
94 clipUser->iMode = TC_RECTANGLES;
95 DPRINT("IntEngCreateClipRegion: iDComplexity: %d\n", clipUser->iDComplexity);
96 RtlCopyMemory(&(clipUser->rclBounds), &rcBounds, sizeof(RECTL));
110 return EngAllocMem(FL_ZERO_MEMORY, sizeof(CLIPOBJ), 0);
117 EngDeleteClip(CLIPOBJ *ClipRegion)
119 EngFreeMem(ClipRegion);
123 CompareRightDown(const PRECT r1, const PRECT r2)
127 if (r1->top < r2->top)
131 else if (r2->top < r1->top)
137 ASSERT(r1->bottom == r2->bottom);
138 if (r1->left < r2->left)
142 else if (r2->left < r1->left)
148 ASSERT(r1->right == r2->right);
157 CompareRightUp(const PRECT r1, const PRECT r2)
161 if (r1->bottom < r2->bottom)
165 else if (r2->bottom < r1->bottom)
171 ASSERT(r1->top == r2->top);
172 if (r1->left < r2->left)
176 else if (r2->left < r1->left)
182 ASSERT(r1->right == r2->right);
191 CompareLeftDown(const PRECT r1, const PRECT r2)
195 if (r1->top < r2->top)
199 else if (r2->top < r1->top)
205 ASSERT(r1->bottom == r2->bottom);
206 if (r1->right < r2->right)
210 else if (r2->right < r1->right)
216 ASSERT(r1->left == r2->left);
225 CompareLeftUp(const PRECT r1, const PRECT r2)
229 if (r1->bottom < r2->bottom)
233 else if (r2->bottom < r1->bottom)
239 ASSERT(r1->top == r2->top);
240 if (r1->right < r2->right)
244 else if (r2->right < r1->right)
250 ASSERT(r1->left == r2->left);
262 CLIPOBJ_cEnumStart(IN PCLIPOBJ ClipObj,
268 CLIPGDI *ClipGDI = (CLIPGDI*)AccessInternalObjectFromUserObject(ClipObj);
269 SORTCOMP CompareFunc;
271 ClipGDI->EnumPos = 0;
272 ClipGDI->EnumMax = (MaxRects > 0) ? MaxRects : ClipGDI->EnumRects.c;
274 if (CD_ANY != BuildOrder && ClipGDI->EnumOrder != BuildOrder)
279 CompareFunc = (SORTCOMP) CompareRightDown;
282 CompareFunc = (SORTCOMP) CompareRightUp;
285 CompareFunc = (SORTCOMP) CompareLeftDown;
288 CompareFunc = (SORTCOMP) CompareLeftUp;
291 DPRINT1("Invalid BuildOrder %d\n", BuildOrder);
292 BuildOrder = ClipGDI->EnumOrder;
297 if (NULL != CompareFunc)
299 EngSort((PBYTE) ClipGDI->EnumRects.arcl, sizeof(RECTL), ClipGDI->EnumRects.c,
303 ClipGDI->EnumOrder = BuildOrder;
306 /* Return the number of rectangles enumerated */
307 if ((MaxRects > 0) && (ClipGDI->EnumRects.c > MaxRects))
312 return ClipGDI->EnumRects.c;
319 CLIPOBJ_bEnum(IN PCLIPOBJ ClipObj,
321 OUT ULONG *EnumRects)
323 CLIPGDI *ClipGDI = (CLIPGDI*)AccessInternalObjectFromUserObject(ClipObj);
325 PENUMRECTS pERects = (PENUMRECTS)EnumRects;
327 //calculate how many rectangles we should copy
328 nCopy = MIN( ClipGDI->EnumMax - ClipGDI->EnumPos,
329 MIN( ClipGDI->EnumRects.c - ClipGDI->EnumPos,
330 (ObjSize - sizeof(ULONG)) / sizeof(RECTL)));
332 RtlCopyMemory( pERects->arcl, ClipGDI->EnumRects.arcl + ClipGDI->EnumPos,
333 nCopy * sizeof(RECTL) );
336 ClipGDI->EnumPos+=nCopy;
338 return ClipGDI->EnumPos < ClipGDI->EnumRects.c;