__all__ = ["FontBuilder"]

"""
This module is *experimental*, meaning it still may evolve and change.

The `FontBuilder` class is a convenient helper to construct working TTF or
OTF fonts from scratch.

Note that the various setup methods cannot be called in arbitrary order,
due to various interdependencies between OpenType tables. Here is an order
that works:

    fb = FontBuilder(...)
    fb.setupGlyphOrder(...)
    fb.setupCharacterMap(...)
    fb.setupGlyf(...) --or-- fb.setupCFF(...)
    fb.setupHorizontalMetrics(...)
    fb.setupHorizontalHeader()
    fb.setupNameTable(...)
    fb.setupOS2()
    fb.addOpenTypeFeatures(...)
    fb.setupPost()
    fb.save(...)

Here is how to build a minimal TTF:

```python
from fontTools.fontBuilder import FontBuilder
from fontTools.pens.ttGlyphPen import TTGlyphPen


def drawTestGlyph(pen):
    pen.moveTo((100, 100))
    pen.lineTo((100, 1000))
    pen.qCurveTo((200, 900), (400, 900), (500, 1000))
    pen.lineTo((500, 100))
    pen.closePath()


fb = FontBuilder(1024, isTTF=True)
fb.setupGlyphOrder([".notdef", ".null", "space", "A", "a"])
fb.setupCharacterMap({32: "space", 65: "A", 97: "a"})
advanceWidths = {".notdef": 600, "space": 500, "A": 600, "a": 600, ".null": 0}

familyName = "HelloTestFont"
styleName = "TotallyNormal"
version = "0.1"

nameStrings = dict(
    familyName=dict(en=familyName, nl="HalloTestFont"),
    styleName=dict(en=styleName, nl="TotaalNormaal"),
    uniqueFontIdentifier="fontBuilder: " + familyName + "." + styleName,
    fullName=familyName + "-" + styleName,
    psName=familyName + "-" + styleName,
    version="Version " + version,
)

pen = TTGlyphPen(None)
drawTestGlyph(pen)
glyph = pen.glyph()
glyphs = {".notdef": glyph, "space": glyph, "A": glyph, "a": glyph, ".null": glyph}
fb.setupGlyf(glyphs)
metrics = {}
glyphTable = fb.font["glyf"]
for gn, advanceWidth in advanceWidths.items():
    metrics[gn] = (advanceWidth, glyphTable[gn].xMin)
fb.setupHorizontalMetrics(metrics)
fb.setupHorizontalHeader(ascent=824, descent=-200)
fb.setupNameTable(nameStrings)
fb.setupOS2(sTypoAscender=824, usWinAscent=824, usWinDescent=200)
fb.setupPost()
fb.save("test.ttf")
```

And here's how to build a minimal OTF:

```python
from fontTools.fontBuilder import FontBuilder
from fontTools.pens.t2CharStringPen import T2CharStringPen


def drawTestGlyph(pen):
    pen.moveTo((100, 100))
    pen.lineTo((100, 1000))
    pen.curveTo((200, 900), (400, 900), (500, 1000))
    pen.lineTo((500, 100))
    pen.closePath()


fb = FontBuilder(1024, isTTF=False)
fb.setupGlyphOrder([".notdef", ".null", "space", "A", "a"])
fb.setupCharacterMap({32: "space", 65: "A", 97: "a"})
advanceWidths = {".notdef": 600, "space": 500, "A": 600, "a": 600, ".null": 0}

familyName = "HelloTestFont"
styleName = "TotallyNormal"
version = "0.1"

nameStrings = dict(
    familyName=dict(en=familyName, nl="HalloTestFont"),
    styleName=dict(en=styleName, nl="TotaalNormaal"),
    uniqueFontIdentifier="fontBuilder: " + familyName + "." + styleName,
    fullName=familyName + "-" + styleName,
    psName=familyName + "-" + styleName,
    version="Version " + version,
)

pen = T2CharStringPen(600, None)
drawTestGlyph(pen)
charString = pen.getCharString()
charStrings = {
    ".notdef": charString,
    "space": charString,
    "A": charString,
    "a": charString,
    ".null": charString,
}
fb.setupCFF(nameStrings["psName"], {"FullName": nameStrings["psName"]}, charStrings, {})
lsb = {gn: cs.calcBounds(None)[0] for gn, cs in charStrings.items()}
metrics = {}
for gn, advanceWidth in advanceWidths.items():
    metrics[gn] = (advanceWidth, lsb[gn])
fb.setupHorizontalMetrics(metrics)
fb.setupHorizontalHeader(ascent=824, descent=200)
fb.setupNameTable(nameStrings)
fb.setupOS2(sTypoAscender=824, usWinAscent=824, usWinDescent=200)
fb.setupPost()
fb.save("test.otf")
```
"""

