[colorLib.geometry] use math.isclose with relative tolerance to check circle inside-ness
Fixes rounding of radial gradient in 'SING OF THE HORNS' (medium-light skin tone) noto emoji 🤘🏼
This commit is contained in:
parent
69fc06a1af
commit
5558ccd3bb
@ -1,6 +1,6 @@
|
||||
"""Helpers for manipulating 2D points and vectors in COLR table."""
|
||||
|
||||
from math import copysign, cos, hypot, pi
|
||||
from math import copysign, cos, hypot, isclose, pi
|
||||
from fontTools.misc.roundTools import otRound
|
||||
|
||||
|
||||
@ -19,9 +19,7 @@ def _unit_vector(vec):
|
||||
return (vec[0] / length, vec[1] / length)
|
||||
|
||||
|
||||
# This is the same tolerance used by Skia's SkTwoPointConicalGradient.cpp to detect
|
||||
# when a radial gradient's focal point lies on the end circle.
|
||||
_NEARLY_ZERO = 1 / (1 << 12) # 0.000244140625
|
||||
_CIRCLE_INSIDE_TOLERANCE = 1e-4
|
||||
|
||||
|
||||
# The unit vector's X and Y components are respectively
|
||||
@ -64,10 +62,10 @@ class Circle:
|
||||
def round(self):
|
||||
return Circle(_round_point(self.centre), otRound(self.radius))
|
||||
|
||||
def inside(self, outer_circle):
|
||||
def inside(self, outer_circle, tolerance=_CIRCLE_INSIDE_TOLERANCE):
|
||||
dist = self.radius + hypot(*_vector_between(self.centre, outer_circle.centre))
|
||||
return (
|
||||
abs(outer_circle.radius - dist) <= _NEARLY_ZERO
|
||||
isclose(outer_circle.radius, dist, rel_tol=_CIRCLE_INSIDE_TOLERANCE)
|
||||
or outer_circle.radius > dist
|
||||
)
|
||||
|
||||
|
@ -1747,6 +1747,16 @@ class TrickyRadialGradientTest:
|
||||
r1 = 260.0072
|
||||
assert self.round_start_circle(c0, r0, c1, r1, inside=True) == ((386, 71), 0)
|
||||
|
||||
def test_noto_emoji_horns_sign_u1f918_1f3fc(self):
|
||||
# This radial gradient is taken from noto-emoji's 'SIGNS OF THE HORNS'
|
||||
# (1f918_1f3fc). We check that c0 is inside c1 both before and after rounding.
|
||||
c0 = (-437.6789059060543, -2116.9237094478003)
|
||||
r0 = 0.0
|
||||
c1 = (-488.7330118252256, -1876.5036857045086)
|
||||
r1 = 245.77147821915673
|
||||
assert self.circle_inside_circle(c0, r0, c1, r1)
|
||||
assert self.circle_inside_circle(c0, r0, c1, r1, rounded=True)
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
"c0, r0, c1, r1, inside, expected",
|
||||
[
|
||||
|
Loading…
x
Reference in New Issue
Block a user