Module: wine Branch: master Commit: 5254a76a0c1f9694cb40a8332d69b899b3fb0c26 URL: http://source.winehq.org/git/wine.git/?a=commit;h=5254a76a0c1f9694cb40a8332d...
Author: Vincent Povirk vincent@codeweavers.com Date: Sat Mar 31 12:38:17 2012 -0500
gdiplus: Implement path gradient preset blend accessors.
---
dlls/gdiplus/brush.c | 85 ++++++++++++++++++++++++++++++++++++--- dlls/gdiplus/gdiplus_private.h | 3 + dlls/gdiplus/graphics.c | 14 +++++++ 3 files changed, 95 insertions(+), 7 deletions(-)
diff --git a/dlls/gdiplus/brush.c b/dlls/gdiplus/brush.c index 9eb9dff..07d32dc 100644 --- a/dlls/gdiplus/brush.c +++ b/dlls/gdiplus/brush.c @@ -60,7 +60,7 @@ GpStatus WINGDIPAPI GdipCloneBrush(GpBrush *brush, GpBrush **clone) } case BrushTypePathGradient:{ GpPathGradient *src, *dest; - INT count; + INT count, pcount; GpStatus stat;
*clone = GdipAlloc(sizeof(GpPathGradient)); @@ -84,12 +84,21 @@ GpStatus WINGDIPAPI GdipCloneBrush(GpBrush *brush, GpBrush **clone) dest->blendfac = GdipAlloc(count * sizeof(REAL)); dest->blendpos = GdipAlloc(count * sizeof(REAL)); dest->surroundcolors = GdipAlloc(dest->surroundcolorcount * sizeof(ARGB)); + pcount = dest->pblendcount; + if (pcount) + { + dest->pblendcolor = GdipAlloc(pcount * sizeof(ARGB)); + dest->pblendpos = GdipAlloc(pcount * sizeof(REAL)); + }
- if(!dest->blendfac || !dest->blendpos || !dest->surroundcolors){ + if(!dest->blendfac || !dest->blendpos || !dest->surroundcolors || + (pcount && (!dest->pblendcolor || !dest->pblendpos))){ GdipDeletePath(dest->path); GdipFree(dest->blendfac); GdipFree(dest->blendpos); GdipFree(dest->surroundcolors); + GdipFree(dest->pblendcolor); + GdipFree(dest->pblendpos); GdipFree(dest); return OutOfMemory; } @@ -98,6 +107,12 @@ GpStatus WINGDIPAPI GdipCloneBrush(GpBrush *brush, GpBrush **clone) memcpy(dest->blendpos, src->blendpos, count * sizeof(REAL)); memcpy(dest->surroundcolors, src->surroundcolors, dest->surroundcolorcount * sizeof(ARGB));
+ if (pcount) + { + memcpy(dest->pblendcolor, src->pblendcolor, pcount * sizeof(ARGB)); + memcpy(dest->pblendpos, src->pblendpos, pcount * sizeof(REAL)); + } + break; } case BrushTypeLinearGradient:{ @@ -878,6 +893,8 @@ GpStatus WINGDIPAPI GdipDeleteBrush(GpBrush *brush) GdipFree(((GpPathGradient*) brush)->blendfac); GdipFree(((GpPathGradient*) brush)->blendpos); GdipFree(((GpPathGradient*) brush)->surroundcolors); + GdipFree(((GpPathGradient*) brush)->pblendcolor); + GdipFree(((GpPathGradient*) brush)->pblendpos); break; case BrushTypeLinearGradient: GdipFree(((GpLineGradient*)brush)->blendfac); @@ -1413,22 +1430,76 @@ GpStatus WINGDIPAPI GdipSetPathGradientLinearBlend(GpPathGradient *brush, GpStatus WINGDIPAPI GdipSetPathGradientPresetBlend(GpPathGradient *brush, GDIPCONST ARGB *blend, GDIPCONST REAL *pos, INT count) { - FIXME("(%p,%p,%p,%i): stub\n", brush, blend, pos, count); - return NotImplemented; + ARGB *new_color; + REAL *new_pos; + TRACE("(%p,%p,%p,%i)\n", brush, blend, pos, count); + + if (!brush || !blend || !pos || count < 2 || + pos[0] != 0.0f || pos[count-1] != 1.0f) + { + return InvalidParameter; + } + + new_color = GdipAlloc(count * sizeof(ARGB)); + new_pos = GdipAlloc(count * sizeof(REAL)); + if (!new_color || !new_pos) + { + GdipFree(new_color); + GdipFree(new_pos); + return OutOfMemory; + } + + memcpy(new_color, blend, sizeof(ARGB) * count); + memcpy(new_pos, pos, sizeof(REAL) * count); + + GdipFree(brush->pblendcolor); + GdipFree(brush->pblendpos); + + brush->pblendcolor = new_color; + brush->pblendpos = new_pos; + brush->pblendcount = count; + + return Ok; }
GpStatus WINGDIPAPI GdipGetPathGradientPresetBlend(GpPathGradient *brush, ARGB *blend, REAL *pos, INT count) { - FIXME("(%p,%p,%p,%i): stub\n", brush, blend, pos, count); - return NotImplemented; + TRACE("(%p,%p,%p,%i)\n", brush, blend, pos, count); + + if (count < 0) + return OutOfMemory; + + if (!brush || !blend || !pos || count < 2) + return InvalidParameter; + + if (brush->pblendcount == 0) + return GenericError; + + if (count != brush->pblendcount) + { + /* Native lines up the ends of each array, and copies the destination size. */ + FIXME("Braindead behavior on wrong-sized buffer not implemented.\n"); + return InvalidParameter; + } + + memcpy(blend, brush->pblendcolor, sizeof(ARGB) * brush->pblendcount); + memcpy(pos, brush->pblendpos, sizeof(REAL) * brush->pblendcount); + + return Ok; }
GpStatus WINGDIPAPI GdipGetPathGradientPresetBlendCount(GpPathGradient *brush, INT *count) { FIXME("(%p,%p): stub\n", brush, count); - return NotImplemented; + + if (!brush || !count) + return InvalidParameter; + + *count = brush->pblendcount; + + return Ok; }
GpStatus WINGDIPAPI GdipSetPathGradientCenterColor(GpPathGradient *grad, diff --git a/dlls/gdiplus/gdiplus_private.h b/dlls/gdiplus/gdiplus_private.h index 3b82b08..c9853ec 100644 --- a/dlls/gdiplus/gdiplus_private.h +++ b/dlls/gdiplus/gdiplus_private.h @@ -198,6 +198,9 @@ struct GpPathGradient{ INT blendcount; ARGB *surroundcolors; INT surroundcolorcount; + ARGB* pblendcolor; /* preset blend colors */ + REAL* pblendpos; /* preset blend positions */ + INT pblendcount; };
struct GpLineGradient{ diff --git a/dlls/gdiplus/graphics.c b/dlls/gdiplus/graphics.c index ee6325a..885d9a7 100644 --- a/dlls/gdiplus/graphics.c +++ b/dlls/gdiplus/graphics.c @@ -1207,6 +1207,20 @@ static GpStatus brush_fill_pixels(GpGraphics *graphics, GpBrush *brush, FIXME("path gradient gamma correction not implemented\n"); }
+ if (fill->blendcount) + { + static int once; + if (!once++) + FIXME("path gradient blend not implemented\n"); + } + + if (fill->pblendcount) + { + static int once; + if (!once++) + FIXME("path gradient preset blend not implemented\n"); + } + stat = GdipClonePath(fill->path, &flat_path);
if (stat != Ok)