Skip to content

Commit

Permalink
[transformations]: add metrics
Browse files Browse the repository at this point in the history
  • Loading branch information
moyogo committed Mar 26, 2018
1 parent 07217be commit 5bc1c7d
Show file tree
Hide file tree
Showing 2 changed files with 118 additions and 3 deletions.
43 changes: 40 additions & 3 deletions Lib/ufo2ft/filters/transformations.py
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,14 @@ class TransformationsFilter(BaseFilter):
'ScaleY': 100,
'Slant': 0,
'Origin': 4, # BASELINE
'Width': None,
'Height': None,
'LSB': None,
'RSB': None,
# Not in Glyphs SDK:
'TSB': None,
'BSB': None,
'VerticalOrigin': None,
}

def start(self):
Expand All @@ -92,6 +100,19 @@ def set_context(self, font, glyphSet):

origin_height = self.get_origin_height(font, self.options.Origin)

# Metrics
ctx.metrics = dict()
if self.options.LSB:
ctx.metrics["leftMargin"] = self.options.LSB
if self.options.RSB:
ctx.metrics["rightMargin"] = self.options.RSB
if self.options.TSB:
ctx.metrics["topMargin"] = self.options.TSB
if self.options.BSB:
ctx.metrics["bottomMargin"] = self.options.BSB
if self.options.VerticalOrigin:
ctx.metrics["verticalOrigin"] = self.options.VerticalOrigin

m = Identity
dx, dy = self.options.OffsetX, self.options.OffsetY
if dx != 0 or dy != 0:
Expand All @@ -117,9 +138,10 @@ def set_context(self, font, glyphSet):

return ctx

def filter(self, glyph):
def filter(self, glyph, isComponent=False):
metrics = self.context.metrics
matrix = self.context.matrix
if (matrix == Identity or
if ((not metrics and matrix == Identity) or
not (glyph or glyph.components or glyph.anchors)):
return False # nothing to do

Expand All @@ -130,12 +152,27 @@ def filter(self, glyph):
if base_name in modified:
continue
base_glyph = glyphSet[base_name]
if self.include(base_glyph) and self.filter(base_glyph):
if self.include(base_glyph) and \
self.filter(base_glyph, isComponent=True):
# base glyph is included but was not transformed yet; we
# call filter recursively until all the included bases are
# transformed, or there are no more components
modified.add(base_name)

if not isComponent:
for attr in ["leftMargin", "rightMargin", "topMargin",
"bottomMargin", "verticalOrigin"]:
if attr in metrics:
value = getattr(glyph, attr)
if value is not None:
value += metrics.get(attr)
setattr(glyph, attr, value)
else:
logger.warning(
"Cannot add %i to undefined %s in %s",
metrics.get(attr), attr, glyph.name
)

rec = RecordingPen()
glyph.draw(rec)
glyph.clearContours()
Expand Down
78 changes: 78 additions & 0 deletions tests/filters/transformations_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@
{
'name': 'a',
'width': 350,
'height': 400,
'verticalOrigin': 350,
'outline': [
('moveTo', ((0, 0),)),
('lineTo', ((300, 0),)),
Expand All @@ -33,6 +35,8 @@
{
'name': 'b',
'width': 450,
'height': 400,
'verticalOrigin': 350,
'outline': [
('addComponent', ('a', (1, 0, 0, 1, 0, 0))),
('addComponent', ('c', (1, 0, 0, 1, 0, 0))),
Expand Down Expand Up @@ -63,6 +67,8 @@ def font(request):
for param in request.param['glyphs']:
glyph = font.newGlyph(param['name'])
glyph.width = param.get('width', 0)
glyph.height = param.get('height', 0)
glyph.verticalOrigin = param.get('verticalOrigin', None)
pen = glyph.getPen()
for operator, operands in param.get('outline', []):
getattr(pen, operator)(*operands)
Expand Down Expand Up @@ -192,3 +198,75 @@ def test_composite_glyphs(self, font):
# its original transform had a scale, so it was necessary to
# compensate for the transformation applied on the base glyph
assert d.components[0].transformation == (1, 0, 0, -1, 0, 102)

@pytest.mark.parametrize(
"name",
["a", "b", "c", "d"])
def test_LSB(self, font, name):
value = -10
filter_ = TransformationsFilter(
LSB=value, include={name})
glyph = font[name]
previousLeftMargin = glyph.leftMargin
assert {name} == filter_(font)
assert glyph.leftMargin == previousLeftMargin + value

@pytest.mark.parametrize(
"name",
["a", "b", "c", "d"])
def test_RSB(self, font, name):
value = +10
filter_ = TransformationsFilter(
RSB=value, include={name})
glyph = font[name]
previousRightMargin = glyph.rightMargin
assert {name} == filter_(font)
assert glyph.rightMargin == previousRightMargin + value

@pytest.mark.parametrize(
"name",
["a", "b", "c", "d"])
def test_TSB(self, font, name):
value = -12
filter_ = TransformationsFilter(
TSB=value, include={name})
glyph = font[name]
previousTopMargin = glyph.topMargin
assert {name} == filter_(font)
assert glyph.topMargin == previousTopMargin + value

@pytest.mark.parametrize(
"name",
["a", "b", "c", "d"])
def test_BSB(self, font, name):
value = +12
filter_ = TransformationsFilter(
BSB=value, include={name})
glyph = font[name]
previousBottomMargin = glyph.bottomMargin
assert {name} == filter_(font)
assert glyph.bottomMargin == previousBottomMargin + value

@pytest.mark.parametrize(
"name",
["a", "b"])
def test_verticalOrigin(self, font, name):
value = +13
filter_ = TransformationsFilter(
VerticalOrigin=value, include={name})
glyph = font[name]
previousVerticalOrigin = glyph.verticalOrigin
assert {name} == filter_(font)
assert glyph.verticalOrigin == previousVerticalOrigin + value

@pytest.mark.parametrize(
"name",
["c", "d"])
def test_verticalOrigin_undefined(self, font, name):
value = +14
with CapturingLogHandler(logger, level="WARNING") as captor:
filter_ = TransformationsFilter(
VerticalOrigin=value, include={name})
filter_(font)
captor.assertRegex(
"Cannot add %i to undefined verticalOrigin in %s" % (value, name))

0 comments on commit 5bc1c7d

Please sign in to comment.