from __future__ import print_function, division, absolute_import
from __future__ import unicode_literals

__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", "A", "a"])
fb.setupCharacterMap({65: "A", 97: "a"})

advanceWidths = {".notdef": 600, "A": 600, "a": 600, ".null": 600}

familyName = "HelloTestFont"
styleName = "TotallyNormal"
nameStrings = dict(familyName=dict(en="HelloTestFont", nl="HalloTestFont"),
                   styleName=dict(en="TotallyNormal", nl="TotaalNormaal"))
nameStrings['psName'] = familyName + "-" + styleName

pen = TTGlyphPen(None)
drawTestGlyph(pen)
glyph = pen.glyph()
glyphs = {".notdef": 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()
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", "A", "a"])
fb.setupCharacterMap({65: "A", 97: "a"})

advanceWidths = {".notdef": 600, "A": 600, "a": 600, ".null": 600}

familyName = "HelloTestFont"
styleName = "TotallyNormal"
nameStrings = dict(familyName=dict(en="HelloTestFont", nl="HalloTestFont"),
                   styleName=dict(en="TotallyNormal", nl="TotaalNormaal"))
nameStrings['psName'] = familyName + "-" + styleName

pen = T2CharStringPen(600, None)
drawTestGlyph(pen)
charString = pen.getCharString()
charStrings = {".notdef": 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()
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.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
        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)
        self.font["CFF2"].cff.topDictIndex[0].VarStore = 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 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
