예제 #1
0
 def __init__(self, axisTags):
     self._axisTags = axisTags
     self._regionMap = {}
     self._regionList = buildVarRegionList([], axisTags)
     self._store = buildVarStore(self._regionList, [])
     self._data = None
     self._model = None
     self._cache = {}
예제 #2
0
	def __init__(self, axisTags):
		self._axisTags = axisTags
		self._regionMap = {}
		self._regionList = buildVarRegionList([], axisTags)
		self._store = buildVarStore(self._regionList, [])
		self._data = None
		self._model = None
		self._cache = {}
예제 #3
0
def _add_HVAR(font, model, master_ttfs, axisTags):

    print("Generating HVAR")

    hAdvanceDeltas = {}
    metricses = [m["hmtx"].metrics for m in master_ttfs]
    for glyph in font.getGlyphOrder():
        hAdvances = [metrics[glyph][0] for metrics in metricses]
        # TODO move round somewhere else?
        hAdvanceDeltas[glyph] = tuple(
            round(d) for d in model.getDeltas(hAdvances)[1:])

    # We only support the direct mapping right now.

    supports = model.supports[1:]
    varTupleList = builder.buildVarRegionList(supports, axisTags)
    varTupleIndexes = list(range(len(supports)))
    n = len(supports)
    items = []
    zeroes = [0] * n
    for glyphName in font.getGlyphOrder():
        items.append(hAdvanceDeltas.get(glyphName, zeroes))
    while items and items[-1] is zeroes:
        del items[-1]

    advanceMapping = None
    # Add indirect mapping to save on duplicates
    uniq = set(items)
    # TODO Improve heuristic
    if (len(items) - len(uniq)) * len(varTupleIndexes) > len(items):
        newItems = sorted(uniq)
        mapper = {v: i for i, v in enumerate(newItems)}
        mapping = [mapper[item] for item in items]
        while len(mapping) > 1 and mapping[-1] == mapping[-2]:
            del mapping[-1]
        advanceMapping = builder.buildVarIdxMap(mapping)
        items = newItems
        del mapper, mapping, newItems
    del uniq

    varData = builder.buildVarData(varTupleIndexes, items)
    varStore = builder.buildVarStore(varTupleList, [varData])

    assert "HVAR" not in font
    HVAR = font["HVAR"] = newTable('HVAR')
    hvar = HVAR.table = ot.HVAR()
    hvar.Version = 0x00010000
    hvar.VarStore = varStore
    hvar.AdvWidthMap = advanceMapping
    hvar.LsbMap = hvar.RsbMap = None
예제 #4
0
def _add_HVAR(font, model, master_ttfs, axisTags):

	log.info("Generating HVAR")

	hAdvanceDeltas = {}
	metricses = [m["hmtx"].metrics for m in master_ttfs]
	for glyph in font.getGlyphOrder():
		hAdvances = [metrics[glyph][0] for metrics in metricses]
		# TODO move round somewhere else?
		hAdvanceDeltas[glyph] = tuple(round(d) for d in model.getDeltas(hAdvances)[1:])

	# We only support the direct mapping right now.

	supports = model.supports[1:]
	varTupleList = builder.buildVarRegionList(supports, axisTags)
	varTupleIndexes = list(range(len(supports)))
	n = len(supports)
	items = []
	zeroes = [0]*n
	for glyphName in font.getGlyphOrder():
		items.append(hAdvanceDeltas.get(glyphName, zeroes))
	while items and items[-1] is zeroes:
		del items[-1]

	advanceMapping = None
	# Add indirect mapping to save on duplicates
	uniq = set(items)
	# TODO Improve heuristic
	if (len(items) - len(uniq)) * len(varTupleIndexes) > len(items):
		newItems = sorted(uniq)
		mapper = {v:i for i,v in enumerate(newItems)}
		mapping = [mapper[item] for item in items]
		while len(mapping) > 1 and mapping[-1] == mapping[-2]:
			del mapping[-1]
		advanceMapping = builder.buildVarIdxMap(mapping)
		items = newItems
		del mapper, mapping, newItems
	del uniq

	varData = builder.buildVarData(varTupleIndexes, items)
	varStore = builder.buildVarStore(varTupleList, [varData])

	assert "HVAR" not in font
	HVAR = font["HVAR"] = newTable('HVAR')
	hvar = HVAR.table = ot.HVAR()
	hvar.Version = 0x00010000
	hvar.VarStore = varStore
	hvar.AdvWidthMap = advanceMapping
	hvar.LsbMap = hvar.RsbMap = None
