www.pudn.com > GdiplusTest16.zip > GdiPlusPath.h


/**************************************************************************\ 
* 
* Copyright (c) 1998-2001, Microsoft Corp.  All Rights Reserved. 
* 
* Module Name: 
* 
*   GdiplusPath.h 
* 
* Abstract: 
* 
*   GDI+ Graphics Path class 
* 
\**************************************************************************/ 
 
#ifndef _GDIPLUSPATH_H 
#define _GDIPLUSPATH_H 
 
class GraphicsPath : public GdiplusBase 
{ 
public: 
    friend class Graphics; 
    friend class Region; 
    friend class PathGradientBrush; 
    friend class GraphicsPathIterator; 
    friend class CustomLineCap; 
 
    GraphicsPath(IN FillMode fillMode = FillModeAlternate) 
    { 
        nativePath = NULL; 
        lastResult = DllExports::GdipCreatePath(fillMode, &nativePath); 
    } 
 
    GraphicsPath(IN const PointF* points, 
                 IN const BYTE* types, 
                 IN INT count, 
                 IN FillMode fillMode = FillModeAlternate) 
    { 
        nativePath = NULL; 
        lastResult = DllExports::GdipCreatePath2(points, 
                                                 types, 
                                                 count, 
                                                 fillMode, 
                                                 &nativePath); 
    } 
 
    GraphicsPath(IN const Point* points, 
                 IN const BYTE* types, 
                 IN INT count, 
                 IN FillMode fillMode = FillModeAlternate) 
    { 
        nativePath = NULL; 
        lastResult = DllExports::GdipCreatePath2I(points, 
                                                  types, 
                                                  count, 
                                                  fillMode, 
                                                  &nativePath); 
    } 
 
    ~GraphicsPath() 
    { 
        DllExports::GdipDeletePath(nativePath); 
    } 
 
    GraphicsPath* Clone() const 
    { 
        GpPath *clonepath = NULL; 
 
        SetStatus(DllExports::GdipClonePath(nativePath, &clonepath)); 
 
        return new GraphicsPath(clonepath); 
    } 
 
    // Reset the path object to empty (and fill mode to FillModeAlternate) 
 
    Status Reset() 
    { 
        return SetStatus(DllExports::GdipResetPath(nativePath)); 
    } 
 
    FillMode GetFillMode() const 
    { 
        FillMode fillmode = FillModeAlternate; 
 
        SetStatus(DllExports::GdipGetPathFillMode(nativePath, &fillmode)); 
 
        return fillmode; 
    } 
 
    Status SetFillMode(IN FillMode fillmode) 
    { 
        return SetStatus(DllExports::GdipSetPathFillMode(nativePath,  
                                                         fillmode)); 
    } 
 
