[2/5] gdiplus: Store a real path in path gradient brushes.
Vincent Povirk
madewokherd at gmail.com
Mon Mar 12 16:00:48 CDT 2012
-------------- next part --------------
From 49111089f783d23d1cf5006a5ef0a54abe8f7d86 Mon Sep 17 00:00:00 2001
From: Vincent Povirk <vincent at codeweavers.com>
Date: Mon, 20 Feb 2012 11:54:38 -0600
Subject: [PATCH 02/14] gdiplus: Store a real path in path gradient brushes.
---
dlls/gdiplus/brush.c | 185 ++++++++++++++++------------------------
dlls/gdiplus/gdiplus_private.h | 2 +-
2 files changed, 74 insertions(+), 113 deletions(-)
diff --git a/dlls/gdiplus/brush.c b/dlls/gdiplus/brush.c
index ca4d8eb..dc00a4f 100644
--- a/dlls/gdiplus/brush.c
+++ b/dlls/gdiplus/brush.c
@@ -67,30 +67,23 @@ GpStatus WINGDIPAPI GdipCloneBrush(GpBrush *brush, GpBrush **clone)
case BrushTypePathGradient:{
GpPathGradient *src, *dest;
INT count;
+ GpStatus stat;
*clone = GdipAlloc(sizeof(GpPathGradient));
if (!*clone) return OutOfMemory;
src = (GpPathGradient*) brush,
dest = (GpPathGradient*) *clone;
- count = src->pathdata.Count;
memcpy(dest, src, sizeof(GpPathGradient));
- dest->pathdata.Count = count;
- dest->pathdata.Points = GdipAlloc(count * sizeof(PointF));
- dest->pathdata.Types = GdipAlloc(count);
+ stat = GdipClonePath(src->path, &dest->path);
- if(!dest->pathdata.Points || !dest->pathdata.Types){
- GdipFree(dest->pathdata.Points);
- GdipFree(dest->pathdata.Types);
+ if(stat != Ok){
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 */
count = src->blendcount;
dest->blendcount = count;
@@ -98,8 +91,7 @@ GpStatus WINGDIPAPI GdipCloneBrush(GpBrush *brush, GpBrush **clone)
dest->blendpos = GdipAlloc(count * sizeof(REAL));
if(!dest->blendfac || !dest->blendpos){
- GdipFree(dest->pathdata.Points);
- GdipFree(dest->pathdata.Types);
+ GdipDeletePath(dest->path);
GdipFree(dest->blendfac);
GdipFree(dest->blendpos);
GdipFree(dest);
@@ -496,19 +488,16 @@ GpStatus WINGDIPAPI GdipCreateLineBrushFromRectWithAngleI(GDIPCONST GpRect* rect
wrap, line);
}
-GpStatus WINGDIPAPI GdipCreatePathGradient(GDIPCONST GpPointF* points,
- INT count, GpWrapMode wrap, GpPathGradient **grad)
+static GpStatus create_path_gradient(GpPath *path, GpPathGradient **grad)
{
- TRACE("(%p, %d, %d, %p)\n", points, count, wrap, grad);
-
- if(!points || !grad)
+ if(!path || !grad)
return InvalidParameter;
- if(count <= 0)
- return OutOfMemory;
-
*grad = GdipAlloc(sizeof(GpPathGradient));
- if (!*grad) return OutOfMemory;
+ if (!*grad)
+ {
+ return OutOfMemory;
+ }
(*grad)->blendfac = GdipAlloc(sizeof(REAL));
(*grad)->blendpos = GdipAlloc(sizeof(REAL));
@@ -523,24 +512,13 @@ GpStatus WINGDIPAPI GdipCreatePathGradient(GDIPCONST GpPointF* points,
(*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)->path = path;
(*grad)->brush.bt = BrushTypePathGradient;
(*grad)->centercolor = 0xffffffff;
- (*grad)->wrap = wrap;
+ (*grad)->wrap = WrapModeClamp;
(*grad)->gamma = FALSE;
+ /* FIXME: this should be set to the "centroid" of the path by default */
(*grad)->center.X = 0.0;
(*grad)->center.Y = 0.0;
(*grad)->focus.X = 0.0;
@@ -551,12 +529,11 @@ GpStatus WINGDIPAPI GdipCreatePathGradient(GDIPCONST GpPointF* points,
return Ok;
}
-GpStatus WINGDIPAPI GdipCreatePathGradientI(GDIPCONST GpPoint* points,
+GpStatus WINGDIPAPI GdipCreatePathGradient(GDIPCONST GpPointF* points,
INT count, GpWrapMode wrap, GpPathGradient **grad)
{
- GpPointF *pointsF;
- GpStatus ret;
- INT i;
+ GpStatus stat;
+ GpPath *path;
TRACE("(%p, %d, %d, %p)\n", points, count, wrap, grad);
@@ -566,78 +543,77 @@ GpStatus WINGDIPAPI GdipCreatePathGradientI(GDIPCONST GpPoint* points,
if(count <= 0)
return OutOfMemory;
- pointsF = GdipAlloc(sizeof(GpPointF) * count);
- if(!pointsF)
- return OutOfMemory;
+ stat = GdipCreatePath(FillModeAlternate, &path);
+
+ if (stat == Ok)
+ {
+ stat = GdipAddPathLine2(path, points, count);
+
+ if (stat == Ok)
+ stat = create_path_gradient(path, grad);
- for(i = 0; i < count; i++){
- pointsF[i].X = (REAL)points[i].X;
- pointsF[i].Y = (REAL)points[i].Y;
+ if (stat != Ok)
+ GdipDeletePath(path);
}
- ret = GdipCreatePathGradient(pointsF, count, wrap, grad);
- GdipFree(pointsF);
+ return stat;
+}
- return ret;
+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.@]
- *
- * FIXME: path gradient brushes not truly supported (drawn as solid brushes)
*/
GpStatus WINGDIPAPI GdipCreatePathGradientFromPath(GDIPCONST GpPath* path,
GpPathGradient **grad)
{
+ GpStatus stat;
+ GpPath *new_path;
+
TRACE("(%p, %p)\n", path, grad);
if(!path || !grad)
return InvalidParameter;
- *grad = GdipAlloc(sizeof(GpPathGradient));
- if (!*grad) return OutOfMemory;
+ stat = GdipClonePath((GpPath*)path, &new_path);
- (*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 = path->pathdata.Count;
- (*grad)->pathdata.Points = GdipAlloc(path->pathdata.Count * sizeof(PointF));
- (*grad)->pathdata.Types = GdipAlloc(path->pathdata.Count);
+ if (stat == Ok)
+ {
+ stat = create_path_gradient(new_path, grad);
- if(!(*grad)->pathdata.Points || !(*grad)->pathdata.Types){
- GdipFree((*grad)->pathdata.Points);
- GdipFree((*grad)->pathdata.Types);
- GdipFree(*grad);
- return OutOfMemory;
+ if (stat != Ok)
+ GdipDeletePath(new_path);
}
- 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)->centercolor = 0xffffffff;
- (*grad)->wrap = WrapModeClamp;
- (*grad)->gamma = FALSE;
- /* FIXME: this should be set to the "centroid" of the path by default */
- (*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;
+ return stat;
}
/******************************************************************************
@@ -894,8 +870,7 @@ GpStatus WINGDIPAPI GdipDeleteBrush(GpBrush *brush)
switch(brush->bt)
{
case BrushTypePathGradient:
- GdipFree(((GpPathGradient*) brush)->pathdata.Points);
- GdipFree(((GpPathGradient*) brush)->pathdata.Types);
+ GdipDeletePath(((GpPathGradient*) brush)->path);
GdipFree(((GpPathGradient*) brush)->blendfac);
GdipFree(((GpPathGradient*) brush)->blendpos);
break;
@@ -1063,15 +1038,13 @@ GpStatus WINGDIPAPI GdipGetPathGradientPointCount(GpPathGradient *grad,
if(!grad || !count)
return InvalidParameter;
- *count = grad->pathdata.Count;
+ *count = grad->path->pathdata.Count;
return Ok;
}
GpStatus WINGDIPAPI GdipGetPathGradientRect(GpPathGradient *brush, GpRectF *rect)
{
- GpRectF r;
- GpPath* path;
GpStatus stat;
TRACE("(%p, %p)\n", brush, rect);
@@ -1079,21 +1052,9 @@ GpStatus WINGDIPAPI GdipGetPathGradientRect(GpPathGradient *brush, GpRectF *rect
if(!brush || !rect)
return InvalidParameter;
- stat = GdipCreatePath2(brush->pathdata.Points, brush->pathdata.Types,
- brush->pathdata.Count, FillModeAlternate, &path);
- if(stat != Ok) return stat;
-
- stat = GdipGetPathWorldBounds(path, &r, NULL, NULL);
- if(stat != Ok){
- GdipDeletePath(path);
- return stat;
- }
-
- memcpy(rect, &r, sizeof(GpRectF));
+ stat = GdipGetPathWorldBounds(brush->path, rect, NULL, NULL);
- GdipDeletePath(path);
-
- return Ok;
+ return stat;
}
GpStatus WINGDIPAPI GdipGetPathGradientRectI(GpPathGradient *brush, GpRect *rect)
@@ -1124,7 +1085,7 @@ GpStatus WINGDIPAPI GdipGetPathGradientSurroundColorsWithCount(GpPathGradient
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;
if(!(calls++))
@@ -1542,7 +1503,7 @@ GpStatus WINGDIPAPI GdipSetPathGradientSurroundColorsWithCount(GpPathGradient
TRACE("(%p,%p,%p)\n", grad, argb, count);
if(!grad || !argb || !count || (*count <= 0) ||
- (*count > grad->pathdata.Count))
+ (*count > grad->path->pathdata.Count))
return InvalidParameter;
if(!(calls++))
diff --git a/dlls/gdiplus/gdiplus_private.h b/dlls/gdiplus/gdiplus_private.h
index 2a5fe69..2e6c60b 100644
--- a/dlls/gdiplus/gdiplus_private.h
+++ b/dlls/gdiplus/gdiplus_private.h
@@ -188,7 +188,7 @@ struct GpSolidFill{
struct GpPathGradient{
GpBrush brush;
- PathData pathdata;
+ GpPath* path;
ARGB centercolor;
GpWrapMode wrap;
BOOL gamma;
--
1.7.9
More information about the wine-patches
mailing list