예제 #5
0
 def asItemVarStore(self):
     regionOrder = [frozenset(axes.items()) for axes in self.regions]
     varDatas = []
     for variations, itemCount in zip(self.tupleVarData, self.itemCounts):
         if variations:
             assert len(variations[0].coordinates) == itemCount
             varRegionIndices = [
                 regionOrder.index(frozenset(var.axes.items())) for var in variations
             ]
             varDataItems = list(zip(*(var.coordinates for var in variations)))
             varDatas.append(
                 builder.buildVarData(varRegionIndices, varDataItems, optimize=False)
             )
         else:
             varDatas.append(
                 builder.buildVarData([], [[] for _ in range(itemCount)])
             )
     regionList = builder.buildVarRegionList(self.regions, self.axisOrder)
     itemVarStore = builder.buildVarStore(regionList, varDatas)
     # remove unused regions from VarRegionList
     itemVarStore.prune_regions()
     return itemVarStore
예제 #6
0
def _get_advance_metrics(font,
                         masterModel,
                         master_ttfs,
                         axisTags,
                         glyphOrder,
                         advMetricses,
                         vOrigMetricses=None):

    vhAdvanceDeltasAndSupports = {}
    vOrigDeltasAndSupports = {}
    for glyph in glyphOrder:
        vhAdvances = [
            metrics[glyph][0] if glyph in metrics else None
            for metrics in advMetricses
        ]
        vhAdvanceDeltasAndSupports[glyph] = masterModel.getDeltasAndSupports(
            vhAdvances, round=round)

    singleModel = models.allEqual(
        id(v[1]) for v in vhAdvanceDeltasAndSupports.values())

    if vOrigMetricses:
        singleModel = False
        for glyph in glyphOrder:
            # We need to supply a vOrigs tuple with non-None default values
            # for each glyph. vOrigMetricses contains values only for those
            # glyphs which have a non-default vOrig.
            vOrigs = [
                metrics[glyph] if glyph in metrics else defaultVOrig
                for metrics, defaultVOrig in vOrigMetricses
            ]
            vOrigDeltasAndSupports[glyph] = masterModel.getDeltasAndSupports(
                vOrigs, round=round)

    directStore = None
    if singleModel:
        # Build direct mapping
        supports = next(iter(vhAdvanceDeltasAndSupports.values()))[1][1:]
        varTupleList = builder.buildVarRegionList(supports, axisTags)
        varTupleIndexes = list(range(len(supports)))
        varData = builder.buildVarData(varTupleIndexes, [], optimize=False)
        for glyphName in glyphOrder:
            varData.addItem(vhAdvanceDeltasAndSupports[glyphName][0],
                            round=noRound)
        varData.optimize()
        directStore = builder.buildVarStore(varTupleList, [varData])

    # Build optimized indirect mapping
    storeBuilder = varStore.OnlineVarStoreBuilder(axisTags)
    advMapping = {}
    for glyphName in glyphOrder:
        deltas, supports = vhAdvanceDeltasAndSupports[glyphName]
        storeBuilder.setSupports(supports)
        advMapping[glyphName] = storeBuilder.storeDeltas(deltas, round=noRound)

    if vOrigMetricses:
        vOrigMap = {}
        for glyphName in glyphOrder:
            deltas, supports = vOrigDeltasAndSupports[glyphName]
            storeBuilder.setSupports(supports)
            vOrigMap[glyphName] = storeBuilder.storeDeltas(deltas,
                                                           round=noRound)

    indirectStore = storeBuilder.finish()
    mapping2 = indirectStore.optimize()
    advMapping = [mapping2[advMapping[g]] for g in glyphOrder]
    advanceMapping = builder.buildVarIdxMap(advMapping, glyphOrder)

    if vOrigMetricses:
        vOrigMap = [mapping2[vOrigMap[g]] for g in glyphOrder]

    useDirect = False
    vOrigMapping = None
    if directStore:
        # Compile both, see which is more compact

        writer = OTTableWriter()
        directStore.compile(writer, font)
        directSize = len(writer.getAllData())

        writer = OTTableWriter()
        indirectStore.compile(writer, font)
        advanceMapping.compile(writer, font)
        indirectSize = len(writer.getAllData())

        useDirect = directSize < indirectSize

    if useDirect:
        metricsStore = directStore
        advanceMapping = None
    else:
        metricsStore = indirectStore
        if vOrigMetricses:
            vOrigMapping = builder.buildVarIdxMap(vOrigMap, glyphOrder)

    return metricsStore, advanceMapping, vOrigMapping