    Status GetPathData(OUT PathData* pathData) const 
    { 
        if (pathData == NULL)  
        { 
            return SetStatus(InvalidParameter); 
        } 
         
        INT count = GetPointCount(); 
         
        if ((count <= 0) || (pathData->Count>0 && pathData->CountCount = 0; 
            if (pathData->Points) 
            { 
                delete pathData->Points; 
                pathData->Points = NULL; 
            } 
 
            if (pathData->Types)  
            { 
                delete pathData->Types; 
                pathData->Types = NULL; 
            } 
 
            if (count <= 0) 
            { 
                return lastResult; 
            } 
        } 
 
        if (pathData->Count == 0)  
        { 
            pathData->Points = new PointF[count]; 
            if (pathData->Points == NULL)  
            { 
                return SetStatus(OutOfMemory); 
             
            } 
            pathData->Types = new byte[count]; 
            if (pathData->Types == NULL)  
            { 
                delete pathData->Points; 
                pathData->Points = NULL; 
 
                return SetStatus(OutOfMemory); 
            } 
            pathData->Count = count; 
        } 
 
        return SetStatus(DllExports::GdipGetPathData(nativePath, pathData)); 
    } 
 
    Status StartFigure() 
    { 
        return SetStatus(DllExports::GdipStartPathFigure(nativePath)); 
    } 
 
    Status CloseFigure() 
    { 
        return SetStatus(DllExports::GdipClosePathFigure(nativePath)); 
    } 
 
    Status CloseAllFigures() 
    { 
        return SetStatus(DllExports::GdipClosePathFigures(nativePath)); 
    } 
 
    Status SetMarker() 
    { 
        return SetStatus(DllExports::GdipSetPathMarker(nativePath)); 
    } 
 
    Status ClearMarkers() 
    { 
        return SetStatus(DllExports::GdipClearPathMarkers(nativePath)); 
    } 
 
    Status Reverse() 
    { 
        return SetStatus(DllExports::GdipReversePath(nativePath)); 
    } 
 
    Status GetLastPoint(OUT PointF* lastPoint) const 
    { 
        return SetStatus(DllExports::GdipGetPathLastPoint(nativePath,  
                                                          lastPoint)); 
    } 
 
    Status AddLine(IN const PointF& pt1,  
                   IN const PointF& pt2) 
    { 
        return AddLine(pt1.X, pt1.Y, pt2.X, pt2.Y); 
    } 
 
    Status AddLine(IN REAL x1, 
                   IN REAL y1,  
                   IN REAL x2,  
                   IN REAL y2) 
    { 
        return SetStatus(DllExports::GdipAddPathLine(nativePath, x1, y1,  
                                                     x2, y2)); 
    } 
 
    Status AddLines(IN const PointF* points,  
                    IN INT count) 
    { 
        return SetStatus(DllExports::GdipAddPathLine2(nativePath, points,  
                                                      count)); 
    } 
 
    Status AddLine(IN const Point& pt1,  
                   IN const Point& pt2) 
    { 
        return AddLine(pt1.X, 
                       pt1.Y, 
                       pt2.X, 
                       pt2.Y); 
    } 
 
    Status AddLine(IN INT x1,  
                   IN INT y1,  
                   IN INT x2,  
                   IN INT y2) 
    { 
        return SetStatus(DllExports::GdipAddPathLineI(nativePath, 
                                                     x1, 
                                                     y1, 
                                                     x2, 
                                                     y2)); 
    } 
 
    Status AddLines(IN const Point* points,  
                    IN INT count) 
    { 
        return SetStatus(DllExports::GdipAddPathLine2I(nativePath, 
                                                       points, 
                                                       count)); 
    } 
 
    Status AddArc(IN const RectF& rect,  
                  IN REAL startAngle,  
                  IN REAL sweepAngle) 
    { 
        return AddArc(rect.X, rect.Y, rect.Width, rect.Height, 
                      startAngle, sweepAngle); 
    } 
 
    Status AddArc(IN REAL x,  
                  IN REAL y,  
                  IN REAL width,  
                  IN REAL height, 
                  IN REAL startAngle,  
                  IN REAL sweepAngle) 
    { 
        return SetStatus(DllExports::GdipAddPathArc(nativePath, x, y, width,  
                                                    height, startAngle,  
                                                    sweepAngle)); 
    } 
 
    Status AddArc(IN const Rect& rect,  
                  IN REAL startAngle,  
                  IN REAL sweepAngle) 
    { 
        return AddArc(rect.X, rect.Y, rect.Width, rect.Height, 
                      startAngle, sweepAngle); 
    } 
 
    Status AddArc(IN INT x,  
                  IN INT y,  
                  IN INT width,  
                  IN INT height, 
                  IN REAL startAngle,  
                  IN REAL sweepAngle) 
    { 
        return SetStatus(DllExports::GdipAddPathArcI(nativePath, 
                                                    x, 
                                                    y, 
                                                    width, 
                                                    height, 
                                                    startAngle, 
                                                    sweepAngle)); 
    } 
 
    Status AddBezier(IN const PointF& pt1,  
                     IN const PointF& pt2, 
                     IN const PointF& pt3,  
                     IN const PointF& pt4) 
    { 
        return AddBezier(pt1.X, pt1.Y, pt2.X, pt2.Y, pt3.X, pt3.Y, pt4.X, 
                         pt4.Y); 
    } 
 
    Status AddBezier(IN REAL x1,  
                     IN REAL y1,  
                     IN REAL x2,  
                     IN REAL y2, 
                     IN REAL x3,  
                     IN REAL y3,  
                     IN REAL x4,  
                     IN REAL y4) 
    { 
        return SetStatus(DllExports::GdipAddPathBezier(nativePath, x1, y1, x2,  
                                                       y2, x3, y3, x4, y4)); 
    } 
 
    Status AddBeziers(IN const PointF* points,  
                      IN INT count) 
    { 
        return SetStatus(DllExports::GdipAddPathBeziers(nativePath, points,  
                                                        count)); 
    } 
 
    Status AddBezier(IN const Point& pt1,  
                     IN const Point& pt2, 
                     IN const Point& pt3,  
                     IN const Point& pt4) 
    { 
       return AddBezier(pt1.X, pt1.Y, pt2.X, pt2.Y, pt3.X, pt3.Y, pt4.X, 
                        pt4.Y); 
    } 
 
    Status AddBezier(IN INT x1,  
                     IN INT y1,  
                     IN INT x2,  
                     IN INT y2, 
                     IN INT x3, 
                     IN INT y3,  
                     IN INT x4,  
                     IN INT y4) 
    { 
       return SetStatus(DllExports::GdipAddPathBezierI(nativePath, 
                                                      x1, 
                                                      y1, 
                                                      x2, 
                                                      y2, 
                                                      x3, 
                                                      y3, 
                                                      x4, 
                                                      y4)); 
    } 
 
    Status AddBeziers(IN const Point* points, 
                      IN INT count) 
    { 
       return SetStatus(DllExports::GdipAddPathBeziersI(nativePath, 
                                                        points, 
                                                        count)); 
    } 
 
    Status AddCurve(IN const PointF* points,  
                    IN INT count) 
    { 
        return SetStatus(DllExports::GdipAddPathCurve(nativePath, 
                                                      points, 
                                                      count)); 
    } 
 
    Status AddCurve(IN const PointF* points,  
                    IN INT count, 
                    IN REAL tension) 
    { 
        return SetStatus(DllExports::GdipAddPathCurve2(nativePath, 
                                                       points, 
                                                       count, 
                                                       tension)); 
    } 
 
    Status AddCurve(IN const PointF* points,  
                    IN INT count,  
                    IN INT offset, 
                    IN INT numberOfSegments,  
                    IN REAL tension) 
    { 
        return SetStatus(DllExports::GdipAddPathCurve3(nativePath, 
                                                       points, 
                                                       count, 
                                                       offset, 
                                                       numberOfSegments, 
                                                       tension)); 
    } 
 
    Status AddCurve(IN const Point* points,  
                    IN INT count) 
    { 
       return SetStatus(DllExports::GdipAddPathCurveI(nativePath, 
                                                     points, 
                                                     count)); 
    } 
 
    Status AddCurve(IN const Point* points,  
                    IN INT count,  
                    IN REAL tension) 
    { 
       return SetStatus(DllExports::GdipAddPathCurve2I(nativePath, 
                                                      points, 
                                                      count, 
                                                      tension)); 
    } 
 
    Status AddCurve(IN const Point* points,  
                    IN INT count,  
                    IN INT offset, 
                    IN INT numberOfSegments,  
                    IN REAL tension) 
    { 
       return SetStatus(DllExports::GdipAddPathCurve3I(nativePath, 
                                                      points, 
                                                      count, 
                                                      offset, 
                                                      numberOfSegments, 
                                                      tension)); 
    } 
 
    Status AddClosedCurve(IN const PointF* points,  
                          IN INT count) 
    { 
        return SetStatus(DllExports::GdipAddPathClosedCurve(nativePath, 
                                                            points, 
                                                            count)); 
    } 
 
    Status AddClosedCurve(IN const PointF* points,  
                          IN INT count,  
                          IN REAL tension) 
    { 
        return SetStatus(DllExports::GdipAddPathClosedCurve2(nativePath, 
                                                             points, 
                                                             count, 
                                                             tension)); 
    } 
 
    Status AddClosedCurve(IN const Point* points,  
                          IN INT count) 
    { 
       return SetStatus(DllExports::GdipAddPathClosedCurveI(nativePath, 
                                                            points, 
                                                            count)); 
    } 
 
 
    Status AddClosedCurve(IN const Point* points,  
                          IN INT count, 
                          IN REAL tension) 
    { 
       return SetStatus(DllExports::GdipAddPathClosedCurve2I(nativePath, 
                                                             points, 
                                                             count, 
                                                             tension)); 
    } 
 
    Status AddRectangle(IN const RectF& rect) 
    { 
        return SetStatus(DllExports::GdipAddPathRectangle(nativePath, 
                                                          rect.X, 
                                                          rect.Y, 
                                                          rect.Width, 
                                                          rect.Height)); 
    } 
 
    Status AddRectangles(IN const RectF* rects,  
                         IN INT count) 
    { 
        return SetStatus(DllExports::GdipAddPathRectangles(nativePath, 
                                                           rects, 
                                                           count)); 
    } 
 
    Status AddRectangle(IN const Rect& rect) 
    { 
        return SetStatus(DllExports::GdipAddPathRectangleI(nativePath, 
                                                          rect.X, 
                                                          rect.Y, 
                                                          rect.Width, 
                                                          rect.Height)); 
    } 
 
    Status AddRectangles(IN const Rect* rects, INT count) 
    { 
        return SetStatus(DllExports::GdipAddPathRectanglesI(nativePath, 
                                                           rects, 
                                                           count)); 
    } 
 
    Status AddEllipse(IN const RectF& rect) 
    { 
        return AddEllipse(rect.X, rect.Y, rect.Width, rect.Height); 
    } 
 
    Status AddEllipse(IN REAL x,  
                      IN REAL y,  
                      IN REAL width,  
                      IN REAL height) 
    { 
        return SetStatus(DllExports::GdipAddPathEllipse(nativePath, 
                                                        x, 
                                                        y, 
                                                        width, 
                                                        height)); 
    } 
 
    Status AddEllipse(IN const Rect& rect) 
    { 
        return AddEllipse(rect.X, rect.Y, rect.Width, rect.Height); 
    } 
 
    Status AddEllipse(IN INT x,  
                      IN INT y,  
                      IN INT width,  
                      IN INT height) 
    { 
        return SetStatus(DllExports::GdipAddPathEllipseI(nativePath, 
                                                        x, 
                                                        y, 
                                                        width, 
                                                        height)); 
    } 
 
    Status AddPie(IN const RectF& rect,  
                  IN REAL startAngle,  
                  IN REAL sweepAngle) 
    { 
        return AddPie(rect.X, rect.Y, rect.Width, rect.Height, startAngle, 
                      sweepAngle); 
    } 
 
    Status AddPie(IN REAL x,  
                  IN REAL y,  
                  IN REAL width,  
                  IN REAL height,  
                  IN REAL startAngle, 
                  IN REAL sweepAngle) 
    { 
        return SetStatus(DllExports::GdipAddPathPie(nativePath, x, y, width, 
                                                    height, startAngle,  
                                                    sweepAngle)); 
    } 
 
    Status AddPie(IN const Rect& rect,  
                  IN REAL startAngle,  
                  IN REAL sweepAngle) 
    { 
        return AddPie(rect.X, 
                      rect.Y, 
                      rect.Width, 
                      rect.Height, 
                      startAngle, 
                      sweepAngle); 
    } 
 
    Status AddPie(IN INT x,  
                  IN INT y,  
                  IN INT width,  
                  IN INT height,  
                  IN REAL startAngle, 
                  IN REAL sweepAngle) 
    { 
        return SetStatus(DllExports::GdipAddPathPieI(nativePath, 
                                                    x, 
                                                    y, 
                                                    width, 
                                                    height, 
                                                    startAngle, 
                                                    sweepAngle)); 
    } 
 
    Status AddPolygon(IN const PointF* points,  
                      IN INT count) 
    { 
        return SetStatus(DllExports::GdipAddPathPolygon(nativePath, points,  
                                                        count)); 
    } 
 
    Status AddPolygon(IN const Point* points,  
                      IN INT count) 
    { 
       return SetStatus(DllExports::GdipAddPathPolygonI(nativePath, points,  
                                                        count)); 
    } 
 
    Status AddPath(IN const GraphicsPath* addingPath,  
                   IN BOOL connect) 
    { 
        GpPath* nativePath2 = NULL; 
        if(addingPath) 
            nativePath2 = addingPath->nativePath; 
 
        return SetStatus(DllExports::GdipAddPathPath(nativePath, nativePath2,  
                                                     connect)); 
    } 
 
    Status AddString( 
        IN const WCHAR         *string, 
        IN INT                  length, 
        IN const FontFamily    *family, 
        IN INT                  style, 
        IN REAL                 emSize,  // World units 
        IN const PointF        &origin, 
        IN const StringFormat  *format 
    ) 
    { 
        RectF rect(origin.X, origin.Y, 0.0f, 0.0f); 
 
        return SetStatus(DllExports::GdipAddPathString( 
            nativePath, 
            string, 
            length, 
            family ? family->nativeFamily : NULL, 
            style, 
            emSize, 
            &rect, 
            format ? format->nativeFormat : NULL 
        )); 
    } 
 
    Status AddString( 
        IN const WCHAR         *string, 
        IN INT                  length, 
        IN const FontFamily    *family, 
        IN INT                  style, 
        IN REAL                 emSize,  // World units 
        IN const RectF         &layoutRect, 
        IN const StringFormat  *format 
    ) 
    { 
        return SetStatus(DllExports::GdipAddPathString( 
            nativePath, 
            string, 
            length, 
            family ? family->nativeFamily : NULL, 
            style, 
            emSize, 
            &layoutRect, 
            format ? format->nativeFormat : NULL 
        )); 
    } 
 
    Status AddString( 
        IN const WCHAR         *string, 
        IN INT                  length, 
        IN const FontFamily    *family, 
        IN INT                  style, 
        IN REAL                 emSize,  // World units 
        IN const Point         &origin, 
        IN const StringFormat  *format 
    ) 
    { 
        Rect rect(origin.X, origin.Y, 0, 0); 
 
        return SetStatus(DllExports::GdipAddPathStringI( 
            nativePath, 
            string, 
            length, 
            family ? family->nativeFamily : NULL, 
            style, 
            emSize, 
            &rect, 
            format ? format->nativeFormat : NULL 
        )); 
    } 
 
    Status AddString( 
        IN const WCHAR         *string, 
        IN INT                  length, 
        IN const FontFamily    *family, 
        IN INT                  style, 
        IN REAL                 emSize,  // World units 
        IN const Rect          &layoutRect, 
        IN const StringFormat  *format 
    ) 
    { 
        return SetStatus(DllExports::GdipAddPathStringI( 
            nativePath, 
            string, 
            length, 
            family ? family->nativeFamily : NULL, 
            style, 
            emSize, 
            &layoutRect, 
            format ? format->nativeFormat : NULL 
        )); 
    } 
     
    Status Transform(IN const Matrix* matrix) 
    { 
        if(matrix) 
            return SetStatus(DllExports::GdipTransformPath(nativePath,  
                                                      matrix->nativeMatrix)); 
        else 
            return Ok; 
    } 
 
    // This is not always the tightest bounds. 
 
    Status GetBounds(OUT RectF* bounds,  
                     IN const Matrix* matrix = NULL,  
                     IN const Pen* pen = NULL) const; 
 
    Status GetBounds(OUT Rect* bounds, 
                     IN const Matrix* matrix = NULL,  
                     IN const Pen* pen = NULL) const; 
 
    // Once flattened, the resultant path is made of line segments and 
    // the original path information is lost.  When matrix is NULL the 
    // identity matrix is assumed. 
         
    Status Flatten(IN const Matrix* matrix = NULL,  
                   IN REAL flatness = FlatnessDefault) 
    { 
        GpMatrix* nativeMatrix = NULL; 
        if(matrix) 
        { 
            nativeMatrix = matrix->nativeMatrix; 
        } 
 
        return SetStatus(DllExports::GdipFlattenPath( 
            nativePath,  
            nativeMatrix,  
            flatness 
        )); 
    } 
 
    Status Widen( 
        IN const Pen* pen,  
        IN const Matrix* matrix = NULL, 
        IN REAL flatness = FlatnessDefault 
    ) 
    { 
        GpMatrix* nativeMatrix = NULL; 
        if(matrix) 
            nativeMatrix = matrix->nativeMatrix; 
 
        return SetStatus(DllExports::GdipWidenPath( 
            nativePath,  
            pen->nativePen, 
            nativeMatrix,  
            flatness 
        )); 
    } 
 
    Status Outline( 
        IN const Matrix *matrix = NULL, 
        IN REAL flatness = FlatnessDefault 
    ) 
    { 
        GpMatrix* nativeMatrix = NULL; 
        if(matrix) 
        { 
            nativeMatrix = matrix->nativeMatrix; 
        } 
 
        return SetStatus(DllExports::GdipWindingModeOutline( 
            nativePath, nativeMatrix, flatness 
        )); 
    } 
     
    // Once this is called, the resultant path is made of line segments and 
    // the original path information is lost.  When matrix is NULL, the  
    // identity matrix is assumed. 
     
    Status Warp(IN const PointF* destPoints,  
                IN INT count, 
                IN const RectF& srcRect,  
                IN const Matrix* matrix = NULL, 
                IN WarpMode warpMode = WarpModePerspective, 
                IN REAL flatness = FlatnessDefault) 
    { 
        GpMatrix* nativeMatrix = NULL; 
        if(matrix) 
            nativeMatrix = matrix->nativeMatrix; 
 
        return SetStatus(DllExports::GdipWarpPath( 
                                        nativePath, 
                                        nativeMatrix, 
                                        destPoints, 
                                        count, 
                                        srcRect.X, 
                                        srcRect.Y, 
                                        srcRect.Width, 
                                        srcRect.Height, 
                                        warpMode, 
                                        flatness)); 
    } 
 
    INT GetPointCount() const 
    { 
        INT count = 0; 
 
        SetStatus(DllExports::GdipGetPointCount(nativePath, &count)); 
 
        return count; 
    } 
 
    Status GetPathTypes(OUT BYTE* types,  
                        IN INT count) const 
    { 
        return SetStatus(DllExports::GdipGetPathTypes(nativePath, types, 
                                                      count)); 
    } 
 
    Status GetPathPoints(OUT PointF* points,  
                         IN INT count) const 
    { 
        return SetStatus(DllExports::GdipGetPathPoints(nativePath, points,  
                                                       count)); 
    } 
 
    Status GetPathPoints(OUT Point* points,  
                         IN INT count) const 
    { 
        return SetStatus(DllExports::GdipGetPathPointsI(nativePath, points,  
                                                        count)); 
    } 
 
    Status GetLastStatus() const 
    { 
        Status lastStatus = lastResult; 
        lastResult = Ok; 
 
        return lastStatus; 
    } 
 
    BOOL IsVisible(IN const PointF& point,  
                   IN const Graphics* g = NULL) const 
    { 
        return IsVisible(point.X, point.Y, g); 
    } 
     
    BOOL IsVisible(IN REAL x,  
                   IN REAL y,  
                   IN const Graphics* g = NULL) const; 
 
    BOOL IsVisible(IN const Point& point, 
                   IN const Graphics* g = NULL) const 
    { 
        return IsVisible(point.X, point.Y, g); 
    } 
 
    BOOL IsVisible(IN INT x,  
                   IN INT y,  
                   IN const Graphics* g = NULL) const; 
     
    BOOL IsOutlineVisible(IN const PointF& point, 
                          IN const Pen* pen,  
                          IN const Graphics* g = NULL) const 
    { 
        return IsOutlineVisible(point.X, point.Y, pen, g); 
    } 
 
    BOOL IsOutlineVisible(IN REAL x,  
                          IN REAL y,  
                          IN const Pen* pen,  
                          IN const Graphics* g = NULL) const; 
 
    BOOL IsOutlineVisible(IN const Point& point, 
                          IN const Pen* pen,  
                          IN const Graphics* g = NULL) const 
    { 
        return IsOutlineVisible(point.X, point.Y, pen, g); 
    } 
     
    BOOL IsOutlineVisible(IN INT x,  
                          IN INT y,  
                          IN const Pen* pen,  
                          IN const Graphics* g = NULL) const; 
 
protected: 
 
    GraphicsPath(const GraphicsPath& path) 
    { 
        GpPath *clonepath = NULL; 
        SetStatus(DllExports::GdipClonePath(path.nativePath, &clonepath)); 
        SetNativePath(clonepath); 
    } 
 
private: 
    GraphicsPath& operator=(const GraphicsPath &); 
 
protected: 
    GraphicsPath(GpPath* nativePath) 
    { 
        lastResult = Ok; 
        SetNativePath(nativePath); 
    } 
 
    VOID SetNativePath(GpPath *nativePath) 
    { 
        this->nativePath = nativePath; 
    } 
 
    Status SetStatus(Status status) const 
    { 
        if (status != Ok) 
            return (lastResult = status); 
        else 
            return status; 
    } 
 
protected: 
    GpPath* nativePath; 
    mutable Status lastResult; 
}; 
 
 
//-------------------------------------------------------------------------- 
// GraphisPathIterator class 
//-------------------------------------------------------------------------- 
 
class GraphicsPathIterator : public GdiplusBase 
{ 
public: 
 
