72f27c2079bcdad52d5c4d9a2157ef4fb89b9517
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 /* TYPES *********************************************************************/
19 /* extended PATHDATA */
20 typedef struct _EXTPATHDATA
23 struct _EXTPATHDATA
*ppdNext
;
24 } EXTPATHDATA
, *PEXTPATHDATA
;
26 /* extended PATHOBJ */
27 typedef struct _EXTPATHOBJ
30 PEXTPATHDATA ppdFirst
;
32 PEXTPATHDATA ppdCurrent
;
33 } EXTPATHOBJ
, *PEXTPATHOBJ
;
35 /* FUNCTIONS *****************************************************************/
37 /* FIXME: set last error */
38 /* FIXME: PATHOBJ_vEnumStartClipLines and PATHOBJ_bEnumClipLines */
48 const ULONG size
= sizeof(EXTPATHOBJ
);
50 pPathObj
= ExAllocatePoolWithTag(PagedPool
, size
, GDITAG_PATHOBJ
);
56 RtlZeroMemory(pPathObj
, size
);
65 EngDeletePath(IN PATHOBJ
*ppo
)
68 PEXTPATHDATA ppd
, ppdNext
;
70 pPathObj
= (PEXTPATHOBJ
)ppo
;
74 for (ppd
= pPathObj
->ppdFirst
; ppd
; ppd
= ppdNext
)
76 ppdNext
= ppd
->ppdNext
;
77 ExFreePoolWithTag(ppd
, GDITAG_PATHOBJ
);
79 ExFreePoolWithTag(pPathObj
, GDITAG_PATHOBJ
);
87 PATHOBJ_bCloseFigure(IN PATHOBJ
*ppo
)
90 PEXTPATHOBJ pPathObj
= (PEXTPATHOBJ
)ppo
;
94 ppd
= pPathObj
->ppdLast
;
98 ppd
->pd
.flags
|= PD_CLOSEFIGURE
| PD_ENDSUBPATH
;
107 PATHOBJ_vEnumStart(IN PATHOBJ
*ppo
)
109 PEXTPATHOBJ pPathObj
= (PEXTPATHOBJ
)ppo
;
110 if (pPathObj
== NULL
)
113 pPathObj
->ppdCurrent
= pPathObj
->ppdFirst
;
125 PEXTPATHOBJ pPathObj
= (PEXTPATHOBJ
)ppo
;
126 if (pPathObj
== NULL
|| pPathObj
->ppdCurrent
== NULL
)
129 *ppd
= pPathObj
->ppdCurrent
->pd
;
131 pPathObj
->ppdCurrent
= pPathObj
->ppdCurrent
->ppdNext
;
132 return (pPathObj
->ppdCurrent
!= NULL
);
144 PEXTPATHOBJ pPathObj
;
145 PEXTPATHDATA ppd
, ppdLast
;
147 pPathObj
= (PEXTPATHOBJ
)ppo
;
148 if (pPathObj
== NULL
)
151 /* allocate a subpath data */
152 ppd
= ExAllocatePoolWithTag(PagedPool
, sizeof(EXTPATHDATA
), GDITAG_PATHOBJ
);
156 RtlZeroMemory(ppd
, sizeof(EXTPATHDATA
));
158 /* add the first point to the subpath */
159 ppd
->pd
.flags
= PD_BEGINSUBPATH
;
161 ppd
->pd
.pptfx
= ExAllocatePoolWithTag(PagedPool
, sizeof(POINTFIX
), GDITAG_PATHOBJ
);
162 if (ppd
->pd
.pptfx
== NULL
)
164 ExFreePoolWithTag(ppd
, GDITAG_PATHOBJ
);
167 ppd
->pd
.pptfx
[0] = ptfx
;
169 ppdLast
= pPathObj
->ppdLast
;
172 /* end the last subpath */
173 ppdLast
->pd
.flags
|= PD_ENDSUBPATH
;
175 /* add the subpath to the last */
176 ppdLast
->ppdNext
= ppd
;
177 pPathObj
->ppdLast
= ppd
;
181 /* add the subpath */
182 pPathObj
->ppdLast
= pPathObj
->ppdFirst
= ppd
;
185 pPathObj
->po
.cCurves
++;
200 PEXTPATHOBJ pPathObj
;
201 PEXTPATHDATA ppd
, ppdLast
;
202 PPOINTFIX pptfxNew
, pptfxOld
;
205 pPathObj
= (PEXTPATHOBJ
)ppo
;
206 if (pPathObj
== NULL
|| pptfx
== NULL
|| cptfx
== 0)
209 ppdLast
= pPathObj
->ppdLast
;
212 /* allocate a subpath data */
213 ppd
= ExAllocatePoolWithTag(PagedPool
, sizeof(EXTPATHDATA
), GDITAG_PATHOBJ
);
218 RtlZeroMemory(ppd
, sizeof(EXTPATHDATA
));
219 ppd
->pd
.flags
= PD_BEGINSUBPATH
;
221 size
= cptfx
* sizeof(POINTFIX
);
222 pptfxNew
= ExAllocatePoolWithTag(PagedPool
, size
, GDITAG_PATHOBJ
);
223 if (pptfxNew
== NULL
)
225 ExFreePoolWithTag(ppd
, GDITAG_PATHOBJ
);
228 RtlCopyMemory(pptfxNew
, pptfx
, size
);
229 ppd
->pd
.pptfx
= pptfxNew
;
230 ppd
->pd
.count
= cptfx
;
232 /* set the subpath */
233 pPathObj
->ppdLast
= pPathObj
->ppdFirst
= ppd
;
235 pPathObj
->po
.cCurves
++;
237 else if (ppdLast
->pd
.flags
& (PD_BEZIERS
| PD_ENDSUBPATH
))
239 /* allocate a subpath data */
240 ppd
= ExAllocatePoolWithTag(PagedPool
, sizeof(EXTPATHDATA
), GDITAG_PATHOBJ
);
245 RtlZeroMemory(ppd
, sizeof(EXTPATHDATA
));
247 ppd
->pd
.count
= cptfx
;
249 size
= cptfx
* sizeof(POINTFIX
);
250 pptfxNew
= ExAllocatePoolWithTag(PagedPool
, size
, GDITAG_PATHOBJ
);
251 if (pptfxNew
== NULL
)
253 ExFreePoolWithTag(ppd
, GDITAG_PATHOBJ
);
256 RtlCopyMemory(pptfxNew
, pptfx
, size
);
257 ppd
->pd
.pptfx
= pptfxNew
;
260 ppdLast
->ppdNext
= ppd
;
261 pPathObj
->ppdLast
= ppd
;
263 pPathObj
->po
.cCurves
++;
267 /* concatenate ppdLast->pd.pptfx and pptfx */
268 size
= (ppdLast
->pd
.count
+ cptfx
) * sizeof(POINTFIX
);
269 pptfxNew
= ExAllocatePoolWithTag(PagedPool
, size
, GDITAG_PATHOBJ
);
270 if (pptfxNew
== NULL
)
273 size
= ppdLast
->pd
.count
* sizeof(POINTFIX
);
274 RtlCopyMemory(&pptfxNew
[0], ppdLast
->pd
.pptfx
, size
);
275 size
= cptfx
* sizeof(POINTFIX
);
276 RtlCopyMemory(&pptfxNew
[ppdLast
->pd
.count
], pptfx
, size
);
278 pptfxOld
= ppdLast
->pd
.pptfx
;
279 ppdLast
->pd
.pptfx
= pptfxNew
;
280 ppdLast
->pd
.count
+= cptfx
;
281 ExFreePoolWithTag(pptfxOld
, GDITAG_PATHOBJ
);
292 PATHOBJ_bPolyBezierTo(
297 PEXTPATHOBJ pPathObj
;
298 PEXTPATHDATA ppd
, ppdLast
;
299 PPOINTFIX pptfxNew
, pptfxOld
;
302 pPathObj
= (PEXTPATHOBJ
)ppo
;
303 if (pPathObj
== NULL
|| pptfx
== NULL
|| cptfx
== 0)
306 ppdLast
= pPathObj
->ppdLast
;
309 /* allocate a subpath data */
310 ppd
= ExAllocatePoolWithTag(PagedPool
, sizeof(EXTPATHDATA
), GDITAG_PATHOBJ
);
315 RtlZeroMemory(ppd
, sizeof(EXTPATHDATA
));
316 ppd
->pd
.flags
= PD_BEGINSUBPATH
| PD_BEZIERS
;
318 size
= cptfx
* sizeof(POINTFIX
);
319 pptfxNew
= ExAllocatePoolWithTag(PagedPool
, size
, GDITAG_PATHOBJ
);
320 if (pptfxNew
== NULL
)
322 ExFreePoolWithTag(ppd
, GDITAG_PATHOBJ
);
325 RtlCopyMemory(pptfxNew
, pptfx
, size
);
326 ppd
->pd
.pptfx
= pptfxNew
;
327 ppd
->pd
.count
= cptfx
;
329 /* set the subpath */
330 pPathObj
->ppdLast
= pPathObj
->ppdFirst
= ppd
;
332 pPathObj
->po
.cCurves
++;
334 else if (!(ppdLast
->pd
.flags
& PD_BEZIERS
) || (ppdLast
->pd
.flags
& PD_ENDSUBPATH
))
336 /* allocate a subpath data */
337 ppd
= ExAllocatePoolWithTag(PagedPool
, sizeof(EXTPATHDATA
), GDITAG_PATHOBJ
);
342 RtlZeroMemory(ppd
, sizeof(EXTPATHDATA
));
343 ppd
->pd
.flags
= PD_BEZIERS
;
344 ppd
->pd
.count
= cptfx
;
346 size
= cptfx
* sizeof(POINTFIX
);
347 pptfxNew
= ExAllocatePoolWithTag(PagedPool
, size
, GDITAG_PATHOBJ
);
348 if (pptfxNew
== NULL
)
350 ExFreePoolWithTag(ppd
, GDITAG_PATHOBJ
);
353 RtlCopyMemory(pptfxNew
, pptfx
, size
);
354 ppd
->pd
.pptfx
= pptfxNew
;
357 ppdLast
->ppdNext
= ppd
;
358 pPathObj
->ppdLast
= ppd
;
360 pPathObj
->po
.cCurves
++;
364 /* concatenate ppdLast->pd.pptfx and pptfx */
365 size
= (ppdLast
->pd
.count
+ cptfx
) * sizeof(POINTFIX
);
366 pptfxNew
= ExAllocatePoolWithTag(PagedPool
, size
, GDITAG_PATHOBJ
);
367 if (pptfxNew
== NULL
)
370 size
= ppdLast
->pd
.count
* sizeof(POINTFIX
);
371 RtlCopyMemory(&pptfxNew
[0], ppdLast
->pd
.pptfx
, size
);
372 size
= cptfx
* sizeof(POINTFIX
);
373 RtlCopyMemory(&pptfxNew
[ppdLast
->pd
.count
], pptfx
, size
);
375 pptfxOld
= ppdLast
->pd
.pptfx
;
376 ppdLast
->pd
.pptfx
= pptfxNew
;
377 ppdLast
->pd
.count
+= cptfx
;
378 ExFreePoolWithTag(pptfxOld
, GDITAG_PATHOBJ
);
381 pPathObj
->po
.fl
|= PO_BEZIERS
;
388 PATHOBJ_vEnumStartClipLines(
399 PATHOBJ_bEnumClipLines(
417 FIX xLeft
, yTop
, xRight
, yBottom
;
418 PEXTPATHOBJ pPathObj
;
419 PEXTPATHDATA ppd
, ppdNext
;
422 pPathObj
= (PEXTPATHOBJ
)ppo
;
423 if (pPathObj
== NULL
|| prectfx
== NULL
)
426 yTop
= xLeft
= MAXLONG
;
427 yBottom
= xRight
= MINLONG
;
429 for (ppd
= pPathObj
->ppdFirst
; ppd
; ppd
= ppdNext
)
431 ppdNext
= ppd
->ppdNext
;
432 for (i
= 0; i
< ppd
->pd
.count
; ++i
)
434 PPOINTFIX pptfx
= &ppd
->pd
.pptfx
[i
];
435 if (pptfx
->x
< xLeft
)
437 if (pptfx
->x
> xRight
)
441 if (pptfx
->y
> yBottom
)
446 if (xLeft
<= xRight
&& yTop
<= yBottom
)
448 prectfx
->xLeft
= xLeft
;
449 prectfx
->yTop
= yTop
;
450 prectfx
->xRight
= xRight
+ 1;
451 prectfx
->yBottom
= yBottom
+ 1;
455 RtlZeroMemory(prectfx
, sizeof(*prectfx
));