diff --git a/dlls/gdiplus/gdiplus.spec b/dlls/gdiplus/gdiplus.spec index f3ebc6b1caf..4ab38bada03 100644 --- a/dlls/gdiplus/gdiplus.spec +++ b/dlls/gdiplus/gdiplus.spec @@ -16,7 +16,7 @@ @ stub GdipAddPathCurveI @ stub GdipAddPathEllipse @ stub GdipAddPathEllipseI -@ stub GdipAddPathLine2 +@ stdcall GdipAddPathLine2(ptr ptr long) @ stub GdipAddPathLine2I @ stub GdipAddPathLine @ stub GdipAddPathLineI diff --git a/dlls/gdiplus/gdiplus_private.h b/dlls/gdiplus/gdiplus_private.h index b023c315035..7c5195a7d7c 100644 --- a/dlls/gdiplus/gdiplus_private.h +++ b/dlls/gdiplus/gdiplus_private.h @@ -52,9 +52,9 @@ struct GpSolidFill{ struct GpPath{ GpFillMode fill; - GpGraphics* graphics; GpPathData pathdata; BOOL newfigure; /* whether the next drawing action starts a new figure */ + INT datalen; /* size of the arrays in pathdata */ }; #endif diff --git a/dlls/gdiplus/graphicspath.c b/dlls/gdiplus/graphicspath.c index cce60c6a885..f8d2d49261c 100644 --- a/dlls/gdiplus/graphicspath.c +++ b/dlls/gdiplus/graphicspath.c @@ -30,11 +30,68 @@ WINE_DEFAULT_DEBUG_CHANNEL(gdiplus); +/* make sure path has enough space for len more points */ +static BOOL lengthen_path(GpPath *path, INT len) +{ + /* initial allocation */ + if(path->datalen == 0){ + path->datalen = len * 2; + + path->pathdata.Points = GdipAlloc(path->datalen * sizeof(PointF)); + if(!path->pathdata.Points) return FALSE; + + path->pathdata.Types = GdipAlloc(path->datalen); + if(!path->pathdata.Types){ + GdipFree(path->pathdata.Points); + return FALSE; + } + } + /* reallocation, double size of arrays */ + else if(path->datalen - path->pathdata.Count < len){ + while(path->datalen - path->pathdata.Count < len) + path->datalen *= 2; + + path->pathdata.Points = HeapReAlloc(GetProcessHeap(), 0, + path->pathdata.Points, path->datalen * sizeof(PointF)); + if(!path->pathdata.Points) return FALSE; + + path->pathdata.Types = HeapReAlloc(GetProcessHeap(), 0, + path->pathdata.Types, path->datalen); + if(!path->pathdata.Types) return FALSE; + } + + return TRUE; +} + +GpStatus WINGDIPAPI GdipAddPathLine2(GpPath *path, GDIPCONST GpPointF *points, + INT count) +{ + INT i, old_count = path->pathdata.Count; + + if(!path || !points) + return InvalidParameter; + + if(!lengthen_path(path, count + (path->newfigure ? 1 : 0))) + return OutOfMemory; + + for(i = 0; i < count; i++){ + path->pathdata.Points[old_count + i].X = points[i].X; + path->pathdata.Points[old_count + i].Y = points[i].Y; + path->pathdata.Types[old_count + i] = PathPointTypeLine; + } + + if(path->newfigure){ + path->pathdata.Types[old_count] = PathPointTypeStart; + path->newfigure = FALSE; + } + + path->pathdata.Count += count; + + return Ok; +} + GpStatus WINGDIPAPI GdipCreatePath(GpFillMode fill, GpPath **path) { - HDC hdc; - GpStatus ret; - if(!path) return InvalidParameter; @@ -44,24 +101,14 @@ GpStatus WINGDIPAPI GdipCreatePath(GpFillMode fill, GpPath **path) (*path)->fill = fill; (*path)->newfigure = TRUE; - hdc = GetDC(0); - ret = GdipCreateFromHDC(hdc, &((*path)->graphics)); - - if(ret != Ok){ - ReleaseDC(0, hdc); - GdipFree(*path); - } - - return ret; + return Ok; } GpStatus WINGDIPAPI GdipDeletePath(GpPath *path) { - if(!path || !(path->graphics)) + if(!path) return InvalidParameter; - ReleaseDC(0, path->graphics->hdc); - GdipDeleteGraphics(path->graphics); GdipFree(path); return Ok; diff --git a/include/gdiplusenums.h b/include/gdiplusenums.h index 16ded0dd9b8..1d00188d2d2 100644 --- a/include/gdiplusenums.h +++ b/include/gdiplusenums.h @@ -62,12 +62,24 @@ enum LineCap LineCapAnchorMask = 0xf0 }; +enum PathPointType{ + PathPointTypeStart = 0, /* start of a figure */ + PathPointTypeLine = 1, + PathPointTypeBezier = 3, + PathPointTypePathTypeMask = 7, + PathPointTypePathDashMode = 16, /* not used */ + PathPointTypePathMarker = 32, + PathPointTypeCloseSubpath = 128, /* end of a closed figure */ + PathPointTypeBezier3 = 3 +}; + #ifndef __cplusplus typedef enum Unit Unit; typedef enum BrushType BrushType; typedef enum FillMode FillMode; typedef enum LineCap LineCap; +typedef enum PathPointType PathPointType; #endif /* end of c typedefs */ diff --git a/include/gdiplusflat.h b/include/gdiplusflat.h index d308c2a5948..42a60b9ffc2 100644 --- a/include/gdiplusflat.h +++ b/include/gdiplusflat.h @@ -48,6 +48,7 @@ GpStatus WINGDIPAPI GdipCreateSolidFill(ARGB,GpSolidFill**); GpStatus WINGDIPAPI GdipGetBrushType(GpBrush*,GpBrushType*); GpStatus WINGDIPAPI GdipDeleteBrush(GpBrush*); +GpStatus WINGDIPAPI GdipAddPathLine2(GpPath*,GDIPCONST GpPointF*,INT); GpStatus WINGDIPAPI GdipCreatePath(GpFillMode,GpPath**); GpStatus WINGDIPAPI GdipDeletePath(GpPath*);