    GraphicsPathIterator(IN const GraphicsPath* path) 
    { 
        GpPath* nativePath = NULL; 
        if(path) 
            nativePath = path->nativePath; 
 
        GpPathIterator *iter = NULL; 
        lastResult = DllExports::GdipCreatePathIter(&iter, nativePath); 
        SetNativeIterator(iter); 
    } 
 
    ~GraphicsPathIterator() 
    { 
        DllExports::GdipDeletePathIter(nativeIterator); 
    } 
 
 
    INT NextSubpath(OUT INT* startIndex, 
                    OUT INT* endIndex, 
                    OUT BOOL* isClosed) 
    { 
        INT resultCount; 
 
        SetStatus(DllExports::GdipPathIterNextSubpath(nativeIterator, 
            &resultCount, startIndex, endIndex, isClosed)); 
 
        return resultCount; 
    } 
 
 
    INT NextSubpath(OUT const GraphicsPath* path,  
                    OUT BOOL* isClosed) 
    { 
        GpPath* nativePath = NULL; 
 
        INT resultCount; 
 
        if(path) 
            nativePath= path->nativePath; 
 
        SetStatus(DllExports::GdipPathIterNextSubpathPath(nativeIterator, 
            &resultCount, nativePath, isClosed)); 
 
        return resultCount; 
    } 
 
