Add registry for custom table packer/unpacker classes (#2055)
* Add custom table packer/unpacker registry * fix documentation for getTableClass(): it will never return None * add unregisterCustomTableClass(), mostly for testing
This commit is contained in:
parent
a41005077d
commit
9064e53c7a
@ -830,10 +830,48 @@ def getTableModule(tag):
|
|||||||
return getattr(tables, pyTag)
|
return getattr(tables, pyTag)
|
||||||
|
|
||||||
|
|
||||||
def getTableClass(tag):
|
# Registry for custom table packer/unpacker classes. Keys are table
|
||||||
"""Fetch the packer/unpacker class for a table.
|
# tags, values are (moduleName, className) tuples.
|
||||||
Return None when no class is found.
|
# See registerCustomTableClass() and getCustomTableClass()
|
||||||
|
_customTableRegistry = {}
|
||||||
|
|
||||||
|
|
||||||
|
def registerCustomTableClass(tag, moduleName, className=None):
|
||||||
|
"""Register a custom packer/unpacker class for a table.
|
||||||
|
The 'moduleName' must be an importable module. If no 'className'
|
||||||
|
is given, it is derived from the tag, for example it will be
|
||||||
|
table_C_U_S_T_ for a 'CUST' tag.
|
||||||
|
|
||||||
|
The registered table class should be a subclass of
|
||||||
|
fontTools.ttLib.tables.DefaultTable.DefaultTable
|
||||||
"""
|
"""
|
||||||
|
if className is None:
|
||||||
|
className = "table_" + tagToIdentifier(tag)
|
||||||
|
_customTableRegistry[tag] = (moduleName, className)
|
||||||
|
|
||||||
|
|
||||||
|
def unregisterCustomTableClass(tag):
|
||||||
|
"""Unregister the custom packer/unpacker class for a table."""
|
||||||
|
del _customTableRegistry[tag]
|
||||||
|
|
||||||
|
|
||||||
|
def getCustomTableClass(tag):
|
||||||
|
"""Return the custom table class for tag, if one has been registered
|
||||||
|
with 'registerCustomTableClass()'. Else return None.
|
||||||
|
"""
|
||||||
|
if tag not in _customTableRegistry:
|
||||||
|
return None
|
||||||
|
import importlib
|
||||||
|
moduleName, className = _customTableRegistry[tag]
|
||||||
|
module = importlib.import_module(moduleName)
|
||||||
|
return getattr(module, className)
|
||||||
|
|
||||||
|
|
||||||
|
def getTableClass(tag):
|
||||||
|
"""Fetch the packer/unpacker class for a table."""
|
||||||
|
tableClass = getCustomTableClass(tag)
|
||||||
|
if tableClass is not None:
|
||||||
|
return tableClass
|
||||||
module = getTableModule(tag)
|
module = getTableModule(tag)
|
||||||
if module is None:
|
if module is None:
|
||||||
from .tables.DefaultTable import DefaultTable
|
from .tables.DefaultTable import DefaultTable
|
||||||
|
48
Tests/ttLib/ttFont_test.py
Normal file
48
Tests/ttLib/ttFont_test.py
Normal file
@ -0,0 +1,48 @@
|
|||||||
|
import io
|
||||||
|
from fontTools.ttLib import TTFont, newTable, registerCustomTableClass, unregisterCustomTableClass
|
||||||
|
from fontTools.ttLib.tables.DefaultTable import DefaultTable
|
||||||
|
|
||||||
|
|
||||||
|
class CustomTableClass(DefaultTable):
|
||||||
|
|
||||||
|
def decompile(self, data, ttFont):
|
||||||
|
self.numbers = list(data)
|
||||||
|
|
||||||
|
def compile(self, ttFont):
|
||||||
|
return bytes(self.numbers)
|
||||||
|
|
||||||
|
# not testing XML read/write
|
||||||
|
|
||||||
|
|
||||||
|
table_C_U_S_T_ = CustomTableClass # alias for testing
|
||||||
|
|
||||||
|
|
||||||
|
TABLETAG = "CUST"
|
||||||
|
|
||||||
|
|
||||||
|
def test_registerCustomTableClass():
|
||||||
|
font = TTFont()
|
||||||
|
font[TABLETAG] = newTable(TABLETAG)
|
||||||
|
font[TABLETAG].data = b"\x00\x01\xff"
|
||||||
|
f = io.BytesIO()
|
||||||
|
font.save(f)
|
||||||
|
f.seek(0)
|
||||||
|
assert font[TABLETAG].data == b"\x00\x01\xff"
|
||||||
|
registerCustomTableClass(TABLETAG, "ttFont_test", "CustomTableClass")
|
||||||
|
try:
|
||||||
|
font = TTFont(f)
|
||||||
|
assert font[TABLETAG].numbers == [0, 1, 255]
|
||||||
|
assert font[TABLETAG].compile(font) == b"\x00\x01\xff"
|
||||||
|
finally:
|
||||||
|
unregisterCustomTableClass(TABLETAG)
|
||||||
|
|
||||||
|
|
||||||
|
def test_registerCustomTableClassStandardName():
|
||||||
|
registerCustomTableClass(TABLETAG, "ttFont_test")
|
||||||
|
try:
|
||||||
|
font = TTFont()
|
||||||
|
font[TABLETAG] = newTable(TABLETAG)
|
||||||
|
font[TABLETAG].numbers = [4, 5, 6]
|
||||||
|
assert font[TABLETAG].compile(font) == b"\x04\x05\x06"
|
||||||
|
finally:
|
||||||
|
unregisterCustomTableClass(TABLETAG)
|
Loading…
x
Reference in New Issue
Block a user