Vincent Povirk : gdiplus: Implement GdipSetPathGradientSigmaBlend.

Alexandre Julliard julliard at winehq.org
Wed Apr 25 13:40:25 CDT 2012


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

Author: Vincent Povirk <vincent at codeweavers.com>
Date:   Tue Apr 24 09:55:29 2012 -0500

gdiplus: Implement GdipSetPathGradientSigmaBlend.

---

 dlls/gdiplus/brush.c |   48 ++++++++++++++++++++++++++++++++++++++++++++----
 1 files changed, 44 insertions(+), 4 deletions(-)

diff --git a/dlls/gdiplus/brush.c b/dlls/gdiplus/brush.c
index 490a0b9..a2cf1f9 100644
--- a/dlls/gdiplus/brush.c
+++ b/dlls/gdiplus/brush.c
@@ -1642,17 +1642,57 @@ GpStatus WINGDIPAPI GdipSetPathGradientGammaCorrection(GpPathGradient *grad,
 GpStatus WINGDIPAPI GdipSetPathGradientSigmaBlend(GpPathGradient *grad,
     REAL focus, REAL scale)
 {
-    static int calls;
+    REAL factors[33];
+    REAL positions[33];
+    int num_points = 0;
+    int i;
+    const int precision = 16;
+    REAL erf_range; /* we use values erf(-erf_range) through erf(+erf_range) */
+    REAL min_erf;
+    REAL scale_erf;
 
     TRACE("(%p,%0.2f,%0.2f)\n", grad, focus, scale);
 
     if(!grad || focus < 0.0 || focus > 1.0 || scale < 0.0 || scale > 1.0)
         return InvalidParameter;
 
-    if(!(calls++))
-        FIXME("not implemented\n");
+    /* we want 2 standard deviations */
+    erf_range = 2.0 / sqrt(2);
 
-    return NotImplemented;
+    /* calculate the constants we need to normalize the error function to be
+        between 0.0 and scale over the range we need */
+    min_erf = erf(-erf_range);
+    scale_erf = scale / (-2.0 * min_erf);
+
+    if (focus != 0.0)
+    {
+        positions[0] = 0.0;
+        factors[0] = 0.0;
+        for (i=1; i<precision; i++)
+        {
+            positions[i] = focus * i / precision;
+            factors[i] = scale_erf * (erf(2 * erf_range * i / precision - erf_range) - min_erf);
+        }
+        num_points += precision;
+    }
+
+    positions[num_points] = focus;
+    factors[num_points] = scale;
+    num_points += 1;
+
+    if (focus != 1.0)
+    {
+        for (i=1; i<precision; i++)
+        {
+            positions[i+num_points-1] = (focus + ((1.0-focus) * i / precision));
+            factors[i+num_points-1] = scale_erf * (erf(erf_range - 2 * erf_range * i / precision) - min_erf);
+        }
+        num_points += precision;
+        positions[num_points-1] = 1.0;
+        factors[num_points-1] = 0.0;
+    }
+
+    return GdipSetPathGradientBlend(grad, factors, positions, num_points);
 }
 
 GpStatus WINGDIPAPI GdipSetPathGradientSurroundColorsWithCount(GpPathGradient




More information about the wine-cvs mailing list