"""
Module for dealing with 'gvar'-style font variations, also known as run-time
interpolation.

The ideas here are very similar to MutatorMath.  There is even code to read
MutatorMath .designspace files in the varLib.designspace module.

For now, if you run this file on a designspace file, it tries to find
ttf-interpolatable files for the masters and build a variable-font from
them.  Such ttf-interpolatable and designspace files can be generated from
a Glyphs source, eg., using noto-source as an example:

	$ fontmake -o ttf-interpolatable -g NotoSansArabic-MM.glyphs

Then you can make a variable-font this way:

	$ fonttools varLib master_ufo/NotoSansArabic.designspace

API *will* change in near future.
"""

from typing import List
from fontTools.misc.vector import Vector
from fontTools.misc.roundTools import noRound, otRound
from fontTools.misc.fixedTools import floatToFixed as fl2fi
from fontTools.misc.textTools import Tag, tostr
from fontTools.ttLib import TTFont, newTable
from fontTools.ttLib.tables._f_v_a_r import Axis, NamedInstance
from fontTools.ttLib.tables._g_l_y_f import GlyphCoordinates, dropImpliedOnCurvePoints
from fontTools.ttLib.tables.ttProgram import Program
from fontTools.ttLib.tables.TupleVariation import TupleVariation
from fontTools.ttLib.tables import otTables as ot
from fontTools.ttLib.tables.otBase import OTTableWriter
from fontTools.varLib import builder, models, varStore
from fontTools.varLib.merger import VariationMerger, COLRVariationMerger
from fontTools.varLib.mvar import MVAR_ENTRIES
from fontTools.varLib.iup import iup_delta_optimize
from fontTools.varLib.featureVars import addFeatureVariations
from fontTools.designspaceLib import DesignSpaceDocument, InstanceDescriptor
from fontTools.designspaceLib.split import splitInterpolable, splitVariableFonts
from fontTools.varLib.stat import buildVFStatTable
from fontTools.colorLib.builder import buildColrV1
from fontTools.colorLib.unbuilder import unbuildColrV1
from functools import partial
from collections import OrderedDict, defaultdict, namedtuple
import os.path
import logging
from copy import deepcopy
from pprint import pformat
from re import fullmatch
from .errors import VarLibError, VarLibValidationError

log = logging.getLogger("fontTools.varLib")

# This is a lib key for the designspace document. The value should be
# a comma-separated list of OpenType feature tag(s), to be used as the
# FeatureVariations feature.
# If present, the DesignSpace <rules processing="..."> flag is ignored.
FEAVAR_FEATURETAG_LIB_KEY = "com.github.fonttools.varLib.featureVarsFeatureTag"

#
# Creation routines
#


def _add_fvar(font, axes, instances: List[InstanceDescriptor]):
    """
    Add 'fvar' table to font.

    axes is an ordered dictionary of DesignspaceAxis objects.

    instances is list of dictionary objects with 'location', 'stylename',
    and possibly 'postscriptfontname' entries.
    """

    assert axes
    assert isinstance(axes, OrderedDict)

    log.info("Generating fvar")

    fvar = newTable("fvar")
    nameTable = font["name"]

    for a in axes.values():
        axis = Axis()
        axis.axisTag = Tag(a.tag)
        # TODO Skip axes that have no variation.
        axis.minValue, axis.defaultValue, axis.maxValue = (
            a.minimum,
            a.default,
            a.maximum,
        )
        axis.axisNameID = nameTable.addMultilingualName(
            a.labelNames, font, minNameID=256
        )
        axis.flags = int(a.hidden)
        fvar.axes.append(axis)

    for instance in instances:
        # Filter out discrete axis locations
        coordinates = {
            name: value for name, value in instance.location.items() if name in axes
        }

        if "en" not in instance.localisedStyleName:
            if not instance.styleName:
                raise VarLibValidationError(
                    f"Instance at location '{coordinates}' must have a default English "
                    "style name ('stylename' attribute on the instance element or a "
                    "stylename element with an 'xml:lang=\"en\"' attribute)."
                )
            localisedStyleName = dict(instance.localisedStyleName)
            localisedStyleName["en"] = tostr(instance.styleName)
        else:
            localisedStyleName = instance.localisedStyleName

        psname = instance.postScriptFontName

        inst = NamedInstance()
        inst.subfamilyNameID = nameTable.addMultilingualName(localisedStyleName)
        if psname is not None:
            psname = tostr(psname)
            inst.postscriptNameID = nameTable.addName(psname)
        inst.coordinates = {
            axes[k].tag: axes[k].map_backward(v) for k, v in coordinates.items()
        }
        # inst.coordinates = {axes[k].tag:v for k,v in coordinates.items()}
        fvar.instances.append(inst)

    assert "fvar" not in font
    font["fvar"] = fvar

    return fvar


