sw_engine: fix focal point clamping
Some checks are pending
Android / build_x86_64 (push) Waiting to run
Android / build_aarch64 (push) Waiting to run
iOS / build_x86_64 (push) Waiting to run
iOS / build_arm64 (push) Waiting to run
macOS / build (push) Waiting to run
macOS / compact_test (push) Waiting to run
macOS / unit_test (push) Waiting to run
Ubuntu / build (push) Waiting to run
Ubuntu / compact_test (push) Waiting to run
Ubuntu / unit_test (push) Waiting to run
Windows / build (push) Waiting to run
Windows / compact_test (push) Waiting to run
Windows / unit_test (push) Waiting to run

This approach should be introduced in d8ebd8b4f5.
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.
This commit is contained in:
Mira Grudzinska 2025-06-18 12:13:39 +02:00 committed by Hermet Park
parent 666a8b7682
commit 3426531dd2

View file

@ -262,11 +262,12 @@ bool _prepareRadial(SwFill* fill, const RadialGradient* radial, const Matrix& pT
//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