d3a97f251080f273745af7b411634b5c000ed5a8
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
42 if (r1
->top
< r2
->top
)
46 else if (r2
->top
< r1
->top
)
52 ASSERT(r1
->bottom
== r2
->bottom
);
53 if (r1
->left
< r2
->left
)
57 else if (r2
->left
< r1
->left
)
63 ASSERT(r1
->right
== r2
->right
);
78 if (r1
->bottom
< r2
->bottom
)
82 else if (r2
->bottom
< r1
->bottom
)
88 ASSERT(r1
->top
== r2
->top
);
89 if (r1
->left
< r2
->left
)
93 else if (r2
->left
< r1
->left
)
99 ASSERT(r1
->right
== r2
->right
);
114 if (r1
->top
< r2
->top
)
118 else if (r2
->top
< r1
->top
)
124 ASSERT(r1
->bottom
== r2
->bottom
);
125 if (r1
->right
< r2
->right
)
129 else if (r2
->right
< r1
->right
)
135 ASSERT(r1
->left
== r2
->left
);
150 if (r1
->bottom
< r2
->bottom
)
154 else if (r2
->bottom
< r1
->bottom
)
160 ASSERT(r1
->top
== r2
->top
);
161 if (r1
->right
< r2
->right
)
165 else if (r2
->right
< r1
->right
)
171 ASSERT(r1
->left
== r2
->left
);
185 if (Span1
->Y
< Span2
->Y
)
189 else if (Span2
->Y
< Span1
->Y
)
195 if (Span1
->X
< Span2
->X
)
199 else if (Span2
->X
< Span1
->X
)
213 IntEngDeleteClipRegion(CLIPOBJ
*ClipObj
)
215 EngFreeMem(ObjToGDI(ClipObj
, CLIP
));
219 IntEngCreateClipRegion(ULONG count
, PRECTL pRect
, PRECTL rcBounds
)
227 Clip
= EngAllocMem(0, sizeof(CLIPGDI
) + ((count
- 1) * sizeof(RECTL
)), TAG_CLIPOBJ
);
231 Clip
->EnumRects
.c
= count
;
232 Clip
->EnumOrder
= CD_ANY
;
233 for(dest
= Clip
->EnumRects
.arcl
;count
> 0; count
--, dest
++, pRect
++)
238 Clip
->ClipObj
.iDComplexity
= DC_COMPLEX
;
239 Clip
->ClipObj
.iFComplexity
= ((Clip
->EnumRects
.c
<= 4) ? FC_RECT4
: FC_COMPLEX
);
240 Clip
->ClipObj
.iMode
= TC_RECTANGLES
;
241 Clip
->ClipObj
.rclBounds
= *rcBounds
;
243 return GDIToObj(Clip
, CLIP
);
248 Clip
= EngAllocMem(0, sizeof(CLIPGDI
), TAG_CLIPOBJ
);
252 Clip
->EnumRects
.c
= 1;
253 Clip
->EnumOrder
= CD_ANY
;
254 Clip
->EnumRects
.arcl
[0] = *rcBounds
;
256 Clip
->ClipObj
.iDComplexity
= (((rcBounds
->top
== rcBounds
->bottom
) &&
257 (rcBounds
->left
== rcBounds
->right
))
258 ? DC_TRIVIAL
: DC_RECT
);
260 Clip
->ClipObj
.iFComplexity
= FC_RECT
;
261 Clip
->ClipObj
.iMode
= TC_RECTANGLES
;
262 Clip
->ClipObj
.rclBounds
= *rcBounds
;
264 return GDIToObj(Clip
, CLIP
);
277 CLIPGDI
*Clip
= EngAllocMem(FL_ZERO_MEMORY
, sizeof(CLIPGDI
), TAG_CLIPOBJ
);
280 return GDIToObj(Clip
, CLIP
);
290 EngDeleteClip(CLIPOBJ
*ClipRegion
)
292 EngFreeMem(ObjToGDI(ClipRegion
, CLIP
));
306 CLIPGDI
*ClipGDI
= ObjToGDI(ClipObj
, CLIP
);
307 SORTCOMP CompareFunc
;
309 ClipGDI
->EnumPos
= 0;
310 ClipGDI
->EnumMax
= (MaxRects
> 0) ? MaxRects
: ClipGDI
->EnumRects
.c
;
312 if (CD_ANY
!= BuildOrder
&& ClipGDI
->EnumOrder
!= BuildOrder
)
317 CompareFunc
= (SORTCOMP
) CompareRightDown
;
321 CompareFunc
= (SORTCOMP
) CompareRightUp
;
325 CompareFunc
= (SORTCOMP
) CompareLeftDown
;
329 CompareFunc
= (SORTCOMP
) CompareLeftUp
;
333 DPRINT1("Invalid BuildOrder %d\n", BuildOrder
);
334 BuildOrder
= ClipGDI
->EnumOrder
;
339 if (NULL
!= CompareFunc
)
341 EngSort((PBYTE
) ClipGDI
->EnumRects
.arcl
, sizeof(RECTL
), ClipGDI
->EnumRects
.c
, CompareFunc
);
344 ClipGDI
->EnumOrder
= BuildOrder
;
347 /* Return the number of rectangles enumerated */
348 if ((MaxRects
> 0) && (ClipGDI
->EnumRects
.c
> MaxRects
))
353 return ClipGDI
->EnumRects
.c
;
363 OUT ULONG
*EnumRects
)
366 CLIPGDI
*ClipGDI
= ObjToGDI(ClipObj
, CLIP
);
368 ENUMRECTS
* pERects
= (ENUMRECTS
*)EnumRects
;
370 //calculate how many rectangles we should copy
371 nCopy
= min( ClipGDI
->EnumMax
- ClipGDI
->EnumPos
,
372 min( ClipGDI
->EnumRects
.c
- ClipGDI
->EnumPos
,
373 (ObjSize
- sizeof(ULONG
)) / sizeof(RECTL
)));
380 /* copy rectangles */
381 src
= ClipGDI
->EnumRects
.arcl
+ ClipGDI
->EnumPos
;
382 for(i
= 0, dest
= pERects
->arcl
; i
< nCopy
; i
++, dest
++, src
++)
389 ClipGDI
->EnumPos
+=nCopy
;
391 return ClipGDI
->EnumPos
< ClipGDI
->EnumRects
.c
;
407 ASSERT(Boundary
->top
<= Boundary
->bottom
&& Boundary
->left
<= Boundary
->right
);
410 if (NULL
== ClipRegion
|| DC_TRIVIAL
== ClipRegion
->iDComplexity
)
412 *Count
= Boundary
->bottom
- Boundary
->top
;
415 *Spans
= ExAllocatePoolWithTag(PagedPool
, *Count
* sizeof(SPAN
), TAG_CLIP
);
421 for (i
= 0; i
< Boundary
->bottom
- Boundary
->top
; i
++)
423 (*Spans
)[i
].X
= Boundary
->left
;
424 (*Spans
)[i
].Y
= Boundary
->top
+ i
;
425 (*Spans
)[i
].Width
= Boundary
->right
- Boundary
->left
;
432 CLIPOBJ_cEnumStart(ClipRegion
, FALSE
, CT_RECTANGLES
, CD_ANY
, 0);
435 EnumMore
= CLIPOBJ_bEnum(ClipRegion
, (ULONG
) sizeof(RECT_ENUM
), (PVOID
) &RectEnum
);
438 for (i
= 0; i
< RectEnum
.c
; i
++)
440 NewCount
+= RectEnum
.arcl
[i
].bottom
- RectEnum
.arcl
[i
].top
;
442 if (NewCount
!= *Count
)
444 NewSpans
= ExAllocatePoolWithTag(PagedPool
, NewCount
* sizeof(SPAN
), TAG_CLIP
);
445 if (NULL
== NewSpans
)
449 ExFreePoolWithTag(*Spans
, TAG_CLIP
);
459 for(dest
= NewSpans
, src
= *Spans
;i
> 0; i
--)
463 ExFreePoolWithTag(*Spans
, TAG_CLIP
);
467 for (Rect
= RectEnum
.arcl
; Rect
< RectEnum
.arcl
+ RectEnum
.c
; Rect
++)
469 for (i
= 0; i
< Rect
->bottom
- Rect
->top
; i
++)
471 (*Spans
)[*Count
].X
= Rect
->left
;
472 (*Spans
)[*Count
].Y
= Rect
->top
+ i
;
473 (*Spans
)[*Count
].Width
= Rect
->right
- Rect
->left
;
477 ASSERT(*Count
== NewCount
);
483 EngSort((PBYTE
) *Spans
, sizeof(SPAN
), *Count
, (SORTCOMP
) CompareSpans
);