mirror of
https://github.com/thorvg/thorvg.git
synced 2025-06-07 21:23:32 +00:00
sw_engine: fix radial gradient when focal point is outside circle on ARM/Apple Silicon
sw_engine: radial gradient [issues 2014: radial gradient](#2014) Radial gradient results in a corrupted image when the focal point is outside the circle on Apple Silicon. This happens because some compilers use FMA to optimize the a = dr² - dx² - dy² calculation, which cause loss of precision. We rely on temporary variables to prevent FMA. We could also use compiler specific float contraction control pragmas to avoid this if this doesn't work in the future
This commit is contained in:
parent
5b76206540
commit
cea221e2d5
3 changed files with 20 additions and 1 deletions
1
AUTHORS
1
AUTHORS
|
@ -26,3 +26,4 @@ SergeyLebedkin <sergii@lottiefiles.com>
|
|||
Jinny You <jinny@lottiefiles.com>
|
||||
Nattu Adnan <nattu@reallynattu.com>
|
||||
Gabor Kiss-Vamosi <kisvegabor@gmail.com>
|
||||
Lorcán Mc Donagh <lorcan@lmdsp.com>
|
||||
|
|
|
@ -0,0 +1,12 @@
|
|||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<svg width="800" height="590" version="1.1" id="https://github.com/thorvg/thorvg/issues/2014" xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:svg="http://www.w3.org/2000/svg">
|
||||
<defs>
|
||||
<radialGradient cx="429" cy="3" fx="429" fy="-600" gradientUnits="userSpaceOnUse" id="b" r="600">
|
||||
<stop offset="0" stop-color="red" id="stop10" />
|
||||
<stop offset="1" stop-color="white" id="stop11" />
|
||||
</radialGradient>
|
||||
</defs>
|
||||
|
||||
<path d="M 800,200 H 0 V 590 H 800 V 0 Z" fill="url(#b)" id="svg_4" />
|
||||
</svg>
|
After Width: | Height: | Size: 575 B |
|
@ -201,7 +201,13 @@ bool _prepareRadial(SwFill* fill, const RadialGradient* radial, const Matrix* tr
|
|||
fill->radial.fy = cy + r * (fy - cy) / dist;
|
||||
fill->radial.dx = cx - fill->radial.fx;
|
||||
fill->radial.dy = cy - fill->radial.fy;
|
||||
fill->radial.a = fill->radial.dr * fill->radial.dr - fill->radial.dx * fill->radial.dx - fill->radial.dy * fill->radial.dy;
|
||||
// Prevent loss of precision on Apple Silicon when dr=dy and dx=0 due to FMA
|
||||
// https://github.com/thorvg/thorvg/issues/2014
|
||||
auto dr2 = fill->radial.dr * fill->radial.dr;
|
||||
auto dx2 = fill->radial.dx * fill->radial.dx;
|
||||
auto dy2 = fill->radial.dy * fill->radial.dy;
|
||||
|
||||
fill->radial.a = dr2 - dx2 - dy2;
|
||||
}
|
||||
|
||||
if (fill->radial.a > 0) fill->radial.invA = 1.0f / fill->radial.a;
|
||||
|
|
Loading…
Add table
Reference in a new issue