python-fontbro 0.26.0__tar.gz → 0.27.0__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.26.0/python_fontbro.egg-info → python_fontbro-0.27.0}/PKG-INFO +2 -2
- {python_fontbro-0.26.0 → python_fontbro-0.27.0}/fontbro/font.py +75 -14
- {python_fontbro-0.26.0 → python_fontbro-0.27.0}/fontbro/metadata.py +1 -1
- {python_fontbro-0.26.0 → python_fontbro-0.27.0}/pyproject.toml +1 -1
- {python_fontbro-0.26.0 → python_fontbro-0.27.0/python_fontbro.egg-info}/PKG-INFO +2 -2
- {python_fontbro-0.26.0 → python_fontbro-0.27.0}/python_fontbro.egg-info/requires.txt +1 -1
- {python_fontbro-0.26.0 → python_fontbro-0.27.0}/tests/test_clone.py +15 -0
- {python_fontbro-0.26.0 → python_fontbro-0.27.0}/tests/test_filename.py +18 -8
- {python_fontbro-0.26.0 → python_fontbro-0.27.0}/tests/test_instantiation.py +15 -0
- {python_fontbro-0.26.0 → python_fontbro-0.27.0}/tests/test_sanitize.py +17 -0
- {python_fontbro-0.26.0 → python_fontbro-0.27.0}/tests/test_save.py +30 -0
- {python_fontbro-0.26.0 → python_fontbro-0.27.0}/tests/test_str.py +2 -2
- {python_fontbro-0.26.0 → python_fontbro-0.27.0}/LICENSE.txt +0 -0
- {python_fontbro-0.26.0 → python_fontbro-0.27.0}/MANIFEST.in +0 -0
- {python_fontbro-0.26.0 → python_fontbro-0.27.0}/README.md +0 -0
- {python_fontbro-0.26.0 → python_fontbro-0.27.0}/fontbro/__init__.py +0 -0
- {python_fontbro-0.26.0 → python_fontbro-0.27.0}/fontbro/data/family-classifications.json +0 -0
- {python_fontbro-0.26.0 → python_fontbro-0.27.0}/fontbro/data/features.json +0 -0
- {python_fontbro-0.26.0 → python_fontbro-0.27.0}/fontbro/data/unicode-blocks.json +0 -0
- {python_fontbro-0.26.0 → python_fontbro-0.27.0}/fontbro/data/unicode-scripts.json +0 -0
- {python_fontbro-0.26.0 → python_fontbro-0.27.0}/fontbro/exceptions.py +0 -0
- {python_fontbro-0.26.0 → python_fontbro-0.27.0}/fontbro/flags.py +0 -0
- {python_fontbro-0.26.0 → python_fontbro-0.27.0}/fontbro/math.py +0 -0
- {python_fontbro-0.26.0 → python_fontbro-0.27.0}/fontbro/py.typed +0 -0
- {python_fontbro-0.26.0 → python_fontbro-0.27.0}/fontbro/subset.py +0 -0
- {python_fontbro-0.26.0 → python_fontbro-0.27.0}/fontbro/utils.py +0 -0
- {python_fontbro-0.26.0 → python_fontbro-0.27.0}/python_fontbro.egg-info/SOURCES.txt +0 -0
- {python_fontbro-0.26.0 → python_fontbro-0.27.0}/python_fontbro.egg-info/dependency_links.txt +0 -0
- {python_fontbro-0.26.0 → python_fontbro-0.27.0}/python_fontbro.egg-info/top_level.txt +0 -0
- {python_fontbro-0.26.0 → python_fontbro-0.27.0}/setup.cfg +0 -0
- {python_fontbro-0.26.0 → python_fontbro-0.27.0}/setup.py +0 -0
- {python_fontbro-0.26.0 → python_fontbro-0.27.0}/tests/test_characters.py +0 -0
- {python_fontbro-0.26.0 → python_fontbro-0.27.0}/tests/test_close.py +0 -0
- {python_fontbro-0.26.0 → python_fontbro-0.27.0}/tests/test_collection.py +0 -0
- {python_fontbro-0.26.0 → python_fontbro-0.27.0}/tests/test_color.py +0 -0
- {python_fontbro-0.26.0 → python_fontbro-0.27.0}/tests/test_context_manager.py +0 -0
- {python_fontbro-0.26.0 → python_fontbro-0.27.0}/tests/test_family_classification.py +0 -0
- {python_fontbro-0.26.0 → python_fontbro-0.27.0}/tests/test_family_name.py +0 -0
- {python_fontbro-0.26.0 → python_fontbro-0.27.0}/tests/test_features.py +0 -0
- {python_fontbro-0.26.0 → python_fontbro-0.27.0}/tests/test_fingerprint.py +0 -0
- {python_fontbro-0.26.0 → python_fontbro-0.27.0}/tests/test_format.py +0 -0
- {python_fontbro-0.26.0 → python_fontbro-0.27.0}/tests/test_glyphs.py +0 -0
- {python_fontbro-0.26.0 → python_fontbro-0.27.0}/tests/test_image.py +0 -0
- {python_fontbro-0.26.0 → python_fontbro-0.27.0}/tests/test_init.py +0 -0
- {python_fontbro-0.26.0 → python_fontbro-0.27.0}/tests/test_issues.py +0 -0
- {python_fontbro-0.26.0 → python_fontbro-0.27.0}/tests/test_italic_angle.py +0 -0
- {python_fontbro-0.26.0 → python_fontbro-0.27.0}/tests/test_monospace.py +0 -0
- {python_fontbro-0.26.0 → python_fontbro-0.27.0}/tests/test_names.py +0 -0
- {python_fontbro-0.26.0 → python_fontbro-0.27.0}/tests/test_rename.py +0 -0
- {python_fontbro-0.26.0 → python_fontbro-0.27.0}/tests/test_style_flags.py +0 -0
- {python_fontbro-0.26.0 → python_fontbro-0.27.0}/tests/test_style_name.py +0 -0
- {python_fontbro-0.26.0 → python_fontbro-0.27.0}/tests/test_subset.py +0 -0
- {python_fontbro-0.26.0 → python_fontbro-0.27.0}/tests/test_svg.py +0 -0
- {python_fontbro-0.26.0 → python_fontbro-0.27.0}/tests/test_unicode_blocks_and_scripts.py +0 -0
- {python_fontbro-0.26.0 → python_fontbro-0.27.0}/tests/test_update_unicode_data.py +0 -0
- {python_fontbro-0.26.0 → python_fontbro-0.27.0}/tests/test_variable.py +0 -0
- {python_fontbro-0.26.0 → python_fontbro-0.27.0}/tests/test_version.py +0 -0
- {python_fontbro-0.26.0 → python_fontbro-0.27.0}/tests/test_vertical_metrics.py +0 -0
- {python_fontbro-0.26.0 → python_fontbro-0.27.0}/tests/test_weight.py +0 -0
- {python_fontbro-0.26.0 → python_fontbro-0.27.0}/tests/test_width.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: python-fontbro
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.27.0
|
|
4
4
|
Summary: friendly font operations on top of fontTools.
|
|
5
5
|
Author-email: Fabio Caccamo <fabio.caccamo@gmail.com>
|
|
6
6
|
Maintainer-email: Fabio Caccamo <fabio.caccamo@gmail.com>
|
|
@@ -57,7 +57,7 @@ License-File: LICENSE.txt
|
|
|
57
57
|
Requires-Dist: fonttools[lxml,pathops,unicode,woff]<5.0,>=4.43.0
|
|
58
58
|
Requires-Dist: imagehash<5.0.0,>=4.2.1
|
|
59
59
|
Requires-Dist: opentype-sanitizer<10.0.0,>=9.1.0
|
|
60
|
-
Requires-Dist: pillow<13.0.0,>=
|
|
60
|
+
Requires-Dist: pillow<13.0.0,>=12.2.0
|
|
61
61
|
Requires-Dist: python-fsutil<1.0.0,>=0.16.0
|
|
62
62
|
Dynamic: license-file
|
|
63
63
|
|
|
@@ -8,7 +8,6 @@ import sys
|
|
|
8
8
|
import tempfile
|
|
9
9
|
from collections import Counter
|
|
10
10
|
from collections.abc import Generator
|
|
11
|
-
from curses import ascii
|
|
12
11
|
from io import BytesIO
|
|
13
12
|
from pathlib import Path
|
|
14
13
|
from typing import IO, Any, cast
|
|
@@ -489,9 +488,13 @@ class Font:
|
|
|
489
488
|
self,
|
|
490
489
|
) -> Font:
|
|
491
490
|
"""
|
|
492
|
-
Creates a new Font instance
|
|
491
|
+
Creates a new Font instance with the current in-memory state,
|
|
492
|
+
including any modifications made to the current instance.
|
|
493
493
|
"""
|
|
494
|
-
|
|
494
|
+
font = self.get_ttfont()
|
|
495
|
+
font_clone = Font(font, **self._kwargs)
|
|
496
|
+
font_clone._filepath = self._filepath
|
|
497
|
+
return font_clone
|
|
495
498
|
|
|
496
499
|
def close(
|
|
497
500
|
self,
|
|
@@ -550,7 +553,9 @@ class Font:
|
|
|
550
553
|
char = chr(code)
|
|
551
554
|
else:
|
|
552
555
|
continue
|
|
553
|
-
if
|
|
556
|
+
# check if is control character
|
|
557
|
+
char_code = ord(char)
|
|
558
|
+
if char_code < 0x20 or char_code == 0x7F:
|
|
554
559
|
continue
|
|
555
560
|
if glyfs and ignore_blank:
|
|
556
561
|
glyf = glyfs.get(char_name)
|
|
@@ -707,20 +712,23 @@ class Font:
|
|
|
707
712
|
def get_filename(
|
|
708
713
|
self,
|
|
709
714
|
*,
|
|
710
|
-
variable_suffix: str = "
|
|
715
|
+
variable_suffix: str = "",
|
|
711
716
|
variable_axes_tags: bool = True,
|
|
712
717
|
variable_axes_values: bool = False,
|
|
713
718
|
) -> str:
|
|
714
719
|
"""
|
|
715
720
|
Gets the filename to use for saving the font to file-system.
|
|
716
721
|
|
|
717
|
-
:param variable_suffix: The variable suffix, default
|
|
722
|
+
:param variable_suffix: The variable suffix, default empty string (no suffix).
|
|
723
|
+
Suffixes like 'Variable' or 'VF' or any other are not recommended
|
|
724
|
+
per Google Fonts naming convention. Pass a custom suffix only if needed,
|
|
725
|
+
e.g. variable_suffix='Variable' -> 'FamilyName-Variable[wght].ttf'.
|
|
718
726
|
:type variable_suffix: str
|
|
719
727
|
:param variable_axes_tags: The variable axes tags flag,
|
|
720
|
-
if True, the axes tags will be appended, eg '[wght
|
|
728
|
+
if True, the axes tags will be appended, eg '[wdth,wght]'
|
|
721
729
|
:type variable_axes_tags: bool
|
|
722
|
-
:param variable_axes_values: The variable axes values flag
|
|
723
|
-
if True, each axis values will be appended, eg '[
|
|
730
|
+
:param variable_axes_values: The variable axes values flag,
|
|
731
|
+
if True, each axis values will be appended, eg '[wdth(75,100,125),wght(100,400,900)]'
|
|
724
732
|
:type variable_axes_values: bool
|
|
725
733
|
|
|
726
734
|
:returns: The filename.
|
|
@@ -742,7 +750,7 @@ class Font:
|
|
|
742
750
|
basename = f"{basename}-{variable_suffix}"
|
|
743
751
|
# append axis tags stringified suffix, eg. [wdth,wght,slnt]
|
|
744
752
|
if variable_axes_tags:
|
|
745
|
-
axes = self.get_variable_axes() or []
|
|
753
|
+
axes = self.get_variable_axes(sort=True) or []
|
|
746
754
|
axes_str_parts = []
|
|
747
755
|
for axis in axes:
|
|
748
756
|
axis_tag = axis["tag"]
|
|
@@ -1282,17 +1290,23 @@ class Font:
|
|
|
1282
1290
|
|
|
1283
1291
|
def get_variable_axes(
|
|
1284
1292
|
self,
|
|
1293
|
+
*,
|
|
1294
|
+
sort: bool = False,
|
|
1285
1295
|
) -> list[dict[str, Any]] | None:
|
|
1286
1296
|
"""
|
|
1287
1297
|
Gets the font variable axes.
|
|
1288
1298
|
|
|
1299
|
+
:param sort: If True, axes are sorted following the Google Fonts naming convention:
|
|
1300
|
+
uppercase custom axes first, then lowercase standard axes, each group alphabetical.
|
|
1301
|
+
:type sort: bool
|
|
1302
|
+
|
|
1289
1303
|
:returns: The list of axes if the font is a variable font otherwise None.
|
|
1290
1304
|
:rtype: list of dict or None
|
|
1291
1305
|
"""
|
|
1292
1306
|
if not self.is_variable():
|
|
1293
1307
|
return None
|
|
1294
1308
|
font = self.get_ttfont()
|
|
1295
|
-
|
|
1309
|
+
axes = [
|
|
1296
1310
|
{
|
|
1297
1311
|
"tag": axis.axisTag,
|
|
1298
1312
|
"name": self._VARIABLE_AXES_BY_TAG.get(axis.axisTag, {}).get(
|
|
@@ -1304,6 +1318,12 @@ class Font:
|
|
|
1304
1318
|
}
|
|
1305
1319
|
for axis in font["fvar"].axes
|
|
1306
1320
|
]
|
|
1321
|
+
if sort:
|
|
1322
|
+
axes = sorted(
|
|
1323
|
+
axes,
|
|
1324
|
+
key=lambda axis: (axis["tag"].islower(), axis["tag"]),
|
|
1325
|
+
)
|
|
1326
|
+
return axes
|
|
1307
1327
|
|
|
1308
1328
|
def get_variable_axis_by_tag(
|
|
1309
1329
|
self,
|
|
@@ -1759,7 +1779,7 @@ class Font:
|
|
|
1759
1779
|
def _save_with_flavor(
|
|
1760
1780
|
self,
|
|
1761
1781
|
*,
|
|
1762
|
-
flavor: str,
|
|
1782
|
+
flavor: str | None,
|
|
1763
1783
|
filepath: str | Path | None = None,
|
|
1764
1784
|
overwrite: bool = True,
|
|
1765
1785
|
) -> str:
|
|
@@ -1776,6 +1796,30 @@ class Font:
|
|
|
1776
1796
|
# return file path
|
|
1777
1797
|
return saved_font_filepath
|
|
1778
1798
|
|
|
1799
|
+
def save_as_ttf(
|
|
1800
|
+
self,
|
|
1801
|
+
filepath: str | Path | None = None,
|
|
1802
|
+
*,
|
|
1803
|
+
overwrite: bool = True,
|
|
1804
|
+
) -> str:
|
|
1805
|
+
"""
|
|
1806
|
+
Saves font without web compression (woff/woff2 flavor is removed).
|
|
1807
|
+
The resulting format will be ttf or otf depending on the source font.
|
|
1808
|
+
|
|
1809
|
+
:param filepath: The filepath
|
|
1810
|
+
:type filepath: str or None
|
|
1811
|
+
:param overwrite: The overwrite, if True the source font file can be overwritten
|
|
1812
|
+
:type overwrite: bool
|
|
1813
|
+
|
|
1814
|
+
:returns: The filepath where the font has been saved to.
|
|
1815
|
+
:rtype: str
|
|
1816
|
+
"""
|
|
1817
|
+
return self._save_with_flavor(
|
|
1818
|
+
flavor=None,
|
|
1819
|
+
filepath=filepath,
|
|
1820
|
+
overwrite=overwrite,
|
|
1821
|
+
)
|
|
1822
|
+
|
|
1779
1823
|
def save_as_woff(
|
|
1780
1824
|
self,
|
|
1781
1825
|
filepath: str | Path | None = None,
|
|
@@ -1877,7 +1921,7 @@ class Font:
|
|
|
1877
1921
|
fsutil.assert_not_file(dirpath)
|
|
1878
1922
|
fsutil.make_dirs(dirpath)
|
|
1879
1923
|
|
|
1880
|
-
instances_format = self.get_format()
|
|
1924
|
+
instances_format = self.get_format(ignore_flavor=True)
|
|
1881
1925
|
instances_saved = []
|
|
1882
1926
|
instances = self.get_variable_instances() or []
|
|
1883
1927
|
for instance in instances:
|
|
@@ -1896,7 +1940,7 @@ class Font:
|
|
|
1896
1940
|
Font.FORMAT_WOFF2: None,
|
|
1897
1941
|
Font.FORMAT_WOFF: None,
|
|
1898
1942
|
}
|
|
1899
|
-
instance_files[instances_format] = instance_font.
|
|
1943
|
+
instance_files[instances_format] = instance_font.save_as_ttf(
|
|
1900
1944
|
dirpath,
|
|
1901
1945
|
overwrite=overwrite,
|
|
1902
1946
|
)
|
|
@@ -2317,6 +2361,10 @@ class Font:
|
|
|
2317
2361
|
# instantiate the static font
|
|
2318
2362
|
instancer.instantiateVariableFont(font, coordinates, **options)
|
|
2319
2363
|
|
|
2364
|
+
# remove STAT table
|
|
2365
|
+
# not useful in static fonts and after instancing it may contain incorrect values
|
|
2366
|
+
self._remove_stat_table()
|
|
2367
|
+
|
|
2320
2368
|
# update name records and style flags based on instance style name
|
|
2321
2369
|
if instance and update_names:
|
|
2322
2370
|
self.rename(
|
|
@@ -2331,6 +2379,19 @@ class Font:
|
|
|
2331
2379
|
if has_italic or has_slant:
|
|
2332
2380
|
self.set_style_flags(regular=False, italic=True)
|
|
2333
2381
|
|
|
2382
|
+
def _remove_stat_table(self) -> bool:
|
|
2383
|
+
"""
|
|
2384
|
+
Removes the STAT table from the font.
|
|
2385
|
+
|
|
2386
|
+
:returns: True if the STAT table was removed, False if it was not present.
|
|
2387
|
+
:rtype: bool
|
|
2388
|
+
"""
|
|
2389
|
+
font = self.get_ttfont()
|
|
2390
|
+
if "STAT" in font:
|
|
2391
|
+
del font["STAT"]
|
|
2392
|
+
return True
|
|
2393
|
+
return False
|
|
2394
|
+
|
|
2334
2395
|
def __str__(
|
|
2335
2396
|
self,
|
|
2336
2397
|
) -> str:
|
|
@@ -54,7 +54,7 @@ dependencies = [
|
|
|
54
54
|
"fonttools[lxml,woff,unicode,pathops] >= 4.43.0, < 5.0",
|
|
55
55
|
"imagehash >= 4.2.1, < 5.0.0",
|
|
56
56
|
"opentype-sanitizer >= 9.1.0, < 10.0.0",
|
|
57
|
-
"pillow >=
|
|
57
|
+
"pillow >= 12.2.0, < 13.0.0",
|
|
58
58
|
"python-fsutil >= 0.16.0, < 1.0.0",
|
|
59
59
|
]
|
|
60
60
|
dynamic = ["version"]
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: python-fontbro
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.27.0
|
|
4
4
|
Summary: friendly font operations on top of fontTools.
|
|
5
5
|
Author-email: Fabio Caccamo <fabio.caccamo@gmail.com>
|
|
6
6
|
Maintainer-email: Fabio Caccamo <fabio.caccamo@gmail.com>
|
|
@@ -57,7 +57,7 @@ License-File: LICENSE.txt
|
|
|
57
57
|
Requires-Dist: fonttools[lxml,pathops,unicode,woff]<5.0,>=4.43.0
|
|
58
58
|
Requires-Dist: imagehash<5.0.0,>=4.2.1
|
|
59
59
|
Requires-Dist: opentype-sanitizer<10.0.0,>=9.1.0
|
|
60
|
-
Requires-Dist: pillow<13.0.0,>=
|
|
60
|
+
Requires-Dist: pillow<13.0.0,>=12.2.0
|
|
61
61
|
Requires-Dist: python-fsutil<1.0.0,>=0.16.0
|
|
62
62
|
Dynamic: license-file
|
|
63
63
|
|
|
@@ -45,3 +45,18 @@ class CloneTestCase(AbstractTestCase):
|
|
|
45
45
|
font_clone = font2.clone()
|
|
46
46
|
self.assertFalse(font2 == font_clone)
|
|
47
47
|
self.assertEqual(f"{font2}", f"{font_clone}")
|
|
48
|
+
|
|
49
|
+
def test_clone_preserves_in_memory_changes(self):
|
|
50
|
+
filepath = self._get_font_path("/Noto_Sans_TC/NotoSansTC-Regular.otf")
|
|
51
|
+
font = Font(filepath)
|
|
52
|
+
font.set_name(Font.NAME_FAMILY_NAME, "NotoSansTCCustom")
|
|
53
|
+
font_clone = font.clone()
|
|
54
|
+
self.assertEqual(
|
|
55
|
+
font_clone.get_name(Font.NAME_FAMILY_NAME),
|
|
56
|
+
font.get_name(Font.NAME_FAMILY_NAME),
|
|
57
|
+
)
|
|
58
|
+
self.assertEqual(
|
|
59
|
+
font_clone.get_name(Font.NAME_FAMILY_NAME),
|
|
60
|
+
"NotoSansTCCustom",
|
|
61
|
+
)
|
|
62
|
+
self.assertEqual(font_clone._filepath, filepath)
|
|
@@ -23,28 +23,38 @@ class FilenameTestCase(AbstractTestCase):
|
|
|
23
23
|
font = self._get_font("/Tourney/Tourney-Italic-VariableFont_wdth,wght.ttf")
|
|
24
24
|
self.assertEqual(
|
|
25
25
|
font.get_filename(),
|
|
26
|
-
"Tourney-Italic
|
|
26
|
+
"Tourney-Italic[wdth,wght].ttf",
|
|
27
27
|
)
|
|
28
28
|
|
|
29
29
|
font = self._get_font("/Tourney/Tourney-VariableFont_wdth,wght.ttf")
|
|
30
30
|
self.assertEqual(
|
|
31
31
|
font.get_filename(),
|
|
32
|
-
"Tourney
|
|
32
|
+
"Tourney[wdth,wght].ttf",
|
|
33
33
|
)
|
|
34
34
|
|
|
35
35
|
font = self._get_font("/Roboto_Mono/RobotoMono-Italic-VariableFont_wght.ttf")
|
|
36
36
|
self.assertEqual(
|
|
37
37
|
font.get_filename(),
|
|
38
|
-
"RobotoMono-Italic
|
|
38
|
+
"RobotoMono-Italic[wght].ttf",
|
|
39
39
|
)
|
|
40
40
|
|
|
41
41
|
font = self._get_font("/Roboto_Mono/RobotoMono-VariableFont_wght.ttf")
|
|
42
42
|
self.assertEqual(
|
|
43
43
|
font.get_filename(),
|
|
44
|
-
"RobotoMono
|
|
44
|
+
"RobotoMono[wght].ttf",
|
|
45
45
|
)
|
|
46
46
|
|
|
47
47
|
def test_get_filename_with_variable_font_and_custom_suffixes(self):
|
|
48
|
+
font = self._get_font("/Tourney/Tourney-VariableFont_wdth,wght.ttf")
|
|
49
|
+
self.assertEqual(
|
|
50
|
+
font.get_filename(
|
|
51
|
+
variable_suffix="Variable",
|
|
52
|
+
variable_axes_tags=False,
|
|
53
|
+
variable_axes_values=False,
|
|
54
|
+
),
|
|
55
|
+
"Tourney-Variable.ttf",
|
|
56
|
+
)
|
|
57
|
+
|
|
48
58
|
font = self._get_font("/Tourney/Tourney-VariableFont_wdth,wght.ttf")
|
|
49
59
|
self.assertEqual(
|
|
50
60
|
font.get_filename(
|
|
@@ -71,7 +81,7 @@ class FilenameTestCase(AbstractTestCase):
|
|
|
71
81
|
variable_suffix="VF",
|
|
72
82
|
variable_axes_tags=True,
|
|
73
83
|
),
|
|
74
|
-
"Tourney-VF[wght
|
|
84
|
+
"Tourney-VF[wdth,wght].ttf",
|
|
75
85
|
)
|
|
76
86
|
|
|
77
87
|
font = self._get_font("/Tourney/Tourney-VariableFont_wdth,wght.ttf")
|
|
@@ -81,7 +91,7 @@ class FilenameTestCase(AbstractTestCase):
|
|
|
81
91
|
variable_axes_tags=True,
|
|
82
92
|
variable_axes_values=True,
|
|
83
93
|
),
|
|
84
|
-
"Tourney-VF[
|
|
94
|
+
"Tourney-VF[wdth(75,100,125),wght(100,100,900)].ttf",
|
|
85
95
|
)
|
|
86
96
|
|
|
87
97
|
font = self._get_font("/Tourney/Tourney-VariableFont_wdth,wght.ttf")
|
|
@@ -90,7 +100,7 @@ class FilenameTestCase(AbstractTestCase):
|
|
|
90
100
|
variable_suffix="",
|
|
91
101
|
variable_axes_tags=True,
|
|
92
102
|
),
|
|
93
|
-
"Tourney[wght
|
|
103
|
+
"Tourney[wdth,wght].ttf",
|
|
94
104
|
)
|
|
95
105
|
|
|
96
106
|
font = self._get_font("/Tourney/Tourney-VariableFont_wdth,wght.ttf")
|
|
@@ -100,7 +110,7 @@ class FilenameTestCase(AbstractTestCase):
|
|
|
100
110
|
variable_axes_tags=True,
|
|
101
111
|
variable_axes_values=True,
|
|
102
112
|
),
|
|
103
|
-
"Tourney[
|
|
113
|
+
"Tourney[wdth(75,100,125),wght(100,100,900)].ttf",
|
|
104
114
|
)
|
|
105
115
|
|
|
106
116
|
font = self._get_font("/Tourney/Tourney-VariableFont_wdth,wght.ttf")
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
from fontbro import Font
|
|
1
2
|
from tests import AbstractTestCase
|
|
2
3
|
|
|
3
4
|
|
|
@@ -131,6 +132,20 @@ class InstantiationTestCase(AbstractTestCase):
|
|
|
131
132
|
)
|
|
132
133
|
self.assertFalse(font.get_style_flag("italic"))
|
|
133
134
|
|
|
135
|
+
def test_to_static_removes_stat_table(self):
|
|
136
|
+
font = self._get_variable_font()
|
|
137
|
+
self.assertIn("STAT", font.get_ttfont())
|
|
138
|
+
font.to_static(coordinates={"wght": 400, "wdth": 100})
|
|
139
|
+
self.assertNotIn("STAT", font.get_ttfont())
|
|
140
|
+
|
|
141
|
+
def test_to_static_stat_table_not_present_in_saved_file(self):
|
|
142
|
+
font = self._get_variable_font()
|
|
143
|
+
font.to_static(coordinates={"wght": 400, "wdth": 100})
|
|
144
|
+
output_filepath = self._get_font_temp_path("")
|
|
145
|
+
font_saved_filepath = font.save(output_filepath, overwrite=True)
|
|
146
|
+
font_saved = Font(font_saved_filepath)
|
|
147
|
+
self.assertNotIn("STAT", font_saved.get_ttfont())
|
|
148
|
+
|
|
134
149
|
def test_to_sliced_variable_with_static_font(self):
|
|
135
150
|
font = self._get_static_font()
|
|
136
151
|
with self.assertRaises(TypeError):
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import logging
|
|
2
|
+
|
|
1
3
|
import fsutil
|
|
2
4
|
|
|
3
5
|
from fontbro import Font
|
|
@@ -9,6 +11,21 @@ class SanitizeTestCase(AbstractTestCase):
|
|
|
9
11
|
This class describes a sanitize test case.
|
|
10
12
|
"""
|
|
11
13
|
|
|
14
|
+
# fontTools uses log.error()/log.warning() when parsing malformed tables
|
|
15
|
+
# (e.g. "skipping malformed name record", "timestamp out of range").
|
|
16
|
+
# NullHandler prevents Python's lastResort from printing them to stderr.
|
|
17
|
+
_fonttools_null_handler = logging.NullHandler()
|
|
18
|
+
|
|
19
|
+
@classmethod
|
|
20
|
+
def setUpClass(cls):
|
|
21
|
+
super().setUpClass()
|
|
22
|
+
logging.getLogger("fontTools").addHandler(cls._fonttools_null_handler)
|
|
23
|
+
|
|
24
|
+
@classmethod
|
|
25
|
+
def tearDownClass(cls):
|
|
26
|
+
logging.getLogger("fontTools").removeHandler(cls._fonttools_null_handler)
|
|
27
|
+
super().tearDownClass()
|
|
28
|
+
|
|
12
29
|
def _test_sanitize(
|
|
13
30
|
self,
|
|
14
31
|
dirpath,
|
|
@@ -191,3 +191,33 @@ class SaveTestCase(AbstractTestCase):
|
|
|
191
191
|
output_dirpath = self._get_font_temp_path("")
|
|
192
192
|
with self.assertRaises(TypeError):
|
|
193
193
|
font.save_variable_instances(output_dirpath)
|
|
194
|
+
|
|
195
|
+
def test_save_as_ttf_from_woff(self):
|
|
196
|
+
# create woff2 on the fly
|
|
197
|
+
font = self._get_font("/Roboto_Mono/static/RobotoMono-Regular.ttf")
|
|
198
|
+
woff_filepath = self._get_font_temp_path("RobotoMono-Regular.woff")
|
|
199
|
+
font.save_as_woff(woff_filepath, overwrite=True)
|
|
200
|
+
# create font instance from woff file
|
|
201
|
+
font_woff = Font(woff_filepath)
|
|
202
|
+
output_filepath = self._get_font_temp_path("")
|
|
203
|
+
font_saved_filepath = font_woff.save_as_ttf(output_filepath)
|
|
204
|
+
self.assertTrue(font_saved_filepath.endswith(".ttf"))
|
|
205
|
+
# ensure that the original font format is not changed
|
|
206
|
+
self.assertEqual(font_woff.get_format(), Font.FORMAT_WOFF)
|
|
207
|
+
font_saved = Font(font_saved_filepath)
|
|
208
|
+
self.assertEqual(font_saved.get_format(), Font.FORMAT_TTF)
|
|
209
|
+
|
|
210
|
+
def test_save_as_ttf_from_woff2(self):
|
|
211
|
+
# create woff2 on the fly
|
|
212
|
+
font = self._get_font("/Roboto_Mono/static/RobotoMono-Regular.ttf")
|
|
213
|
+
woff2_filepath = self._get_font_temp_path("RobotoMono-Regular.woff2")
|
|
214
|
+
font.save_as_woff2(woff2_filepath, overwrite=True)
|
|
215
|
+
# create font instance from woff2 file
|
|
216
|
+
font_woff2 = Font(woff2_filepath)
|
|
217
|
+
output_filepath = self._get_font_temp_path("")
|
|
218
|
+
font_saved_filepath = font_woff2.save_as_ttf(output_filepath)
|
|
219
|
+
self.assertTrue(font_saved_filepath.endswith(".ttf"))
|
|
220
|
+
# ensure that the original font format is not changed
|
|
221
|
+
self.assertEqual(font_woff2.get_format(), Font.FORMAT_WOFF2)
|
|
222
|
+
font_saved = Font(font_saved_filepath)
|
|
223
|
+
self.assertEqual(font_saved.get_format(), Font.FORMAT_TTF)
|
|
@@ -10,5 +10,5 @@ class StrTestCase(AbstractTestCase):
|
|
|
10
10
|
filepath = "/Roboto_Mono/static/RobotoMono-Regular.ttf"
|
|
11
11
|
font = self._get_font(filepath)
|
|
12
12
|
s = str(font)
|
|
13
|
-
|
|
14
|
-
self.
|
|
13
|
+
expected = f"Font('{font._filepath}')"
|
|
14
|
+
self.assertEqual(s, expected)
|
|
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.26.0 → python_fontbro-0.27.0}/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
|