
__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 .misc.py23 import *
from .ttLib import TTFont, newTable
from .ttLib.tables._c_m_a_p import cmap_classes
from .ttLib.tables._n_a_m_e import NameRecord, makeName
from .misc.timeTools import timestampNow
import struct


_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, basestring):
                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):
        addFvar(self.font, axes, instances)

    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):
        """Build new COLR table using color layers dictionary.

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

        self.font["COLR"] = buildCOLR(colorLayers)

    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 .misc.py23 import Tag, tounicode
    from .ttLib.tables._f_v_a_r import Axis, NamedInstance

    assert axes

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

    for tag, minValue, defaultValue, maxValue, name in axes:
        axis = Axis()
        axis.axisTag = Tag(tag)
        axis.minValue, axis.defaultValue, axis.maxValue = minValue, defaultValue, maxValue
        axis.axisNameID = nameTable.addName(tounicode(name))
        fvar.axes.append(axis)

    for instance in instances:
        coordinates = instance['location']
        name = tounicode(instance['stylename'])
        psname = instance.get('postscriptfontname')

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

    font['fvar'] = fvar
