gdiplus: Store a real path in path gradient brushes.
This commit is contained in:
parent
dc3a08d840
commit
96d66f1666
|
@ -61,30 +61,23 @@ GpStatus WINGDIPAPI GdipCloneBrush(GpBrush *brush, GpBrush **clone)
|
||||||
case BrushTypePathGradient:{
|
case BrushTypePathGradient:{
|
||||||
GpPathGradient *src, *dest;
|
GpPathGradient *src, *dest;
|
||||||
INT count;
|
INT count;
|
||||||
|
GpStatus stat;
|
||||||
|
|
||||||
*clone = GdipAlloc(sizeof(GpPathGradient));
|
*clone = GdipAlloc(sizeof(GpPathGradient));
|
||||||
if (!*clone) return OutOfMemory;
|
if (!*clone) return OutOfMemory;
|
||||||
|
|
||||||
src = (GpPathGradient*) brush,
|
src = (GpPathGradient*) brush,
|
||||||
dest = (GpPathGradient*) *clone;
|
dest = (GpPathGradient*) *clone;
|
||||||
count = src->pathdata.Count;
|
|
||||||
|
|
||||||
memcpy(dest, src, sizeof(GpPathGradient));
|
memcpy(dest, src, sizeof(GpPathGradient));
|
||||||
|
|
||||||
dest->pathdata.Count = count;
|
stat = GdipClonePath(src->path, &dest->path);
|
||||||
dest->pathdata.Points = GdipAlloc(count * sizeof(PointF));
|
|
||||||
dest->pathdata.Types = GdipAlloc(count);
|
|
||||||
|
|
||||||
if(!dest->pathdata.Points || !dest->pathdata.Types){
|
if(stat != Ok){
|
||||||
GdipFree(dest->pathdata.Points);
|
|
||||||
GdipFree(dest->pathdata.Types);
|
|
||||||
GdipFree(dest);
|
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 */
|
/* blending */
|
||||||
count = src->blendcount;
|
count = src->blendcount;
|
||||||
dest->blendcount = count;
|
dest->blendcount = count;
|
||||||
|
@ -92,8 +85,7 @@ GpStatus WINGDIPAPI GdipCloneBrush(GpBrush *brush, GpBrush **clone)
|
||||||
dest->blendpos = GdipAlloc(count * sizeof(REAL));
|
dest->blendpos = GdipAlloc(count * sizeof(REAL));
|
||||||
|
|
||||||
if(!dest->blendfac || !dest->blendpos){
|
if(!dest->blendfac || !dest->blendpos){
|
||||||
GdipFree(dest->pathdata.Points);
|
GdipDeletePath(dest->path);
|
||||||
GdipFree(dest->pathdata.Types);
|
|
||||||
GdipFree(dest->blendfac);
|
GdipFree(dest->blendfac);
|
||||||
GdipFree(dest->blendpos);
|
GdipFree(dest->blendpos);
|
||||||
GdipFree(dest);
|
GdipFree(dest);
|
||||||
|
@ -490,106 +482,16 @@ GpStatus WINGDIPAPI GdipCreateLineBrushFromRectWithAngleI(GDIPCONST GpRect* rect
|
||||||
wrap, line);
|
wrap, line);
|
||||||
}
|
}
|
||||||
|
|
||||||
GpStatus WINGDIPAPI GdipCreatePathGradient(GDIPCONST GpPointF* points,
|
static GpStatus create_path_gradient(GpPath *path, GpPathGradient **grad)
|
||||||
INT count, GpWrapMode wrap, GpPathGradient **grad)
|
|
||||||
{
|
{
|
||||||
TRACE("(%p, %d, %d, %p)\n", points, count, wrap, grad);
|
|
||||||
|
|
||||||
if(!points || !grad)
|
|
||||||
return InvalidParameter;
|
|
||||||
|
|
||||||
if(count <= 0)
|
|
||||||
return OutOfMemory;
|
|
||||||
|
|
||||||
*grad = GdipAlloc(sizeof(GpPathGradient));
|
|
||||||
if (!*grad) return OutOfMemory;
|
|
||||||
|
|
||||||
(*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 = 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)->brush.bt = BrushTypePathGradient;
|
|
||||||
(*grad)->centercolor = 0xffffffff;
|
|
||||||
(*grad)->wrap = wrap;
|
|
||||||
(*grad)->gamma = FALSE;
|
|
||||||
(*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;
|
|
||||||
}
|
|
||||||
|
|
||||||
GpStatus WINGDIPAPI GdipCreatePathGradientI(GDIPCONST GpPoint* points,
|
|
||||||
INT count, GpWrapMode wrap, GpPathGradient **grad)
|
|
||||||
{
|
|
||||||
GpPointF *pointsF;
|
|
||||||
GpStatus ret;
|
|
||||||
INT i;
|
|
||||||
|
|
||||||
TRACE("(%p, %d, %d, %p)\n", points, count, wrap, grad);
|
|
||||||
|
|
||||||
if(!points || !grad)
|
|
||||||
return InvalidParameter;
|
|
||||||
|
|
||||||
if(count <= 0)
|
|
||||||
return OutOfMemory;
|
|
||||||
|
|
||||||
pointsF = GdipAlloc(sizeof(GpPointF) * count);
|
|
||||||
if(!pointsF)
|
|
||||||
return OutOfMemory;
|
|
||||||
|
|
||||||
for(i = 0; i < count; i++){
|
|
||||||
pointsF[i].X = (REAL)points[i].X;
|
|
||||||
pointsF[i].Y = (REAL)points[i].Y;
|
|
||||||
}
|
|
||||||
|
|
||||||
ret = GdipCreatePathGradient(pointsF, count, wrap, grad);
|
|
||||||
GdipFree(pointsF);
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
/******************************************************************************
|
|
||||||
* GdipCreatePathGradientFromPath [GDIPLUS.@]
|
|
||||||
*
|
|
||||||
* FIXME: path gradient brushes not truly supported (drawn as solid brushes)
|
|
||||||
*/
|
|
||||||
GpStatus WINGDIPAPI GdipCreatePathGradientFromPath(GDIPCONST GpPath* path,
|
|
||||||
GpPathGradient **grad)
|
|
||||||
{
|
|
||||||
TRACE("(%p, %p)\n", path, grad);
|
|
||||||
|
|
||||||
if(!path || !grad)
|
if(!path || !grad)
|
||||||
return InvalidParameter;
|
return InvalidParameter;
|
||||||
|
|
||||||
*grad = GdipAlloc(sizeof(GpPathGradient));
|
*grad = GdipAlloc(sizeof(GpPathGradient));
|
||||||
if (!*grad) return OutOfMemory;
|
if (!*grad)
|
||||||
|
{
|
||||||
|
return OutOfMemory;
|
||||||
|
}
|
||||||
|
|
||||||
(*grad)->blendfac = GdipAlloc(sizeof(REAL));
|
(*grad)->blendfac = GdipAlloc(sizeof(REAL));
|
||||||
(*grad)->blendpos = GdipAlloc(sizeof(REAL));
|
(*grad)->blendpos = GdipAlloc(sizeof(REAL));
|
||||||
|
@ -604,20 +506,7 @@ GpStatus WINGDIPAPI GdipCreatePathGradientFromPath(GDIPCONST GpPath* path,
|
||||||
(*grad)->blendpos[0] = 1.0;
|
(*grad)->blendpos[0] = 1.0;
|
||||||
(*grad)->blendcount = 1;
|
(*grad)->blendcount = 1;
|
||||||
|
|
||||||
(*grad)->pathdata.Count = path->pathdata.Count;
|
(*grad)->path = path;
|
||||||
(*grad)->pathdata.Points = GdipAlloc(path->pathdata.Count * sizeof(PointF));
|
|
||||||
(*grad)->pathdata.Types = GdipAlloc(path->pathdata.Count);
|
|
||||||
|
|
||||||
if(!(*grad)->pathdata.Points || !(*grad)->pathdata.Types){
|
|
||||||
GdipFree((*grad)->pathdata.Points);
|
|
||||||
GdipFree((*grad)->pathdata.Types);
|
|
||||||
GdipFree(*grad);
|
|
||||||
return OutOfMemory;
|
|
||||||
}
|
|
||||||
|
|
||||||
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)->brush.bt = BrushTypePathGradient;
|
||||||
(*grad)->centercolor = 0xffffffff;
|
(*grad)->centercolor = 0xffffffff;
|
||||||
|
@ -634,6 +523,93 @@ GpStatus WINGDIPAPI GdipCreatePathGradientFromPath(GDIPCONST GpPath* path,
|
||||||
return Ok;
|
return Ok;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
GpStatus WINGDIPAPI GdipCreatePathGradient(GDIPCONST GpPointF* 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 = GdipAddPathLine2(path, points, count);
|
||||||
|
|
||||||
|
if (stat == Ok)
|
||||||
|
stat = create_path_gradient(path, grad);
|
||||||
|
|
||||||
|
if (stat != Ok)
|
||||||
|
GdipDeletePath(path);
|
||||||
|
}
|
||||||
|
|
||||||
|
return stat;
|
||||||
|
}
|
||||||
|
|
||||||
|
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.@]
|
||||||
|
*/
|
||||||
|
GpStatus WINGDIPAPI GdipCreatePathGradientFromPath(GDIPCONST GpPath* path,
|
||||||
|
GpPathGradient **grad)
|
||||||
|
{
|
||||||
|
GpStatus stat;
|
||||||
|
GpPath *new_path;
|
||||||
|
|
||||||
|
TRACE("(%p, %p)\n", path, grad);
|
||||||
|
|
||||||
|
if(!path || !grad)
|
||||||
|
return InvalidParameter;
|
||||||
|
|
||||||
|
stat = GdipClonePath((GpPath*)path, &new_path);
|
||||||
|
|
||||||
|
if (stat == Ok)
|
||||||
|
{
|
||||||
|
stat = create_path_gradient(new_path, grad);
|
||||||
|
|
||||||
|
if (stat != Ok)
|
||||||
|
GdipDeletePath(new_path);
|
||||||
|
}
|
||||||
|
|
||||||
|
return stat;
|
||||||
|
}
|
||||||
|
|
||||||
/******************************************************************************
|
/******************************************************************************
|
||||||
* GdipCreateSolidFill [GDIPLUS.@]
|
* GdipCreateSolidFill [GDIPLUS.@]
|
||||||
*/
|
*/
|
||||||
|
@ -887,8 +863,7 @@ GpStatus WINGDIPAPI GdipDeleteBrush(GpBrush *brush)
|
||||||
switch(brush->bt)
|
switch(brush->bt)
|
||||||
{
|
{
|
||||||
case BrushTypePathGradient:
|
case BrushTypePathGradient:
|
||||||
GdipFree(((GpPathGradient*) brush)->pathdata.Points);
|
GdipDeletePath(((GpPathGradient*) brush)->path);
|
||||||
GdipFree(((GpPathGradient*) brush)->pathdata.Types);
|
|
||||||
GdipFree(((GpPathGradient*) brush)->blendfac);
|
GdipFree(((GpPathGradient*) brush)->blendfac);
|
||||||
GdipFree(((GpPathGradient*) brush)->blendpos);
|
GdipFree(((GpPathGradient*) brush)->blendpos);
|
||||||
break;
|
break;
|
||||||
|
@ -1052,15 +1027,13 @@ GpStatus WINGDIPAPI GdipGetPathGradientPointCount(GpPathGradient *grad,
|
||||||
if(!grad || !count)
|
if(!grad || !count)
|
||||||
return InvalidParameter;
|
return InvalidParameter;
|
||||||
|
|
||||||
*count = grad->pathdata.Count;
|
*count = grad->path->pathdata.Count;
|
||||||
|
|
||||||
return Ok;
|
return Ok;
|
||||||
}
|
}
|
||||||
|
|
||||||
GpStatus WINGDIPAPI GdipGetPathGradientRect(GpPathGradient *brush, GpRectF *rect)
|
GpStatus WINGDIPAPI GdipGetPathGradientRect(GpPathGradient *brush, GpRectF *rect)
|
||||||
{
|
{
|
||||||
GpRectF r;
|
|
||||||
GpPath* path;
|
|
||||||
GpStatus stat;
|
GpStatus stat;
|
||||||
|
|
||||||
TRACE("(%p, %p)\n", brush, rect);
|
TRACE("(%p, %p)\n", brush, rect);
|
||||||
|
@ -1068,21 +1041,9 @@ GpStatus WINGDIPAPI GdipGetPathGradientRect(GpPathGradient *brush, GpRectF *rect
|
||||||
if(!brush || !rect)
|
if(!brush || !rect)
|
||||||
return InvalidParameter;
|
return InvalidParameter;
|
||||||
|
|
||||||
stat = GdipCreatePath2(brush->pathdata.Points, brush->pathdata.Types,
|
stat = GdipGetPathWorldBounds(brush->path, rect, NULL, NULL);
|
||||||
brush->pathdata.Count, FillModeAlternate, &path);
|
|
||||||
if(stat != Ok) return stat;
|
|
||||||
|
|
||||||
stat = GdipGetPathWorldBounds(path, &r, NULL, NULL);
|
return stat;
|
||||||
if(stat != Ok){
|
|
||||||
GdipDeletePath(path);
|
|
||||||
return stat;
|
|
||||||
}
|
|
||||||
|
|
||||||
memcpy(rect, &r, sizeof(GpRectF));
|
|
||||||
|
|
||||||
GdipDeletePath(path);
|
|
||||||
|
|
||||||
return Ok;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
GpStatus WINGDIPAPI GdipGetPathGradientRectI(GpPathGradient *brush, GpRect *rect)
|
GpStatus WINGDIPAPI GdipGetPathGradientRectI(GpPathGradient *brush, GpRect *rect)
|
||||||
|
@ -1113,7 +1074,7 @@ GpStatus WINGDIPAPI GdipGetPathGradientSurroundColorsWithCount(GpPathGradient
|
||||||
|
|
||||||
TRACE("(%p,%p,%p)\n", grad, argb, count);
|
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;
|
return InvalidParameter;
|
||||||
|
|
||||||
if(!(calls++))
|
if(!(calls++))
|
||||||
|
@ -1531,7 +1492,7 @@ GpStatus WINGDIPAPI GdipSetPathGradientSurroundColorsWithCount(GpPathGradient
|
||||||
TRACE("(%p,%p,%p)\n", grad, argb, count);
|
TRACE("(%p,%p,%p)\n", grad, argb, count);
|
||||||
|
|
||||||
if(!grad || !argb || !count || (*count <= 0) ||
|
if(!grad || !argb || !count || (*count <= 0) ||
|
||||||
(*count > grad->pathdata.Count))
|
(*count > grad->path->pathdata.Count))
|
||||||
return InvalidParameter;
|
return InvalidParameter;
|
||||||
|
|
||||||
if(!(calls++))
|
if(!(calls++))
|
||||||
|
|
|
@ -187,7 +187,7 @@ struct GpSolidFill{
|
||||||
|
|
||||||
struct GpPathGradient{
|
struct GpPathGradient{
|
||||||
GpBrush brush;
|
GpBrush brush;
|
||||||
PathData pathdata;
|
GpPath* path;
|
||||||
ARGB centercolor;
|
ARGB centercolor;
|
||||||
GpWrapMode wrap;
|
GpWrapMode wrap;
|
||||||
BOOL gamma;
|
BOOL gamma;
|
||||||
|
|
Loading…
Reference in New Issue