예제 #7
0
def _add_HVAR(font, masterModel, master_ttfs, axisTags):

    log.info("Generating HVAR")

    glyphOrder = font.getGlyphOrder()

    hAdvanceDeltasAndSupports = {}
    metricses = [m["hmtx"].metrics for m in master_ttfs]
    for glyph in glyphOrder:
        hAdvances = [
            metrics[glyph][0] if glyph in metrics else None
            for metrics in metricses
        ]
        hAdvanceDeltasAndSupports[glyph] = masterModel.getDeltasAndSupports(
            hAdvances)

    singleModel = models.allEqual(
        id(v[1]) for v in hAdvanceDeltasAndSupports.values())

    directStore = None
    if singleModel:
        # Build direct mapping

        supports = next(iter(hAdvanceDeltasAndSupports.values()))[1][1:]
        varTupleList = builder.buildVarRegionList(supports, axisTags)
        varTupleIndexes = list(range(len(supports)))
        varData = builder.buildVarData(varTupleIndexes, [], optimize=False)
        for glyphName in glyphOrder:
            varData.addItem(hAdvanceDeltasAndSupports[glyphName][0])
        varData.optimize()
        directStore = builder.buildVarStore(varTupleList, [varData])

    # Build optimized indirect mapping
    storeBuilder = varStore.OnlineVarStoreBuilder(axisTags)
    mapping = {}
    for glyphName in glyphOrder:
        deltas, supports = hAdvanceDeltasAndSupports[glyphName]
        storeBuilder.setSupports(supports)
        mapping[glyphName] = storeBuilder.storeDeltas(deltas)
    indirectStore = storeBuilder.finish()
    mapping2 = indirectStore.optimize()
    mapping = [mapping2[mapping[g]] for g in glyphOrder]
    advanceMapping = builder.buildVarIdxMap(mapping, glyphOrder)

    use_direct = False
    if directStore:
        # Compile both, see which is more compact

        writer = OTTableWriter()
        directStore.compile(writer, font)
        directSize = len(writer.getAllData())

        writer = OTTableWriter()
        indirectStore.compile(writer, font)
        advanceMapping.compile(writer, font)
        indirectSize = len(writer.getAllData())

        use_direct = directSize < indirectSize

    # Done; put it all together.
    assert "HVAR" not in font
    HVAR = font["HVAR"] = newTable('HVAR')
    hvar = HVAR.table = ot.HVAR()
    hvar.Version = 0x00010000
    hvar.LsbMap = hvar.RsbMap = None
    if use_direct:
        hvar.VarStore = directStore
        hvar.AdvWidthMap = None
    else:
        hvar.VarStore = indirectStore
        hvar.AdvWidthMap = advanceMapping
예제 #8
0
def _add_HVAR(font, model, master_ttfs, axisTags):

    log.info("Generating HVAR")

    hAdvanceDeltas = {}
    metricses = [m["hmtx"].metrics for m in master_ttfs]
    for glyph in font.getGlyphOrder():
        hAdvances = [metrics[glyph][0] for metrics in metricses]
        # TODO move round somewhere else?
        hAdvanceDeltas[glyph] = tuple(
            round(d) for d in model.getDeltas(hAdvances)[1:])

    # Direct mapping
    supports = model.supports[1:]
    varTupleList = builder.buildVarRegionList(supports, axisTags)
    varTupleIndexes = list(range(len(supports)))
    n = len(supports)
    items = []
    for glyphName in font.getGlyphOrder():
        items.append(hAdvanceDeltas[glyphName])

    # Build indirect mapping to save on duplicates, compare both sizes
    uniq = list(set(items))
    mapper = {v: i for i, v in enumerate(uniq)}
    mapping = [mapper[item] for item in items]
    advanceMapping = builder.buildVarIdxMap(mapping, font.getGlyphOrder())

    # Direct
    varData = builder.buildVarData(varTupleIndexes, items)
    directStore = builder.buildVarStore(varTupleList, [varData])

    # Indirect
    varData = builder.buildVarData(varTupleIndexes, uniq)
    indirectStore = builder.buildVarStore(varTupleList, [varData])
    mapping = indirectStore.optimize()
    advanceMapping.mapping = {
        k: mapping[v]
        for k, v in advanceMapping.mapping.items()
    }

    # Compile both, see which is more compact

    writer = OTTableWriter()
    directStore.compile(writer, font)
    directSize = len(writer.getAllData())

    writer = OTTableWriter()
    indirectStore.compile(writer, font)
    advanceMapping.compile(writer, font)
    indirectSize = len(writer.getAllData())

    use_direct = directSize < indirectSize

    # Done; put it all together.
    assert "HVAR" not in font
    HVAR = font["HVAR"] = newTable('HVAR')
    hvar = HVAR.table = ot.HVAR()
    hvar.Version = 0x00010000
    hvar.LsbMap = hvar.RsbMap = None
    if use_direct:
        hvar.VarStore = directStore
        hvar.AdvWidthMap = None
    else:
        hvar.VarStore = indirectStore
        hvar.AdvWidthMap = advanceMapping