from .ttLib import TTFont, newTable
from .ttLib.tables._c_m_a_p import cmap_classes
from .misc.timeTools import timestampNow
import struct
from collections import OrderedDict


_headDefaults = dict(
    tableVersion=1.0,
    fontRevision=1.0,
    checkSumAdjustment=0,
    magicNumber=0x5F0F3CF5,
    flags=0x0003,
    unitsPerEm=1000,
    created=0,
    modified=0,
    xMin=0,
    yMin=0,
    xMax=0,
    yMax=0,
    macStyle=0,
    lowestRecPPEM=3,
    fontDirectionHint=2,
    indexToLocFormat=0,
    glyphDataFormat=0,
)

_maxpDefaultsTTF = dict(
    tableVersion=0x00010000,
    numGlyphs=0,
    maxPoints=0,
    maxContours=0,
    maxCompositePoints=0,
    maxCompositeContours=0,
    maxZones=2,
    maxTwilightPoints=0,
    maxStorage=0,
    maxFunctionDefs=0,
    maxInstructionDefs=0,
    maxStackElements=0,
    maxSizeOfInstructions=0,
    maxComponentElements=0,
    maxComponentDepth=0,
)
_maxpDefaultsOTF = dict(
    tableVersion=0x00005000,
    numGlyphs=0,
)

_postDefaults = dict(
    formatType=3.0,
    italicAngle=0,
    underlinePosition=0,
    underlineThickness=0,
    isFixedPitch=0,
    minMemType42=0,
    maxMemType42=0,
    minMemType1=0,
    maxMemType1=0,
)

_hheaDefaults = dict(
    tableVersion=0x00010000,
    ascent=0,
    descent=0,
    lineGap=0,
    advanceWidthMax=0,
    minLeftSideBearing=0,
    minRightSideBearing=0,
    xMaxExtent=0,
    caretSlopeRise=1,
    caretSlopeRun=0,
    caretOffset=0,
    reserved0=0,
    reserved1=0,
    reserved2=0,
    reserved3=0,
    metricDataFormat=0,
    numberOfHMetrics=0,
)

_vheaDefaults = dict(
    tableVersion=0x00010000,
    ascent=0,
    descent=0,
    lineGap=0,
    advanceHeightMax=0,
    minTopSideBearing=0,
    minBottomSideBearing=0,
    yMaxExtent=0,
    caretSlopeRise=0,
    caretSlopeRun=0,
    reserved0=0,
    reserved1=0,
    reserved2=0,
    reserved3=0,
    reserved4=0,
    metricDataFormat=0,
    numberOfVMetrics=0,
)

_nameIDs = dict(
    copyright=0,
    familyName=1,
    styleName=2,
    uniqueFontIdentifier=3,
    fullName=4,
    version=5,
    psName=6,
    trademark=7,
    manufacturer=8,
    designer=9,
    description=10,
    vendorURL=11,
    designerURL=12,
    licenseDescription=13,
    licenseInfoURL=14,
    # reserved = 15,
    typographicFamily=16,
    typographicSubfamily=17,
    compatibleFullName=18,
    sampleText=19,
    postScriptCIDFindfontName=20,
    wwsFamilyName=21,
    wwsSubfamilyName=22,
    lightBackgroundPalette=23,
    darkBackgroundPalette=24,
    variationsPostScriptNamePrefix=25,
)

