[2/5] gdiplus: Implement path gradient preset blend accessors.

Vincent Povirk madewokherd at gmail.com
Sat Mar 31 13:40:04 CDT 2012


-------------- next part --------------
From 8555fd3aa099202222f3c76df79b95d4716a10db Mon Sep 17 00:00:00 2001
From: Vincent Povirk <vincent at codeweavers.com>
Date: Sat, 31 Mar 2012 12:38:17 -0500
Subject: [PATCH 2/8] gdiplus: Implement path gradient preset blend accessors.

---
 dlls/gdiplus/brush.c           |   85 ++++++++++++++++++++++++++++++++++++---
 dlls/gdiplus/gdiplus_private.h |    3 +
 dlls/gdiplus/graphics.c        |   14 +++++++
 3 files changed, 95 insertions(+), 7 deletions(-)

diff --git a/dlls/gdiplus/brush.c b/dlls/gdiplus/brush.c
index 9eb9dff..07d32dc 100644
--- a/dlls/gdiplus/brush.c
+++ b/dlls/gdiplus/brush.c
@@ -60,7 +60,7 @@ GpStatus WINGDIPAPI GdipCloneBrush(GpBrush *brush, GpBrush **clone)
         }
         case BrushTypePathGradient:{
             GpPathGradient *src, *dest;
-            INT count;
+            INT count, pcount;
             GpStatus stat;
 
             *clone = GdipAlloc(sizeof(GpPathGradient));
@@ -84,12 +84,21 @@ GpStatus WINGDIPAPI GdipCloneBrush(GpBrush *brush, GpBrush **clone)
             dest->blendfac = GdipAlloc(count * sizeof(REAL));
             dest->blendpos = GdipAlloc(count * sizeof(REAL));
             dest->surroundcolors = GdipAlloc(dest->surroundcolorcount * sizeof(ARGB));
+            pcount = dest->pblendcount;
+            if (pcount)
+            {
+                dest->pblendcolor = GdipAlloc(pcount * sizeof(ARGB));
+                dest->pblendpos = GdipAlloc(pcount * sizeof(REAL));
+            }
 
-            if(!dest->blendfac || !dest->blendpos || !dest->surroundcolors){
+            if(!dest->blendfac || !dest->blendpos || !dest->surroundcolors ||
+               (pcount && (!dest->pblendcolor || !dest->pblendpos))){
                 GdipDeletePath(dest->path);
                 GdipFree(dest->blendfac);
                 GdipFree(dest->blendpos);
                 GdipFree(dest->surroundcolors);
+                GdipFree(dest->pblendcolor);
+                GdipFree(dest->pblendpos);
                 GdipFree(dest);
                 return OutOfMemory;
             }
@@ -98,6 +107,12 @@ GpStatus WINGDIPAPI GdipCloneBrush(GpBrush *brush, GpBrush **clone)
             memcpy(dest->blendpos, src->blendpos, count * sizeof(REAL));
             memcpy(dest->surroundcolors, src->surroundcolors, dest->surroundcolorcount * sizeof(ARGB));
 
+            if (pcount)
+            {
+                memcpy(dest->pblendcolor, src->pblendcolor, pcount * sizeof(ARGB));
+                memcpy(dest->pblendpos, src->pblendpos, pcount * sizeof(REAL));
+            }
+
             break;
         }
         case BrushTypeLinearGradient:{
@@ -878,6 +893,8 @@ GpStatus WINGDIPAPI GdipDeleteBrush(GpBrush *brush)
             GdipFree(((GpPathGradient*) brush)->blendfac);
             GdipFree(((GpPathGradient*) brush)->blendpos);
             GdipFree(((GpPathGradient*) brush)->surroundcolors);
+            GdipFree(((GpPathGradient*) brush)->pblendcolor);
+            GdipFree(((GpPathGradient*) brush)->pblendpos);
             break;
         case BrushTypeLinearGradient:
             GdipFree(((GpLineGradient*)brush)->blendfac);
@@ -1413,22 +1430,76 @@ GpStatus WINGDIPAPI GdipSetPathGradientLinearBlend(GpPathGradient *brush,
 GpStatus WINGDIPAPI GdipSetPathGradientPresetBlend(GpPathGradient *brush,
     GDIPCONST ARGB *blend, GDIPCONST REAL *pos, INT count)
 {
-    FIXME("(%p,%p,%p,%i): stub\n", brush, blend, pos, count);
-    return NotImplemented;
+    ARGB *new_color;
+    REAL *new_pos;
+    TRACE("(%p,%p,%p,%i)\n", brush, blend, pos, count);
+
+    if (!brush || !blend || !pos || count < 2 ||
+        pos[0] != 0.0f || pos[count-1] != 1.0f)
+    {
+        return InvalidParameter;
+    }
+
+    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, pos, sizeof(REAL) * count);
+
+    GdipFree(brush->pblendcolor);
+    GdipFree(brush->pblendpos);
+
+    brush->pblendcolor = new_color;
+    brush->pblendpos = new_pos;
+    brush->pblendcount = count;
+
+    return Ok;
 }
 
 GpStatus WINGDIPAPI GdipGetPathGradientPresetBlend(GpPathGradient *brush,
     ARGB *blend, REAL *pos, INT count)
 {
-    FIXME("(%p,%p,%p,%i): stub\n", brush, blend, pos, count);
-    return NotImplemented;
+    TRACE("(%p,%p,%p,%i)\n", brush, blend, pos, count);
+
+    if (count < 0)
+        return OutOfMemory;
+
+    if (!brush || !blend || !pos || count < 2)
+        return InvalidParameter;
+
+    if (brush->pblendcount == 0)
+        return GenericError;
+
+    if (count != brush->pblendcount)
+    {
+        /* Native lines up the ends of each array, and copies the destination size. */
+        FIXME("Braindead behavior on wrong-sized buffer not implemented.\n");
+        return InvalidParameter;
+    }
+
+    memcpy(blend, brush->pblendcolor, sizeof(ARGB) * brush->pblendcount);
+    memcpy(pos, brush->pblendpos, sizeof(REAL) * brush->pblendcount);
+
+    return Ok;
 }
 
 GpStatus WINGDIPAPI GdipGetPathGradientPresetBlendCount(GpPathGradient *brush,
     INT *count)
 {
     FIXME("(%p,%p): stub\n", brush, count);
-    return NotImplemented;
+
+    if (!brush || !count)
+        return InvalidParameter;
+
+    *count = brush->pblendcount;
+
+    return Ok;
 }
 
 GpStatus WINGDIPAPI GdipSetPathGradientCenterColor(GpPathGradient *grad,
diff --git a/dlls/gdiplus/gdiplus_private.h b/dlls/gdiplus/gdiplus_private.h
index 3b82b08..c9853ec 100644
--- a/dlls/gdiplus/gdiplus_private.h
+++ b/dlls/gdiplus/gdiplus_private.h
@@ -198,6 +198,9 @@ struct GpPathGradient{
     INT blendcount;
     ARGB *surroundcolors;
     INT surroundcolorcount;
+    ARGB* pblendcolor; /* preset blend colors */
+    REAL* pblendpos; /* preset blend positions */
+    INT pblendcount;
 };
 
 struct GpLineGradient{
diff --git a/dlls/gdiplus/graphics.c b/dlls/gdiplus/graphics.c
index ee6325a..885d9a7 100644
--- a/dlls/gdiplus/graphics.c
+++ b/dlls/gdiplus/graphics.c
@@ -1207,6 +1207,20 @@ static GpStatus brush_fill_pixels(GpGraphics *graphics, GpBrush *brush,
                 FIXME("path gradient gamma correction not implemented\n");
         }
 
+        if (fill->blendcount)
+        {
+            static int once;
+            if (!once++)
+                FIXME("path gradient blend not implemented\n");
+        }
+
+        if (fill->pblendcount)
+        {
+            static int once;
+            if (!once++)
+                FIXME("path gradient preset blend not implemented\n");
+        }
+
         stat = GdipClonePath(fill->path, &flat_path);
 
         if (stat != Ok)
-- 
1.7.2.5


More information about the wine-patches mailing list