Properly merge head.flags and OS/2.fsType
Also install the merge script.
This commit is contained in:
parent
95f795f40a
commit
642eaf135d
@ -47,6 +47,9 @@ def recalculate(lst):
|
||||
def current_time(lst):
|
||||
return int(time.time() - _h_e_a_d.mac_epoch_diff)
|
||||
|
||||
def bitwise_and(lst):
|
||||
return reduce(operator.and_, lst)
|
||||
|
||||
def bitwise_or(lst):
|
||||
return reduce(operator.or_, lst)
|
||||
|
||||
@ -118,6 +121,22 @@ def mergeObjects(lst):
|
||||
|
||||
return returnTable
|
||||
|
||||
def mergeBits(logic, lst):
|
||||
lst = list(lst)
|
||||
returnValue = 0
|
||||
for bitNumber in range(logic['size']):
|
||||
try:
|
||||
mergeLogic = logic[bitNumber]
|
||||
except KeyError:
|
||||
try:
|
||||
mergeLogic = logic['*']
|
||||
except KeyError:
|
||||
raise Exception("Don't know how to merge bit %s" % bitNumber)
|
||||
shiftedBit = 1 << bitNumber
|
||||
mergedValue = mergeLogic(bool(item & shiftedBit) for item in lst)
|
||||
returnValue |= mergedValue << bitNumber
|
||||
return returnValue
|
||||
|
||||
|
||||
@_add_method(DefaultTable, allowDefaultTable=True)
|
||||
def merge(self, m, tables):
|
||||
@ -139,13 +158,27 @@ ttLib.getTableClass('maxp').mergeMap = {
|
||||
# maxFunctionDefs, maxInstructionDefs, maxSizeOfInstructions
|
||||
}
|
||||
|
||||
headFlagsMergeMap = {
|
||||
'size': 16,
|
||||
'*': bitwise_or,
|
||||
1: bitwise_and, # Baseline at y = 0
|
||||
2: bitwise_and, # lsb at x = 0
|
||||
3: bitwise_and, # Force ppem to integer values. FIXME?
|
||||
5: bitwise_and, # Font is vertical
|
||||
6: lambda bit: 0, # Always set to zero
|
||||
11: bitwise_and, # Font data is 'lossless'
|
||||
13: bitwise_and, # Optimized for ClearType
|
||||
14: bitwise_and, # Last resort font. FIXME? equal or first may be better
|
||||
15: lambda bit: 0, # Always set to zero
|
||||
}
|
||||
|
||||
ttLib.getTableClass('head').mergeMap = {
|
||||
'tableTag': equal,
|
||||
'tableVersion': max,
|
||||
'fontRevision': max,
|
||||
'checkSumAdjustment': lambda lst: 0, # We need *something* here
|
||||
'magicNumber': equal,
|
||||
'flags': first, # FIXME: replace with bit-sensitive code
|
||||
'flags': lambda lst: mergeBits(headFlagsMergeMap, lst),
|
||||
'unitsPerEm': equal,
|
||||
'created': current_time,
|
||||
'modified': current_time,
|
||||
@ -171,19 +204,53 @@ ttLib.getTableClass('hhea').mergeMap = {
|
||||
'minLeftSideBearing': min,
|
||||
'minRightSideBearing': min,
|
||||
'xMaxExtent': max,
|
||||
'caretSlopeRise': first, # FIXME
|
||||
'caretSlopeRun': first, # FIXME
|
||||
'caretOffset': first, # FIXME
|
||||
'caretSlopeRise': first,
|
||||
'caretSlopeRun': first,
|
||||
'caretOffset': first,
|
||||
'numberOfHMetrics': recalculate,
|
||||
}
|
||||
|
||||
os2FsTypeMergeMap = {
|
||||
'size': 16,
|
||||
'*': lambda bit: 0,
|
||||
1: bitwise_or, # no embedding permitted
|
||||
2: bitwise_and, # allow previewing and printing documents
|
||||
3: bitwise_and, # allow editing documents
|
||||
8: bitwise_or, # no subsetting permitted
|
||||
9: bitwise_or, # no embedding of outlines permitted
|
||||
}
|
||||
|
||||
def mergeOs2FsType(lst):
|
||||
lst = list(lst)
|
||||
if all(item == 0 for item in lst):
|
||||
return 0
|
||||
|
||||
# Compute least restrictive logic for each fsType value
|
||||
for i in range(len(lst)):
|
||||
# unset bit 1 (no embedding permitted) if either bit 2 or 3 is set
|
||||
if lst[i] & 0x000C:
|
||||
lst[i] &= ~0x0002
|
||||
# set bit 2 (allow previewing) if bit 3 is set (allow editing)
|
||||
elif lst[i] & 0x0008:
|
||||
lst[i] |= 0x0004
|
||||
# set bits 2 and 3 if everything is allowed
|
||||
elif lst[i] == 0:
|
||||
lst[i] = 0x000C
|
||||
|
||||
fsType = mergeBits(os2FsTypeMergeMap, lst)
|
||||
# unset bits 2 and 3 if bit 1 is set (some font is "no embedding")
|
||||
if fsType & 0x0002:
|
||||
fsType &= ~0x000C
|
||||
return fsType
|
||||
|
||||
|
||||
ttLib.getTableClass('OS/2').mergeMap = {
|
||||
'*': first,
|
||||
'tableTag': equal,
|
||||
'version': max,
|
||||
'xAvgCharWidth': avg_int, # Apparently fontTools doesn't recalc this
|
||||
'fsType': first, # FIXME
|
||||
'panose': first, # FIXME?
|
||||
'fsType': mergeOs2FsType, # Will be overwritten
|
||||
'panose': first, # FIXME: should really be the first Latin font
|
||||
'ulUnicodeRange1': bitwise_or,
|
||||
'ulUnicodeRange2': bitwise_or,
|
||||
'ulUnicodeRange3': bitwise_or,
|
||||
@ -201,6 +268,20 @@ ttLib.getTableClass('OS/2').mergeMap = {
|
||||
# TODO version 5
|
||||
}
|
||||
|
||||
@_add_method(ttLib.getTableClass('OS/2'))
|
||||
def merge(self, m, tables):
|
||||
DefaultTable.merge(self, m, tables)
|
||||
if self.version < 2:
|
||||
# bits 8 and 9 are reserved and should be set to zero
|
||||
self.fsType &= ~0x0300
|
||||
if self.version >= 3:
|
||||
# Only one of bits 1, 2, and 3 may be set. We already take
|
||||
# care of bit 1 implications in mergeOs2FsType. So unset
|
||||
# bit 2 if bit 3 is already set.
|
||||
if self.fsType & 0x0008:
|
||||
self.fsType &= ~0x0004
|
||||
return self
|
||||
|
||||
ttLib.getTableClass('post').mergeMap = {
|
||||
'*': first,
|
||||
'tableTag': equal,
|
||||
|
2
setup.py
2
setup.py
@ -80,7 +80,7 @@ setup(
|
||||
],
|
||||
package_dir = {'': 'Lib'},
|
||||
extra_path = 'FontTools',
|
||||
scripts = ["Tools/ttx", "Tools/pyftsubset", "Tools/pyftinspect"],
|
||||
scripts = ["Tools/ttx", "Tools/pyftsubset", "Tools/pyftinspect", "Tools/pyftmerge"],
|
||||
cmdclass = {"build_ext": build_ext_optional},
|
||||
data_files = [('share/man/man1', ["Doc/ttx.1"])],
|
||||
**classifiers
|
||||
|
Loading…
x
Reference in New Issue
Block a user