2022-08-14 12:48:30 -06:00
|
|
|
from fontTools.ttLib import TTFont
|
2022-08-22 16:51:48 +01:00
|
|
|
from fontTools.ttLib import ttGlyphSet
|
2022-08-14 12:48:30 -06:00
|
|
|
from fontTools.pens.recordingPen import RecordingPen
|
2023-01-18 16:06:57 -07:00
|
|
|
from fontTools.misc.roundTools import otRound
|
2022-08-14 12:48:30 -06:00
|
|
|
import os
|
|
|
|
import pytest
|
|
|
|
|
|
|
|
|
|
|
|
class TTGlyphSetTest(object):
|
|
|
|
@staticmethod
|
|
|
|
def getpath(testfile):
|
2022-08-15 11:06:51 -06:00
|
|
|
path = os.path.dirname(__file__)
|
2022-08-14 12:48:30 -06:00
|
|
|
return os.path.join(path, "data", testfile)
|
|
|
|
|
|
|
|
@pytest.mark.parametrize(
|
2022-08-26 21:38:58 -06:00
|
|
|
"fontfile, location, expected",
|
2022-08-14 12:48:30 -06:00
|
|
|
[
|
2022-08-22 16:51:48 +01:00
|
|
|
(
|
2022-08-26 21:38:58 -06:00
|
|
|
"I.ttf",
|
2022-08-22 16:51:48 +01:00
|
|
|
None,
|
|
|
|
[
|
2022-08-26 21:38:58 -06:00
|
|
|
("moveTo", ((175, 0),)),
|
|
|
|
("lineTo", ((367, 0),)),
|
|
|
|
("lineTo", ((367, 1456),)),
|
|
|
|
("lineTo", ((175, 1456),)),
|
|
|
|
("closePath", ()),
|
|
|
|
],
|
2022-08-22 16:51:48 +01:00
|
|
|
),
|
2022-08-14 12:48:30 -06:00
|
|
|
(
|
2022-08-26 21:38:58 -06:00
|
|
|
"I.ttf",
|
2022-08-14 12:48:30 -06:00
|
|
|
{},
|
|
|
|
[
|
2022-08-26 21:38:58 -06:00
|
|
|
("moveTo", ((175, 0),)),
|
|
|
|
("lineTo", ((367, 0),)),
|
|
|
|
("lineTo", ((367, 1456),)),
|
|
|
|
("lineTo", ((175, 1456),)),
|
|
|
|
("closePath", ()),
|
|
|
|
],
|
|
|
|
),
|
|
|
|
(
|
|
|
|
"I.ttf",
|
|
|
|
{"wght": 100},
|
|
|
|
[
|
|
|
|
("moveTo", ((175, 0),)),
|
|
|
|
("lineTo", ((271, 0),)),
|
|
|
|
("lineTo", ((271, 1456),)),
|
|
|
|
("lineTo", ((175, 1456),)),
|
|
|
|
("closePath", ()),
|
|
|
|
],
|
2022-08-14 12:48:30 -06:00
|
|
|
),
|
|
|
|
(
|
2022-08-26 21:38:58 -06:00
|
|
|
"I.ttf",
|
|
|
|
{"wght": 1000},
|
2022-08-14 12:48:30 -06:00
|
|
|
[
|
2022-08-26 21:38:58 -06:00
|
|
|
("moveTo", ((128, 0),)),
|
|
|
|
("lineTo", ((550, 0),)),
|
|
|
|
("lineTo", ((550, 1456),)),
|
|
|
|
("lineTo", ((128, 1456),)),
|
|
|
|
("closePath", ()),
|
|
|
|
],
|
2022-08-14 12:48:30 -06:00
|
|
|
),
|
|
|
|
(
|
2022-08-26 21:38:58 -06:00
|
|
|
"I.ttf",
|
|
|
|
{"wght": 1000, "wdth": 25},
|
2022-08-14 12:48:30 -06:00
|
|
|
[
|
2022-08-26 21:38:58 -06:00
|
|
|
("moveTo", ((140, 0),)),
|
|
|
|
("lineTo", ((553, 0),)),
|
|
|
|
("lineTo", ((553, 1456),)),
|
|
|
|
("lineTo", ((140, 1456),)),
|
|
|
|
("closePath", ()),
|
|
|
|
],
|
2022-08-14 12:48:30 -06:00
|
|
|
),
|
|
|
|
(
|
2022-08-26 21:38:58 -06:00
|
|
|
"I.ttf",
|
|
|
|
{"wght": 1000, "wdth": 50},
|
2022-08-14 12:48:30 -06:00
|
|
|
[
|
2022-08-26 21:38:58 -06:00
|
|
|
("moveTo", ((136, 0),)),
|
|
|
|
("lineTo", ((552, 0),)),
|
|
|
|
("lineTo", ((552, 1456),)),
|
|
|
|
("lineTo", ((136, 1456),)),
|
|
|
|
("closePath", ()),
|
|
|
|
],
|
2022-08-14 12:48:30 -06:00
|
|
|
),
|
|
|
|
(
|
2022-08-26 21:38:58 -06:00
|
|
|
"I.otf",
|
|
|
|
{"wght": 1000},
|
2022-08-14 12:48:30 -06:00
|
|
|
[
|
2022-08-26 21:38:58 -06:00
|
|
|
("moveTo", ((179, 74),)),
|
|
|
|
("lineTo", ((28, 59),)),
|
|
|
|
("lineTo", ((28, 0),)),
|
|
|
|
("lineTo", ((367, 0),)),
|
|
|
|
("lineTo", ((367, 59),)),
|
|
|
|
("lineTo", ((212, 74),)),
|
|
|
|
("lineTo", ((179, 74),)),
|
|
|
|
("closePath", ()),
|
|
|
|
("moveTo", ((179, 578),)),
|
|
|
|
("lineTo", ((212, 578),)),
|
|
|
|
("lineTo", ((367, 593),)),
|
|
|
|
("lineTo", ((367, 652),)),
|
|
|
|
("lineTo", ((28, 652),)),
|
|
|
|
("lineTo", ((28, 593),)),
|
|
|
|
("lineTo", ((179, 578),)),
|
|
|
|
("closePath", ()),
|
|
|
|
("moveTo", ((98, 310),)),
|
|
|
|
("curveTo", ((98, 205), (98, 101), (95, 0))),
|
|
|
|
("lineTo", ((299, 0),)),
|
|
|
|
("curveTo", ((296, 103), (296, 207), (296, 311))),
|
|
|
|
("lineTo", ((296, 342),)),
|
|
|
|
("curveTo", ((296, 447), (296, 551), (299, 652))),
|
|
|
|
("lineTo", ((95, 652),)),
|
|
|
|
("curveTo", ((98, 549), (98, 445), (98, 342))),
|
|
|
|
("lineTo", ((98, 310),)),
|
|
|
|
("closePath", ()),
|
|
|
|
],
|
2022-08-14 12:48:30 -06:00
|
|
|
),
|
2022-09-20 10:54:09 +02:00
|
|
|
(
|
2022-09-20 11:17:58 +02:00
|
|
|
# In this font, /I has an lsb of 30, but an xMin of 25, so an
|
|
|
|
# offset of 5 units needs to be applied when drawing the outline.
|
|
|
|
# See https://github.com/fonttools/fonttools/issues/2824
|
2022-09-20 10:54:09 +02:00
|
|
|
"issue2824.ttf",
|
|
|
|
None,
|
|
|
|
[
|
|
|
|
("moveTo", ((309, 180),)),
|
|
|
|
("qCurveTo", ((274, 151), (187, 136), (104, 166), (74, 201))),
|
|
|
|
("qCurveTo", ((45, 236), (30, 323), (59, 407), (95, 436))),
|
|
|
|
("qCurveTo", ((130, 466), (217, 480), (301, 451), (330, 415))),
|
|
|
|
("qCurveTo", ((360, 380), (374, 293), (345, 210), (309, 180))),
|
|
|
|
("closePath", ()),
|
|
|
|
],
|
|
|
|
),
|
2022-08-26 21:38:58 -06:00
|
|
|
],
|
2022-08-14 12:48:30 -06:00
|
|
|
)
|
2022-08-26 21:38:58 -06:00
|
|
|
def test_glyphset(self, fontfile, location, expected):
|
|
|
|
font = TTFont(self.getpath(fontfile))
|
2022-08-14 12:48:30 -06:00
|
|
|
glyphset = font.getGlyphSet(location=location)
|
2022-08-22 16:51:48 +01:00
|
|
|
|
|
|
|
assert isinstance(glyphset, ttGlyphSet._TTGlyphSet)
|
|
|
|
|
|
|
|
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
|
|
|
|
|
2022-08-14 12:48:30 -06:00
|
|
|
pen = RecordingPen()
|
2022-08-26 21:38:58 -06:00
|
|
|
glyph = glyphset["I"]
|
2022-08-22 16:51:48 +01:00
|
|
|
|
|
|
|
assert glyphset.get("foobar") is None
|
|
|
|
|
|
|
|
assert isinstance(glyph, ttGlyphSet._TTGlyph)
|
2022-08-26 21:38:58 -06:00
|
|
|
is_glyf = fontfile.endswith(".ttf")
|
2022-08-29 19:41:30 +02:00
|
|
|
glyphType = ttGlyphSet._TTGlyphGlyf if is_glyf else ttGlyphSet._TTGlyphCFF
|
2022-08-26 21:38:58 -06:00
|
|
|
assert isinstance(glyph, glyphType)
|
2022-08-22 16:51:48 +01:00
|
|
|
|
2022-08-14 12:48:30 -06:00
|
|
|
glyph.draw(pen)
|
|
|
|
actual = pen.value
|
|
|
|
|
|
|
|
assert actual == expected, (location, actual, expected)
|
2023-01-18 16:06:57 -07:00
|
|
|
|
|
|
|
def test_glyphset_varComposite(self):
|
|
|
|
font = TTFont(self.getpath("varc-ac00-ac01.ttf"))
|
2023-02-01 18:31:54 -07:00
|
|
|
glyphset = font.getGlyphSet(location={"wght": 600})
|
2023-01-18 16:06:57 -07:00
|
|
|
|
|
|
|
pen = RecordingPen()
|
|
|
|
glyph = glyphset["uniAC00"]
|
|
|
|
|
|
|
|
glyph.draw(pen)
|
|
|
|
actual = pen.value
|
|
|
|
|
|
|
|
expected = [
|
2023-02-01 18:31:54 -07:00
|
|
|
("moveTo", ((432, 678),)),
|
|
|
|
("lineTo", ((432, 620),)),
|
2023-01-18 16:06:57 -07:00
|
|
|
(
|
|
|
|
"qCurveTo",
|
|
|
|
(
|
2023-02-01 18:31:54 -07:00
|
|
|
(419, 620),
|
|
|
|
(374, 621),
|
|
|
|
(324, 619),
|
|
|
|
(275, 618),
|
|
|
|
(237, 617),
|
|
|
|
(228, 616),
|
2023-01-18 16:06:57 -07:00
|
|
|
),
|
|
|
|
),
|
2023-02-01 18:31:54 -07:00
|
|
|
("qCurveTo", ((218, 616), (188, 612), (160, 605), (149, 601))),
|
|
|
|
("qCurveTo", ((127, 611), (83, 639), (67, 654))),
|
|
|
|
("qCurveTo", ((64, 657), (63, 662), (64, 666))),
|
|
|
|
("lineTo", ((72, 678),)),
|
|
|
|
("qCurveTo", ((93, 674), (144, 672), (164, 672))),
|
2023-01-18 16:06:57 -07:00
|
|
|
(
|
|
|
|
"qCurveTo",
|
|
|
|
(
|
2023-02-01 18:31:54 -07:00
|
|
|
(173, 672),
|
|
|
|
(213, 672),
|
|
|
|
(266, 673),
|
|
|
|
(323, 674),
|
|
|
|
(377, 675),
|
|
|
|
(421, 678),
|
|
|
|
(432, 678),
|
2023-01-18 16:06:57 -07:00
|
|
|
),
|
|
|
|
),
|
|
|
|
("closePath", ()),
|
2023-02-01 18:31:54 -07:00
|
|
|
("moveTo", ((525, 619),)),
|
|
|
|
("lineTo", ((412, 620),)),
|
|
|
|
("lineTo", ((429, 678),)),
|
|
|
|
("lineTo", ((466, 697),)),
|
|
|
|
("qCurveTo", ((470, 698), (482, 698), (486, 697))),
|
|
|
|
("qCurveTo", ((494, 693), (515, 682), (536, 670), (541, 667))),
|
|
|
|
("qCurveTo", ((545, 663), (545, 656), (543, 652))),
|
|
|
|
("lineTo", ((525, 619),)),
|
2023-01-18 16:06:57 -07:00
|
|
|
("closePath", ()),
|
2023-02-01 18:31:54 -07:00
|
|
|
("moveTo", ((63, 118),)),
|
|
|
|
("lineTo", ((47, 135),)),
|
|
|
|
("qCurveTo", ((42, 141), (48, 146))),
|
|
|
|
("qCurveTo", ((135, 213), (278, 373), (383, 541), (412, 620))),
|
|
|
|
("lineTo", ((471, 642),)),
|
|
|
|
("lineTo", ((525, 619),)),
|
|
|
|
("qCurveTo", ((496, 529), (365, 342), (183, 179), (75, 121))),
|
|
|
|
("qCurveTo", ((72, 119), (65, 118), (63, 118))),
|
2023-01-18 16:06:57 -07:00
|
|
|
("closePath", ()),
|
2023-02-01 18:31:54 -07:00
|
|
|
("moveTo", ((925, 372),)),
|
|
|
|
("lineTo", ((739, 368),)),
|
|
|
|
("lineTo", ((739, 427),)),
|
|
|
|
("lineTo", ((822, 430),)),
|
|
|
|
("lineTo", ((854, 451),)),
|
|
|
|
("qCurveTo", ((878, 453), (930, 449), (944, 445))),
|
|
|
|
("qCurveTo", ((961, 441), (962, 426))),
|
|
|
|
("qCurveTo", ((964, 411), (956, 386), (951, 381))),
|
|
|
|
("qCurveTo", ((947, 376), (931, 372), (925, 372))),
|
2023-01-18 16:06:57 -07:00
|
|
|
("closePath", ()),
|
2023-02-01 18:31:54 -07:00
|
|
|
("moveTo", ((729, -113),)),
|
|
|
|
("lineTo", ((674, -113),)),
|
|
|
|
("qCurveTo", ((671, -98), (669, -42), (666, 22), (665, 83), (665, 102))),
|
|
|
|
("lineTo", ((665, 763),)),
|
|
|
|
("qCurveTo", ((654, 780), (608, 810), (582, 820))),
|
|
|
|
("lineTo", ((593, 850),)),
|
|
|
|
("qCurveTo", ((594, 852), (599, 856), (607, 856))),
|
|
|
|
("qCurveTo", ((628, 855), (684, 846), (736, 834), (752, 827))),
|
|
|
|
("qCurveTo", ((766, 818), (766, 802))),
|
|
|
|
("lineTo", ((762, 745),)),
|
|
|
|
("lineTo", ((762, 134),)),
|
|
|
|
("qCurveTo", ((762, 107), (757, 43), (749, -25), (737, -87), (729, -113))),
|
2023-01-18 16:06:57 -07:00
|
|
|
("closePath", ()),
|
|
|
|
]
|
|
|
|
|
|
|
|
actual = [
|
|
|
|
(op, tuple((otRound(pt[0]), otRound(pt[1])) for pt in args))
|
|
|
|
for op, args in actual
|
|
|
|
]
|
|
|
|
|
|
|
|
assert actual == expected, (actual, expected)
|