python-fontbro 0.28.0__tar.gz → 0.28.1__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {python_fontbro-0.28.0/python_fontbro.egg-info → python_fontbro-0.28.1}/PKG-INFO +1 -1
- {python_fontbro-0.28.0 → python_fontbro-0.28.1}/fontbro/metadata.py +1 -1
- {python_fontbro-0.28.0 → python_fontbro-0.28.1}/fontbro/names.py +28 -12
- {python_fontbro-0.28.0 → python_fontbro-0.28.1/python_fontbro.egg-info}/PKG-INFO +1 -1
- {python_fontbro-0.28.0 → python_fontbro-0.28.1}/tests/test_names.py +80 -2
- {python_fontbro-0.28.0 → python_fontbro-0.28.1}/LICENSE.txt +0 -0
- {python_fontbro-0.28.0 → python_fontbro-0.28.1}/MANIFEST.in +0 -0
- {python_fontbro-0.28.0 → python_fontbro-0.28.1}/README.md +0 -0
- {python_fontbro-0.28.0 → python_fontbro-0.28.1}/fontbro/__init__.py +0 -0
- {python_fontbro-0.28.0 → python_fontbro-0.28.1}/fontbro/bitmap.py +0 -0
- {python_fontbro-0.28.0 → python_fontbro-0.28.1}/fontbro/color.py +0 -0
- {python_fontbro-0.28.0 → python_fontbro-0.28.1}/fontbro/data/family-classifications.json +0 -0
- {python_fontbro-0.28.0 → python_fontbro-0.28.1}/fontbro/data/features.json +0 -0
- {python_fontbro-0.28.0 → python_fontbro-0.28.1}/fontbro/data/unicode-blocks.json +0 -0
- {python_fontbro-0.28.0 → python_fontbro-0.28.1}/fontbro/data/unicode-scripts.json +0 -0
- {python_fontbro-0.28.0 → python_fontbro-0.28.1}/fontbro/embedding_permissions.py +0 -0
- {python_fontbro-0.28.0 → python_fontbro-0.28.1}/fontbro/exceptions.py +0 -0
- {python_fontbro-0.28.0 → python_fontbro-0.28.1}/fontbro/family_classification.py +0 -0
- {python_fontbro-0.28.0 → python_fontbro-0.28.1}/fontbro/features.py +0 -0
- {python_fontbro-0.28.0 → python_fontbro-0.28.1}/fontbro/files.py +0 -0
- {python_fontbro-0.28.0 → python_fontbro-0.28.1}/fontbro/fingerprint.py +0 -0
- {python_fontbro-0.28.0 → python_fontbro-0.28.1}/fontbro/flags.py +0 -0
- {python_fontbro-0.28.0 → python_fontbro-0.28.1}/fontbro/font.py +0 -0
- {python_fontbro-0.28.0 → python_fontbro-0.28.1}/fontbro/glyphs.py +0 -0
- {python_fontbro-0.28.0 → python_fontbro-0.28.1}/fontbro/math.py +0 -0
- {python_fontbro-0.28.0 → python_fontbro-0.28.1}/fontbro/metrics.py +0 -0
- {python_fontbro-0.28.0 → python_fontbro-0.28.1}/fontbro/monospace.py +0 -0
- {python_fontbro-0.28.0 → python_fontbro-0.28.1}/fontbro/pixel.py +0 -0
- {python_fontbro-0.28.0 → python_fontbro-0.28.1}/fontbro/py.typed +0 -0
- {python_fontbro-0.28.0 → python_fontbro-0.28.1}/fontbro/render.py +0 -0
- {python_fontbro-0.28.0 → python_fontbro-0.28.1}/fontbro/sanitize.py +0 -0
- {python_fontbro-0.28.0 → python_fontbro-0.28.1}/fontbro/style_flags.py +0 -0
- {python_fontbro-0.28.0 → python_fontbro-0.28.1}/fontbro/subset.py +0 -0
- {python_fontbro-0.28.0 → python_fontbro-0.28.1}/fontbro/support.py +0 -0
- {python_fontbro-0.28.0 → python_fontbro-0.28.1}/fontbro/tables.py +0 -0
- {python_fontbro-0.28.0 → python_fontbro-0.28.1}/fontbro/unicode.py +0 -0
- {python_fontbro-0.28.0 → python_fontbro-0.28.1}/fontbro/utils.py +0 -0
- {python_fontbro-0.28.0 → python_fontbro-0.28.1}/fontbro/variable.py +0 -0
- {python_fontbro-0.28.0 → python_fontbro-0.28.1}/pyproject.toml +0 -0
- {python_fontbro-0.28.0 → python_fontbro-0.28.1}/python_fontbro.egg-info/SOURCES.txt +0 -0
- {python_fontbro-0.28.0 → python_fontbro-0.28.1}/python_fontbro.egg-info/dependency_links.txt +0 -0
- {python_fontbro-0.28.0 → python_fontbro-0.28.1}/python_fontbro.egg-info/requires.txt +0 -0
- {python_fontbro-0.28.0 → python_fontbro-0.28.1}/python_fontbro.egg-info/top_level.txt +0 -0
- {python_fontbro-0.28.0 → python_fontbro-0.28.1}/setup.cfg +0 -0
- {python_fontbro-0.28.0 → python_fontbro-0.28.1}/setup.py +0 -0
- {python_fontbro-0.28.0 → python_fontbro-0.28.1}/tests/test_bitmap.py +0 -0
- {python_fontbro-0.28.0 → python_fontbro-0.28.1}/tests/test_characters.py +0 -0
- {python_fontbro-0.28.0 → python_fontbro-0.28.1}/tests/test_clone.py +0 -0
- {python_fontbro-0.28.0 → python_fontbro-0.28.1}/tests/test_close.py +0 -0
- {python_fontbro-0.28.0 → python_fontbro-0.28.1}/tests/test_collection.py +0 -0
- {python_fontbro-0.28.0 → python_fontbro-0.28.1}/tests/test_color.py +0 -0
- {python_fontbro-0.28.0 → python_fontbro-0.28.1}/tests/test_context_manager.py +0 -0
- {python_fontbro-0.28.0 → python_fontbro-0.28.1}/tests/test_embedding_permissions.py +0 -0
- {python_fontbro-0.28.0 → python_fontbro-0.28.1}/tests/test_family_classification.py +0 -0
- {python_fontbro-0.28.0 → python_fontbro-0.28.1}/tests/test_family_name.py +0 -0
- {python_fontbro-0.28.0 → python_fontbro-0.28.1}/tests/test_features.py +0 -0
- {python_fontbro-0.28.0 → python_fontbro-0.28.1}/tests/test_filename.py +0 -0
- {python_fontbro-0.28.0 → python_fontbro-0.28.1}/tests/test_fingerprint.py +0 -0
- {python_fontbro-0.28.0 → python_fontbro-0.28.1}/tests/test_format.py +0 -0
- {python_fontbro-0.28.0 → python_fontbro-0.28.1}/tests/test_glyphs.py +0 -0
- {python_fontbro-0.28.0 → python_fontbro-0.28.1}/tests/test_image.py +0 -0
- {python_fontbro-0.28.0 → python_fontbro-0.28.1}/tests/test_init.py +0 -0
- {python_fontbro-0.28.0 → python_fontbro-0.28.1}/tests/test_instantiation.py +0 -0
- {python_fontbro-0.28.0 → python_fontbro-0.28.1}/tests/test_issues.py +0 -0
- {python_fontbro-0.28.0 → python_fontbro-0.28.1}/tests/test_italic_angle.py +0 -0
- {python_fontbro-0.28.0 → python_fontbro-0.28.1}/tests/test_monospace.py +0 -0
- {python_fontbro-0.28.0 → python_fontbro-0.28.1}/tests/test_pixel.py +0 -0
- {python_fontbro-0.28.0 → python_fontbro-0.28.1}/tests/test_rename.py +0 -0
- {python_fontbro-0.28.0 → python_fontbro-0.28.1}/tests/test_sanitize.py +0 -0
- {python_fontbro-0.28.0 → python_fontbro-0.28.1}/tests/test_save.py +0 -0
- {python_fontbro-0.28.0 → python_fontbro-0.28.1}/tests/test_str.py +0 -0
- {python_fontbro-0.28.0 → python_fontbro-0.28.1}/tests/test_style_flags.py +0 -0
- {python_fontbro-0.28.0 → python_fontbro-0.28.1}/tests/test_style_name.py +0 -0
- {python_fontbro-0.28.0 → python_fontbro-0.28.1}/tests/test_subset.py +0 -0
- {python_fontbro-0.28.0 → python_fontbro-0.28.1}/tests/test_support.py +0 -0
- {python_fontbro-0.28.0 → python_fontbro-0.28.1}/tests/test_svg.py +0 -0
- {python_fontbro-0.28.0 → python_fontbro-0.28.1}/tests/test_tables.py +0 -0
- {python_fontbro-0.28.0 → python_fontbro-0.28.1}/tests/test_unicode.py +0 -0
- {python_fontbro-0.28.0 → python_fontbro-0.28.1}/tests/test_unicode_blocks_and_scripts.py +0 -0
- {python_fontbro-0.28.0 → python_fontbro-0.28.1}/tests/test_update_unicode_data.py +0 -0
- {python_fontbro-0.28.0 → python_fontbro-0.28.1}/tests/test_variable.py +0 -0
- {python_fontbro-0.28.0 → python_fontbro-0.28.1}/tests/test_version.py +0 -0
- {python_fontbro-0.28.0 → python_fontbro-0.28.1}/tests/test_vertical_metrics.py +0 -0
- {python_fontbro-0.28.0 → python_fontbro-0.28.1}/tests/test_weight.py +0 -0
- {python_fontbro-0.28.0 → python_fontbro-0.28.1}/tests/test_width.py +0 -0
|
@@ -116,11 +116,20 @@ def get_name(
|
|
|
116
116
|
Gets the name by its identifier from the name table of the given font.
|
|
117
117
|
"""
|
|
118
118
|
name_id = _get_name_id(key)
|
|
119
|
-
name_table = ttfont
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
119
|
+
name_table = ttfont.get("name")
|
|
120
|
+
if not name_table:
|
|
121
|
+
return None
|
|
122
|
+
# the windows english record is preferred: mac records are legacy
|
|
123
|
+
# and they can follow different naming conventions (eg. name id 1)
|
|
124
|
+
name_record = name_table.getName(name_id, **_NAMES_WIN_IDS)
|
|
125
|
+
if name_record:
|
|
126
|
+
try:
|
|
127
|
+
return str(name_record.toUnicode())
|
|
128
|
+
except UnicodeDecodeError:
|
|
129
|
+
pass
|
|
130
|
+
# fallback to the english (mac) record or to any other decodable record
|
|
131
|
+
name: str | None = name_table.getDebugName(name_id)
|
|
132
|
+
return name
|
|
124
133
|
|
|
125
134
|
|
|
126
135
|
def get_names(
|
|
@@ -129,12 +138,12 @@ def get_names(
|
|
|
129
138
|
"""
|
|
130
139
|
Gets the names records of the given font mapped by their property name.
|
|
131
140
|
"""
|
|
132
|
-
|
|
133
|
-
names = {
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
if
|
|
137
|
-
|
|
141
|
+
# read each name as get_name does, to get consistent values
|
|
142
|
+
names = {}
|
|
143
|
+
for name_id, name_item in _NAMES_BY_ID.items():
|
|
144
|
+
name = get_name(ttfont, name_id)
|
|
145
|
+
if name is not None:
|
|
146
|
+
names[name_item["key"]] = name
|
|
138
147
|
return names
|
|
139
148
|
|
|
140
149
|
|
|
@@ -149,10 +158,17 @@ def set_name(
|
|
|
149
158
|
name_id = _get_name_id(key)
|
|
150
159
|
name_table = ttfont["name"]
|
|
151
160
|
# https://github.com/fonttools/fonttools/blob/main/Lib/fontTools/ttLib/tables/_n_a_m_e.py#L568
|
|
161
|
+
# the windows record is always written, it's the one read first by get_name
|
|
152
162
|
name_table.setName(value, name_id, **_NAMES_WIN_IDS)
|
|
163
|
+
# mac records are legacy (modern tools don't produce them anymore),
|
|
164
|
+
# so they are updated only if the font already has some of them
|
|
165
|
+
mac_platform_id = _NAMES_MAC_IDS["platformID"]
|
|
166
|
+
if not any(record.platformID == mac_platform_id for record in name_table.names):
|
|
167
|
+
return
|
|
153
168
|
# the mac roman encoding can't encode many characters (eg. greek, cyrillic, cjk),
|
|
154
169
|
# in that case the mac name record is removed (as fontTools addMultilingualName
|
|
155
|
-
# does), otherwise the font would raise UnicodeEncodeError when saved
|
|
170
|
+
# does), otherwise the font would raise UnicodeEncodeError when saved;
|
|
171
|
+
# removing it is safe because the windows record has just been written
|
|
156
172
|
if _is_encodable(value, _NAMES_MAC_IDS):
|
|
157
173
|
name_table.setName(value, name_id, **_NAMES_MAC_IDS)
|
|
158
174
|
else:
|
|
@@ -85,9 +85,25 @@ class NamesTestCase(AbstractTestCase):
|
|
|
85
85
|
font_saved = Font(font.save_to_fileobject())
|
|
86
86
|
self.assertEqual(font_saved.get_name(Font.NAME_FAMILY_NAME), value)
|
|
87
87
|
|
|
88
|
+
def _add_mac_name_record(self, font):
|
|
89
|
+
# the fixtures fonts have only windows name records
|
|
90
|
+
name_table = font.get_ttfont()["name"]
|
|
91
|
+
name_table.setName("Roboto Mono", 1, 1, 0, 0)
|
|
92
|
+
|
|
93
|
+
def test_set_name_without_mac_records(self):
|
|
94
|
+
# mac records are legacy (modern tools don't produce them anymore),
|
|
95
|
+
# so they are not added to fonts having only windows records
|
|
96
|
+
font = self._get_font("/Roboto_Mono/static/RobotoMono-Regular.ttf")
|
|
97
|
+
font.set_name(Font.NAME_FAMILY_NAME, "Café Sans")
|
|
98
|
+
self.assertEqual(self._get_name_records_by_platform(font, 1), {3: "Café Sans"})
|
|
99
|
+
platforms = {record.platformID for record in font.get_ttfont()["name"].names}
|
|
100
|
+
self.assertEqual(platforms, {3})
|
|
101
|
+
|
|
88
102
|
def test_set_name_encodable_in_mac_roman(self):
|
|
89
103
|
# values encodable in mac roman are written in both windows and mac records
|
|
104
|
+
# if the font already has mac records
|
|
90
105
|
font = self._get_font("/Roboto_Mono/static/RobotoMono-Regular.ttf")
|
|
106
|
+
self._add_mac_name_record(font)
|
|
91
107
|
font.set_name(Font.NAME_FAMILY_NAME, "Café Sans")
|
|
92
108
|
self.assertEqual(
|
|
93
109
|
self._get_name_records_by_platform(font, 1),
|
|
@@ -95,11 +111,17 @@ class NamesTestCase(AbstractTestCase):
|
|
|
95
111
|
)
|
|
96
112
|
|
|
97
113
|
def test_set_name_not_encodable_in_mac_roman_removes_mac_record(self):
|
|
98
|
-
# an existing mac name record is removed to not keep an outdated value
|
|
114
|
+
# an existing mac name record is removed to not keep an outdated value,
|
|
115
|
+
# the name is still readable from the windows record
|
|
99
116
|
font = self._get_font("/Roboto_Mono/static/RobotoMono-Regular.ttf")
|
|
100
|
-
|
|
117
|
+
self._add_mac_name_record(font)
|
|
118
|
+
self.assertEqual(
|
|
119
|
+
self._get_name_records_by_platform(font, 1),
|
|
120
|
+
{1: "Roboto Mono", 3: "Roboto Mono"},
|
|
121
|
+
)
|
|
101
122
|
font.set_name(Font.NAME_FAMILY_NAME, "Шрифт")
|
|
102
123
|
self.assertEqual(self._get_name_records_by_platform(font, 1), {3: "Шрифт"})
|
|
124
|
+
self.assertEqual(font.get_name(Font.NAME_FAMILY_NAME), "Шрифт")
|
|
103
125
|
|
|
104
126
|
def test_rename_not_encodable_in_mac_roman(self):
|
|
105
127
|
# regression: renaming with non-latin names must not prevent saving
|
|
@@ -126,3 +148,59 @@ class NamesTestCase(AbstractTestCase):
|
|
|
126
148
|
self.assertEqual(family_name, "Roboto Mono Renamed")
|
|
127
149
|
subfamily_name = font.get_name(Font.NAME_SUBFAMILY_NAME)
|
|
128
150
|
self.assertEqual(subfamily_name, "Regular Renamed")
|
|
151
|
+
|
|
152
|
+
def test_get_names_consistent_with_get_name(self):
|
|
153
|
+
# regression: get_names returned the last name record found for each name id,
|
|
154
|
+
# (eg. the japanese family name), instead of the same value of get_name
|
|
155
|
+
font = self._get_font("/DotGothic16/DotGothic16-Regular.ttf")
|
|
156
|
+
font_names = font.get_names()
|
|
157
|
+
self.assertEqual(font_names["family_name"], "DotGothic16")
|
|
158
|
+
for key, value in font_names.items():
|
|
159
|
+
with self.subTest(key=key):
|
|
160
|
+
self.assertEqual(font.get_name(key), value)
|
|
161
|
+
|
|
162
|
+
def _replace_name_records(self, font, platform_id, plat_enc_id, lang_id):
|
|
163
|
+
# replace all the name records with records of the given platform/language
|
|
164
|
+
name_table = font.get_ttfont()["name"]
|
|
165
|
+
for record in list(name_table.names):
|
|
166
|
+
name_table.setName(
|
|
167
|
+
record.toUnicode(), record.nameID, platform_id, plat_enc_id, lang_id
|
|
168
|
+
)
|
|
169
|
+
for record in list(name_table.names):
|
|
170
|
+
if (record.platformID, record.platEncID, record.langID) != (
|
|
171
|
+
platform_id,
|
|
172
|
+
plat_enc_id,
|
|
173
|
+
lang_id,
|
|
174
|
+
):
|
|
175
|
+
name_table.names.remove(record)
|
|
176
|
+
|
|
177
|
+
def test_get_name_without_windows_english_records(self):
|
|
178
|
+
# regression: names were not found without windows english name records
|
|
179
|
+
platforms_ids = {
|
|
180
|
+
"unicode": (0, 3, 0),
|
|
181
|
+
"windows japanese": (3, 1, 0x411),
|
|
182
|
+
"mac english": (1, 0, 0),
|
|
183
|
+
}
|
|
184
|
+
for label, (platform_id, plat_enc_id, lang_id) in platforms_ids.items():
|
|
185
|
+
with self.subTest(records=label):
|
|
186
|
+
font = self._get_font("/Roboto_Mono/static/RobotoMono-Regular.ttf")
|
|
187
|
+
self._replace_name_records(font, platform_id, plat_enc_id, lang_id)
|
|
188
|
+
self.assertEqual(font.get_name(Font.NAME_FAMILY_NAME), "Roboto Mono")
|
|
189
|
+
self.assertEqual(font.get_family_name(), "Roboto Mono")
|
|
190
|
+
self.assertEqual(font.get_names()["family_name"], "Roboto Mono")
|
|
191
|
+
|
|
192
|
+
def test_get_name_with_undecodable_windows_record(self):
|
|
193
|
+
# an undecodable windows record is skipped, the other records are read
|
|
194
|
+
font = self._get_font("/Roboto_Mono/static/RobotoMono-Regular.ttf")
|
|
195
|
+
self._add_mac_name_record(font)
|
|
196
|
+
name_table = font.get_ttfont()["name"]
|
|
197
|
+
# lone utf-16 surrogate
|
|
198
|
+
name_table.getName(1, 3, 1, 0x409).string = b"\xd8\x00"
|
|
199
|
+
self.assertEqual(font.get_name(Font.NAME_FAMILY_NAME), "Roboto Mono")
|
|
200
|
+
|
|
201
|
+
def test_get_name_without_name_table(self):
|
|
202
|
+
font = self._get_font("/Roboto_Mono/static/RobotoMono-Regular.ttf")
|
|
203
|
+
del font.get_ttfont()["name"]
|
|
204
|
+
self.assertIsNone(font.get_name(Font.NAME_FAMILY_NAME))
|
|
205
|
+
self.assertEqual(font.get_names(), {})
|
|
206
|
+
self.assertEqual(font.get_family_name(), "")
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{python_fontbro-0.28.0 → python_fontbro-0.28.1}/python_fontbro.egg-info/dependency_links.txt
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|