OSDN Git Service

f11a040c61eada4b013270e423b51b384db6f7b0
[mingw/mingw-org-wsl.git] / include / gdiplus / gdipluspath.h
1 /**
2  * @file gdipluspath.h
3  * @copy 2012 MinGW.org project
4  *
5  * Permission is hereby granted, free of charge, to any person obtaining a
6  * copy of this software and associated documentation files (the "Software"),
7  * to deal in the Software without restriction, including without limitation
8  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
9  * and/or sell copies of the Software, and to permit persons to whom the
10  * Software is furnished to do so, subject to the following conditions:
11  * 
12  * The above copyright notice and this permission notice (including the next
13  * paragraph) shall be included in all copies or substantial portions of the
14  * Software.
15  * 
16  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
21  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
22  * DEALINGS IN THE SOFTWARE.
23  */
24 /* Created by Markus Koenig <markus@stber-koenig.de> */
25 #ifndef __GDIPLUS_PATH_H
26 #define __GDIPLUS_PATH_H
27 #pragma GCC system_header
28 #include <_mingw.h>
29
30 /*
31  * GDI+ GraphicsPath class
32  */
33
34 #ifndef __cplusplus
35 #error "A C++ compiler is required to include gdipluspath.h."
36 #endif
37
38 // Note that some methods of GraphicsPath are implemented in gdiplusimpl.h.
39 // This avoids a cyclic dependency on Graphics and Pen.
40
41 class GraphicsPath: public GdiplusBase
42 {
43         friend class CustomLineCap;
44         friend class Graphics;
45         friend class GraphicsPathIterator;
46         friend class PathGradientBrush;
47         friend class Region;
48
49 public:
50         GraphicsPath(FillMode fillMode = FillModeAlternate):
51                         nativePath(NULL), lastStatus(Ok)
52         {
53                 lastStatus = DllExports::GdipCreatePath(fillMode, &nativePath);
54         }
55         GraphicsPath(const PointF *points, const BYTE *types, INT count,
56                         FillMode fillMode = FillModeAlternate):
57                         nativePath(NULL), lastStatus(Ok)
58         {
59                 lastStatus = DllExports::GdipCreatePath2(
60                                 points, types, count, fillMode, &nativePath);
61         }
62         GraphicsPath(const Point *points, const BYTE *types, INT count,
63                         FillMode fillMode = FillModeAlternate):
64                         nativePath(NULL), lastStatus(Ok)
65         {
66                 lastStatus = DllExports::GdipCreatePath2I(
67                                 points, types, count, fillMode, &nativePath);
68         }
69         ~GraphicsPath()
70         {
71                 DllExports::GdipDeletePath(nativePath);
72         }
73         GraphicsPath* Clone() const
74         {
75                 GpPath *clonePath = NULL;
76                 Status status = updateStatus(DllExports::GdipClonePath(
77                                 nativePath, &clonePath));
78                 if (status == Ok) {
79                         GraphicsPath *result = new GraphicsPath(clonePath, lastStatus);
80                         if (!result) {
81                                 DllExports::GdipDeletePath(clonePath);
82                                 lastStatus = OutOfMemory;
83                         }
84                         return result;
85                 } else {
86                         return NULL;
87                 }
88         }
89
90         Status AddArc(REAL x, REAL y, REAL width, REAL height,
91                         REAL startAngle, REAL sweepAngle)
92         {
93                 return updateStatus(DllExports::GdipAddPathArc(nativePath,
94                                 x, y, width, height, startAngle, sweepAngle));
95         }
96         Status AddArc(INT x, INT y, INT width, INT height,
97                         REAL startAngle, REAL sweepAngle)
98         {
99                 return updateStatus(DllExports::GdipAddPathArcI(nativePath,
100                                 x, y, width, height, startAngle, sweepAngle));
101         }
102         Status AddArc(const RectF& rect, REAL startAngle, REAL sweepAngle)
103         {
104                 return updateStatus(DllExports::GdipAddPathArc(nativePath,
105                                 rect.X, rect.Y, rect.Width, rect.Height,
106                                 startAngle, sweepAngle));
107         }
108         Status AddArc(const Rect& rect, REAL startAngle, REAL sweepAngle)
109         {
110                 return updateStatus(DllExports::GdipAddPathArcI(nativePath,
111                                 rect.X, rect.Y, rect.Width, rect.Height,
112                                 startAngle, sweepAngle));
113         }
114         Status AddBezier(REAL x1, REAL y1, REAL x2, REAL y2,
115                         REAL x3, REAL y3, REAL x4, REAL y4)
116         {
117                 return updateStatus(DllExports::GdipAddPathBezier(nativePath,
118                                 x1, y1, x2, y2, x3, y3, x4, y4));
119         }
120         Status AddBezier(INT x1, INT y1, INT x2, INT y2,
121                         INT x3, INT y3, INT x4, INT y4)
122         {
123                 return updateStatus(DllExports::GdipAddPathBezierI(nativePath,
124                                 x1, y1, x2, y2, x3, y3, x4, y4));
125         }
126         Status AddBezier(const PointF& pt1, const PointF& pt2,
127                         const PointF& pt3, const PointF& pt4)
128         {
129                 return updateStatus(DllExports::GdipAddPathBezier(nativePath,
130                                 pt1.X, pt1.Y, pt2.X, pt2.Y,
131                                 pt3.X, pt3.Y, pt4.X, pt4.Y));
132         }
133         Status AddBezier(const Point& pt1, const Point& pt2,
134                         const Point& pt3, const Point& pt4)
135         {
136                 return updateStatus(DllExports::GdipAddPathBezierI(nativePath,
137                                 pt1.X, pt1.Y, pt2.X, pt2.Y,
138                                 pt3.X, pt3.Y, pt4.X, pt4.Y));
139         }
140         Status AddBeziers(const PointF *points, INT count)
141         {
142                 return updateStatus(DllExports::GdipAddPathBeziers(
143                                 nativePath, points, count));
144         }
145         Status AddBeziers(const Point *points, INT count)
146         {
147                 return updateStatus(DllExports::GdipAddPathBeziersI(
148                                 nativePath, points, count));
149         }
150         Status AddClosedCurve(const PointF *points, INT count)
151         {
152                 return updateStatus(DllExports::GdipAddPathClosedCurve(
153                                 nativePath, points, count));
154         }
155         Status AddClosedCurve(const Point *points, INT count)
156         {
157                 return updateStatus(DllExports::GdipAddPathClosedCurveI(
158                                 nativePath, points, count));
159         }
160         Status AddClosedCurve(const PointF *points, INT count, REAL tension)
161         {
162                 return updateStatus(DllExports::GdipAddPathClosedCurve2(
163                                 nativePath, points, count, tension));
164         }
165         Status AddClosedCurve(const Point *points, INT count, REAL tension)
166         {
167                 return updateStatus(DllExports::GdipAddPathClosedCurve2I(
168                                 nativePath, points, count, tension));
169         }
170         Status AddCurve(const PointF *points, INT count)
171         {
172                 return updateStatus(DllExports::GdipAddPathCurve(
173                                 nativePath, points, count));
174         }
175         Status AddCurve(const Point *points, INT count)
176         {
177                 return updateStatus(DllExports::GdipAddPathCurveI(
178                                 nativePath, points, count));
179         }
180         Status AddCurve(const PointF *points, INT count, REAL tension)
181         {
182                 return updateStatus(DllExports::GdipAddPathCurve2(
183                                 nativePath, points, count, tension));
184         }
185         Status AddCurve(const Point *points, INT count, REAL tension)
186         {
187                 return updateStatus(DllExports::GdipAddPathCurve2I(
188                                 nativePath, points, count, tension));
189         }
190         Status AddCurve(const PointF *points, INT count, INT offset,
191                         INT numberOfSegments, REAL tension)
192         {
193                 return updateStatus(DllExports::GdipAddPathCurve3(
194                                 nativePath, points, count,
195                                 offset, numberOfSegments, tension));
196         }
197         Status AddCurve(const Point *points, INT count, INT offset,
198                         INT numberOfSegments, REAL tension)
199         {
200                 return updateStatus(DllExports::GdipAddPathCurve3I(
201                                 nativePath, points, count,
202                                 offset, numberOfSegments, tension));
203         }
204         Status AddEllipse(REAL x, REAL y, REAL width, REAL height)
205         {
206                 return updateStatus(DllExports::GdipAddPathEllipse(nativePath,
207                                 x, y, width, height));
208         }
209         Status AddEllipse(INT x, INT y, INT width, INT height)
210         {
211                 return updateStatus(DllExports::GdipAddPathEllipseI(nativePath,
212                                 x, y, width, height));
213         }
214         Status AddEllipse(const RectF& rect)
215         {
216                 return updateStatus(DllExports::GdipAddPathEllipse(nativePath,
217                                 rect.X, rect.Y, rect.Width, rect.Height));
218         }
219         Status AddEllipse(const Rect& rect)
220         {
221                 return updateStatus(DllExports::GdipAddPathEllipseI(nativePath,
222                                 rect.X, rect.Y, rect.Width, rect.Height));
223         }
224         Status AddLine(REAL x1, REAL y1, REAL x2, REAL y2)
225         {
226                 return updateStatus(DllExports::GdipAddPathLine(nativePath,
227                                 x1, y1, x2, y2));
228         }
229         Status AddLine(INT x1, INT y1, INT x2, INT y2)
230         {
231                 return updateStatus(DllExports::GdipAddPathLineI(nativePath,
232                                 x1, y1, x2, y2));
233         }
234         Status AddLine(const PointF& pt1, const PointF& pt2)
235         {
236                 return updateStatus(DllExports::GdipAddPathLine(nativePath,
237                                 pt1.X, pt1.Y, pt2.X, pt2.Y));
238         }
239         Status AddLine(const Point& pt1, const Point& pt2)
240         {
241                 return updateStatus(DllExports::GdipAddPathLineI(nativePath,
242                                 pt1.X, pt1.Y, pt2.X, pt2.Y));
243         }
244         Status AddLines(const PointF *points, INT count)
245         {
246                 return updateStatus(DllExports::GdipAddPathLine2(nativePath,
247                                 points, count));
248         }
249         Status AddLines(const Point *points, INT count)
250         {
251                 return updateStatus(DllExports::GdipAddPathLine2I(nativePath,
252                                 points, count));
253         }
254         Status AddPath(const GraphicsPath *addingPath, BOOL connect)
255         {
256                 return updateStatus(DllExports::GdipAddPathPath(nativePath,
257                                 addingPath ? addingPath->nativePath : NULL,
258                                 connect));
259         }
260         Status AddPie(REAL x, REAL y, REAL width, REAL height,
261                         REAL startAngle, REAL sweepAngle)
262         {
263                 return updateStatus(DllExports::GdipAddPathPie(nativePath,
264                                 x, y, width, height, startAngle, sweepAngle));
265         }
266         Status AddPie(INT x, INT y, INT width, INT height,
267                         REAL startAngle, REAL sweepAngle)
268         {
269                 return updateStatus(DllExports::GdipAddPathPieI(nativePath,
270                                 x, y, width, height, startAngle, sweepAngle));
271         }
272         Status AddPie(const RectF& rect, REAL startAngle, REAL sweepAngle)
273         {
274                 return updateStatus(DllExports::GdipAddPathPie(nativePath,
275                                 rect.X, rect.Y, rect.Width, rect.Height,
276                                 startAngle, sweepAngle));
277         }
278         Status AddPie(const Rect& rect, REAL startAngle, REAL sweepAngle)
279         {
280                 return updateStatus(DllExports::GdipAddPathPieI(nativePath,
281                                 rect.X, rect.Y, rect.Width, rect.Height,
282                                 startAngle, sweepAngle));
283         }
284         Status AddPolygon(const PointF *points, INT count)
285         {
286                 return updateStatus(DllExports::GdipAddPathPolygon(nativePath,
287                                 points, count));
288         }
289         Status AddPolygon(const Point *points, INT count)
290         {
291                 return updateStatus(DllExports::GdipAddPathPolygonI(nativePath,
292                                 points, count));
293         }
294         Status AddRectangle(const RectF& rect)
295         {
296                 return updateStatus(DllExports::GdipAddPathRectangle(nativePath,
297                                 rect.X, rect.Y, rect.Width, rect.Height));
298         }
299         Status AddRectangle(const Rect& rect)
300         {
301                 return updateStatus(DllExports::GdipAddPathRectangleI(
302                                 nativePath,
303                                 rect.X, rect.Y, rect.Width, rect.Height));
304         }
305         Status AddRectangles(const RectF *rects, INT count)
306         {
307                 return updateStatus(DllExports::GdipAddPathRectangles(
308                                 nativePath, rects, count));
309         }
310         Status AddRectangles(const Rect *rects, INT count)
311         {
312                 return updateStatus(DllExports::GdipAddPathRectanglesI(
313                                 nativePath, rects, count));
314         }
315         Status AddString(const WCHAR *string, INT length,
316                         const FontFamily *family, INT style, REAL emSize,
317                         const PointF& origin, const StringFormat *format)
318         {
319                 RectF layoutRect(origin, SizeF(0.0f, 0.0f));
320                 return updateStatus(DllExports::GdipAddPathString(nativePath,
321                                 string, length,
322                                 family ? family->nativeFontFamily : NULL,
323                                 style, emSize, &layoutRect,
324                                 format ? format->nativeStringFormat : NULL));
325         }
326         Status AddString(const WCHAR *string, INT length,
327                         const FontFamily *family, INT style, REAL emSize,
328                         const Point& origin, const StringFormat *format)
329         {
330                 Rect layoutRect(origin, Size(0, 0));
331                 return updateStatus(DllExports::GdipAddPathStringI(nativePath,
332                                 string, length,
333                                 family ? family->nativeFontFamily : NULL,
334                                 style, emSize, &layoutRect,
335                                 format ? format->nativeStringFormat : NULL));
336         }
337         Status AddString(const WCHAR *string, INT length,
338                         const FontFamily *family, INT style, REAL emSize,
339                         const RectF& layoutRect, const StringFormat *format)
340         {
341                 return updateStatus(DllExports::GdipAddPathString(nativePath,
342                                 string, length,
343                                 family ? family->nativeFontFamily : NULL,
344                                 style, emSize, &layoutRect,
345                                 format ? format->nativeStringFormat : NULL));
346         }
347         Status AddString(const WCHAR *string, INT length,
348                         const FontFamily *family, INT style, REAL emSize,
349                         const Rect& layoutRect, const StringFormat *format)
350         {
351                 return updateStatus(DllExports::GdipAddPathStringI(nativePath,
352                                 string, length,
353                                 family ? family->nativeFontFamily : NULL,
354                                 style, emSize, &layoutRect,
355                                 format ? format->nativeStringFormat : NULL));
356         }
357         Status ClearMarkers()
358         {
359                 return updateStatus(DllExports::GdipClearPathMarkers(
360                                 nativePath));
361         }
362         Status CloseAllFigures()
363         {
364                 return updateStatus(DllExports::GdipClosePathFigures(
365                                 nativePath));
366         }
367         Status CloseFigure()
368         {
369                 return updateStatus(DllExports::GdipClosePathFigure(
370                                 nativePath));
371         }
372         Status Flatten(const Matrix *matrix = NULL,
373                         REAL flatness = FlatnessDefault)
374         {
375                 return updateStatus(DllExports::GdipFlattenPath(nativePath,
376                                 matrix ? matrix->nativeMatrix : NULL,
377                                 flatness));
378         }
379         Status GetBounds(RectF *bounds, const Matrix *matrix = NULL,
380                         const Pen *pen = NULL) const
381         {
382                 return updateStatus(DllExports::GdipGetPathWorldBounds(
383                                 nativePath, bounds,
384                                 matrix ? matrix->nativeMatrix : NULL,
385                                 pen ? pen->nativePen : NULL));
386         }
387         Status GetBounds(Rect *bounds, const Matrix *matrix = NULL,
388                         const Pen *pen = NULL) const
389         {
390                 return updateStatus(DllExports::GdipGetPathWorldBoundsI(
391                                 nativePath, bounds,
392                                 matrix ? matrix->nativeMatrix : NULL,
393                                 pen ? pen->nativePen : NULL));
394         }       
395         FillMode GetFillMode() const
396         {
397                 FillMode result = FillModeAlternate;
398                 updateStatus(DllExports::GdipGetPathFillMode(nativePath,
399                                 &result));
400                 return result;
401         }
402         Status GetLastPoint(PointF *lastPoint) const
403         {
404                 return updateStatus(DllExports::GdipGetPathLastPoint(
405                                 nativePath, lastPoint));
406         }
407         Status GetLastStatus() const
408         {
409                 Status result = lastStatus;
410                 lastStatus = Ok;
411                 return result;
412         }
413         Status GetPathData(PathData *pathData) const
414         {
415                 if (!pathData) return lastStatus = InvalidParameter;
416
417                 Status status;
418                 INT count;
419
420                 status = updateStatus(DllExports::GdipGetPointCount(
421                                 nativePath, &count));
422                 if (status != Ok) return status;
423
424                 status = updateStatus(pathData->AllocateArrays(count));
425                 if (status != Ok) return status;
426
427                 return updateStatus(DllExports::GdipGetPathData(
428                                 nativePath, (GpPathData*) pathData));
429         }
430         Status GetPathPoints(PointF *points, INT count) const
431         {
432                 return updateStatus(DllExports::GdipGetPathPoints(nativePath,
433                                 points, count));
434         }
435         Status GetPathPoints(Point *points, INT count) const
436         {
437                 return updateStatus(DllExports::GdipGetPathPointsI(nativePath,
438                                 points, count));
439         }
440         Status GetPathTypes(BYTE *types, INT count) const
441         {
442                 return updateStatus(DllExports::GdipGetPathTypes(nativePath,
443                                 types, count));
444         }
445         INT GetPointCount() const
446         {
447                 INT result = 0;
448                 updateStatus(DllExports::GdipGetPointCount(nativePath,
449                                 &result));
450                 return result;
451         }
452         BOOL IsOutlineVisible(REAL x, REAL y, const Pen *pen,
453                         const Graphics *g = NULL) const;
454         BOOL IsOutlineVisible(INT x, INT y, const Pen *pen,
455                         const Graphics *g = NULL) const;
456         BOOL IsOutlineVisible(const PointF& point, const Pen *pen,
457                         const Graphics *g = NULL) const;
458         BOOL IsOutlineVisible(const Point& point, const Pen *pen,
459                         const Graphics *g = NULL) const;
460         BOOL IsVisible(REAL x, REAL y, const Graphics *g = NULL) const;
461         BOOL IsVisible(INT x, INT y, const Graphics *g = NULL) const;
462         BOOL IsVisible(const PointF& point, const Graphics *g = NULL) const;
463         BOOL IsVisible(const Point& point, const Graphics *g = NULL) const;
464         Status Outline(const Matrix *matrix = NULL,
465                         REAL flatness = FlatnessDefault)
466         {
467                 return updateStatus(DllExports::GdipWindingModeOutline(
468                                 nativePath,
469                                 matrix ? matrix->nativeMatrix : NULL,
470                                 flatness));
471         }
472         Status Reset()
473         {
474                 return updateStatus(DllExports::GdipResetPath(nativePath));
475         }
476         Status Reverse()
477         {
478                 return updateStatus(DllExports::GdipReversePath(nativePath));
479         }
480         Status SetFillMode(FillMode fillMode)
481         {
482                 return updateStatus(DllExports::GdipSetPathFillMode(
483                                 nativePath, fillMode));
484         }
485         Status SetMarker()
486         {
487                 return updateStatus(DllExports::GdipSetPathMarker(nativePath));
488         }
489         Status StartFigure()
490         {
491                 return updateStatus(DllExports::GdipStartPathFigure(
492                                 nativePath));
493         }
494         Status Transform(const Matrix *matrix)
495         {
496                 return updateStatus(DllExports::GdipTransformPath(
497                                 nativePath,
498                                 matrix ? matrix->nativeMatrix : NULL));
499         }
500         Status Warp(const PointF *destPoints, INT count, const RectF& srcRect,
501                         const Matrix *matrix = NULL,
502                         WarpMode warpMode = WarpModePerspective,
503                         REAL flatness = FlatnessDefault)
504         {
505                 return updateStatus(DllExports::GdipWarpPath(nativePath,
506                                 matrix ? matrix->nativeMatrix : NULL,
507                                 destPoints, count,
508                                 srcRect.X, srcRect.Y,
509                                 srcRect.Width, srcRect.Height,
510                                 warpMode, flatness));
511         }
512         Status Widen(const Pen *pen, const Matrix *matrix = NULL,
513                         REAL flatness = FlatnessDefault)
514         {
515                 return updateStatus(DllExports::GdipWidenPath(nativePath,
516                                 pen ? pen->nativePen : NULL,
517                                 matrix ? matrix->nativeMatrix : NULL,
518                                 flatness));
519         }
520
521 private:
522         GraphicsPath(GpPath *path, Status status):
523                 nativePath(path), lastStatus(status) {}
524         GraphicsPath(const GraphicsPath&);
525         GraphicsPath& operator=(const GraphicsPath&);
526
527         Status updateStatus(Status newStatus) const
528         {
529                 if (newStatus != Ok) lastStatus = newStatus;
530                 return newStatus;
531         }
532
533         GpPath *nativePath;
534         mutable Status lastStatus;
535 };
536
537 class GraphicsPathIterator: public GdiplusBase
538 {
539 public:
540         GraphicsPathIterator(GraphicsPath *path):
541                 nativePathIterator(NULL), lastStatus(Ok)
542         {
543                 lastStatus = DllExports::GdipCreatePathIter(
544                                 &nativePathIterator,
545                                 path ? path->nativePath : NULL);
546         }
547         ~GraphicsPathIterator()
548         {
549                 DllExports::GdipDeletePathIter(nativePathIterator);
550         }
551
552         INT CopyData(PointF *points, BYTE *types, INT startIndex, INT endIndex)
553         {
554                 INT result = 0;
555                 updateStatus(DllExports::GdipPathIterCopyData(
556                                 nativePathIterator, &result,
557                                 points, types, startIndex, endIndex));
558                 return result;
559         }
560         INT Enumerate(PointF *points, BYTE *types, INT count)
561         {
562                 INT result = 0;
563                 updateStatus(DllExports::GdipPathIterEnumerate(
564                                 nativePathIterator, &result,
565                                 points, types, count));
566                 return result;
567         }
568         INT GetCount() const
569         {
570                 INT result = 0;
571                 updateStatus(DllExports::GdipPathIterGetCount(
572                                 nativePathIterator, &result));
573                 return result;
574         }
575         Status GetLastStatus() const
576         {
577                 Status result = lastStatus;
578                 lastStatus = Ok;
579                 return result;
580         }
581         INT GetSubpathCount() const
582         {
583                 INT result = 0;
584                 updateStatus(DllExports::GdipPathIterGetSubpathCount(
585                                 nativePathIterator, &result));
586                 return result;
587         }
588         BOOL HasCurve() const
589         {
590                 BOOL result = FALSE;
591                 updateStatus(DllExports::GdipPathIterHasCurve(
592                                 nativePathIterator, &result));
593                 return result;
594         }
595         INT NextMarker(INT *startIndex, INT *endIndex)
596         {
597                 INT result = 0;
598                 updateStatus(DllExports::GdipPathIterNextMarker(
599                                 nativePathIterator, &result,
600                                 startIndex, endIndex));
601                 return result;
602         }
603         INT NextMarker(GraphicsPath *path)
604         {
605                 INT result = 0;
606                 updateStatus(DllExports::GdipPathIterNextMarkerPath(
607                                 nativePathIterator, &result,
608                                 path ? path->nativePath : NULL));
609                 return result;
610         }
611         INT NextPathType(BYTE *pathType, INT *startIndex, INT *endIndex)
612         {
613                 INT result = 0;
614                 updateStatus(DllExports::GdipPathIterNextPathType(
615                                 nativePathIterator, &result,
616                                 pathType, startIndex, endIndex));
617                 return result;
618         }
619         INT NextSubpath(INT *startIndex, INT *endIndex, BOOL *isClosed)
620         {
621                 INT result = 0;
622                 updateStatus(DllExports::GdipPathIterNextSubpath(
623                                 nativePathIterator, &result,
624                                 startIndex, endIndex, isClosed));
625                 return result;
626         }
627         INT NextSubpath(GraphicsPath *path, BOOL *isClosed)
628         {
629                 INT result = 0;
630                 updateStatus(DllExports::GdipPathIterNextSubpathPath(
631                                 nativePathIterator, &result,
632                                 path ? path->nativePath : NULL, isClosed));
633                 return result;
634         }
635         VOID Rewind()
636         {
637                 updateStatus(DllExports::GdipPathIterRewind(
638                                 nativePathIterator));
639         }
640
641 private:
642         GraphicsPathIterator(GpPathIterator *pathIterator, Status status):
643                 nativePathIterator(pathIterator), lastStatus(status) {}
644         GraphicsPathIterator(const GraphicsPathIterator&);
645         GraphicsPathIterator& operator=(const GraphicsPathIterator&);
646
647         Status updateStatus(Status newStatus) const
648         {
649                 if (newStatus != Ok) lastStatus = newStatus;
650                 return newStatus;
651         }
652
653         GpPathIterator *nativePathIterator;
654         mutable Status lastStatus;
655 };
656
657 class PathGradientBrush: public Brush
658 {
659 public:
660         PathGradientBrush(const PointF *points, INT count,
661                         WrapMode wrapMode = WrapModeClamp)
662         {
663                 GpPathGradient *nativePathGradient = NULL;
664                 lastStatus = DllExports::GdipCreatePathGradient(
665                                 points, count, wrapMode, &nativePathGradient);
666                 nativeBrush = nativePathGradient;
667         }
668         PathGradientBrush(const Point *points, INT count,
669                         WrapMode wrapMode = WrapModeClamp)
670         {
671                 GpPathGradient *nativePathGradient = NULL;
672                 lastStatus = DllExports::GdipCreatePathGradientI(
673                                 points, count, wrapMode, &nativePathGradient);
674                 nativeBrush = nativePathGradient;
675         }
676         PathGradientBrush(const GraphicsPath *path)
677         {
678                 GpPathGradient *nativePathGradient = NULL;
679                 lastStatus = DllExports::GdipCreatePathGradientFromPath(
680                                 path ? path->nativePath : NULL,
681                                 &nativePathGradient);
682                 nativeBrush = nativePathGradient;
683         }
684         virtual PathGradientBrush *Clone() const
685         {
686                 GpBrush *cloneBrush = NULL;
687                 Status status = updateStatus(DllExports::GdipCloneBrush(
688                                 nativeBrush, &cloneBrush));
689                 if (status == Ok) {
690                         PathGradientBrush *result =
691                                 new PathGradientBrush(cloneBrush, lastStatus);
692                         if (!result) {
693                                 DllExports::GdipDeleteBrush(cloneBrush);
694                                 updateStatus(OutOfMemory);
695                         }
696                         return result;
697                 } else {
698                         return NULL;
699                 }
700         }
701
702         Status GetBlend(REAL *blendFactors, REAL *blendPositions,
703                         INT count) const
704         {
705                 return updateStatus(DllExports::GdipGetPathGradientBlend(
706                                 (GpPathGradient*) nativeBrush,
707                                 blendFactors, blendPositions, count));
708         }
709         INT GetBlendCount() const
710         {
711                 INT result = 0;
712                 updateStatus(DllExports::GdipGetPathGradientBlendCount(
713                                 (GpPathGradient*) nativeBrush, &result));
714                 return result;
715         }
716         Status GetCenterColor(Color *color) const
717         {
718                 return updateStatus(DllExports::GdipGetPathGradientCenterColor(
719                                 (GpPathGradient*) nativeBrush,
720                                 color ? &color->Value : NULL));
721         }
722         Status GetCenterPoint(PointF *point) const
723         {
724                 return updateStatus(DllExports::GdipGetPathGradientCenterPoint(
725                                 (GpPathGradient*) nativeBrush, point));
726         }
727         Status GetCenterPoint(Point *point) const
728         {
729                 return updateStatus(DllExports::GdipGetPathGradientCenterPointI(
730                                 (GpPathGradient*) nativeBrush, point));
731         }
732         Status GetFocusScales(REAL *xScale, REAL *yScale) const
733         {
734                 return updateStatus(DllExports::GdipGetPathGradientFocusScales(
735                                 (GpPathGradient*) nativeBrush, xScale, yScale));
736         }
737         BOOL GetGammaCorrection() const
738         {
739                 BOOL result = FALSE;
740                 updateStatus(DllExports::GdipGetPathGradientGammaCorrection(
741                                 (GpPathGradient*) nativeBrush, &result));
742                 return result;
743         }
744         //Status GetGraphicsPath(GraphicsPath *path) const
745         //{
746         //      // TODO: implement PathGradientBrush::GetGraphicsPath
747         //      return updateStatus(NotImplemented);
748         //}
749         INT GetInterpolationColorCount() const
750         {
751                 INT result = 0;
752                 updateStatus(DllExports::GdipGetPathGradientPresetBlendCount(
753                                 (GpPathGradient*) nativeBrush, &result));
754                 return result;
755         }
756         Status GetInterpolationColors(Color *presetColors,
757                         REAL *blendPositions, INT count) const
758         {
759                 if (!presetColors || count <= 0)
760                         return lastStatus = InvalidParameter;
761
762                 ARGB *presetArgb =
763                         (ARGB*) DllExports::GdipAlloc(count * sizeof(ARGB));
764                 if (!presetArgb)
765                         return lastStatus = OutOfMemory;
766
767                 Status status = updateStatus(DllExports::GdipGetPathGradientPresetBlend(
768                                 (GpPathGradient*) nativeBrush,
769                                 presetArgb, blendPositions, count));
770                 for (INT i = 0; i < count; ++i) {
771                         presetColors[i].SetValue(presetArgb[i]);
772                 }
773                 DllExports::GdipFree((void*) presetArgb);
774                 return status;
775         }
776         INT GetPointCount() const
777         {
778                 INT result = 0;
779                 updateStatus(DllExports::GdipGetPathGradientPointCount(
780                                 (GpPathGradient*) nativeBrush, &result));
781                 return result;
782         }
783         Status GetRectangle(RectF *rect) const
784         {
785                 return updateStatus(DllExports::GdipGetPathGradientRect(
786                                 (GpPathGradient*) nativeBrush, rect));
787         }
788         Status GetRectangle(Rect *rect) const
789         {
790                 return updateStatus(DllExports::GdipGetPathGradientRectI(
791                                 (GpPathGradient*) nativeBrush, rect));
792         }
793         INT GetSurroundColorCount() const
794         {
795                 INT result = 0;
796                 updateStatus(DllExports::GdipGetPathGradientSurroundColorCount(
797                                 (GpPathGradient*) nativeBrush, &result));
798                 return result;
799         }
800         Status GetSurroundColors(Color *colors, INT *count)
801         {
802                 if (!colors || !count || *count <= 0)
803                         return lastStatus = InvalidParameter;
804
805                 ARGB *colorsArgb =
806                         (ARGB*) DllExports::GdipAlloc(*count * sizeof(ARGB));
807                 if (!colorsArgb)
808                         return lastStatus = OutOfMemory;
809
810                 Status status = updateStatus(DllExports::GdipGetPathGradientSurroundColorsWithCount(
811                                 (GpPathGradient*) nativeBrush,
812                                 colorsArgb, count));
813                 for (INT i = 0; i < *count; ++i) {
814                         colors[i].SetValue(colorsArgb[i]);
815                 }
816                 DllExports::GdipFree((void*) colorsArgb);
817                 return status;
818         }
819         Status GetTransform(Matrix *matrix) const
820         {
821                 return updateStatus(DllExports::GdipGetPathGradientTransform(
822                                 (GpPathGradient*) nativeBrush,
823                                 matrix ? matrix->nativeMatrix : NULL));
824         }
825         WrapMode GetWrapMode() const
826         {
827                 WrapMode result = WrapModeTile;
828                 updateStatus(DllExports::GdipGetPathGradientWrapMode(
829                                 (GpPathGradient*) nativeBrush, &result));
830                 return result;
831         }
832         Status MultiplyTransform(const Matrix *matrix,
833                         MatrixOrder order = MatrixOrderPrepend)
834         {
835                 return updateStatus(DllExports::GdipMultiplyPathGradientTransform(
836                                 (GpPathGradient*) nativeBrush,
837                                 matrix ? matrix->nativeMatrix : NULL, order));
838         }
839         Status ResetTransform()
840         {
841                 return updateStatus(DllExports::GdipResetPathGradientTransform(
842                                 (GpPathGradient*) nativeBrush));
843         }
844         Status RotateTransform(REAL angle,
845                         MatrixOrder order = MatrixOrderPrepend)
846         {
847                 return updateStatus(DllExports::GdipRotatePathGradientTransform(
848                                 (GpPathGradient*) nativeBrush, angle, order));
849         }
850         Status ScaleTransform(REAL sx, REAL sy,
851                         MatrixOrder order = MatrixOrderPrepend)
852         {
853                 return updateStatus(DllExports::GdipScalePathGradientTransform(
854                                 (GpPathGradient*) nativeBrush, sx, sy, order));
855         }
856         Status SetBlend(REAL *blendFactors, REAL *blendPositions, INT count)
857         {
858                 return updateStatus(DllExports::GdipSetPathGradientBlend(
859                                 (GpPathGradient*) nativeBrush,
860                                 blendFactors, blendPositions, count));
861         }
862         Status SetBlendBellShape(REAL focus, REAL scale = 1.0f)
863         {
864                 return updateStatus(DllExports::GdipSetPathGradientSigmaBlend(
865                                 (GpPathGradient*) nativeBrush, focus, scale));
866         }
867         Status SetBlendTriangularShape(REAL focus, REAL scale = 1.0f)
868         {
869                 return updateStatus(DllExports::GdipSetPathGradientLinearBlend(
870                                 (GpPathGradient*) nativeBrush, focus, scale));
871         }
872         Status SetCenterColor(const Color& color)
873         {
874                 return updateStatus(DllExports::GdipSetPathGradientCenterColor(
875                                 (GpPathGradient*) nativeBrush,
876                                 color.GetValue()));
877         }
878         Status SetCenterPoint(const PointF& point)
879         {
880                 return updateStatus(DllExports::GdipSetPathGradientCenterPoint(
881                                 (GpPathGradient*) nativeBrush, &point));
882         }
883         Status SetCenterPoint(const Point& point)
884         {
885                 return updateStatus(DllExports::GdipSetPathGradientCenterPointI(
886                                 (GpPathGradient*) nativeBrush, &point));
887         }
888         Status SetFocusScales(REAL xScale, REAL yScale)
889         {
890                 return updateStatus(DllExports::GdipSetPathGradientFocusScales(
891                                 (GpPathGradient*) nativeBrush, xScale, yScale));
892         }
893         Status SetGammaCorrection(BOOL useGammaCorrection)
894         {
895                 return updateStatus(DllExports::GdipSetPathGradientGammaCorrection(
896                                 (GpPathGradient*) nativeBrush,
897                                 useGammaCorrection));
898         }
899         //Status SetGraphicsPath(const GraphicsPath *path)
900         //{
901         //      // TODO: implement PathGradientBrush::SetGraphicsPath
902         //      return updateStatus(NotImplemented);
903         //}
904         Status SetInterpolationColors(const Color *presetColors,
905                         REAL *blendPositions, INT count)
906         {
907                 if (!presetColors || count <= 0)
908                         return lastStatus = InvalidParameter;
909
910                 ARGB *presetArgb =
911                         (ARGB*) DllExports::GdipAlloc(count * sizeof(ARGB));
912                 if (!presetArgb)
913                         return lastStatus = OutOfMemory;
914                 for (INT i = 0; i < count; ++i) {
915                         presetArgb[i] = presetColors[i].GetValue();
916                 }
917
918                 Status status = updateStatus(DllExports::GdipSetPathGradientPresetBlend(
919                                 (GpPathGradient*) nativeBrush,
920                                 presetArgb, blendPositions, count));
921                 DllExports::GdipFree((void*) presetArgb);
922                 return status;
923         }
924         Status SetSurroundColors(const Color *colors, INT *count)
925         {
926                 if (!colors || !count || *count <= 0)
927                         return lastStatus = InvalidParameter;
928
929                 ARGB *colorsArgb =
930                         (ARGB*) DllExports::GdipAlloc(*count * sizeof(ARGB));
931                 if (!colorsArgb)
932                         return lastStatus = OutOfMemory;
933                 for (INT i = 0; i < *count; ++i) {
934                         colorsArgb[i] = colors[i].GetValue();
935                 }
936
937                 Status status = updateStatus(DllExports::GdipSetPathGradientSurroundColorsWithCount(
938                                 (GpPathGradient*) nativeBrush,
939                                 colorsArgb, count));
940                 DllExports::GdipFree((void*) colorsArgb);
941                 return status;
942         }
943         Status SetTransform(const Matrix *matrix)
944         {
945                 return updateStatus(DllExports::GdipSetPathGradientTransform(
946                                 (GpPathGradient*) nativeBrush,
947                                 matrix ? matrix->nativeMatrix : NULL));
948         }
949         Status SetWrapMode(WrapMode wrapMode)
950         {
951                 return updateStatus(DllExports::GdipSetPathGradientWrapMode(
952                                 (GpPathGradient*) nativeBrush, wrapMode));
953         }
954         Status TranslateTransform(REAL dx, REAL dy,
955                         MatrixOrder order = MatrixOrderPrepend)
956         {
957                 return updateStatus(DllExports::GdipTranslatePathGradientTransform(
958                                 (GpPathGradient*) nativeBrush, dx, dy, order));
959         }
960
961 private:
962         PathGradientBrush(GpBrush *brush, Status status): Brush(brush, status) {}
963         PathGradientBrush(const PathGradientBrush&);
964         PathGradientBrush& operator=(const PathGradientBrush&);
965 };
966
967
968
969 #endif /* __GDIPLUS_PATH_H */