2 * Copyright (C) 2007 Google (Evan Stade)
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2.1 of the License, or (at your option) any later version.
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this library; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
28 #include "gdiplus_private.h"
30 GpStatus WINGDIPAPI
GdipCreatePathIter(GpPathIterator
**iterator
, GpPath
* path
)
35 return InvalidParameter
;
37 *iterator
= GdipAlloc(sizeof(GpPathIterator
));
38 if(!*iterator
) return OutOfMemory
;
41 size
= path
->pathdata
.Count
;
43 (*iterator
)->pathdata
.Types
= GdipAlloc(size
);
44 (*iterator
)->pathdata
.Points
= GdipAlloc(size
* sizeof(PointF
));
46 memcpy((*iterator
)->pathdata
.Types
, path
->pathdata
.Types
, size
);
47 memcpy((*iterator
)->pathdata
.Points
, path
->pathdata
.Points
,size
* sizeof(PointF
));
48 (*iterator
)->pathdata
.Count
= size
;
51 (*iterator
)->pathdata
.Types
= NULL
;
52 (*iterator
)->pathdata
.Points
= NULL
;
53 (*iterator
)->pathdata
.Count
= 0;
56 (*iterator
)->subpath_pos
= 0;
57 (*iterator
)->marker_pos
= 0;
58 (*iterator
)->pathtype_pos
= 0;
63 GpStatus WINGDIPAPI
GdipDeletePathIter(GpPathIterator
*iter
)
66 return InvalidParameter
;
68 GdipFree(iter
->pathdata
.Types
);
69 GdipFree(iter
->pathdata
.Points
);
75 GpStatus WINGDIPAPI
GdipPathIterCopyData(GpPathIterator
* iterator
,
76 INT
* resultCount
, GpPointF
* points
, BYTE
* types
, INT startIndex
, INT endIndex
)
78 if(!iterator
|| !types
|| !points
)
79 return InvalidParameter
;
81 if(endIndex
> iterator
->pathdata
.Count
- 1 || startIndex
< 0 ||
82 endIndex
< startIndex
){
87 *resultCount
= endIndex
- startIndex
+ 1;
89 memcpy(types
, &(iterator
->pathdata
.Types
[startIndex
]), *resultCount
);
90 memcpy(points
, &(iterator
->pathdata
.Points
[startIndex
]),
91 *resultCount
* sizeof(PointF
));
96 GpStatus WINGDIPAPI
GdipPathIterHasCurve(GpPathIterator
* iterator
, BOOL
* hasCurve
)
101 return InvalidParameter
;
105 for(i
= 0; i
< iterator
->pathdata
.Count
; i
++)
106 if((iterator
->pathdata
.Types
[i
] & PathPointTypePathTypeMask
) == PathPointTypeBezier
){
114 GpStatus WINGDIPAPI
GdipPathIterGetSubpathCount(GpPathIterator
* iterator
, INT
* count
)
118 if(!iterator
|| !count
)
119 return InvalidParameter
;
122 for(i
= 0; i
< iterator
->pathdata
.Count
; i
++){
123 if(iterator
->pathdata
.Types
[i
] == PathPointTypeStart
)
130 GpStatus WINGDIPAPI
GdipPathIterNextMarker(GpPathIterator
* iterator
, INT
*resultCount
,
131 INT
* startIndex
, INT
* endIndex
)
135 if(!iterator
|| !startIndex
|| !endIndex
)
136 return InvalidParameter
;
140 /* first call could start with second point as all subsequent, cause
141 path couldn't contain only one */
142 for(i
= iterator
->marker_pos
+ 1; i
< iterator
->pathdata
.Count
; i
++){
143 if((iterator
->pathdata
.Types
[i
] & PathPointTypePathMarker
) ||
144 (i
== iterator
->pathdata
.Count
- 1)){
145 *startIndex
= iterator
->marker_pos
;
146 if(iterator
->marker_pos
> 0) (*startIndex
)++;
147 *endIndex
= iterator
->marker_pos
= i
;
148 *resultCount
= *endIndex
- *startIndex
+ 1;
156 GpStatus WINGDIPAPI
GdipPathIterNextSubpath(GpPathIterator
* iterator
,
157 INT
*resultCount
, INT
* startIndex
, INT
* endIndex
, BOOL
* isClosed
)
161 if(!iterator
|| !startIndex
|| !endIndex
|| !isClosed
|| !resultCount
)
162 return InvalidParameter
;
164 count
= iterator
->pathdata
.Count
;
166 /* iterator created with NULL path */
172 if(iterator
->subpath_pos
== count
){
173 *startIndex
= *endIndex
= *resultCount
= 0;
178 *startIndex
= iterator
->subpath_pos
;
180 for(i
= iterator
->subpath_pos
+ 1; i
< count
&&
181 !(iterator
->pathdata
.Types
[i
] == PathPointTypeStart
); i
++);
184 iterator
->subpath_pos
= i
;
186 *resultCount
= *endIndex
- *startIndex
+ 1;
188 if(iterator
->pathdata
.Types
[*endIndex
] & PathPointTypeCloseSubpath
)
195 GpStatus WINGDIPAPI
GdipPathIterRewind(GpPathIterator
*iterator
)
198 return InvalidParameter
;
200 iterator
->subpath_pos
= 0;
201 iterator
->marker_pos
= 0;
202 iterator
->pathtype_pos
= 0;
207 GpStatus WINGDIPAPI
GdipPathIterGetCount(GpPathIterator
* iterator
, INT
* count
)
209 if(!iterator
|| !count
)
210 return InvalidParameter
;
212 *count
= iterator
->pathdata
.Count
;
217 GpStatus WINGDIPAPI
GdipPathIterEnumerate(GpPathIterator
* iterator
, INT
* resultCount
,
218 GpPointF
*points
, BYTE
*types
, INT count
)
220 if((count
< 0) || !resultCount
)
221 return InvalidParameter
;
228 return GdipPathIterCopyData(iterator
, resultCount
, points
, types
, 0, count
-1);
231 GpStatus WINGDIPAPI
GdipPathIterIsValid(GpPathIterator
* iterator
, BOOL
* valid
)
233 if(!iterator
|| !valid
)
234 return InvalidParameter
;
241 GpStatus WINGDIPAPI
GdipPathIterNextSubpathPath(GpPathIterator
* iter
, INT
* result
,
242 GpPath
* path
, BOOL
* closed
)
246 if(!iter
|| !result
|| !closed
)
247 return InvalidParameter
;
249 GdipPathIterNextSubpath(iter
, result
, &start
, &end
, closed
);
251 if(((*result
) > 0) && path
){
254 if(!lengthen_path(path
, *result
))
257 memcpy(path
->pathdata
.Points
, &(iter
->pathdata
.Points
[start
]), sizeof(GpPointF
)*(*result
));
258 memcpy(path
->pathdata
.Types
, &(iter
->pathdata
.Types
[start
]), sizeof(BYTE
)*(*result
));
259 path
->pathdata
.Count
= *result
;