2 * Copyright (C) 2007 Google (Evan Stade)
3 * Copyright (C) 2008 Nikolay Sivov <bunglehead at gmail dot com>
5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Lesser General Public
7 * License as published by the Free Software Foundation; either
8 * version 2.1 of the License, or (at your option) any later version.
10 * This library 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 GNU
13 * Lesser General Public License for more details.
15 * You should have received a copy of the GNU Lesser General Public
16 * License along with this library; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
29 #include "gdiplus_private.h"
30 #include "wine/debug.h"
32 WINE_DEFAULT_DEBUG_CHANNEL(gdiplus
);
34 GpStatus WINGDIPAPI
GdipCreatePathIter(GpPathIterator
**iterator
, GpPath
* path
)
38 TRACE("(%p, %p)\n", iterator
, path
);
41 return InvalidParameter
;
43 *iterator
= GdipAlloc(sizeof(GpPathIterator
));
44 if(!*iterator
) return OutOfMemory
;
47 size
= path
->pathdata
.Count
;
49 (*iterator
)->pathdata
.Types
= GdipAlloc(size
);
50 (*iterator
)->pathdata
.Points
= GdipAlloc(size
* sizeof(PointF
));
52 memcpy((*iterator
)->pathdata
.Types
, path
->pathdata
.Types
, size
);
53 memcpy((*iterator
)->pathdata
.Points
, path
->pathdata
.Points
,size
* sizeof(PointF
));
54 (*iterator
)->pathdata
.Count
= size
;
57 (*iterator
)->pathdata
.Types
= NULL
;
58 (*iterator
)->pathdata
.Points
= NULL
;
59 (*iterator
)->pathdata
.Count
= 0;
62 (*iterator
)->subpath_pos
= 0;
63 (*iterator
)->marker_pos
= 0;
64 (*iterator
)->pathtype_pos
= 0;
69 GpStatus WINGDIPAPI
GdipDeletePathIter(GpPathIterator
*iter
)
71 TRACE("(%p)\n", iter
);
74 return InvalidParameter
;
76 GdipFree(iter
->pathdata
.Types
);
77 GdipFree(iter
->pathdata
.Points
);
83 GpStatus WINGDIPAPI
GdipPathIterCopyData(GpPathIterator
* iterator
,
84 INT
* resultCount
, GpPointF
* points
, BYTE
* types
, INT startIndex
, INT endIndex
)
86 TRACE("(%p, %p, %p, %p, %d, %d)\n", iterator
, resultCount
, points
, types
,
87 startIndex
, endIndex
);
89 if(!iterator
|| !types
|| !points
)
90 return InvalidParameter
;
92 if(endIndex
> iterator
->pathdata
.Count
- 1 || startIndex
< 0 ||
93 endIndex
< startIndex
){
98 *resultCount
= endIndex
- startIndex
+ 1;
100 memcpy(types
, &(iterator
->pathdata
.Types
[startIndex
]), *resultCount
);
101 memcpy(points
, &(iterator
->pathdata
.Points
[startIndex
]),
102 *resultCount
* sizeof(PointF
));
107 GpStatus WINGDIPAPI
GdipPathIterHasCurve(GpPathIterator
* iterator
, BOOL
* hasCurve
)
111 TRACE("(%p, %p)\n", iterator
, hasCurve
);
114 return InvalidParameter
;
118 for(i
= 0; i
< iterator
->pathdata
.Count
; i
++)
119 if((iterator
->pathdata
.Types
[i
] & PathPointTypePathTypeMask
) == PathPointTypeBezier
){
127 GpStatus WINGDIPAPI
GdipPathIterGetSubpathCount(GpPathIterator
* iterator
, INT
* count
)
131 TRACE("(%p, %p)\n", iterator
, count
);
133 if(!iterator
|| !count
)
134 return InvalidParameter
;
137 for(i
= 0; i
< iterator
->pathdata
.Count
; i
++){
138 if(iterator
->pathdata
.Types
[i
] == PathPointTypeStart
)
145 GpStatus WINGDIPAPI
GdipPathIterNextMarker(GpPathIterator
* iterator
, INT
*resultCount
,
146 INT
* startIndex
, INT
* endIndex
)
150 TRACE("(%p, %p, %p, %p)\n", iterator
, resultCount
, startIndex
, endIndex
);
152 if(!iterator
|| !startIndex
|| !endIndex
)
153 return InvalidParameter
;
157 /* first call could start with second point as all subsequent, cause
158 path couldn't contain only one */
159 for(i
= iterator
->marker_pos
+ 1; i
< iterator
->pathdata
.Count
; i
++){
160 if((iterator
->pathdata
.Types
[i
] & PathPointTypePathMarker
) ||
161 (i
== iterator
->pathdata
.Count
- 1)){
162 *startIndex
= iterator
->marker_pos
;
163 if(iterator
->marker_pos
> 0) (*startIndex
)++;
164 *endIndex
= iterator
->marker_pos
= i
;
165 *resultCount
= *endIndex
- *startIndex
+ 1;
173 GpStatus WINGDIPAPI
GdipPathIterNextMarkerPath(GpPathIterator
* iterator
, INT
* result
,
178 TRACE("(%p, %p, %p)\n", iterator
, result
, path
);
180 if(!iterator
|| !result
)
181 return InvalidParameter
;
183 GdipPathIterNextMarker(iterator
, result
, &start
, &end
);
185 if(((*result
) > 0) && path
){
188 if(!lengthen_path(path
, *result
))
191 memcpy(path
->pathdata
.Points
, &(iterator
->pathdata
.Points
[start
]), sizeof(GpPointF
)*(*result
));
192 memcpy(path
->pathdata
.Types
, &(iterator
->pathdata
.Types
[start
]), sizeof(BYTE
)*(*result
));
193 path
->pathdata
.Count
= *result
;
199 GpStatus WINGDIPAPI
GdipPathIterNextSubpath(GpPathIterator
* iterator
,
200 INT
*resultCount
, INT
* startIndex
, INT
* endIndex
, BOOL
* isClosed
)
204 TRACE("(%p, %p, %p, %p, %p)\n", iterator
, resultCount
, startIndex
,
207 if(!iterator
|| !startIndex
|| !endIndex
|| !isClosed
|| !resultCount
)
208 return InvalidParameter
;
210 count
= iterator
->pathdata
.Count
;
212 /* iterator created with NULL path */
218 if(iterator
->subpath_pos
== count
){
219 *startIndex
= *endIndex
= *resultCount
= 0;
224 *startIndex
= iterator
->subpath_pos
;
226 for(i
= iterator
->subpath_pos
+ 1; i
< count
&&
227 !(iterator
->pathdata
.Types
[i
] == PathPointTypeStart
); i
++);
230 iterator
->subpath_pos
= i
;
232 *resultCount
= *endIndex
- *startIndex
+ 1;
234 if(iterator
->pathdata
.Types
[*endIndex
] & PathPointTypeCloseSubpath
)
241 GpStatus WINGDIPAPI
GdipPathIterRewind(GpPathIterator
*iterator
)
243 TRACE("(%p)\n", iterator
);
246 return InvalidParameter
;
248 iterator
->subpath_pos
= 0;
249 iterator
->marker_pos
= 0;
250 iterator
->pathtype_pos
= 0;
255 GpStatus WINGDIPAPI
GdipPathIterGetCount(GpPathIterator
* iterator
, INT
* count
)
257 TRACE("(%p, %p)\n", iterator
, count
);
259 if(!iterator
|| !count
)
260 return InvalidParameter
;
262 *count
= iterator
->pathdata
.Count
;
267 GpStatus WINGDIPAPI
GdipPathIterEnumerate(GpPathIterator
* iterator
, INT
* resultCount
,
268 GpPointF
*points
, BYTE
*types
, INT count
)
270 TRACE("(%p, %p, %p, %p, %d)\n", iterator
, resultCount
, points
, types
, count
);
272 if((count
< 0) || !resultCount
)
273 return InvalidParameter
;
280 return GdipPathIterCopyData(iterator
, resultCount
, points
, types
, 0, count
-1);
283 GpStatus WINGDIPAPI
GdipPathIterIsValid(GpPathIterator
* iterator
, BOOL
* valid
)
285 TRACE("(%p, %p)\n", iterator
, valid
);
287 if(!iterator
|| !valid
)
288 return InvalidParameter
;
295 GpStatus WINGDIPAPI
GdipPathIterNextPathType(GpPathIterator
* iter
, INT
* result
,
296 BYTE
* type
, INT
* start
, INT
* end
)
298 FIXME("(%p, %p, %p, %p, %p) stub\n", iter
, result
, type
, start
, end
);
300 if(!iter
|| !result
|| !type
|| !start
|| !end
)
301 return InvalidParameter
;
303 return NotImplemented
;
306 GpStatus WINGDIPAPI
GdipPathIterNextSubpathPath(GpPathIterator
* iter
, INT
* result
,
307 GpPath
* path
, BOOL
* closed
)
311 TRACE("(%p, %p, %p, %p)\n", iter
, result
, path
, closed
);
313 if(!iter
|| !result
|| !closed
)
314 return InvalidParameter
;
316 GdipPathIterNextSubpath(iter
, result
, &start
, &end
, closed
);
318 if(((*result
) > 0) && path
){
321 if(!lengthen_path(path
, *result
))
324 memcpy(path
->pathdata
.Points
, &(iter
->pathdata
.Points
[start
]), sizeof(GpPointF
)*(*result
));
325 memcpy(path
->pathdata
.Types
, &(iter
->pathdata
.Types
[start
]), sizeof(BYTE
)*(*result
));
326 path
->pathdata
.Count
= *result
;