Reformat with black for ease of further maintenance
This commit is contained in:
parent
4a8617fc92
commit
04f04474fd
@ -1,4 +1,3 @@
|
||||
|
||||
__all__ = ["FontBuilder"]
|
||||
|
||||
"""
|
||||
@ -140,189 +139,188 @@ 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,
|
||||
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,
|
||||
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,
|
||||
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,
|
||||
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,
|
||||
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,
|
||||
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,
|
||||
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,
|
||||
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,
|
||||
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.
|
||||
|
||||
@ -396,7 +394,7 @@ class FontBuilder(object):
|
||||
"""
|
||||
subTables = []
|
||||
highestUnicode = max(cmapping)
|
||||
if highestUnicode > 0xffff:
|
||||
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)
|
||||
@ -409,7 +407,9 @@ class FontBuilder(object):
|
||||
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.")
|
||||
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)
|
||||
@ -490,17 +490,33 @@ class FontBuilder(object):
|
||||
"""
|
||||
if "xAvgCharWidth" not in values:
|
||||
gs = self.font.getGlyphSet()
|
||||
widths = [gs[glyphName].width for glyphName in gs.keys() if gs[glyphName].width > 0]
|
||||
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"
|
||||
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
|
||||
from .cffLib import (
|
||||
CFFFontSet,
|
||||
TopDictIndex,
|
||||
TopDict,
|
||||
CharStrings,
|
||||
GlobalSubrsIndex,
|
||||
PrivateDict,
|
||||
)
|
||||
|
||||
assert not self.isTTF
|
||||
self.font.sfntVersion = "OTTO"
|
||||
@ -529,7 +545,9 @@ class FontBuilder(object):
|
||||
scale = 1 / self.font["head"].unitsPerEm
|
||||
topDict.FontMatrix = [scale, 0, 0, scale, 0, 0]
|
||||
|
||||
charStrings = CharStrings(None, topDict.charset, globalSubrs, private, fdSelect, fdArray)
|
||||
charStrings = CharStrings(
|
||||
None, topDict.charset, globalSubrs, private, fdSelect, fdArray
|
||||
)
|
||||
for glyphName, charString in charStringsDict.items():
|
||||
charString.private = private
|
||||
charString.globalSubrs = globalSubrs
|
||||
@ -542,8 +560,16 @@ class FontBuilder(object):
|
||||
self.font["CFF "].cff = fontSet
|
||||
|
||||
def setupCFF2(self, charStringsDict, fdArrayList=None, regions=None):
|
||||
from .cffLib import CFFFontSet, TopDictIndex, TopDict, CharStrings, \
|
||||
GlobalSubrsIndex, PrivateDict, FDArrayIndex, FontDict
|
||||
from .cffLib import (
|
||||
CFFFontSet,
|
||||
TopDictIndex,
|
||||
TopDict,
|
||||
CharStrings,
|
||||
GlobalSubrsIndex,
|
||||
PrivateDict,
|
||||
FDArrayIndex,
|
||||
FontDict,
|
||||
)
|
||||
|
||||
assert not self.isTTF
|
||||
self.font.sfntVersion = "OTTO"
|
||||
@ -659,7 +685,7 @@ class FontBuilder(object):
|
||||
_add_avar(self.font, OrderedDict(enumerate(axes))) # Only values are used
|
||||
|
||||
def setupGvar(self, variations):
|
||||
gvar = self.font["gvar"] = newTable('gvar')
|
||||
gvar = self.font["gvar"] = newTable("gvar")
|
||||
gvar.version = 1
|
||||
gvar.reserved = 0
|
||||
gvar.variations = variations
|
||||
@ -678,7 +704,7 @@ class FontBuilder(object):
|
||||
The `metrics` argument must be a dict, mapping glyph names to
|
||||
`(width, leftSidebearing)` tuples.
|
||||
"""
|
||||
self.setupMetrics('hmtx', metrics)
|
||||
self.setupMetrics("hmtx", metrics)
|
||||
|
||||
def setupVerticalMetrics(self, metrics):
|
||||
"""Create a new `vmtx` table, for horizontal metrics.
|
||||
@ -686,7 +712,7 @@ class FontBuilder(object):
|
||||
The `metrics` argument must be a dict, mapping glyph names to
|
||||
`(height, topSidebearing)` tuples.
|
||||
"""
|
||||
self.setupMetrics('vmtx', metrics)
|
||||
self.setupMetrics("vmtx", metrics)
|
||||
|
||||
def setupMetrics(self, tableTag, metrics):
|
||||
"""See `setupHorizontalMetrics()` and `setupVerticalMetrics()`."""
|
||||
@ -727,8 +753,14 @@ class FontBuilder(object):
|
||||
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))
|
||||
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
|
||||
@ -739,7 +771,7 @@ class FontBuilder(object):
|
||||
"""Create a new `post` table and initialize it with default values,
|
||||
which can be overridden by keyword arguments.
|
||||
"""
|
||||
isCFF2 = 'CFF2' in self.font
|
||||
isCFF2 = "CFF2" in self.font
|
||||
postTable = self._initTableWithValues("post", _postDefaults, values)
|
||||
if (self.isTTF or isCFF2) and keepGlyphNames:
|
||||
postTable.formatType = 2.0
|
||||
@ -763,10 +795,10 @@ class FontBuilder(object):
|
||||
happy. This does not properly sign the font.
|
||||
"""
|
||||
values = dict(
|
||||
ulVersion = 1,
|
||||
usFlag = 0,
|
||||
usNumSigs = 0,
|
||||
signatureRecords = [],
|
||||
ulVersion=1,
|
||||
usFlag=0,
|
||||
usNumSigs=0,
|
||||
signatureRecords=[],
|
||||
)
|
||||
self._initTableWithValues("DSIG", {}, values)
|
||||
|
||||
@ -782,7 +814,10 @@ class FontBuilder(object):
|
||||
`fontTools.feaLib` for details.
|
||||
"""
|
||||
from .feaLib.builder import addOpenTypeFeaturesFromString
|
||||
addOpenTypeFeaturesFromString(self.font, features, filename=filename, tables=tables)
|
||||
|
||||
addOpenTypeFeaturesFromString(
|
||||
self.font, features, filename=filename, tables=tables
|
||||
)
|
||||
|
||||
def addFeatureVariations(self, conditionalSubstitutions, featureTag="rvrn"):
|
||||
"""Add conditional substitutions to a Variable Font.
|
||||
@ -831,7 +866,7 @@ class FontBuilder(object):
|
||||
paletteTypes=paletteTypes,
|
||||
paletteLabels=paletteLabels,
|
||||
paletteEntryLabels=paletteEntryLabels,
|
||||
nameTable=self.font.get("name")
|
||||
nameTable=self.font.get("name"),
|
||||
)
|
||||
|
||||
def setupStat(self, axes, locations=None, elidedFallbackName=2):
|
||||
@ -841,6 +876,7 @@ class FontBuilder(object):
|
||||
the arguments.
|
||||
"""
|
||||
from .otlLib.builder import buildStatTable
|
||||
|
||||
buildStatTable(self.font, axes, locations, elidedFallbackName)
|
||||
|
||||
|
||||
@ -889,9 +925,9 @@ def addFvar(font, axes, instances):
|
||||
fvar.axes.append(axis)
|
||||
|
||||
for instance in instances:
|
||||
coordinates = instance['location']
|
||||
name = instance['stylename']
|
||||
psname = instance.get('postscriptfontname')
|
||||
coordinates = instance["location"]
|
||||
name = instance["stylename"]
|
||||
psname = instance.get("postscriptfontname")
|
||||
|
||||
inst = NamedInstance()
|
||||
inst.subfamilyNameID = nameTable.addName(name)
|
||||
@ -901,4 +937,4 @@ def addFvar(font, axes, instances):
|
||||
inst.coordinates = coordinates
|
||||
fvar.instances.append(inst)
|
||||
|
||||
font['fvar'] = fvar
|
||||
font["fvar"] = fvar
|
||||
|
Loading…
x
Reference in New Issue
Block a user