[visitor] Add register_attr(s) example

This commit is contained in:
Behdad Esfahbod 2022-08-15 12:17:51 -06:00
parent 9b0d0e7b56
commit a0686e8d2e
2 changed files with 75 additions and 6 deletions

View File

@ -7,7 +7,7 @@ class Visitor(object):
defaultStop = False
@classmethod
def register(celf, clazzes, attrs=(None,)):
def _register(celf, clazzes, attrs=(None,)):
assert celf != Visitor, "Subclass Visitor instead."
if "_visitors" not in celf.__dict__:
celf._visitors = {}
@ -34,6 +34,20 @@ class Visitor(object):
return wrapper
@classmethod
def register(celf, clazzes):
return celf._register(clazzes)
@classmethod
def register_attr(celf, clazzes, attrs):
return celf._register(clazzes, attrs)
@classmethod
def register_attrs(celf, clazzes_attrs):
for clazz, attrs in clazzes_attrs:
celf._register(clazz, attrs)
return lambda _: None
@classmethod
def _visitorsFor(celf, thing, _default={}):
typ = type(thing)

View File

@ -1,31 +1,86 @@
from fontTools.misc.visitor import TTVisitor
import fontTools.ttLib as ttLib
import fontTools.ttLib.tables.otBase as otBase
import fontTools.ttLib.tables.otTables as otTables
class ScalerVisitor(TTVisitor):
def scale(self, v):
return v // 2
@ScalerVisitor.register_attrs(
(
(ttLib.getTableClass("head"), ("unitsPerEm", "xMin", "yMin", "xMax", "yMax")),
(
ttLib.getTableClass("hhea"),
(
"ascent",
"descent",
"lineGap",
"advanceWidthMax",
"minLeftSideBearing",
"minRightSideBearing",
"xMaxExtent",
),
),
(
ttLib.getTableClass("OS/2"),
(
"xAvgCharWidth",
"ySubscriptXSize",
"ySubscriptYSize",
"ySubscriptXOffset",
"ySubscriptYOffset",
"ySuperscriptXSize",
"ySuperscriptYSize",
"ySuperscriptXOffset",
"ySuperscriptYOffset",
"yStrikeoutSize",
"yStrikeoutSize",
"yStrikeoutPosition",
"sTypoAscender",
"sTypoDescender",
"sTypoLineGap",
"usWinAscent",
"usWinDescent",
"sxHeight",
"sCapHeight",
),
),
)
)
def visit(visitor, obj, attr, value):
setattr(obj, attr, visitor.scale(value))
@ScalerVisitor.register_attr(ttLib.getTableClass("hmtx"), "metrics")
def visit(visitor, obj, attr, metrics):
for g in metrics:
advance, lsb = metrics[g]
metrics[g] = visitor.scale(advance), visitor.scale(lsb)
# GPOS
@ScalerVisitor.register(otTables.ValueRecord)
def visit(visitor, obj):
attrs = ['XAdvance', 'YAdvance', 'XPlacement', 'YPlacement']
attrs = ["XAdvance", "YAdvance", "XPlacement", "YPlacement"]
for attr in attrs:
v = getattr(obj, attr, None)
if v is not None:
v = visitor.scale(v)
setattr(obj, attr, v)
return False
@ScalerVisitor.register(otTables.Anchor)
def visit(visitor, obj):
attrs = ['XCoordinate', 'YCoordinate']
attrs = ["XCoordinate", "YCoordinate"]
for attr in attrs:
v = getattr(obj, attr)
v = visitor.scale(v)
setattr(obj, attr, v)
return False
from fontTools.ttLib import TTFont