# to insert in setupNameTable doc string:
# print("\n".join(("%s (nameID %s)" % (k, v)) for k, v in sorted(_nameIDs.items(), key=lambda x: x[1])))

_panoseDefaults = dict(
    bFamilyType=0,
    bSerifStyle=0,
    bWeight=0,
    bProportion=0,
    bContrast=0,
    bStrokeVariation=0,
    bArmStyle=0,
    bLetterForm=0,
    bMidline=0,
    bXHeight=0,
)

_OS2Defaults = dict(
    version=3,
    xAvgCharWidth=0,
    usWeightClass=400,
    usWidthClass=5,
    fsType=0x0004,  # default: Preview & Print embedding
    ySubscriptXSize=0,
    ySubscriptYSize=0,
    ySubscriptXOffset=0,
    ySubscriptYOffset=0,
    ySuperscriptXSize=0,
    ySuperscriptYSize=0,
    ySuperscriptXOffset=0,
    ySuperscriptYOffset=0,
    yStrikeoutSize=0,
    yStrikeoutPosition=0,
    sFamilyClass=0,
    panose=_panoseDefaults,
    ulUnicodeRange1=0,
    ulUnicodeRange2=0,
    ulUnicodeRange3=0,
    ulUnicodeRange4=0,
    achVendID="????",
    fsSelection=0,
    usFirstCharIndex=0,
    usLastCharIndex=0,
    sTypoAscender=0,
    sTypoDescender=0,
    sTypoLineGap=0,
    usWinAscent=0,
    usWinDescent=0,
    ulCodePageRange1=0,
    ulCodePageRange2=0,
    sxHeight=0,
    sCapHeight=0,
    usDefaultChar=0,  # .notdef
    usBreakChar=32,  # space
    usMaxContext=0,
    usLowerOpticalPointSize=0,
    usUpperOpticalPointSize=0,
)


