Vincent Povirk : gdiplus: Implement path gradient preset blend accessors.
Alexandre Julliard
julliard at winehq.org
Mon Apr 2 13:14:49 CDT 2012
Module: wine
Branch: master
Commit: 5254a76a0c1f9694cb40a8332d69b899b3fb0c26
URL: http://source.winehq.org/git/wine.git/?a=commit;h=5254a76a0c1f9694cb40a8332d69b899b3fb0c26
Author: Vincent Povirk <vincent at 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)
More information about the wine-cvs
mailing list