Merge pull request #1583 from anthrotype/partial-instantiate-HVAR
[instancer] support instantiating HVAR and VVAR (TTF only for now)
This commit is contained in:
commit
691547b00b
@ -362,9 +362,9 @@ class table__g_l_y_f(DefaultTable.DefaultTable):
|
||||
"coord" is an array of GlyphCoordinates which must include the four
|
||||
"phantom points".
|
||||
|
||||
Only the horizontal advance and sidebearings in "hmtx" table are updated
|
||||
from the first two phantom points. The last two phantom points for
|
||||
vertical typesetting are currently ignored.
|
||||
Both the horizontal/vertical advances and left/top sidebearings in "hmtx"
|
||||
and "vmtx" tables (if any) are updated from four phantom points and
|
||||
the glyph's bounding boxes.
|
||||
"""
|
||||
# TODO: Create new glyph if not already present
|
||||
assert glyphName in self.glyphs
|
||||
@ -372,8 +372,6 @@ class table__g_l_y_f(DefaultTable.DefaultTable):
|
||||
|
||||
# Handle phantom points for (left, right, top, bottom) positions.
|
||||
assert len(coord) >= 4
|
||||
if not hasattr(glyph, 'xMin'):
|
||||
glyph.recalcBounds(self)
|
||||
leftSideX = coord[-4][0]
|
||||
rightSideX = coord[-3][0]
|
||||
topSideY = coord[-2][1]
|
||||
@ -400,9 +398,15 @@ class table__g_l_y_f(DefaultTable.DefaultTable):
|
||||
# https://github.com/fonttools/fonttools/pull/1198
|
||||
horizontalAdvanceWidth = 0
|
||||
leftSideBearing = otRound(glyph.xMin - leftSideX)
|
||||
# TODO Handle vertical metrics?
|
||||
ttFont["hmtx"].metrics[glyphName] = horizontalAdvanceWidth, leftSideBearing
|
||||
|
||||
if "vmtx" in ttFont:
|
||||
verticalAdvanceWidth = otRound(topSideY - bottomSideY)
|
||||
if verticalAdvanceWidth < 0: # unlikely but do the same as horizontal
|
||||
verticalAdvanceWidth = 0
|
||||
topSideBearing = otRound(topSideY - glyph.yMax)
|
||||
ttFont["vmtx"].metrics[glyphName] = verticalAdvanceWidth, topSideBearing
|
||||
|
||||
|
||||
_GlyphControls = namedtuple(
|
||||
"_GlyphControls", "numberOfContours endPts flags components"
|
||||
|
@ -367,20 +367,20 @@ def _merge_TTHinting(font, masterModel, master_ttfs, tolerance=0.5):
|
||||
var = TupleVariation(support, delta)
|
||||
cvar.variations.append(var)
|
||||
|
||||
MetricsFields = namedtuple('MetricsFields',
|
||||
_MetricsFields = namedtuple('_MetricsFields',
|
||||
['tableTag', 'metricsTag', 'sb1', 'sb2', 'advMapping', 'vOrigMapping'])
|
||||
|
||||
hvarFields = MetricsFields(tableTag='HVAR', metricsTag='hmtx', sb1='LsbMap',
|
||||
HVAR_FIELDS = _MetricsFields(tableTag='HVAR', metricsTag='hmtx', sb1='LsbMap',
|
||||
sb2='RsbMap', advMapping='AdvWidthMap', vOrigMapping=None)
|
||||
|
||||
vvarFields = MetricsFields(tableTag='VVAR', metricsTag='vmtx', sb1='TsbMap',
|
||||
VVAR_FIELDS = _MetricsFields(tableTag='VVAR', metricsTag='vmtx', sb1='TsbMap',
|
||||
sb2='BsbMap', advMapping='AdvHeightMap', vOrigMapping='VOrgMap')
|
||||
|
||||
def _add_HVAR(font, masterModel, master_ttfs, axisTags):
|
||||
_add_VHVAR(font, masterModel, master_ttfs, axisTags, hvarFields)
|
||||
_add_VHVAR(font, masterModel, master_ttfs, axisTags, HVAR_FIELDS)
|
||||
|
||||
def _add_VVAR(font, masterModel, master_ttfs, axisTags):
|
||||
_add_VHVAR(font, masterModel, master_ttfs, axisTags, vvarFields)
|
||||
_add_VHVAR(font, masterModel, master_ttfs, axisTags, VVAR_FIELDS)
|
||||
|
||||
def _add_VHVAR(font, masterModel, master_ttfs, axisTags, tableFields):
|
||||
|
||||
|
@ -17,6 +17,7 @@ from fontTools.varLib.models import supportScalar, normalizeValue, piecewiseLine
|
||||
from fontTools.ttLib import TTFont
|
||||
from fontTools.ttLib.tables.TupleVariation import TupleVariation
|
||||
from fontTools.ttLib.tables._g_l_y_f import GlyphCoordinates
|
||||
from fontTools import varLib
|
||||
from fontTools.varLib import builder
|
||||
from fontTools.varLib.mvar import MVAR_ENTRIES
|
||||
from fontTools.varLib.merger import MutatorMerger
|
||||
@ -82,8 +83,8 @@ def instantiateGvarGlyph(varfont, glyphname, location, optimize=True):
|
||||
|
||||
if defaultDeltas:
|
||||
coordinates += GlyphCoordinates(defaultDeltas)
|
||||
# this will also set the hmtx advance widths and sidebearings from
|
||||
# the fourth-last and third-last phantom points (and glyph.xMin)
|
||||
# this will also set the hmtx/vmtx advance widths and sidebearings from
|
||||
# the four phantom points and glyph bounding boxes
|
||||
glyf.setCoordinates(glyphname, coordinates, varfont)
|
||||
|
||||
if not tupleVarStore:
|
||||
@ -158,24 +159,74 @@ def setMvarDeltas(varfont, deltas):
|
||||
)
|
||||
|
||||
|
||||
def instantiateMvar(varfont, location):
|
||||
def instantiateMVAR(varfont, location):
|
||||
log.info("Instantiating MVAR table")
|
||||
|
||||
mvar = varfont["MVAR"].table
|
||||
fvarAxes = varfont["fvar"].axes
|
||||
defaultDeltas, varIndexMapping = instantiateItemVariationStore(
|
||||
mvar.VarStore, fvarAxes, location
|
||||
)
|
||||
varStore = mvar.VarStore
|
||||
defaultDeltas = instantiateItemVariationStore(varStore, fvarAxes, location)
|
||||
setMvarDeltas(varfont, defaultDeltas)
|
||||
|
||||
if varIndexMapping:
|
||||
if varStore.VarRegionList.Region:
|
||||
varIndexMapping = varStore.optimize()
|
||||
for rec in mvar.ValueRecord:
|
||||
rec.VarIdx = varIndexMapping[rec.VarIdx]
|
||||
else:
|
||||
# Delete table if no more regions left.
|
||||
del varfont["MVAR"]
|
||||
|
||||
|
||||
def _remapVarIdxMap(table, attrName, varIndexMapping, glyphOrder):
|
||||
oldMapping = getattr(table, attrName).mapping
|
||||
newMapping = [varIndexMapping[oldMapping[glyphName]] for glyphName in glyphOrder]
|
||||
setattr(table, attrName, builder.buildVarIdxMap(newMapping, glyphOrder))
|
||||
|
||||
|
||||
# TODO(anthrotype) Add support for HVAR/VVAR in CFF2
|
||||
def _instantiateVHVAR(varfont, location, tableFields):
|
||||
tableTag = tableFields.tableTag
|
||||
fvarAxes = varfont["fvar"].axes
|
||||
# Deltas from gvar table have already been applied to the hmtx/vmtx. For full
|
||||
# instances (i.e. all axes pinned), we can simply drop HVAR/VVAR and return
|
||||
if set(location).issuperset(axis.axisTag for axis in fvarAxes):
|
||||
log.info("Dropping %s table", tableTag)
|
||||
del varfont[tableTag]
|
||||
return
|
||||
|
||||
log.info("Instantiating %s table", tableTag)
|
||||
vhvar = varfont[tableTag].table
|
||||
varStore = vhvar.VarStore
|
||||
# since deltas were already applied, the return value here is ignored
|
||||
instantiateItemVariationStore(varStore, fvarAxes, location)
|
||||
|
||||
if varStore.VarRegionList.Region:
|
||||
# Only re-optimize VarStore if the HVAR/VVAR already uses indirect AdvWidthMap
|
||||
# or AdvHeightMap. If a direct, implicit glyphID->VariationIndex mapping is
|
||||
# used for advances, skip re-optimizing and maintain original VariationIndex.
|
||||
if getattr(vhvar, tableFields.advMapping):
|
||||
varIndexMapping = varStore.optimize()
|
||||
glyphOrder = varfont.getGlyphOrder()
|
||||
_remapVarIdxMap(vhvar, tableFields.advMapping, varIndexMapping, glyphOrder)
|
||||
if getattr(vhvar, tableFields.sb1): # left or top sidebearings
|
||||
_remapVarIdxMap(vhvar, tableFields.sb1, varIndexMapping, glyphOrder)
|
||||
if getattr(vhvar, tableFields.sb2): # right or bottom sidebearings
|
||||
_remapVarIdxMap(vhvar, tableFields.sb2, varIndexMapping, glyphOrder)
|
||||
if tableTag == "VVAR" and getattr(vhvar, tableFields.vOrigMapping):
|
||||
_remapVarIdxMap(
|
||||
vhvar, tableFields.vOrigMapping, varIndexMapping, glyphOrder
|
||||
)
|
||||
else:
|
||||
del varfont[tableTag]
|
||||
|
||||
|
||||
def instantiateHVAR(varfont, location):
|
||||
return _instantiateVHVAR(varfont, location, varLib.HVAR_FIELDS)
|
||||
|
||||
|
||||
def instantiateVVAR(varfont, location):
|
||||
return _instantiateVHVAR(varfont, location, varLib.VVAR_FIELDS)
|
||||
|
||||
|
||||
class _TupleVarStoreAdapter(object):
|
||||
def __init__(self, regions, axisOrder, tupleVarData, itemCounts):
|
||||
self.regions = regions
|
||||
@ -249,6 +300,8 @@ class _TupleVarStoreAdapter(object):
|
||||
)
|
||||
regionList = builder.buildVarRegionList(self.regions, self.axisOrder)
|
||||
itemVarStore = builder.buildVarStore(regionList, varDatas)
|
||||
# remove unused regions from VarRegionList
|
||||
itemVarStore.prune_regions()
|
||||
return itemVarStore
|
||||
|
||||
|
||||
@ -258,6 +311,10 @@ def instantiateItemVariationStore(itemVarStore, fvarAxes, location):
|
||||
Remove regions in which all axes were instanced, and scale the deltas of
|
||||
the remaining regions where only some of the axes were instanced.
|
||||
|
||||
The number of VarData subtables, and the number of items within each, are
|
||||
not modified, in order to keep the existing VariationIndex valid.
|
||||
One may call VarStore.optimize() method after this to further optimize those.
|
||||
|
||||
Args:
|
||||
varStore: An otTables.VarStore object (Item Variation Store)
|
||||
fvarAxes: list of fvar's Axis objects
|
||||
@ -267,8 +324,6 @@ def instantiateItemVariationStore(itemVarStore, fvarAxes, location):
|
||||
Returns:
|
||||
defaultDeltas: to be added to the default instance, of type dict of ints keyed
|
||||
by VariationIndex compound values: i.e. (outer << 16) + inner.
|
||||
varIndexMapping: a mapping from old to new VarIdx after optimization (None if
|
||||
varStore was fully instanced thus left empty).
|
||||
"""
|
||||
tupleVarStore = _TupleVarStoreAdapter.fromItemVarStore(itemVarStore, fvarAxes)
|
||||
defaultDeltaArray = tupleVarStore.instantiate(location)
|
||||
@ -278,18 +333,12 @@ def instantiateItemVariationStore(itemVarStore, fvarAxes, location):
|
||||
assert itemVarStore.VarDataCount == newItemVarStore.VarDataCount
|
||||
itemVarStore.VarData = newItemVarStore.VarData
|
||||
|
||||
if itemVarStore.VarRegionList.Region:
|
||||
# optimize VarStore, and get a map from old to new VarIdx after optimization
|
||||
varIndexMapping = itemVarStore.optimize()
|
||||
else:
|
||||
varIndexMapping = None # VarStore is empty
|
||||
|
||||
defaultDeltas = {
|
||||
((major << 16) + minor): delta
|
||||
for major, deltas in enumerate(defaultDeltaArray)
|
||||
for minor, delta in enumerate(deltas)
|
||||
}
|
||||
return defaultDeltas, varIndexMapping
|
||||
return defaultDeltas
|
||||
|
||||
|
||||
def instantiateOTL(varfont, location):
|
||||
@ -305,11 +354,10 @@ def instantiateOTL(varfont, location):
|
||||
log.info(msg)
|
||||
|
||||
gdef = varfont["GDEF"].table
|
||||
varStore = gdef.VarStore
|
||||
fvarAxes = varfont["fvar"].axes
|
||||
|
||||
defaultDeltas, varIndexMapping = instantiateItemVariationStore(
|
||||
gdef.VarStore, fvarAxes, location
|
||||
)
|
||||
defaultDeltas = instantiateItemVariationStore(varStore, fvarAxes, location)
|
||||
|
||||
# When VF are built, big lookups may overflow and be broken into multiple
|
||||
# subtables. MutatorMerger (which inherits from AligningMerger) reattaches
|
||||
@ -321,11 +369,12 @@ def instantiateOTL(varfont, location):
|
||||
# LigatureCarets, and optionally deletes all VariationIndex tables if the
|
||||
# VarStore is fully instanced.
|
||||
merger = MutatorMerger(
|
||||
varfont, defaultDeltas, deleteVariations=(varIndexMapping is None)
|
||||
varfont, defaultDeltas, deleteVariations=(not varStore.VarRegionList.Region)
|
||||
)
|
||||
merger.mergeTables(varfont, [varfont], ["GDEF", "GPOS"])
|
||||
|
||||
if varIndexMapping:
|
||||
if varStore.VarRegionList.Region:
|
||||
varIndexMapping = varStore.optimize()
|
||||
gdef.remap_device_varidxes(varIndexMapping)
|
||||
if "GPOS" in varfont:
|
||||
varfont["GPOS"].table.remap_device_varidxes(varIndexMapping)
|
||||
@ -439,6 +488,9 @@ def sanityCheckVariableTables(varfont):
|
||||
if "gvar" in varfont:
|
||||
if "glyf" not in varfont:
|
||||
raise ValueError("Can't have gvar without glyf")
|
||||
# TODO(anthrotype) Remove once we do support partial instancing CFF2
|
||||
if "CFF2" in varfont:
|
||||
raise NotImplementedError("Instancing CFF2 variable fonts is not supported yet")
|
||||
|
||||
|
||||
def instantiateVariableFont(varfont, axis_limits, inplace=False, optimize=True):
|
||||
@ -461,15 +513,18 @@ def instantiateVariableFont(varfont, axis_limits, inplace=False, optimize=True):
|
||||
instantiateCvar(varfont, axis_limits)
|
||||
|
||||
if "MVAR" in varfont:
|
||||
instantiateMvar(varfont, axis_limits)
|
||||
instantiateMVAR(varfont, axis_limits)
|
||||
|
||||
if "HVAR" in varfont:
|
||||
instantiateHVAR(varfont, axis_limits)
|
||||
|
||||
if "VVAR" in varfont:
|
||||
instantiateVVAR(varfont, axis_limits)
|
||||
|
||||
instantiateOTL(varfont, axis_limits)
|
||||
|
||||
instantiateFeatureVariations(varfont, axis_limits)
|
||||
|
||||
# TODO: actually process HVAR instead of dropping it
|
||||
del varfont["HVAR"]
|
||||
|
||||
return varfont
|
||||
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ttFont sfntVersion="\x00\x01\x00\x00" ttLibVersion="3.39">
|
||||
<ttFont sfntVersion="\x00\x01\x00\x00" ttLibVersion="3.40">
|
||||
|
||||
<GlyphOrder>
|
||||
<!-- The 'id' attribute is only for humans; it is ignored when parsed. -->
|
||||
@ -12,12 +12,12 @@
|
||||
<!-- Most of this table will be recalculated by the compiler -->
|
||||
<tableVersion value="1.0"/>
|
||||
<fontRevision value="2.001"/>
|
||||
<checkSumAdjustment value="0x45c905be"/>
|
||||
<checkSumAdjustment value="0x9180a393"/>
|
||||
<magicNumber value="0x5f0f3cf5"/>
|
||||
<flags value="00000000 00000011"/>
|
||||
<unitsPerEm value="1000"/>
|
||||
<created value="Tue Mar 5 00:05:14 2019"/>
|
||||
<modified value="Mon Mar 25 12:51:29 2019"/>
|
||||
<modified value="Sat Apr 20 17:03:24 2019"/>
|
||||
<xMin value="40"/>
|
||||
<yMin value="-200"/>
|
||||
<xMax value="450"/>
|
||||
@ -570,7 +570,7 @@
|
||||
</VarRegionList>
|
||||
<!-- VarDataCount=1 -->
|
||||
<VarData index="0">
|
||||
<!-- ItemCount=3 -->
|
||||
<!-- ItemCount=2 -->
|
||||
<NumShorts value="0"/>
|
||||
<!-- VarRegionCount=5 -->
|
||||
<VarRegionIndex index="0" value="2"/>
|
||||
@ -578,18 +578,22 @@
|
||||
<VarRegionIndex index="2" value="4"/>
|
||||
<VarRegionIndex index="3" value="5"/>
|
||||
<VarRegionIndex index="4" value="6"/>
|
||||
<Item index="0" value="[0, 0, 0, 0, 0]"/>
|
||||
<Item index="1" value="[-4, -48, -11, 31, 55]"/>
|
||||
<Item index="2" value="[0, 0, 0, 0, 0]"/>
|
||||
<Item index="0" value="[-4, -48, -11, 31, 55]"/>
|
||||
<Item index="1" value="[0, 0, 0, 0, 0]"/>
|
||||
</VarData>
|
||||
</VarStore>
|
||||
<AdvWidthMap>
|
||||
<Map glyph=".notdef" outer="0" inner="1"/>
|
||||
<Map glyph="hyphen" outer="0" inner="0"/>
|
||||
<Map glyph="space" outer="0" inner="1"/>
|
||||
</AdvWidthMap>
|
||||
</HVAR>
|
||||
|
||||
<MVAR>
|
||||
<Version value="0x00010000"/>
|
||||
<Reserved value="0"/>
|
||||
<ValueRecordSize value="8"/>
|
||||
<!-- ValueRecordCount=3 -->
|
||||
<!-- ValueRecordCount=4 -->
|
||||
<VarStore Format="1">
|
||||
<Format value="1"/>
|
||||
<VarRegionList>
|
||||
@ -632,7 +636,7 @@
|
||||
</VarRegionAxis>
|
||||
</Region>
|
||||
</VarRegionList>
|
||||
<!-- VarDataCount=1 -->
|
||||
<!-- VarDataCount=2 -->
|
||||
<VarData index="0">
|
||||
<!-- ItemCount=3 -->
|
||||
<NumShorts value="1"/>
|
||||
@ -644,7 +648,7 @@
|
||||
<Item index="1" value="[100, 0, -20]"/>
|
||||
<Item index="2" value="[50, -30, -20]"/>
|
||||
</VarData>
|
||||
<VarData>
|
||||
<VarData index="1">
|
||||
<!-- ItemCount=1 -->
|
||||
<NumShorts value="0"/>
|
||||
<!-- VarRegionCount=1 -->
|
||||
@ -1016,4 +1020,10 @@
|
||||
</glyphVariations>
|
||||
</gvar>
|
||||
|
||||
<vmtx>
|
||||
<mtx name=".notdef" height="1000" tsb="100"/>
|
||||
<mtx name="hyphen" height="536" tsb="229"/>
|
||||
<mtx name="space" height="600" tsb="0"/>
|
||||
</vmtx>
|
||||
|
||||
</ttFont>
|
||||
|
@ -67,7 +67,7 @@ class InstantiateGvarTest(object):
|
||||
(247, 229),
|
||||
(0, 0),
|
||||
(274, 0),
|
||||
(0, 1000),
|
||||
(0, 536),
|
||||
(0, 0),
|
||||
]
|
||||
},
|
||||
@ -83,7 +83,7 @@ class InstantiateGvarTest(object):
|
||||
(265, 229),
|
||||
(0, 0),
|
||||
(298, 0),
|
||||
(0, 1000),
|
||||
(0, 536),
|
||||
(0, 0),
|
||||
]
|
||||
},
|
||||
@ -101,7 +101,7 @@ class InstantiateGvarTest(object):
|
||||
(282, 229),
|
||||
(0, 0),
|
||||
(322, 0),
|
||||
(0, 1000),
|
||||
(0, 536),
|
||||
(0, 0),
|
||||
]
|
||||
},
|
||||
@ -133,7 +133,7 @@ class InstantiateGvarTest(object):
|
||||
(265, 229),
|
||||
(0, 0),
|
||||
(298, 0),
|
||||
(0, 1000),
|
||||
(0, 536),
|
||||
(0, 0),
|
||||
]
|
||||
|
||||
@ -169,7 +169,7 @@ class InstantiateCvarTest(object):
|
||||
assert "cvar" not in varfont
|
||||
|
||||
|
||||
class InstantiateMvarTest(object):
|
||||
class InstantiateMVARTest(object):
|
||||
@pytest.mark.parametrize(
|
||||
"location, expected",
|
||||
[
|
||||
@ -217,7 +217,7 @@ class InstantiateMvarTest(object):
|
||||
assert mvar.VarStore.VarData[1].VarRegionCount == 1
|
||||
assert all(len(item) == 1 for item in mvar.VarStore.VarData[1].Item)
|
||||
|
||||
instancer.instantiateMvar(varfont, location)
|
||||
instancer.instantiateMVAR(varfont, location)
|
||||
|
||||
for mvar_tag, expected_value in expected.items():
|
||||
table_tag, item_name = MVAR_ENTRIES[mvar_tag]
|
||||
@ -268,7 +268,7 @@ class InstantiateMvarTest(object):
|
||||
],
|
||||
)
|
||||
def test_full_instance(self, varfont, location, expected):
|
||||
instancer.instantiateMvar(varfont, location)
|
||||
instancer.instantiateMVAR(varfont, location)
|
||||
|
||||
for mvar_tag, expected_value in expected.items():
|
||||
table_tag, item_name = MVAR_ENTRIES[mvar_tag]
|
||||
@ -277,6 +277,62 @@ class InstantiateMvarTest(object):
|
||||
assert "MVAR" not in varfont
|
||||
|
||||
|
||||
class InstantiateHVARTest(object):
|
||||
# the 'expectedDeltas' below refer to the VarData item deltas for the "hyphen"
|
||||
# glyph in the PartialInstancerTest-VF.ttx test font, that are left after
|
||||
# partial instancing
|
||||
@pytest.mark.parametrize(
|
||||
"location, expectedRegions, expectedDeltas",
|
||||
[
|
||||
({"wght": -1.0}, [{"wdth": (-1.0, -1.0, 0)}], [-59]),
|
||||
({"wght": 0}, [{"wdth": (-1.0, -1.0, 0)}], [-48]),
|
||||
({"wght": 1.0}, [{"wdth": (-1.0, -1.0, 0)}], [7]),
|
||||
(
|
||||
{"wdth": -1.0},
|
||||
[
|
||||
{"wght": (-1.0, -1.0, 0.0)},
|
||||
{"wght": (0.0, 0.61, 1.0)},
|
||||
{"wght": (0.61, 1.0, 1.0)},
|
||||
],
|
||||
[-11, 31, 51],
|
||||
),
|
||||
({"wdth": 0}, [{"wght": (0.61, 1.0, 1.0)}], [-4]),
|
||||
],
|
||||
)
|
||||
def test_partial_instance(
|
||||
self, varfont, fvarAxes, location, expectedRegions, expectedDeltas
|
||||
):
|
||||
instancer.instantiateHVAR(varfont, location)
|
||||
|
||||
assert "HVAR" in varfont
|
||||
hvar = varfont["HVAR"].table
|
||||
varStore = hvar.VarStore
|
||||
|
||||
regions = varStore.VarRegionList.Region
|
||||
assert [reg.get_support(fvarAxes) for reg in regions] == expectedRegions
|
||||
|
||||
assert len(varStore.VarData) == 1
|
||||
assert varStore.VarData[0].ItemCount == 2
|
||||
|
||||
assert hvar.AdvWidthMap is not None
|
||||
advWithMap = hvar.AdvWidthMap.mapping
|
||||
|
||||
assert advWithMap[".notdef"] == advWithMap["space"]
|
||||
varIdx = advWithMap[".notdef"]
|
||||
# these glyphs have no metrics variations in the test font
|
||||
assert varStore.VarData[varIdx >> 16].Item[varIdx & 0xFFFF] == (
|
||||
[0] * varStore.VarData[0].VarRegionCount
|
||||
)
|
||||
|
||||
varIdx = advWithMap["hyphen"]
|
||||
assert varStore.VarData[varIdx >> 16].Item[varIdx & 0xFFFF] == expectedDeltas
|
||||
|
||||
def test_full_instance(self, varfont):
|
||||
instancer.instantiateHVAR(varfont, {"wght": 0, "wdth": 0})
|
||||
|
||||
assert "HVAR" not in varfont
|
||||
|
||||
|
||||
class InstantiateItemVariationStoreTest(object):
|
||||
def test_VarRegion_get_support(self):
|
||||
axisOrder = ["wght", "wdth", "opsz"]
|
||||
@ -328,7 +384,7 @@ class InstantiateItemVariationStoreTest(object):
|
||||
def test_instantiate_default_deltas(
|
||||
self, varStore, fvarAxes, location, expected_deltas, num_regions
|
||||
):
|
||||
defaultDeltas, _ = instancer.instantiateItemVariationStore(
|
||||
defaultDeltas = instancer.instantiateItemVariationStore(
|
||||
varStore, fvarAxes, location
|
||||
)
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user