def _add_avar(font, axes, mappings, axisTags):
    """
    Add 'avar' table to font.

    axes is an ordered dictionary of AxisDescriptor objects.
    """

    assert axes
    assert isinstance(axes, OrderedDict)

    log.info("Generating avar")

    avar = newTable("avar")

    interesting = False
    vals_triples = {}
    for axis in axes.values():
        # Currently, some rasterizers require that the default value maps
        # (-1 to -1, 0 to 0, and 1 to 1) be present for all the segment
        # maps, even when the default normalization mapping for the axis
        # was not modified.
        # https://github.com/googlei18n/fontmake/issues/295
        # https://github.com/fonttools/fonttools/issues/1011
        # TODO(anthrotype) revert this (and 19c4b37) when issue is fixed
        curve = avar.segments[axis.tag] = {-1.0: -1.0, 0.0: 0.0, 1.0: 1.0}

        keys_triple = (axis.minimum, axis.default, axis.maximum)
        vals_triple = tuple(axis.map_forward(v) for v in keys_triple)
        vals_triples[axis.tag] = vals_triple

        if not axis.map:
            continue

        items = sorted(axis.map)
        keys = [item[0] for item in items]
        vals = [item[1] for item in items]

        # Current avar requirements.  We don't have to enforce
        # these on the designer and can deduce some ourselves,
        # but for now just enforce them.
        if axis.minimum != min(keys):
            raise VarLibValidationError(
                f"Axis '{axis.name}': there must be a mapping for the axis minimum "
                f"value {axis.minimum} and it must be the lowest input mapping value."
            )
        if axis.maximum != max(keys):
            raise VarLibValidationError(
                f"Axis '{axis.name}': there must be a mapping for the axis maximum "
                f"value {axis.maximum} and it must be the highest input mapping value."
            )
        if axis.default not in keys:
            raise VarLibValidationError(
                f"Axis '{axis.name}': there must be a mapping for the axis default "
                f"value {axis.default}."
            )
        # No duplicate input values (output values can be >= their preceeding value).
        if len(set(keys)) != len(keys):
            raise VarLibValidationError(
                f"Axis '{axis.name}': All axis mapping input='...' values must be "
                "unique, but we found duplicates."
            )
        # Ascending values
        if sorted(vals) != vals:
            raise VarLibValidationError(
                f"Axis '{axis.name}': mapping output values must be in ascending order."
            )

        keys = [models.normalizeValue(v, keys_triple) for v in keys]
        vals = [models.normalizeValue(v, vals_triple) for v in vals]

        if all(k == v for k, v in zip(keys, vals)):
            continue
        interesting = True

        curve.update(zip(keys, vals))

        assert 0.0 in curve and curve[0.0] == 0.0
        assert -1.0 not in curve or curve[-1.0] == -1.0
        assert +1.0 not in curve or curve[+1.0] == +1.0
        # curve.update({-1.0: -1.0, 0.0: 0.0, 1.0: 1.0})

    if mappings:
        interesting = True

        inputLocations = [
            {
                axes[name].tag: models.normalizeValue(v, vals_triples[axes[name].tag])
                for name, v in mapping.inputLocation.items()
            }
            for mapping in mappings
        ]
        outputLocations = [
            {
                axes[name].tag: models.normalizeValue(v, vals_triples[axes[name].tag])
                for name, v in mapping.outputLocation.items()
            }
            for mapping in mappings
        ]
        assert len(inputLocations) == len(outputLocations)

        # If base-master is missing, insert it at zero location.
        if not any(all(v == 0 for k, v in loc.items()) for loc in inputLocations):
            inputLocations.insert(0, {})
            outputLocations.insert(0, {})

        model = models.VariationModel(inputLocations, axisTags)
        storeBuilder = varStore.OnlineVarStoreBuilder(axisTags)
        storeBuilder.setModel(model)
        varIdxes = {}
        for tag in axisTags:
            masterValues = []
            for vo, vi in zip(outputLocations, inputLocations):
                if tag not in vo:
                    masterValues.append(0)
                    continue
                v = vo[tag] - vi.get(tag, 0)
                masterValues.append(fl2fi(v, 14))
            varIdxes[tag] = storeBuilder.storeMasters(masterValues)[1]

        store = storeBuilder.finish()
        optimized = store.optimize()
        varIdxes = {axis: optimized[value] for axis, value in varIdxes.items()}

        varIdxMap = builder.buildDeltaSetIndexMap(varIdxes[t] for t in axisTags)

        avar.majorVersion = 2
        avar.table = ot.avar()
        avar.table.VarIdxMap = varIdxMap
        avar.table.VarStore = store

    assert "avar" not in font
    if not interesting:
        log.info("No need for avar")
        avar = None
    else:
        font["avar"] = avar

    return avar


def _add_stat(font):
    # Note: this function only gets called by old code that calls `build()`
    # directly. Newer code that wants to benefit from STAT data from the
    # designspace should call `build_many()`

    if "STAT" in font:
        return

    from ..otlLib.builder import buildStatTable

    fvarTable = font["fvar"]
    axes = [dict(tag=a.axisTag, name=a.axisNameID) for a in fvarTable.axes]
    buildStatTable(font, axes)


_MasterData = namedtuple("_MasterData", ["glyf", "hMetrics", "vMetrics"])


def _add_gvar(font, masterModel, master_ttfs, tolerance=0.5, optimize=True):
    if tolerance < 0:
        raise ValueError("`tolerance` must be a positive number.")

    log.info("Generating gvar")
    assert "gvar" not in font
    gvar = font["gvar"] = newTable("gvar")
    glyf = font["glyf"]
    defaultMasterIndex = masterModel.reverseMapping[0]

    master_datas = [
        _MasterData(
            m["glyf"], m["hmtx"].metrics, getattr(m.get("vmtx"), "metrics", None)
        )
        for m in master_ttfs
    ]

    for glyph in font.getGlyphOrder():
        log.debug("building gvar for glyph '%s'", glyph)
        isComposite = glyf[glyph].isComposite()

        allData = [
            m.glyf._getCoordinatesAndControls(glyph, m.hMetrics, m.vMetrics)
            for m in master_datas
        ]

        if allData[defaultMasterIndex][1].numberOfContours != 0:
            # If the default master is not empty, interpret empty non-default masters
            # as missing glyphs from a sparse master
            allData = [
                d if d is not None and d[1].numberOfContours != 0 else None
                for d in allData
            ]

        model, allData = masterModel.getSubModel(allData)

        allCoords = [d[0] for d in allData]
        allControls = [d[1] for d in allData]
        control = allControls[0]
        if not models.allEqual(allControls):
            log.warning("glyph %s has incompatible masters; skipping" % glyph)
            continue
        del allControls

        # Update gvar
        gvar.variations[glyph] = []
        deltas = model.getDeltas(
            allCoords, round=partial(GlyphCoordinates.__round__, round=round)
        )
        supports = model.supports
        assert len(deltas) == len(supports)

        # Prepare for IUP optimization
        origCoords = deltas[0]
        endPts = control.endPts

        for i, (delta, support) in enumerate(zip(deltas[1:], supports[1:])):
            if all(v == 0 for v in delta.array) and not isComposite:
                continue
            var = TupleVariation(support, delta)
            if optimize:
                delta_opt = iup_delta_optimize(
                    delta, origCoords, endPts, tolerance=tolerance
                )

                if None in delta_opt:
                    """In composite glyphs, there should be one 0 entry
                    to make sure the gvar entry is written to the font.

                    This is to work around an issue with macOS 10.14 and can be
                    removed once the behaviour of macOS is changed.

                    https://github.com/fonttools/fonttools/issues/1381
                    """
                    if all(d is None for d in delta_opt):
                        delta_opt = [(0, 0)] + [None] * (len(delta_opt) - 1)
                    # Use "optimized" version only if smaller...
                    var_opt = TupleVariation(support, delta_opt)

                    axis_tags = sorted(
                        support.keys()
                    )  # Shouldn't matter that this is different from fvar...?
                    tupleData, auxData = var.compile(axis_tags)
                    unoptimized_len = len(tupleData) + len(auxData)
                    tupleData, auxData = var_opt.compile(axis_tags)
                    optimized_len = len(tupleData) + len(auxData)

                    if optimized_len < unoptimized_len:
                        var = var_opt

            gvar.variations[glyph].append(var)


