Nikolay Sivov : gdiplus: Implement unfilled mode for arrow caps.

Alexandre Julliard julliard at winehq.org
Mon May 14 17:20:10 CDT 2018


Module: wine
Branch: master
Commit: 39c8ebddcc302dac896dcd594a43b16e52d723c4
URL:    https://source.winehq.org/git/wine.git/?a=commit;h=39c8ebddcc302dac896dcd594a43b16e52d723c4

Author: Nikolay Sivov <nsivov at codeweavers.com>
Date:   Mon May 14 07:59:36 2018 +0300

gdiplus: Implement unfilled mode for arrow caps.

Signed-off-by: Nikolay Sivov <nsivov at codeweavers.com>
Signed-off-by: Vincent Povirk <vincent at codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard at winehq.org>

---

 dlls/gdiplus/customlinecap.c       | 75 +++++++++++++++++++++++---------------
 dlls/gdiplus/tests/customlinecap.c |  5 +--
 2 files changed, 46 insertions(+), 34 deletions(-)

diff --git a/dlls/gdiplus/customlinecap.c b/dlls/gdiplus/customlinecap.c
index 7fbe8b6..c74928e 100644
--- a/dlls/gdiplus/customlinecap.c
+++ b/dlls/gdiplus/customlinecap.c
@@ -282,19 +282,43 @@ GpStatus WINGDIPAPI GdipGetCustomLineCapType(GpCustomLineCap *customCap, CustomL
 
 static void arrowcap_update_path(GpAdjustableArrowCap *cap)
 {
+    static const BYTE types_filled[] =
+    {
+        PathPointTypeStart, PathPointTypeLine, PathPointTypeLine, PathPointTypeLine | PathPointTypeCloseSubpath
+    };
+    static const BYTE types_unfilled[] =
+    {
+        PathPointTypeStart, PathPointTypeLine, PathPointTypeLine
+    };
     GpPointF *points;
 
-    assert(cap->cap.pathdata.Count == 4);
+    assert(cap->cap.pathdata.Count == 3 || cap->cap.pathdata.Count == 4);
 
     points = cap->cap.pathdata.Points;
-    points[0].X = 0.0;
-    points[0].Y = 0.0;
-    points[1].X = -cap->width / 2.0;
-    points[1].Y = -cap->height;
-    points[2].X = 0.0;
-    points[2].Y = -cap->height - cap->middle_inset;
-    points[3].X = cap->width / 2.0;
-    points[3].Y = -cap->height;
+    if (cap->cap.fill)
+    {
+        memcpy(cap->cap.pathdata.Types, types_filled, sizeof(types_filled));
+        cap->cap.pathdata.Count = 4;
+        points[0].X = -cap->width / 2.0;
+        points[0].Y = -cap->height;
+        points[1].X = 0.0;
+        points[1].Y = 0.0;
+        points[2].X = cap->width / 2.0;
+        points[2].Y = -cap->height;
+        points[3].X = 0.0;
+        points[3].Y = -cap->height - cap->middle_inset;
+    }
+    else
+    {
+        memcpy(cap->cap.pathdata.Types, types_unfilled, sizeof(types_unfilled));
+        cap->cap.pathdata.Count = 3;
+        points[0].X = -cap->width / 4.0;
+        points[0].Y = -cap->height / 2.0;
+        points[1].X = 0.0;
+        points[1].Y = 0.0;
+        points[2].X = cap->width / 4.0;
+        points[2].Y = -cap->height / 2.0;
+    }
 
     if (cap->width == 0.0)
         cap->cap.inset = 0.0;
@@ -306,7 +330,6 @@ GpStatus WINGDIPAPI GdipCreateAdjustableArrowCap(REAL height, REAL width, BOOL f
     GpAdjustableArrowCap **cap)
 {
     GpPathData pathdata;
-    BYTE types[4];
     GpStatus stat;
 
     TRACE("(%0.2f,%0.2f,%i,%p)\n", height, width, fill, cap);
@@ -314,22 +337,15 @@ GpStatus WINGDIPAPI GdipCreateAdjustableArrowCap(REAL height, REAL width, BOOL f
     if (!cap)
         return InvalidParameter;
 
-    if (!fill)
-        FIXME("Arrows without fills are not supported.\n");
-
     *cap = heap_alloc_zero(sizeof(**cap));
     if (!*cap)
         return OutOfMemory;
 
-    types[0] = PathPointTypeStart;
-    types[1] = PathPointTypeLine;
-    types[2] = PathPointTypeLine;
-    types[3] = PathPointTypeLine | PathPointTypeCloseSubpath;
-
+    /* We'll need 4 points at most. */
     pathdata.Count = 4;
     pathdata.Points = NULL;
-    pathdata.Types = types;
-    stat = init_custom_linecap(&(*cap)->cap, &pathdata, TRUE, LineCapTriangle, width != 0.0 ? height / width : 0.0);
+    pathdata.Types = NULL;
+    stat = init_custom_linecap(&(*cap)->cap, &pathdata, fill, LineCapTriangle, width != 0.0 ? height / width : 0.0);
     if (stat != Ok)
     {
         heap_free(*cap);
@@ -347,14 +363,13 @@ GpStatus WINGDIPAPI GdipCreateAdjustableArrowCap(REAL height, REAL width, BOOL f
 
 GpStatus WINGDIPAPI GdipGetAdjustableArrowCapFillState(GpAdjustableArrowCap* cap, BOOL* fill)
 {
-    static int calls;
-
     TRACE("(%p,%p)\n", cap, fill);
 
-    if(!(calls++))
-        FIXME("not implemented\n");
+    if (!cap || !fill)
+        return InvalidParameter;
 
-    return NotImplemented;
+    *fill = cap->cap.fill;
+    return Ok;
 }
 
 GpStatus WINGDIPAPI GdipGetAdjustableArrowCapHeight(GpAdjustableArrowCap* cap, REAL* height)
@@ -392,14 +407,14 @@ GpStatus WINGDIPAPI GdipGetAdjustableArrowCapWidth(GpAdjustableArrowCap* cap, RE
 
 GpStatus WINGDIPAPI GdipSetAdjustableArrowCapFillState(GpAdjustableArrowCap* cap, BOOL fill)
 {
-    static int calls;
-
     TRACE("(%p,%i)\n", cap, fill);
 
-    if(!(calls++))
-        FIXME("not implemented\n");
+    if (!cap)
+        return InvalidParameter;
 
-    return NotImplemented;
+    cap->cap.fill = fill;
+    arrowcap_update_path(cap);
+    return Ok;
 }
 
 GpStatus WINGDIPAPI GdipSetAdjustableArrowCapHeight(GpAdjustableArrowCap* cap, REAL height)
diff --git a/dlls/gdiplus/tests/customlinecap.c b/dlls/gdiplus/tests/customlinecap.c
index 6a22c26..e4ec329 100644
--- a/dlls/gdiplus/tests/customlinecap.c
+++ b/dlls/gdiplus/tests/customlinecap.c
@@ -250,16 +250,13 @@ static void test_create_adjustable_cap(void)
     ok(stat == Ok, "Failed to create adjustable cap, %d\n", stat);
 
     stat = GdipGetAdjustableArrowCapFillState(cap, NULL);
-todo_wine
     ok(stat == InvalidParameter, "Unexpected return code, %d\n", stat);
 
     ret = FALSE;
     stat = GdipGetAdjustableArrowCapFillState(cap, &ret);
-todo_wine
-{
     ok(stat == Ok, "Unexpected return code, %d\n", stat);
     ok(ret, "Unexpected fill state %d\n", ret);
-}
+
     stat = GdipGetAdjustableArrowCapHeight(cap, NULL);
     ok(stat == InvalidParameter, "Unexpected return code, %d\n", stat);
 




More information about the wine-cvs mailing list