I have covered implementation with additional test cases.
From: Bartosz Kosiorek gang65@poczta.onet.pl
--- dlls/gdiplus/pathiterator.c | 39 +++++++++- dlls/gdiplus/tests/pathiterator.c | 123 ++++++++++++++++++++++++------ 2 files changed, 137 insertions(+), 25 deletions(-)
diff --git a/dlls/gdiplus/pathiterator.c b/dlls/gdiplus/pathiterator.c index 2addbc3bc57..72d7ad74b87 100644 --- a/dlls/gdiplus/pathiterator.c +++ b/dlls/gdiplus/pathiterator.c @@ -222,6 +222,8 @@ GpStatus WINGDIPAPI GdipPathIterNextSubpath(GpPathIterator* iterator, }
*startIndex = iterator->subpath_pos; + /* Set new pathtype position */ + iterator->pathtype_pos = iterator->subpath_pos;
for(i = iterator->subpath_pos + 1; i < count && !(iterator->pathdata.Types[i] == PathPointTypeStart); i++); @@ -238,6 +240,7 @@ GpStatus WINGDIPAPI GdipPathIterNextSubpath(GpPathIterator* iterator,
return Ok; } +// FIXME not returning anything GpStatus WINGDIPAPI GdipPathIterRewind(GpPathIterator *iterator) { TRACE("(%p)\n", iterator); @@ -295,12 +298,42 @@ GpStatus WINGDIPAPI GdipPathIterIsValid(GpPathIterator* iterator, BOOL* valid) GpStatus WINGDIPAPI GdipPathIterNextPathType(GpPathIterator* iter, INT* result, BYTE* type, INT* start, INT* end) { - FIXME("(%p, %p, %p, %p, %p) stub\n", iter, result, type, start, end); + INT i, count, tempType; + TRACE("(%p, %p, %p, %p, %p)\n", iter, result, type, start, end);
- if(!iter || !result || !type || !start || !end) + if (!iter || !result || !type || !start || !end) return InvalidParameter;
- return NotImplemented; + count = iter->subpath_pos; + i = iter->pathtype_pos; + if (i >= count) { + *result = 0; + return Ok; + } + + /* set starting point to first PathPointTypeStart and */ + if ((iter->pathdata.Types[i] & PathPointTypePathTypeMask) == PathPointTypeStart) { + *start = i; + i++; + *end = i; + *type = iter->pathdata.Types[i] & PathPointTypePathTypeMask; + i++; + } + else + return Ok; + + if (iter->pathtype_pos < count) { + for ( ; i < count; i++) { + tempType = iter->pathdata.Types[i] & PathPointTypePathTypeMask; + if ((tempType != *type) || (tempType == PathPointTypeStart)) + break; + } + *end = i - 1; + iter->pathtype_pos = i; + } + *result = *end - *start + 1; + + return Ok; }
GpStatus WINGDIPAPI GdipPathIterNextSubpathPath(GpPathIterator* iter, INT* result, diff --git a/dlls/gdiplus/tests/pathiterator.c b/dlls/gdiplus/tests/pathiterator.c index 9bd3ac5452e..5c216d92d91 100644 --- a/dlls/gdiplus/tests/pathiterator.c +++ b/dlls/gdiplus/tests/pathiterator.c @@ -471,11 +471,32 @@ static void test_nextsubpath(void) GdipCreatePath(FillModeAlternate, &path); GdipCreatePathIter(&iter, path);
- result = -2; + result = start = end = (INT)0xdeadbeef; closed = TRUE; stat = GdipPathIterNextSubpath(iter, &result, &start, &end, &closed); expect(Ok, stat); expect(0, result); + expect((INT)0xdeadbeef, start); + expect((INT)0xdeadbeef, end); + expect(TRUE, closed); /* Not changed */ + + /* four points figure */ + GdipAddPathLine(path, 0.0, 0.0, 10.0, 30.0); + GdipAddPathLine(path, -10.0, 5.0, 15.0, 8.0); + GdipCreatePathIter(&iter, path); + stat = GdipPathIterNextSubpath(iter, &result, &start, &end, &closed); + expect(Ok, stat); + expect(4, result); + expect(0, start); + expect(3, end); + expect(FALSE, closed); + + /* No more subpaths*/ + stat = GdipPathIterNextSubpath(iter, &result, &start, &end, &closed); + expect(Ok, stat); + expect(0, result); + expect(0, start); + expect(0, end); expect(TRUE, closed);
GdipDeletePathIter(iter); @@ -487,8 +508,9 @@ static void test_nextpathtype(void) GpPath *path; GpPathIterator *iter; GpStatus stat; - INT start, end, result; + INT count, start, end, result; BYTE type; + BOOL closed;
GdipCreatePath(FillModeAlternate, &path); GdipCreatePathIter(&iter, path); @@ -512,49 +534,106 @@ static void test_nextpathtype(void) /* empty path */ start = end = result = (INT)0xdeadbeef; stat = GdipPathIterNextPathType(iter, &result, &type, &start, &end); - todo_wine expect(Ok, stat); + expect(Ok, stat); expect((INT)0xdeadbeef, start); expect((INT)0xdeadbeef, end); - todo_wine expect(0, result); + expect(0, result); GdipDeletePathIter(iter);
- /* single figure */ - GdipAddPathLine(path, 0.0, 0.0, 10.0, 30.0); + /* figure with two subpaths */ + stat = GdipAddPathLine(path, 0.0, 0.0, 10.0, 30.0); + expect(Ok, stat); + stat = GdipAddPathRectangle(path, 1.0, 2.0, 3.0, 4.0); + expect(Ok, stat); + stat = GdipAddPathEllipse(path, 0.0, 0.0, 35.0, 70.0); + expect(Ok, stat); GdipCreatePathIter(&iter, path); + + /* When pathIterator is not set, + it is not possible to get Path Type */ + result = -2; start = end = result = (INT)0xdeadbeef; type = 255; /* out of range */ stat = GdipPathIterNextPathType(iter, &result, &type, &start, &end); - todo_wine expect(Ok, stat); + expect(Ok, stat); expect((INT)0xdeadbeef, start); expect((INT)0xdeadbeef, end); expect(255, type); - todo_wine expect(0, result); - GdipDeletePathIter(iter); + expect(0, result);
- stat = GdipAddPathEllipse(path, 0.0, 0.0, 35.0, 70.0); + /* When pathIterator is not set, + it is possible to get number of path points */ + stat = GdipPathIterGetCount(iter, &count); expect(Ok, stat); - GdipCreatePathIter(&iter, path); + expect(19, count); + + /* When pathIteration is set, return PathType of line */ + result = start = end = (INT)0xdeadbeef; + closed = TRUE; + stat = GdipPathIterNextSubpath(iter, &result, &start, &end, &closed); + expect(Ok, stat); + expect(2, result); + expect(0, start); + expect(1, end); + expect(FALSE, closed); + /* Return two points with standard line */ + result = -2; start = end = result = (INT)0xdeadbeef; type = 255; /* out of range */ stat = GdipPathIterNextPathType(iter, &result, &type, &start, &end); - todo_wine expect(Ok, stat); - expect((INT)0xdeadbeef, start); - expect((INT)0xdeadbeef, end); - expect(255, type); - todo_wine expect(0, result); - GdipDeletePathIter(iter); + expect(Ok, stat); + expect(0, start); + expect(1, end); + expect(1, type); + expect(2, result);
- /* closed */ - GdipClosePathFigure(path); - GdipCreatePathIter(&iter, path); + /* When NextSubpath is running twice, without NextPathType (skipping Rectangle), + make sure that PathType index is updated */ + result = start = end = (INT)0xdeadbeef; + closed = TRUE; + stat = GdipPathIterNextSubpath(iter, &result, &start, &end, &closed); + expect(Ok, stat); + expect(4, result); + expect(2, start); + expect(5, end); + expect(TRUE, closed); + + /* When pathIteration is incremented, return next subpath (Ellipse) */ + result = start = end = (INT)0xdeadbeef; + closed = TRUE; + stat = GdipPathIterNextSubpath(iter, &result, &start, &end, &closed); + expect(Ok, stat); + expect(13, result); + expect(6, start); + expect(18, end); + expect(TRUE, closed); + + stat = GdipPathIterNextPathType(iter, &result, &type, &start, &end); + expect(Ok, stat); + expect(6, start); + expect(18, end); + expect(3, type); + expect(13, result); + + /* When pathIteration is incremented, there is no more subpaths */ + result = start = end = (INT)0xdeadbeef; + closed = TRUE; + stat = GdipPathIterNextSubpath(iter, &result, &start, &end, &closed); + expect(Ok, stat); + expect(0, result); + expect(0, start); + expect(0, end); + expect(TRUE, closed); + + /* When no more elements, don't change output numbers */ start = end = result = (INT)0xdeadbeef; type = 255; /* out of range */ stat = GdipPathIterNextPathType(iter, &result, &type, &start, &end); - todo_wine expect(Ok, stat); + expect(Ok, stat); expect((INT)0xdeadbeef, start); expect((INT)0xdeadbeef, end); expect(255, type); - todo_wine expect(0, result); + expect(0, result); GdipDeletePathIter(iter);
GdipDeletePath(path);