    INT NextPathType(OUT BYTE* pathType,  
                     OUT INT* startIndex,  
                     OUT INT* endIndex) 
    { 
        INT resultCount; 
 
        SetStatus(DllExports::GdipPathIterNextPathType(nativeIterator, 
            &resultCount, pathType, startIndex, endIndex)); 
 
        return resultCount; 
    } 
 
    INT NextMarker(OUT INT* startIndex,  
                   OUT INT* endIndex) 
    { 
        INT resultCount; 
 
        SetStatus(DllExports::GdipPathIterNextMarker(nativeIterator, 
            &resultCount, startIndex, endIndex)); 
 
        return resultCount; 
    } 
 
 
    INT NextMarker(OUT const GraphicsPath* path) 
    { 
        GpPath* nativePath = NULL; 
 
        INT resultCount; 
 
        if(path) 
            nativePath= path->nativePath; 
 
        SetStatus(DllExports::GdipPathIterNextMarkerPath(nativeIterator, 
            &resultCount, nativePath)); 
 
        return resultCount; 
    } 
 
    INT GetCount() const 
    { 
        INT resultCount; 
 
        SetStatus(DllExports::GdipPathIterGetCount(nativeIterator,  
                                                   &resultCount)); 
 
        return resultCount; 
    } 
 
