[PATCH 2/2] gdiplus: Revise closeness check for bezier curve flattening.
Robert Feuerbach
rjfeuerbach at gmail.com
Fri Feb 4 09:58:48 CST 2022
The float equality and flatness calculation in flatten_bezier
can fail due to the limited precision of the float math.
The equality test was replaced with a simple check against
the given flatness tolerance.
Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=52492
Signed-off-by: Robert Feuerbach <rjfeuerbach at gmail.com>
---
dlls/gdiplus/graphicspath.c | 11 ++++++-----
1 file changed, 6 insertions(+), 5 deletions(-)
diff --git a/dlls/gdiplus/graphicspath.c b/dlls/gdiplus/graphicspath.c
index ce2666eedab..c1bdf226e52 100644
--- a/dlls/gdiplus/graphicspath.c
+++ b/dlls/gdiplus/graphicspath.c
@@ -109,7 +109,7 @@ static INT path_list_count(path_list_node_t *node)
* - (x2, y2): first control point;
* - (x3, y3): second control point;
* - end : pointer to end point node
- * - flatness: admissible error of linear approximation.
+ * - flatness: admissible error of linear approximation in coordinate units.
*
* Return value:
* TRUE : success
@@ -142,12 +142,13 @@ static BOOL flatten_bezier(path_list_node_t *start, REAL x2, REAL y2, REAL x3, R
mp[2].X = (mp[1].X + mp[3].X) / 2.0;
mp[2].Y = (mp[1].Y + mp[3].Y) / 2.0;
- if ((x2 == mp[0].X && y2 == mp[0].Y && x3 == mp[1].X && y3 == mp[1].Y) ||
- (x2 == mp[3].X && y2 == mp[3].Y && x3 == mp[4].X && y3 == mp[4].Y))
- return TRUE;
-
pt = end->pt;
pt_st = start->pt;
+ /* test for closely spaced points to avoid limited-precision errors in flatness check */
+ if((fabs(pt.X - mp[2].X) + fabs(pt.Y - mp[2].Y) +
+ fabs(pt_st.X - mp[2].X) + fabs(pt_st.Y - mp[2].Y) ) <= flatness)
+ return TRUE;
+
/* check flatness as a half of distance between middle point and a linearized path */
if(fabs(((pt.Y - pt_st.Y)*mp[2].X + (pt_st.X - pt.X)*mp[2].Y +
(pt_st.Y*pt.X - pt_st.X*pt.Y))) <=
--
2.32.0 (Apple Git-132)
More information about the wine-devel
mailing list