124 lines
3.5 KiB
Python
124 lines
3.5 KiB
Python
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
|
|
from fontTools.misc.fixedTools import otRound
|
|
|
|
|
|
class ScalerVisitor(TTVisitor):
|
|
def __init__(self, scaleFactor):
|
|
self.scaleFactor = scaleFactor
|
|
|
|
def scale(self, v):
|
|
return otRound(v * self.scaleFactor)
|
|
|
|
|
|
@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)
|
|
|
|
|
|
@ScalerVisitor.register_attr(ttLib.getTableClass("glyf"), "glyphs")
|
|
def visit(visitor, obj, attr, glyphs):
|
|
for g in glyphs.values():
|
|
if g.isComposite():
|
|
for component in g.components:
|
|
component.x = visitor.scale(component.x)
|
|
component.y = visitor.scale(component.y)
|
|
else:
|
|
for attr in ("xMin", "xMax", "yMin", "yMax"):
|
|
v = getattr(g, attr, None)
|
|
if v is not None:
|
|
setattr(g, attr, visitor.scale(v))
|
|
|
|
glyf = visitor.font["glyf"]
|
|
coordinates = g.getCoordinates(glyf)[0]
|
|
for i, (x, y) in enumerate(coordinates):
|
|
coordinates[i] = visitor.scale(x), visitor.scale(y)
|
|
|
|
|
|
@ScalerVisitor.register_attr(ttLib.getTableClass("kern"), "kernTables")
|
|
def visit(visitor, obj, attr, kernTables):
|
|
for table in kernTables:
|
|
kernTable = table.kernTable
|
|
for k in kernTable.keys():
|
|
kernTable[k] = visitor.scale(kernTable[k])
|
|
|
|
|
|
# GPOS
|
|
|
|
|
|
@ScalerVisitor.register(otTables.ValueRecord)
|
|
def visit(visitor, obj):
|
|
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)
|
|
|
|
|
|
@ScalerVisitor.register(otTables.Anchor)
|
|
def visit(visitor, obj):
|
|
attrs = ["XCoordinate", "YCoordinate"]
|
|
for attr in attrs:
|
|
v = getattr(obj, attr)
|
|
v = visitor.scale(v)
|
|
setattr(obj, attr, v)
|
|
|
|
|
|
from fontTools.ttLib import TTFont
|
|
import sys
|
|
|
|
font = TTFont(sys.argv[1])
|
|
|
|
visitor = ScalerVisitor(0.5)
|
|
visitor.visit(font)
|