    INT GetSubpathCount() const 
    { 
        INT resultCount; 
 
        SetStatus(DllExports::GdipPathIterGetSubpathCount(nativeIterator,  
                                                          &resultCount)); 
 
        return resultCount; 
    } 
 
    BOOL HasCurve() const 
    { 
        BOOL hasCurve; 
 
        SetStatus(DllExports::GdipPathIterHasCurve(nativeIterator, &hasCurve)); 
 
        return hasCurve; 
    } 
 
    VOID Rewind() 
    { 
        SetStatus(DllExports::GdipPathIterRewind(nativeIterator)); 
    } 
 
    INT Enumerate(OUT PointF *points, 
                  OUT BYTE *types,  
                  IN INT count) 
    { 
        INT resultCount; 
 
        SetStatus(DllExports::GdipPathIterEnumerate(nativeIterator, 
            &resultCount, points, types, count)); 
 
        return resultCount; 
    } 
 
    INT CopyData(OUT PointF* points,  
                 OUT BYTE* types, 
                 IN INT startIndex,  
                 IN INT endIndex) 
    { 
        INT resultCount; 
 
        SetStatus(DllExports::GdipPathIterCopyData(nativeIterator, 
            &resultCount, points, types, startIndex, endIndex)); 
 
        return resultCount; 
    } 
 
