From 96d66f16661f637f59abb3d209f7a72f04afcee1 Mon Sep 17 00:00:00 2001 From: Vincent Povirk Date: Mon, 20 Feb 2012 11:54:38 -0600 Subject: [PATCH] gdiplus: Store a real path in path gradient brushes. --- dlls/gdiplus/brush.c | 185 ++++++++++++++++------------------------- dlls/gdiplus/gdiplus_private.h | 2 +- 2 files changed, 74 insertions(+), 113 deletions(-) diff --git a/dlls/gdiplus/brush.c b/dlls/gdiplus/brush.c index 0b326ed1b1e..963aa74220d 100644 --- a/dlls/gdiplus/brush.c +++ b/dlls/gdiplus/brush.c @@ -61,30 +61,23 @@ GpStatus WINGDIPAPI GdipCloneBrush(GpBrush *brush, GpBrush **clone) case BrushTypePathGradient:{ GpPathGradient *src, *dest; INT count; + GpStatus stat; *clone = GdipAlloc(sizeof(GpPathGradient)); if (!*clone) return OutOfMemory; src = (GpPathGradient*) brush, dest = (GpPathGradient*) *clone; - count = src->pathdata.Count; memcpy(dest, src, sizeof(GpPathGradient)); - dest->pathdata.Count = count; - dest->pathdata.Points = GdipAlloc(count * sizeof(PointF)); - dest->pathdata.Types = GdipAlloc(count); + stat = GdipClonePath(src->path, &dest->path); - if(!dest->pathdata.Points || !dest->pathdata.Types){ - GdipFree(dest->pathdata.Points); - GdipFree(dest->pathdata.Types); + if(stat != Ok){ GdipFree(dest); - return OutOfMemory; + return stat; } - memcpy(dest->pathdata.Points, src->pathdata.Points, count * sizeof(PointF)); - memcpy(dest->pathdata.Types, src->pathdata.Types, count); - /* blending */ count = src->blendcount; dest->blendcount = count; @@ -92,8 +85,7 @@ GpStatus WINGDIPAPI GdipCloneBrush(GpBrush *brush, GpBrush **clone) dest->blendpos = GdipAlloc(count * sizeof(REAL)); if(!dest->blendfac || !dest->blendpos){ - GdipFree(dest->pathdata.Points); - GdipFree(dest->pathdata.Types); + GdipDeletePath(dest->path); GdipFree(dest->blendfac); GdipFree(dest->blendpos); GdipFree(dest); @@ -490,19 +482,16 @@ GpStatus WINGDIPAPI GdipCreateLineBrushFromRectWithAngleI(GDIPCONST GpRect* rect wrap, line); } -GpStatus WINGDIPAPI GdipCreatePathGradient(GDIPCONST GpPointF* points, - INT count, GpWrapMode wrap, GpPathGradient **grad) +static GpStatus create_path_gradient(GpPath *path, GpPathGradient **grad) { - TRACE("(%p, %d, %d, %p)\n", points, count, wrap, grad); - - if(!points || !grad) + if(!path || !grad) return InvalidParameter; - if(count <= 0) - return OutOfMemory; - *grad = GdipAlloc(sizeof(GpPathGradient)); - if (!*grad) return OutOfMemory; + if (!*grad) + { + return OutOfMemory; + } (*grad)->blendfac = GdipAlloc(sizeof(REAL)); (*grad)->blendpos = GdipAlloc(sizeof(REAL)); @@ -517,24 +506,13 @@ GpStatus WINGDIPAPI GdipCreatePathGradient(GDIPCONST GpPointF* points, (*grad)->blendpos[0] = 1.0; (*grad)->blendcount = 1; - (*grad)->pathdata.Count = count; - (*grad)->pathdata.Points = GdipAlloc(count * sizeof(PointF)); - (*grad)->pathdata.Types = GdipAlloc(count); - - if(!(*grad)->pathdata.Points || !(*grad)->pathdata.Types){ - GdipFree((*grad)->pathdata.Points); - GdipFree((*grad)->pathdata.Types); - GdipFree(*grad); - return OutOfMemory; - } - - memcpy((*grad)->pathdata.Points, points, count * sizeof(PointF)); - memset((*grad)->pathdata.Types, PathPointTypeLine, count); + (*grad)->path = path; (*grad)->brush.bt = BrushTypePathGradient; (*grad)->centercolor = 0xffffffff; - (*grad)->wrap = wrap; + (*grad)->wrap = WrapModeClamp; (*grad)->gamma = FALSE; + /* FIXME: this should be set to the "centroid" of the path by default */ (*grad)->center.X = 0.0; (*grad)->center.Y = 0.0; (*grad)->focus.X = 0.0; @@ -545,12 +523,11 @@ GpStatus WINGDIPAPI GdipCreatePathGradient(GDIPCONST GpPointF* points, return Ok; } -GpStatus WINGDIPAPI GdipCreatePathGradientI(GDIPCONST GpPoint* points, +GpStatus WINGDIPAPI GdipCreatePathGradient(GDIPCONST GpPointF* points, INT count, GpWrapMode wrap, GpPathGradient **grad) { - GpPointF *pointsF; - GpStatus ret; - INT i; + GpStatus stat; + GpPath *path; TRACE("(%p, %d, %d, %p)\n", points, count, wrap, grad); @@ -560,78 +537,77 @@ GpStatus WINGDIPAPI GdipCreatePathGradientI(GDIPCONST GpPoint* points, if(count <= 0) return OutOfMemory; - pointsF = GdipAlloc(sizeof(GpPointF) * count); - if(!pointsF) - return OutOfMemory; + stat = GdipCreatePath(FillModeAlternate, &path); + + if (stat == Ok) + { + stat = GdipAddPathLine2(path, points, count); + + if (stat == Ok) + stat = create_path_gradient(path, grad); - for(i = 0; i < count; i++){ - pointsF[i].X = (REAL)points[i].X; - pointsF[i].Y = (REAL)points[i].Y; + if (stat != Ok) + GdipDeletePath(path); } - ret = GdipCreatePathGradient(pointsF, count, wrap, grad); - GdipFree(pointsF); + return stat; +} - return ret; +GpStatus WINGDIPAPI GdipCreatePathGradientI(GDIPCONST GpPoint* points, + INT count, GpWrapMode wrap, GpPathGradient **grad) +{ + GpStatus stat; + GpPath *path; + + TRACE("(%p, %d, %d, %p)\n", points, count, wrap, grad); + + if(!points || !grad) + return InvalidParameter; + + if(count <= 0) + return OutOfMemory; + + stat = GdipCreatePath(FillModeAlternate, &path); + + if (stat == Ok) + { + stat = GdipAddPathLine2I(path, points, count); + + if (stat == Ok) + stat = create_path_gradient(path, grad); + + if (stat != Ok) + GdipDeletePath(path); + } + + return stat; } /****************************************************************************** * GdipCreatePathGradientFromPath [GDIPLUS.@] - * - * FIXME: path gradient brushes not truly supported (drawn as solid brushes) */ GpStatus WINGDIPAPI GdipCreatePathGradientFromPath(GDIPCONST GpPath* path, GpPathGradient **grad) { + GpStatus stat; + GpPath *new_path; + TRACE("(%p, %p)\n", path, grad); if(!path || !grad) return InvalidParameter; - *grad = GdipAlloc(sizeof(GpPathGradient)); - if (!*grad) return OutOfMemory; + stat = GdipClonePath((GpPath*)path, &new_path); - (*grad)->blendfac = GdipAlloc(sizeof(REAL)); - (*grad)->blendpos = GdipAlloc(sizeof(REAL)); - if(!(*grad)->blendfac || !(*grad)->blendpos){ - GdipFree((*grad)->blendfac); - GdipFree((*grad)->blendpos); - GdipFree(*grad); - *grad = NULL; - return OutOfMemory; - } - (*grad)->blendfac[0] = 1.0; - (*grad)->blendpos[0] = 1.0; - (*grad)->blendcount = 1; - - (*grad)->pathdata.Count = path->pathdata.Count; - (*grad)->pathdata.Points = GdipAlloc(path->pathdata.Count * sizeof(PointF)); - (*grad)->pathdata.Types = GdipAlloc(path->pathdata.Count); + if (stat == Ok) + { + stat = create_path_gradient(new_path, grad); - if(!(*grad)->pathdata.Points || !(*grad)->pathdata.Types){ - GdipFree((*grad)->pathdata.Points); - GdipFree((*grad)->pathdata.Types); - GdipFree(*grad); - return OutOfMemory; + if (stat != Ok) + GdipDeletePath(new_path); } - memcpy((*grad)->pathdata.Points, path->pathdata.Points, - path->pathdata.Count * sizeof(PointF)); - memcpy((*grad)->pathdata.Types, path->pathdata.Types, path->pathdata.Count); - - (*grad)->brush.bt = BrushTypePathGradient; - (*grad)->centercolor = 0xffffffff; - (*grad)->wrap = WrapModeClamp; - (*grad)->gamma = FALSE; - /* FIXME: this should be set to the "centroid" of the path by default */ - (*grad)->center.X = 0.0; - (*grad)->center.Y = 0.0; - (*grad)->focus.X = 0.0; - (*grad)->focus.Y = 0.0; - - TRACE("<-- %p\n", *grad); - - return Ok; + return stat; } /****************************************************************************** @@ -887,8 +863,7 @@ GpStatus WINGDIPAPI GdipDeleteBrush(GpBrush *brush) switch(brush->bt) { case BrushTypePathGradient: - GdipFree(((GpPathGradient*) brush)->pathdata.Points); - GdipFree(((GpPathGradient*) brush)->pathdata.Types); + GdipDeletePath(((GpPathGradient*) brush)->path); GdipFree(((GpPathGradient*) brush)->blendfac); GdipFree(((GpPathGradient*) brush)->blendpos); break; @@ -1052,15 +1027,13 @@ GpStatus WINGDIPAPI GdipGetPathGradientPointCount(GpPathGradient *grad, if(!grad || !count) return InvalidParameter; - *count = grad->pathdata.Count; + *count = grad->path->pathdata.Count; return Ok; } GpStatus WINGDIPAPI GdipGetPathGradientRect(GpPathGradient *brush, GpRectF *rect) { - GpRectF r; - GpPath* path; GpStatus stat; TRACE("(%p, %p)\n", brush, rect); @@ -1068,21 +1041,9 @@ GpStatus WINGDIPAPI GdipGetPathGradientRect(GpPathGradient *brush, GpRectF *rect if(!brush || !rect) return InvalidParameter; - stat = GdipCreatePath2(brush->pathdata.Points, brush->pathdata.Types, - brush->pathdata.Count, FillModeAlternate, &path); - if(stat != Ok) return stat; - - stat = GdipGetPathWorldBounds(path, &r, NULL, NULL); - if(stat != Ok){ - GdipDeletePath(path); - return stat; - } - - memcpy(rect, &r, sizeof(GpRectF)); + stat = GdipGetPathWorldBounds(brush->path, rect, NULL, NULL); - GdipDeletePath(path); - - return Ok; + return stat; } GpStatus WINGDIPAPI GdipGetPathGradientRectI(GpPathGradient *brush, GpRect *rect) @@ -1113,7 +1074,7 @@ GpStatus WINGDIPAPI GdipGetPathGradientSurroundColorsWithCount(GpPathGradient TRACE("(%p,%p,%p)\n", grad, argb, count); - if(!grad || !argb || !count || (*count < grad->pathdata.Count)) + if(!grad || !argb || !count || (*count < grad->path->pathdata.Count)) return InvalidParameter; if(!(calls++)) @@ -1531,7 +1492,7 @@ GpStatus WINGDIPAPI GdipSetPathGradientSurroundColorsWithCount(GpPathGradient TRACE("(%p,%p,%p)\n", grad, argb, count); if(!grad || !argb || !count || (*count <= 0) || - (*count > grad->pathdata.Count)) + (*count > grad->path->pathdata.Count)) return InvalidParameter; if(!(calls++)) diff --git a/dlls/gdiplus/gdiplus_private.h b/dlls/gdiplus/gdiplus_private.h index 20812900a03..909f48916e7 100644 --- a/dlls/gdiplus/gdiplus_private.h +++ b/dlls/gdiplus/gdiplus_private.h @@ -187,7 +187,7 @@ struct GpSolidFill{ struct GpPathGradient{ GpBrush brush; - PathData pathdata; + GpPath* path; ARGB centercolor; GpWrapMode wrap; BOOL gamma; -- 2.11.4.GIT