[PATCH 4/6] gdiplus: Add LineCapSquareAnchor path-widening.

Jeff Smith whydoubt at gmail.com
Tue Feb 18 23:51:59 CST 2020


Signed-off-by: Jeff Smith <whydoubt at gmail.com>
---
 dlls/gdiplus/graphicspath.c       | 50 +++++++++++++++++++++++++++++--
 dlls/gdiplus/tests/graphicspath.c |  2 +-
 2 files changed, 49 insertions(+), 3 deletions(-)

diff --git a/dlls/gdiplus/graphicspath.c b/dlls/gdiplus/graphicspath.c
index 96078c3da9..fcb2ed0b9e 100644
--- a/dlls/gdiplus/graphicspath.c
+++ b/dlls/gdiplus/graphicspath.c
@@ -1983,6 +1983,44 @@ static void widen_cap(const GpPointF *endpoint, const GpPointF *nextpoint,
     }
 }
 
+static void add_anchor(const GpPointF *endpoint, const GpPointF *nextpoint,
+    GpPen *pen, GpLineCap cap, GpCustomLineCap *custom, path_list_node_t **last_point)
+{
+    switch (cap)
+    {
+    default:
+    case LineCapNoAnchor:
+        return;
+    case LineCapSquareAnchor:
+    {
+        REAL segment_dy = nextpoint->Y-endpoint->Y;
+        REAL segment_dx = nextpoint->X-endpoint->X;
+        REAL segment_length = sqrtf(segment_dy*segment_dy + segment_dx*segment_dx);
+        REAL distance = pen->width / sqrtf(2.0);
+        REAL par_dx, par_dy;
+        REAL perp_dx, perp_dy;
+
+        par_dx = -distance * segment_dx / segment_length;
+        par_dy = -distance * segment_dy / segment_length;
+
+        perp_dx = -distance * segment_dy / segment_length;
+        perp_dy = distance * segment_dx / segment_length;
+
+        *last_point = add_path_list_node(*last_point, endpoint->X - par_dx - perp_dx,
+            endpoint->Y - par_dy - perp_dy, PathPointTypeStart);
+        *last_point = add_path_list_node(*last_point, endpoint->X - par_dx + perp_dx,
+            endpoint->Y - par_dy + perp_dy, PathPointTypeLine);
+        *last_point = add_path_list_node(*last_point, endpoint->X + par_dx + perp_dx,
+            endpoint->Y + par_dy + perp_dy, PathPointTypeLine);
+        *last_point = add_path_list_node(*last_point, endpoint->X + par_dx - perp_dx,
+            endpoint->Y + par_dy - perp_dy, PathPointTypeLine);
+        break;
+    }
+    }
+
+    (*last_point)->type |= PathPointTypeCloseSubpath;
+}
+
 static void widen_open_figure(const GpPointF *points, GpPen *pen, int start, int end,
     GpLineCap start_cap, GpCustomLineCap *start_custom, GpLineCap end_cap,
     GpCustomLineCap *end_custom, path_list_node_t **last_point)
@@ -2014,6 +2052,14 @@ static void widen_open_figure(const GpPointF *points, GpPen *pen, int start, int
 
     prev_point->next->type = PathPointTypeStart;
     (*last_point)->type |= PathPointTypeCloseSubpath;
+
+    if (start_cap & LineCapAnchorMask)
+        add_anchor(&points[start], &points[start+1],
+            pen, start_cap, start_custom, last_point);
+
+    if (end_cap & LineCapAnchorMask)
+        add_anchor(&points[end], &points[end-1],
+            pen, end_cap, end_custom, last_point);
 }
 
 static void widen_closed_figure(GpPath *path, GpPen *pen, int start, int end,
@@ -2225,10 +2271,10 @@ GpStatus WINGDIPAPI GdipWidenPath(GpPath *path, GpPen *pen, GpMatrix *matrix,
     {
         last_point = points;
 
-        if (pen->endcap > LineCapTriangle)
+        if (pen->endcap > LineCapSquareAnchor)
             FIXME("unimplemented end cap %x\n", pen->endcap);
 
-        if (pen->startcap > LineCapTriangle)
+        if (pen->startcap > LineCapSquareAnchor)
             FIXME("unimplemented start cap %x\n", pen->startcap);
 
         if (pen->dashcap != DashCapFlat)
diff --git a/dlls/gdiplus/tests/graphicspath.c b/dlls/gdiplus/tests/graphicspath.c
index b840801739..9ce95a2c74 100644
--- a/dlls/gdiplus/tests/graphicspath.c
+++ b/dlls/gdiplus/tests/graphicspath.c
@@ -1385,7 +1385,7 @@ static void test_widen_cap(void)
         { LineCapNoAnchor, widenline_capflat_path,
                 ARRAY_SIZE(widenline_capflat_path) },
         { LineCapSquareAnchor, widenline_capsquareanchor_path,
-                ARRAY_SIZE(widenline_capsquareanchor_path), TRUE },
+                ARRAY_SIZE(widenline_capsquareanchor_path) },
         { LineCapRoundAnchor, widenline_caproundanchor_path,
                 ARRAY_SIZE(widenline_caproundanchor_path), TRUE },
         { LineCapDiamondAnchor, widenline_capdiamondanchor_path,
-- 
2.23.0




More information about the wine-devel mailing list