    Status GetLastStatus() const 
    { 
        Status lastStatus = lastResult; 
        lastResult = Ok; 
 
        return lastStatus; 
    } 
 
private: 
    GraphicsPathIterator(const GraphicsPathIterator &); 
    GraphicsPathIterator& operator=(const GraphicsPathIterator &); 
 
protected: 
    VOID SetNativeIterator(GpPathIterator *nativeIterator) 
    { 
        this->nativeIterator = nativeIterator; 
    } 
 
    Status SetStatus(Status status) const 
    { 
        if (status != Ok) 
            return (lastResult = status); 
        else 
            return status; 
    } 
 
protected: 
    GpPathIterator* nativeIterator; 
    mutable Status lastResult; 
}; 
 
 
//-------------------------------------------------------------------------- 
// Path Gradient Brush 
//-------------------------------------------------------------------------- 
 
class PathGradientBrush : public Brush 
{ 
public: 
    friend class Pen; 
 
    PathGradientBrush( 
        IN const PointF* points, 
        IN INT count, 
        IN WrapMode wrapMode = WrapModeClamp) 
    { 
        GpPathGradient *brush = NULL; 
 
        lastResult = DllExports::GdipCreatePathGradient( 
                                        points, count, 
                                        wrapMode, &brush); 
        SetNativeBrush(brush); 
    } 
 
    PathGradientBrush( 
        IN const Point* points, 
        IN INT count, 
        IN WrapMode wrapMode = WrapModeClamp) 
    { 
        GpPathGradient *brush = NULL; 
 
        lastResult = DllExports::GdipCreatePathGradientI( 
                                        points, count, 
                                        wrapMode, &brush); 
 
        SetNativeBrush(brush); 
    } 
 
    PathGradientBrush( 
        IN const GraphicsPath* path 
        ) 
    { 
        GpPathGradient *brush = NULL; 
 
        lastResult = DllExports::GdipCreatePathGradientFromPath( 
                                        path->nativePath, &brush); 
        SetNativeBrush(brush); 
    } 
 
    Status GetCenterColor(OUT Color* color) const 
    { 
        ARGB argb; 
         
        if (color == NULL)  
        { 
            return SetStatus(InvalidParameter); 
        } 
 
        SetStatus(DllExports::GdipGetPathGradientCenterColor( 
                       (GpPathGradient*) nativeBrush, &argb)); 
 
        color->SetValue(argb); 
 
        return lastResult; 
    } 
 
    Status SetCenterColor(IN const Color& color) 
    { 
        SetStatus(DllExports::GdipSetPathGradientCenterColor( 
                       (GpPathGradient*) nativeBrush, 
                       color.GetValue())); 
 
        return lastResult; 
    } 
 
    INT GetPointCount() const 
    { 
        INT count; 
 
        SetStatus(DllExports::GdipGetPathGradientPointCount( 
                       (GpPathGradient*) nativeBrush, &count)); 
 
        return count; 
    } 
 
    INT GetSurroundColorCount() const 
    { 
        INT count; 
 
        SetStatus(DllExports::GdipGetPathGradientSurroundColorCount( 
                       (GpPathGradient*) nativeBrush, &count)); 
 
        return count; 
    } 
 
