thorvg-python 1.1.0__tar.gz → 1.1.2__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.
- {thorvg_python-1.1.0/src/thorvg_python.egg-info → thorvg_python-1.1.2}/PKG-INFO +6 -5
- {thorvg_python-1.1.0 → thorvg_python-1.1.2}/README.md +5 -4
- {thorvg_python-1.1.0 → thorvg_python-1.1.2}/pyproject.toml +1 -1
- {thorvg_python-1.1.0 → thorvg_python-1.1.2}/setup.py +54 -42
- {thorvg_python-1.1.0 → thorvg_python-1.1.2}/src/thorvg_python/__init__.py +4 -1
- {thorvg_python-1.1.0 → thorvg_python-1.1.2}/src/thorvg_python/accessor.py +1 -1
- {thorvg_python-1.1.0 → thorvg_python-1.1.2}/src/thorvg_python/animation/lottie.py +45 -1
- {thorvg_python-1.1.0 → thorvg_python-1.1.2}/src/thorvg_python/base.py +27 -0
- {thorvg_python-1.1.0 → thorvg_python-1.1.2}/src/thorvg_python/paint/__init__.py +57 -22
- {thorvg_python-1.1.0 → thorvg_python-1.1.2}/src/thorvg_python/paint/picture.py +36 -4
- {thorvg_python-1.1.0 → thorvg_python-1.1.2}/src/thorvg_python/paint/text.py +104 -7
- {thorvg_python-1.1.0 → thorvg_python-1.1.2/src/thorvg_python.egg-info}/PKG-INFO +6 -5
- {thorvg_python-1.1.0 → thorvg_python-1.1.2}/src/thorvg_python.egg-info/SOURCES.txt +0 -1
- {thorvg_python-1.1.0 → thorvg_python-1.1.2}/tests/test_all.py +13 -0
- thorvg_python-1.1.2/thorvg_conan/conandata.yml +4 -0
- thorvg_python-1.1.0/src/thorvg_python/libthorvg-1.so +0 -0
- thorvg_python-1.1.0/thorvg_conan/conandata.yml +0 -4
- {thorvg_python-1.1.0 → thorvg_python-1.1.2}/LICENSE +0 -0
- {thorvg_python-1.1.0 → thorvg_python-1.1.2}/MANIFEST.in +0 -0
- {thorvg_python-1.1.0 → thorvg_python-1.1.2}/setup.cfg +0 -0
- {thorvg_python-1.1.0 → thorvg_python-1.1.2}/src/thorvg_python/animation/__init__.py +0 -0
- {thorvg_python-1.1.0 → thorvg_python-1.1.2}/src/thorvg_python/canvas/__init__.py +0 -0
- {thorvg_python-1.1.0 → thorvg_python-1.1.2}/src/thorvg_python/canvas/gl.py +0 -0
- {thorvg_python-1.1.0 → thorvg_python-1.1.2}/src/thorvg_python/canvas/sw.py +0 -0
- {thorvg_python-1.1.0 → thorvg_python-1.1.2}/src/thorvg_python/canvas/wg.py +0 -0
- {thorvg_python-1.1.0 → thorvg_python-1.1.2}/src/thorvg_python/engine.py +0 -0
- {thorvg_python-1.1.0 → thorvg_python-1.1.2}/src/thorvg_python/gradient/__init__.py +0 -0
- {thorvg_python-1.1.0 → thorvg_python-1.1.2}/src/thorvg_python/gradient/linear.py +0 -0
- {thorvg_python-1.1.0 → thorvg_python-1.1.2}/src/thorvg_python/gradient/radial.py +0 -0
- {thorvg_python-1.1.0 → thorvg_python-1.1.2}/src/thorvg_python/paint/scene.py +0 -0
- {thorvg_python-1.1.0 → thorvg_python-1.1.2}/src/thorvg_python/paint/shape.py +0 -0
- {thorvg_python-1.1.0 → thorvg_python-1.1.2}/src/thorvg_python/py.typed +0 -0
- {thorvg_python-1.1.0 → thorvg_python-1.1.2}/src/thorvg_python/saver.py +0 -0
- {thorvg_python-1.1.0 → thorvg_python-1.1.2}/src/thorvg_python.egg-info/dependency_links.txt +0 -0
- {thorvg_python-1.1.0 → thorvg_python-1.1.2}/src/thorvg_python.egg-info/not-zip-safe +0 -0
- {thorvg_python-1.1.0 → thorvg_python-1.1.2}/src/thorvg_python.egg-info/requires.txt +0 -0
- {thorvg_python-1.1.0 → thorvg_python-1.1.2}/src/thorvg_python.egg-info/top_level.txt +0 -0
- {thorvg_python-1.1.0 → thorvg_python-1.1.2}/thorvg_conan/conanfile.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: thorvg-python
|
|
3
|
-
Version: 1.1.
|
|
3
|
+
Version: 1.1.2
|
|
4
4
|
Summary: A ctypes API for thorvg, a vector graphics engine supporting SVG and Lottie formats.
|
|
5
5
|
Author-email: chaudominic <chaudominic2@gmail.com>
|
|
6
6
|
License: GNU LESSER GENERAL PUBLIC LICENSE
|
|
@@ -532,7 +532,7 @@ Dynamic: license-file
|
|
|
532
532
|
|
|
533
533
|
A ctypes API for thorvg, with additional functions for getting Pillow Image.
|
|
534
534
|
|
|
535
|
-
The functions mostly follow [thorvg/src/bindings/capi/thorvg_capi.h](https://github.com/thorvg/thorvg/blob/v1.0.
|
|
535
|
+
The functions mostly follow [thorvg/src/bindings/capi/thorvg_capi.h](https://github.com/thorvg/thorvg/blob/v1.0.3/src/bindings/capi/thorvg_capi.h)
|
|
536
536
|
|
|
537
537
|
Documentations: https://thorvg-python.readthedocs.io/en/latest/
|
|
538
538
|
|
|
@@ -546,7 +546,7 @@ Documentations: https://thorvg-python.readthedocs.io/en/latest/
|
|
|
546
546
|
|
|
547
547
|
Note that thorvg is included in the wheel package, you need not install libthorvg.
|
|
548
548
|
Version bundled is the version available on [Conan](https://conan.io/center/recipes/thorvg)
|
|
549
|
-
(Currently 1.0.
|
|
549
|
+
(Currently 1.0.3)
|
|
550
550
|
|
|
551
551
|
To install, run the following:
|
|
552
552
|
```bash
|
|
@@ -568,15 +568,16 @@ canvas = tvg.SwCanvas(engine)
|
|
|
568
568
|
canvas.set_target(512, 256) # w, h
|
|
569
569
|
|
|
570
570
|
rect = tvg.Shape(engine)
|
|
571
|
-
rect.append_rect(10, 10, 64, 64, 10, 10) # x, y, w, h, rx, ry
|
|
571
|
+
rect.append_rect(10, 10, 64, 64, 10, 10, True) # x, y, w, h, rx, ry, clockwise
|
|
572
572
|
rect.set_fill_color(32, 64, 128, 100) # r, g, b, a
|
|
573
|
-
canvas.
|
|
573
|
+
canvas.add(rect)
|
|
574
574
|
|
|
575
575
|
canvas.update()
|
|
576
576
|
canvas.draw(True)
|
|
577
577
|
canvas.sync()
|
|
578
578
|
|
|
579
579
|
im = canvas.get_pillow()
|
|
580
|
+
im.save("test.png")
|
|
580
581
|
canvas.destroy()
|
|
581
582
|
engine.term()
|
|
582
583
|
```
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
A ctypes API for thorvg, with additional functions for getting Pillow Image.
|
|
4
4
|
|
|
5
|
-
The functions mostly follow [thorvg/src/bindings/capi/thorvg_capi.h](https://github.com/thorvg/thorvg/blob/v1.0.
|
|
5
|
+
The functions mostly follow [thorvg/src/bindings/capi/thorvg_capi.h](https://github.com/thorvg/thorvg/blob/v1.0.3/src/bindings/capi/thorvg_capi.h)
|
|
6
6
|
|
|
7
7
|
Documentations: https://thorvg-python.readthedocs.io/en/latest/
|
|
8
8
|
|
|
@@ -16,7 +16,7 @@ Documentations: https://thorvg-python.readthedocs.io/en/latest/
|
|
|
16
16
|
|
|
17
17
|
Note that thorvg is included in the wheel package, you need not install libthorvg.
|
|
18
18
|
Version bundled is the version available on [Conan](https://conan.io/center/recipes/thorvg)
|
|
19
|
-
(Currently 1.0.
|
|
19
|
+
(Currently 1.0.3)
|
|
20
20
|
|
|
21
21
|
To install, run the following:
|
|
22
22
|
```bash
|
|
@@ -38,15 +38,16 @@ canvas = tvg.SwCanvas(engine)
|
|
|
38
38
|
canvas.set_target(512, 256) # w, h
|
|
39
39
|
|
|
40
40
|
rect = tvg.Shape(engine)
|
|
41
|
-
rect.append_rect(10, 10, 64, 64, 10, 10) # x, y, w, h, rx, ry
|
|
41
|
+
rect.append_rect(10, 10, 64, 64, 10, 10, True) # x, y, w, h, rx, ry, clockwise
|
|
42
42
|
rect.set_fill_color(32, 64, 128, 100) # r, g, b, a
|
|
43
|
-
canvas.
|
|
43
|
+
canvas.add(rect)
|
|
44
44
|
|
|
45
45
|
canvas.update()
|
|
46
46
|
canvas.draw(True)
|
|
47
47
|
canvas.sync()
|
|
48
48
|
|
|
49
49
|
im = canvas.get_pillow()
|
|
50
|
+
im.save("test.png")
|
|
50
51
|
canvas.destroy()
|
|
51
52
|
engine.term()
|
|
52
53
|
```
|
|
@@ -8,7 +8,7 @@ authors = [{ "name" = "chaudominic", "email" = "chaudominic2@gmail.com" }]
|
|
|
8
8
|
keywords = ["thorvg", "lottie", "svg", "ctypes", "python"]
|
|
9
9
|
classifiers = ["Topic :: Multimedia :: Graphics"]
|
|
10
10
|
dependencies = []
|
|
11
|
-
version = "1.1.
|
|
11
|
+
version = "1.1.2"
|
|
12
12
|
|
|
13
13
|
[project.urls]
|
|
14
14
|
Repository = "https://github.com/laggykiller/thorvg-python"
|
|
@@ -7,6 +7,7 @@ import sys
|
|
|
7
7
|
from typing import Any, Dict, List
|
|
8
8
|
|
|
9
9
|
from setuptools import find_packages, setup # type: ignore
|
|
10
|
+
from setuptools.command.build_py import build_py # type: ignore
|
|
10
11
|
|
|
11
12
|
CONAN_ARCHS = {
|
|
12
13
|
"x86_64": ["amd64", "x86_64", "x64"],
|
|
@@ -90,18 +91,25 @@ def install_thorvg(arch: str) -> Dict[Any, Any]:
|
|
|
90
91
|
if "thorvg_python" not in profiles:
|
|
91
92
|
subprocess.run(["conan", "profile", "detect", "-f", "--name", "thorvg_python"])
|
|
92
93
|
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
subprocess.run(
|
|
98
|
-
["conan", "profile", "path", "thorvg_python"],
|
|
99
|
-
stdout=subprocess.PIPE,
|
|
100
|
-
)
|
|
101
|
-
.stdout.decode()
|
|
102
|
-
.strip()
|
|
94
|
+
profile_path = (
|
|
95
|
+
subprocess.run(
|
|
96
|
+
["conan", "profile", "path", "thorvg_python"],
|
|
97
|
+
stdout=subprocess.PIPE,
|
|
103
98
|
)
|
|
99
|
+
.stdout.decode()
|
|
100
|
+
.strip()
|
|
101
|
+
)
|
|
104
102
|
|
|
103
|
+
with open(profile_path, "a+") as f:
|
|
104
|
+
# https://github.com/conan-io/conan/issues/19179#issuecomment-3472691734
|
|
105
|
+
f.write("\n")
|
|
106
|
+
f.write("[replace_requires]\n")
|
|
107
|
+
f.write("libjpeg-turbo/*: libjpeg-turbo/3.1.3")
|
|
108
|
+
|
|
109
|
+
if (
|
|
110
|
+
platform.architecture()[0] == "32bit"
|
|
111
|
+
or platform.machine().lower() not in (CONAN_ARCHS["x86_64"])
|
|
112
|
+
):
|
|
105
113
|
with open(profile_path, "a+") as f:
|
|
106
114
|
# https://github.com/conan-io/conan/issues/19179#issuecomment-3472691734
|
|
107
115
|
f.write("\n")
|
|
@@ -114,7 +122,7 @@ def install_thorvg(arch: str) -> Dict[Any, Any]:
|
|
|
114
122
|
[
|
|
115
123
|
"conan",
|
|
116
124
|
"export",
|
|
117
|
-
"--version=1.0.
|
|
125
|
+
"--version=1.0.3",
|
|
118
126
|
"thorvg_conan",
|
|
119
127
|
]
|
|
120
128
|
)
|
|
@@ -133,7 +141,7 @@ def install_thorvg(arch: str) -> Dict[Any, Any]:
|
|
|
133
141
|
"--deployer=direct_deploy",
|
|
134
142
|
"--format=json",
|
|
135
143
|
"--profile:all=thorvg_python",
|
|
136
|
-
"--requires=thorvg/1.0.
|
|
144
|
+
"--requires=thorvg/1.0.3",
|
|
137
145
|
],
|
|
138
146
|
stdout=subprocess.PIPE,
|
|
139
147
|
).stdout.decode()
|
|
@@ -175,33 +183,38 @@ def fetch_thorvg(conan_info: Dict[Any, Any]) -> List[str]:
|
|
|
175
183
|
return lib_paths
|
|
176
184
|
|
|
177
185
|
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
186
|
+
class build_py_custom(build_py):
|
|
187
|
+
def run(self, *args: Any, **kwargs: Any):
|
|
188
|
+
arch = get_arch()
|
|
189
|
+
print(f"Detected system architecture as {arch}")
|
|
190
|
+
|
|
191
|
+
if arch == "universal2":
|
|
192
|
+
conan_info = install_thorvg("x86_64")
|
|
193
|
+
lib_paths = fetch_thorvg(conan_info)
|
|
194
|
+
conan_info = install_thorvg("armv8")
|
|
195
|
+
lib_paths.extend(fetch_thorvg(conan_info))
|
|
196
|
+
print(f"{lib_paths=}")
|
|
197
|
+
subprocess.run(
|
|
198
|
+
[
|
|
199
|
+
"lipo",
|
|
200
|
+
"-create",
|
|
201
|
+
lib_paths[0],
|
|
202
|
+
lib_paths[1],
|
|
203
|
+
"-output",
|
|
204
|
+
"src/thorvg_python/libthorvg-1.dylib",
|
|
205
|
+
]
|
|
206
|
+
)
|
|
207
|
+
else:
|
|
208
|
+
conan_info = install_thorvg(arch)
|
|
209
|
+
lib_paths = fetch_thorvg(conan_info)
|
|
210
|
+
print(f"{lib_paths=}")
|
|
211
|
+
for lib_path in lib_paths:
|
|
212
|
+
shutil.copy(lib_path, "src/thorvg_python/")
|
|
204
213
|
|
|
214
|
+
super().run(*args, **kwargs)
|
|
215
|
+
|
|
216
|
+
|
|
217
|
+
if __name__ == "__main__":
|
|
205
218
|
setup(
|
|
206
219
|
zip_safe=False,
|
|
207
220
|
packages=find_packages(where="src"),
|
|
@@ -210,8 +223,7 @@ def compile():
|
|
|
210
223
|
package_data={
|
|
211
224
|
"thorvg_python": ["*.dll", "*.dylib", "*.so"],
|
|
212
225
|
},
|
|
226
|
+
cmdclass={
|
|
227
|
+
"build_py": build_py_custom,
|
|
228
|
+
},
|
|
213
229
|
)
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
if __name__ == "__main__":
|
|
217
|
-
compile()
|
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
#!/usr/bin/env python3
|
|
2
2
|
"""thorvg-python"""
|
|
3
3
|
|
|
4
|
-
__version__ = "1.1.
|
|
4
|
+
__version__ = "1.1.2"
|
|
5
5
|
|
|
6
|
+
from .accessor import Accessor # type: ignore # noqa: F401
|
|
6
7
|
from .animation import Animation # type: ignore # noqa: F401
|
|
7
8
|
from .animation.lottie import LottieAnimation # type: ignore # noqa: F401
|
|
8
9
|
from .base import BlendMethod # type: ignore # noqa: F401
|
|
@@ -10,6 +11,8 @@ from .base import Colorspace # type: ignore # noqa: F401
|
|
|
10
11
|
from .base import ColorStop # type: ignore # noqa: F401
|
|
11
12
|
from .base import EngineOption # type: ignore # noqa: F401
|
|
12
13
|
from .base import FillRule # type: ignore # noqa: F401
|
|
14
|
+
from .base import FilterMethod # type: ignore # noqa: F401
|
|
15
|
+
from .base import GlyphMetrics # type: ignore # noqa: F401
|
|
13
16
|
from .base import MaskMethod # type: ignore # noqa: F401
|
|
14
17
|
from .base import Matrix # type: ignore # noqa: F401
|
|
15
18
|
from .base import PathCommand # type: ignore # noqa: F401
|
|
@@ -112,4 +112,4 @@ class Accessor:
|
|
|
112
112
|
ctypes.POINTER(name_char_type)
|
|
113
113
|
]
|
|
114
114
|
self.thorvg_lib.tvg_accessor_generate_id.restype = ctypes.c_uint32
|
|
115
|
-
return self.thorvg_lib.tvg_accessor_generate_id(ctypes.pointer(name_char))
|
|
115
|
+
return self.thorvg_lib.tvg_accessor_generate_id(ctypes.pointer(name_char))
|
|
@@ -189,7 +189,7 @@ class LottieAnimation(Animation):
|
|
|
189
189
|
name = ctypes.c_char_p()
|
|
190
190
|
self.thorvg_lib.tvg_lottie_animation_get_marker.argtypes = [
|
|
191
191
|
AnimationPointer,
|
|
192
|
-
ctypes.
|
|
192
|
+
ctypes.c_uint32,
|
|
193
193
|
ctypes.POINTER(ctypes.c_char_p),
|
|
194
194
|
]
|
|
195
195
|
self.thorvg_lib.tvg_lottie_animation_get_marker.restype = Result
|
|
@@ -204,6 +204,50 @@ class LottieAnimation(Animation):
|
|
|
204
204
|
_name = None
|
|
205
205
|
return result, _name
|
|
206
206
|
|
|
207
|
+
def get_marker_info(self, idx: int) -> Tuple[Result, Optional[str], float, float]:
|
|
208
|
+
"""Retrieves marker information by index
|
|
209
|
+
|
|
210
|
+
:param int idx: The zero-based index of the animation marker.
|
|
211
|
+
|
|
212
|
+
:return:
|
|
213
|
+
Result.INVALID_ARGUMENT if ``idx`` is out of range.
|
|
214
|
+
Result.INSUFFICIENT_CONDITION In case the animation is not loaded.
|
|
215
|
+
:rtype: Result
|
|
216
|
+
:return: The marker name.
|
|
217
|
+
:rtype: Optional[str]
|
|
218
|
+
:return: The marker's starting frame.
|
|
219
|
+
:rtype: float
|
|
220
|
+
:return: The marker's ending frame.
|
|
221
|
+
:rtype: float
|
|
222
|
+
|
|
223
|
+
.. seealso:: LottieAnimation.get_markers_cnt()
|
|
224
|
+
.. note::
|
|
225
|
+
Experimental API
|
|
226
|
+
"""
|
|
227
|
+
name = ctypes.c_char_p()
|
|
228
|
+
begin = ctypes.c_float()
|
|
229
|
+
end = ctypes.c_float()
|
|
230
|
+
self.thorvg_lib.tvg_lottie_animation_get_marker_info.argtypes = [
|
|
231
|
+
AnimationPointer,
|
|
232
|
+
ctypes.POINTER(ctypes.c_uint32),
|
|
233
|
+
ctypes.POINTER(ctypes.c_char_p),
|
|
234
|
+
ctypes.POINTER(ctypes.c_float),
|
|
235
|
+
ctypes.POINTER(ctypes.c_float),
|
|
236
|
+
]
|
|
237
|
+
self.thorvg_lib.tvg_lottie_animation_get_marker_info.restype = Result
|
|
238
|
+
result = self.thorvg_lib.tvg_lottie_animation_get_marker_info(
|
|
239
|
+
self._animation,
|
|
240
|
+
ctypes.c_uint32(idx),
|
|
241
|
+
ctypes.pointer(name),
|
|
242
|
+
ctypes.pointer(begin),
|
|
243
|
+
ctypes.pointer(end),
|
|
244
|
+
)
|
|
245
|
+
if name.value is not None:
|
|
246
|
+
_name = name.value.decode("utf-8")
|
|
247
|
+
else:
|
|
248
|
+
_name = None
|
|
249
|
+
return result, _name, begin.value, end.value
|
|
250
|
+
|
|
207
251
|
def tween(self, _from: float, to: float, progress: float) -> Result:
|
|
208
252
|
"""Interpolates between two frames over a specified duration.
|
|
209
253
|
|
|
@@ -396,6 +396,20 @@ class FillRule(IntEnum):
|
|
|
396
396
|
return int(obj)
|
|
397
397
|
|
|
398
398
|
|
|
399
|
+
class FilterMethod(IntEnum):
|
|
400
|
+
"""Defines the image filtering method used during image scaling or transformation.
|
|
401
|
+
|
|
402
|
+
.. note::
|
|
403
|
+
Experimental API
|
|
404
|
+
"""
|
|
405
|
+
|
|
406
|
+
#: Smooth interpolation using surrounding pixels for higher quality.
|
|
407
|
+
BILINEAR = 0
|
|
408
|
+
|
|
409
|
+
#: Fast filtering using nearest-neighbor sampling.
|
|
410
|
+
NEAREST = 1
|
|
411
|
+
|
|
412
|
+
|
|
399
413
|
class ColorStop(ctypes.Structure):
|
|
400
414
|
"""A data structure storing the information about the color and its relative position inside the gradient bounds."""
|
|
401
415
|
|
|
@@ -495,6 +509,19 @@ class TextMetrics(ctypes.Structure):
|
|
|
495
509
|
advance: float #: The total vertical advance between lines of text: ascent - descent + linegap (i.e., ascent + |descent| + linegap when descent is negative).
|
|
496
510
|
|
|
497
511
|
|
|
512
|
+
class GlyphMetrics(ctypes.Structure):
|
|
513
|
+
_fields_ = [
|
|
514
|
+
("advance", ctypes.c_float),
|
|
515
|
+
("bearing", ctypes.c_float),
|
|
516
|
+
("min", PointStruct),
|
|
517
|
+
("max", PointStruct),
|
|
518
|
+
]
|
|
519
|
+
advance: float #: The advance distance along the baseline (inline) direction.
|
|
520
|
+
bearing: float #: The bearing from the origin to the glyph’s visible bound along the inline-start direction.
|
|
521
|
+
min: PointStruct #: The minimum point of the glyph bounding box in local space.
|
|
522
|
+
max: PointStruct #: The maximum point of the glyph bounding box in local space.
|
|
523
|
+
|
|
524
|
+
|
|
498
525
|
"""Callback function type for resolving external assets.
|
|
499
526
|
|
|
500
527
|
This callback is invoked when a Picture requires an external asset
|
|
@@ -64,9 +64,9 @@ class Paint:
|
|
|
64
64
|
self.thorvg_lib.tvg_paint_ref.restype = ctypes.c_uint16
|
|
65
65
|
return self.thorvg_lib.tvg_paint_ref(
|
|
66
66
|
self._paint,
|
|
67
|
-
)
|
|
67
|
+
)
|
|
68
68
|
|
|
69
|
-
def
|
|
69
|
+
def unref(self, free: bool) -> int:
|
|
70
70
|
"""Decrement the reference count for the PaintPointer object.
|
|
71
71
|
|
|
72
72
|
This method decreases the reference count of the PaintPointer object by 1.
|
|
@@ -82,12 +82,12 @@ class Paint:
|
|
|
82
82
|
|
|
83
83
|
.. versionadded:: 1.0
|
|
84
84
|
"""
|
|
85
|
-
self.thorvg_lib.
|
|
85
|
+
self.thorvg_lib.tvg_paint_unref.argtypes = [
|
|
86
86
|
PaintPointer,
|
|
87
87
|
ctypes.c_bool,
|
|
88
88
|
]
|
|
89
|
-
self.thorvg_lib.
|
|
90
|
-
return self.thorvg_lib.
|
|
89
|
+
self.thorvg_lib.tvg_paint_unref.restype = ctypes.c_uint16
|
|
90
|
+
return self.thorvg_lib.tvg_paint_unref(self._paint, ctypes.c_bool(free))
|
|
91
91
|
|
|
92
92
|
def get_ref(self) -> int:
|
|
93
93
|
"""Retrieve the current reference count of the PaintPointer object.
|
|
@@ -108,7 +108,7 @@ class Paint:
|
|
|
108
108
|
self.thorvg_lib.tvg_paint_get_ref.restype = ctypes.c_uint16
|
|
109
109
|
return self.thorvg_lib.tvg_paint_get_ref(
|
|
110
110
|
self._paint,
|
|
111
|
-
)
|
|
111
|
+
)
|
|
112
112
|
|
|
113
113
|
def set_visible(self, visible: bool) -> Result:
|
|
114
114
|
"""Sets the visibility of the Paint object.
|
|
@@ -139,23 +139,15 @@ class Paint:
|
|
|
139
139
|
self._paint, ctypes.c_bool(visible)
|
|
140
140
|
)
|
|
141
141
|
|
|
142
|
-
def get_visible(self
|
|
143
|
-
"""
|
|
144
|
-
|
|
145
|
-
This is useful for selectively excluding paint objects during rendering.
|
|
146
|
-
|
|
147
|
-
:param bool visible: A boolean flag indicating visibility. The default is ``true``.
|
|
148
|
-
- ``true``: the object will be rendered by the engine.
|
|
149
|
-
- ``false``: the object will be excluded from the drawing process.
|
|
142
|
+
def get_visible(self) -> Result:
|
|
143
|
+
"""Gets the current visibility status of the Paint object..
|
|
150
144
|
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
a paint object, remove it from the canvas.
|
|
145
|
+
:return:
|
|
146
|
+
True if the object is visible and will be rendered.
|
|
147
|
+
False if the object is hidden and will not be rendered.
|
|
148
|
+
:rtype: bool
|
|
156
149
|
|
|
157
|
-
.. seealso:: Paint.
|
|
158
|
-
.. seealso:: Canvas.remove()
|
|
150
|
+
.. seealso:: Paint.set_visible()
|
|
159
151
|
|
|
160
152
|
.. versionadded:: 1.0
|
|
161
153
|
"""
|
|
@@ -165,7 +157,50 @@ class Paint:
|
|
|
165
157
|
self.thorvg_lib.tvg_paint_get_visible.restype = ctypes.c_bool
|
|
166
158
|
return self.thorvg_lib.tvg_paint_get_visible(
|
|
167
159
|
self._paint,
|
|
168
|
-
)
|
|
160
|
+
)
|
|
161
|
+
|
|
162
|
+
def get_id(self) -> int:
|
|
163
|
+
"""Gets the ID of the Paint object.
|
|
164
|
+
|
|
165
|
+
:return: The ID of the paint object, or 0 if the ID is not set.
|
|
166
|
+
:rtype: int
|
|
167
|
+
|
|
168
|
+
.. seealso:: Picture.get_paint()
|
|
169
|
+
.. seealso:: Accessor.generate_id()
|
|
170
|
+
.. seealso:: Paint.set_id()
|
|
171
|
+
|
|
172
|
+
.. note::
|
|
173
|
+
Experimental API
|
|
174
|
+
"""
|
|
175
|
+
self.thorvg_lib.tvg_paint_get_id.argtypes = [
|
|
176
|
+
PaintPointer,
|
|
177
|
+
]
|
|
178
|
+
self.thorvg_lib.tvg_paint_get_id.restype = ctypes.c_uint32
|
|
179
|
+
return self.thorvg_lib.tvg_paint_get_id(
|
|
180
|
+
self._paint,
|
|
181
|
+
)
|
|
182
|
+
|
|
183
|
+
def set_id(self, _id: int) -> Result:
|
|
184
|
+
"""Sets the ID of the Paint object.
|
|
185
|
+
|
|
186
|
+
:param int _id: The ID to assign to the paint object.
|
|
187
|
+
|
|
188
|
+
.. seealso:: Picture.get_paint()
|
|
189
|
+
.. seealso:: Accessor.generate_id()
|
|
190
|
+
.. seealso:: Paint.get_id()
|
|
191
|
+
|
|
192
|
+
.. note::
|
|
193
|
+
Experimental API
|
|
194
|
+
"""
|
|
195
|
+
self.thorvg_lib.tvg_paint_set_id.argtypes = [
|
|
196
|
+
PaintPointer,
|
|
197
|
+
ctypes.c_uint32,
|
|
198
|
+
]
|
|
199
|
+
self.thorvg_lib.tvg_paint_set_id.restype = Result
|
|
200
|
+
return self.thorvg_lib.tvg_paint_set_id(
|
|
201
|
+
self._paint,
|
|
202
|
+
_id,
|
|
203
|
+
)
|
|
169
204
|
|
|
170
205
|
def scale(self, factor: float) -> Result:
|
|
171
206
|
"""Scales the given PaintPointer object by the given factor.
|
|
@@ -2,7 +2,13 @@
|
|
|
2
2
|
import ctypes
|
|
3
3
|
from typing import Callable, Optional, Tuple
|
|
4
4
|
|
|
5
|
-
from ..base import
|
|
5
|
+
from ..base import (
|
|
6
|
+
Colorspace,
|
|
7
|
+
FilterMethod,
|
|
8
|
+
PaintPointer,
|
|
9
|
+
PictureAssetResolverType,
|
|
10
|
+
Result,
|
|
11
|
+
)
|
|
6
12
|
from ..engine import Engine
|
|
7
13
|
from . import Paint
|
|
8
14
|
|
|
@@ -355,12 +361,12 @@ class Picture(Paint):
|
|
|
355
361
|
.. seealso:: Engine.accessor_generate_id()
|
|
356
362
|
.. versionadded: 1.0
|
|
357
363
|
"""
|
|
358
|
-
self.thorvg_lib.
|
|
364
|
+
self.thorvg_lib.tvg_picture_get_paint.argtypes = [
|
|
359
365
|
PaintPointer,
|
|
360
366
|
ctypes.c_uint32,
|
|
361
367
|
]
|
|
362
|
-
self.thorvg_lib.
|
|
363
|
-
paint_struct = self.thorvg_lib.
|
|
368
|
+
self.thorvg_lib.tvg_picture_get_paint.restype = PaintPointer
|
|
369
|
+
paint_struct = self.thorvg_lib.tvg_picture_get_paint(
|
|
364
370
|
self._paint,
|
|
365
371
|
ctypes.c_uint32(_id),
|
|
366
372
|
)
|
|
@@ -368,3 +374,29 @@ class Picture(Paint):
|
|
|
368
374
|
return Paint(self.engine, paint_struct)
|
|
369
375
|
else:
|
|
370
376
|
return None
|
|
377
|
+
|
|
378
|
+
def set_filter(self, method: FilterMethod) -> Result:
|
|
379
|
+
"""Sets the image filtering method for rendering this picture.
|
|
380
|
+
|
|
381
|
+
Specifies how the image data should be filtered when it is scaled or transformed
|
|
382
|
+
during rendering. This affects the visual quality and performance of the output.
|
|
383
|
+
|
|
384
|
+
:param thorvg_python.base.FilterMethod method:
|
|
385
|
+
The filtering method to apply. Default is thorvg_python.base.FilterMethod.BILINEAR
|
|
386
|
+
|
|
387
|
+
:return: Result
|
|
388
|
+
:rtype: thorvg_python.base.Result
|
|
389
|
+
|
|
390
|
+
.. seealso:: FilterMethod
|
|
391
|
+
.. note::
|
|
392
|
+
Experimental API
|
|
393
|
+
"""
|
|
394
|
+
self.thorvg_lib.tvg_picture_set_filter.argtypes = [
|
|
395
|
+
PaintPointer,
|
|
396
|
+
ctypes.c_uint8,
|
|
397
|
+
]
|
|
398
|
+
self.thorvg_lib.tvg_picture_set_filter.restype = Result
|
|
399
|
+
result = self.thorvg_lib.tvg_picture_set_filter(
|
|
400
|
+
self._paint, ctypes.c_uint8(method)
|
|
401
|
+
)
|
|
402
|
+
return result
|
|
@@ -2,7 +2,14 @@
|
|
|
2
2
|
import ctypes
|
|
3
3
|
from typing import Optional, Tuple
|
|
4
4
|
|
|
5
|
-
from ..base import
|
|
5
|
+
from ..base import (
|
|
6
|
+
GlyphMetrics,
|
|
7
|
+
GradientPointer,
|
|
8
|
+
PaintPointer,
|
|
9
|
+
Result,
|
|
10
|
+
TextMetrics,
|
|
11
|
+
TextWrap,
|
|
12
|
+
)
|
|
6
13
|
from ..engine import Engine
|
|
7
14
|
from ..gradient import Gradient
|
|
8
15
|
from . import Paint
|
|
@@ -128,8 +135,9 @@ class Text(Paint):
|
|
|
128
135
|
|
|
129
136
|
:param str utf8: The multi-byte text encoded with utf8 string to be rendered.
|
|
130
137
|
|
|
131
|
-
:
|
|
138
|
+
:rtype: Result
|
|
132
139
|
|
|
140
|
+
.. seealso:: Text.get_text()
|
|
133
141
|
.. versionadded: 1.0
|
|
134
142
|
"""
|
|
135
143
|
utf8_bytes = utf8.encode() + b"\x00"
|
|
@@ -145,6 +153,29 @@ class Text(Paint):
|
|
|
145
153
|
ctypes.pointer(text_arr),
|
|
146
154
|
)
|
|
147
155
|
|
|
156
|
+
def get_text(self) -> str:
|
|
157
|
+
"""Returns the currently assigned unicode text.
|
|
158
|
+
|
|
159
|
+
This function retrieves the unicode string that is currently set
|
|
160
|
+
for rendering. The returned text is encoded in UTF-8.
|
|
161
|
+
|
|
162
|
+
:return: The UTF-8 encoded multi-byte text string.
|
|
163
|
+
:rtype: str
|
|
164
|
+
|
|
165
|
+
.. seealso:: Text.set_text()
|
|
166
|
+
|
|
167
|
+
.. note::
|
|
168
|
+
Experimental API
|
|
169
|
+
"""
|
|
170
|
+
self.thorvg_lib.tvg_text_set_text.argtypes = [
|
|
171
|
+
PaintPointer,
|
|
172
|
+
]
|
|
173
|
+
self.thorvg_lib.tvg_text_set_text.restype = ctypes.c_char_p
|
|
174
|
+
|
|
175
|
+
return self.thorvg_lib.tvg_text_set_text(
|
|
176
|
+
self._paint,
|
|
177
|
+
).decode("utf-8")
|
|
178
|
+
|
|
148
179
|
def align(self, x: float, y: float) -> Result:
|
|
149
180
|
"""Sets text alignment or anchor per axis.
|
|
150
181
|
|
|
@@ -210,6 +241,7 @@ class Text(Paint):
|
|
|
210
241
|
:param thorvg_python.base.TextWrap mode: The wrapping strategy to apply. Default is ``NONE``.
|
|
211
242
|
|
|
212
243
|
.. seealso:: TextWrap
|
|
244
|
+
.. seealso:: Text.line_count()
|
|
213
245
|
.. versionadded:: 1.0
|
|
214
246
|
"""
|
|
215
247
|
self.thorvg_lib.tvg_text_wrap_mode.argtypes = [
|
|
@@ -222,6 +254,28 @@ class Text(Paint):
|
|
|
222
254
|
mode,
|
|
223
255
|
)
|
|
224
256
|
|
|
257
|
+
def line_count(self) -> int:
|
|
258
|
+
"""Returns the number of text lines.
|
|
259
|
+
|
|
260
|
+
This function retrieves the number of lines generated after applying text layout and wrapping.
|
|
261
|
+
The returned value reflects the current wrapping configuration set by thorvg_python.Text.wrap_mode().
|
|
262
|
+
The line count is also increased by explicit line feed characters ('\n') contained in the text.
|
|
263
|
+
|
|
264
|
+
:return: The total number of lines
|
|
265
|
+
:rtype: int
|
|
266
|
+
|
|
267
|
+
.. seealso:: Text.wrap_mode()
|
|
268
|
+
.. note::
|
|
269
|
+
Experimental API
|
|
270
|
+
"""
|
|
271
|
+
self.thorvg_lib.tvg_text_wrap_mode.argtypes = [
|
|
272
|
+
PaintPointer,
|
|
273
|
+
]
|
|
274
|
+
self.thorvg_lib.tvg_text_wrap_mode.restype = ctypes.c_uint32
|
|
275
|
+
return self.thorvg_lib.tvg_text_wrap_mode(
|
|
276
|
+
self._paint,
|
|
277
|
+
)
|
|
278
|
+
|
|
225
279
|
def spacing(self, letter: float, line: float) -> Result:
|
|
226
280
|
"""Set the spacing scale factors for text layout.
|
|
227
281
|
|
|
@@ -389,7 +443,7 @@ class Text(Paint):
|
|
|
389
443
|
gradient._grad, # type: ignore
|
|
390
444
|
)
|
|
391
445
|
|
|
392
|
-
def
|
|
446
|
+
def get_text_metrics(self) -> Tuple[Result, TextMetrics]:
|
|
393
447
|
"""Retrieves the layout metrics of the text object.
|
|
394
448
|
|
|
395
449
|
Fills the provided `TextMetrics` structure with the font layout values of this text object,
|
|
@@ -400,7 +454,7 @@ class Text(Paint):
|
|
|
400
454
|
|
|
401
455
|
:return: A `TextMetrics` structure filled with the resulting values.
|
|
402
456
|
:rtype: thorvg_python.base.TextMetrics
|
|
403
|
-
:return:
|
|
457
|
+
:return: Result.INSUFFICIENT_CONDITION if no font or size has been set yet.
|
|
404
458
|
:rtype: thorvg_python.base.Result
|
|
405
459
|
|
|
406
460
|
.. seealso:: TextMetrics
|
|
@@ -408,13 +462,56 @@ class Text(Paint):
|
|
|
408
462
|
Experimental API
|
|
409
463
|
"""
|
|
410
464
|
metrics = TextMetrics()
|
|
411
|
-
self.thorvg_lib.
|
|
465
|
+
self.thorvg_lib.tvg_text_get_text_metrics.argtypes = [
|
|
412
466
|
PaintPointer,
|
|
413
467
|
ctypes.POINTER(TextMetrics),
|
|
414
468
|
]
|
|
415
|
-
self.thorvg_lib.
|
|
416
|
-
result = self.thorvg_lib.
|
|
469
|
+
self.thorvg_lib.tvg_text_get_text_metrics.restype = Result
|
|
470
|
+
result = self.thorvg_lib.tvg_text_get_text_metrics(
|
|
471
|
+
self._paint,
|
|
472
|
+
ctypes.pointer(metrics),
|
|
473
|
+
)
|
|
474
|
+
return result, metrics
|
|
475
|
+
|
|
476
|
+
def get_glyph_metrics(self, ch: str) -> Tuple[Result, GlyphMetrics]:
|
|
477
|
+
"""Retrieves the layout metrics of a glyph in the text object.
|
|
478
|
+
|
|
479
|
+
Fills the provided @ref Tvg_Glyph_Metrics structure with the horizontal layout values
|
|
480
|
+
of the specified glyph, such as advance, left-side bearing, and bounding box.
|
|
481
|
+
|
|
482
|
+
The returned values reflect the font size applied to the text object,
|
|
483
|
+
but do not include any transformations (e.g., scale, rotation, or translation).
|
|
484
|
+
|
|
485
|
+
The input character must be a single UTF-8 encoded character.
|
|
486
|
+
|
|
487
|
+
:return: A `GlyphMetrics` structure filled with the resulting values.
|
|
488
|
+
:rtype: thorvg_python.base.GlyphMetrics
|
|
489
|
+
:return:
|
|
490
|
+
Result.INSUFFICIENT_CONDITION if no font or size has been set yet.
|
|
491
|
+
RESULT.INVALID_ARGUMENT if the given character is invalid or not supported.
|
|
492
|
+
:rtype: thorvg_python.base.Result
|
|
493
|
+
|
|
494
|
+
.. seealso:: GlyphMetrics
|
|
495
|
+
.. note::
|
|
496
|
+
Currently, ThorVG only supports horizontal text layout.
|
|
497
|
+
.. note::
|
|
498
|
+
Experimental API
|
|
499
|
+
"""
|
|
500
|
+
metrics = GlyphMetrics()
|
|
501
|
+
|
|
502
|
+
ch_bytes = ch.encode() + b"\x00"
|
|
503
|
+
ch_arr_type = ctypes.c_char * len(ch_bytes)
|
|
504
|
+
ch_arr = ch_arr_type.from_buffer_copy(ch_bytes)
|
|
505
|
+
|
|
506
|
+
self.thorvg_lib.tvg_text_get_glyph_metrics.argtypes = [
|
|
507
|
+
PaintPointer,
|
|
508
|
+
ctypes.POINTER(ch_arr_type),
|
|
509
|
+
ctypes.POINTER(GlyphMetrics),
|
|
510
|
+
]
|
|
511
|
+
self.thorvg_lib.tvg_text_get_glyph_metrics.restype = Result
|
|
512
|
+
result = self.thorvg_lib.tvg_text_get_glyph_metrics(
|
|
417
513
|
self._paint,
|
|
514
|
+
ctypes.pointer(ch_arr),
|
|
418
515
|
ctypes.pointer(metrics),
|
|
419
516
|
)
|
|
420
517
|
return result, metrics
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: thorvg-python
|
|
3
|
-
Version: 1.1.
|
|
3
|
+
Version: 1.1.2
|
|
4
4
|
Summary: A ctypes API for thorvg, a vector graphics engine supporting SVG and Lottie formats.
|
|
5
5
|
Author-email: chaudominic <chaudominic2@gmail.com>
|
|
6
6
|
License: GNU LESSER GENERAL PUBLIC LICENSE
|
|
@@ -532,7 +532,7 @@ Dynamic: license-file
|
|
|
532
532
|
|
|
533
533
|
A ctypes API for thorvg, with additional functions for getting Pillow Image.
|
|
534
534
|
|
|
535
|
-
The functions mostly follow [thorvg/src/bindings/capi/thorvg_capi.h](https://github.com/thorvg/thorvg/blob/v1.0.
|
|
535
|
+
The functions mostly follow [thorvg/src/bindings/capi/thorvg_capi.h](https://github.com/thorvg/thorvg/blob/v1.0.3/src/bindings/capi/thorvg_capi.h)
|
|
536
536
|
|
|
537
537
|
Documentations: https://thorvg-python.readthedocs.io/en/latest/
|
|
538
538
|
|
|
@@ -546,7 +546,7 @@ Documentations: https://thorvg-python.readthedocs.io/en/latest/
|
|
|
546
546
|
|
|
547
547
|
Note that thorvg is included in the wheel package, you need not install libthorvg.
|
|
548
548
|
Version bundled is the version available on [Conan](https://conan.io/center/recipes/thorvg)
|
|
549
|
-
(Currently 1.0.
|
|
549
|
+
(Currently 1.0.3)
|
|
550
550
|
|
|
551
551
|
To install, run the following:
|
|
552
552
|
```bash
|
|
@@ -568,15 +568,16 @@ canvas = tvg.SwCanvas(engine)
|
|
|
568
568
|
canvas.set_target(512, 256) # w, h
|
|
569
569
|
|
|
570
570
|
rect = tvg.Shape(engine)
|
|
571
|
-
rect.append_rect(10, 10, 64, 64, 10, 10) # x, y, w, h, rx, ry
|
|
571
|
+
rect.append_rect(10, 10, 64, 64, 10, 10, True) # x, y, w, h, rx, ry, clockwise
|
|
572
572
|
rect.set_fill_color(32, 64, 128, 100) # r, g, b, a
|
|
573
|
-
canvas.
|
|
573
|
+
canvas.add(rect)
|
|
574
574
|
|
|
575
575
|
canvas.update()
|
|
576
576
|
canvas.draw(True)
|
|
577
577
|
canvas.sync()
|
|
578
578
|
|
|
579
579
|
im = canvas.get_pillow()
|
|
580
|
+
im.save("test.png")
|
|
580
581
|
canvas.destroy()
|
|
581
582
|
engine.term()
|
|
582
583
|
```
|
|
@@ -318,6 +318,18 @@ def test_paint():
|
|
|
318
318
|
]
|
|
319
319
|
assert matrix_list == matrix_out_list
|
|
320
320
|
|
|
321
|
+
assert shape.get_ref() == 1
|
|
322
|
+
assert shape.ref() == 2
|
|
323
|
+
assert shape.unref(free=False) == 1
|
|
324
|
+
|
|
325
|
+
assert shape.set_visible(False) == tvg.Result.SUCCESS
|
|
326
|
+
assert shape.get_visible() is False
|
|
327
|
+
assert shape.set_visible(True) == tvg.Result.SUCCESS
|
|
328
|
+
|
|
329
|
+
assert shape.get_id() == 0
|
|
330
|
+
assert shape.set_id(1337) == tvg.Result.SUCCESS
|
|
331
|
+
assert shape.get_id() == 1337
|
|
332
|
+
|
|
321
333
|
shape2 = tvg.Shape(engine)
|
|
322
334
|
assert shape.set_mask_method(shape2, tvg.MaskMethod.DARKEN) == tvg.Result.SUCCESS
|
|
323
335
|
result, method = shape.get_mask_method(shape2)
|
|
@@ -515,6 +527,7 @@ def _test_picture_load(test_file: str, ref: str):
|
|
|
515
527
|
assert check_im_same(im, ref) is True
|
|
516
528
|
|
|
517
529
|
assert picture.get_size() == (tvg.Result.SUCCESS, 256, 256)
|
|
530
|
+
assert isinstance(picture.get_paint(0), tvg.Paint)
|
|
518
531
|
|
|
519
532
|
assert canvas.destroy() == tvg.Result.SUCCESS
|
|
520
533
|
assert engine.term() == tvg.Result.SUCCESS
|
|
Binary file
|
|
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
|