[varLib/merger] Fix merging of SinglePos with pos=0
Fixes https://github.com/fonttools/fonttools/issues/3111
This commit is contained in:
parent
65bc6105f7
commit
4c24a3e328
@ -81,7 +81,6 @@ class Merger(object):
|
|||||||
typ = type(thing)
|
typ = type(thing)
|
||||||
|
|
||||||
for celf in celf.mro():
|
for celf in celf.mro():
|
||||||
|
|
||||||
mergers = getattr(celf, "mergers", None)
|
mergers = getattr(celf, "mergers", None)
|
||||||
if mergers is None:
|
if mergers is None:
|
||||||
break
|
break
|
||||||
@ -318,7 +317,13 @@ def merge(merger, self, lst):
|
|||||||
):
|
):
|
||||||
self.Value = otBase.ValueRecord(valueFormat, self.Value)
|
self.Value = otBase.ValueRecord(valueFormat, self.Value)
|
||||||
if valueFormat != 0:
|
if valueFormat != 0:
|
||||||
merger.mergeThings(self.Value, [v.Value for v in lst])
|
# If v.Value is None, it means a kerning of 0; we want
|
||||||
|
# it to participate in the model still.
|
||||||
|
# https://github.com/fonttools/fonttools/issues/3111
|
||||||
|
merger.mergeThings(
|
||||||
|
self.Value,
|
||||||
|
[v.Value if v.Value is not None else otBase.ValueRecord() for v in lst],
|
||||||
|
)
|
||||||
self.ValueFormat = self.Value.getFormat()
|
self.ValueFormat = self.Value.getFormat()
|
||||||
return
|
return
|
||||||
|
|
||||||
@ -449,7 +454,6 @@ def _PairPosFormat1_merge(self, lst, merger):
|
|||||||
|
|
||||||
|
|
||||||
def _ClassDef_invert(self, allGlyphs=None):
|
def _ClassDef_invert(self, allGlyphs=None):
|
||||||
|
|
||||||
if isinstance(self, dict):
|
if isinstance(self, dict):
|
||||||
classDefs = self
|
classDefs = self
|
||||||
else:
|
else:
|
||||||
@ -505,7 +509,6 @@ def _ClassDef_merge_classify(lst, allGlyphses=None):
|
|||||||
|
|
||||||
|
|
||||||
def _PairPosFormat2_align_matrices(self, lst, font, transparent=False):
|
def _PairPosFormat2_align_matrices(self, lst, font, transparent=False):
|
||||||
|
|
||||||
matrices = [l.Class1Record for l in lst]
|
matrices = [l.Class1Record for l in lst]
|
||||||
|
|
||||||
# Align first classes
|
# Align first classes
|
||||||
@ -1057,7 +1060,6 @@ def merge(merger, self, lst):
|
|||||||
("XPlacement", "XPlaDevice"),
|
("XPlacement", "XPlaDevice"),
|
||||||
("YPlacement", "YPlaDevice"),
|
("YPlacement", "YPlaDevice"),
|
||||||
]:
|
]:
|
||||||
|
|
||||||
assert not hasattr(self, tableName)
|
assert not hasattr(self, tableName)
|
||||||
|
|
||||||
if hasattr(self, name):
|
if hasattr(self, name):
|
||||||
@ -1085,7 +1087,6 @@ class MutatorMerger(AligningMerger):
|
|||||||
|
|
||||||
@MutatorMerger.merger(ot.CaretValue)
|
@MutatorMerger.merger(ot.CaretValue)
|
||||||
def merge(merger, self, lst):
|
def merge(merger, self, lst):
|
||||||
|
|
||||||
# Hack till we become selfless.
|
# Hack till we become selfless.
|
||||||
self.__dict__ = lst[0].__dict__.copy()
|
self.__dict__ = lst[0].__dict__.copy()
|
||||||
|
|
||||||
@ -1108,7 +1109,6 @@ def merge(merger, self, lst):
|
|||||||
|
|
||||||
@MutatorMerger.merger(ot.Anchor)
|
@MutatorMerger.merger(ot.Anchor)
|
||||||
def merge(merger, self, lst):
|
def merge(merger, self, lst):
|
||||||
|
|
||||||
# Hack till we become selfless.
|
# Hack till we become selfless.
|
||||||
self.__dict__ = lst[0].__dict__.copy()
|
self.__dict__ = lst[0].__dict__.copy()
|
||||||
|
|
||||||
@ -1139,7 +1139,6 @@ def merge(merger, self, lst):
|
|||||||
|
|
||||||
@MutatorMerger.merger(otBase.ValueRecord)
|
@MutatorMerger.merger(otBase.ValueRecord)
|
||||||
def merge(merger, self, lst):
|
def merge(merger, self, lst):
|
||||||
|
|
||||||
# Hack till we become selfless.
|
# Hack till we become selfless.
|
||||||
self.__dict__ = lst[0].__dict__.copy()
|
self.__dict__ = lst[0].__dict__.copy()
|
||||||
|
|
||||||
@ -1150,7 +1149,6 @@ def merge(merger, self, lst):
|
|||||||
("XPlacement", "XPlaDevice"),
|
("XPlacement", "XPlaDevice"),
|
||||||
("YPlacement", "YPlaDevice"),
|
("YPlacement", "YPlaDevice"),
|
||||||
]:
|
]:
|
||||||
|
|
||||||
if not hasattr(self, tableName):
|
if not hasattr(self, tableName):
|
||||||
continue
|
continue
|
||||||
dev = getattr(self, tableName)
|
dev = getattr(self, tableName)
|
||||||
@ -1266,7 +1264,6 @@ def merge(merger, self, lst):
|
|||||||
("XPlacement", "XPlaDevice"),
|
("XPlacement", "XPlaDevice"),
|
||||||
("YPlacement", "YPlaDevice"),
|
("YPlacement", "YPlaDevice"),
|
||||||
]:
|
]:
|
||||||
|
|
||||||
if hasattr(self, name):
|
if hasattr(self, name):
|
||||||
value, deviceTable = buildVarDevTable(
|
value, deviceTable = buildVarDevTable(
|
||||||
merger.store_builder, [getattr(a, name, 0) for a in lst]
|
merger.store_builder, [getattr(a, name, 0) for a in lst]
|
||||||
|
@ -7,6 +7,7 @@ from fontTools.varLib.models import VariationModel
|
|||||||
from fontTools.ttLib import TTFont
|
from fontTools.ttLib import TTFont
|
||||||
from fontTools.ttLib.tables import otTables as ot
|
from fontTools.ttLib.tables import otTables as ot
|
||||||
from fontTools.ttLib.tables.otBase import OTTableReader, OTTableWriter
|
from fontTools.ttLib.tables.otBase import OTTableReader, OTTableWriter
|
||||||
|
from io import BytesIO
|
||||||
import pytest
|
import pytest
|
||||||
|
|
||||||
|
|
||||||
@ -1842,3 +1843,41 @@ class COLRVariationMergerTest:
|
|||||||
|
|
||||||
if colr.table.LayerList:
|
if colr.table.LayerList:
|
||||||
assert len({id(p) for p in colr.table.LayerList.Paint}) == after_layer_count
|
assert len({id(p) for p in colr.table.LayerList.Paint}) == after_layer_count
|
||||||
|
|
||||||
|
|
||||||
|
class SparsePositioningMergerTest:
|
||||||
|
def test_sparse_positioning_at_default(self):
|
||||||
|
# https://github.com/fonttools/fonttools/issues/3111
|
||||||
|
|
||||||
|
pytest.importorskip("ufo2ft")
|
||||||
|
pytest.importorskip("ufoLib2")
|
||||||
|
|
||||||
|
from fontTools.designspaceLib import DesignSpaceDocument
|
||||||
|
from ufo2ft import compileVariableTTF
|
||||||
|
from ufoLib2 import Font
|
||||||
|
|
||||||
|
ds = DesignSpaceDocument()
|
||||||
|
ds.addAxisDescriptor(
|
||||||
|
name="wght", tag="wght", minimum=100, maximum=900, default=400
|
||||||
|
)
|
||||||
|
ds.addSourceDescriptor(font=Font(), location=dict(wght=100))
|
||||||
|
ds.addSourceDescriptor(font=Font(), location=dict(wght=400))
|
||||||
|
ds.addSourceDescriptor(font=Font(), location=dict(wght=900))
|
||||||
|
|
||||||
|
ds.sources[0].font.newGlyph("a").unicode = ord("a")
|
||||||
|
ds.sources[0].font.newGlyph("b").unicode = ord("b")
|
||||||
|
ds.sources[0].font.features.text = "feature kern { pos a b b' 100; } kern;"
|
||||||
|
|
||||||
|
ds.sources[1].font.newGlyph("a").unicode = ord("a")
|
||||||
|
ds.sources[1].font.newGlyph("b").unicode = ord("b")
|
||||||
|
ds.sources[1].font.features.text = "feature kern { pos a b b' 0; } kern;"
|
||||||
|
|
||||||
|
ds.sources[2].font.newGlyph("a").unicode = ord("a")
|
||||||
|
ds.sources[2].font.newGlyph("b").unicode = ord("b")
|
||||||
|
ds.sources[2].font.features.text = "feature kern { pos a b b' -100; } kern;"
|
||||||
|
|
||||||
|
font = compileVariableTTF(ds, inplace=True)
|
||||||
|
b = BytesIO()
|
||||||
|
font.save(b)
|
||||||
|
|
||||||
|
assert font["GDEF"].table.VarStore.VarData[0].Item[0] == [100, -100]
|
||||||
|
@ -10,6 +10,7 @@ fs==2.4.16
|
|||||||
skia-pathops==0.7.3; platform_python_implementation != "PyPy"
|
skia-pathops==0.7.3; platform_python_implementation != "PyPy"
|
||||||
# this is only required to run Tests/cu2qu/{ufo,cli}_test.py
|
# this is only required to run Tests/cu2qu/{ufo,cli}_test.py
|
||||||
ufoLib2==0.14.0
|
ufoLib2==0.14.0
|
||||||
|
ufo2ft==2.31.0
|
||||||
pyobjc==9.0; sys_platform == "darwin"
|
pyobjc==9.0; sys_platform == "darwin"
|
||||||
freetype-py==2.3.0
|
freetype-py==2.3.0
|
||||||
uharfbuzz==0.32.0
|
uharfbuzz==0.32.0
|
||||||
|
Loading…
x
Reference in New Issue
Block a user