    Status GetSurroundColors(OUT Color* colors,  
                             IN OUT INT* count) const 
    { 
        if(colors == NULL || count == NULL) 
        { 
            return SetStatus(InvalidParameter); 
        } 
 
        INT count1; 
         
        SetStatus(DllExports::GdipGetPathGradientSurroundColorCount( 
                        (GpPathGradient*) nativeBrush, &count1)); 
 
        if(lastResult != Ok) 
            return lastResult; 
 
        if((*count < count1) || (count1 <= 0)) 
            return SetStatus(InsufficientBuffer); 
 
        ARGB* argbs = (ARGB*) new ARGB[count1]; 
        if(argbs == NULL) 
            return SetStatus(OutOfMemory); 
 
        SetStatus(DllExports::GdipGetPathGradientSurroundColorsWithCount( 
                    (GpPathGradient*)nativeBrush, argbs, &count1)); 
 
        if(lastResult == Ok) 
        { 
            for(INT i = 0; i < count1; i++) 
            { 
                colors[i].SetValue(argbs[i]); 
            }         
            *count = count1; 
        } 
 
        delete [] argbs; 
        return lastResult; 
    } 
 
    Status SetSurroundColors(IN const Color* colors,  
                             IN OUT INT* count) 
    { 
        if(colors == NULL || count == NULL) 
        { 
            return SetStatus(InvalidParameter); 
        } 
 
        INT count1 = GetPointCount(); 
 
        if((*count > count1) || (count1 <= 0)) 
            return SetStatus(InvalidParameter); 
 
        count1 = *count; 
 
        ARGB* argbs = (ARGB*) new ARGB[count1]; 
        if(argbs == NULL) 
            return SetStatus(OutOfMemory); 
 
        for(INT i = 0; i < count1; i++) 
        { 
            argbs[i] = colors[i].GetValue(); 
        } 
 
        SetStatus(DllExports::GdipSetPathGradientSurroundColorsWithCount( 
                    (GpPathGradient*)nativeBrush, argbs, &count1)); 
 
        if(lastResult == Ok) 
            *count = count1; 
 
        delete [] argbs; 
 
        return lastResult; 
    } 
 
    Status GetGraphicsPath(OUT GraphicsPath* path) const 
    { 
        if(path == NULL) 
            return SetStatus(InvalidParameter); 
 
        return SetStatus(DllExports::GdipGetPathGradientPath( 
                    (GpPathGradient*)nativeBrush, path->nativePath)); 
    } 
 
    Status SetGraphicsPath(IN const GraphicsPath* path) 
    { 
        if(path == NULL) 
            return SetStatus(InvalidParameter); 
 
        return SetStatus(DllExports::GdipSetPathGradientPath( 
                    (GpPathGradient*)nativeBrush, path->nativePath)); 
    } 
 
    Status GetCenterPoint(OUT PointF* point) const 
    { 
        return SetStatus(DllExports::GdipGetPathGradientCenterPoint( 
                                (GpPathGradient*)nativeBrush, 
                                point)); 
    } 
 
    Status GetCenterPoint(OUT Point* point) const 
    { 
        return SetStatus(DllExports::GdipGetPathGradientCenterPointI( 
                                (GpPathGradient*)nativeBrush, 
                                point)); 
    } 
 
    Status SetCenterPoint(IN const PointF& point) 
    { 
        return SetStatus(DllExports::GdipSetPathGradientCenterPoint( 
                                (GpPathGradient*)nativeBrush, 
                                &point)); 
    } 
 
    Status SetCenterPoint(IN const Point& point) 
    { 
        return SetStatus(DllExports::GdipSetPathGradientCenterPointI( 
                                (GpPathGradient*)nativeBrush, 
                                &point)); 
    } 
 
    Status GetRectangle(OUT RectF* rect) const 
    { 
        return SetStatus(DllExports::GdipGetPathGradientRect( 
                            (GpPathGradient*)nativeBrush, rect)); 
    } 
 
    Status GetRectangle(OUT Rect* rect) const 
    { 
        return SetStatus(DllExports::GdipGetPathGradientRectI( 
                            (GpPathGradient*)nativeBrush, rect)); 
    } 
 
    Status SetGammaCorrection(IN BOOL useGammaCorrection) 
    { 
        return SetStatus(DllExports::GdipSetPathGradientGammaCorrection( 
            (GpPathGradient*)nativeBrush, useGammaCorrection)); 
    } 
 
    BOOL GetGammaCorrection() const 
    { 
        BOOL useGammaCorrection; 
 
        SetStatus(DllExports::GdipGetPathGradientGammaCorrection( 
            (GpPathGradient*)nativeBrush, &useGammaCorrection)); 
 
        return useGammaCorrection; 
    } 
 
    INT GetBlendCount() const 
    { 
       INT count = 0; 
 
       SetStatus(DllExports::GdipGetPathGradientBlendCount( 
                           (GpPathGradient*) nativeBrush, &count)); 
 
       return count; 
    } 
 
    Status GetBlend(OUT REAL* blendFactors, 
                    OUT REAL* blendPositions, 
                    IN INT count) const 
    { 
        return SetStatus(DllExports::GdipGetPathGradientBlend( 
                            (GpPathGradient*)nativeBrush, 
                            blendFactors, blendPositions, count)); 
    } 
 
    Status SetBlend(IN const REAL* blendFactors,  
                    IN const REAL* blendPositions,  
                    IN INT count) 
    { 
        return SetStatus(DllExports::GdipSetPathGradientBlend( 
                            (GpPathGradient*)nativeBrush, 
                            blendFactors, blendPositions, count)); 
    } 
 
    INT GetInterpolationColorCount() const 
    { 
       INT count = 0; 
 
       SetStatus(DllExports::GdipGetPathGradientPresetBlendCount( 
                        (GpPathGradient*) nativeBrush, &count)); 
 
       return count; 
    } 
 
