Vincent Povirk : gdiplus: Store preset blends in linear gradient brushes.
Alexandre Julliard
julliard at winehq.org
Tue Sep 15 17:47:56 CDT 2009
Module: wine
Branch: master
Commit: 8bdabe3a1840755187ed7fad4146603fcb63ba2d
URL: http://source.winehq.org/git/wine.git/?a=commit;h=8bdabe3a1840755187ed7fad4146603fcb63ba2d
Author: Vincent Povirk <vincent at codeweavers.com>
Date: Mon Sep 14 16:21:50 2009 -0500
gdiplus: Store preset blends in linear gradient brushes.
---
dlls/gdiplus/brush.c | 80 +++++++++++++++++++++++++++++++++-------
dlls/gdiplus/gdiplus_private.h | 3 +
2 files changed, 69 insertions(+), 14 deletions(-)
diff --git a/dlls/gdiplus/brush.c b/dlls/gdiplus/brush.c
index 8b18684..1425ab7 100644
--- a/dlls/gdiplus/brush.c
+++ b/dlls/gdiplus/brush.c
@@ -116,7 +116,7 @@ GpStatus WINGDIPAPI GdipCloneBrush(GpBrush *brush, GpBrush **clone)
}
case BrushTypeLinearGradient:{
GpLineGradient *dest, *src;
- INT count;
+ INT count, pcount;
dest = GdipAlloc(sizeof(GpLineGradient));
if(!dest) return OutOfMemory;
@@ -130,11 +130,20 @@ GpStatus WINGDIPAPI GdipCloneBrush(GpBrush *brush, GpBrush **clone)
count = dest->blendcount;
dest->blendfac = GdipAlloc(count * sizeof(REAL));
dest->blendpos = GdipAlloc(count * sizeof(REAL));
+ pcount = dest->pblendcount;
+ if (pcount)
+ {
+ dest->pblendcolor = GdipAlloc(pcount * sizeof(ARGB));
+ dest->pblendpos = GdipAlloc(pcount * sizeof(REAL));
+ }
- if (!dest->blendfac || !dest->blendpos)
+ if (!dest->blendfac || !dest->blendpos ||
+ (pcount && (!dest->pblendcolor || !dest->pblendpos)))
{
GdipFree(dest->blendfac);
GdipFree(dest->blendpos);
+ GdipFree(dest->pblendcolor);
+ GdipFree(dest->pblendpos);
DeleteObject(dest->brush.gdibrush);
GdipFree(dest);
return OutOfMemory;
@@ -143,6 +152,12 @@ GpStatus WINGDIPAPI GdipCloneBrush(GpBrush *brush, GpBrush **clone)
memcpy(dest->blendfac, src->blendfac, count * sizeof(REAL));
memcpy(dest->blendpos, src->blendpos, count * sizeof(REAL));
+ if (pcount)
+ {
+ memcpy(dest->pblendcolor, src->pblendcolor, pcount * sizeof(ARGB));
+ memcpy(dest->pblendpos, src->pblendpos, pcount * sizeof(REAL));
+ }
+
*clone = &dest->brush;
break;
}
@@ -289,6 +304,10 @@ GpStatus WINGDIPAPI GdipCreateLineBrush(GDIPCONST GpPointF* startpoint,
(*line)->blendfac[0] = 1.0f;
(*line)->blendpos[0] = 1.0f;
+ (*line)->pblendcolor = NULL;
+ (*line)->pblendpos = NULL;
+ (*line)->pblendcount = 0;
+
return Ok;
}
@@ -866,6 +885,8 @@ GpStatus WINGDIPAPI GdipDeleteBrush(GpBrush *brush)
case BrushTypeLinearGradient:
GdipFree(((GpLineGradient*)brush)->blendfac);
GdipFree(((GpLineGradient*)brush)->blendpos);
+ GdipFree(((GpLineGradient*)brush)->pblendcolor);
+ GdipFree(((GpLineGradient*)brush)->pblendpos);
break;
case BrushTypeTextureFill:
GdipDeleteMatrix(((GpTexture*)brush)->transform);
@@ -1574,34 +1595,65 @@ GpStatus WINGDIPAPI GdipSetLineLinearBlend(GpLineGradient *brush, REAL focus,
GpStatus WINGDIPAPI GdipSetLinePresetBlend(GpLineGradient *brush,
GDIPCONST ARGB *blend, GDIPCONST REAL* positions, INT count)
{
- static int calls;
+ ARGB *new_color;
+ REAL *new_pos;
+ TRACE("(%p,%p,%p,%i)\n", brush, blend, positions, count);
- if(!(calls++))
- FIXME("not implemented\n");
+ if (!brush || !blend || !positions || count < 2 ||
+ positions[0] != 0.0f || positions[count-1] != 1.0f)
+ {
+ return InvalidParameter;
+ }
- return NotImplemented;
+ 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, positions, sizeof(REAL) * count);
+
+ GdipFree(brush->pblendcolor);
+ GdipFree(brush->pblendpos);
+
+ brush->pblendcolor = new_color;
+ brush->pblendpos = new_pos;
+ brush->pblendcount = count;
+
+ return Ok;
}
GpStatus WINGDIPAPI GdipGetLinePresetBlend(GpLineGradient *brush,
ARGB *blend, REAL* positions, INT count)
{
- static int calls;
+ if (!brush || !blend || !positions || count < 2)
+ return InvalidParameter;
- if(!(calls++))
- FIXME("not implemented\n");
+ if (brush->pblendcount == 0)
+ return GenericError;
- return NotImplemented;
+ if (count < brush->pblendcount)
+ return InsufficientBuffer;
+
+ memcpy(blend, brush->pblendcolor, sizeof(ARGB) * brush->pblendcount);
+ memcpy(positions, brush->pblendpos, sizeof(REAL) * brush->pblendcount);
+
+ return Ok;
}
GpStatus WINGDIPAPI GdipGetLinePresetBlendCount(GpLineGradient *brush,
INT *count)
{
- static int calls;
+ if (!brush || !count)
+ return InvalidParameter;
- if(!(calls++))
- FIXME("not implemented\n");
+ *count = brush->pblendcount;
- return NotImplemented;
+ return Ok;
}
GpStatus WINGDIPAPI GdipResetLineTransform(GpLineGradient *brush)
diff --git a/dlls/gdiplus/gdiplus_private.h b/dlls/gdiplus/gdiplus_private.h
index c95f3ff..02c03dc 100644
--- a/dlls/gdiplus/gdiplus_private.h
+++ b/dlls/gdiplus/gdiplus_private.h
@@ -166,6 +166,9 @@ struct GpLineGradient{
REAL* blendfac; /* blend factors */
REAL* blendpos; /* blend positions */
INT blendcount;
+ ARGB* pblendcolor; /* preset blend colors */
+ REAL* pblendpos; /* preset blend positions */
+ INT pblendcount;
};
struct GpTexture{
More information about the wine-cvs
mailing list