[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