[PATCH 5/6] gdiplus: Add LineCapRoundAnchor path-widening.

Jeff Smith whydoubt at gmail.com
Tue Feb 18 23:52:00 CST 2020


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

diff --git a/dlls/gdiplus/graphicspath.c b/dlls/gdiplus/graphicspath.c
index fcb2ed0b9e..79d99a3eb4 100644
--- a/dlls/gdiplus/graphicspath.c
+++ b/dlls/gdiplus/graphicspath.c
@@ -2016,6 +2016,58 @@ static void add_anchor(const GpPointF *endpoint, const GpPointF *nextpoint,
             endpoint->Y + par_dy - perp_dy, PathPointTypeLine);
         break;
     }
+    case LineCapRoundAnchor:
+    {
+        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 dx, dy, dx2, dy2;
+        const REAL control_point_distance = 0.55228475; /* 4/3 * (sqrt(2) - 1) */
+
+        dx = -pen->width * segment_dx / segment_length;
+        dy = -pen->width * segment_dy / segment_length;
+
+        dx2 = dx * control_point_distance;
+        dy2 = dy * control_point_distance;
+
+        /* starting point */
+        *last_point = add_path_list_node(*last_point, endpoint->X + dy,
+            endpoint->Y - dx, PathPointTypeStart);
+
+        /* first 90-degree arc */
+        *last_point = add_path_list_node(*last_point, endpoint->X + dy + dx2,
+            endpoint->Y - dx + dy2, PathPointTypeBezier);
+        *last_point = add_path_list_node(*last_point, endpoint->X + dx + dy2,
+            endpoint->Y + dy - dx2, PathPointTypeBezier);
+        *last_point = add_path_list_node(*last_point, endpoint->X + dx,
+            endpoint->Y + dy, PathPointTypeBezier);
+
+        /* second 90-degree arc */
+        *last_point = add_path_list_node(*last_point, endpoint->X + dx - dy2,
+            endpoint->Y + dy + dx2, PathPointTypeBezier);
+        *last_point = add_path_list_node(*last_point, endpoint->X - dy + dx2,
+            endpoint->Y + dx + dy2, PathPointTypeBezier);
+        *last_point = add_path_list_node(*last_point, endpoint->X - dy,
+            endpoint->Y + dx, PathPointTypeBezier);
+
+        /* third 90-degree arc */
+        *last_point = add_path_list_node(*last_point, endpoint->X - dy - dx2,
+            endpoint->Y + dx - dy2, PathPointTypeBezier);
+        *last_point = add_path_list_node(*last_point, endpoint->X - dx - dy2,
+            endpoint->Y - dy + dx2, PathPointTypeBezier);
+        *last_point = add_path_list_node(*last_point, endpoint->X - dx,
+            endpoint->Y - dy, PathPointTypeBezier);
+
+        /* fourth 90-degree arc */
+        *last_point = add_path_list_node(*last_point, endpoint->X - dx + dy2,
+            endpoint->Y - dy - dx2, PathPointTypeBezier);
+        *last_point = add_path_list_node(*last_point, endpoint->X + dy - dx2,
+            endpoint->Y - dx - dy2, PathPointTypeBezier);
+        *last_point = add_path_list_node(*last_point, endpoint->X + dy,
+            endpoint->Y - dx, PathPointTypeBezier);
+
+        break;
+    }
     }
 
     (*last_point)->type |= PathPointTypeCloseSubpath;
@@ -2271,10 +2323,10 @@ GpStatus WINGDIPAPI GdipWidenPath(GpPath *path, GpPen *pen, GpMatrix *matrix,
     {
         last_point = points;
 
-        if (pen->endcap > LineCapSquareAnchor)
+        if (pen->endcap > LineCapRoundAnchor)
             FIXME("unimplemented end cap %x\n", pen->endcap);
 
-        if (pen->startcap > LineCapSquareAnchor)
+        if (pen->startcap > LineCapRoundAnchor)
             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 9ce95a2c74..6acfddd53e 100644
--- a/dlls/gdiplus/tests/graphicspath.c
+++ b/dlls/gdiplus/tests/graphicspath.c
@@ -1387,7 +1387,7 @@ static void test_widen_cap(void)
         { LineCapSquareAnchor, widenline_capsquareanchor_path,
                 ARRAY_SIZE(widenline_capsquareanchor_path) },
         { LineCapRoundAnchor, widenline_caproundanchor_path,
-                ARRAY_SIZE(widenline_caproundanchor_path), TRUE },
+                ARRAY_SIZE(widenline_caproundanchor_path) },
         { LineCapDiamondAnchor, widenline_capdiamondanchor_path,
                 ARRAY_SIZE(widenline_capdiamondanchor_path), TRUE },
         { LineCapArrowAnchor, widenline_caparrowanchor_path,
-- 
2.23.0




More information about the wine-devel mailing list