class FontBuilder(object):
    def __init__(self, unitsPerEm=None, font=None, isTTF=True):
        """Initialize a FontBuilder instance.

        If the `font` argument is not given, a new `TTFont` will be
        constructed, and `unitsPerEm` must be given. If `isTTF` is True,
        the font will be a glyf-based TTF; if `isTTF` is False it will be
        a CFF-based OTF.

        If `font` is given, it must be a `TTFont` instance and `unitsPerEm`
        must _not_ be given. The `isTTF` argument will be ignored.
        """
        if font is None:
            self.font = TTFont(recalcTimestamp=False)
            self.isTTF = isTTF
            now = timestampNow()
            assert unitsPerEm is not None
            self.setupHead(unitsPerEm=unitsPerEm, created=now, modified=now)
            self.setupMaxp()
        else:
            assert unitsPerEm is None
            self.font = font
            self.isTTF = "glyf" in font

    def save(self, file):
        """Save the font. The 'file' argument can be either a pathname or a
        writable file object.
        """
        self.font.save(file)

    def _initTableWithValues(self, tableTag, defaults, values):
        table = self.font[tableTag] = newTable(tableTag)
        for k, v in defaults.items():
            setattr(table, k, v)
        for k, v in values.items():
            setattr(table, k, v)
        return table

    def _updateTableWithValues(self, tableTag, values):
        table = self.font[tableTag]
        for k, v in values.items():
            setattr(table, k, v)

    def setupHead(self, **values):
        """Create a new `head` table and initialize it with default values,
        which can be overridden by keyword arguments.
        """
        self._initTableWithValues("head", _headDefaults, values)

    def updateHead(self, **values):
        """Update the head table with the fields and values passed as
        keyword arguments.
        """
        self._updateTableWithValues("head", values)

    def setupGlyphOrder(self, glyphOrder):
        """Set the glyph order for the font."""
        self.font.setGlyphOrder(glyphOrder)

    def setupCharacterMap(self, cmapping, uvs=None, allowFallback=False):
        """Build the `cmap` table for the font. The `cmapping` argument should
        be a dict mapping unicode code points as integers to glyph names.

        The `uvs` argument, when passed, must be a list of tuples, describing
        Unicode Variation Sequences. These tuples have three elements:
            (unicodeValue, variationSelector, glyphName)
        `unicodeValue` and `variationSelector` are integer code points.
        `glyphName` may be None, to indicate this is the default variation.
        Text processors will then use the cmap to find the glyph name.
        Each Unicode Variation Sequence should be an officially supported
        sequence, but this is not policed.
        """
        subTables = []
        highestUnicode = max(cmapping)
        if highestUnicode > 0xFFFF:
            cmapping_3_1 = dict((k, v) for k, v in cmapping.items() if k < 0x10000)
            subTable_3_10 = buildCmapSubTable(cmapping, 12, 3, 10)
            subTables.append(subTable_3_10)
        else:
            cmapping_3_1 = cmapping
        format = 4
        subTable_3_1 = buildCmapSubTable(cmapping_3_1, format, 3, 1)
        try:
            subTable_3_1.compile(self.font)
        except struct.error:
            # format 4 overflowed, fall back to format 12
            if not allowFallback:
                raise ValueError(
                    "cmap format 4 subtable overflowed; sort glyph order by unicode to fix."
                )
            format = 12
            subTable_3_1 = buildCmapSubTable(cmapping_3_1, format, 3, 1)
        subTables.append(subTable_3_1)
        subTable_0_3 = buildCmapSubTable(cmapping_3_1, format, 0, 3)
        subTables.append(subTable_0_3)

        if uvs is not None:
            uvsDict = {}
            for unicodeValue, variationSelector, glyphName in uvs:
                if cmapping.get(unicodeValue) == glyphName:
                    # this is a default variation
                    glyphName = None
                if variationSelector not in uvsDict:
                    uvsDict[variationSelector] = []
                uvsDict[variationSelector].append((unicodeValue, glyphName))
            uvsSubTable = buildCmapSubTable({}, 14, 0, 5)
            uvsSubTable.uvsDict = uvsDict
            subTables.append(uvsSubTable)

        self.font["cmap"] = newTable("cmap")
        self.font["cmap"].tableVersion = 0
        self.font["cmap"].tables = subTables

    def setupNameTable(self, nameStrings, windows=True, mac=True):
        """Create the `name` table for the font. The `nameStrings` argument must
        be a dict, mapping nameIDs or descriptive names for the nameIDs to name
        record values. A value is either a string, or a dict, mapping language codes
        to strings, to allow localized name table entries.

        By default, both Windows (platformID=3) and Macintosh (platformID=1) name
        records are added, unless any of `windows` or `mac` arguments is False.

        The following descriptive names are available for nameIDs:

            copyright (nameID 0)
            familyName (nameID 1)
            styleName (nameID 2)
            uniqueFontIdentifier (nameID 3)
            fullName (nameID 4)
            version (nameID 5)
            psName (nameID 6)
            trademark (nameID 7)
            manufacturer (nameID 8)
            designer (nameID 9)
            description (nameID 10)
            vendorURL (nameID 11)
            designerURL (nameID 12)
            licenseDescription (nameID 13)
            licenseInfoURL (nameID 14)
            typographicFamily (nameID 16)
            typographicSubfamily (nameID 17)
            compatibleFullName (nameID 18)
            sampleText (nameID 19)
            postScriptCIDFindfontName (nameID 20)
            wwsFamilyName (nameID 21)
            wwsSubfamilyName (nameID 22)
            lightBackgroundPalette (nameID 23)
            darkBackgroundPalette (nameID 24)
            variationsPostScriptNamePrefix (nameID 25)
        """
        nameTable = self.font["name"] = newTable("name")
        nameTable.names = []

        for nameName, nameValue in nameStrings.items():
            if isinstance(nameName, int):
                nameID = nameName
            else:
                nameID = _nameIDs[nameName]
            if isinstance(nameValue, str):
                nameValue = dict(en=nameValue)
            nameTable.addMultilingualName(
                nameValue, ttFont=self.font, nameID=nameID, windows=windows, mac=mac
            )

    def setupOS2(self, **values):
        """Create a new `OS/2` table and initialize it with default values,
        which can be overridden by keyword arguments.
        """
        if "xAvgCharWidth" not in values:
            gs = self.font.getGlyphSet()
            widths = [
                gs[glyphName].width
                for glyphName in gs.keys()
                if gs[glyphName].width > 0
            ]
            values["xAvgCharWidth"] = int(round(sum(widths) / float(len(widths))))
        self._initTableWithValues("OS/2", _OS2Defaults, values)
        if not (
            "ulUnicodeRange1" in values
            or "ulUnicodeRange2" in values
            or "ulUnicodeRange3" in values
            or "ulUnicodeRange3" in values
        ):
            assert (
                "cmap" in self.font
            ), "the 'cmap' table must be setup before the 'OS/2' table"
            self.font["OS/2"].recalcUnicodeRanges(self.font)

    def setupCFF(self, psName, fontInfo, charStringsDict, privateDict):
        from .cffLib import (
            CFFFontSet,
            TopDictIndex,
            TopDict,
            CharStrings,
            GlobalSubrsIndex,
            PrivateDict,
        )

        assert not self.isTTF
        self.font.sfntVersion = "OTTO"
        fontSet = CFFFontSet()
        fontSet.major = 1
        fontSet.minor = 0
        fontSet.otFont = self.font
        fontSet.fontNames = [psName]
        fontSet.topDictIndex = TopDictIndex()

        globalSubrs = GlobalSubrsIndex()
        fontSet.GlobalSubrs = globalSubrs
        private = PrivateDict()
        for key, value in privateDict.items():
            setattr(private, key, value)
        fdSelect = None
        fdArray = None

        topDict = TopDict()
        topDict.charset = self.font.getGlyphOrder()
        topDict.Private = private
        topDict.GlobalSubrs = fontSet.GlobalSubrs
        for key, value in fontInfo.items():
            setattr(topDict, key, value)
        if "FontMatrix" not in fontInfo:
            scale = 1 / self.font["head"].unitsPerEm
            topDict.FontMatrix = [scale, 0, 0, scale, 0, 0]

        charStrings = CharStrings(
            None, topDict.charset, globalSubrs, private, fdSelect, fdArray
        )
        for glyphName, charString in charStringsDict.items():
            charString.private = private
            charString.globalSubrs = globalSubrs
            charStrings[glyphName] = charString
        topDict.CharStrings = charStrings

        fontSet.topDictIndex.append(topDict)

        self.font["CFF "] = newTable("CFF ")
        self.font["CFF "].cff = fontSet

    def setupCFF2(self, charStringsDict, fdArrayList=None, regions=None):
        from .cffLib import (
            CFFFontSet,
            TopDictIndex,
            TopDict,
            CharStrings,
            GlobalSubrsIndex,
            PrivateDict,
            FDArrayIndex,
            FontDict,
        )

        assert not self.isTTF
        self.font.sfntVersion = "OTTO"
        fontSet = CFFFontSet()
        fontSet.major = 2
        fontSet.minor = 0

        cff2GetGlyphOrder = self.font.getGlyphOrder
        fontSet.topDictIndex = TopDictIndex(None, cff2GetGlyphOrder, None)

        globalSubrs = GlobalSubrsIndex()
        fontSet.GlobalSubrs = globalSubrs

        if fdArrayList is None:
            fdArrayList = [{}]
        fdSelect = None
        fdArray = FDArrayIndex()
        fdArray.strings = None
        fdArray.GlobalSubrs = globalSubrs
        for privateDict in fdArrayList:
            fontDict = FontDict()
            fontDict.setCFF2(True)
            private = PrivateDict()
            for key, value in privateDict.items():
                setattr(private, key, value)
            fontDict.Private = private
            fdArray.append(fontDict)

        topDict = TopDict()
        topDict.cff2GetGlyphOrder = cff2GetGlyphOrder
        topDict.FDArray = fdArray
        scale = 1 / self.font["head"].unitsPerEm
        topDict.FontMatrix = [scale, 0, 0, scale, 0, 0]

        private = fdArray[0].Private
        charStrings = CharStrings(None, None, globalSubrs, private, fdSelect, fdArray)
        for glyphName, charString in charStringsDict.items():
            charString.private = private
            charString.globalSubrs = globalSubrs
            charStrings[glyphName] = charString
        topDict.CharStrings = charStrings

        fontSet.topDictIndex.append(topDict)

        self.font["CFF2"] = newTable("CFF2")
        self.font["CFF2"].cff = fontSet

        if regions:
            self.setupCFF2Regions(regions)

    def setupCFF2Regions(self, regions):
        from .varLib.builder import buildVarRegionList, buildVarData, buildVarStore
        from .cffLib import VarStoreData

        assert "fvar" in self.font, "fvar must to be set up first"
        assert "CFF2" in self.font, "CFF2 must to be set up first"
        axisTags = [a.axisTag for a in self.font["fvar"].axes]
        varRegionList = buildVarRegionList(regions, axisTags)
        varData = buildVarData(list(range(len(regions))), None, optimize=False)
        varStore = buildVarStore(varRegionList, [varData])
        vstore = VarStoreData(otVarStore=varStore)
        topDict = self.font["CFF2"].cff.topDictIndex[0]
        topDict.VarStore = vstore
        for fontDict in topDict.FDArray:
            fontDict.Private.vstore = vstore

    def setupGlyf(self, glyphs, calcGlyphBounds=True):
        """Create the `glyf` table from a dict, that maps glyph names
        to `fontTools.ttLib.tables._g_l_y_f.Glyph` objects, for example
        as made by `fontTools.pens.ttGlyphPen.TTGlyphPen`.

        If `calcGlyphBounds` is True, the bounds of all glyphs will be
        calculated. Only pass False if your glyph objects already have
        their bounding box values set.
        """
        assert self.isTTF
        self.font["loca"] = newTable("loca")
        self.font["glyf"] = newTable("glyf")
        self.font["glyf"].glyphs = glyphs
        if hasattr(self.font, "glyphOrder"):
            self.font["glyf"].glyphOrder = self.font.glyphOrder
        if calcGlyphBounds:
            self.calcGlyphBounds()

    def setupFvar(self, axes, instances):
        """Adds an font variations table to the font.

        Args:
            axes (list): See below.
            instances (list): See below.

        ``axes`` should be a list of axes, with each axis either supplied as
        a py:class:`.designspaceLib.AxisDescriptor` object, or a tuple in the
        format ```tupletag, minValue, defaultValue, maxValue, name``.
        The ``name`` is either a string, or a dict, mapping language codes
        to strings, to allow localized name table entries.

        ```instances`` should be a list of instances, with each instance either
        supplied as a py:class:`.designspaceLib.InstanceDescriptor` object, or a
        dict with keys ``location`` (mapping of axis tags to float values),
        ``stylename`` and (optionally) ``postscriptfontname``.
        The ``stylename`` is either a string, or a dict, mapping language codes
        to strings, to allow localized name table entries.
        """

        addFvar(self.font, axes, instances)

    def setupAvar(self, axes):
        """Adds an axis variations table to the font.

        Args:
            axes (list): A list of py:class:`.designspaceLib.AxisDescriptor` objects.
        """
        from .varLib import _add_avar

        _add_avar(self.font, OrderedDict(enumerate(axes)))  # Only values are used

    def setupGvar(self, variations):
        gvar = self.font["gvar"] = newTable("gvar")
        gvar.version = 1
        gvar.reserved = 0
        gvar.variations = variations

    def calcGlyphBounds(self):
        """Calculate the bounding boxes of all glyphs in the `glyf` table.
        This is usually not called explicitly by client code.
        """
        glyphTable = self.font["glyf"]
        for glyph in glyphTable.glyphs.values():
            glyph.recalcBounds(glyphTable)

    def setupHorizontalMetrics(self, metrics):
        """Create a new `hmtx` table, for horizontal metrics.

        The `metrics` argument must be a dict, mapping glyph names to
        `(width, leftSidebearing)` tuples.
        """
        self.setupMetrics("hmtx", metrics)

    def setupVerticalMetrics(self, metrics):
        """Create a new `vmtx` table, for horizontal metrics.

        The `metrics` argument must be a dict, mapping glyph names to
        `(height, topSidebearing)` tuples.
        """
        self.setupMetrics("vmtx", metrics)

    def setupMetrics(self, tableTag, metrics):
        """See `setupHorizontalMetrics()` and `setupVerticalMetrics()`."""
        assert tableTag in ("hmtx", "vmtx")
        mtxTable = self.font[tableTag] = newTable(tableTag)
        roundedMetrics = {}
        for gn in metrics:
            w, lsb = metrics[gn]
            roundedMetrics[gn] = int(round(w)), int(round(lsb))
        mtxTable.metrics = roundedMetrics

    def setupHorizontalHeader(self, **values):
        """Create a new `hhea` table initialize it with default values,
        which can be overridden by keyword arguments.
        """
        self._initTableWithValues("hhea", _hheaDefaults, values)

    def setupVerticalHeader(self, **values):
        """Create a new `vhea` table initialize it with default values,
        which can be overridden by keyword arguments.
        """
        self._initTableWithValues("vhea", _vheaDefaults, values)

    def setupVerticalOrigins(self, verticalOrigins, defaultVerticalOrigin=None):
        """Create a new `VORG` table. The `verticalOrigins` argument must be
        a dict, mapping glyph names to vertical origin values.

        The `defaultVerticalOrigin` argument should be the most common vertical
        origin value. If omitted, this value will be derived from the actual
        values in the `verticalOrigins` argument.
        """
        if defaultVerticalOrigin is None:
            # find the most frequent vorg value
            bag = {}
            for gn in verticalOrigins:
                vorg = verticalOrigins[gn]
                if vorg not in bag:
                    bag[vorg] = 1
                else:
                    bag[vorg] += 1
            defaultVerticalOrigin = sorted(
                bag, key=lambda vorg: bag[vorg], reverse=True
            )[0]
        self._initTableWithValues(
            "VORG",
            {},
            dict(VOriginRecords={}, defaultVertOriginY=defaultVerticalOrigin),
        )
        vorgTable = self.font["VORG"]
        vorgTable.majorVersion = 1
        vorgTable.minorVersion = 0
        for gn in verticalOrigins:
            vorgTable[gn] = verticalOrigins[gn]

    def setupPost(self, keepGlyphNames=True, **values):
        """Create a new `post` table and initialize it with default values,
        which can be overridden by keyword arguments.
        """
        isCFF2 = "CFF2" in self.font
        postTable = self._initTableWithValues("post", _postDefaults, values)
        if (self.isTTF or isCFF2) and keepGlyphNames:
            postTable.formatType = 2.0
            postTable.extraNames = []
            postTable.mapping = {}
        else:
            postTable.formatType = 3.0

    def setupMaxp(self):
        """Create a new `maxp` table. This is called implicitly by FontBuilder
        itself and is usually not called by client code.
        """
        if self.isTTF:
            defaults = _maxpDefaultsTTF
        else:
            defaults = _maxpDefaultsOTF
        self._initTableWithValues("maxp", defaults, {})

    def setupDummyDSIG(self):
        """This adds an empty DSIG table to the font to make some MS applications
        happy. This does not properly sign the font.
        """
        values = dict(
            ulVersion=1,
            usFlag=0,
            usNumSigs=0,
            signatureRecords=[],
        )
        self._initTableWithValues("DSIG", {}, values)

    def addOpenTypeFeatures(self, features, filename=None, tables=None):
        """Add OpenType features to the font from a string containing
        Feature File syntax.

        The `filename` argument is used in error messages and to determine
        where to look for "include" files.

        The optional `tables` argument can be a list of OTL tables tags to
        build, allowing the caller to only build selected OTL tables. See
        `fontTools.feaLib` for details.
        """
        from .feaLib.builder import addOpenTypeFeaturesFromString

        addOpenTypeFeaturesFromString(
            self.font, features, filename=filename, tables=tables
        )

    def addFeatureVariations(self, conditionalSubstitutions, featureTag="rvrn"):
        """Add conditional substitutions to a Variable Font.

        See `fontTools.varLib.featureVars.addFeatureVariations`.
        """
        from .varLib import featureVars

        if "fvar" not in self.font:
            raise KeyError("'fvar' table is missing; can't add FeatureVariations.")

        featureVars.addFeatureVariations(
            self.font, conditionalSubstitutions, featureTag=featureTag
        )

    def setupCOLR(
        self,
        colorLayers,
        version=None,
        varStore=None,
        varIndexMap=None,
        clipBoxes=None,
    ):
        """Build new COLR table using color layers dictionary.

        Cf. `fontTools.colorLib.builder.buildCOLR`.
        """
        from fontTools.colorLib.builder import buildCOLR

        glyphMap = self.font.getReverseGlyphMap()
        self.font["COLR"] = buildCOLR(
            colorLayers,
            version=version,
            glyphMap=glyphMap,
            varStore=varStore,
            varIndexMap=varIndexMap,
            clipBoxes=clipBoxes,
        )

    def setupCPAL(
        self,
        palettes,
        paletteTypes=None,
        paletteLabels=None,
        paletteEntryLabels=None,
    ):
        """Build new CPAL table using list of palettes.

        Optionally build CPAL v1 table using paletteTypes, paletteLabels and
        paletteEntryLabels.

        Cf. `fontTools.colorLib.builder.buildCPAL`.
        """
        from fontTools.colorLib.builder import buildCPAL

        self.font["CPAL"] = buildCPAL(
            palettes,
            paletteTypes=paletteTypes,
            paletteLabels=paletteLabels,
            paletteEntryLabels=paletteEntryLabels,
            nameTable=self.font.get("name"),
        )

    def setupStat(self, axes, locations=None, elidedFallbackName=2):
        """Build a new 'STAT' table.

        See `fontTools.otlLib.builder.buildStatTable` for details about
        the arguments.
        """
        from .otlLib.builder import buildStatTable

        buildStatTable(self.font, axes, locations, elidedFallbackName)