예제 #9
0
def _add_HVAR(font, model, master_ttfs, axisTags):

	log.info("Generating HVAR")

	hAdvanceDeltas = {}
	metricses = [m["hmtx"].metrics for m in master_ttfs]
	for glyph in font.getGlyphOrder():
		hAdvances = [metrics[glyph][0] for metrics in metricses]
		# TODO move round somewhere else?
		hAdvanceDeltas[glyph] = tuple(otRound(d) for d in model.getDeltas(hAdvances)[1:])

	# Direct mapping
	supports = model.supports[1:]
	varTupleList = builder.buildVarRegionList(supports, axisTags)
	varTupleIndexes = list(range(len(supports)))
	n = len(supports)
	items = []
	for glyphName in font.getGlyphOrder():
		items.append(hAdvanceDeltas[glyphName])

	# Build indirect mapping to save on duplicates, compare both sizes
	uniq = list(set(items))
	mapper = {v:i for i,v in enumerate(uniq)}
	mapping = [mapper[item] for item in items]
	advanceMapping = builder.buildVarIdxMap(mapping, font.getGlyphOrder())

	# Direct
	varData = builder.buildVarData(varTupleIndexes, items)
	directStore = builder.buildVarStore(varTupleList, [varData])

	# Indirect
	varData = builder.buildVarData(varTupleIndexes, uniq)
	indirectStore = builder.buildVarStore(varTupleList, [varData])
	mapping = indirectStore.optimize()
	advanceMapping.mapping = {k:mapping[v] for k,v in advanceMapping.mapping.items()}

	# Compile both, see which is more compact

	writer = OTTableWriter()
	directStore.compile(writer, font)
	directSize = len(writer.getAllData())

	writer = OTTableWriter()
	indirectStore.compile(writer, font)
	advanceMapping.compile(writer, font)
	indirectSize = len(writer.getAllData())

	use_direct = directSize < indirectSize

	# Done; put it all together.
	assert "HVAR" not in font
	HVAR = font["HVAR"] = newTable('HVAR')
	hvar = HVAR.table = ot.HVAR()
	hvar.Version = 0x00010000
	hvar.LsbMap = hvar.RsbMap = None
	if use_direct:
		hvar.VarStore = directStore
		hvar.AdvWidthMap = None
	else:
		hvar.VarStore = indirectStore
		hvar.AdvWidthMap = advanceMapping
예제 #10
0
def _add_HVAR(font, masterModel, master_ttfs, axisTags):

	log.info("Generating HVAR")

	glyphOrder = font.getGlyphOrder()

	hAdvanceDeltasAndSupports = {}
	metricses = [m["hmtx"].metrics for m in master_ttfs]
	for glyph in glyphOrder:
		hAdvances = [metrics[glyph][0] if glyph in metrics else None for metrics in metricses]
		hAdvanceDeltasAndSupports[glyph] = masterModel.getDeltasAndSupports(hAdvances)

	singleModel = models.allEqual(id(v[1]) for v in hAdvanceDeltasAndSupports.values())

	directStore = None
	if singleModel:
		# Build direct mapping

		supports = next(iter(hAdvanceDeltasAndSupports.values()))[1][1:]
		varTupleList = builder.buildVarRegionList(supports, axisTags)
		varTupleIndexes = list(range(len(supports)))
		varData = builder.buildVarData(varTupleIndexes, [], optimize=False)
		for glyphName in glyphOrder:
			varData.addItem(hAdvanceDeltasAndSupports[glyphName][0])
		varData.optimize()
		directStore = builder.buildVarStore(varTupleList, [varData])

	# Build optimized indirect mapping
	storeBuilder = varStore.OnlineVarStoreBuilder(axisTags)
	mapping = {}
	for glyphName in glyphOrder:
		deltas,supports = hAdvanceDeltasAndSupports[glyphName]
		storeBuilder.setSupports(supports)
		mapping[glyphName] = storeBuilder.storeDeltas(deltas)
	indirectStore = storeBuilder.finish()
	mapping2 = indirectStore.optimize()
	mapping = [mapping2[mapping[g]] for g in glyphOrder]
	advanceMapping = builder.buildVarIdxMap(mapping, glyphOrder)

	use_direct = False
	if directStore:
		# Compile both, see which is more compact

		writer = OTTableWriter()
		directStore.compile(writer, font)
		directSize = len(writer.getAllData())

		writer = OTTableWriter()
		indirectStore.compile(writer, font)
		advanceMapping.compile(writer, font)
		indirectSize = len(writer.getAllData())

		use_direct = directSize < indirectSize

	# Done; put it all together.
	assert "HVAR" not in font
	HVAR = font["HVAR"] = newTable('HVAR')
	hvar = HVAR.table = ot.HVAR()
	hvar.Version = 0x00010000
	hvar.LsbMap = hvar.RsbMap = None
	if use_direct:
		hvar.VarStore = directStore
		hvar.AdvWidthMap = None
	else:
		hvar.VarStore = indirectStore
		hvar.AdvWidthMap = advanceMapping
