manimpango 0.2.6__tar.gz → 0.3.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.
- {ManimPango-0.2.6 → ManimPango-0.3.0}/ManimPango.egg-info/PKG-INFO +1 -1
- {ManimPango-0.2.6 → ManimPango-0.3.0}/ManimPango.egg-info/SOURCES.txt +1 -2
- {ManimPango-0.2.6 → ManimPango-0.3.0}/PKG-INFO +1 -1
- {ManimPango-0.2.6 → ManimPango-0.3.0}/manimpango/_version.py +1 -1
- {ManimPango-0.2.6 → ManimPango-0.3.0}/manimpango/cmanimpango.pyx +33 -3
- {ManimPango-0.2.6 → ManimPango-0.3.0}/manimpango/glib.pxd +5 -0
- {ManimPango-0.2.6 → ManimPango-0.3.0}/manimpango/register_font.pxd +14 -12
- {ManimPango-0.2.6 → ManimPango-0.3.0}/manimpango/register_font.pyx +73 -53
- {ManimPango-0.2.6 → ManimPango-0.3.0}/setup.py +10 -4
- {ManimPango-0.2.6 → ManimPango-0.3.0}/tests/__init__.py +0 -8
- {ManimPango-0.2.6 → ManimPango-0.3.0}/tests/_manim.py +1 -1
- ManimPango-0.3.0/tests/conftest.py +129 -0
- {ManimPango-0.2.6 → ManimPango-0.3.0}/tests/fonts/LICENSE.txt +1 -1
- ManimPango-0.3.0/tests/fonts/MaShanZheng-Regular.ttf +0 -0
- ManimPango-0.3.0/tests/test_fonts.py +122 -0
- {ManimPango-0.2.6 → ManimPango-0.3.0}/tests/test_list_fonts.py +6 -6
- {ManimPango-0.2.6 → ManimPango-0.3.0}/tests/test_markup.py +30 -18
- ManimPango-0.2.6/tests/conftest.py +0 -10
- ManimPango-0.2.6/tests/fonts/NotoNastaliqUrdu-Regular.ttf +0 -0
- ManimPango-0.2.6/tests/test_fonts.py +0 -97
- ManimPango-0.2.6/tests/test_import.py +0 -5
- {ManimPango-0.2.6 → ManimPango-0.3.0}/.coveragerc +0 -0
- {ManimPango-0.2.6 → ManimPango-0.3.0}/CODE_OF_CONDUCT.md +0 -0
- {ManimPango-0.2.6 → ManimPango-0.3.0}/LICENSE +0 -0
- {ManimPango-0.2.6 → ManimPango-0.3.0}/MANIFEST.in +0 -0
- {ManimPango-0.2.6 → ManimPango-0.3.0}/ManimPango.egg-info/dependency_links.txt +0 -0
- {ManimPango-0.2.6 → ManimPango-0.3.0}/ManimPango.egg-info/not-zip-safe +0 -0
- {ManimPango-0.2.6 → ManimPango-0.3.0}/ManimPango.egg-info/top_level.txt +0 -0
- {ManimPango-0.2.6 → ManimPango-0.3.0}/README.md +0 -0
- {ManimPango-0.2.6 → ManimPango-0.3.0}/docs/RELEASE.rst +0 -0
- {ManimPango-0.2.6 → ManimPango-0.3.0}/docs/_static/favicon.ico +0 -0
- {ManimPango-0.2.6 → ManimPango-0.3.0}/docs/_templates/autosummary/class.rst +0 -0
- {ManimPango-0.2.6 → ManimPango-0.3.0}/docs/_templates/autosummary/module.rst +0 -0
- {ManimPango-0.2.6 → ManimPango-0.3.0}/docs/conf.py +0 -0
- {ManimPango-0.2.6 → ManimPango-0.3.0}/docs/index.rst +0 -0
- {ManimPango-0.2.6 → ManimPango-0.3.0}/docs/make.bat +0 -0
- {ManimPango-0.2.6 → ManimPango-0.3.0}/docs/reference.rst +0 -0
- {ManimPango-0.2.6 → ManimPango-0.3.0}/manimpango/__init__.py +0 -0
- {ManimPango-0.2.6 → ManimPango-0.3.0}/manimpango/cairo.pxd +0 -0
- {ManimPango-0.2.6 → ManimPango-0.3.0}/manimpango/cmanimpango.pxd +0 -0
- {ManimPango-0.2.6 → ManimPango-0.3.0}/manimpango/enums.pyx +0 -0
- {ManimPango-0.2.6 → ManimPango-0.3.0}/manimpango/pango.pxd +0 -0
- {ManimPango-0.2.6 → ManimPango-0.3.0}/manimpango/utils.py +0 -0
- {ManimPango-0.2.6 → ManimPango-0.3.0}/pyproject.toml +0 -0
- {ManimPango-0.2.6 → ManimPango-0.3.0}/requirements-dev.txt +0 -0
- {ManimPango-0.2.6 → ManimPango-0.3.0}/setup.cfg +0 -0
- {ManimPango-0.2.6 → ManimPango-0.3.0}/tests/fonts/AdobeVFPrototype.ttf +0 -0
- {ManimPango-0.2.6 → ManimPango-0.3.0}/tests/fonts/BungeeColor-Regular_colr_Windows.ttf +0 -0
- {ManimPango-0.2.6 → ManimPango-0.3.0}/tests/fonts/BungeeOutline-Regular.ttf +0 -0
- {ManimPango-0.2.6 → ManimPango-0.3.0}/tests/svg_tester.py +0 -0
- {ManimPango-0.2.6 → ManimPango-0.3.0}/tests/test_utils.py +0 -0
- {ManimPango-0.2.6 → ManimPango-0.3.0}/tests/test_version.py +0 -0
|
@@ -36,7 +36,6 @@ tests/_manim.py
|
|
|
36
36
|
tests/conftest.py
|
|
37
37
|
tests/svg_tester.py
|
|
38
38
|
tests/test_fonts.py
|
|
39
|
-
tests/test_import.py
|
|
40
39
|
tests/test_list_fonts.py
|
|
41
40
|
tests/test_markup.py
|
|
42
41
|
tests/test_utils.py
|
|
@@ -45,4 +44,4 @@ tests/fonts/AdobeVFPrototype.ttf
|
|
|
45
44
|
tests/fonts/BungeeColor-Regular_colr_Windows.ttf
|
|
46
45
|
tests/fonts/BungeeOutline-Regular.ttf
|
|
47
46
|
tests/fonts/LICENSE.txt
|
|
48
|
-
tests/fonts/
|
|
47
|
+
tests/fonts/MaShanZheng-Regular.ttf
|
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
# -*- coding: utf-8 -*-
|
|
2
|
-
__version__ = "0.
|
|
2
|
+
__version__ = "0.3.0"
|
|
@@ -134,9 +134,39 @@ def text2svg(
|
|
|
134
134
|
|
|
135
135
|
class MarkupUtils:
|
|
136
136
|
@staticmethod
|
|
137
|
-
def validate(
|
|
138
|
-
|
|
139
|
-
return
|
|
137
|
+
def validate(markup: str) -> str:
|
|
138
|
+
"""Validates whether markup is a valid Markup
|
|
139
|
+
and return the error's if any.
|
|
140
|
+
|
|
141
|
+
Parameters
|
|
142
|
+
==========
|
|
143
|
+
markup : :class:`str`
|
|
144
|
+
The markup which should be checked.
|
|
145
|
+
|
|
146
|
+
Returns
|
|
147
|
+
=======
|
|
148
|
+
:class:`str`
|
|
149
|
+
Returns empty string if markup is valid. If markup
|
|
150
|
+
contains error it return the error message.
|
|
151
|
+
|
|
152
|
+
"""
|
|
153
|
+
cdef GError *err = NULL
|
|
154
|
+
text_bytes = markup.encode("utf-8")
|
|
155
|
+
res = pango_parse_markup(
|
|
156
|
+
text_bytes,
|
|
157
|
+
-1,
|
|
158
|
+
0,
|
|
159
|
+
NULL,
|
|
160
|
+
NULL,
|
|
161
|
+
NULL,
|
|
162
|
+
&err
|
|
163
|
+
)
|
|
164
|
+
if res:
|
|
165
|
+
return ""
|
|
166
|
+
else:
|
|
167
|
+
message = <bytes>err.message
|
|
168
|
+
g_error_free(err)
|
|
169
|
+
return message.decode('utf-8')
|
|
140
170
|
|
|
141
171
|
@staticmethod
|
|
142
172
|
def text2svg(
|
|
@@ -4,5 +4,10 @@ cdef extern from "glib.h":
|
|
|
4
4
|
ctypedef unsigned int guint
|
|
5
5
|
ctypedef gint gboolean
|
|
6
6
|
ctypedef unsigned short guint16
|
|
7
|
+
ctypedef char gchar
|
|
8
|
+
ctypedef struct GError:
|
|
9
|
+
gint code
|
|
10
|
+
gchar *message
|
|
11
|
+
void g_error_free (GError *error)
|
|
7
12
|
void g_object_unref(gpointer object)
|
|
8
13
|
void g_free(gpointer mem)
|
|
@@ -1,15 +1,17 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
1
|
+
|
|
2
|
+
cdef extern from "fontconfig/fontconfig.h":
|
|
3
|
+
ctypedef int FcBool
|
|
4
|
+
ctypedef struct FcConfig:
|
|
5
|
+
pass
|
|
6
|
+
FcBool FcConfigAppFontAddFile(
|
|
7
|
+
FcConfig* config,
|
|
8
|
+
const unsigned char* file_name
|
|
9
|
+
)
|
|
10
|
+
FcConfig* FcConfigGetCurrent()
|
|
11
|
+
void FcConfigAppFontClear(void *)
|
|
12
|
+
|
|
13
|
+
# Windows and macOS specific API's
|
|
14
|
+
IF UNAME_SYSNAME == "Windows":
|
|
13
15
|
cdef extern from "windows.h":
|
|
14
16
|
ctypedef Py_UNICODE WCHAR
|
|
15
17
|
ctypedef const WCHAR* LPCWSTR
|
|
@@ -1,61 +1,74 @@
|
|
|
1
1
|
from pathlib import Path
|
|
2
2
|
from pango cimport *
|
|
3
3
|
import copy
|
|
4
|
-
IF UNAME_SYSNAME == "Linux":
|
|
5
|
-
cpdef bint register_font(str font_path):
|
|
6
|
-
"""This function registers the font file using ``fontconfig`` so that
|
|
7
|
-
it is available for use by Pango.
|
|
8
|
-
Parameters
|
|
9
|
-
==========
|
|
10
|
-
font_path : :class:`str`
|
|
11
|
-
Relative or absolute path to font file.
|
|
12
|
-
Returns
|
|
13
|
-
=======
|
|
14
|
-
:class:`bool`
|
|
15
|
-
True means it worked without any error.
|
|
16
|
-
False means there was an unknown error
|
|
17
|
-
Examples
|
|
18
|
-
--------
|
|
19
|
-
>>> register_font("/home/roboto.tff")
|
|
20
|
-
1
|
|
21
|
-
Raises
|
|
22
|
-
------
|
|
23
|
-
AssertionError
|
|
24
|
-
Font is missing.
|
|
25
|
-
"""
|
|
26
|
-
a=Path(font_path)
|
|
27
|
-
assert a.exists(), f"font doesn't exist at {a.absolute()}"
|
|
28
|
-
font_path = str(a.absolute())
|
|
29
|
-
font_path_bytes=font_path.encode('utf-8')
|
|
30
|
-
cdef const unsigned char* fontPath = font_path_bytes
|
|
31
|
-
fontAddStatus = FcConfigAppFontAddFile(FcConfigGetCurrent(), fontPath)
|
|
32
|
-
if fontAddStatus:
|
|
33
|
-
return True
|
|
34
|
-
else:
|
|
35
|
-
return False
|
|
36
|
-
cpdef bint unregister_font(str font_path):
|
|
37
|
-
"""This function unregisters(removes) the font file using
|
|
38
|
-
``fontconfig``. It is mostly optional to call this.
|
|
39
|
-
Mainly used in tests.
|
|
40
|
-
Note:
|
|
41
|
-
The API for Windows is different that this.
|
|
42
|
-
|
|
43
|
-
Parameters
|
|
44
|
-
==========
|
|
45
4
|
|
|
46
|
-
|
|
47
|
-
|
|
5
|
+
cpdef bint fc_register_font(str font_path):
|
|
6
|
+
"""This function registers the font file using ``fontconfig`` so that
|
|
7
|
+
it is available for use by Pango. On Linux it is aliased to
|
|
8
|
+
:func:`register_font` and on Windows and macOS this would work only when
|
|
9
|
+
using ``fontconfig`` backend.
|
|
48
10
|
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
11
|
+
Parameters
|
|
12
|
+
==========
|
|
13
|
+
font_path : :class:`str`
|
|
14
|
+
Relative or absolute path to font file.
|
|
15
|
+
Returns
|
|
16
|
+
=======
|
|
17
|
+
:class:`bool`
|
|
18
|
+
True means it worked without any error.
|
|
19
|
+
False means there was an unknown error
|
|
20
|
+
Examples
|
|
21
|
+
--------
|
|
22
|
+
>>> register_font("/home/roboto.tff")
|
|
23
|
+
True
|
|
54
24
|
|
|
55
|
-
|
|
56
|
-
|
|
25
|
+
Raises
|
|
26
|
+
------
|
|
27
|
+
AssertionError
|
|
28
|
+
Font is missing.
|
|
29
|
+
"""
|
|
30
|
+
a=Path(font_path)
|
|
31
|
+
assert a.exists(), f"font doesn't exist at {a.absolute()}"
|
|
32
|
+
font_path = str(a.absolute())
|
|
33
|
+
font_path_bytes=font_path.encode('utf-8')
|
|
34
|
+
cdef const unsigned char* fontPath = font_path_bytes
|
|
35
|
+
fontAddStatus = FcConfigAppFontAddFile(FcConfigGetCurrent(), fontPath)
|
|
36
|
+
if fontAddStatus:
|
|
57
37
|
return True
|
|
58
|
-
|
|
38
|
+
else:
|
|
39
|
+
return False
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
cpdef bint fc_unregister_font(str font_path):
|
|
43
|
+
"""This function unregisters(removes) the font file using
|
|
44
|
+
``fontconfig``. It is mostly optional to call this.
|
|
45
|
+
Mainly used in tests. On Linux it is aliased to
|
|
46
|
+
:func:`unregister_font` and on Windows and macOS this
|
|
47
|
+
would work only when using ``fontconfig`` backend.
|
|
48
|
+
|
|
49
|
+
Parameters
|
|
50
|
+
==========
|
|
51
|
+
|
|
52
|
+
font_path: :class:`str`
|
|
53
|
+
For compatibility with the windows function.
|
|
54
|
+
|
|
55
|
+
Returns
|
|
56
|
+
=======
|
|
57
|
+
:class:`bool`
|
|
58
|
+
True means it worked without any error.
|
|
59
|
+
False means there was an unknown error
|
|
60
|
+
|
|
61
|
+
"""
|
|
62
|
+
FcConfigAppFontClear(NULL)
|
|
63
|
+
return True
|
|
64
|
+
|
|
65
|
+
|
|
66
|
+
IF UNAME_SYSNAME == "Linux":
|
|
67
|
+
register_font = fc_register_font
|
|
68
|
+
unregister_font = fc_unregister_font
|
|
69
|
+
|
|
70
|
+
|
|
71
|
+
ELIF UNAME_SYSNAME == "Windows":
|
|
59
72
|
cpdef bint register_font(str font_path):
|
|
60
73
|
"""This function registers the font file using native windows API
|
|
61
74
|
so that it is available for use by Pango.
|
|
@@ -72,7 +85,7 @@ IF UNAME_SYSNAME == "Windows":
|
|
|
72
85
|
Examples
|
|
73
86
|
--------
|
|
74
87
|
>>> register_font("C:/home/roboto.tff")
|
|
75
|
-
|
|
88
|
+
True
|
|
76
89
|
Raises
|
|
77
90
|
------
|
|
78
91
|
AssertionError
|
|
@@ -90,6 +103,8 @@ IF UNAME_SYSNAME == "Windows":
|
|
|
90
103
|
return True
|
|
91
104
|
else:
|
|
92
105
|
return False
|
|
106
|
+
|
|
107
|
+
|
|
93
108
|
cpdef bint unregister_font(str font_path):
|
|
94
109
|
"""This function unregisters(removes) the font file using
|
|
95
110
|
native Windows API. It is mostly optional to call this.
|
|
@@ -116,6 +131,8 @@ IF UNAME_SYSNAME == "Windows":
|
|
|
116
131
|
FR_PRIVATE,
|
|
117
132
|
0
|
|
118
133
|
)
|
|
134
|
+
|
|
135
|
+
|
|
119
136
|
ELIF UNAME_SYSNAME == "Darwin":
|
|
120
137
|
cpdef bint register_font(str font_path):
|
|
121
138
|
"""This function registers the font file using ``CoreText`` API so that
|
|
@@ -132,7 +149,7 @@ ELIF UNAME_SYSNAME == "Darwin":
|
|
|
132
149
|
Examples
|
|
133
150
|
--------
|
|
134
151
|
>>> register_font("/home/roboto.tff")
|
|
135
|
-
|
|
152
|
+
True
|
|
136
153
|
Raises
|
|
137
154
|
------
|
|
138
155
|
AssertionError
|
|
@@ -149,6 +166,8 @@ ELIF UNAME_SYSNAME == "Darwin":
|
|
|
149
166
|
kCTFontManagerScopeProcess,
|
|
150
167
|
NULL
|
|
151
168
|
)
|
|
169
|
+
|
|
170
|
+
|
|
152
171
|
cpdef bint unregister_font(str font_path):
|
|
153
172
|
"""This function unregisters(removes) the font file using
|
|
154
173
|
native ``CoreText`` API. It is mostly optional to call this.
|
|
@@ -179,6 +198,7 @@ ELIF UNAME_SYSNAME == "Darwin":
|
|
|
179
198
|
NULL
|
|
180
199
|
)
|
|
181
200
|
|
|
201
|
+
|
|
182
202
|
cpdef list list_fonts():
|
|
183
203
|
"""Lists the fonts available to Pango.
|
|
184
204
|
This is usually same as system fonts but it also
|
|
@@ -63,6 +63,7 @@ NEEDED_LIBS = [
|
|
|
63
63
|
"intl",
|
|
64
64
|
"harfbuzz",
|
|
65
65
|
"cairo",
|
|
66
|
+
"fontconfig",
|
|
66
67
|
]
|
|
67
68
|
|
|
68
69
|
|
|
@@ -190,10 +191,15 @@ def update_dict(dict1: dict, dict2: dict):
|
|
|
190
191
|
|
|
191
192
|
ext = ".pyx" if USE_CYTHON else ".c"
|
|
192
193
|
base_file = Path(__file__).parent / "manimpango"
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
194
|
+
_pkg_config_pangocairo = PKG_CONFIG("pangocairo")
|
|
195
|
+
_pkg_config_fontconfig = PKG_CONFIG("pangofc")
|
|
196
|
+
if _pkg_config_pangocairo.check_pkgconfig:
|
|
197
|
+
_pkg_config_pangocairo.check_min_version(MINIMUM_PANGO_VERSION)
|
|
198
|
+
returns = update_dict(
|
|
199
|
+
_pkg_config_pangocairo.setuptools_args, _pkg_config_fontconfig.setuptools_args
|
|
200
|
+
)
|
|
201
|
+
else:
|
|
202
|
+
returns = {}
|
|
197
203
|
returns["libraries"] = NEEDED_LIBS
|
|
198
204
|
if sys.platform == "win32":
|
|
199
205
|
returns["libraries"] += ["Gdi32"]
|
|
@@ -31,11 +31,3 @@ set_dll_search_path()
|
|
|
31
31
|
delete_media_dir()
|
|
32
32
|
CASES_DIR = Path(Path(__file__).parent, "cases").absolute()
|
|
33
33
|
FONT_DIR = Path(__file__).parent / "fonts"
|
|
34
|
-
|
|
35
|
-
import manimpango # noqa: E402
|
|
36
|
-
|
|
37
|
-
font = str((FONT_DIR / "BungeeOutline-Regular.ttf").absolute())
|
|
38
|
-
orig = manimpango.list_fonts()
|
|
39
|
-
assert manimpango.register_font(font)
|
|
40
|
-
final = manimpango.list_fonts()
|
|
41
|
-
main_font = list(set(final) - set(orig))[0]
|
|
@@ -44,7 +44,7 @@ class MarkupText:
|
|
|
44
44
|
self.indent = indent
|
|
45
45
|
self.alignment = alignment
|
|
46
46
|
self.wrap_text = wrap_text
|
|
47
|
-
if
|
|
47
|
+
if MarkupUtils.validate(self.text):
|
|
48
48
|
raise ValueError(
|
|
49
49
|
f"Pango cannot parse your markup in {self.text}. "
|
|
50
50
|
"Please check for typos, unmatched tags or unescaped "
|
|
@@ -0,0 +1,129 @@
|
|
|
1
|
+
# -*- coding: utf-8 -*-
|
|
2
|
+
import sys
|
|
3
|
+
from textwrap import dedent
|
|
4
|
+
|
|
5
|
+
import pytest
|
|
6
|
+
|
|
7
|
+
import manimpango
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
def pytest_report_header(config):
|
|
11
|
+
return (
|
|
12
|
+
f"ManimPango version {manimpango.__version__}\n"
|
|
13
|
+
f"Pango version {manimpango.pango_version()}\n"
|
|
14
|
+
f"Cairo version {manimpango.cairo_version()}"
|
|
15
|
+
)
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
@pytest.fixture
|
|
19
|
+
def setup_fontconfig(tmpdir, monkeypatch):
|
|
20
|
+
if sys.platform.startswith("win32") and "GCC" not in sys.version:
|
|
21
|
+
default_fontconfig_configuration = dedent(
|
|
22
|
+
"""\
|
|
23
|
+
<?xml version="1.0"?>
|
|
24
|
+
<!DOCTYPE fontconfig SYSTEM "urn:fontconfig:fonts.dtd">
|
|
25
|
+
<!-- /etc/fonts/fonts.conf file to configure system font access -->
|
|
26
|
+
<fontconfig>
|
|
27
|
+
<description>Default configuration file</description>
|
|
28
|
+
|
|
29
|
+
<!--
|
|
30
|
+
DO NOT EDIT THIS FILE.
|
|
31
|
+
IT WILL BE REPLACED WHEN FONTCONFIG IS UPDATED.
|
|
32
|
+
LOCAL CHANGES BELONG IN 'local.conf'.
|
|
33
|
+
|
|
34
|
+
The intent of this standard configuration file is to be adequate for
|
|
35
|
+
most environments. If you have a reasonably normal environment and
|
|
36
|
+
have found problems with this configuration, they are probably
|
|
37
|
+
things that others will also want fixed. Please submit any
|
|
38
|
+
problems to the fontconfig bugzilla system located at fontconfig.org
|
|
39
|
+
|
|
40
|
+
Note that the normal 'make install' procedure for fontconfig is to
|
|
41
|
+
replace any existing fonts.conf file with the new version. Place
|
|
42
|
+
any local customizations in local.conf which this file references.
|
|
43
|
+
|
|
44
|
+
Keith Packard
|
|
45
|
+
-->
|
|
46
|
+
|
|
47
|
+
<!-- Font directory list -->
|
|
48
|
+
|
|
49
|
+
<dir>WINDOWSFONTDIR</dir>
|
|
50
|
+
|
|
51
|
+
<dir prefix="xdg">fonts</dir>
|
|
52
|
+
<!-- the following element will be removed in the future -->
|
|
53
|
+
<dir>~/.fonts</dir>
|
|
54
|
+
|
|
55
|
+
<!--
|
|
56
|
+
Accept deprecated 'mono' alias, replacing it with 'monospace'
|
|
57
|
+
-->
|
|
58
|
+
<match target="pattern">
|
|
59
|
+
<test qual="any" name="family">
|
|
60
|
+
<string>mono</string>
|
|
61
|
+
</test>
|
|
62
|
+
<edit name="family" mode="assign" binding="same">
|
|
63
|
+
<string>monospace</string>
|
|
64
|
+
</edit>
|
|
65
|
+
</match>
|
|
66
|
+
|
|
67
|
+
<!--
|
|
68
|
+
Accept alternate 'sans serif' spelling, replacing it with 'sans-serif'
|
|
69
|
+
-->
|
|
70
|
+
<match target="pattern">
|
|
71
|
+
<test qual="any" name="family">
|
|
72
|
+
<string>sans serif</string>
|
|
73
|
+
</test>
|
|
74
|
+
<edit name="family" mode="assign" binding="same">
|
|
75
|
+
<string>sans-serif</string>
|
|
76
|
+
</edit>
|
|
77
|
+
</match>
|
|
78
|
+
|
|
79
|
+
<!--
|
|
80
|
+
Accept deprecated 'sans' alias, replacing it with 'sans-serif'
|
|
81
|
+
-->
|
|
82
|
+
<match target="pattern">
|
|
83
|
+
<test qual="any" name="family">
|
|
84
|
+
<string>sans</string>
|
|
85
|
+
</test>
|
|
86
|
+
<edit name="family" mode="assign" binding="same">
|
|
87
|
+
<string>sans-serif</string>
|
|
88
|
+
</edit>
|
|
89
|
+
</match>
|
|
90
|
+
<!--
|
|
91
|
+
Accept alternate 'system ui' spelling, replacing it with 'system-ui'
|
|
92
|
+
-->
|
|
93
|
+
<match target="pattern">
|
|
94
|
+
<test qual="any" name="family">
|
|
95
|
+
<string>system ui</string>
|
|
96
|
+
</test>
|
|
97
|
+
<edit name="family" mode="assign" binding="same">
|
|
98
|
+
<string>system-ui</string>
|
|
99
|
+
</edit>
|
|
100
|
+
</match>
|
|
101
|
+
|
|
102
|
+
<!--
|
|
103
|
+
Load local system customization file
|
|
104
|
+
-->
|
|
105
|
+
<include ignore_missing="yes">conf.d</include>
|
|
106
|
+
|
|
107
|
+
<!-- Font cache directory list -->
|
|
108
|
+
|
|
109
|
+
<cachedir>LOCAL_APPDATA_FONTCONFIG_CACHE</cachedir>
|
|
110
|
+
<cachedir prefix="xdg">fontconfig</cachedir>
|
|
111
|
+
<!-- the following element will be removed in the future -->
|
|
112
|
+
<cachedir>~/.fontconfig</cachedir>
|
|
113
|
+
|
|
114
|
+
<config>
|
|
115
|
+
<!--
|
|
116
|
+
Rescan configuration every 30 seconds when FcFontSetList is called
|
|
117
|
+
-->
|
|
118
|
+
<rescan>
|
|
119
|
+
<int>30</int>
|
|
120
|
+
</rescan>
|
|
121
|
+
</config>
|
|
122
|
+
|
|
123
|
+
</fontconfig>
|
|
124
|
+
"""
|
|
125
|
+
)
|
|
126
|
+
with open(tmpdir / "fonts.conf", "w") as f:
|
|
127
|
+
f.write(default_fontconfig_configuration)
|
|
128
|
+
monkeypatch.setenv("FONTCONFIG_PATH", str(tmpdir))
|
|
129
|
+
monkeypatch.setenv("PANGOCAIRO_BACKEND", "fc")
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
|
|
1
|
+
MaShanZheng-Regular.ttf from https://fonts.google.com/specimen/Ma+Shan+Zheng
|
|
2
2
|
BungeeColor-Regular_colr_Windows.ttf, from https://github.com/djrrb/bungee
|
|
3
3
|
AdobeVFPrototype.ttf, from https://github.com/adobe-fonts/adobe-variable-font-prototype
|
|
4
4
|
BungeeOutline-Regular.ttf, from https://fonts.google.com/specimen/Bungee+Outline
|
|
Binary file
|
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
# -*- coding: utf-8 -*-
|
|
2
|
+
import sys
|
|
3
|
+
from pathlib import Path
|
|
4
|
+
from shutil import copyfile
|
|
5
|
+
|
|
6
|
+
import manim
|
|
7
|
+
import pytest
|
|
8
|
+
|
|
9
|
+
import manimpango
|
|
10
|
+
|
|
11
|
+
from . import FONT_DIR
|
|
12
|
+
from ._manim import MarkupText
|
|
13
|
+
|
|
14
|
+
font_lists = {
|
|
15
|
+
(FONT_DIR / "AdobeVFPrototype.ttf").absolute(): "Adobe Variable Font Prototype",
|
|
16
|
+
(
|
|
17
|
+
FONT_DIR / "BungeeColor-Regular_colr_Windows.ttf"
|
|
18
|
+
).absolute(): "Bungee Color Regular",
|
|
19
|
+
(FONT_DIR / "MaShanZheng-Regular.ttf").absolute(): "Ma Shan Zheng",
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
def test_unicode_font_name(tmpdir):
|
|
24
|
+
final_font = str(Path(tmpdir, "庞门正.ttf").absolute())
|
|
25
|
+
copyfile(FONT_DIR / "AdobeVFPrototype.ttf", final_font)
|
|
26
|
+
assert manimpango.register_font(final_font)
|
|
27
|
+
assert manimpango.unregister_font(final_font)
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
@pytest.mark.parametrize("font_name", font_lists)
|
|
31
|
+
def test_register_font(font_name):
|
|
32
|
+
intial = manimpango.list_fonts()
|
|
33
|
+
assert manimpango.register_font(str(font_name)), "Invalid Font possibly."
|
|
34
|
+
final = manimpango.list_fonts()
|
|
35
|
+
assert intial != final
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+
@pytest.mark.parametrize("font_name", font_lists.values())
|
|
39
|
+
def test_warning(capfd, font_name):
|
|
40
|
+
print(font_name)
|
|
41
|
+
manim.Text("Testing", font=font_name)
|
|
42
|
+
captured = capfd.readouterr()
|
|
43
|
+
assert "Pango-WARNING **" not in captured.err, "Looks like pango raised a warning?"
|
|
44
|
+
|
|
45
|
+
|
|
46
|
+
@pytest.mark.skipif(
|
|
47
|
+
sys.platform.startswith("linux"), reason="unsupported api for linux"
|
|
48
|
+
)
|
|
49
|
+
@pytest.mark.parametrize("font_name", font_lists)
|
|
50
|
+
def test_unregister_font(font_name):
|
|
51
|
+
intial = manimpango.list_fonts()
|
|
52
|
+
assert manimpango.unregister_font(str(font_name)), "Failed to unregister the font"
|
|
53
|
+
final = manimpango.list_fonts()
|
|
54
|
+
assert intial != final
|
|
55
|
+
|
|
56
|
+
|
|
57
|
+
@pytest.mark.skipif(
|
|
58
|
+
sys.platform.startswith("linux"), reason="unsupported api for linux"
|
|
59
|
+
)
|
|
60
|
+
@pytest.mark.parametrize("font_name", font_lists)
|
|
61
|
+
def test_register_and_unregister_font(font_name):
|
|
62
|
+
assert manimpango.register_font(str(font_name)), "Invalid Font possibly."
|
|
63
|
+
assert manimpango.unregister_font(str(font_name)), "Failed to unregister the font"
|
|
64
|
+
|
|
65
|
+
|
|
66
|
+
@pytest.mark.skipif(
|
|
67
|
+
sys.platform.startswith("linux"), reason="unsupported api for linux"
|
|
68
|
+
)
|
|
69
|
+
@pytest.mark.parametrize("font_name", font_lists)
|
|
70
|
+
@pytest.mark.skipif(sys.platform.startswith("darwin"), reason="always returns true")
|
|
71
|
+
def test_fail_just_unregister(font_name):
|
|
72
|
+
assert not manimpango.unregister_font(
|
|
73
|
+
str(font_name)
|
|
74
|
+
), "Failed to unregister the font"
|
|
75
|
+
|
|
76
|
+
|
|
77
|
+
@pytest.mark.skipif(
|
|
78
|
+
sys.platform.startswith("win32"), reason="unsupported api for win32"
|
|
79
|
+
)
|
|
80
|
+
@pytest.mark.skipif(sys.platform.startswith("darwin"), reason="unsupported api for mac")
|
|
81
|
+
def test_unregister_linux():
|
|
82
|
+
assert manimpango.unregister_font("random")
|
|
83
|
+
|
|
84
|
+
|
|
85
|
+
@pytest.mark.skipif(
|
|
86
|
+
sys.platform.startswith("linux"), reason="unsupported api for linux"
|
|
87
|
+
)
|
|
88
|
+
def test_adding_dummy_font(tmpdir):
|
|
89
|
+
dummy = tmpdir / "font.ttf"
|
|
90
|
+
with open(dummy, "wb") as f:
|
|
91
|
+
f.write(b"dummy")
|
|
92
|
+
assert not manimpango.register_font(str(dummy)), "Registered a dummy font?"
|
|
93
|
+
|
|
94
|
+
|
|
95
|
+
def test_simple_fonts_render(tmpdir):
|
|
96
|
+
filename = str(Path(tmpdir) / "hello.svg")
|
|
97
|
+
MarkupText("Hello World", filename=filename)
|
|
98
|
+
assert Path(filename).exists()
|
|
99
|
+
|
|
100
|
+
|
|
101
|
+
@pytest.mark.skipif(
|
|
102
|
+
not sys.platform.startswith("linux"), reason="unsupported api other than linux"
|
|
103
|
+
)
|
|
104
|
+
def test_both_fc_and_register_font_are_same():
|
|
105
|
+
assert manimpango.fc_register_font == manimpango.register_font
|
|
106
|
+
assert manimpango.fc_unregister_font == manimpango.unregister_font
|
|
107
|
+
|
|
108
|
+
|
|
109
|
+
@pytest.mark.parametrize("font_file", font_lists)
|
|
110
|
+
def test_fc_font_register(setup_fontconfig, font_file):
|
|
111
|
+
intial = manimpango.list_fonts()
|
|
112
|
+
assert manimpango.fc_register_font(str(font_file)), "Invalid Font possibly."
|
|
113
|
+
final = manimpango.list_fonts()
|
|
114
|
+
assert intial != final
|
|
115
|
+
|
|
116
|
+
|
|
117
|
+
def test_fc_font_unregister(setup_fontconfig):
|
|
118
|
+
# it will remove everything
|
|
119
|
+
intial = manimpango.list_fonts()
|
|
120
|
+
manimpango.fc_unregister_font("clear")
|
|
121
|
+
final = manimpango.list_fonts()
|
|
122
|
+
assert intial != final
|
|
@@ -18,9 +18,9 @@ def test_whether_list():
|
|
|
18
18
|
sys.platform.startswith("linux") or sys.platform.startswith("darwin"),
|
|
19
19
|
reason="names don't match for some reason.",
|
|
20
20
|
)
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
21
|
+
@pytest.mark.parametrize("font_file", font_lists)
|
|
22
|
+
def test_resgister_font_with_list(font_file):
|
|
23
|
+
manimpango.register_font(str(font_file))
|
|
24
|
+
a = manimpango.list_fonts()
|
|
25
|
+
assert font_lists[font_file] in a
|
|
26
|
+
manimpango.unregister_font(str(font_file))
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
# -*- coding: utf-8 -*-
|
|
2
2
|
from pathlib import Path
|
|
3
3
|
|
|
4
|
+
import pytest
|
|
5
|
+
|
|
4
6
|
import manimpango
|
|
5
7
|
|
|
6
8
|
from . import CASES_DIR
|
|
@@ -20,27 +22,37 @@ ipsum_text = (
|
|
|
20
22
|
)
|
|
21
23
|
|
|
22
24
|
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
assert manimpango.MarkupUtils.validate(
|
|
26
|
-
"foo",
|
|
27
|
-
), '"foo" should not fail validation'
|
|
28
|
-
assert manimpango.MarkupUtils.validate(
|
|
29
|
-
"<b>bar</b>"
|
|
30
|
-
), '"<b>bar</b>" should not fail validation'
|
|
31
|
-
assert manimpango.MarkupUtils.validate(
|
|
32
|
-
"வணக்கம்",
|
|
33
|
-
), '"வணக்கம்" should not fail'
|
|
25
|
+
@pytest.mark.parametrize("text", ["foo", "<b>bar</b>", "வணக்கம்"])
|
|
26
|
+
def test_good_markup(text):
|
|
34
27
|
|
|
28
|
+
assert not manimpango.MarkupUtils.validate(
|
|
29
|
+
text,
|
|
30
|
+
), f"{text} should not fail validation"
|
|
35
31
|
|
|
36
|
-
def test_bad_markup():
|
|
37
32
|
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
33
|
+
@pytest.mark.parametrize("text", ["<b>foo", "<xyz>foo</xyz>"])
|
|
34
|
+
def test_bad_markup(text):
|
|
35
|
+
assert manimpango.MarkupUtils.validate(
|
|
36
|
+
text
|
|
37
|
+
), f"{text} should fail validation (unbalanced tags)"
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
@pytest.mark.parametrize(
|
|
41
|
+
"text,error",
|
|
42
|
+
[
|
|
43
|
+
(
|
|
44
|
+
"<b>foo",
|
|
45
|
+
"Error on line 1 char 23: Element “markup” was closed, "
|
|
46
|
+
"but the currently open element is “b”",
|
|
47
|
+
),
|
|
48
|
+
(
|
|
49
|
+
"<xyz>foo</xyz>",
|
|
50
|
+
"Unknown tag 'xyz' on line 1 char 14",
|
|
51
|
+
),
|
|
52
|
+
],
|
|
53
|
+
)
|
|
54
|
+
def test_bad_markup_error_message(text, error):
|
|
55
|
+
assert manimpango.MarkupUtils.validate(text) == error
|
|
44
56
|
|
|
45
57
|
|
|
46
58
|
def test_markup_text(tmpdir):
|
|
Binary file
|
|
@@ -1,97 +0,0 @@
|
|
|
1
|
-
# -*- coding: utf-8 -*-
|
|
2
|
-
import sys
|
|
3
|
-
from pathlib import Path
|
|
4
|
-
from shutil import copyfile
|
|
5
|
-
|
|
6
|
-
import manim
|
|
7
|
-
import pytest
|
|
8
|
-
|
|
9
|
-
import manimpango
|
|
10
|
-
|
|
11
|
-
from . import FONT_DIR, main_font
|
|
12
|
-
from ._manim import MarkupText
|
|
13
|
-
|
|
14
|
-
font_lists = {
|
|
15
|
-
(FONT_DIR / "AdobeVFPrototype.ttf").absolute(): "Adobe Variable Font Prototype",
|
|
16
|
-
(
|
|
17
|
-
FONT_DIR / "BungeeColor-Regular_colr_Windows.ttf"
|
|
18
|
-
).absolute(): "Bungee Color Regular",
|
|
19
|
-
(FONT_DIR / "NotoNastaliqUrdu-Regular.ttf").absolute(): "Noto Nastaliq Urdu",
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
def test_unicode_font_name(tmpdir):
|
|
24
|
-
final_font = str(Path(tmpdir, "庞门正.ttf").absolute())
|
|
25
|
-
copyfile(FONT_DIR / "AdobeVFPrototype.ttf", final_font)
|
|
26
|
-
assert manimpango.register_font(final_font)
|
|
27
|
-
assert manimpango.unregister_font(final_font)
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
def test_register_font():
|
|
31
|
-
for font_name in font_lists:
|
|
32
|
-
assert manimpango.register_font(str(font_name)), "Invalid Font possibly."
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
def test_warning(capfd):
|
|
36
|
-
for font_name in font_lists.values():
|
|
37
|
-
manim.Text("Testing", font=font_name)
|
|
38
|
-
captured = capfd.readouterr()
|
|
39
|
-
assert (
|
|
40
|
-
"Pango-WARNING **" not in captured.err
|
|
41
|
-
), "Looks like pango raised a warning?"
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
@pytest.mark.skipif(
|
|
45
|
-
sys.platform.startswith("linux"), reason="unsupported api for linux"
|
|
46
|
-
)
|
|
47
|
-
def test_unregister_font():
|
|
48
|
-
for font_name in font_lists:
|
|
49
|
-
assert manimpango.unregister_font(
|
|
50
|
-
str(font_name)
|
|
51
|
-
), "Failed to unregister the font"
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
@pytest.mark.skipif(
|
|
55
|
-
sys.platform.startswith("linux"), reason="unsupported api for linux"
|
|
56
|
-
)
|
|
57
|
-
def test_register_and_unregister_font():
|
|
58
|
-
for font_name in font_lists:
|
|
59
|
-
assert manimpango.register_font(str(font_name)), "Invalid Font possibly."
|
|
60
|
-
assert manimpango.unregister_font(
|
|
61
|
-
str(font_name)
|
|
62
|
-
), "Failed to unregister the font"
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
@pytest.mark.skipif(
|
|
66
|
-
sys.platform.startswith("linux"), reason="unsupported api for linux"
|
|
67
|
-
)
|
|
68
|
-
@pytest.mark.skipif(sys.platform.startswith("darwin"), reason="always returns true")
|
|
69
|
-
def test_fail_just_unregister():
|
|
70
|
-
for font_name in font_lists:
|
|
71
|
-
assert not manimpango.unregister_font(
|
|
72
|
-
str(font_name)
|
|
73
|
-
), "Failed to unregister the font"
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
@pytest.mark.skipif(
|
|
77
|
-
sys.platform.startswith("win32"), reason="unsupported api for win32"
|
|
78
|
-
)
|
|
79
|
-
@pytest.mark.skipif(sys.platform.startswith("darwin"), reason="unsupported api for mac")
|
|
80
|
-
def test_unregister_linux():
|
|
81
|
-
assert manimpango.unregister_font("random")
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
@pytest.mark.skipif(
|
|
85
|
-
sys.platform.startswith("linux"), reason="unsupported api for linux"
|
|
86
|
-
)
|
|
87
|
-
def test_adding_dummy_font(tmpdir):
|
|
88
|
-
dummy = tmpdir / "font.ttf"
|
|
89
|
-
with open(dummy, "wb") as f:
|
|
90
|
-
f.write(b"dummy")
|
|
91
|
-
assert not manimpango.register_font(str(dummy)), "Registered a dummy font?"
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
def test_fonts_render(tmpdir):
|
|
95
|
-
filename = str(Path(tmpdir) / "hello.svg")
|
|
96
|
-
MarkupText("Hello World", font=main_font, filename=filename)
|
|
97
|
-
assert Path(filename).exists()
|
|
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
|