Vincent Povirk : gdiplus: Add blend information to linear gradient brushes.

Alexandre Julliard julliard at winehq.org
Wed Apr 29 10:20:18 CDT 2009


Module: wine
Branch: master
Commit: b05cf906d1efa98f09e10a0a3f13aff06a8fe468
URL:    http://source.winehq.org/git/wine.git/?a=commit;h=b05cf906d1efa98f09e10a0a3f13aff06a8fe468

Author: Vincent Povirk <vincent at codeweavers.com>
Date:   Tue Apr 28 18:03:41 2009 -0500

gdiplus: Add blend information to linear gradient brushes.

---

 dlls/gdiplus/brush.c           |   54 ++++++++++++++++++++++++++++++++++++---
 dlls/gdiplus/gdiplus_private.h |    3 ++
 2 files changed, 52 insertions(+), 5 deletions(-)

diff --git a/dlls/gdiplus/brush.c b/dlls/gdiplus/brush.c
index e22d5aa..9df52ad 100644
--- a/dlls/gdiplus/brush.c
+++ b/dlls/gdiplus/brush.c
@@ -108,14 +108,38 @@ GpStatus WINGDIPAPI GdipCloneBrush(GpBrush *brush, GpBrush **clone)
 
             break;
         }
-        case BrushTypeLinearGradient:
-            *clone = GdipAlloc(sizeof(GpLineGradient));
-            if(!*clone)    return OutOfMemory;
+        case BrushTypeLinearGradient:{
+            GpLineGradient *dest, *src;
+            INT count;
+
+            dest = GdipAlloc(sizeof(GpLineGradient));
+            if(!dest)    return OutOfMemory;
+
+            src = (GpLineGradient*)brush;
+
+            memcpy(dest, src, sizeof(GpLineGradient));
+
+            dest->brush.gdibrush = CreateSolidBrush(dest->brush.lb.lbColor);
+
+            count = dest->blendcount;
+            dest->blendfac = GdipAlloc(count * sizeof(REAL));
+            dest->blendpos = GdipAlloc(count * sizeof(REAL));
+
+            if (!dest->blendfac || !dest->blendpos)
+            {
+                GdipFree(dest->blendfac);
+                GdipFree(dest->blendpos);
+                DeleteObject(dest->brush.gdibrush);
+                GdipFree(dest);
+                return OutOfMemory;
+            }
 
-            memcpy(*clone, brush, sizeof(GpLineGradient));
+            memcpy(dest->blendfac, src->blendfac, count * sizeof(REAL));
+            memcpy(dest->blendpos, src->blendpos, count * sizeof(REAL));
 
-            (*clone)->gdibrush = CreateSolidBrush((*clone)->lb.lbColor);
+            *clone = &dest->brush;
             break;
+        }
         case BrushTypeTextureFill:
             *clone = GdipAlloc(sizeof(GpTexture));
             if(!*clone)    return OutOfMemory;
@@ -226,6 +250,23 @@ GpStatus WINGDIPAPI GdipCreateLineBrush(GDIPCONST GpPointF* startpoint,
     (*line)->wrap = wrap;
     (*line)->gamma = FALSE;
 
+    (*line)->blendcount = 1;
+    (*line)->blendfac = GdipAlloc(sizeof(REAL));
+    (*line)->blendpos = GdipAlloc(sizeof(REAL));
+
+    if (!(*line)->blendfac || !(*line)->blendpos)
+    {
+        GdipFree((*line)->blendfac);
+        GdipFree((*line)->blendpos);
+        DeleteObject((*line)->brush.gdibrush);
+        GdipFree(*line);
+        *line = NULL;
+        return OutOfMemory;
+    }
+
+    (*line)->blendfac[0] = 1.0f;
+    (*line)->blendpos[0] = 1.0f;
+
     return Ok;
 }
 
@@ -765,7 +806,10 @@ GpStatus WINGDIPAPI GdipDeleteBrush(GpBrush *brush)
             GdipFree(((GpPathGradient*) brush)->blendpos);
             break;
         case BrushTypeSolidColor:
+            break;
         case BrushTypeLinearGradient:
+            GdipFree(((GpLineGradient*)brush)->blendfac);
+            GdipFree(((GpLineGradient*)brush)->blendpos);
             break;
         case BrushTypeTextureFill:
             GdipDeleteMatrix(((GpTexture*)brush)->transform);
diff --git a/dlls/gdiplus/gdiplus_private.h b/dlls/gdiplus/gdiplus_private.h
index a8c49d3..e038baf 100644
--- a/dlls/gdiplus/gdiplus_private.h
+++ b/dlls/gdiplus/gdiplus_private.h
@@ -145,6 +145,9 @@ struct GpLineGradient{
     ARGB endcolor;
     GpWrapMode wrap;
     BOOL gamma;
+    REAL* blendfac;  /* blend factors */
+    REAL* blendpos;  /* blend positions */
+    INT blendcount;
 };
 
 struct GpTexture{




More information about the wine-cvs mailing list