gdiplus: Implemented GdipPathIterNextSubpathPath with tests.
This commit is contained in:
parent
09950e3ab5
commit
ef889d94a3
|
@ -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*);
|
||||
|
|
Loading…
Reference in New Issue