diff --git a/dlls/gdiplus/gdiplus.spec b/dlls/gdiplus/gdiplus.spec index c1d6725b3dc..ad0e44c21e0 100644 --- a/dlls/gdiplus/gdiplus.spec +++ b/dlls/gdiplus/gdiplus.spec @@ -330,7 +330,7 @@ @ stdcall GdipGetPathPoints(ptr ptr long) @ stub GdipGetPathPointsI @ stdcall GdipGetPathTypes(ptr ptr long) -@ stub GdipGetPathWorldBounds +@ stdcall GdipGetPathWorldBounds(ptr ptr ptr ptr) @ stub GdipGetPathWorldBoundsI @ stub GdipGetPenBrushFill @ stub GdipGetPenColor diff --git a/dlls/gdiplus/graphicspath.c b/dlls/gdiplus/graphicspath.c index 4665fca44d7..664cde2a17d 100644 --- a/dlls/gdiplus/graphicspath.c +++ b/dlls/gdiplus/graphicspath.c @@ -203,6 +203,58 @@ GpStatus WINGDIPAPI GdipGetPathTypes(GpPath *path, BYTE* types, INT count) return Ok; } +/* Windows expands the bounding box to the maximum possible bounding box + * for a given pen. For example, if a line join can extend past the point + * it's joining by x units, the bounding box is extended by x units in every + * direction (even though this is too conservative for most cases). */ +GpStatus WINGDIPAPI GdipGetPathWorldBounds(GpPath* path, GpRectF* bounds, + GDIPCONST GpMatrix *matrix, GDIPCONST GpPen *pen) +{ + /* extrema[0] is upper left corner of bounding box, + * extrema[1] is lower right corner */ + GpPointF extrema[2]; + GpPointF * points; + INT count, i; + + /* Matrix and pen can be null. */ + if(!path || !bounds) + return InvalidParameter; + + /* If path is empty just return. */ + count = path->pathdata.Count; + if(count == 0){ + bounds->X = bounds->Y = bounds->Width = bounds->Height = 0.0; + return Ok; + } + + /* FIXME: implement case where pen is non-NULL. */ + if(pen) + return NotImplemented; + + points = path->pathdata.Points; + extrema[0].X = extrema[1].X = points[0].X; + extrema[0].Y = extrema[1].Y = points[0].Y; + + for(i = 1; i < count; i++){ + extrema[0].X = min(points[i].X, extrema[0].X); + extrema[0].Y = min(points[i].Y, extrema[0].Y); + extrema[1].X = max(points[i].X, extrema[1].X); + extrema[1].Y = max(points[i].Y, extrema[1].Y); + } + + /* If matrix is non-null transform the points. */ + if(matrix){ + GdipTransformMatrixPoints((GpMatrix*)matrix, extrema, 2); + } + + bounds->X = extrema[0].X; + bounds->Y = extrema[0].Y; + bounds->Width = extrema[1].X - extrema[0].X; + bounds->Height = extrema[1].Y - extrema[0].Y; + + return Ok; +} + GpStatus WINGDIPAPI GdipGetPointCount(GpPath *path, INT *count) { if(!path) diff --git a/include/gdiplusflat.h b/include/gdiplusflat.h index 95dafde1b3d..4e5e95fd29e 100644 --- a/include/gdiplusflat.h +++ b/include/gdiplusflat.h @@ -57,6 +57,8 @@ GpStatus WINGDIPAPI GdipCreatePath(GpFillMode,GpPath**); GpStatus WINGDIPAPI GdipDeletePath(GpPath*); GpStatus WINGDIPAPI GdipGetPathPoints(GpPath*,GpPointF*,INT); GpStatus WINGDIPAPI GdipGetPathTypes(GpPath*,BYTE*,INT); +GpStatus WINGDIPAPI GdipGetPathWorldBounds(GpPath*,GpRectF*,GDIPCONST GpMatrix*, + GDIPCONST GpPen*); GpStatus WINGDIPAPI GdipGetPointCount(GpPath*,INT*); GpStatus WINGDIPAPI GdipStartPathFigure(GpPath*); GpStatus WINGDIPAPI GdipTransformPath(GpPath*,GpMatrix*); diff --git a/include/gdiplusgpstubs.h b/include/gdiplusgpstubs.h index 39bca1fd732..5c0226844b4 100644 --- a/include/gdiplusgpstubs.h +++ b/include/gdiplusgpstubs.h @@ -46,5 +46,6 @@ typedef PointF GpPointF; typedef FillMode GpFillMode; typedef PathData GpPathData; typedef LineCap GpLineCap; +typedef RectF GpRectF; #endif diff --git a/include/gdiplustypes.h b/include/gdiplustypes.h index 581041205e5..9404376416a 100644 --- a/include/gdiplustypes.h +++ b/include/gdiplustypes.h @@ -122,6 +122,16 @@ public: BYTE* Types; }; +/* FIXME: missing the methods. */ +class RectF +{ +public: + REAL X; + REAL Y; + REAL Width; + REAL Height; +}; + #else /* end of c++ typedefs */ typedef struct PointF @@ -137,6 +147,14 @@ typedef struct PathData BYTE* Types; } PathData; +typedef struct RectF +{ + REAL X; + REAL Y; + REAL Width; + REAL Height; +} RectF; + typedef enum Status Status; #endif /* end of c typedefs */