[varStore] Generate variation for Anchors and store in GDEF
Finally! Phew...
This commit is contained in:
parent
cfd7bfbb2c
commit
caa353d5dd
@ -203,6 +203,7 @@ class VarData(BaseTable):
|
||||
numShorts = 0
|
||||
count = len(self.VarRegionIndex)
|
||||
for item in self.Item:
|
||||
assert len(item) == count, ("Item length mismatch", len(item), count)
|
||||
for i in range(count - 1, numShorts - 1, -1):
|
||||
if not (-128 <= item[i] <= 127):
|
||||
numShorts = i + 1
|
||||
|
@ -85,6 +85,8 @@ def _add_fvar(font, axes, instances, axis_map):
|
||||
inst.coordinates = {axis_map[k][0]:v for k,v in coordinates.items()}
|
||||
fvar.instances.append(inst)
|
||||
|
||||
return fvar
|
||||
|
||||
# TODO Move to glyf or gvar table proper
|
||||
def _GetCoordinates(font, glyphName):
|
||||
"""font, glyphName --> glyph coordinates as expected by "gvar" table
|
||||
@ -187,7 +189,7 @@ def _add_gvar(font, model, master_ttfs):
|
||||
var = GlyphVariation(support, delta)
|
||||
gvar.variations[glyph].append(var)
|
||||
|
||||
def _add_HVAR(font, model, master_ttfs, axes):
|
||||
def _add_HVAR(font, model, master_ttfs, axisTags):
|
||||
|
||||
print("Generating HVAR")
|
||||
|
||||
@ -201,7 +203,7 @@ def _add_HVAR(font, model, master_ttfs, axes):
|
||||
# We only support the direct mapping right now.
|
||||
|
||||
supports = model.supports[1:]
|
||||
varTupleList = builder.buildVarRegionList(supports, axes.keys())
|
||||
varTupleList = builder.buildVarRegionList(supports, axisTags)
|
||||
varTupleIndexes = list(range(len(supports)))
|
||||
n = len(supports)
|
||||
items = []
|
||||
@ -249,8 +251,8 @@ def _all_equal(lst):
|
||||
def buildVarDevTable(store_builder, master_values):
|
||||
if _all_equal(master_values):
|
||||
return None
|
||||
deltas = master_values
|
||||
return builder.buildVarDevTable(0xdeadbeef)
|
||||
varIdx = store_builder.storeMasters(master_values)
|
||||
return builder.buildVarDevTable(varIdx)
|
||||
|
||||
class VariationMerger(Merger):
|
||||
|
||||
@ -269,15 +271,13 @@ def merge(merger, self, lst):
|
||||
self.XDeviceTable = XDeviceTable
|
||||
self.YDeviceTable = YDeviceTable
|
||||
|
||||
def _merge_OTL(font, model, master_fonts, axes, base_idx):
|
||||
def _merge_OTL(font, model, master_fonts, axisTags, base_idx):
|
||||
|
||||
print("Merging OpenType Layout tables")
|
||||
|
||||
axisTags = [] # XXX
|
||||
merger = VariationMerger(model, axisTags)
|
||||
|
||||
print("Building variations tables")
|
||||
merge_tables(font, merger, master_fonts, axes, base_idx, ['GPOS'])
|
||||
merge_tables(font, merger, master_fonts, axisTags, base_idx, ['GPOS'])
|
||||
|
||||
store = merger.store_builder.finish()
|
||||
GDEF = font['GDEF'].table
|
||||
@ -354,7 +354,8 @@ def build(designspace_filename, master_finder=lambda s:s, axisMap=None):
|
||||
gx = TTFont(master_ttfs[base_idx])
|
||||
|
||||
# TODO append masters as named-instances as well; needs .designspace change.
|
||||
_add_fvar(gx, axes, instances, axis_map)
|
||||
fvar = _add_fvar(gx, axes, instances, axis_map)
|
||||
|
||||
|
||||
# Normalize master locations
|
||||
master_locs = [models.normalizeLocation(m, axes) for m in master_locs]
|
||||
@ -363,8 +364,11 @@ def build(designspace_filename, master_finder=lambda s:s, axisMap=None):
|
||||
pprint(master_locs)
|
||||
|
||||
# TODO Clean this up.
|
||||
del instances
|
||||
del axes
|
||||
master_locs = [{axis_map[k][0]:v for k,v in loc.items()} for loc in master_locs]
|
||||
#instance_locs = [{axis_map[k][0]:v for k,v in loc.items()} for loc in instance_locs]
|
||||
axisTags = [axis.axisTag for axis in fvar.axes]
|
||||
|
||||
# Assume single-model for now.
|
||||
model = models.VariationModel(master_locs)
|
||||
@ -373,8 +377,8 @@ def build(designspace_filename, master_finder=lambda s:s, axisMap=None):
|
||||
print("Building variations tables")
|
||||
if 'glyf' in gx:
|
||||
_add_gvar(gx, model, master_fonts)
|
||||
_add_HVAR(gx, model, master_fonts, axes)
|
||||
_merge_OTL(gx, model, master_fonts, axes, base_idx)
|
||||
_add_HVAR(gx, model, master_fonts, axisTags)
|
||||
_merge_OTL(gx, model, master_fonts, axisTags, base_idx)
|
||||
|
||||
return gx, model, master_ttfs
|
||||
|
||||
|
@ -10,6 +10,7 @@ def buildVarRegionAxis(axisSupport):
|
||||
return self
|
||||
|
||||
def buildVarRegion(support, axisTags):
|
||||
assert all(tag in axisTags for tag in support.keys()), ("Unknown axis tag found.", support, axisTags)
|
||||
self = ot.VarRegion()
|
||||
self.VarRegionAxis = []
|
||||
for tag in axisTags:
|
||||
@ -23,7 +24,7 @@ def buildVarRegionList(supports, axisTags):
|
||||
self.Region = []
|
||||
for support in supports:
|
||||
self.Region.append(buildVarRegion(support, axisTags))
|
||||
self.VarRegionCount = len(self.Region)
|
||||
self.RegionCount = len(self.Region)
|
||||
return self
|
||||
|
||||
|
||||
@ -81,18 +82,40 @@ def buildVarStore(varRegionList, varDataList):
|
||||
return self
|
||||
|
||||
|
||||
def _getLocationKey(loc):
|
||||
return tuple(sorted(loc.items(), key=lambda kv: kv[0]))
|
||||
|
||||
class OnlineVarStoreBuilder(object):
|
||||
|
||||
def __init__(self, axisTags):
|
||||
self._regions = buildVarRegionList([], axisTags)
|
||||
self._store = buildVarStore(self._regions, [])
|
||||
self._axisTags = axisTags
|
||||
self._regionMap = {}
|
||||
self._regionList = buildVarRegionList([], axisTags)
|
||||
self._store = buildVarStore(self._regionList, [])
|
||||
|
||||
def setModel(self, model):
|
||||
self._model = model
|
||||
# Store model's regions
|
||||
|
||||
regionMap = self._regionMap
|
||||
regionList = self._regionList
|
||||
|
||||
regions = model.supports[1:]
|
||||
regionIndices = []
|
||||
for region in regions:
|
||||
key = _getLocationKey(region)
|
||||
idx = regionMap.get(key)
|
||||
if idx is None:
|
||||
varRegion = buildVarRegion(region, self._axisTags)
|
||||
idx = regionMap[key] = len(regionList.Region)
|
||||
regionList.Region.append(varRegion)
|
||||
regionIndices.append(idx)
|
||||
|
||||
data = self._data = buildVarData(regionIndices, [], optimize=False)
|
||||
self._outer = len(self._store.VarData)
|
||||
self._store.VarData.append(data)
|
||||
|
||||
def finish(self, optimize=True):
|
||||
self._regions.VarRegionCount = len(self._regions.Region)
|
||||
self._regionList.RegionCount = len(self._regionList.Region)
|
||||
self._store.VarDataCount = len(self._store.VarData)
|
||||
for data in self._store.VarData:
|
||||
data.ItemCount = len(data.Item)
|
||||
@ -100,6 +123,14 @@ class OnlineVarStoreBuilder(object):
|
||||
optimizeVarData(data)
|
||||
return self._store
|
||||
|
||||
def storeMasters(self, master_values):
|
||||
deltas = [int(round(d)) for d in self._model.getDeltas(master_values)[1:]]
|
||||
inner = len(self._data.Item)
|
||||
self._data.Item.append(deltas)
|
||||
# TODO Check for full data array?
|
||||
return (self._outer << 16) + inner
|
||||
|
||||
|
||||
|
||||
# Variation helpers
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user