gdiplus: Implement path gradient preset blend accessors.
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 @@
}
case BrushTypePathGradient:{
GpPathGradient *src, *dest;
- INT count;
+ INT count, pcount;
GpStatus stat;
*clone = GdipAlloc(sizeof(GpPathGradient));
@@ -84,12 +84,21 @@
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 @@
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 @@
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 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 @@
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 @@
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)