thorvg-python 1.0.1__py3-none-win32.whl
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/__init__.py +35 -0
- thorvg_python/animation/__init__.py +251 -0
- thorvg_python/animation/lottie.py +162 -0
- thorvg_python/base.py +447 -0
- thorvg_python/canvas/__init__.py +246 -0
- thorvg_python/canvas/sw.py +196 -0
- thorvg_python/engine.py +371 -0
- thorvg_python/gradient/__init__.py +248 -0
- thorvg_python/gradient/linear.py +130 -0
- thorvg_python/gradient/radial.py +114 -0
- thorvg_python/paint/__init__.py +432 -0
- thorvg_python/paint/picture.py +226 -0
- thorvg_python/paint/scene.py +123 -0
- thorvg_python/paint/shape.py +1082 -0
- thorvg_python/paint/text.py +198 -0
- thorvg_python/py.typed +0 -0
- thorvg_python/saver.py +118 -0
- thorvg_python/thorvg-0.dll +0 -0
- thorvg_python-1.0.1.dist-info/METADATA +647 -0
- thorvg_python-1.0.1.dist-info/RECORD +23 -0
- thorvg_python-1.0.1.dist-info/WHEEL +5 -0
- thorvg_python-1.0.1.dist-info/licenses/LICENSE +504 -0
- thorvg_python-1.0.1.dist-info/top_level.txt +1 -0
|
@@ -0,0 +1,196 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
import ctypes
|
|
3
|
+
from typing import TYPE_CHECKING, Optional, Tuple
|
|
4
|
+
|
|
5
|
+
from ..base import CanvasStruct, Colorspace, MempoolPolicy, Result
|
|
6
|
+
from ..engine import Engine
|
|
7
|
+
from . import Canvas
|
|
8
|
+
|
|
9
|
+
if TYPE_CHECKING:
|
|
10
|
+
from PIL import Image
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
class SwCanvas(Canvas):
|
|
14
|
+
"""
|
|
15
|
+
SwCanvas API
|
|
16
|
+
|
|
17
|
+
A module for rendering the graphical elements using the software engine.
|
|
18
|
+
"""
|
|
19
|
+
|
|
20
|
+
def __init__(self, engine: Engine, canvas: Optional[CanvasStruct] = None):
|
|
21
|
+
self.engine = engine
|
|
22
|
+
self.thorvg_lib = engine.thorvg_lib
|
|
23
|
+
self.buffer_arr: Optional[ctypes.Array[ctypes.c_uint32]] = None
|
|
24
|
+
self.w: Optional[int] = None
|
|
25
|
+
self.h: Optional[int] = None
|
|
26
|
+
self.stride: Optional[int] = None
|
|
27
|
+
self.cs: Optional[Colorspace] = None
|
|
28
|
+
if canvas is None:
|
|
29
|
+
self._canvas = self._create()
|
|
30
|
+
else:
|
|
31
|
+
self._canvas = canvas
|
|
32
|
+
|
|
33
|
+
def _create(self) -> CanvasStruct:
|
|
34
|
+
"""Creates a Canvas object.
|
|
35
|
+
|
|
36
|
+
Note that you need not call this method as it is auto called when initializing ``SwCanvas()``.
|
|
37
|
+
|
|
38
|
+
.. code-block:: python
|
|
39
|
+
from thorvg_python import Engine, SwCanvas
|
|
40
|
+
|
|
41
|
+
engine = Engine()
|
|
42
|
+
canvas = SwCanvas(engine)
|
|
43
|
+
result, buffer = canvas.set_target(100, 100, 100, Colorspace.ARGB8888)
|
|
44
|
+
|
|
45
|
+
//set up paints and add them into the canvas before drawing it
|
|
46
|
+
|
|
47
|
+
canvas.destroy()
|
|
48
|
+
engine.term()
|
|
49
|
+
|
|
50
|
+
:return: new CanvasStruct object.
|
|
51
|
+
:rtype: CanvasStruct
|
|
52
|
+
"""
|
|
53
|
+
self.thorvg_lib.tvg_swcanvas_create.restype = ctypes.POINTER(CanvasStruct)
|
|
54
|
+
return self.thorvg_lib.tvg_swcanvas_create().contents
|
|
55
|
+
|
|
56
|
+
def set_target(
|
|
57
|
+
self,
|
|
58
|
+
w: int,
|
|
59
|
+
h: int,
|
|
60
|
+
stride: Optional[int] = None,
|
|
61
|
+
cs: Colorspace = Colorspace.ABGR8888,
|
|
62
|
+
) -> Tuple[Result, ctypes.Array[ctypes.c_uint32]]:
|
|
63
|
+
"""Sets the buffer used in the rasterization process and defines the used colorspace.
|
|
64
|
+
|
|
65
|
+
For optimisation reasons TVG does not allocate memory for the output buffer on its own.
|
|
66
|
+
The buffer of a desirable size should be allocated and owned by the caller.
|
|
67
|
+
|
|
68
|
+
w, h, stride, cs and buffer_arr will be stored in instance when calling this method.
|
|
69
|
+
|
|
70
|
+
:param int w: The width of the raster image.
|
|
71
|
+
:param int h: The height of the raster image.
|
|
72
|
+
:param Optional[int] stride: The stride of the raster image - default is same value as ``w``.
|
|
73
|
+
:param Colorspace cs: The colorspace value defining the way the 32-bits colors should be read/written.
|
|
74
|
+
- ABGR8888 (Default)
|
|
75
|
+
- ARGB8888
|
|
76
|
+
|
|
77
|
+
:return:
|
|
78
|
+
- INVALID_ARGUMENTS An invalid canvas or buffer pointer passed or one of the ``stride``, ``w`` or ``h`` being zero.
|
|
79
|
+
- INSUFFICIENT_CONDITION if the canvas is performing rendering. Please ensure the canvas is synced.
|
|
80
|
+
- NOT_SUPPORTED The software engine is not supported.
|
|
81
|
+
:rtype: Result
|
|
82
|
+
:return: A pointer to the allocated memory block of the size ``stride`` x ``h``.
|
|
83
|
+
:rtype: ctypes.Array[ctypes.c_uint32]
|
|
84
|
+
|
|
85
|
+
.. warning::
|
|
86
|
+
Do not access ``buffer`` during tvg_canvas_draw() - tvg_canvas_sync(). It should not be accessed while the engine is writing on it.
|
|
87
|
+
|
|
88
|
+
.. seealso:: Colorspace
|
|
89
|
+
"""
|
|
90
|
+
if stride is None:
|
|
91
|
+
stride = w
|
|
92
|
+
buffer_arr_type = ctypes.c_uint32 * (stride * h)
|
|
93
|
+
buffer_arr = buffer_arr_type()
|
|
94
|
+
self.thorvg_lib.tvg_swcanvas_set_target.argtypes = [
|
|
95
|
+
ctypes.POINTER(CanvasStruct),
|
|
96
|
+
ctypes.POINTER(buffer_arr_type),
|
|
97
|
+
ctypes.c_uint32,
|
|
98
|
+
ctypes.c_uint32,
|
|
99
|
+
ctypes.c_uint32,
|
|
100
|
+
ctypes.c_int,
|
|
101
|
+
]
|
|
102
|
+
self.thorvg_lib.tvg_swcanvas_set_target.restype = Result
|
|
103
|
+
result = self.thorvg_lib.tvg_swcanvas_set_target(
|
|
104
|
+
ctypes.pointer(self._canvas),
|
|
105
|
+
ctypes.pointer(buffer_arr),
|
|
106
|
+
ctypes.c_uint32(stride),
|
|
107
|
+
ctypes.c_uint32(w),
|
|
108
|
+
ctypes.c_uint32(h),
|
|
109
|
+
cs,
|
|
110
|
+
)
|
|
111
|
+
self.buffer_arr = buffer_arr
|
|
112
|
+
self.w = w
|
|
113
|
+
self.h = h
|
|
114
|
+
self.stride = stride
|
|
115
|
+
self.cs = cs
|
|
116
|
+
return result
|
|
117
|
+
|
|
118
|
+
def get_pillow(self, pil_mode: str = "RGBA") -> "Image.Image":
|
|
119
|
+
"""Gets Pillow Image from buffer of canvas
|
|
120
|
+
|
|
121
|
+
.. code-block:: python
|
|
122
|
+
|
|
123
|
+
from thorvg_python import Engine, SwCanvas, Shape
|
|
124
|
+
|
|
125
|
+
engine = tvg.Engine()
|
|
126
|
+
canvas = tvg.SwCanvas(engine)
|
|
127
|
+
canvas.set_target(1920, 1080)
|
|
128
|
+
|
|
129
|
+
// Draw on canvas
|
|
130
|
+
rect = Shape(engine)
|
|
131
|
+
rect.append_rect(50, 50, 200, 200, 20, 20)
|
|
132
|
+
rect.set_fill_color(100, 100, 100, 100)
|
|
133
|
+
canvas.push(rect)
|
|
134
|
+
|
|
135
|
+
canvas.draw()
|
|
136
|
+
canvas.sync()
|
|
137
|
+
|
|
138
|
+
im = canvas.get_pillow()
|
|
139
|
+
|
|
140
|
+
canvas.destroy()
|
|
141
|
+
engine.term()
|
|
142
|
+
|
|
143
|
+
:param str pil_mode: Color mode of Pillow Image. Defaults to RGBA
|
|
144
|
+
|
|
145
|
+
:return: Pillow image
|
|
146
|
+
:rtype: PIL.Image.Image
|
|
147
|
+
"""
|
|
148
|
+
from PIL import Image
|
|
149
|
+
|
|
150
|
+
if self.w is None:
|
|
151
|
+
raise RuntimeError("w cannot be None")
|
|
152
|
+
if self.h is None:
|
|
153
|
+
raise RuntimeError("h cannot be None")
|
|
154
|
+
if self.buffer_arr is None:
|
|
155
|
+
raise RuntimeError("buffer_arr cannot be None")
|
|
156
|
+
|
|
157
|
+
return Image.frombuffer( # type: ignore
|
|
158
|
+
"RGBA", (self.w, self.h), bytes(self.buffer_arr), "raw"
|
|
159
|
+
).convert(pil_mode)
|
|
160
|
+
|
|
161
|
+
def set_mempool(
|
|
162
|
+
self,
|
|
163
|
+
policy: MempoolPolicy,
|
|
164
|
+
) -> Result:
|
|
165
|
+
"""Sets the software engine memory pool behavior policy.
|
|
166
|
+
|
|
167
|
+
ThorVG draws a lot of shapes, it allocates/deallocates a few chunk of memory
|
|
168
|
+
while processing rendering. It internally uses one shared memory pool
|
|
169
|
+
which can be reused among the canvases in order to avoid memory overhead.
|
|
170
|
+
|
|
171
|
+
Thus ThorVG suggests using a memory pool policy to satisfy user demands,
|
|
172
|
+
if it needs to guarantee the thread-safety of the internal data access.
|
|
173
|
+
|
|
174
|
+
:param MempoolPolicy policy: The method specifying the Memory Pool behavior. The default value is ``DEFAULT``.
|
|
175
|
+
|
|
176
|
+
:return:
|
|
177
|
+
- INVALID_ARGUMENTS An invalid canvas pointer passed.
|
|
178
|
+
- INSUFFICIENT_CONDITION The canvas contains some paints already.
|
|
179
|
+
- NOT_SUPPORTED The software engine is not supported.
|
|
180
|
+
:rtype: Result
|
|
181
|
+
|
|
182
|
+
.. note::
|
|
183
|
+
When ``policy`` is set as ``INDIVIDUAL``, the current instance of canvas uses its own individual
|
|
184
|
+
memory data, which is not shared with others. This is necessary when the canvas is accessed on a worker-thread.
|
|
185
|
+
|
|
186
|
+
.. warning::
|
|
187
|
+
It's not allowed after pushing any paints.
|
|
188
|
+
"""
|
|
189
|
+
self.thorvg_lib.tvg_swcanvas_set_mempool.argtypes = [
|
|
190
|
+
ctypes.POINTER(CanvasStruct),
|
|
191
|
+
ctypes.c_int,
|
|
192
|
+
]
|
|
193
|
+
self.thorvg_lib.tvg_swcanvas_set_mempool.restype = Result
|
|
194
|
+
return self.thorvg_lib.tvg_swcanvas_set_mempool(
|
|
195
|
+
ctypes.pointer(self._canvas), policy
|
|
196
|
+
)
|
thorvg_python/engine.py
ADDED
|
@@ -0,0 +1,371 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
import ctypes
|
|
3
|
+
import os
|
|
4
|
+
import sys
|
|
5
|
+
import sysconfig
|
|
6
|
+
from types import TracebackType
|
|
7
|
+
from typing import List, Optional, Tuple, Type
|
|
8
|
+
|
|
9
|
+
from .base import EngineBackend, Result
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
def _load_lib_with_prefix_suffix(
|
|
13
|
+
lib_prefix: str, lib_suffix: str
|
|
14
|
+
) -> Optional[ctypes.CDLL]:
|
|
15
|
+
package_dir = os.path.dirname(__file__)
|
|
16
|
+
thorvg_lib_name = lib_prefix + "thorvg" + lib_suffix
|
|
17
|
+
thorvg_lib_path_local = os.path.join(package_dir, thorvg_lib_name)
|
|
18
|
+
|
|
19
|
+
if os.path.isfile(thorvg_lib_path_local):
|
|
20
|
+
thorvg_lib_path = thorvg_lib_path_local
|
|
21
|
+
elif os.path.isfile(thorvg_lib_name):
|
|
22
|
+
thorvg_lib_path = os.path.abspath(thorvg_lib_name)
|
|
23
|
+
else:
|
|
24
|
+
thorvg_lib_path = thorvg_lib_name
|
|
25
|
+
|
|
26
|
+
try:
|
|
27
|
+
return ctypes.cdll.LoadLibrary(thorvg_lib_path)
|
|
28
|
+
except OSError:
|
|
29
|
+
return None
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
def _load_lib(thorvg_lib_path: Optional[str] = None) -> Optional[ctypes.CDLL]:
|
|
33
|
+
if thorvg_lib_path:
|
|
34
|
+
try:
|
|
35
|
+
return ctypes.cdll.LoadLibrary(thorvg_lib_path)
|
|
36
|
+
except OSError:
|
|
37
|
+
return None
|
|
38
|
+
|
|
39
|
+
if sys.platform.startswith(("win32", "cygwin", "msys", "os2")):
|
|
40
|
+
lib = _load_lib_with_prefix_suffix("", "-0.dll")
|
|
41
|
+
elif sys.platform.startswith("darwin"):
|
|
42
|
+
lib = _load_lib_with_prefix_suffix("lib", ".dylib")
|
|
43
|
+
else:
|
|
44
|
+
lib = _load_lib_with_prefix_suffix("lib", ".so")
|
|
45
|
+
|
|
46
|
+
if lib:
|
|
47
|
+
return lib
|
|
48
|
+
|
|
49
|
+
lib_suffixes: List[str] = []
|
|
50
|
+
shlib_suffix = sysconfig.get_config_var("SHLIB_SUFFIX")
|
|
51
|
+
if isinstance(shlib_suffix, str):
|
|
52
|
+
lib_suffixes.append(shlib_suffix)
|
|
53
|
+
if sys.platform.startswith(("win32", "cygwin", "msys", "os2")):
|
|
54
|
+
lib_prefixes = ("", "lib")
|
|
55
|
+
elif sys.platform.startswith("darwin"):
|
|
56
|
+
lib_prefixes = ("lib", "")
|
|
57
|
+
else:
|
|
58
|
+
lib_prefixes = ("lib", "")
|
|
59
|
+
lib_suffixes.extend([".so", "-0.dll", ".dll", ".dylib"])
|
|
60
|
+
|
|
61
|
+
for lib_prefix in lib_prefixes:
|
|
62
|
+
for lib_suffix in set(lib_suffixes):
|
|
63
|
+
lib = _load_lib_with_prefix_suffix(lib_prefix, lib_suffix)
|
|
64
|
+
if lib:
|
|
65
|
+
return lib
|
|
66
|
+
|
|
67
|
+
return None
|
|
68
|
+
|
|
69
|
+
|
|
70
|
+
THORVG_LIB = _load_lib()
|
|
71
|
+
|
|
72
|
+
|
|
73
|
+
class Engine:
|
|
74
|
+
"""
|
|
75
|
+
Engine API
|
|
76
|
+
|
|
77
|
+
A module enabling initialization and termination of the TVG engines.
|
|
78
|
+
"""
|
|
79
|
+
|
|
80
|
+
def __init__(
|
|
81
|
+
self,
|
|
82
|
+
thorvg_lib_path: Optional[str] = None,
|
|
83
|
+
engine_method: EngineBackend = EngineBackend.SW,
|
|
84
|
+
threads: int = 0,
|
|
85
|
+
) -> None:
|
|
86
|
+
self.engine_method = engine_method
|
|
87
|
+
self.threads = threads
|
|
88
|
+
self._load_lib(thorvg_lib_path)
|
|
89
|
+
self.init_result = self.init(self.engine_method, threads)
|
|
90
|
+
|
|
91
|
+
def _load_lib(self, thorvg_lib_path: Optional[str] = None) -> None:
|
|
92
|
+
if thorvg_lib_path is None:
|
|
93
|
+
if THORVG_LIB is None:
|
|
94
|
+
raise OSError("Could not load thorvg library")
|
|
95
|
+
else:
|
|
96
|
+
self.thorvg_lib = THORVG_LIB
|
|
97
|
+
return
|
|
98
|
+
|
|
99
|
+
thorvg_lib = _load_lib(thorvg_lib_path)
|
|
100
|
+
if thorvg_lib is None:
|
|
101
|
+
raise OSError(f"Could not load thorvg library from {thorvg_lib_path}")
|
|
102
|
+
else:
|
|
103
|
+
self.thorvg_lib = thorvg_lib
|
|
104
|
+
|
|
105
|
+
def __del__(self) -> None:
|
|
106
|
+
if self.thorvg_lib:
|
|
107
|
+
self.term(self.engine_method)
|
|
108
|
+
|
|
109
|
+
def __enter__(self) -> "Engine":
|
|
110
|
+
return self
|
|
111
|
+
|
|
112
|
+
def __exit__(
|
|
113
|
+
self,
|
|
114
|
+
exc_type: Optional[Type[BaseException]],
|
|
115
|
+
exc_val: Optional[BaseException],
|
|
116
|
+
exc_tb: Optional[TracebackType],
|
|
117
|
+
) -> None:
|
|
118
|
+
if self.thorvg_lib:
|
|
119
|
+
self.term(self.engine_method)
|
|
120
|
+
|
|
121
|
+
def init(self, engine_method: EngineBackend, threads: int) -> Result:
|
|
122
|
+
"""Initializes TVG engines.
|
|
123
|
+
|
|
124
|
+
TVG requires the running-engine environment.
|
|
125
|
+
TVG runs its own task-scheduler for parallelizing rendering tasks efficiently.
|
|
126
|
+
You can indicate the number of threads, the count of which is designated ``threads``.
|
|
127
|
+
In the initialization step, TVG will generate/spawn the threads as set by ``threads`` count.
|
|
128
|
+
|
|
129
|
+
.. code-block:: python
|
|
130
|
+
|
|
131
|
+
from thorvg_python import Engine
|
|
132
|
+
engine = Engine.init(EngineBackend.SW, 0); //Initialize software renderer and use the main thread only
|
|
133
|
+
|
|
134
|
+
:param EngineBackend engine_method: The engine types to initialize. This is relative to the Canvas types, in which it will be used. For multiple backends bitwise operation is allowed.
|
|
135
|
+
- SW: CPU rasterizer
|
|
136
|
+
- GL: OpenGL rasterizer (not supported yet)
|
|
137
|
+
:param int threads: The number of additional threads used to perform rendering. Zero indicates only the main thread is to be used.
|
|
138
|
+
|
|
139
|
+
:return:
|
|
140
|
+
- INVALID_ARGUMENT Unknown engine type.
|
|
141
|
+
- NOT_SUPPORTED Unsupported engine type.
|
|
142
|
+
:rtype: Result
|
|
143
|
+
|
|
144
|
+
.. note::
|
|
145
|
+
The Initializer keeps track of the number of times it was called. Threads count is fixed at the first init() call.
|
|
146
|
+
.. seealso:: Engine.term()
|
|
147
|
+
.. seealso:: EngineBackend
|
|
148
|
+
"""
|
|
149
|
+
self.thorvg_lib.tvg_engine_init.argtypes = [ctypes.c_int, ctypes.c_int]
|
|
150
|
+
self.thorvg_lib.tvg_engine_init.restype = Result
|
|
151
|
+
return self.thorvg_lib.tvg_engine_init(engine_method, ctypes.c_int(threads))
|
|
152
|
+
|
|
153
|
+
def term(self, engine_method: Optional[EngineBackend] = None) -> Result:
|
|
154
|
+
"""Terminates TVG engines.
|
|
155
|
+
|
|
156
|
+
It should be called in case of termination of the TVG client with the same engine types as were passed when tvg_engine_init() was called.
|
|
157
|
+
|
|
158
|
+
.. code-block:: python
|
|
159
|
+
|
|
160
|
+
from thorvg_python import Engine
|
|
161
|
+
engine = Engine()
|
|
162
|
+
//define canvas and shapes, update shapes, general rendering calls
|
|
163
|
+
engine.tvg_engine_term()
|
|
164
|
+
|
|
165
|
+
:param Optional[EngineBackend] engine_method: The engine types to terminate.
|
|
166
|
+
This is relative to the Canvas types, in which it will be used.
|
|
167
|
+
For multiple backends bitwise operation is allowed.
|
|
168
|
+
If ``None`` is passed, all engine types will be terminated
|
|
169
|
+
- SW: CPU rasterizer
|
|
170
|
+
- GL: OpenGL rasterizer (not supported yet)
|
|
171
|
+
|
|
172
|
+
:return:
|
|
173
|
+
- INSUFFICIENT_CONDITION Nothing to be terminated.
|
|
174
|
+
- INVALID_ARGUMENT Unknown engine type.
|
|
175
|
+
- NOT_SUPPORTED Unsupported engine type.
|
|
176
|
+
:rtype: Result
|
|
177
|
+
|
|
178
|
+
.. seealso:: Engine.init()
|
|
179
|
+
.. seealso:: EngineBackend
|
|
180
|
+
"""
|
|
181
|
+
if engine_method is None:
|
|
182
|
+
engine_method = self.engine_method
|
|
183
|
+
self.thorvg_lib.tvg_engine_term.argtypes = [ctypes.c_int]
|
|
184
|
+
self.thorvg_lib.tvg_engine_term.restype = Result
|
|
185
|
+
return self.thorvg_lib.tvg_engine_term(engine_method)
|
|
186
|
+
|
|
187
|
+
def version(self) -> Tuple[Result, int, int, int, Optional[str]]:
|
|
188
|
+
"""
|
|
189
|
+
Retrieves the version of the TVG engine.
|
|
190
|
+
|
|
191
|
+
:return: SUCCESS
|
|
192
|
+
:rtype: Result
|
|
193
|
+
:return: A major version number.
|
|
194
|
+
:rtype: int
|
|
195
|
+
:return: A minor version number.
|
|
196
|
+
:rtype: int
|
|
197
|
+
:return: A micro version number.
|
|
198
|
+
:rtype: int
|
|
199
|
+
:return: The version of the engine in the format major.minor.micro, or a ``nullptr`` in case of an internal error.
|
|
200
|
+
:rtype: Optional[str]
|
|
201
|
+
|
|
202
|
+
.. versionadded:: 0.15
|
|
203
|
+
"""
|
|
204
|
+
self.thorvg_lib.tvg_engine_version.argtypes = [
|
|
205
|
+
ctypes.POINTER(ctypes.c_uint32),
|
|
206
|
+
ctypes.POINTER(ctypes.c_uint32),
|
|
207
|
+
ctypes.POINTER(ctypes.c_uint32),
|
|
208
|
+
ctypes.POINTER(ctypes.c_char_p),
|
|
209
|
+
]
|
|
210
|
+
self.thorvg_lib.tvg_engine_version.restype = Result
|
|
211
|
+
major = ctypes.c_uint32()
|
|
212
|
+
minor = ctypes.c_uint32()
|
|
213
|
+
micro = ctypes.c_uint32()
|
|
214
|
+
version = ctypes.c_char_p()
|
|
215
|
+
result = self.thorvg_lib.tvg_engine_version(
|
|
216
|
+
ctypes.pointer(major),
|
|
217
|
+
ctypes.pointer(minor),
|
|
218
|
+
ctypes.pointer(micro),
|
|
219
|
+
ctypes.pointer(version),
|
|
220
|
+
)
|
|
221
|
+
if version.value is not None:
|
|
222
|
+
v = version.value.decode("utf-8")
|
|
223
|
+
else:
|
|
224
|
+
v = None
|
|
225
|
+
return result, major.value, minor.value, micro.value, v
|
|
226
|
+
|
|
227
|
+
def font_load(
|
|
228
|
+
self,
|
|
229
|
+
path: str,
|
|
230
|
+
) -> Result:
|
|
231
|
+
"""Loads a scalable font data from a file.
|
|
232
|
+
|
|
233
|
+
ThorVG efficiently caches the loaded data using the specified ``path`` as a key.
|
|
234
|
+
This means that loading the same file again will not result in duplicate operations;
|
|
235
|
+
instead, ThorVG will reuse the previously loaded font data.
|
|
236
|
+
|
|
237
|
+
:param str path: The path to the font file.
|
|
238
|
+
|
|
239
|
+
:return:
|
|
240
|
+
- INVALID_ARGUMENT An invalid ``path`` passed as an argument.
|
|
241
|
+
- NOT_SUPPORTED When trying to load a file with an unknown extension.
|
|
242
|
+
:rtype: Result
|
|
243
|
+
|
|
244
|
+
.. seealso:: Engine.font_unload()
|
|
245
|
+
|
|
246
|
+
.. versionadded:: 0.15
|
|
247
|
+
"""
|
|
248
|
+
path_bytes = path.encode() + b"\x00"
|
|
249
|
+
path_arr_type = ctypes.c_char * len(path_bytes)
|
|
250
|
+
path_arr = path_arr_type.from_buffer_copy(path_bytes)
|
|
251
|
+
self.thorvg_lib.tvg_font_load.argtypes = [
|
|
252
|
+
ctypes.POINTER(path_arr_type),
|
|
253
|
+
]
|
|
254
|
+
self.thorvg_lib.tvg_font_load.restype = Result
|
|
255
|
+
return self.thorvg_lib.tvg_font_load(ctypes.pointer(path_arr))
|
|
256
|
+
|
|
257
|
+
def font_load_data(
|
|
258
|
+
self,
|
|
259
|
+
name: str,
|
|
260
|
+
data: bytes,
|
|
261
|
+
mimetype: Optional[str],
|
|
262
|
+
copy: bool,
|
|
263
|
+
) -> Result:
|
|
264
|
+
"""Loads a scalable font data from a memory block of a given size.
|
|
265
|
+
|
|
266
|
+
ThorVG efficiently caches the loaded font data using the specified ``name`` as a key.
|
|
267
|
+
This means that loading the same fonts again will not result in duplicate operations.
|
|
268
|
+
Instead, ThorVG will reuse the previously loaded font data.
|
|
269
|
+
|
|
270
|
+
:param str name: The name under which the font will be stored and accessible (e.x. in a ``tvg_text_set_font`` API).
|
|
271
|
+
:param bytes data: A pointer to a memory location where the content of the font data is stored.
|
|
272
|
+
:param str mimetype: Mimetype or extension of font data. In case a ``None`` or an empty "" value is provided the loader will be determined automatically.
|
|
273
|
+
:param bool copy: If ``true`` the data are copied into the engine local buffer, otherwise they are not (default).
|
|
274
|
+
|
|
275
|
+
:return:
|
|
276
|
+
- INVALID_ARGUMENT If no name is provided or if ``size`` is zero while ``data`` points to a valid memory location.
|
|
277
|
+
- NOT_SUPPORTED When trying to load a file with an unknown extension.
|
|
278
|
+
- INSUFFICIENT_CONDITION When trying to unload the font data that has not been previously loaded.
|
|
279
|
+
:rtype: Result
|
|
280
|
+
|
|
281
|
+
.. warning::
|
|
282
|
+
: It's the user responsibility to release the ``data`` memory.
|
|
283
|
+
|
|
284
|
+
.. note::
|
|
285
|
+
To unload the font data loaded using this API, pass the proper ``name`` and ``nullptr`` as ``data``.
|
|
286
|
+
|
|
287
|
+
.. versionadded:: 0.15
|
|
288
|
+
"""
|
|
289
|
+
name_bytes = name.encode() + b"\x00"
|
|
290
|
+
name_bytes += b"\x00"
|
|
291
|
+
name_char_type = ctypes.c_char * len(name_bytes)
|
|
292
|
+
name_char = name_char_type.from_buffer_copy(name_bytes)
|
|
293
|
+
data_arr_type = ctypes.c_ubyte * len(data)
|
|
294
|
+
data_arr = data_arr_type.from_buffer_copy(data)
|
|
295
|
+
if mimetype is not None and mimetype != "":
|
|
296
|
+
mimetype_bytes = name.encode() + b"\x00"
|
|
297
|
+
mimetype_char_type = ctypes.c_char * len(mimetype_bytes)
|
|
298
|
+
mimetype_char_ptr_type = ctypes.POINTER(mimetype_char_type)
|
|
299
|
+
mimetype_char = mimetype_char_type.from_buffer_copy(mimetype_bytes)
|
|
300
|
+
mimetype_char_ptr = ctypes.pointer(mimetype_char)
|
|
301
|
+
else:
|
|
302
|
+
mimetype_char_ptr_type = ctypes.c_void_p # type: ignore
|
|
303
|
+
mimetype_char_ptr = ctypes.c_void_p() # type: ignore
|
|
304
|
+
self.thorvg_lib.tvg_picture_load_raw.argtypes = [
|
|
305
|
+
ctypes.POINTER(name_char_type),
|
|
306
|
+
ctypes.POINTER(data_arr_type),
|
|
307
|
+
ctypes.c_uint32,
|
|
308
|
+
mimetype_char_ptr_type,
|
|
309
|
+
ctypes.c_bool,
|
|
310
|
+
]
|
|
311
|
+
return self.thorvg_lib.tvg_picture_load_raw(
|
|
312
|
+
ctypes.pointer(name_char),
|
|
313
|
+
ctypes.pointer(data_arr),
|
|
314
|
+
ctypes.c_uint32(ctypes.sizeof(data_arr)),
|
|
315
|
+
mimetype_char_ptr,
|
|
316
|
+
ctypes.c_bool(copy),
|
|
317
|
+
)
|
|
318
|
+
|
|
319
|
+
def font_unload(
|
|
320
|
+
self,
|
|
321
|
+
path: str,
|
|
322
|
+
) -> Result:
|
|
323
|
+
"""Unloads the specified scalable font data that was previously loaded.
|
|
324
|
+
|
|
325
|
+
This function is used to release resources associated with a font file that has been loaded into memory.
|
|
326
|
+
|
|
327
|
+
:param str path: The path to the loaded font file.
|
|
328
|
+
|
|
329
|
+
:return: INSUFFICIENT_CONDITION The loader is not initialized.
|
|
330
|
+
:rtype: Result
|
|
331
|
+
|
|
332
|
+
.. note::
|
|
333
|
+
If the font data is currently in use, it will not be immediately unloaded.
|
|
334
|
+
.. seealso:: Engine.font_load()
|
|
335
|
+
|
|
336
|
+
.. versionadded:: 0.15
|
|
337
|
+
"""
|
|
338
|
+
path_bytes = path.encode() + b"\x00"
|
|
339
|
+
path_arr_type = ctypes.c_char * len(path_bytes)
|
|
340
|
+
path_arr = path_arr_type.from_buffer_copy(path_bytes)
|
|
341
|
+
self.thorvg_lib.tvg_font_unload.argtypes = [
|
|
342
|
+
ctypes.POINTER(path_arr_type),
|
|
343
|
+
]
|
|
344
|
+
self.thorvg_lib.tvg_font_unload.restype = Result
|
|
345
|
+
return self.thorvg_lib.tvg_font_unload(ctypes.pointer(path_arr))
|
|
346
|
+
|
|
347
|
+
def accessor_generate_id(
|
|
348
|
+
self,
|
|
349
|
+
name: str,
|
|
350
|
+
) -> int:
|
|
351
|
+
"""Generate a unique ID (hash key) from a given name.
|
|
352
|
+
|
|
353
|
+
This function computes a unique identifier value based on the provided string.
|
|
354
|
+
You can use this to assign a unique ID to the Paint object.
|
|
355
|
+
|
|
356
|
+
:param str name: The input string to generate the unique identifier from.
|
|
357
|
+
|
|
358
|
+
:return: The generated unique identifier value.
|
|
359
|
+
:rtype: int
|
|
360
|
+
|
|
361
|
+
.. note::
|
|
362
|
+
Experimental API
|
|
363
|
+
"""
|
|
364
|
+
name_bytes = name.encode() + b"\x00"
|
|
365
|
+
name_char_type = ctypes.c_char * len(name_bytes)
|
|
366
|
+
name_char = name_char_type.from_buffer_copy(name_bytes)
|
|
367
|
+
self.thorvg_lib.tvg_accessor_generate_id.argtypes = [
|
|
368
|
+
ctypes.POINTER(name_char_type)
|
|
369
|
+
]
|
|
370
|
+
self.thorvg_lib.tvg_accessor_generate_id.restype = ctypes.c_uint32
|
|
371
|
+
return self.thorvg_lib.tvg_accessor_generate_id(ctypes.pointer(name_char)).value
|