svg-ultralight 0.48.0__py3-none-any.whl → 0.50.2__py3-none-any.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.
Potentially problematic release.
This version of svg-ultralight might be problematic. Click here for more details.
- svg_ultralight/__init__.py +108 -105
- svg_ultralight/animate.py +40 -40
- svg_ultralight/attrib_hints.py +14 -14
- svg_ultralight/bounding_boxes/__init__.py +5 -5
- svg_ultralight/bounding_boxes/bound_helpers.py +189 -189
- svg_ultralight/bounding_boxes/padded_text_initializers.py +207 -207
- svg_ultralight/bounding_boxes/supports_bounds.py +166 -166
- svg_ultralight/bounding_boxes/type_bound_collection.py +71 -71
- svg_ultralight/bounding_boxes/type_bound_element.py +65 -65
- svg_ultralight/bounding_boxes/type_bounding_box.py +396 -396
- svg_ultralight/bounding_boxes/type_padded_text.py +411 -411
- svg_ultralight/constructors/__init__.py +14 -14
- svg_ultralight/constructors/new_element.py +120 -115
- svg_ultralight/font_tools/__init__.py +5 -5
- svg_ultralight/font_tools/comp_results.py +295 -293
- svg_ultralight/font_tools/font_info.py +793 -792
- svg_ultralight/image_ops.py +156 -156
- svg_ultralight/inkscape.py +261 -261
- svg_ultralight/layout.py +291 -291
- svg_ultralight/main.py +183 -198
- svg_ultralight/metadata.py +122 -122
- svg_ultralight/nsmap.py +36 -36
- svg_ultralight/py.typed +5 -0
- svg_ultralight/query.py +254 -249
- svg_ultralight/read_svg.py +58 -0
- svg_ultralight/root_elements.py +87 -87
- svg_ultralight/string_conversion.py +244 -244
- svg_ultralight/strings/__init__.py +21 -13
- svg_ultralight/strings/svg_strings.py +106 -67
- svg_ultralight/transformations.py +140 -141
- svg_ultralight/unit_conversion.py +247 -248
- {svg_ultralight-0.48.0.dist-info → svg_ultralight-0.50.2.dist-info}/METADATA +208 -214
- svg_ultralight-0.50.2.dist-info/RECORD +34 -0
- svg_ultralight-0.50.2.dist-info/WHEEL +4 -0
- svg_ultralight-0.48.0.dist-info/RECORD +0 -34
- svg_ultralight-0.48.0.dist-info/WHEEL +0 -5
- svg_ultralight-0.48.0.dist-info/top_level.txt +0 -1
|
@@ -1,166 +1,166 @@
|
|
|
1
|
-
"""A protocol for objects that support bounds.
|
|
2
|
-
|
|
3
|
-
This module defines a protocol for objects that can have bounds. Existing and
|
|
4
|
-
future types like BoundingBox, BoundElement, and PaddedText can be arranged,
|
|
5
|
-
aligned, and uniformly scaled by reading and setting their bounds. This is the
|
|
6
|
-
interface needed to support such alignment.
|
|
7
|
-
|
|
8
|
-
Attributes:
|
|
9
|
-
x (float): The minimum x coordinate. x2 (float): The maximum x coordinate.
|
|
10
|
-
cx (float): The center x coordinate. y (float): The minimum y coordinate. y2
|
|
11
|
-
(float): The maximum y coordinate. cy (float): The center y coordinate.
|
|
12
|
-
width (float): The width of the object. height (float): The height of the
|
|
13
|
-
object. scale (float): The scale of the object.
|
|
14
|
-
|
|
15
|
-
:author: Shay Hill
|
|
16
|
-
:created: 2023-02-15
|
|
17
|
-
"""
|
|
18
|
-
|
|
19
|
-
from __future__ import annotations
|
|
20
|
-
|
|
21
|
-
from typing import Protocol
|
|
22
|
-
|
|
23
|
-
_Matrix = tuple[float, float, float, float, float, float]
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
class SupportsBounds(Protocol):
|
|
27
|
-
"""Protocol for objects that can have bounds.
|
|
28
|
-
|
|
29
|
-
Attributes:
|
|
30
|
-
transformation (_Matrix): An svg-style transformation matrix.
|
|
31
|
-
transform (method): Apply a transformation to the object.
|
|
32
|
-
x (float): The minimum x coordinate.
|
|
33
|
-
x2 (float): The maximum x coordinate.
|
|
34
|
-
cx (float): The center x coordinate.
|
|
35
|
-
y (float): The minimum y coordinate.
|
|
36
|
-
y2 (float): The maximum y coordinate.
|
|
37
|
-
cy (float): The center y coordinate.
|
|
38
|
-
width (float): The width of the object.
|
|
39
|
-
height(float): The height of the object.
|
|
40
|
-
scale ((float, float)): The x and yx and y scale of the object.
|
|
41
|
-
|
|
42
|
-
There is no setter for scale. Scale is a function of width and height.
|
|
43
|
-
Setting scale would be ambiguous. because the typical implementation of
|
|
44
|
-
scale would modify the x and y coordinates. If you want to scale an object,
|
|
45
|
-
set width and height.
|
|
46
|
-
"""
|
|
47
|
-
|
|
48
|
-
def transform(
|
|
49
|
-
self,
|
|
50
|
-
transformation: _Matrix | None = None,
|
|
51
|
-
*,
|
|
52
|
-
scale: tuple[float, float] | float | None = None,
|
|
53
|
-
dx: float | None = None,
|
|
54
|
-
dy: float | None = None,
|
|
55
|
-
):
|
|
56
|
-
"""Apply a transformation to the object."""
|
|
57
|
-
...
|
|
58
|
-
|
|
59
|
-
@property
|
|
60
|
-
def x(self) -> float:
|
|
61
|
-
"""Return minimum x coordinate."""
|
|
62
|
-
...
|
|
63
|
-
|
|
64
|
-
@x.setter
|
|
65
|
-
def x(self, value: float):
|
|
66
|
-
"""Set minimum x coordinate.
|
|
67
|
-
|
|
68
|
-
:param value: The minimum x coordinate.
|
|
69
|
-
"""
|
|
70
|
-
|
|
71
|
-
@property
|
|
72
|
-
def x2(self) -> float:
|
|
73
|
-
"""Return maximum x coordinate."""
|
|
74
|
-
...
|
|
75
|
-
|
|
76
|
-
@x2.setter
|
|
77
|
-
def x2(self, value: float):
|
|
78
|
-
"""Set maximum x coordinate.
|
|
79
|
-
|
|
80
|
-
:param value: The maximum x coordinate.
|
|
81
|
-
"""
|
|
82
|
-
|
|
83
|
-
@property
|
|
84
|
-
def cx(self) -> float:
|
|
85
|
-
"""Return center x coordinate."""
|
|
86
|
-
...
|
|
87
|
-
|
|
88
|
-
@cx.setter
|
|
89
|
-
def cx(self, value: float):
|
|
90
|
-
"""Set center x coordinate.
|
|
91
|
-
|
|
92
|
-
:param value: The center x coordinate.
|
|
93
|
-
"""
|
|
94
|
-
|
|
95
|
-
@property
|
|
96
|
-
def y(self) -> float:
|
|
97
|
-
"""Return minimum y coordinate."""
|
|
98
|
-
...
|
|
99
|
-
|
|
100
|
-
@y.setter
|
|
101
|
-
def y(self, value: float):
|
|
102
|
-
"""Set minimum y coordinate.
|
|
103
|
-
|
|
104
|
-
:param value: The minimum y coordinate.
|
|
105
|
-
"""
|
|
106
|
-
|
|
107
|
-
@property
|
|
108
|
-
def y2(self) -> float:
|
|
109
|
-
"""Return maximum y coordinate."""
|
|
110
|
-
...
|
|
111
|
-
|
|
112
|
-
@y2.setter
|
|
113
|
-
def y2(self, value: float):
|
|
114
|
-
"""Set maximum y coordinate.
|
|
115
|
-
|
|
116
|
-
:param value: The maximum y coordinate.
|
|
117
|
-
"""
|
|
118
|
-
|
|
119
|
-
@property
|
|
120
|
-
def cy(self) -> float:
|
|
121
|
-
"""Return center y coordinate."""
|
|
122
|
-
...
|
|
123
|
-
|
|
124
|
-
@cy.setter
|
|
125
|
-
def cy(self, value: float):
|
|
126
|
-
"""Set center y coordinate.
|
|
127
|
-
|
|
128
|
-
:param value: The center y coordinate.
|
|
129
|
-
"""
|
|
130
|
-
|
|
131
|
-
@property
|
|
132
|
-
def width(self) -> float:
|
|
133
|
-
"""Return width of the object."""
|
|
134
|
-
...
|
|
135
|
-
|
|
136
|
-
@width.setter
|
|
137
|
-
def width(self, value: float):
|
|
138
|
-
"""Set width of the object.
|
|
139
|
-
|
|
140
|
-
:param value: The width of the object.
|
|
141
|
-
"""
|
|
142
|
-
|
|
143
|
-
@property
|
|
144
|
-
def height(self) -> float:
|
|
145
|
-
"""Return height of the object."""
|
|
146
|
-
...
|
|
147
|
-
|
|
148
|
-
@height.setter
|
|
149
|
-
def height(self, value: float):
|
|
150
|
-
"""Set height of the object.
|
|
151
|
-
|
|
152
|
-
:param value: The height of the object.
|
|
153
|
-
"""
|
|
154
|
-
|
|
155
|
-
@property
|
|
156
|
-
def scale(self) -> tuple[float, float]:
|
|
157
|
-
"""Return scale of the object."""
|
|
158
|
-
...
|
|
159
|
-
|
|
160
|
-
@scale.setter
|
|
161
|
-
def scale(self, value: tuple[float, float]):
|
|
162
|
-
"""Return scale of the object.
|
|
163
|
-
|
|
164
|
-
:param value: The scale of the object.
|
|
165
|
-
"""
|
|
166
|
-
...
|
|
1
|
+
"""A protocol for objects that support bounds.
|
|
2
|
+
|
|
3
|
+
This module defines a protocol for objects that can have bounds. Existing and
|
|
4
|
+
future types like BoundingBox, BoundElement, and PaddedText can be arranged,
|
|
5
|
+
aligned, and uniformly scaled by reading and setting their bounds. This is the
|
|
6
|
+
interface needed to support such alignment.
|
|
7
|
+
|
|
8
|
+
Attributes:
|
|
9
|
+
x (float): The minimum x coordinate. x2 (float): The maximum x coordinate.
|
|
10
|
+
cx (float): The center x coordinate. y (float): The minimum y coordinate. y2
|
|
11
|
+
(float): The maximum y coordinate. cy (float): The center y coordinate.
|
|
12
|
+
width (float): The width of the object. height (float): The height of the
|
|
13
|
+
object. scale (float): The scale of the object.
|
|
14
|
+
|
|
15
|
+
:author: Shay Hill
|
|
16
|
+
:created: 2023-02-15
|
|
17
|
+
"""
|
|
18
|
+
|
|
19
|
+
from __future__ import annotations
|
|
20
|
+
|
|
21
|
+
from typing import Protocol
|
|
22
|
+
|
|
23
|
+
_Matrix = tuple[float, float, float, float, float, float]
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
class SupportsBounds(Protocol):
|
|
27
|
+
"""Protocol for objects that can have bounds.
|
|
28
|
+
|
|
29
|
+
Attributes:
|
|
30
|
+
transformation (_Matrix): An svg-style transformation matrix.
|
|
31
|
+
transform (method): Apply a transformation to the object.
|
|
32
|
+
x (float): The minimum x coordinate.
|
|
33
|
+
x2 (float): The maximum x coordinate.
|
|
34
|
+
cx (float): The center x coordinate.
|
|
35
|
+
y (float): The minimum y coordinate.
|
|
36
|
+
y2 (float): The maximum y coordinate.
|
|
37
|
+
cy (float): The center y coordinate.
|
|
38
|
+
width (float): The width of the object.
|
|
39
|
+
height(float): The height of the object.
|
|
40
|
+
scale ((float, float)): The x and yx and y scale of the object.
|
|
41
|
+
|
|
42
|
+
There is no setter for scale. Scale is a function of width and height.
|
|
43
|
+
Setting scale would be ambiguous. because the typical implementation of
|
|
44
|
+
scale would modify the x and y coordinates. If you want to scale an object,
|
|
45
|
+
set width and height.
|
|
46
|
+
"""
|
|
47
|
+
|
|
48
|
+
def transform(
|
|
49
|
+
self,
|
|
50
|
+
transformation: _Matrix | None = None,
|
|
51
|
+
*,
|
|
52
|
+
scale: tuple[float, float] | float | None = None,
|
|
53
|
+
dx: float | None = None,
|
|
54
|
+
dy: float | None = None,
|
|
55
|
+
) -> None:
|
|
56
|
+
"""Apply a transformation to the object."""
|
|
57
|
+
...
|
|
58
|
+
|
|
59
|
+
@property
|
|
60
|
+
def x(self) -> float:
|
|
61
|
+
"""Return minimum x coordinate."""
|
|
62
|
+
...
|
|
63
|
+
|
|
64
|
+
@x.setter
|
|
65
|
+
def x(self, value: float) -> None:
|
|
66
|
+
"""Set minimum x coordinate.
|
|
67
|
+
|
|
68
|
+
:param value: The minimum x coordinate.
|
|
69
|
+
"""
|
|
70
|
+
|
|
71
|
+
@property
|
|
72
|
+
def x2(self) -> float:
|
|
73
|
+
"""Return maximum x coordinate."""
|
|
74
|
+
...
|
|
75
|
+
|
|
76
|
+
@x2.setter
|
|
77
|
+
def x2(self, value: float) -> None:
|
|
78
|
+
"""Set maximum x coordinate.
|
|
79
|
+
|
|
80
|
+
:param value: The maximum x coordinate.
|
|
81
|
+
"""
|
|
82
|
+
|
|
83
|
+
@property
|
|
84
|
+
def cx(self) -> float:
|
|
85
|
+
"""Return center x coordinate."""
|
|
86
|
+
...
|
|
87
|
+
|
|
88
|
+
@cx.setter
|
|
89
|
+
def cx(self, value: float) -> None:
|
|
90
|
+
"""Set center x coordinate.
|
|
91
|
+
|
|
92
|
+
:param value: The center x coordinate.
|
|
93
|
+
"""
|
|
94
|
+
|
|
95
|
+
@property
|
|
96
|
+
def y(self) -> float:
|
|
97
|
+
"""Return minimum y coordinate."""
|
|
98
|
+
...
|
|
99
|
+
|
|
100
|
+
@y.setter
|
|
101
|
+
def y(self, value: float) -> None:
|
|
102
|
+
"""Set minimum y coordinate.
|
|
103
|
+
|
|
104
|
+
:param value: The minimum y coordinate.
|
|
105
|
+
"""
|
|
106
|
+
|
|
107
|
+
@property
|
|
108
|
+
def y2(self) -> float:
|
|
109
|
+
"""Return maximum y coordinate."""
|
|
110
|
+
...
|
|
111
|
+
|
|
112
|
+
@y2.setter
|
|
113
|
+
def y2(self, value: float) -> None:
|
|
114
|
+
"""Set maximum y coordinate.
|
|
115
|
+
|
|
116
|
+
:param value: The maximum y coordinate.
|
|
117
|
+
"""
|
|
118
|
+
|
|
119
|
+
@property
|
|
120
|
+
def cy(self) -> float:
|
|
121
|
+
"""Return center y coordinate."""
|
|
122
|
+
...
|
|
123
|
+
|
|
124
|
+
@cy.setter
|
|
125
|
+
def cy(self, value: float) -> None:
|
|
126
|
+
"""Set center y coordinate.
|
|
127
|
+
|
|
128
|
+
:param value: The center y coordinate.
|
|
129
|
+
"""
|
|
130
|
+
|
|
131
|
+
@property
|
|
132
|
+
def width(self) -> float:
|
|
133
|
+
"""Return width of the object."""
|
|
134
|
+
...
|
|
135
|
+
|
|
136
|
+
@width.setter
|
|
137
|
+
def width(self, value: float) -> None:
|
|
138
|
+
"""Set width of the object.
|
|
139
|
+
|
|
140
|
+
:param value: The width of the object.
|
|
141
|
+
"""
|
|
142
|
+
|
|
143
|
+
@property
|
|
144
|
+
def height(self) -> float:
|
|
145
|
+
"""Return height of the object."""
|
|
146
|
+
...
|
|
147
|
+
|
|
148
|
+
@height.setter
|
|
149
|
+
def height(self, value: float) -> None:
|
|
150
|
+
"""Set height of the object.
|
|
151
|
+
|
|
152
|
+
:param value: The height of the object.
|
|
153
|
+
"""
|
|
154
|
+
|
|
155
|
+
@property
|
|
156
|
+
def scale(self) -> tuple[float, float]:
|
|
157
|
+
"""Return scale of the object."""
|
|
158
|
+
...
|
|
159
|
+
|
|
160
|
+
@scale.setter
|
|
161
|
+
def scale(self, value: tuple[float, float]) -> None:
|
|
162
|
+
"""Return scale of the object.
|
|
163
|
+
|
|
164
|
+
:param value: The scale of the object.
|
|
165
|
+
"""
|
|
166
|
+
...
|
|
@@ -1,71 +1,71 @@
|
|
|
1
|
-
"""A class to hold a list of bound elements and transform them together.
|
|
2
|
-
|
|
3
|
-
:author: Shay Hill
|
|
4
|
-
:created: 2024-05-05
|
|
5
|
-
"""
|
|
6
|
-
|
|
7
|
-
from __future__ import annotations
|
|
8
|
-
|
|
9
|
-
import dataclasses
|
|
10
|
-
from typing import TYPE_CHECKING
|
|
11
|
-
|
|
12
|
-
from lxml.etree import _Element as EtreeElement # pyright: ignore[reportPrivateUsage]
|
|
13
|
-
|
|
14
|
-
from svg_ultralight.bounding_boxes.bound_helpers import new_bbox_union
|
|
15
|
-
from svg_ultralight.bounding_boxes.type_bounding_box import HasBoundingBox
|
|
16
|
-
from svg_ultralight.transformations import new_transformation_matrix, transform_element
|
|
17
|
-
|
|
18
|
-
if TYPE_CHECKING:
|
|
19
|
-
from svg_ultralight.bounding_boxes.supports_bounds import SupportsBounds
|
|
20
|
-
from svg_ultralight.bounding_boxes.type_bounding_box import BoundingBox
|
|
21
|
-
|
|
22
|
-
_Matrix = tuple[float, float, float, float, float, float]
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
@dataclasses.dataclass
|
|
26
|
-
class BoundCollection(HasBoundingBox):
|
|
27
|
-
"""A class to hold a list of bound elements and transform them together.
|
|
28
|
-
|
|
29
|
-
This will transform the individual elements in place.
|
|
30
|
-
"""
|
|
31
|
-
|
|
32
|
-
blems: list[SupportsBounds | EtreeElement] = dataclasses.field(init=False)
|
|
33
|
-
bbox: BoundingBox = dataclasses.field(init=False)
|
|
34
|
-
|
|
35
|
-
def __init__(self, *blems: SupportsBounds | EtreeElement) -> None:
|
|
36
|
-
"""Initialize the bound collection.
|
|
37
|
-
|
|
38
|
-
:param blems: bound elements to be transformed together
|
|
39
|
-
"""
|
|
40
|
-
self.blems = list(blems)
|
|
41
|
-
self.bbox = new_bbox_union(*self.blems)
|
|
42
|
-
|
|
43
|
-
def transform(
|
|
44
|
-
self,
|
|
45
|
-
transformation: _Matrix | None = None,
|
|
46
|
-
*,
|
|
47
|
-
scale: tuple[float, float] | float | None = None,
|
|
48
|
-
dx: float | None = None,
|
|
49
|
-
dy: float | None = None,
|
|
50
|
-
):
|
|
51
|
-
"""Transform each bound element in self.blems.
|
|
52
|
-
|
|
53
|
-
:param transformation: 2D transformation matrix
|
|
54
|
-
:param scale: optional scale factor
|
|
55
|
-
:param dx: optional x translation
|
|
56
|
-
:param dy: optional y translation
|
|
57
|
-
|
|
58
|
-
Keep track of all compounding transformations in order to have a value for
|
|
59
|
-
self.scale (required for membersh and to provide access to cumulative
|
|
60
|
-
transforms should this be useful for any reason. This means all
|
|
61
|
-
transformations must be applied to two bounding boxes: a persistant bbox to
|
|
62
|
-
keep track of the scale property and a temporary bbox to isolate each
|
|
63
|
-
transformation.
|
|
64
|
-
"""
|
|
65
|
-
tmat = new_transformation_matrix(transformation, scale=scale, dx=dx, dy=dy)
|
|
66
|
-
self.bbox.transform(tmat)
|
|
67
|
-
for blem in self.blems:
|
|
68
|
-
if isinstance(blem, EtreeElement):
|
|
69
|
-
_ = transform_element(blem, tmat)
|
|
70
|
-
else:
|
|
71
|
-
blem.transform(tmat)
|
|
1
|
+
"""A class to hold a list of bound elements and transform them together.
|
|
2
|
+
|
|
3
|
+
:author: Shay Hill
|
|
4
|
+
:created: 2024-05-05
|
|
5
|
+
"""
|
|
6
|
+
|
|
7
|
+
from __future__ import annotations
|
|
8
|
+
|
|
9
|
+
import dataclasses
|
|
10
|
+
from typing import TYPE_CHECKING
|
|
11
|
+
|
|
12
|
+
from lxml.etree import _Element as EtreeElement # pyright: ignore[reportPrivateUsage]
|
|
13
|
+
|
|
14
|
+
from svg_ultralight.bounding_boxes.bound_helpers import new_bbox_union
|
|
15
|
+
from svg_ultralight.bounding_boxes.type_bounding_box import HasBoundingBox
|
|
16
|
+
from svg_ultralight.transformations import new_transformation_matrix, transform_element
|
|
17
|
+
|
|
18
|
+
if TYPE_CHECKING:
|
|
19
|
+
from svg_ultralight.bounding_boxes.supports_bounds import SupportsBounds
|
|
20
|
+
from svg_ultralight.bounding_boxes.type_bounding_box import BoundingBox
|
|
21
|
+
|
|
22
|
+
_Matrix = tuple[float, float, float, float, float, float]
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
@dataclasses.dataclass
|
|
26
|
+
class BoundCollection(HasBoundingBox):
|
|
27
|
+
"""A class to hold a list of bound elements and transform them together.
|
|
28
|
+
|
|
29
|
+
This will transform the individual elements in place.
|
|
30
|
+
"""
|
|
31
|
+
|
|
32
|
+
blems: list[SupportsBounds | EtreeElement] = dataclasses.field(init=False)
|
|
33
|
+
bbox: BoundingBox = dataclasses.field(init=False)
|
|
34
|
+
|
|
35
|
+
def __init__(self, *blems: SupportsBounds | EtreeElement) -> None:
|
|
36
|
+
"""Initialize the bound collection.
|
|
37
|
+
|
|
38
|
+
:param blems: bound elements to be transformed together
|
|
39
|
+
"""
|
|
40
|
+
self.blems = list(blems)
|
|
41
|
+
self.bbox = new_bbox_union(*self.blems)
|
|
42
|
+
|
|
43
|
+
def transform(
|
|
44
|
+
self,
|
|
45
|
+
transformation: _Matrix | None = None,
|
|
46
|
+
*,
|
|
47
|
+
scale: tuple[float, float] | float | None = None,
|
|
48
|
+
dx: float | None = None,
|
|
49
|
+
dy: float | None = None,
|
|
50
|
+
) -> None:
|
|
51
|
+
"""Transform each bound element in self.blems.
|
|
52
|
+
|
|
53
|
+
:param transformation: 2D transformation matrix
|
|
54
|
+
:param scale: optional scale factor
|
|
55
|
+
:param dx: optional x translation
|
|
56
|
+
:param dy: optional y translation
|
|
57
|
+
|
|
58
|
+
Keep track of all compounding transformations in order to have a value for
|
|
59
|
+
self.scale (required for membersh and to provide access to cumulative
|
|
60
|
+
transforms should this be useful for any reason. This means all
|
|
61
|
+
transformations must be applied to two bounding boxes: a persistant bbox to
|
|
62
|
+
keep track of the scale property and a temporary bbox to isolate each
|
|
63
|
+
transformation.
|
|
64
|
+
"""
|
|
65
|
+
tmat = new_transformation_matrix(transformation, scale=scale, dx=dx, dy=dy)
|
|
66
|
+
self.bbox.transform(tmat)
|
|
67
|
+
for blem in self.blems:
|
|
68
|
+
if isinstance(blem, EtreeElement):
|
|
69
|
+
_ = transform_element(blem, tmat)
|
|
70
|
+
else:
|
|
71
|
+
blem.transform(tmat)
|
|
@@ -1,65 +1,65 @@
|
|
|
1
|
-
"""An element tied to a BoundingBox instance.
|
|
2
|
-
|
|
3
|
-
Take an element, associate it to a BoundingBox instance, transform the BoundingBox
|
|
4
|
-
instance. The element will be transformed accordingly.
|
|
5
|
-
|
|
6
|
-
It is critical to remember that self.elem is a reference. It is not necessary to
|
|
7
|
-
access self.elem through the BoundElement instance. Earlier and later references will
|
|
8
|
-
all be updated as the BoundElement instance is updated.
|
|
9
|
-
|
|
10
|
-
:author: Shay Hill
|
|
11
|
-
:created: 2022-12-09
|
|
12
|
-
"""
|
|
13
|
-
|
|
14
|
-
from __future__ import annotations
|
|
15
|
-
|
|
16
|
-
from typing import TYPE_CHECKING
|
|
17
|
-
|
|
18
|
-
from svg_ultralight.bounding_boxes.type_bounding_box import HasBoundingBox
|
|
19
|
-
from svg_ultralight.transformations import new_transformation_matrix, transform_element
|
|
20
|
-
|
|
21
|
-
if TYPE_CHECKING:
|
|
22
|
-
from lxml.etree import (
|
|
23
|
-
_Element as EtreeElement, # pyright: ignore[reportPrivateUsage]
|
|
24
|
-
)
|
|
25
|
-
|
|
26
|
-
from svg_ultralight.bounding_boxes.type_bounding_box import BoundingBox
|
|
27
|
-
|
|
28
|
-
_Matrix = tuple[float, float, float, float, float, float]
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
class BoundElement(HasBoundingBox):
|
|
32
|
-
"""An element with a bounding box.
|
|
33
|
-
|
|
34
|
-
Updates the element when x, y, x2, y2, width, or height are set.
|
|
35
|
-
|
|
36
|
-
Can access these BoundingBox attributes (plus scale) as attributes of this object.
|
|
37
|
-
"""
|
|
38
|
-
|
|
39
|
-
def __init__(self, element: EtreeElement, bounding_box: BoundingBox) -> None:
|
|
40
|
-
"""Initialize a BoundElement instance.
|
|
41
|
-
|
|
42
|
-
:param element: the element to be bound
|
|
43
|
-
:param bounding_box: the bounding box around the element
|
|
44
|
-
"""
|
|
45
|
-
self.elem = element
|
|
46
|
-
self.bbox = bounding_box
|
|
47
|
-
|
|
48
|
-
def transform(
|
|
49
|
-
self,
|
|
50
|
-
transformation: _Matrix | None = None,
|
|
51
|
-
*,
|
|
52
|
-
scale: tuple[float, float] | float | None = None,
|
|
53
|
-
dx: float | None = None,
|
|
54
|
-
dy: float | None = None,
|
|
55
|
-
):
|
|
56
|
-
"""Transform the element and bounding box.
|
|
57
|
-
|
|
58
|
-
:param transformation: a 6-tuple transformation matrix
|
|
59
|
-
:param scale: a scaling factor
|
|
60
|
-
:param dx: the x translation
|
|
61
|
-
:param dy: the y translation
|
|
62
|
-
"""
|
|
63
|
-
tmat = new_transformation_matrix(transformation, scale=scale, dx=dx, dy=dy)
|
|
64
|
-
self.bbox.transform(tmat)
|
|
65
|
-
_ = transform_element(self.elem, tmat)
|
|
1
|
+
"""An element tied to a BoundingBox instance.
|
|
2
|
+
|
|
3
|
+
Take an element, associate it to a BoundingBox instance, transform the BoundingBox
|
|
4
|
+
instance. The element will be transformed accordingly.
|
|
5
|
+
|
|
6
|
+
It is critical to remember that self.elem is a reference. It is not necessary to
|
|
7
|
+
access self.elem through the BoundElement instance. Earlier and later references will
|
|
8
|
+
all be updated as the BoundElement instance is updated.
|
|
9
|
+
|
|
10
|
+
:author: Shay Hill
|
|
11
|
+
:created: 2022-12-09
|
|
12
|
+
"""
|
|
13
|
+
|
|
14
|
+
from __future__ import annotations
|
|
15
|
+
|
|
16
|
+
from typing import TYPE_CHECKING
|
|
17
|
+
|
|
18
|
+
from svg_ultralight.bounding_boxes.type_bounding_box import HasBoundingBox
|
|
19
|
+
from svg_ultralight.transformations import new_transformation_matrix, transform_element
|
|
20
|
+
|
|
21
|
+
if TYPE_CHECKING:
|
|
22
|
+
from lxml.etree import (
|
|
23
|
+
_Element as EtreeElement, # pyright: ignore[reportPrivateUsage]
|
|
24
|
+
)
|
|
25
|
+
|
|
26
|
+
from svg_ultralight.bounding_boxes.type_bounding_box import BoundingBox
|
|
27
|
+
|
|
28
|
+
_Matrix = tuple[float, float, float, float, float, float]
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
class BoundElement(HasBoundingBox):
|
|
32
|
+
"""An element with a bounding box.
|
|
33
|
+
|
|
34
|
+
Updates the element when x, y, x2, y2, width, or height are set.
|
|
35
|
+
|
|
36
|
+
Can access these BoundingBox attributes (plus scale) as attributes of this object.
|
|
37
|
+
"""
|
|
38
|
+
|
|
39
|
+
def __init__(self, element: EtreeElement, bounding_box: BoundingBox) -> None:
|
|
40
|
+
"""Initialize a BoundElement instance.
|
|
41
|
+
|
|
42
|
+
:param element: the element to be bound
|
|
43
|
+
:param bounding_box: the bounding box around the element
|
|
44
|
+
"""
|
|
45
|
+
self.elem = element
|
|
46
|
+
self.bbox = bounding_box
|
|
47
|
+
|
|
48
|
+
def transform(
|
|
49
|
+
self,
|
|
50
|
+
transformation: _Matrix | None = None,
|
|
51
|
+
*,
|
|
52
|
+
scale: tuple[float, float] | float | None = None,
|
|
53
|
+
dx: float | None = None,
|
|
54
|
+
dy: float | None = None,
|
|
55
|
+
) -> None:
|
|
56
|
+
"""Transform the element and bounding box.
|
|
57
|
+
|
|
58
|
+
:param transformation: a 6-tuple transformation matrix
|
|
59
|
+
:param scale: a scaling factor
|
|
60
|
+
:param dx: the x translation
|
|
61
|
+
:param dy: the y translation
|
|
62
|
+
"""
|
|
63
|
+
tmat = new_transformation_matrix(transformation, scale=scale, dx=dx, dy=dy)
|
|
64
|
+
self.bbox.transform(tmat)
|
|
65
|
+
_ = transform_element(self.elem, tmat)
|