Merge pull request #3366 from fonttools/interpolatable-refactor2
Interpolatable refactor2
This commit is contained in:
commit
0641526a26
@ -282,14 +282,8 @@ def test_gen(
|
|||||||
# "contour_order" check
|
# "contour_order" check
|
||||||
#
|
#
|
||||||
|
|
||||||
matching, matching_cost, identity_cost = test_contour_order(glyph0, glyph1)
|
this_tolerance, matching = test_contour_order(glyph0, glyph1)
|
||||||
if matching_cost < identity_cost * tolerance:
|
if this_tolerance < tolerance:
|
||||||
log.debug(
|
|
||||||
"matching_ratio %g",
|
|
||||||
matching_cost / identity_cost,
|
|
||||||
)
|
|
||||||
this_tolerance = matching_cost / identity_cost
|
|
||||||
log.debug("tolerance: %g", this_tolerance)
|
|
||||||
yield (
|
yield (
|
||||||
glyph_name,
|
glyph_name,
|
||||||
{
|
{
|
||||||
@ -352,119 +346,109 @@ def test_gen(
|
|||||||
# after reordering above.
|
# after reordering above.
|
||||||
continue
|
continue
|
||||||
|
|
||||||
proposed_point, reverse, min_cost, first_cost = test_starting_point(
|
this_tolerance, proposed_point, reverse = test_starting_point(
|
||||||
glyph0, glyph1, ix, tolerance, matching
|
glyph0, glyph1, ix, tolerance, matching
|
||||||
)
|
)
|
||||||
|
|
||||||
if proposed_point or reverse:
|
if this_tolerance < tolerance:
|
||||||
this_tolerance = min_cost / first_cost
|
yield (
|
||||||
log.debug("tolerance: %g", this_tolerance)
|
glyph_name,
|
||||||
if min_cost < first_cost * tolerance:
|
{
|
||||||
yield (
|
"type": "wrong_start_point",
|
||||||
glyph_name,
|
"contour": ix,
|
||||||
{
|
"master_1": names[m0idx],
|
||||||
"type": "wrong_start_point",
|
"master_2": names[m1idx],
|
||||||
"contour": ix,
|
"master_1_idx": m0idx,
|
||||||
"master_1": names[m0idx],
|
"master_2_idx": m1idx,
|
||||||
"master_2": names[m1idx],
|
"value_1": 0,
|
||||||
"master_1_idx": m0idx,
|
"value_2": proposed_point,
|
||||||
"master_2_idx": m1idx,
|
"reversed": reverse,
|
||||||
"value_1": 0,
|
"tolerance": this_tolerance,
|
||||||
"value_2": proposed_point,
|
},
|
||||||
"reversed": reverse,
|
)
|
||||||
"tolerance": this_tolerance,
|
|
||||||
},
|
|
||||||
)
|
|
||||||
else:
|
|
||||||
# Weight check.
|
|
||||||
#
|
|
||||||
# If contour could be mid-interpolated, and the two
|
|
||||||
# contours have the same area sign, proceeed.
|
|
||||||
#
|
|
||||||
# The sign difference can happen if it's a werido
|
|
||||||
# self-intersecting contour; ignore it.
|
|
||||||
contour = midRecording[ix]
|
|
||||||
|
|
||||||
normalized = False
|
# Weight check.
|
||||||
if contour and (m0Vectors[ix][0] < 0) == (m1Vectors[ix][0] < 0):
|
#
|
||||||
if normalized:
|
# If contour could be mid-interpolated, and the two
|
||||||
midStats = StatisticsPen(glyphset=None)
|
# contours have the same area sign, proceeed.
|
||||||
tpen = TransformPen(
|
#
|
||||||
midStats, transform_from_stats(midStats, inverse=True)
|
# The sign difference can happen if it's a weirdo
|
||||||
)
|
# self-intersecting contour; ignore it.
|
||||||
contour.replay(tpen)
|
contour = midRecording[ix]
|
||||||
|
|
||||||
|
normalized = False
|
||||||
|
if contour and (m0Vectors[ix][0] < 0) == (m1Vectors[ix][0] < 0):
|
||||||
|
if normalized:
|
||||||
|
midStats = StatisticsPen(glyphset=None)
|
||||||
|
tpen = TransformPen(
|
||||||
|
midStats, transform_from_stats(midStats, inverse=True)
|
||||||
|
)
|
||||||
|
contour.replay(tpen)
|
||||||
|
else:
|
||||||
|
midStats = StatisticsPen(glyphset=None)
|
||||||
|
contour.replay(midStats)
|
||||||
|
|
||||||
|
midVector = contour_vector_from_stats(midStats)
|
||||||
|
|
||||||
|
m0Vec = m0Vectors[ix] if not normalized else m0VectorsNormalized[ix]
|
||||||
|
m1Vec = m1Vectors[ix] if not normalized else m1VectorsNormalized[ix]
|
||||||
|
size0 = m0Vec[0] * m0Vec[0]
|
||||||
|
size1 = m1Vec[0] * m1Vec[0]
|
||||||
|
midSize = midVector[0] * midVector[0]
|
||||||
|
|
||||||
|
power = 1
|
||||||
|
t = tolerance**power
|
||||||
|
|
||||||
|
for overweight, problem_type in enumerate(
|
||||||
|
("underweight", "overweight")
|
||||||
|
):
|
||||||
|
if overweight:
|
||||||
|
expectedSize = sqrt(size0 * size1)
|
||||||
|
expectedSize = (size0 + size1) - expectedSize
|
||||||
|
expectedSize = size1 + (midSize - size1)
|
||||||
|
continue
|
||||||
else:
|
else:
|
||||||
midStats = StatisticsPen(glyphset=None)
|
expectedSize = sqrt(size0 * size1)
|
||||||
contour.replay(midStats)
|
|
||||||
|
|
||||||
midVector = contour_vector_from_stats(midStats)
|
log.debug(
|
||||||
|
"%s: actual size %g; threshold size %g, master sizes: %g, %g",
|
||||||
m0Vec = (
|
problem_type,
|
||||||
m0Vectors[ix] if not normalized else m0VectorsNormalized[ix]
|
midSize,
|
||||||
|
expectedSize,
|
||||||
|
size0,
|
||||||
|
size1,
|
||||||
)
|
)
|
||||||
m1Vec = (
|
|
||||||
m1Vectors[ix] if not normalized else m1VectorsNormalized[ix]
|
|
||||||
)
|
|
||||||
size0 = m0Vec[0] * m0Vec[0]
|
|
||||||
size1 = m1Vec[0] * m1Vec[0]
|
|
||||||
midSize = midVector[0] * midVector[0]
|
|
||||||
|
|
||||||
power = 1
|
size0, size1 = sorted((size0, size1))
|
||||||
t = tolerance**power
|
|
||||||
|
|
||||||
for overweight, problem_type in enumerate(
|
if (
|
||||||
("underweight", "overweight")
|
not overweight and expectedSize * tolerance > midSize + 1e-5
|
||||||
):
|
) or (overweight and 1e-5 + expectedSize / tolerance < midSize):
|
||||||
if overweight:
|
try:
|
||||||
expectedSize = sqrt(size0 * size1)
|
if overweight:
|
||||||
expectedSize = (size0 + size1) - expectedSize
|
this_tolerance = (expectedSize / midSize) ** (
|
||||||
expectedSize = size1 + (midSize - size1)
|
1 / power
|
||||||
continue
|
)
|
||||||
else:
|
else:
|
||||||
expectedSize = sqrt(size0 * size1)
|
this_tolerance = (midSize / expectedSize) ** (
|
||||||
|
1 / power
|
||||||
log.debug(
|
)
|
||||||
"%s: actual size %g; threshold size %g, master sizes: %g, %g",
|
except ZeroDivisionError:
|
||||||
problem_type,
|
this_tolerance = 0
|
||||||
midSize,
|
log.debug("tolerance %g", this_tolerance)
|
||||||
expectedSize,
|
yield (
|
||||||
size0,
|
glyph_name,
|
||||||
size1,
|
{
|
||||||
|
"type": problem_type,
|
||||||
|
"contour": ix,
|
||||||
|
"master_1": names[m0idx],
|
||||||
|
"master_2": names[m1idx],
|
||||||
|
"master_1_idx": m0idx,
|
||||||
|
"master_2_idx": m1idx,
|
||||||
|
"tolerance": this_tolerance,
|
||||||
|
},
|
||||||
)
|
)
|
||||||
|
|
||||||
size0, size1 = sorted((size0, size1))
|
|
||||||
|
|
||||||
if (
|
|
||||||
not overweight
|
|
||||||
and expectedSize * tolerance > midSize + 1e-5
|
|
||||||
) or (
|
|
||||||
overweight and 1e-5 + expectedSize / tolerance < midSize
|
|
||||||
):
|
|
||||||
try:
|
|
||||||
if overweight:
|
|
||||||
this_tolerance = (expectedSize / midSize) ** (
|
|
||||||
1 / power
|
|
||||||
)
|
|
||||||
else:
|
|
||||||
this_tolerance = (midSize / expectedSize) ** (
|
|
||||||
1 / power
|
|
||||||
)
|
|
||||||
except ZeroDivisionError:
|
|
||||||
this_tolerance = 0
|
|
||||||
log.debug("tolerance %g", this_tolerance)
|
|
||||||
yield (
|
|
||||||
glyph_name,
|
|
||||||
{
|
|
||||||
"type": problem_type,
|
|
||||||
"contour": ix,
|
|
||||||
"master_1": names[m0idx],
|
|
||||||
"master_2": names[m1idx],
|
|
||||||
"master_1_idx": m0idx,
|
|
||||||
"master_2_idx": m1idx,
|
|
||||||
"tolerance": this_tolerance,
|
|
||||||
},
|
|
||||||
)
|
|
||||||
|
|
||||||
#
|
#
|
||||||
# "kink" detector
|
# "kink" detector
|
||||||
#
|
#
|
||||||
|
@ -1,4 +1,7 @@
|
|||||||
from .interpolatableHelpers import *
|
from .interpolatableHelpers import *
|
||||||
|
import logging
|
||||||
|
|
||||||
|
log = logging.getLogger("fontTools.varLib.interpolatable")
|
||||||
|
|
||||||
|
|
||||||
def test_contour_order(glyph0, glyph1):
|
def test_contour_order(glyph0, glyph1):
|
||||||
@ -71,4 +74,9 @@ def test_contour_order(glyph0, glyph1):
|
|||||||
matching_cost = matching_cost_green
|
matching_cost = matching_cost_green
|
||||||
identity_cost = identity_cost_green
|
identity_cost = identity_cost_green
|
||||||
|
|
||||||
return matching, matching_cost, identity_cost
|
this_tolerance = matching_cost / identity_cost if identity_cost else 1
|
||||||
|
log.debug(
|
||||||
|
"test-contour-order: tolerance %g",
|
||||||
|
this_tolerance,
|
||||||
|
)
|
||||||
|
return this_tolerance, matching
|
||||||
|
@ -19,8 +19,10 @@ def test_starting_point(glyph0, glyph1, ix, tolerance, matching):
|
|||||||
min_cost_idx, min_cost = min(enumerate(costs), key=lambda x: x[1])
|
min_cost_idx, min_cost = min(enumerate(costs), key=lambda x: x[1])
|
||||||
first_cost = costs[0]
|
first_cost = costs[0]
|
||||||
|
|
||||||
|
proposed_point = contour1[min_cost_idx][1]
|
||||||
|
reverse = contour1[min_cost_idx][2]
|
||||||
|
|
||||||
if min_cost < first_cost * tolerance:
|
if min_cost < first_cost * tolerance:
|
||||||
this_tolerance = min_cost / first_cost
|
|
||||||
# c0 is the first isomorphism of the m0 master
|
# c0 is the first isomorphism of the m0 master
|
||||||
# contour1 is list of all isomorphisms of the m1 master
|
# contour1 is list of all isomorphisms of the m1 master
|
||||||
#
|
#
|
||||||
@ -37,8 +39,6 @@ def test_starting_point(glyph0, glyph1, ix, tolerance, matching):
|
|||||||
# closest point again. If it matches this time, let it
|
# closest point again. If it matches this time, let it
|
||||||
# pass.
|
# pass.
|
||||||
|
|
||||||
proposed_point = contour1[min_cost_idx][1]
|
|
||||||
reverse = contour1[min_cost_idx][2]
|
|
||||||
num_points = len(glyph1.points[ix])
|
num_points = len(glyph1.points[ix])
|
||||||
leeway = 3
|
leeway = 3
|
||||||
if not reverse and (
|
if not reverse and (
|
||||||
@ -102,4 +102,9 @@ def test_starting_point(glyph0, glyph1, ix, tolerance, matching):
|
|||||||
# proposed_point = 0 # new_contour1[min_cost_idx][1]
|
# proposed_point = 0 # new_contour1[min_cost_idx][1]
|
||||||
pass
|
pass
|
||||||
|
|
||||||
return proposed_point, reverse, min_cost, first_cost
|
this_tolerance = min_cost / first_cost if first_cost else 1
|
||||||
|
log.debug(
|
||||||
|
"test-starting-point: tolerance %g",
|
||||||
|
this_tolerance,
|
||||||
|
)
|
||||||
|
return this_tolerance, proposed_point, reverse
|
||||||
|
Loading…
x
Reference in New Issue
Block a user