def _remove_TTHinting(font):
    for tag in ("cvar", "cvt ", "fpgm", "prep"):
        if tag in font:
            del font[tag]
    maxp = font["maxp"]
    for attr in (
        "maxTwilightPoints",
        "maxStorage",
        "maxFunctionDefs",
        "maxInstructionDefs",
        "maxStackElements",
        "maxSizeOfInstructions",
    ):
        setattr(maxp, attr, 0)
    maxp.maxZones = 1
    font["glyf"].removeHinting()
    # TODO: Modify gasp table to deactivate gridfitting for all ranges?


def _merge_TTHinting(font, masterModel, master_ttfs):
    log.info("Merging TT hinting")
    assert "cvar" not in font

    # Check that the existing hinting is compatible

    # fpgm and prep table

    for tag in ("fpgm", "prep"):
        all_pgms = [m[tag].program for m in master_ttfs if tag in m]
        if not all_pgms:
            continue
        font_pgm = getattr(font.get(tag), "program", None)
        if any(pgm != font_pgm for pgm in all_pgms):
            log.warning(
                "Masters have incompatible %s tables, hinting is discarded." % tag
            )
            _remove_TTHinting(font)
            return

    # glyf table

    font_glyf = font["glyf"]
    master_glyfs = [m["glyf"] for m in master_ttfs]
    for name, glyph in font_glyf.glyphs.items():
        all_pgms = [getattr(glyf.get(name), "program", None) for glyf in master_glyfs]
        if not any(all_pgms):
            continue
        glyph.expand(font_glyf)
        font_pgm = getattr(glyph, "program", None)
        if any(pgm != font_pgm for pgm in all_pgms if pgm):
            log.warning(
                "Masters have incompatible glyph programs in glyph '%s', hinting is discarded."
                % name
            )
            # TODO Only drop hinting from this glyph.
            _remove_TTHinting(font)
            return

    # cvt table

    all_cvs = [Vector(m["cvt "].values) if "cvt " in m else None for m in master_ttfs]

    nonNone_cvs = models.nonNone(all_cvs)
    if not nonNone_cvs:
        # There is no cvt table to make a cvar table from, we're done here.
        return

    if not models.allEqual(len(c) for c in nonNone_cvs):
        log.warning("Masters have incompatible cvt tables, hinting is discarded.")
        _remove_TTHinting(font)
        return

    variations = []
    deltas, supports = masterModel.getDeltasAndSupports(
        all_cvs, round=round
    )  # builtin round calls into Vector.__round__, which uses builtin round as we like
    for i, (delta, support) in enumerate(zip(deltas[1:], supports[1:])):
        if all(v == 0 for v in delta):
            continue
        var = TupleVariation(support, delta)
        variations.append(var)

    # We can build the cvar table now.
    if variations:
        cvar = font["cvar"] = newTable("cvar")
        cvar.version = 1
        cvar.variations = variations


_MetricsFields = namedtuple(
    "_MetricsFields",
    ["tableTag", "metricsTag", "sb1", "sb2", "advMapping", "vOrigMapping"],
)

HVAR_FIELDS = _MetricsFields(
    tableTag="HVAR",
    metricsTag="hmtx",
    sb1="LsbMap",
    sb2="RsbMap",
    advMapping="AdvWidthMap",
    vOrigMapping=None,
)

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, HVAR_FIELDS)


def _add_VVAR(font, masterModel, master_ttfs, axisTags):
    _add_VHVAR(font, masterModel, master_ttfs, axisTags, VVAR_FIELDS)


def _add_VHVAR(font, masterModel, master_ttfs, axisTags, tableFields):
    tableTag = tableFields.tableTag
    assert tableTag not in font
    log.info("Generating " + tableTag)
    VHVAR = newTable(tableTag)
    tableClass = getattr(ot, tableTag)
    vhvar = VHVAR.table = tableClass()
    vhvar.Version = 0x00010000

    glyphOrder = font.getGlyphOrder()

    # Build list of source font advance widths for each glyph
    metricsTag = tableFields.metricsTag
    advMetricses = [m[metricsTag].metrics for m in master_ttfs]

    # Build list of source font vertical origin coords for each glyph
    if tableTag == "VVAR" and "VORG" in master_ttfs[0]:
        vOrigMetricses = [m["VORG"].VOriginRecords for m in master_ttfs]
        defaultYOrigs = [m["VORG"].defaultVertOriginY for m in master_ttfs]
        vOrigMetricses = list(zip(vOrigMetricses, defaultYOrigs))
    else:
        vOrigMetricses = None

    metricsStore, advanceMapping, vOrigMapping = _get_advance_metrics(
        font,
        masterModel,
        master_ttfs,
        axisTags,
        glyphOrder,
        advMetricses,
        vOrigMetricses,
    )

    vhvar.VarStore = metricsStore
    if advanceMapping is None:
        setattr(vhvar, tableFields.advMapping, None)
    else:
        setattr(vhvar, tableFields.advMapping, advanceMapping)
    if vOrigMapping is not None:
        setattr(vhvar, tableFields.vOrigMapping, vOrigMapping)
    setattr(vhvar, tableFields.sb1, None)
    setattr(vhvar, tableFields.sb2, None)

    font[tableTag] = VHVAR
    return


