Naveen Neel / shedskin
Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers gdipluspath.h Source File

gdipluspath.h

00001 /*
00002  * gdipluspath.h
00003  *
00004  * GDI+ GraphicsPath class
00005  *
00006  * This file is part of the w32api package.
00007  *
00008  * Contributors:
00009  *   Created by Markus Koenig <markus@stber-koenig.de>
00010  *
00011  * THIS SOFTWARE IS NOT COPYRIGHTED
00012  *
00013  * This source code is offered for use in the public domain. You may
00014  * use, modify or distribute it freely.
00015  *
00016  * This code is distributed in the hope that it will be useful but
00017  * WITHOUT ANY WARRANTY. ALL WARRANTIES, EXPRESS OR IMPLIED ARE HEREBY
00018  * DISCLAIMED. This includes but is not limited to warranties of
00019  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
00020  *
00021  */
00022 
00023 #ifndef __GDIPLUS_PATH_H
00024 #define __GDIPLUS_PATH_H
00025 #if __GNUC__ >=3
00026 #pragma GCC system_header
00027 #endif
00028 
00029 #ifndef __cplusplus
00030 #error "A C++ compiler is required to include gdipluspath.h."
00031 #endif
00032 
00033 // Note that some methods of GraphicsPath are implemented in gdiplusimpl.h.
00034 // This avoids a cyclic dependency on Graphics and Pen.
00035 
00036 class GraphicsPath: public GdiplusBase
00037 {
00038     friend class CustomLineCap;
00039     friend class Graphics;
00040     friend class GraphicsPathIterator;
00041     friend class PathGradientBrush;
00042     friend class Region;
00043 
00044 public:
00045     GraphicsPath(FillMode fillMode = FillModeAlternate):
00046             nativePath(NULL), lastStatus(Ok)
00047     {
00048         lastStatus = DllExports::GdipCreatePath(fillMode, &nativePath);
00049     }
00050     GraphicsPath(const PointF *points, const BYTE *types, INT count,
00051             FillMode fillMode = FillModeAlternate):
00052             nativePath(NULL), lastStatus(Ok)
00053     {
00054         lastStatus = DllExports::GdipCreatePath2(
00055                 points, types, count, fillMode, &nativePath);
00056     }
00057     GraphicsPath(const Point *points, const BYTE *types, INT count,
00058             FillMode fillMode = FillModeAlternate):
00059             nativePath(NULL), lastStatus(Ok)
00060     {
00061         lastStatus = DllExports::GdipCreatePath2I(
00062                 points, types, count, fillMode, &nativePath);
00063     }
00064     ~GraphicsPath()
00065     {
00066         DllExports::GdipDeletePath(nativePath);
00067     }
00068     GraphicsPath* Clone() const
00069     {
00070         GpPath *clonePath = NULL;
00071         Status status = updateStatus(DllExports::GdipClonePath(
00072                 nativePath, &clonePath));
00073         if (status == Ok) {
00074             GraphicsPath *result = new GraphicsPath(clonePath, lastStatus);
00075             if (!result) {
00076                 DllExports::GdipDeletePath(clonePath);
00077                 lastStatus = OutOfMemory;
00078             }
00079             return result;
00080         } else {
00081             return NULL;
00082         }
00083     }
00084 
00085     Status AddArc(REAL x, REAL y, REAL width, REAL height,
00086             REAL startAngle, REAL sweepAngle)
00087     {
00088         return updateStatus(DllExports::GdipAddPathArc(nativePath,
00089                 x, y, width, height, startAngle, sweepAngle));
00090     }
00091     Status AddArc(INT x, INT y, INT width, INT height,
00092             REAL startAngle, REAL sweepAngle)
00093     {
00094         return updateStatus(DllExports::GdipAddPathArcI(nativePath,
00095                 x, y, width, height, startAngle, sweepAngle));
00096     }
00097     Status AddArc(const RectF& rect, REAL startAngle, REAL sweepAngle)
00098     {
00099         return updateStatus(DllExports::GdipAddPathArc(nativePath,
00100                 rect.X, rect.Y, rect.Width, rect.Height,
00101                 startAngle, sweepAngle));
00102     }
00103     Status AddArc(const Rect& rect, REAL startAngle, REAL sweepAngle)
00104     {
00105         return updateStatus(DllExports::GdipAddPathArcI(nativePath,
00106                 rect.X, rect.Y, rect.Width, rect.Height,
00107                 startAngle, sweepAngle));
00108     }
00109     Status AddBezier(REAL x1, REAL y1, REAL x2, REAL y2,
00110             REAL x3, REAL y3, REAL x4, REAL y4)
00111     {
00112         return updateStatus(DllExports::GdipAddPathBezier(nativePath,
00113                 x1, y1, x2, y2, x3, y3, x4, y4));
00114     }
00115     Status AddBezier(INT x1, INT y1, INT x2, INT y2,
00116             INT x3, INT y3, INT x4, INT y4)
00117     {
00118         return updateStatus(DllExports::GdipAddPathBezierI(nativePath,
00119                 x1, y1, x2, y2, x3, y3, x4, y4));
00120     }
00121     Status AddBezier(const PointF& pt1, const PointF& pt2,
00122             const PointF& pt3, const PointF& pt4)
00123     {
00124         return updateStatus(DllExports::GdipAddPathBezier(nativePath,
00125                 pt1.X, pt1.Y, pt2.X, pt2.Y,
00126                 pt3.X, pt3.Y, pt4.X, pt4.Y));
00127     }
00128     Status AddBezier(const Point& pt1, const Point& pt2,
00129             const Point& pt3, const Point& pt4)
00130     {
00131         return updateStatus(DllExports::GdipAddPathBezierI(nativePath,
00132                 pt1.X, pt1.Y, pt2.X, pt2.Y,
00133                 pt3.X, pt3.Y, pt4.X, pt4.Y));
00134     }
00135     Status AddBeziers(const PointF *points, INT count)
00136     {
00137         return updateStatus(DllExports::GdipAddPathBeziers(
00138                 nativePath, points, count));
00139     }
00140     Status AddBeziers(const Point *points, INT count)
00141     {
00142         return updateStatus(DllExports::GdipAddPathBeziersI(
00143                 nativePath, points, count));
00144     }
00145     Status AddClosedCurve(const PointF *points, INT count)
00146     {
00147         return updateStatus(DllExports::GdipAddPathClosedCurve(
00148                 nativePath, points, count));
00149     }
00150     Status AddClosedCurve(const Point *points, INT count)
00151     {
00152         return updateStatus(DllExports::GdipAddPathClosedCurveI(
00153                 nativePath, points, count));
00154     }
00155     Status AddClosedCurve(const PointF *points, INT count, REAL tension)
00156     {
00157         return updateStatus(DllExports::GdipAddPathClosedCurve2(
00158                 nativePath, points, count, tension));
00159     }
00160     Status AddClosedCurve(const Point *points, INT count, REAL tension)
00161     {
00162         return updateStatus(DllExports::GdipAddPathClosedCurve2I(
00163                 nativePath, points, count, tension));
00164     }
00165     Status AddCurve(const PointF *points, INT count)
00166     {
00167         return updateStatus(DllExports::GdipAddPathCurve(
00168                 nativePath, points, count));
00169     }
00170     Status AddCurve(const Point *points, INT count)
00171     {
00172         return updateStatus(DllExports::GdipAddPathCurveI(
00173                 nativePath, points, count));
00174     }
00175     Status AddCurve(const PointF *points, INT count, REAL tension)
00176     {
00177         return updateStatus(DllExports::GdipAddPathCurve2(
00178                 nativePath, points, count, tension));
00179     }
00180     Status AddCurve(const Point *points, INT count, REAL tension)
00181     {
00182         return updateStatus(DllExports::GdipAddPathCurve2I(
00183                 nativePath, points, count, tension));
00184     }
00185     Status AddCurve(const PointF *points, INT count, INT offset,
00186             INT numberOfSegments, REAL tension)
00187     {
00188         return updateStatus(DllExports::GdipAddPathCurve3(
00189                 nativePath, points, count,
00190                 offset, numberOfSegments, tension));
00191     }
00192     Status AddCurve(const Point *points, INT count, INT offset,
00193             INT numberOfSegments, REAL tension)
00194     {
00195         return updateStatus(DllExports::GdipAddPathCurve3I(
00196                 nativePath, points, count,
00197                 offset, numberOfSegments, tension));
00198     }
00199     Status AddEllipse(REAL x, REAL y, REAL width, REAL height)
00200     {
00201         return updateStatus(DllExports::GdipAddPathEllipse(nativePath,
00202                 x, y, width, height));
00203     }
00204     Status AddEllipse(INT x, INT y, INT width, INT height)
00205     {
00206         return updateStatus(DllExports::GdipAddPathEllipseI(nativePath,
00207                 x, y, width, height));
00208     }
00209     Status AddEllipse(const RectF& rect)
00210     {
00211         return updateStatus(DllExports::GdipAddPathEllipse(nativePath,
00212                 rect.X, rect.Y, rect.Width, rect.Height));
00213     }
00214     Status AddEllipse(const Rect& rect)
00215     {
00216         return updateStatus(DllExports::GdipAddPathEllipseI(nativePath,
00217                 rect.X, rect.Y, rect.Width, rect.Height));
00218     }
00219     Status AddLine(REAL x1, REAL y1, REAL x2, REAL y2)
00220     {
00221         return updateStatus(DllExports::GdipAddPathLine(nativePath,
00222                 x1, y1, x2, y2));
00223     }
00224     Status AddLine(INT x1, INT y1, INT x2, INT y2)
00225     {
00226         return updateStatus(DllExports::GdipAddPathLineI(nativePath,
00227                 x1, y1, x2, y2));
00228     }
00229     Status AddLine(const PointF& pt1, const PointF& pt2)
00230     {
00231         return updateStatus(DllExports::GdipAddPathLine(nativePath,
00232                 pt1.X, pt1.Y, pt2.X, pt2.Y));
00233     }
00234     Status AddLine(const Point& pt1, const Point& pt2)
00235     {
00236         return updateStatus(DllExports::GdipAddPathLineI(nativePath,
00237                 pt1.X, pt1.Y, pt2.X, pt2.Y));
00238     }
00239     Status AddLines(const PointF *points, INT count)
00240     {
00241         return updateStatus(DllExports::GdipAddPathLine2(nativePath,
00242                 points, count));
00243     }
00244     Status AddLines(const Point *points, INT count)
00245     {
00246         return updateStatus(DllExports::GdipAddPathLine2I(nativePath,
00247                 points, count));
00248     }
00249     Status AddPath(const GraphicsPath *addingPath, BOOL connect)
00250     {
00251         return updateStatus(DllExports::GdipAddPathPath(nativePath,
00252                 addingPath ? addingPath->nativePath : NULL,
00253                 connect));
00254     }
00255     Status AddPie(REAL x, REAL y, REAL width, REAL height,
00256             REAL startAngle, REAL sweepAngle)
00257     {
00258         return updateStatus(DllExports::GdipAddPathPie(nativePath,
00259                 x, y, width, height, startAngle, sweepAngle));
00260     }
00261     Status AddPie(INT x, INT y, INT width, INT height,
00262             REAL startAngle, REAL sweepAngle)
00263     {
00264         return updateStatus(DllExports::GdipAddPathPieI(nativePath,
00265                 x, y, width, height, startAngle, sweepAngle));
00266     }
00267     Status AddPie(const RectF& rect, REAL startAngle, REAL sweepAngle)
00268     {
00269         return updateStatus(DllExports::GdipAddPathPie(nativePath,
00270                 rect.X, rect.Y, rect.Width, rect.Height,
00271                 startAngle, sweepAngle));
00272     }
00273     Status AddPie(const Rect& rect, REAL startAngle, REAL sweepAngle)
00274     {
00275         return updateStatus(DllExports::GdipAddPathPieI(nativePath,
00276                 rect.X, rect.Y, rect.Width, rect.Height,
00277                 startAngle, sweepAngle));
00278     }
00279     Status AddPolygon(const PointF *points, INT count)
00280     {
00281         return updateStatus(DllExports::GdipAddPathPolygon(nativePath,
00282                 points, count));
00283     }
00284     Status AddPolygon(const Point *points, INT count)
00285     {
00286         return updateStatus(DllExports::GdipAddPathPolygonI(nativePath,
00287                 points, count));
00288     }
00289     Status AddRectangle(const RectF& rect)
00290     {
00291         return updateStatus(DllExports::GdipAddPathRectangle(nativePath,
00292                 rect.X, rect.Y, rect.Width, rect.Height));
00293     }
00294     Status AddRectangle(const Rect& rect)
00295     {
00296         return updateStatus(DllExports::GdipAddPathRectangleI(
00297                 nativePath,
00298                 rect.X, rect.Y, rect.Width, rect.Height));
00299     }
00300     Status AddRectangles(const RectF *rects, INT count)
00301     {
00302         return updateStatus(DllExports::GdipAddPathRectangles(
00303                 nativePath, rects, count));
00304     }
00305     Status AddRectangles(const Rect *rects, INT count)
00306     {
00307         return updateStatus(DllExports::GdipAddPathRectanglesI(
00308                 nativePath, rects, count));
00309     }
00310     Status AddString(const WCHAR *string, INT length,
00311             const FontFamily *family, INT style, REAL emSize,
00312             const PointF& origin, const StringFormat *format)
00313     {
00314         RectF layoutRect(origin, SizeF(0.0f, 0.0f));
00315         return updateStatus(DllExports::GdipAddPathString(nativePath,
00316                 string, length,
00317                 family ? family->nativeFontFamily : NULL,
00318                 style, emSize, &layoutRect,
00319                 format ? format->nativeStringFormat : NULL));
00320     }
00321     Status AddString(const WCHAR *string, INT length,
00322             const FontFamily *family, INT style, REAL emSize,
00323             const Point& origin, const StringFormat *format)
00324     {
00325         Rect layoutRect(origin, Size(0, 0));
00326         return updateStatus(DllExports::GdipAddPathStringI(nativePath,
00327                 string, length,
00328                 family ? family->nativeFontFamily : NULL,
00329                 style, emSize, &layoutRect,
00330                 format ? format->nativeStringFormat : NULL));
00331     }
00332     Status AddString(const WCHAR *string, INT length,
00333             const FontFamily *family, INT style, REAL emSize,
00334             const RectF& layoutRect, const StringFormat *format)
00335     {
00336         return updateStatus(DllExports::GdipAddPathString(nativePath,
00337                 string, length,
00338                 family ? family->nativeFontFamily : NULL,
00339                 style, emSize, &layoutRect,
00340                 format ? format->nativeStringFormat : NULL));
00341     }
00342     Status AddString(const WCHAR *string, INT length,
00343             const FontFamily *family, INT style, REAL emSize,
00344             const Rect& layoutRect, const StringFormat *format)
00345     {
00346         return updateStatus(DllExports::GdipAddPathStringI(nativePath,
00347                 string, length,
00348                 family ? family->nativeFontFamily : NULL,
00349                 style, emSize, &layoutRect,
00350                 format ? format->nativeStringFormat : NULL));
00351     }
00352     Status ClearMarkers()
00353     {
00354         return updateStatus(DllExports::GdipClearPathMarkers(
00355                 nativePath));
00356     }
00357     Status CloseAllFigures()
00358     {
00359         return updateStatus(DllExports::GdipClosePathFigures(
00360                 nativePath));
00361     }
00362     Status CloseFigure()
00363     {
00364         return updateStatus(DllExports::GdipClosePathFigure(
00365                 nativePath));
00366     }
00367     Status Flatten(const Matrix *matrix = NULL,
00368             REAL flatness = FlatnessDefault)
00369     {
00370         return updateStatus(DllExports::GdipFlattenPath(nativePath,
00371                 matrix ? matrix->nativeMatrix : NULL,
00372                 flatness));
00373     }
00374     Status GetBounds(RectF *bounds, const Matrix *matrix = NULL,
00375             const Pen *pen = NULL) const
00376     {
00377         return updateStatus(DllExports::GdipGetPathWorldBounds(
00378                 nativePath, bounds,
00379                 matrix ? matrix->nativeMatrix : NULL,
00380                 pen ? pen->nativePen : NULL));
00381     }
00382     Status GetBounds(Rect *bounds, const Matrix *matrix = NULL,
00383             const Pen *pen = NULL) const
00384     {
00385         return updateStatus(DllExports::GdipGetPathWorldBoundsI(
00386                 nativePath, bounds,
00387                 matrix ? matrix->nativeMatrix : NULL,
00388                 pen ? pen->nativePen : NULL));
00389     }   
00390     FillMode GetFillMode() const
00391     {
00392         FillMode result = FillModeAlternate;
00393         updateStatus(DllExports::GdipGetPathFillMode(nativePath,
00394                 &result));
00395         return result;
00396     }
00397     Status GetLastPoint(PointF *lastPoint) const
00398     {
00399         return updateStatus(DllExports::GdipGetPathLastPoint(
00400                 nativePath, lastPoint));
00401     }
00402     Status GetLastStatus() const
00403     {
00404         Status result = lastStatus;
00405         lastStatus = Ok;
00406         return result;
00407     }
00408     Status GetPathData(PathData *pathData) const
00409     {
00410         if (!pathData) return lastStatus = InvalidParameter;
00411 
00412         Status status;
00413         INT count;
00414 
00415         status = updateStatus(DllExports::GdipGetPointCount(
00416                 nativePath, &count));
00417         if (status != Ok) return status;
00418 
00419         status = updateStatus(pathData->AllocateArrays(count));
00420         if (status != Ok) return status;
00421 
00422         return updateStatus(DllExports::GdipGetPathData(
00423                 nativePath, (GpPathData*) pathData));
00424     }
00425     Status GetPathPoints(PointF *points, INT count) const
00426     {
00427         return updateStatus(DllExports::GdipGetPathPoints(nativePath,
00428                 points, count));
00429     }
00430     Status GetPathPoints(Point *points, INT count) const
00431     {
00432         return updateStatus(DllExports::GdipGetPathPointsI(nativePath,
00433                 points, count));
00434     }
00435     Status GetPathTypes(BYTE *types, INT count) const
00436     {
00437         return updateStatus(DllExports::GdipGetPathTypes(nativePath,
00438                 types, count));
00439     }
00440     INT GetPointCount() const
00441     {
00442         INT result = 0;
00443         updateStatus(DllExports::GdipGetPointCount(nativePath,
00444                 &result));
00445         return result;
00446     }
00447     BOOL IsOutlineVisible(REAL x, REAL y, const Pen *pen,
00448             const Graphics *g = NULL) const;
00449     BOOL IsOutlineVisible(INT x, INT y, const Pen *pen,
00450             const Graphics *g = NULL) const;
00451     BOOL IsOutlineVisible(const PointF& point, const Pen *pen,
00452             const Graphics *g = NULL) const;
00453     BOOL IsOutlineVisible(const Point& point, const Pen *pen,
00454             const Graphics *g = NULL) const;
00455     BOOL IsVisible(REAL x, REAL y, const Graphics *g = NULL) const;
00456     BOOL IsVisible(INT x, INT y, const Graphics *g = NULL) const;
00457     BOOL IsVisible(const PointF& point, const Graphics *g = NULL) const;
00458     BOOL IsVisible(const Point& point, const Graphics *g = NULL) const;
00459     Status Outline(const Matrix *matrix = NULL,
00460             REAL flatness = FlatnessDefault)
00461     {
00462         return updateStatus(DllExports::GdipWindingModeOutline(
00463                 nativePath,
00464                 matrix ? matrix->nativeMatrix : NULL,
00465                 flatness));
00466     }
00467     Status Reset()
00468     {
00469         return updateStatus(DllExports::GdipResetPath(nativePath));
00470     }
00471     Status Reverse()
00472     {
00473         return updateStatus(DllExports::GdipReversePath(nativePath));
00474     }
00475     Status SetFillMode(FillMode fillMode)
00476     {
00477         return updateStatus(DllExports::GdipSetPathFillMode(
00478                 nativePath, fillMode));
00479     }
00480     Status SetMarker()
00481     {
00482         return updateStatus(DllExports::GdipSetPathMarker(nativePath));
00483     }
00484     Status StartFigure()
00485     {
00486         return updateStatus(DllExports::GdipStartPathFigure(
00487                 nativePath));
00488     }
00489     Status Transform(const Matrix *matrix)
00490     {
00491         return updateStatus(DllExports::GdipTransformPath(
00492                 nativePath,
00493                 matrix ? matrix->nativeMatrix : NULL));
00494     }
00495     Status Warp(const PointF *destPoints, INT count, const RectF& srcRect,
00496             const Matrix *matrix = NULL,
00497             WarpMode warpMode = WarpModePerspective,
00498             REAL flatness = FlatnessDefault)
00499     {
00500         return updateStatus(DllExports::GdipWarpPath(nativePath,
00501                 matrix ? matrix->nativeMatrix : NULL,
00502                 destPoints, count,
00503                 srcRect.X, srcRect.Y,
00504                 srcRect.Width, srcRect.Height,
00505                 warpMode, flatness));
00506     }
00507     Status Widen(const Pen *pen, const Matrix *matrix = NULL,
00508             REAL flatness = FlatnessDefault)
00509     {
00510         return updateStatus(DllExports::GdipWidenPath(nativePath,
00511                 pen ? pen->nativePen : NULL,
00512                 matrix ? matrix->nativeMatrix : NULL,
00513                 flatness));
00514     }
00515 
00516 private:
00517     GraphicsPath(GpPath *path, Status status):
00518         nativePath(path), lastStatus(status) {}
00519     GraphicsPath(const GraphicsPath&);
00520     GraphicsPath& operator=(const GraphicsPath&);
00521 
00522     Status updateStatus(Status newStatus) const
00523     {
00524         if (newStatus != Ok) lastStatus = newStatus;
00525         return newStatus;
00526     }
00527 
00528     GpPath *nativePath;
00529     mutable Status lastStatus;
00530 };
00531 
00532 class GraphicsPathIterator: public GdiplusBase
00533 {
00534 public:
00535     GraphicsPathIterator(GraphicsPath *path):
00536         nativePathIterator(NULL), lastStatus(Ok)
00537     {
00538         lastStatus = DllExports::GdipCreatePathIter(
00539                 &nativePathIterator,
00540                 path ? path->nativePath : NULL);
00541     }
00542     ~GraphicsPathIterator()
00543     {
00544         DllExports::GdipDeletePathIter(nativePathIterator);
00545     }
00546 
00547     INT CopyData(PointF *points, BYTE *types, INT startIndex, INT endIndex)
00548     {
00549         INT result = 0;
00550         updateStatus(DllExports::GdipPathIterCopyData(
00551                 nativePathIterator, &result,
00552                 points, types, startIndex, endIndex));
00553         return result;
00554     }
00555     INT Enumerate(PointF *points, BYTE *types, INT count)
00556     {
00557         INT result = 0;
00558         updateStatus(DllExports::GdipPathIterEnumerate(
00559                 nativePathIterator, &result,
00560                 points, types, count));
00561         return result;
00562     }
00563     INT GetCount() const
00564     {
00565         INT result = 0;
00566         updateStatus(DllExports::GdipPathIterGetCount(
00567                 nativePathIterator, &result));
00568         return result;
00569     }
00570     Status GetLastStatus() const
00571     {
00572         Status result = lastStatus;
00573         lastStatus = Ok;
00574         return result;
00575     }
00576     INT GetSubpathCount() const
00577     {
00578         INT result = 0;
00579         updateStatus(DllExports::GdipPathIterGetSubpathCount(
00580                 nativePathIterator, &result));
00581         return result;
00582     }
00583     BOOL HasCurve() const
00584     {
00585         BOOL result = FALSE;
00586         updateStatus(DllExports::GdipPathIterHasCurve(
00587                 nativePathIterator, &result));
00588         return result;
00589     }
00590     INT NextMarker(INT *startIndex, INT *endIndex)
00591     {
00592         INT result = 0;
00593         updateStatus(DllExports::GdipPathIterNextMarker(
00594                 nativePathIterator, &result,
00595                 startIndex, endIndex));
00596         return result;
00597     }
00598     INT NextMarker(GraphicsPath *path)
00599     {
00600         INT result = 0;
00601         updateStatus(DllExports::GdipPathIterNextMarkerPath(
00602                 nativePathIterator, &result,
00603                 path ? path->nativePath : NULL));
00604         return result;
00605     }
00606     INT NextPathType(BYTE *pathType, INT *startIndex, INT *endIndex)
00607     {
00608         INT result = 0;
00609         updateStatus(DllExports::GdipPathIterNextPathType(
00610                 nativePathIterator, &result,
00611                 pathType, startIndex, endIndex));
00612         return result;
00613     }
00614     INT NextSubpath(INT *startIndex, INT *endIndex, BOOL *isClosed)
00615     {
00616         INT result = 0;
00617         updateStatus(DllExports::GdipPathIterNextSubpath(
00618                 nativePathIterator, &result,
00619                 startIndex, endIndex, isClosed));
00620         return result;
00621     }
00622     INT NextSubpath(GraphicsPath *path, BOOL *isClosed)
00623     {
00624         INT result = 0;
00625         updateStatus(DllExports::GdipPathIterNextSubpathPath(
00626                 nativePathIterator, &result,
00627                 path ? path->nativePath : NULL, isClosed));
00628         return result;
00629     }
00630     VOID Rewind()
00631     {
00632         updateStatus(DllExports::GdipPathIterRewind(
00633                 nativePathIterator));
00634     }
00635 
00636 private:
00637     GraphicsPathIterator(GpPathIterator *pathIterator, Status status):
00638         nativePathIterator(pathIterator), lastStatus(status) {}
00639     GraphicsPathIterator(const GraphicsPathIterator&);
00640     GraphicsPathIterator& operator=(const GraphicsPathIterator&);
00641 
00642     Status updateStatus(Status newStatus) const
00643     {
00644         if (newStatus != Ok) lastStatus = newStatus;
00645         return newStatus;
00646     }
00647 
00648     GpPathIterator *nativePathIterator;
00649     mutable Status lastStatus;
00650 };
00651 
00652 class PathGradientBrush: public Brush
00653 {
00654 public:
00655     PathGradientBrush(const PointF *points, INT count,
00656             WrapMode wrapMode = WrapModeClamp)
00657     {
00658         GpPathGradient *nativePathGradient = NULL;
00659         lastStatus = DllExports::GdipCreatePathGradient(
00660                 points, count, wrapMode, &nativePathGradient);
00661         nativeBrush = nativePathGradient;
00662     }
00663     PathGradientBrush(const Point *points, INT count,
00664             WrapMode wrapMode = WrapModeClamp)
00665     {
00666         GpPathGradient *nativePathGradient = NULL;
00667         lastStatus = DllExports::GdipCreatePathGradientI(
00668                 points, count, wrapMode, &nativePathGradient);
00669         nativeBrush = nativePathGradient;
00670     }
00671     PathGradientBrush(const GraphicsPath *path)
00672     {
00673         GpPathGradient *nativePathGradient = NULL;
00674         lastStatus = DllExports::GdipCreatePathGradientFromPath(
00675                 path ? path->nativePath : NULL,
00676                 &nativePathGradient);
00677         nativeBrush = nativePathGradient;
00678     }
00679     virtual PathGradientBrush *Clone() const
00680     {
00681         GpBrush *cloneBrush = NULL;
00682         Status status = updateStatus(DllExports::GdipCloneBrush(
00683                 nativeBrush, &cloneBrush));
00684         if (status == Ok) {
00685             PathGradientBrush *result =
00686                 new PathGradientBrush(cloneBrush, lastStatus);
00687             if (!result) {
00688                 DllExports::GdipDeleteBrush(cloneBrush);
00689                 updateStatus(OutOfMemory);
00690             }
00691             return result;
00692         } else {
00693             return NULL;
00694         }
00695     }
00696 
00697     Status GetBlend(REAL *blendFactors, REAL *blendPositions,
00698             INT count) const
00699     {
00700         return updateStatus(DllExports::GdipGetPathGradientBlend(
00701                 (GpPathGradient*) nativeBrush,
00702                 blendFactors, blendPositions, count));
00703     }
00704     INT GetBlendCount() const
00705     {
00706         INT result = 0;
00707         updateStatus(DllExports::GdipGetPathGradientBlendCount(
00708                 (GpPathGradient*) nativeBrush, &result));
00709         return result;
00710     }
00711     Status GetCenterColor(Color *color) const
00712     {
00713         return updateStatus(DllExports::GdipGetPathGradientCenterColor(
00714                 (GpPathGradient*) nativeBrush,
00715                 color ? &color->Value : NULL));
00716     }
00717     Status GetCenterPoint(PointF *point) const
00718     {
00719         return updateStatus(DllExports::GdipGetPathGradientCenterPoint(
00720                 (GpPathGradient*) nativeBrush, point));
00721     }
00722     Status GetCenterPoint(Point *point) const
00723     {
00724         return updateStatus(DllExports::GdipGetPathGradientCenterPointI(
00725                 (GpPathGradient*) nativeBrush, point));
00726     }
00727     Status GetFocusScales(REAL *xScale, REAL *yScale) const
00728     {
00729         return updateStatus(DllExports::GdipGetPathGradientFocusScales(
00730                 (GpPathGradient*) nativeBrush, xScale, yScale));
00731     }
00732     BOOL GetGammaCorrection() const
00733     {
00734         BOOL result = FALSE;
00735         updateStatus(DllExports::GdipGetPathGradientGammaCorrection(
00736                 (GpPathGradient*) nativeBrush, &result));
00737         return result;
00738     }
00739     //Status GetGraphicsPath(GraphicsPath *path) const
00740     //{
00741     //  // TODO: implement PathGradientBrush::GetGraphicsPath
00742     //  return updateStatus(NotImplemented);
00743     //}
00744     INT GetInterpolationColorCount() const
00745     {
00746         INT result = 0;
00747         updateStatus(DllExports::GdipGetPathGradientPresetBlendCount(
00748                 (GpPathGradient*) nativeBrush, &result));
00749         return result;
00750     }
00751     Status GetInterpolationColors(Color *presetColors,
00752             REAL *blendPositions, INT count) const
00753     {
00754         if (!presetColors || count <= 0)
00755             return lastStatus = InvalidParameter;
00756 
00757         ARGB *presetArgb =
00758             (ARGB*) DllExports::GdipAlloc(count * sizeof(ARGB));
00759         if (!presetArgb)
00760             return lastStatus = OutOfMemory;
00761 
00762         Status status = updateStatus(DllExports::GdipGetPathGradientPresetBlend(
00763                 (GpPathGradient*) nativeBrush,
00764                 presetArgb, blendPositions, count));
00765         for (INT i = 0; i < count; ++i) {
00766             presetColors[i].SetValue(presetArgb[i]);
00767         }
00768         DllExports::GdipFree((void*) presetArgb);
00769         return status;
00770     }
00771     INT GetPointCount() const
00772     {
00773         INT result = 0;
00774         updateStatus(DllExports::GdipGetPathGradientPointCount(
00775                 (GpPathGradient*) nativeBrush, &result));
00776         return result;
00777     }
00778     Status GetRectangle(RectF *rect) const
00779     {
00780         return updateStatus(DllExports::GdipGetPathGradientRect(
00781                 (GpPathGradient*) nativeBrush, rect));
00782     }
00783     Status GetRectangle(Rect *rect) const
00784     {
00785         return updateStatus(DllExports::GdipGetPathGradientRectI(
00786                 (GpPathGradient*) nativeBrush, rect));
00787     }
00788     INT GetSurroundColorCount() const
00789     {
00790         INT result = 0;
00791         updateStatus(DllExports::GdipGetPathGradientSurroundColorCount(
00792                 (GpPathGradient*) nativeBrush, &result));
00793         return result;
00794     }
00795     Status GetSurroundColors(Color *colors, INT *count)
00796     {
00797         if (!colors || !count || *count <= 0)
00798             return lastStatus = InvalidParameter;
00799 
00800         ARGB *colorsArgb =
00801             (ARGB*) DllExports::GdipAlloc(*count * sizeof(ARGB));
00802         if (!colorsArgb)
00803             return lastStatus = OutOfMemory;
00804 
00805         Status status = updateStatus(DllExports::GdipGetPathGradientSurroundColorsWithCount(
00806                 (GpPathGradient*) nativeBrush,
00807                 colorsArgb, count));
00808         for (INT i = 0; i < *count; ++i) {
00809             colors[i].SetValue(colorsArgb[i]);
00810         }
00811         DllExports::GdipFree((void*) colorsArgb);
00812         return status;
00813     }
00814     Status GetTransform(Matrix *matrix) const
00815     {
00816         return updateStatus(DllExports::GdipGetPathGradientTransform(
00817                 (GpPathGradient*) nativeBrush,
00818                 matrix ? matrix->nativeMatrix : NULL));
00819     }
00820     WrapMode GetWrapMode() const
00821     {
00822         WrapMode result = WrapModeTile;
00823         updateStatus(DllExports::GdipGetPathGradientWrapMode(
00824                 (GpPathGradient*) nativeBrush, &result));
00825         return result;
00826     }
00827     Status MultiplyTransform(const Matrix *matrix,
00828             MatrixOrder order = MatrixOrderPrepend)
00829     {
00830         return updateStatus(DllExports::GdipMultiplyPathGradientTransform(
00831                 (GpPathGradient*) nativeBrush,
00832                 matrix ? matrix->nativeMatrix : NULL, order));
00833     }
00834     Status ResetTransform()
00835     {
00836         return updateStatus(DllExports::GdipResetPathGradientTransform(
00837                 (GpPathGradient*) nativeBrush));
00838     }
00839     Status RotateTransform(REAL angle,
00840             MatrixOrder order = MatrixOrderPrepend)
00841     {
00842         return updateStatus(DllExports::GdipRotatePathGradientTransform(
00843                 (GpPathGradient*) nativeBrush, angle, order));
00844     }
00845     Status ScaleTransform(REAL sx, REAL sy,
00846             MatrixOrder order = MatrixOrderPrepend)
00847     {
00848         return updateStatus(DllExports::GdipScalePathGradientTransform(
00849                 (GpPathGradient*) nativeBrush, sx, sy, order));
00850     }
00851     Status SetBlend(REAL *blendFactors, REAL *blendPositions, INT count)
00852     {
00853         return updateStatus(DllExports::GdipSetPathGradientBlend(
00854                 (GpPathGradient*) nativeBrush,
00855                 blendFactors, blendPositions, count));
00856     }
00857     Status SetBlendBellShape(REAL focus, REAL scale = 1.0f)
00858     {
00859         return updateStatus(DllExports::GdipSetPathGradientSigmaBlend(
00860                 (GpPathGradient*) nativeBrush, focus, scale));
00861     }
00862     Status SetBlendTriangularShape(REAL focus, REAL scale = 1.0f)
00863     {
00864         return updateStatus(DllExports::GdipSetPathGradientLinearBlend(
00865                 (GpPathGradient*) nativeBrush, focus, scale));
00866     }
00867     Status SetCenterColor(const Color& color)
00868     {
00869         return updateStatus(DllExports::GdipSetPathGradientCenterColor(
00870                 (GpPathGradient*) nativeBrush,
00871                 color.GetValue()));
00872     }
00873     Status SetCenterPoint(const PointF& point)
00874     {
00875         return updateStatus(DllExports::GdipSetPathGradientCenterPoint(
00876                 (GpPathGradient*) nativeBrush, &point));
00877     }
00878     Status SetCenterPoint(const Point& point)
00879     {
00880         return updateStatus(DllExports::GdipSetPathGradientCenterPointI(
00881                 (GpPathGradient*) nativeBrush, &point));
00882     }
00883     Status SetFocusScales(REAL xScale, REAL yScale)
00884     {
00885         return updateStatus(DllExports::GdipSetPathGradientFocusScales(
00886                 (GpPathGradient*) nativeBrush, xScale, yScale));
00887     }
00888     Status SetGammaCorrection(BOOL useGammaCorrection)
00889     {
00890         return updateStatus(DllExports::GdipSetPathGradientGammaCorrection(
00891                 (GpPathGradient*) nativeBrush,
00892                 useGammaCorrection));
00893     }
00894     //Status SetGraphicsPath(const GraphicsPath *path)
00895     //{
00896     //  // TODO: implement PathGradientBrush::SetGraphicsPath
00897     //  return updateStatus(NotImplemented);
00898     //}
00899     Status SetInterpolationColors(const Color *presetColors,
00900             REAL *blendPositions, INT count)
00901     {
00902         if (!presetColors || count <= 0)
00903             return lastStatus = InvalidParameter;
00904 
00905         ARGB *presetArgb =
00906             (ARGB*) DllExports::GdipAlloc(count * sizeof(ARGB));
00907         if (!presetArgb)
00908             return lastStatus = OutOfMemory;
00909         for (INT i = 0; i < count; ++i) {
00910             presetArgb[i] = presetColors[i].GetValue();
00911         }
00912 
00913         Status status = updateStatus(DllExports::GdipSetPathGradientPresetBlend(
00914                 (GpPathGradient*) nativeBrush,
00915                 presetArgb, blendPositions, count));
00916         DllExports::GdipFree((void*) presetArgb);
00917         return status;
00918     }
00919     Status SetSurroundColors(const Color *colors, INT *count)
00920     {
00921         if (!colors || !count || *count <= 0)
00922             return lastStatus = InvalidParameter;
00923 
00924         ARGB *colorsArgb =
00925             (ARGB*) DllExports::GdipAlloc(*count * sizeof(ARGB));
00926         if (!colorsArgb)
00927             return lastStatus = OutOfMemory;
00928         for (INT i = 0; i < *count; ++i) {
00929             colorsArgb[i] = colors[i].GetValue();
00930         }
00931 
00932         Status status = updateStatus(DllExports::GdipSetPathGradientSurroundColorsWithCount(
00933                 (GpPathGradient*) nativeBrush,
00934                 colorsArgb, count));
00935         DllExports::GdipFree((void*) colorsArgb);
00936         return status;
00937     }
00938     Status SetTransform(const Matrix *matrix)
00939     {
00940         return updateStatus(DllExports::GdipSetPathGradientTransform(
00941                 (GpPathGradient*) nativeBrush,
00942                 matrix ? matrix->nativeMatrix : NULL));
00943     }
00944     Status SetWrapMode(WrapMode wrapMode)
00945     {
00946         return updateStatus(DllExports::GdipSetPathGradientWrapMode(
00947                 (GpPathGradient*) nativeBrush, wrapMode));
00948     }
00949     Status TranslateTransform(REAL dx, REAL dy,
00950             MatrixOrder order = MatrixOrderPrepend)
00951     {
00952         return updateStatus(DllExports::GdipTranslatePathGradientTransform(
00953                 (GpPathGradient*) nativeBrush, dx, dy, order));
00954     }
00955 
00956 private:
00957     PathGradientBrush(GpBrush *brush, Status status): Brush(brush, status) {}
00958     PathGradientBrush(const PathGradientBrush&);
00959     PathGradientBrush& operator=(const PathGradientBrush&);
00960 };
00961 
00962 
00963 
00964 #endif /* __GDIPLUS_PATH_H */