    Status SetInterpolationColors(IN const Color* presetColors, 
                                  IN const REAL* blendPositions,  
                                  IN INT count) 
    { 
        if ((count <= 0) || !presetColors)  
        { 
            return SetStatus(InvalidParameter); 
        } 
 
        ARGB* argbs = (ARGB*) new ARGB[count]; 
        if(argbs) 
        { 
            for(INT i = 0; i < count; i++) 
            { 
                argbs[i] = presetColors[i].GetValue(); 
            } 
 
            Status status = SetStatus(DllExports:: 
                               GdipSetPathGradientPresetBlend( 
                                    (GpPathGradient*) nativeBrush, 
                                    argbs, 
                                    blendPositions, 
                                    count)); 
            delete[] argbs; 
            return status; 
        } 
        else 
        { 
            return SetStatus(OutOfMemory); 
        } 
    } 
 
    Status GetInterpolationColors(OUT Color* presetColors, 
                                  OUT REAL* blendPositions,  
                                  IN INT count) const 
    { 
        if ((count <= 0) || !presetColors)  
        { 
            return SetStatus(InvalidParameter); 
        } 
 
        ARGB* argbs = (ARGB*) new ARGB[count]; 
         
        if (!argbs) 
        { 
            return SetStatus(OutOfMemory); 
        } 
 
        GpStatus status = SetStatus(DllExports::GdipGetPathGradientPresetBlend( 
                                (GpPathGradient*)nativeBrush, 
                                argbs, 
                                blendPositions, 
                                count)); 
         
        for(INT i = 0; i < count; i++) 
        { 
            presetColors[i] = Color(argbs[i]); 
        } 
        delete [] argbs; 
         
        return status; 
    } 
 
    Status SetBlendBellShape(IN REAL focus,  
                             IN REAL scale = 1.0) 
    { 
        return SetStatus(DllExports::GdipSetPathGradientSigmaBlend( 
                            (GpPathGradient*)nativeBrush, focus, scale)); 
    } 
 
    Status SetBlendTriangularShape( 
        IN REAL focus, 
        IN REAL scale = 1.0 
    ) 
    { 
        return SetStatus(DllExports::GdipSetPathGradientLinearBlend( 
                            (GpPathGradient*)nativeBrush, focus, scale)); 
    } 
 
    Status GetTransform(OUT Matrix *matrix) const 
    { 
        return SetStatus(DllExports::GdipGetPathGradientTransform( 
                            (GpPathGradient*) nativeBrush,  
                            matrix->nativeMatrix)); 
    } 
 
    Status SetTransform(IN const Matrix* matrix) 
    { 
        return SetStatus(DllExports::GdipSetPathGradientTransform( 
                            (GpPathGradient*) nativeBrush,  
                            matrix->nativeMatrix)); 
    } 
 
    Status ResetTransform() 
    { 
        return SetStatus(DllExports::GdipResetPathGradientTransform( 
                            (GpPathGradient*)nativeBrush)); 
    } 
 
    Status MultiplyTransform(IN const Matrix* matrix, 
                             IN MatrixOrder order = MatrixOrderPrepend) 
    { 
        return SetStatus(DllExports::GdipMultiplyPathGradientTransform( 
                            (GpPathGradient*)nativeBrush, 
                            matrix->nativeMatrix, 
                            order)); 
    } 
 
    Status TranslateTransform(IN REAL dx,  
                              IN REAL dy, 
                              IN MatrixOrder order = MatrixOrderPrepend) 
    { 
        return SetStatus(DllExports::GdipTranslatePathGradientTransform( 
                            (GpPathGradient*)nativeBrush, 
                            dx, dy, order)); 
    } 
 
    Status ScaleTransform(IN REAL sx,  
                          IN REAL sy, 
                          IN MatrixOrder order = MatrixOrderPrepend) 
    { 
        return SetStatus(DllExports::GdipScalePathGradientTransform( 
                            (GpPathGradient*)nativeBrush, 
                            sx, sy, order)); 
    } 
 
    Status RotateTransform(IN REAL angle,  
                           IN MatrixOrder order = MatrixOrderPrepend) 
    { 
        return SetStatus(DllExports::GdipRotatePathGradientTransform( 
                            (GpPathGradient*)nativeBrush, 
                            angle, order)); 
    } 
 
    Status GetFocusScales(OUT REAL* xScale,  
                          OUT REAL* yScale) const 
    { 
        return SetStatus(DllExports::GdipGetPathGradientFocusScales( 
                            (GpPathGradient*) nativeBrush, xScale, yScale)); 
    } 
 
    Status SetFocusScales(IN REAL xScale, 
                          IN REAL yScale) 
    { 
        return SetStatus(DllExports::GdipSetPathGradientFocusScales( 
                            (GpPathGradient*) nativeBrush, xScale, yScale)); 
    } 
 
    WrapMode GetWrapMode() const 
    { 
        WrapMode wrapMode; 
 
        SetStatus(DllExports::GdipGetPathGradientWrapMode( 
                     (GpPathGradient*) nativeBrush, &wrapMode)); 
 
        return wrapMode; 
    } 
 
    Status SetWrapMode(IN WrapMode wrapMode) 
    { 
        return SetStatus(DllExports::GdipSetPathGradientWrapMode( 
                            (GpPathGradient*) nativeBrush, wrapMode)); 
    } 
 
private: 
    PathGradientBrush(const PathGradientBrush &); 
    PathGradientBrush& operator=(const PathGradientBrush &); 
 
protected: 
 
    PathGradientBrush() 
    { 
    } 
}; 
 
#endif // !_GRAPHICSPATH_HPP