[2/2] gdiplus: implemented GdipPathIterNextSubpathPath with tests
Nikolay Sivov
bunglehead at gmail.com
Tue Aug 5 11:56:30 CDT 2008
Changelog:
- lengthen_path shared by moving to gdiplus.c to use for pathiterator
- implemented GdipPathIterNextSubpathPath with tests
- fixed GdipPathIterNextSubPath for result return value on empty path (with test)
---
dlls/gdiplus/gdiplus.c | 33 +++++++++
dlls/gdiplus/gdiplus.spec | 2 +-
dlls/gdiplus/gdiplus_private.h | 2 +
dlls/gdiplus/graphicspath.c | 33 ---------
dlls/gdiplus/pathiterator.c | 28 +++++++-
dlls/gdiplus/tests/pathiterator.c | 140 +++++++++++++++++++++++++++++++++++++
include/gdiplusflat.h | 1 +
7 files changed, 204 insertions(+), 35 deletions(-)
diff --git a/dlls/gdiplus/gdiplus.c b/dlls/gdiplus/gdiplus.c
index 070a80f..5e449e2 100644
--- a/dlls/gdiplus/gdiplus.c
+++ b/dlls/gdiplus/gdiplus.c
@@ -311,3 +311,36 @@ void calc_curve_bezier_endp(REAL xend, REAL yend, REAL xadj, REAL yadj,
*x = roundr(tension * (xadj - xend) + xend);
*y = roundr(tension * (yadj - yend) + yend);
}
+
+/* make sure path has enough space for len more points */
+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;
+}
diff --git a/dlls/gdiplus/gdiplus.spec b/dlls/gdiplus/gdiplus.spec
index 625c5a0..5ac1f1a 100644
--- a/dlls/gdiplus/gdiplus.spec
+++ b/dlls/gdiplus/gdiplus.spec
@@ -460,7 +460,7 @@
@ stub GdipPathIterNextMarkerPath
@ stub GdipPathIterNextPathType
@ stdcall GdipPathIterNextSubpath(ptr ptr ptr ptr ptr)
-@ stub GdipPathIterNextSubpathPath
+@ stdcall GdipPathIterNextSubpathPath(ptr ptr ptr ptr)
@ stdcall GdipPathIterRewind(ptr)
@ stub GdipPlayMetafileRecord
@ stub GdipPlayTSClientRecord
diff --git a/dlls/gdiplus/gdiplus_private.h b/dlls/gdiplus/gdiplus_private.h
index 3611239..5a18660 100644
--- a/dlls/gdiplus/gdiplus_private.h
+++ b/dlls/gdiplus/gdiplus_private.h
@@ -52,6 +52,8 @@ extern void calc_curve_bezier(CONST GpPointF *pts, REAL tension, REAL *x1,
extern void calc_curve_bezier_endp(REAL xend, REAL yend, REAL xadj, REAL yadj,
REAL tension, REAL *x, REAL *y);
+extern BOOL lengthen_path(GpPath *path, INT len);
+
static inline INT roundr(REAL x)
{
return (INT) floorf(x + 0.5);
diff --git a/dlls/gdiplus/graphicspath.c b/dlls/gdiplus/graphicspath.c
index 51407c7..d465aaf 100644
--- a/dlls/gdiplus/graphicspath.c
+++ b/dlls/gdiplus/graphicspath.c
@@ -33,39 +33,6 @@
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 GdipAddPathArc(GpPath *path, REAL x1, REAL y1, REAL x2,
REAL y2, REAL startAngle, REAL sweepAngle)
{
diff --git a/dlls/gdiplus/pathiterator.c b/dlls/gdiplus/pathiterator.c
index 5269b0c..2d27e40 100644
--- a/dlls/gdiplus/pathiterator.c
+++ b/dlls/gdiplus/pathiterator.c
@@ -164,8 +164,10 @@ GpStatus WINGDIPAPI GdipPathIterNextSubpath(GpPathIterator* iterator,
count = iterator->pathdata.Count;
/* iterator created with NULL path */
- if(count == 0)
+ if(count == 0){
+ *resultCount = 0;
return Ok;
+ }
if(iterator->subpath_pos == count){
*startIndex = *endIndex = *resultCount = 0;
@@ -235,3 +237,27 @@ GpStatus WINGDIPAPI GdipPathIterIsValid(GpPathIterator* iterator, BOOL* valid)
return Ok;
}
+
+GpStatus WINGDIPAPI GdipPathIterNextSubpathPath(GpPathIterator* iter, INT* result,
+ GpPath* path, BOOL* closed)
+{
+ INT start, end;
+
+ if(!iter || !result || !closed)
+ return InvalidParameter;
+
+ GdipPathIterNextSubpath(iter, result, &start, &end, closed);
+ /* return path */
+ if(((*result) > 0) && path){
+ GdipResetPath(path);
+
+ if(!lengthen_path(path, *result))
+ return OutOfMemory;
+
+ memcpy(path->pathdata.Points, &(iter->pathdata.Points[start]), sizeof(GpPointF)*(*result));
+ memcpy(path->pathdata.Types, &(iter->pathdata.Types[start]), sizeof(BYTE)*(*result));
+ path->pathdata.Count = *result;
+ }
+
+ return Ok;
+}
diff --git a/dlls/gdiplus/tests/pathiterator.c b/dlls/gdiplus/tests/pathiterator.c
index d318360..9cbed13 100644
--- a/dlls/gdiplus/tests/pathiterator.c
+++ b/dlls/gdiplus/tests/pathiterator.c
@@ -255,6 +255,144 @@ static void test_isvalid(void)
GdipDeletePath(path);
}
+static void test_nextsubpathpath(void)
+{
+ GpPath *path, *retpath;
+ GpPathIterator *iter;
+ GpStatus stat;
+ BOOL closed;
+ INT count, result;
+
+ GdipCreatePath(FillModeAlternate, &path);
+
+ /* NULL args */
+ GdipCreatePath(FillModeAlternate, &retpath);
+ GdipCreatePathIter(&iter, path);
+ stat = GdipPathIterNextSubpathPath(NULL, NULL, NULL, NULL);
+ expect(InvalidParameter, stat);
+ stat = GdipPathIterNextSubpathPath(iter, NULL, NULL, NULL);
+ expect(InvalidParameter, stat);
+ stat = GdipPathIterNextSubpathPath(NULL, &result, NULL, NULL);
+ expect(InvalidParameter, stat);
+ stat = GdipPathIterNextSubpathPath(iter, &result, NULL, &closed);
+ expect(Ok, stat);
+ stat = GdipPathIterNextSubpathPath(iter, NULL, NULL, &closed);
+ expect(InvalidParameter, stat);
+ stat = GdipPathIterNextSubpathPath(iter, NULL, retpath, NULL);
+ expect(InvalidParameter, stat);
+ stat = GdipPathIterNextSubpathPath(iter, &result, retpath, NULL);
+ expect(InvalidParameter, stat);
+ GdipDeletePathIter(iter);
+ GdipDeletePath(retpath);
+
+ /* empty path */
+ GdipCreatePath(FillModeAlternate, &retpath);
+ GdipCreatePathIter(&iter, path);
+ result = -2;
+ closed = TRUE;
+ stat = GdipPathIterNextSubpathPath(iter, &result, retpath, &closed);
+ expect(Ok, stat);
+ expect(0, result);
+ expect(TRUE, closed);
+ count = -1;
+ GdipGetPointCount(retpath, &count);
+ expect(0, count);
+ GdipDeletePathIter(iter);
+ GdipDeletePath(retpath);
+
+ /* open figure */
+ GdipAddPathLine(path, 5.0, 5.0, 100.0, 50.0);
+
+ GdipCreatePath(FillModeAlternate, &retpath);
+ GdipCreatePathIter(&iter, path);
+ result = -2;
+ closed = TRUE;
+ stat = GdipPathIterNextSubpathPath(iter, &result, retpath, &closed);
+ expect(Ok, stat);
+ expect(2, result);
+ expect(FALSE, closed);
+ count = -1;
+ GdipGetPointCount(retpath, &count);
+ expect(2, count);
+ /* subsequent call */
+ result = -2;
+ closed = TRUE;
+ stat = GdipPathIterNextSubpathPath(iter, &result, retpath, &closed);
+ expect(Ok, stat);
+ expect(0, result);
+ expect(TRUE, closed);
+ count = -1;
+ GdipGetPointCount(retpath, &count);
+ expect(2, count);
+ GdipDeletePathIter(iter);
+
+ /* closed figure, check does it extend retpath or reset it */
+ GdipAddPathLine(retpath, 50.0, 55.0, 200.0, 150.0);
+
+ GdipClosePathFigure(path);
+ GdipAddPathLine(path, 50.0, 55.0, 200.0, 150.0);
+ GdipClosePathFigure(path);
+
+ GdipCreatePathIter(&iter, path);
+ result = -2;
+ closed = FALSE;
+ stat = GdipPathIterNextSubpathPath(iter, &result, retpath, &closed);
+ expect(Ok, stat);
+ expect(2, result);
+ expect(TRUE, closed);
+ count = -1;
+ GdipGetPointCount(retpath, &count);
+ expect(2, count);
+ /* subsequent call */
+ result = -2;
+ closed = FALSE;
+ stat = GdipPathIterNextSubpathPath(iter, &result, retpath, &closed);
+ expect(Ok, stat);
+ expect(2, result);
+ expect(TRUE, closed);
+ count = -1;
+ GdipGetPointCount(retpath, &count);
+ expect(2, count);
+ result = -2;
+ closed = FALSE;
+ stat = GdipPathIterNextSubpathPath(iter, &result, retpath, &closed);
+ expect(Ok, stat);
+ expect(0, result);
+ expect(TRUE, closed);
+ count = -1;
+ GdipGetPointCount(retpath, &count);
+ expect(2, count);
+ GdipDeletePathIter(iter);
+
+ GdipDeletePath(retpath);
+ GdipDeletePath(path);
+}
+
+static void test_nextsubpath(void)
+{
+ GpPath *path;
+ GpPathIterator *iter;
+ GpStatus stat;
+ INT start, end, result;
+ BOOL closed;
+
+ GdipCreatePath(FillModeAlternate, &path);
+
+ /* empty path */
+ GdipCreatePath(FillModeAlternate, &path);
+ GdipCreatePathIter(&iter, path);
+
+ result = -2;
+ closed = TRUE;
+ stat = GdipPathIterNextSubpath(iter, &result, &start, &end, &closed);
+ expect(Ok, stat);
+ expect(0, result);
+ expect(TRUE, closed);
+ GdipCreatePathIter(&iter, path);
+
+ GdipDeletePath(path);
+}
+
START_TEST(pathiterator)
{
struct GdiplusStartupInput gdiplusStartupInput;
@@ -272,6 +410,8 @@ START_TEST(pathiterator)
test_nextmarker();
test_getsubpathcount();
test_isvalid();
+ test_nextsubpathpath();
+ test_nextsubpath();
GdiplusShutdown(gdiplusToken);
}
diff --git a/include/gdiplusflat.h b/include/gdiplusflat.h
index d7baf52..c0be696 100644
--- a/include/gdiplusflat.h
+++ b/include/gdiplusflat.h
@@ -328,6 +328,7 @@ GpStatus WINGDIPAPI GdipPathIterCopyData(GpPathIterator*,INT*,GpPointF*,BYTE*,
INT,INT);
GpStatus WINGDIPAPI GdipPathIterNextMarker(GpPathIterator*,INT*,INT*,INT*);
GpStatus WINGDIPAPI GdipPathIterNextSubpath(GpPathIterator*,INT*,INT*,INT*,BOOL*);
+GpStatus WINGDIPAPI GdipPathIterNextSubpathPath(GpPathIterator*,INT*,GpPath*,BOOL*);
GpStatus WINGDIPAPI GdipPathIterRewind(GpPathIterator*);
GpStatus WINGDIPAPI GdipPathIterGetCount(GpPathIterator*,INT*);
GpStatus WINGDIPAPI GdipPathIterGetSubpathCount(GpPathIterator*,INT*);
--
1.4.4.4
More information about the wine-patches
mailing list