예제 #11
0
def _get_advance_metrics(font, masterModel, master_ttfs,
		axisTags, glyphOrder, advMetricses, vOrigMetricses=None):

	vhAdvanceDeltasAndSupports = {}
	vOrigDeltasAndSupports = {}
	for glyph in glyphOrder:
		vhAdvances = [metrics[glyph][0] if glyph in metrics else None for metrics in advMetricses]
		vhAdvanceDeltasAndSupports[glyph] = masterModel.getDeltasAndSupports(vhAdvances)

	singleModel = models.allEqual(id(v[1]) for v in vhAdvanceDeltasAndSupports.values())

	if vOrigMetricses:
		singleModel = False
		for glyph in glyphOrder:
			# We need to supply a vOrigs tuple with non-None default values
			# for each glyph. vOrigMetricses contains values only for those
			# glyphs which have a non-default vOrig.
			vOrigs = [metrics[glyph] if glyph in metrics else defaultVOrig
				for metrics, defaultVOrig in vOrigMetricses]
			vOrigDeltasAndSupports[glyph] = masterModel.getDeltasAndSupports(vOrigs)

	directStore = None
	if singleModel:
		# Build direct mapping
		supports = next(iter(vhAdvanceDeltasAndSupports.values()))[1][1:]
		varTupleList = builder.buildVarRegionList(supports, axisTags)
		varTupleIndexes = list(range(len(supports)))
		varData = builder.buildVarData(varTupleIndexes, [], optimize=False)
		for glyphName in glyphOrder:
			varData.addItem(vhAdvanceDeltasAndSupports[glyphName][0])
		varData.optimize()
		directStore = builder.buildVarStore(varTupleList, [varData])

	# Build optimized indirect mapping
	storeBuilder = varStore.OnlineVarStoreBuilder(axisTags)
	advMapping = {}
	for glyphName in glyphOrder:
		deltas, supports = vhAdvanceDeltasAndSupports[glyphName]
		storeBuilder.setSupports(supports)
		advMapping[glyphName] = storeBuilder.storeDeltas(deltas)

	if vOrigMetricses:
		vOrigMap = {}
		for glyphName in glyphOrder:
			deltas, supports = vOrigDeltasAndSupports[glyphName]
			storeBuilder.setSupports(supports)
			vOrigMap[glyphName] = storeBuilder.storeDeltas(deltas)

	indirectStore = storeBuilder.finish()
	mapping2 = indirectStore.optimize()
	advMapping = [mapping2[advMapping[g]] for g in glyphOrder]
	advanceMapping = builder.buildVarIdxMap(advMapping, glyphOrder)

	if vOrigMetricses:
		vOrigMap = [mapping2[vOrigMap[g]] for g in glyphOrder]

	useDirect = False
	vOrigMapping = None
	if directStore:
		# Compile both, see which is more compact

		writer = OTTableWriter()
		directStore.compile(writer, font)
		directSize = len(writer.getAllData())

		writer = OTTableWriter()
		indirectStore.compile(writer, font)
		advanceMapping.compile(writer, font)
		indirectSize = len(writer.getAllData())

		useDirect = directSize < indirectSize

	if useDirect:
		metricsStore = directStore
		advanceMapping = None
	else:
		metricsStore = indirectStore
		if vOrigMetricses:
			vOrigMapping = builder.buildVarIdxMap(vOrigMap, glyphOrder)

	return metricsStore, advanceMapping, vOrigMapping
예제 #12
0
 def __init__(self, axisTags):
     self._axisTags = axisTags
     self._regionMap = {}
     self._regionList = buildVarRegionList([], axisTags)
     self._store = buildVarStore(self._regionList, [])