From 65844fa590b54839923443256f04785202e1e573 Mon Sep 17 00:00:00 2001 From: Mira Grudzinska Date: Wed, 18 Jun 2025 12:13:39 +0200 Subject: [PATCH] sw_engine: fix focal point clamping This approach should be introduced in d8ebd8b4f517a013479bfbebbcdd3523ca3173ee. Using FLOAT_EPSILON is not sufficient due to numerical precision, since it's later inverted, and its very small value leads to significant errors during inversion. --- src/renderer/sw_engine/tvgSwFill.cpp | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/src/renderer/sw_engine/tvgSwFill.cpp b/src/renderer/sw_engine/tvgSwFill.cpp index 19b80f21..383d9b65 100644 --- a/src/renderer/sw_engine/tvgSwFill.cpp +++ b/src/renderer/sw_engine/tvgSwFill.cpp @@ -277,11 +277,12 @@ bool _prepareRadial(SwFill* fill, const RadialGradient* radial, const Matrix& tr //This condition fulfills the SVG 1.1 std: //the focal point, if outside the end circle, is moved to be on the end circle //See: the SVG 2 std requirements: https://www.w3.org/TR/SVG2/pservers.html#RadialGradientNotes - if (fill->radial.a <= FLOAT_EPSILON) { + constexpr float precision = 0.01f; + if (fill->radial.a <= precision) { auto dist = sqrtf(fill->radial.dx * fill->radial.dx + fill->radial.dy * fill->radial.dy); - constexpr const float precision = 0.99f; //retract focal point slightly from edge to avoid numerical errors - fill->radial.fx = cx + r * precision * (fx - cx) / dist; - fill->radial.fy = cy + r * precision * (fy - cy) / dist; + //retract focal point slightly from edge to avoid numerical errors: + fill->radial.fx = cx + r * (1.0f - precision) * (fx - cx) / dist; + fill->radial.fy = cy + r * (1.0f - precision) * (fy - cy) / dist; fill->radial.dx = cx - fill->radial.fx; fill->radial.dy = cy - fill->radial.fy; // Prevent loss of precision on Apple Silicon when dr=dy and dx=0 due to FMA