Commit ef889d94 authored by Nikolay Sivov's avatar Nikolay Sivov Committed by Alexandre Julliard

gdiplus: Implemented GdipPathIterNextSubpathPath with tests.

parent 09950e3a
......@@ -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;
}
......@@ -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
......
......@@ -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);
......
......@@ -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)
{
......
......@@ -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;
}
......@@ -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);
}
......@@ -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*);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment