2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: ReactOS win32 subsystem
4 * PURPOSE: PATHOBJ service routines
5 * FILE: win32ss/gdi/eng/pathobj.c
6 * PROGRAMERS: Katayama Hirofumi MZ (katayama.hirofumi.mz@gmail.com)
9 /* INCLUDES *****************************************************************/
17 /* FUNCTIONS *****************************************************************/
19 /* FIXME: set last error */
20 /* FIXME: PATHOBJ_vEnumStartClipLines and PATHOBJ_bEnumClipLines */
30 const ULONG size
= sizeof(EPATHOBJ
);
32 PPATH pPath
= PATH_AllocPathWithHandle();
38 pPathObj
= ExAllocatePoolWithTag(PagedPool
, size
, GDITAG_PATHOBJ
);
43 RtlZeroMemory(pPathObj
, size
);
45 pPathObj
->pPath
= pPath
;
47 pPath
->flType
= PATHTYPE_KEEPME
;
48 pPath
->epo
= pPathObj
;
58 EngDeletePath(IN PATHOBJ
*ppo
)
61 PEXTPATHDATA ppd
, ppdNext
;
64 pPathObj
= (PEPATHOBJ
)ppo
;
65 if (pPathObj
== NULL
|| pPathObj
->pPath
== NULL
)
68 pPath
= pPathObj
->pPath
;
70 for (ppd
= pPath
->ppdFirst
; ppd
; ppd
= ppdNext
)
72 ppdNext
= ppd
->ppdNext
;
73 ExFreePoolWithTag(ppd
, GDITAG_PATHOBJ
);
75 ExFreePoolWithTag(pPathObj
, GDITAG_PATHOBJ
);
76 GDIOBJ_vDeleteObject(&pPath
->BaseObject
);
84 PATHOBJ_bCloseFigure(IN PATHOBJ
*ppo
)
87 PEPATHOBJ pPathObj
= (PEPATHOBJ
)ppo
;
88 if (pPathObj
== NULL
|| pPathObj
->pPath
== NULL
)
91 ppd
= pPathObj
->pPath
->ppdLast
;
95 ppd
->pd
.flags
|= PD_CLOSEFIGURE
| PD_ENDSUBPATH
;
104 PATHOBJ_vEnumStart(IN PATHOBJ
*ppo
)
106 PEPATHOBJ pPathObj
= (PEPATHOBJ
)ppo
;
107 if (pPathObj
== NULL
|| pPathObj
->pPath
== NULL
)
110 pPathObj
->pPath
->ppdCurrent
= pPathObj
->pPath
->ppdFirst
;
122 PEPATHOBJ pPathObj
= (PEPATHOBJ
)ppo
;
123 if (pPathObj
== NULL
|| pPathObj
->pPath
== NULL
|| pPathObj
->pPath
->ppdCurrent
== NULL
)
126 *ppd
= pPathObj
->pPath
->ppdCurrent
->pd
;
128 pPathObj
->pPath
->ppdCurrent
= pPathObj
->pPath
->ppdCurrent
->ppdNext
;
129 return (pPathObj
->pPath
->ppdCurrent
!= NULL
);
142 PEXTPATHDATA ppd
, ppdLast
;
144 pPathObj
= (PEPATHOBJ
)ppo
;
145 if (pPathObj
== NULL
|| pPathObj
->pPath
== NULL
)
148 /* allocate a subpath data */
149 ppd
= ExAllocatePoolWithTag(PagedPool
, sizeof(EXTPATHDATA
), GDITAG_PATHOBJ
);
153 RtlZeroMemory(ppd
, sizeof(EXTPATHDATA
));
155 /* add the first point to the subpath */
156 ppd
->pd
.flags
= PD_BEGINSUBPATH
;
158 ppd
->pd
.pptfx
= ExAllocatePoolWithTag(PagedPool
, sizeof(POINTFIX
), GDITAG_PATHOBJ
);
159 if (ppd
->pd
.pptfx
== NULL
)
161 ExFreePoolWithTag(ppd
, GDITAG_PATHOBJ
);
164 ppd
->pd
.pptfx
[0] = ptfx
;
166 ppdLast
= pPathObj
->pPath
->ppdLast
;
169 /* end the last subpath */
170 ppdLast
->pd
.flags
|= PD_ENDSUBPATH
;
172 /* add the subpath to the last */
173 ppdLast
->ppdNext
= ppd
;
174 pPathObj
->pPath
->ppdLast
= ppd
;
178 /* add the subpath */
179 pPathObj
->pPath
->ppdLast
= pPathObj
->pPath
->ppdFirst
= ppd
;
182 pPathObj
->po
.cCurves
++;
198 PEXTPATHDATA ppd
, ppdLast
;
199 PPOINTFIX pptfxNew
, pptfxOld
;
202 pPathObj
= (PEPATHOBJ
)ppo
;
203 if (pPathObj
== NULL
|| pPathObj
->pPath
== NULL
|| pptfx
== NULL
|| cptfx
== 0)
206 ppdLast
= pPathObj
->pPath
->ppdLast
;
209 /* allocate a subpath data */
210 ppd
= ExAllocatePoolWithTag(PagedPool
, sizeof(EXTPATHDATA
), GDITAG_PATHOBJ
);
215 RtlZeroMemory(ppd
, sizeof(EXTPATHDATA
));
216 ppd
->pd
.flags
= PD_BEGINSUBPATH
;
218 size
= cptfx
* sizeof(POINTFIX
);
219 pptfxNew
= ExAllocatePoolWithTag(PagedPool
, size
, GDITAG_PATHOBJ
);
220 if (pptfxNew
== NULL
)
222 ExFreePoolWithTag(ppd
, GDITAG_PATHOBJ
);
225 RtlCopyMemory(pptfxNew
, pptfx
, size
);
226 ppd
->pd
.pptfx
= pptfxNew
;
227 ppd
->pd
.count
= cptfx
;
229 /* set the subpath */
230 pPathObj
->pPath
->ppdLast
= pPathObj
->pPath
->ppdFirst
= ppd
;
232 pPathObj
->po
.cCurves
++;
234 else if (ppdLast
->pd
.flags
& (PD_BEZIERS
| PD_ENDSUBPATH
))
236 /* allocate a subpath data */
237 ppd
= ExAllocatePoolWithTag(PagedPool
, sizeof(EXTPATHDATA
), GDITAG_PATHOBJ
);
242 RtlZeroMemory(ppd
, sizeof(EXTPATHDATA
));
244 ppd
->pd
.count
= cptfx
;
246 size
= cptfx
* sizeof(POINTFIX
);
247 pptfxNew
= ExAllocatePoolWithTag(PagedPool
, size
, GDITAG_PATHOBJ
);
248 if (pptfxNew
== NULL
)
250 ExFreePoolWithTag(ppd
, GDITAG_PATHOBJ
);
253 RtlCopyMemory(pptfxNew
, pptfx
, size
);
254 ppd
->pd
.pptfx
= pptfxNew
;
257 ppdLast
->ppdNext
= ppd
;
258 pPathObj
->pPath
->ppdLast
= ppd
;
260 pPathObj
->po
.cCurves
++;
264 /* concatenate ppdLast->pd.pptfx and pptfx */
265 size
= (ppdLast
->pd
.count
+ cptfx
) * sizeof(POINTFIX
);
266 pptfxNew
= ExAllocatePoolWithTag(PagedPool
, size
, GDITAG_PATHOBJ
);
267 if (pptfxNew
== NULL
)
270 size
= ppdLast
->pd
.count
* sizeof(POINTFIX
);
271 RtlCopyMemory(&pptfxNew
[0], ppdLast
->pd
.pptfx
, size
);
272 size
= cptfx
* sizeof(POINTFIX
);
273 RtlCopyMemory(&pptfxNew
[ppdLast
->pd
.count
], pptfx
, size
);
275 pptfxOld
= ppdLast
->pd
.pptfx
;
276 ppdLast
->pd
.pptfx
= pptfxNew
;
277 ppdLast
->pd
.count
+= cptfx
;
278 ExFreePoolWithTag(pptfxOld
, GDITAG_PATHOBJ
);
289 PATHOBJ_bPolyBezierTo(
295 PEXTPATHDATA ppd
, ppdLast
;
296 PPOINTFIX pptfxNew
, pptfxOld
;
299 pPathObj
= (PEPATHOBJ
)ppo
;
300 if (pPathObj
== NULL
|| pPathObj
->pPath
== NULL
|| pptfx
== NULL
|| cptfx
== 0)
303 ppdLast
= pPathObj
->pPath
->ppdLast
;
306 /* allocate a subpath data */
307 ppd
= ExAllocatePoolWithTag(PagedPool
, sizeof(EXTPATHDATA
), GDITAG_PATHOBJ
);
312 RtlZeroMemory(ppd
, sizeof(EXTPATHDATA
));
313 ppd
->pd
.flags
= PD_BEGINSUBPATH
| PD_BEZIERS
;
315 size
= cptfx
* sizeof(POINTFIX
);
316 pptfxNew
= ExAllocatePoolWithTag(PagedPool
, size
, GDITAG_PATHOBJ
);
317 if (pptfxNew
== NULL
)
319 ExFreePoolWithTag(ppd
, GDITAG_PATHOBJ
);
322 RtlCopyMemory(pptfxNew
, pptfx
, size
);
323 ppd
->pd
.pptfx
= pptfxNew
;
324 ppd
->pd
.count
= cptfx
;
326 /* set the subpath */
327 pPathObj
->pPath
->ppdLast
= pPathObj
->pPath
->ppdFirst
= ppd
;
329 pPathObj
->po
.cCurves
++;
331 else if (!(ppdLast
->pd
.flags
& PD_BEZIERS
) || (ppdLast
->pd
.flags
& PD_ENDSUBPATH
))
333 /* allocate a subpath data */
334 ppd
= ExAllocatePoolWithTag(PagedPool
, sizeof(EXTPATHDATA
), GDITAG_PATHOBJ
);
339 RtlZeroMemory(ppd
, sizeof(EXTPATHDATA
));
340 ppd
->pd
.flags
= PD_BEZIERS
;
341 ppd
->pd
.count
= cptfx
;
343 size
= cptfx
* sizeof(POINTFIX
);
344 pptfxNew
= ExAllocatePoolWithTag(PagedPool
, size
, GDITAG_PATHOBJ
);
345 if (pptfxNew
== NULL
)
347 ExFreePoolWithTag(ppd
, GDITAG_PATHOBJ
);
350 RtlCopyMemory(pptfxNew
, pptfx
, size
);
351 ppd
->pd
.pptfx
= pptfxNew
;
354 ppdLast
->ppdNext
= ppd
;
355 pPathObj
->pPath
->ppdLast
= ppd
;
357 pPathObj
->po
.cCurves
++;
361 /* concatenate ppdLast->pd.pptfx and pptfx */
362 size
= (ppdLast
->pd
.count
+ cptfx
) * sizeof(POINTFIX
);
363 pptfxNew
= ExAllocatePoolWithTag(PagedPool
, size
, GDITAG_PATHOBJ
);
364 if (pptfxNew
== NULL
)
367 size
= ppdLast
->pd
.count
* sizeof(POINTFIX
);
368 RtlCopyMemory(&pptfxNew
[0], ppdLast
->pd
.pptfx
, size
);
369 size
= cptfx
* sizeof(POINTFIX
);
370 RtlCopyMemory(&pptfxNew
[ppdLast
->pd
.count
], pptfx
, size
);
372 pptfxOld
= ppdLast
->pd
.pptfx
;
373 ppdLast
->pd
.pptfx
= pptfxNew
;
374 ppdLast
->pd
.count
+= cptfx
;
375 ExFreePoolWithTag(pptfxOld
, GDITAG_PATHOBJ
);
378 pPathObj
->po
.fl
|= PO_BEZIERS
;
385 PATHOBJ_vEnumStartClipLines(
396 PATHOBJ_bEnumClipLines(
414 FIX xLeft
, yTop
, xRight
, yBottom
;
416 PEXTPATHDATA ppd
, ppdNext
;
419 pPathObj
= (PEPATHOBJ
)ppo
;
420 if (pPathObj
== NULL
|| pPathObj
->pPath
== NULL
|| prectfx
== NULL
)
423 yTop
= xLeft
= MAXLONG
;
424 yBottom
= xRight
= MINLONG
;
426 for (ppd
= pPathObj
->pPath
->ppdFirst
; ppd
; ppd
= ppdNext
)
428 ppdNext
= ppd
->ppdNext
;
429 for (i
= 0; i
< ppd
->pd
.count
; ++i
)
431 PPOINTFIX pptfx
= &ppd
->pd
.pptfx
[i
];
432 if (pptfx
->x
< xLeft
)
434 if (pptfx
->x
> xRight
)
438 if (pptfx
->y
> yBottom
)
443 if (xLeft
<= xRight
&& yTop
<= yBottom
)
445 prectfx
->xLeft
= xLeft
;
446 prectfx
->yTop
= yTop
;
447 prectfx
->xRight
= xRight
+ 1;
448 prectfx
->yBottom
= yBottom
+ 1;
452 RtlZeroMemory(prectfx
, sizeof(*prectfx
));