def _get_advance_metrics(
    font,
    masterModel,
    master_ttfs,
    axisTags,
    glyphOrder,
    advMetricses,
    vOrigMetricses=None,
):
    vhAdvanceDeltasAndSupports = {}
    vOrigDeltasAndSupports = {}
    # HACK: we treat width 65535 as a sentinel value to signal that a glyph
    # from a non-default master should not participate in computing {H,V}VAR,
    # as if it were missing. Allows to variate other glyph-related data independently
    # from glyph metrics
    sparse_advance = 0xFFFF
    for glyph in glyphOrder:
        vhAdvances = [
            (
                metrics[glyph][0]
                if glyph in metrics and metrics[glyph][0] != sparse_advance
                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(use_NO_VARIATION_INDEX=False)
    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


def _add_MVAR(font, masterModel, master_ttfs, axisTags):
    log.info("Generating MVAR")

    store_builder = varStore.OnlineVarStoreBuilder(axisTags)

    records = []
    lastTableTag = None
    fontTable = None
    tables = None
    # HACK: we need to special-case post.underlineThickness and .underlinePosition
    # and unilaterally/arbitrarily define a sentinel value to distinguish the case
    # when a post table is present in a given master simply because that's where
    # the glyph names in TrueType must be stored, but the underline values are not
    # meant to be used for building MVAR's deltas. The value of -0x8000 (-36768)
    # the minimum FWord (int16) value, was chosen for its unlikelyhood to appear
    # in real-world underline position/thickness values.
    specialTags = {"unds": -0x8000, "undo": -0x8000}

    for tag, (tableTag, itemName) in sorted(MVAR_ENTRIES.items(), key=lambda kv: kv[1]):
        # For each tag, fetch the associated table from all fonts (or not when we are
        # still looking at a tag from the same tables) and set up the variation model
        # for them.
        if tableTag != lastTableTag:
            tables = fontTable = None
            if tableTag in font:
                fontTable = font[tableTag]
                tables = []
                for master in master_ttfs:
                    if tableTag not in master or (
                        tag in specialTags
                        and getattr(master[tableTag], itemName) == specialTags[tag]
                    ):
                        tables.append(None)
                    else:
                        tables.append(master[tableTag])
                model, tables = masterModel.getSubModel(tables)
                store_builder.setModel(model)
            lastTableTag = tableTag

        if tables is None:  # Tag not applicable to the master font.
            continue

        # TODO support gasp entries

        master_values = [getattr(table, itemName) for table in tables]
        if models.allEqual(master_values):
            base, varIdx = master_values[0], None
        else:
            base, varIdx = store_builder.storeMasters(master_values)
        setattr(fontTable, itemName, base)

        if varIdx is None:
            continue
        log.info("	%s: %s.%s	%s", tag, tableTag, itemName, master_values)
        rec = ot.MetricsValueRecord()
        rec.ValueTag = tag
        rec.VarIdx = varIdx
        records.append(rec)

    assert "MVAR" not in font
    if records:
        store = store_builder.finish()
        # Optimize
        mapping = store.optimize()
        for rec in records:
            rec.VarIdx = mapping[rec.VarIdx]

        MVAR = font["MVAR"] = newTable("MVAR")
        mvar = MVAR.table = ot.MVAR()
        mvar.Version = 0x00010000
        mvar.Reserved = 0
        mvar.VarStore = store
        # XXX these should not be hard-coded but computed automatically
        mvar.ValueRecordSize = 8
        mvar.ValueRecordCount = len(records)
        mvar.ValueRecord = sorted(records, key=lambda r: r.ValueTag)


def _add_BASE(font, masterModel, master_ttfs, axisTags):
    log.info("Generating BASE")

    merger = VariationMerger(masterModel, axisTags, font)
    merger.mergeTables(font, master_ttfs, ["BASE"])
    store = merger.store_builder.finish()

    if not store:
        return
    base = font["BASE"].table
    assert base.Version == 0x00010000
    base.Version = 0x00010001
    base.VarStore = store


def _merge_OTL(font, model, master_fonts, axisTags):
    otl_tags = ["GSUB", "GDEF", "GPOS"]
    if not any(tag in font for tag in otl_tags):
        return

    log.info("Merging OpenType Layout tables")
    merger = VariationMerger(model, axisTags, font)

    merger.mergeTables(font, master_fonts, otl_tags)
    store = merger.store_builder.finish()
    if not store:
        return
    try:
        GDEF = font["GDEF"].table
        assert GDEF.Version <= 0x00010002
    except KeyError:
        font["GDEF"] = newTable("GDEF")
        GDEFTable = font["GDEF"] = newTable("GDEF")
        GDEF = GDEFTable.table = ot.GDEF()
        GDEF.GlyphClassDef = None
        GDEF.AttachList = None
        GDEF.LigCaretList = None
        GDEF.MarkAttachClassDef = None
        GDEF.MarkGlyphSetsDef = None

    GDEF.Version = 0x00010003
    GDEF.VarStore = store

    # Optimize
    varidx_map = store.optimize()
    GDEF.remap_device_varidxes(varidx_map)
    if "GPOS" in font:
        font["GPOS"].table.remap_device_varidxes(varidx_map)


def _add_GSUB_feature_variations(
    font, axes, internal_axis_supports, rules, featureTags
):
    def normalize(name, value):
        return models.normalizeLocation({name: value}, internal_axis_supports)[name]

    log.info("Generating GSUB FeatureVariations")

    axis_tags = {name: axis.tag for name, axis in axes.items()}

    conditional_subs = []
    for rule in rules:
        region = []
        for conditions in rule.conditionSets:
            space = {}
            for condition in conditions:
                axis_name = condition["name"]
                if condition["minimum"] is not None:
                    minimum = normalize(axis_name, condition["minimum"])
                else:
                    minimum = -1.0
                if condition["maximum"] is not None:
                    maximum = normalize(axis_name, condition["maximum"])
                else:
                    maximum = 1.0
                tag = axis_tags[axis_name]
                space[tag] = (minimum, maximum)
            region.append(space)

        subs = {k: v for k, v in rule.subs}

        conditional_subs.append((region, subs))

    addFeatureVariations(font, conditional_subs, featureTags)


_DesignSpaceData = namedtuple(
    "_DesignSpaceData",
    [
        "axes",
        "axisMappings",
        "internal_axis_supports",
        "base_idx",
        "normalized_master_locs",
        "masters",
        "instances",
        "rules",
        "rulesProcessingLast",
        "lib",
    ],
)


def _add_CFF2(varFont, model, master_fonts):
    from .cff import merge_region_fonts

    glyphOrder = varFont.getGlyphOrder()
    if "CFF2" not in varFont:
        from .cff import convertCFFtoCFF2

        convertCFFtoCFF2(varFont)
    ordered_fonts_list = model.reorderMasters(master_fonts, model.reverseMapping)
    # re-ordering the master list simplifies building the CFF2 data item lists.
    merge_region_fonts(varFont, model, ordered_fonts_list, glyphOrder)


def _add_COLR(font, model, master_fonts, axisTags, colr_layer_reuse=True):
    merger = COLRVariationMerger(
        model, axisTags, font, allowLayerReuse=colr_layer_reuse
    )
    merger.mergeTables(font, master_fonts)
    store = merger.store_builder.finish()

    colr = font["COLR"].table
    if store:
        mapping = store.optimize()
        colr.VarStore = store
        varIdxes = [mapping[v] for v in merger.varIdxes]
        colr.VarIndexMap = builder.buildDeltaSetIndexMap(varIdxes)


def load_designspace(designspace, log_enabled=True):
    # TODO: remove this and always assume 'designspace' is a DesignSpaceDocument,
    # never a file path, as that's already handled by caller
    if hasattr(designspace, "sources"):  # Assume a DesignspaceDocument
        ds = designspace
    else:  # Assume a file path
        ds = DesignSpaceDocument.fromfile(designspace)

    masters = ds.sources
    if not masters:
        raise VarLibValidationError("Designspace must have at least one source.")
    instances = ds.instances

    # TODO: Use fontTools.designspaceLib.tagForAxisName instead.
    standard_axis_map = OrderedDict(
        [
            ("weight", ("wght", {"en": "Weight"})),
            ("width", ("wdth", {"en": "Width"})),
            ("slant", ("slnt", {"en": "Slant"})),
            ("optical", ("opsz", {"en": "Optical Size"})),
            ("italic", ("ital", {"en": "Italic"})),
        ]
    )

    # Setup axes
    if not ds.axes:
        raise VarLibValidationError(f"Designspace must have at least one axis.")

    axes = OrderedDict()
    for axis_index, axis in enumerate(ds.axes):
        axis_name = axis.name
        if not axis_name:
            if not axis.tag:
                raise VarLibValidationError(f"Axis at index {axis_index} needs a tag.")
            axis_name = axis.name = axis.tag

        if axis_name in standard_axis_map:
            if axis.tag is None:
                axis.tag = standard_axis_map[axis_name][0]
            if not axis.labelNames:
                axis.labelNames.update(standard_axis_map[axis_name][1])
        else:
            if not axis.tag:
                raise VarLibValidationError(f"Axis at index {axis_index} needs a tag.")
            if not axis.labelNames:
                axis.labelNames["en"] = tostr(axis_name)

        axes[axis_name] = axis
    if log_enabled:
        log.info("Axes:\n%s", pformat([axis.asdict() for axis in axes.values()]))

    axisMappings = ds.axisMappings
    if axisMappings and log_enabled:
        log.info("Mappings:\n%s", pformat(axisMappings))

    # Check all master and instance locations are valid and fill in defaults
    for obj in masters + instances:
        obj_name = obj.name or obj.styleName or ""
        loc = obj.getFullDesignLocation(ds)
        obj.designLocation = loc
        if loc is None:
            raise VarLibValidationError(
                f"Source or instance '{obj_name}' has no location."
            )
        for axis_name in loc.keys():
            if axis_name not in axes:
                raise VarLibValidationError(
                    f"Location axis '{axis_name}' unknown for '{obj_name}'."
                )
        for axis_name, axis in axes.items():
            v = axis.map_backward(loc[axis_name])
            if not (axis.minimum <= v <= axis.maximum):
                raise VarLibValidationError(
                    f"Source or instance '{obj_name}' has out-of-range location "
                    f"for axis '{axis_name}': is mapped to {v} but must be in "
                    f"mapped range [{axis.minimum}..{axis.maximum}] (NOTE: all "
                    "values are in user-space)."
                )

    # Normalize master locations

    internal_master_locs = [o.getFullDesignLocation(ds) for o in masters]
    if log_enabled:
        log.info("Internal master locations:\n%s", pformat(internal_master_locs))

    # TODO This mapping should ideally be moved closer to logic in _add_fvar/avar
    internal_axis_supports = {}
    for axis in axes.values():
        triple = (axis.minimum, axis.default, axis.maximum)
        internal_axis_supports[axis.name] = [axis.map_forward(v) for v in triple]
    if log_enabled:
        log.info("Internal axis supports:\n%s", pformat(internal_axis_supports))

    normalized_master_locs = [
        models.normalizeLocation(m, internal_axis_supports)
        for m in internal_master_locs
    ]
    if log_enabled:
        log.info("Normalized master locations:\n%s", pformat(normalized_master_locs))

    # Find base master
    base_idx = None
    for i, m in enumerate(normalized_master_locs):
        if all(v == 0 for v in m.values()):
            if base_idx is not None:
                raise VarLibValidationError(
                    "More than one base master found in Designspace."
                )
            base_idx = i
    if base_idx is None:
        raise VarLibValidationError(
            "Base master not found; no master at default location?"
        )
    if log_enabled:
        log.info("Index of base master: %s", base_idx)

    return _DesignSpaceData(
        axes,
        axisMappings,
        internal_axis_supports,
        base_idx,
        normalized_master_locs,
        masters,
        instances,
        ds.rules,
        ds.rulesProcessingLast,
        ds.lib,
    )


# https://docs.microsoft.com/en-us/typography/opentype/spec/os2#uswidthclass
WDTH_VALUE_TO_OS2_WIDTH_CLASS = {
    50: 1,
    62.5: 2,
    75: 3,
    87.5: 4,
    100: 5,
    112.5: 6,
    125: 7,
    150: 8,
    200: 9,
}


def set_default_weight_width_slant(font, location):
    if "OS/2" in font:
        if "wght" in location:
            weight_class = otRound(max(1, min(location["wght"], 1000)))
            if font["OS/2"].usWeightClass != weight_class:
                log.info("Setting OS/2.usWeightClass = %s", weight_class)
                font["OS/2"].usWeightClass = weight_class

        if "wdth" in location:
            # map 'wdth' axis (50..200) to OS/2.usWidthClass (1..9), rounding to closest
            widthValue = min(max(location["wdth"], 50), 200)
            widthClass = otRound(
                models.piecewiseLinearMap(widthValue, WDTH_VALUE_TO_OS2_WIDTH_CLASS)
            )
            if font["OS/2"].usWidthClass != widthClass:
                log.info("Setting OS/2.usWidthClass = %s", widthClass)
                font["OS/2"].usWidthClass = widthClass

    if "slnt" in location and "post" in font:
        italicAngle = max(-90, min(location["slnt"], 90))
        if font["post"].italicAngle != italicAngle:
            log.info("Setting post.italicAngle = %s", italicAngle)
            font["post"].italicAngle = italicAngle


def drop_implied_oncurve_points(*masters: TTFont) -> int:
    """Drop impliable on-curve points from all the simple glyphs in masters.

    In TrueType glyf outlines, on-curve points can be implied when they are located
    exactly at the midpoint of the line connecting two consecutive off-curve points.

    The input masters' glyf tables are assumed to contain same-named glyphs that are
    interpolatable. Oncurve points are only dropped if they can be implied for all
    the masters. The fonts are modified in-place.

    Args:
        masters: The TTFont(s) to modify

    Returns:
        The total number of points that were dropped if any.

    Reference:
    https://developer.apple.com/fonts/TrueType-Reference-Manual/RM01/Chap1.html
    """

    count = 0
    glyph_masters = defaultdict(list)
    # multiple DS source may point to the same TTFont object and we want to
    # avoid processing the same glyph twice as they are modified in-place
    for font in {id(m): m for m in masters}.values():
        glyf = font["glyf"]
        for glyphName in glyf.keys():
            glyph_masters[glyphName].append(glyf[glyphName])
    count = 0
    for glyphName, glyphs in glyph_masters.items():
        try:
            dropped = dropImpliedOnCurvePoints(*glyphs)
        except ValueError as e:
            # we don't fail for incompatible glyphs in _add_gvar so we shouldn't here
            log.warning("Failed to drop implied oncurves for %r: %s", glyphName, e)
        else:
            count += len(dropped)
    return count


def build_many(
    designspace: DesignSpaceDocument,
    master_finder=lambda s: s,
    exclude=[],
    optimize=True,
    skip_vf=lambda vf_name: False,
    colr_layer_reuse=True,
    drop_implied_oncurves=False,
):
    """
    Build variable fonts from a designspace file, version 5 which can define
    several VFs, or version 4 which has implicitly one VF covering the whole doc.

    If master_finder is set, it should be a callable that takes master
    filename as found in designspace file and map it to master font
    binary as to be opened (eg. .ttf or .otf).

    skip_vf can be used to skip building some of the variable fonts defined in
    the input designspace. It's a predicate that takes as argument the name
    of the variable font and returns `bool`.

    Always returns a Dict[str, TTFont] keyed by VariableFontDescriptor.name
    """
    res = {}
    # varLib.build (used further below) by default only builds an incomplete 'STAT'
    # with an empty AxisValueArray--unless the VF inherited 'STAT' from its base master.
    # Designspace version 5 can also be used to define 'STAT' labels or customize
    # axes ordering, etc. To avoid overwriting a pre-existing 'STAT' or redoing the
    # same work twice, here we check if designspace contains any 'STAT' info before
    # proceeding to call buildVFStatTable for each VF.
    # https://github.com/fonttools/fonttools/pull/3024
    # https://github.com/fonttools/fonttools/issues/3045
    doBuildStatFromDSv5 = (
        "STAT" not in exclude
        and designspace.formatTuple >= (5, 0)
        and (
            any(a.axisLabels or a.axisOrdering is not None for a in designspace.axes)
            or designspace.locationLabels
        )
    )
    for _location, subDoc in splitInterpolable(designspace):
        for name, vfDoc in splitVariableFonts(subDoc):
            if skip_vf(name):
                log.debug(f"Skipping variable TTF font: {name}")
                continue
            vf = build(
                vfDoc,
                master_finder,
                exclude=exclude,
                optimize=optimize,
                colr_layer_reuse=colr_layer_reuse,
                drop_implied_oncurves=drop_implied_oncurves,
            )[0]
            if doBuildStatFromDSv5:
                buildVFStatTable(vf, designspace, name)
            res[name] = vf
    return res


def build(
    designspace,
    master_finder=lambda s: s,
    exclude=[],
    optimize=True,
    colr_layer_reuse=True,
    drop_implied_oncurves=False,
):
    """
    Build variation font from a designspace file.

    If master_finder is set, it should be a callable that takes master
    filename as found in designspace file and map it to master font
    binary as to be opened (eg. .ttf or .otf).
    """
    if hasattr(designspace, "sources"):  # Assume a DesignspaceDocument
        pass
    else:  # Assume a file path
        designspace = DesignSpaceDocument.fromfile(designspace)

    ds = load_designspace(designspace)
    log.info("Building variable font")

    log.info("Loading master fonts")
    master_fonts = load_masters(designspace, master_finder)

    # TODO: 'master_ttfs' is unused except for return value, remove later
    master_ttfs = []
    for master in master_fonts:
        try:
            master_ttfs.append(master.reader.file.name)
        except AttributeError:
            master_ttfs.append(None)  # in-memory fonts have no path

    if drop_implied_oncurves and "glyf" in master_fonts[ds.base_idx]:
        drop_count = drop_implied_oncurve_points(*master_fonts)
        log.info(
            "Dropped %s on-curve points from simple glyphs in the 'glyf' table",
            drop_count,
        )

    # Copy the base master to work from it
    vf = deepcopy(master_fonts[ds.base_idx])

    if "DSIG" in vf:
        del vf["DSIG"]

    # TODO append masters as named-instances as well; needs .designspace change.
    fvar = _add_fvar(vf, ds.axes, ds.instances)
    if "STAT" not in exclude:
        _add_stat(vf)

    # Map from axis names to axis tags...
    normalized_master_locs = [
        {ds.axes[k].tag: v for k, v in loc.items()} for loc in ds.normalized_master_locs
    ]
    # From here on, we use fvar axes only
    axisTags = [axis.axisTag for axis in fvar.axes]

    # Assume single-model for now.
    model = models.VariationModel(normalized_master_locs, axisOrder=axisTags)
    assert 0 == model.mapping[ds.base_idx]

    log.info("Building variations tables")
    if "avar" not in exclude:
        _add_avar(vf, ds.axes, ds.axisMappings, axisTags)
    if "BASE" not in exclude and "BASE" in vf:
        _add_BASE(vf, model, master_fonts, axisTags)
    if "MVAR" not in exclude:
        _add_MVAR(vf, model, master_fonts, axisTags)
    if "HVAR" not in exclude:
        _add_HVAR(vf, model, master_fonts, axisTags)
    if "VVAR" not in exclude and "vmtx" in vf:
        _add_VVAR(vf, model, master_fonts, axisTags)
    if "GDEF" not in exclude or "GPOS" not in exclude:
        _merge_OTL(vf, model, master_fonts, axisTags)
    if "gvar" not in exclude and "glyf" in vf:
        _add_gvar(vf, model, master_fonts, optimize=optimize)
    if "cvar" not in exclude and "glyf" in vf:
        _merge_TTHinting(vf, model, master_fonts)
    if "GSUB" not in exclude and ds.rules:
        featureTags = _feature_variations_tags(ds)
        _add_GSUB_feature_variations(
            vf, ds.axes, ds.internal_axis_supports, ds.rules, featureTags
        )
    if "CFF2" not in exclude and ("CFF " in vf or "CFF2" in vf):
        _add_CFF2(vf, model, master_fonts)
        if "post" in vf:
            # set 'post' to format 2 to keep the glyph names dropped from CFF2
            post = vf["post"]
            if post.formatType != 2.0:
                post.formatType = 2.0
                post.extraNames = []
                post.mapping = {}
    if "COLR" not in exclude and "COLR" in vf and vf["COLR"].version > 0:
        _add_COLR(vf, model, master_fonts, axisTags, colr_layer_reuse)

    set_default_weight_width_slant(
        vf, location={axis.axisTag: axis.defaultValue for axis in vf["fvar"].axes}
    )

    for tag in exclude:
        if tag in vf:
            del vf[tag]

    # TODO: Only return vf for 4.0+, the rest is unused.
    return vf, model, master_ttfs


def _open_font(path, master_finder=lambda s: s):
    # load TTFont masters from given 'path': this can be either a .TTX or an
    # OpenType binary font; or if neither of these, try use the 'master_finder'
    # callable to resolve the path to a valid .TTX or OpenType font binary.
    from fontTools.ttx import guessFileType

    master_path = os.path.normpath(path)
    tp = guessFileType(master_path)
    if tp is None:
        # not an OpenType binary/ttx, fall back to the master finder.
        master_path = master_finder(master_path)
        tp = guessFileType(master_path)
    if tp in ("TTX", "OTX"):
        font = TTFont()
        font.importXML(master_path)
    elif tp in ("TTF", "OTF", "WOFF", "WOFF2"):
        font = TTFont(master_path)
    else:
        raise VarLibValidationError("Invalid master path: %r" % master_path)
    return font


def load_masters(designspace, master_finder=lambda s: s):
    """Ensure that all SourceDescriptor.font attributes have an appropriate TTFont
    object loaded, or else open TTFont objects from the SourceDescriptor.path
    attributes.

    The paths can point to either an OpenType font, a TTX file, or a UFO. In the
    latter case, use the provided master_finder callable to map from UFO paths to
    the respective master font binaries (e.g. .ttf, .otf or .ttx).

    Return list of master TTFont objects in the same order they are listed in the
    DesignSpaceDocument.
    """
    for master in designspace.sources:
        # If a SourceDescriptor has a layer name, demand that the compiled TTFont
        # be supplied by the caller. This spares us from modifying MasterFinder.
        if master.layerName and master.font is None:
            raise VarLibValidationError(
                f"Designspace source '{master.name or '<Unknown>'}' specified a "
                "layer name but lacks the required TTFont object in the 'font' "
                "attribute."
            )

    return designspace.loadSourceFonts(_open_font, master_finder=master_finder)


class MasterFinder(object):
    def __init__(self, template):
        self.template = template

    def __call__(self, src_path):
        fullname = os.path.abspath(src_path)
        dirname, basename = os.path.split(fullname)
        stem, ext = os.path.splitext(basename)
        path = self.template.format(
            fullname=fullname,
            dirname=dirname,
            basename=basename,
            stem=stem,
            ext=ext,
        )
        return os.path.normpath(path)


def _feature_variations_tags(ds):
    raw_tags = ds.lib.get(
        FEAVAR_FEATURETAG_LIB_KEY,
        "rclt" if ds.rulesProcessingLast else "rvrn",
    )
    return sorted({t.strip() for t in raw_tags.split(",")})


def addGSUBFeatureVariations(vf, designspace, featureTags=(), *, log_enabled=False):
    """Add GSUB FeatureVariations table to variable font, based on DesignSpace rules.

    Args:
        vf: A TTFont object representing the variable font.
        designspace: A DesignSpaceDocument object.
        featureTags: Optional feature tag(s) to use for the FeatureVariations records.
            If unset, the key 'com.github.fonttools.varLib.featureVarsFeatureTag' is
            looked up in the DS <lib> and used; otherwise the default is 'rclt' if
            the <rules processing="last"> attribute is set, else 'rvrn'.
            See <https://fonttools.readthedocs.io/en/latest/designspaceLib/xml.html#rules-element>
        log_enabled: If True, log info about DS axes and sources. Default is False, as
            the same info may have already been logged as part of varLib.build.
    """
    ds = load_designspace(designspace, log_enabled=log_enabled)
    if not ds.rules:
        return
    if not featureTags:
        featureTags = _feature_variations_tags(ds)
    _add_GSUB_feature_variations(
        vf, ds.axes, ds.internal_axis_supports, ds.rules, featureTags
    )


def main(args=None):
    """Build variable fonts from a designspace file and masters"""
    from argparse import ArgumentParser
    from fontTools import configLogger

    parser = ArgumentParser(prog="varLib", description=main.__doc__)
    parser.add_argument("designspace")
    output_group = parser.add_mutually_exclusive_group()
    output_group.add_argument(
        "-o", metavar="OUTPUTFILE", dest="outfile", default=None, help="output file"
    )
    output_group.add_argument(
        "-d",
        "--output-dir",
        metavar="OUTPUTDIR",
        default=None,
        help="output dir (default: same as input designspace file)",
    )
    parser.add_argument(
        "-x",
        metavar="TAG",
        dest="exclude",
        action="append",
        default=[],
        help="exclude table",
    )
    parser.add_argument(
        "--disable-iup",
        dest="optimize",
        action="store_false",
        help="do not perform IUP optimization",
    )
    parser.add_argument(
        "--no-colr-layer-reuse",
        dest="colr_layer_reuse",
        action="store_false",
        help="do not rebuild variable COLR table to optimize COLR layer reuse",
    )
    parser.add_argument(
        "--drop-implied-oncurves",
        action="store_true",
        help=(
            "drop on-curve points that can be implied when exactly in the middle of "
            "two off-curve points (only applies to TrueType fonts)"
        ),
    )
    parser.add_argument(
        "--master-finder",
        default="master_ttf_interpolatable/{stem}.ttf",
        help=(
            "templated string used for finding binary font "
            "files given the source file names defined in the "
            "designspace document. The following special strings "
            "are defined: {fullname} is the absolute source file "
            "name; {basename} is the file name without its "
            "directory; {stem} is the basename without the file "
            "extension; {ext} is the source file extension; "
            "{dirname} is the directory of the absolute file "
            'name. The default value is "%(default)s".'
        ),
    )
    parser.add_argument(
        "--variable-fonts",
        default=".*",
        metavar="VF_NAME",
        help=(
            "Filter the list of variable fonts produced from the input "
            "Designspace v5 file. By default all listed variable fonts are "
            "generated. To generate a specific variable font (or variable fonts) "
            'that match a given "name" attribute, you can pass as argument '
            "the full name or a regular expression. E.g.: --variable-fonts "
            '"MyFontVF_WeightOnly"; or --variable-fonts "MyFontVFItalic_.*".'
        ),
    )
    logging_group = parser.add_mutually_exclusive_group(required=False)
    logging_group.add_argument(
        "-v", "--verbose", action="store_true", help="Run more verbosely."
    )
    logging_group.add_argument(
        "-q", "--quiet", action="store_true", help="Turn verbosity off."
    )
    options = parser.parse_args(args)

    configLogger(
        level=("DEBUG" if options.verbose else "ERROR" if options.quiet else "INFO")
    )

    designspace_filename = options.designspace
    designspace = DesignSpaceDocument.fromfile(designspace_filename)

    vf_descriptors = designspace.getVariableFonts()
    if not vf_descriptors:
        parser.error(f"No variable fonts in given designspace {designspace.path!r}")

    vfs_to_build = []
    for vf in vf_descriptors:
        # Skip variable fonts that do not match the user's inclusion regex if given.
        if not fullmatch(options.variable_fonts, vf.name):
            continue
        vfs_to_build.append(vf)

    if not vfs_to_build:
        parser.error(f"No variable fonts matching {options.variable_fonts!r}")

    if options.outfile is not None and len(vfs_to_build) > 1:
        parser.error(
            "can't specify -o because there are multiple VFs to build; "
            "use --output-dir, or select a single VF with --variable-fonts"
        )

    output_dir = options.output_dir
    if output_dir is None:
        output_dir = os.path.dirname(designspace_filename)

    vf_name_to_output_path = {}
    if len(vfs_to_build) == 1 and options.outfile is not None:
        vf_name_to_output_path[vfs_to_build[0].name] = options.outfile
    else:
        for vf in vfs_to_build:
            filename = vf.filename if vf.filename is not None else vf.name + ".{ext}"
            vf_name_to_output_path[vf.name] = os.path.join(output_dir, filename)

    finder = MasterFinder(options.master_finder)

    vfs = build_many(
        designspace,
        finder,
        exclude=options.exclude,
        optimize=options.optimize,
        colr_layer_reuse=options.colr_layer_reuse,
        drop_implied_oncurves=options.drop_implied_oncurves,
    )

    for vf_name, vf in vfs.items():
        ext = "otf" if vf.sfntVersion == "OTTO" else "ttf"
        output_path = vf_name_to_output_path[vf_name].format(ext=ext)
        output_dir = os.path.dirname(output_path)
        if output_dir:
            os.makedirs(output_dir, exist_ok=True)
        log.info("Saving variation font %s", output_path)
        vf.save(output_path)


if __name__ == "__main__":
    import sys

    if len(sys.argv) > 1:
        sys.exit(main())
    import doctest

    sys.exit(doctest.testmod().failed)
