Merge pull request #2762 from fonttools/var-glyph-set-inheritance

[ttGlyphSet] Inherit ttVarGlyphSet from ttGlyphSet
This commit is contained in:
Cosimo Lupo 2022-08-22 17:24:05 +01:00 committed by GitHub
commit 0adc164355
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 60 additions and 24 deletions

View File

@ -107,19 +107,22 @@ class _TTGlyphGlyf(_TTGlyph):
class _TTVarGlyphSet(object):
class _TTVarGlyphSet(_TTGlyphSet):
def __init__(self, font, location, normalized=False):
from fontTools.varLib.models import normalizeLocation, piecewiseLinearMap
self._ttFont = font
self._glyphs = font['glyf']
if not normalized:
from fontTools.varLib.models import normalizeLocation, piecewiseLinearMap
axes = {a.axisTag: (a.minValue, a.defaultValue, a.maxValue) for a in font['fvar'].axes}
location = normalizeLocation(location, axes)
if 'avar' in font:
avar = font['avar']
avarSegments = avar.segments
new_location = {}
for axis_tag,value in location.items():
for axis_tag, value in location.items():
avarMapping = avarSegments.get(axis_tag, None)
if avarMapping is not None:
value = piecewiseLinearMap(value, avarMapping)
@ -129,21 +132,11 @@ class _TTVarGlyphSet(object):
self.location = location
def keys(self):
return list(self._ttFont['glyf'].keys())
def has_key(self, glyphName):
return glyphName in self._ttFont['glyf']
__contains__ = has_key
def __getitem__(self, glyphName):
if glyphName not in self._glyphs:
raise KeyError(glyphName)
return _TTVarGlyphGlyf(self._ttFont, glyphName, self.location)
def get(self, glyphName, default=None):
try:
return self[glyphName]
except KeyError:
return default
def _setCoordinates(glyph, coord, glyfTable):
# Handle phantom points for (left, right, top, bottom) positions.
@ -174,16 +167,25 @@ def _setCoordinates(glyph, coord, glyfTable):
horizontalAdvanceWidth = otRound(rightSideX - leftSideX)
verticalAdvanceWidth = otRound(topSideY - bottomSideY)
leftSideBearing = otRound(glyph.xMin - leftSideX)
return horizontalAdvanceWidth, leftSideBearing, verticalAdvanceWidth
topSideBearing = otRound(topSideY - glyph.yMax)
return (
horizontalAdvanceWidth,
leftSideBearing,
verticalAdvanceWidth,
topSideBearing,
)
class _TTVarGlyphGlyf(object):
class _TTVarGlyph(_TTGlyph):
def __init__(self, ttFont, glyphName, location):
self._ttFont = ttFont
self._glyphName = glyphName
self._location = location
self.width = None # draw fills it in
# draw() fills these in
self.width = self.height = self.lsb = self.tsb = None
class _TTVarGlyphGlyf(_TTVarGlyph):
def draw(self, pen):
from fontTools.varLib.iup import iup_delta
@ -210,8 +212,10 @@ class _TTVarGlyphGlyf(object):
coordinates += GlyphCoordinates(delta) * scalar
glyph = copy(glyf[self._glyphName]) # Shallow copy
horizontalAdvanceWidth, leftSideBearing, verticalAdvanceWidth = _setCoordinates(glyph, coordinates, glyf)
self.width = horizontalAdvanceWidth
self.height = verticalAdvanceWidth
offset = leftSideBearing - glyph.xMin if hasattr(glyph, "xMin") else 0
width, lsb, height, tsb = _setCoordinates(glyph, coordinates, glyf)
self.width = width
self.lsb = lsb
self.height = height
self.tsb = tsb
offset = lsb - glyph.xMin if hasattr(glyph, "xMin") else 0
glyph.draw(pen, glyf, offset)

View File

@ -1,4 +1,5 @@
from fontTools.ttLib import TTFont
from fontTools.ttLib import ttGlyphSet
from fontTools.pens.recordingPen import RecordingPen
import os
import pytest
@ -14,6 +15,16 @@ class TTGlyphSetTest(object):
@pytest.mark.parametrize(
"location, expected",
[
(
None,
[
('moveTo', ((175, 0),)),
('lineTo', ((367, 0),)),
('lineTo', ((367, 1456),)),
('lineTo', ((175, 1456),)),
('closePath', ())
]
),
(
{},
[
@ -69,11 +80,32 @@ class TTGlyphSetTest(object):
def test_glyphset(
self, location, expected
):
# TODO: also test loading CFF-flavored fonts
font = TTFont(self.getpath("I.ttf"))
glyphset = font.getGlyphSet(location=location)
assert isinstance(glyphset, ttGlyphSet._TTGlyphSet)
if location:
assert isinstance(glyphset, ttGlyphSet._TTVarGlyphSet)
assert list(glyphset.keys()) == [".notdef", "I"]
assert "I" in glyphset
assert glyphset.has_key("I") # we should really get rid of this...
assert len(glyphset) == 2
pen = RecordingPen()
glyph = glyphset['I']
assert glyphset.get("foobar") is None
assert isinstance(glyph, ttGlyphSet._TTGlyph)
if location:
assert isinstance(glyph, ttGlyphSet._TTVarGlyphGlyf)
else:
assert isinstance(glyph, ttGlyphSet._TTGlyphGlyf)
glyph.draw(pen)
actual = pen.value