def buildCmapSubTable(cmapping, format, platformID, platEncID):
    subTable = cmap_classes[format](format)
    subTable.cmap = cmapping
    subTable.platformID = platformID
    subTable.platEncID = platEncID
    subTable.language = 0
    return subTable


def addFvar(font, axes, instances):
    from .ttLib.tables._f_v_a_r import Axis, NamedInstance

    assert axes

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

    for axis_def in axes:
        axis = Axis()

        if isinstance(axis_def, tuple):
            (
                axis.axisTag,
                axis.minValue,
                axis.defaultValue,
                axis.maxValue,
                name,
            ) = axis_def
        else:
            (axis.axisTag, axis.minValue, axis.defaultValue, axis.maxValue, name) = (
                axis_def.tag,
                axis_def.minimum,
                axis_def.default,
                axis_def.maximum,
                axis_def.name,
            )

        if isinstance(name, str):
            name = dict(en=name)

        axis.axisNameID = nameTable.addMultilingualName(name, ttFont=font)
        fvar.axes.append(axis)

    for instance in instances:
        if isinstance(instance, dict):
            coordinates = instance["location"]
            name = instance["stylename"]
            psname = instance.get("postscriptfontname")
        else:
            coordinates = instance.location
            name = instance.localisedStyleName or instance.styleName
            psname = instance.postScriptFontName

        if isinstance(name, str):
            name = dict(en=name)

        inst = NamedInstance()
        inst.subfamilyNameID = nameTable.addMultilingualName(name, ttFont=font)
        if psname is not None:
            inst.postscriptNameID = nameTable.addName(psname)
        inst.coordinates = coordinates
        fvar.instances.append(inst)

    font["fvar"] = fvar
