pyblend2d 0.21.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.
Files changed (56) hide show
  1. blend2d/__init__.py +284 -0
  2. blend2d/_bin/blend2d_fx.lib +0 -0
  3. blend2d/_bin/blend2d_geo.lib +0 -0
  4. blend2d/_bin/blend2d_motion.lib +0 -0
  5. blend2d/_bin/blend2d_perspective.lib +0 -0
  6. blend2d/_bin/blend2d_video.lib +0 -0
  7. blend2d/_bin/libblend2d.dll +0 -0
  8. blend2d/_bin/libblend2d.so +0 -0
  9. blend2d/_bin/libblend2d_fx.dll +0 -0
  10. blend2d/_bin/libblend2d_fx.pdb +0 -0
  11. blend2d/_bin/libblend2d_geo.dll +0 -0
  12. blend2d/_bin/libblend2d_geo.pdb +0 -0
  13. blend2d/_bin/libblend2d_motion.dll +0 -0
  14. blend2d/_bin/libblend2d_motion.pdb +0 -0
  15. blend2d/_bin/libblend2d_perspective.dll +0 -0
  16. blend2d/_bin/libblend2d_perspective.pdb +0 -0
  17. blend2d/_bin/libblend2d_video.dll +0 -0
  18. blend2d/_bin/libblend2d_video.pdb +0 -0
  19. blend2d/color.py +202 -0
  20. blend2d/context.py +1439 -0
  21. blend2d/diagnostics.py +201 -0
  22. blend2d/enums.py +272 -0
  23. blend2d/ffi.py +1301 -0
  24. blend2d/font.py +251 -0
  25. blend2d/fx/__init__.py +55 -0
  26. blend2d/fx/_ffi.py +74 -0
  27. blend2d/fx/blur.py +39 -0
  28. blend2d/fx/color_grade.py +73 -0
  29. blend2d/fx/glitch.py +61 -0
  30. blend2d/fx/glow.py +104 -0
  31. blend2d/fx/lens.py +98 -0
  32. blend2d/fx/pipeline.py +105 -0
  33. blend2d/geometry.py +242 -0
  34. blend2d/image.py +349 -0
  35. blend2d/matrix.py +153 -0
  36. blend2d/motion/__init__.py +74 -0
  37. blend2d/motion/easing.py +410 -0
  38. blend2d/motion/particles.py +345 -0
  39. blend2d/motion/path_anim.py +303 -0
  40. blend2d/motion/perspective.py +426 -0
  41. blend2d/motion/scene.py +237 -0
  42. blend2d/motion/timeline.py +208 -0
  43. blend2d/path.py +582 -0
  44. blend2d/py.typed +1 -0
  45. blend2d/shapgeo.py +705 -0
  46. blend2d/shapgeo_downloader.py +159 -0
  47. blend2d/shapgeo_io.py +303 -0
  48. blend2d/shapgeo_proj.py +242 -0
  49. blend2d/style.py +210 -0
  50. blend2d/svg.py +383 -0
  51. blend2d/video.py +498 -0
  52. blend2d-src/blend2d-version.py +23 -0
  53. pyblend2d-0.21.2.dist-info/METADATA +318 -0
  54. pyblend2d-0.21.2.dist-info/RECORD +56 -0
  55. pyblend2d-0.21.2.dist-info/WHEEL +5 -0
  56. pyblend2d-0.21.2.dist-info/top_level.txt +2 -0
blend2d/__init__.py ADDED
@@ -0,0 +1,284 @@
1
+ """
2
+ PyBlend: High-Performance 2D Vector Graphics Engine for Python powered by Blend2D.
3
+ """
4
+
5
+ from blend2d.enums import (
6
+ Format,
7
+ CompOp,
8
+ FillRule,
9
+ GeometryType,
10
+ ExtendMode,
11
+ GradientType,
12
+ StrokeCap,
13
+ StrokeCapPosition,
14
+ StrokeJoin,
15
+ StrokeTransformOrder,
16
+ TransformOp,
17
+ ClipOp,
18
+ FlattenMode,
19
+ RenderingEngine,
20
+ ResultCode,
21
+ ContextHint,
22
+ RenderingQuality,
23
+ GradientQuality,
24
+ PatternQuality,
25
+ RuntimeInfoType,
26
+ RuntimeCpuArch,
27
+ RuntimeCpuFeatures,
28
+ )
29
+ from blend2d.ffi import Blend2DError
30
+ from blend2d.geometry import (
31
+ Point,
32
+ PointI,
33
+ Size,
34
+ SizeI,
35
+ Rect,
36
+ RectI,
37
+ Box,
38
+ BoxI,
39
+ Circle,
40
+ Ellipse,
41
+ RoundRect,
42
+ Triangle,
43
+ Arc,
44
+ Line,
45
+ )
46
+ from blend2d.matrix import Matrix2D
47
+ from blend2d.color import (
48
+ Rgba32,
49
+ Rgba,
50
+ parse_color,
51
+ NAMED_COLORS,
52
+ )
53
+ from blend2d.image import Image
54
+ from blend2d.path import Path
55
+ from blend2d.style import (
56
+ Gradient,
57
+ LinearGradient,
58
+ RadialGradient,
59
+ ConicGradient,
60
+ Pattern,
61
+ )
62
+ from blend2d.font import (
63
+ FontFace,
64
+ Font,
65
+ FontMetrics,
66
+ TextMetrics,
67
+ )
68
+ from blend2d.context import Context
69
+ from blend2d.diagnostics import (
70
+ diagnose_environment,
71
+ print_diagnostic_report,
72
+ get_error_details,
73
+ get_runtime_info,
74
+ )
75
+ from blend2d import svg
76
+ from blend2d.svg import SvgContext, export_svg
77
+ from blend2d import video
78
+ from blend2d.video import (
79
+ VideoWriter,
80
+ VideoReader,
81
+ record_animation,
82
+ detect_hardware_encoders,
83
+ VideoError,
84
+ CodecNotFoundError,
85
+ FrameFormatError,
86
+ )
87
+ from blend2d import shapgeo
88
+ from blend2d.shapgeo import (
89
+ GeoCanvas,
90
+ GeoTransform,
91
+ from_shapely,
92
+ from_geojson,
93
+ from_wkt,
94
+ render_gdf,
95
+ auto_bounds,
96
+ read_file,
97
+ read_shapefile,
98
+ read_geojson,
99
+ proj,
100
+ Transformer,
101
+ to_web_mercator,
102
+ to_wgs84,
103
+ reproject_gdf,
104
+ downloader,
105
+ download_dataset,
106
+ load_dataset,
107
+ register_dataset,
108
+ )
109
+ from blend2d import motion
110
+ from blend2d.motion import (
111
+ Timeline,
112
+ Easing,
113
+ Spring,
114
+ CubicBezier,
115
+ trim_path,
116
+ PathFollower,
117
+ PathMorph,
118
+ ParticleSystem,
119
+ Camera2D,
120
+ PerspectiveCamera,
121
+ render_globe,
122
+ Node,
123
+ Layer,
124
+ Scene,
125
+ )
126
+ from blend2d import fx
127
+ from blend2d.fx import (
128
+ FXPipeline,
129
+ gaussian_blur,
130
+ box_blur,
131
+ bloom,
132
+ neon_glow,
133
+ drop_shadow,
134
+ chromatic_aberration,
135
+ vignette,
136
+ film_grain,
137
+ color_grade,
138
+ grayscale,
139
+ invert,
140
+ sepia,
141
+ scanlines,
142
+ glitch_displacement,
143
+ )
144
+
145
+ # Alias geo -> shapgeo for developer convenience
146
+ geo = shapgeo
147
+
148
+ __version__ = "0.21.2"
149
+ __author__ = "Islam Arifi, PyBlend Team, Blend2D Authors"
150
+
151
+ __all__ = [
152
+ # Core
153
+ "Image",
154
+ "Context",
155
+ "Path",
156
+ "Blend2DError",
157
+ # Post-Processing FX Engine
158
+ "fx",
159
+ "FXPipeline",
160
+ "gaussian_blur",
161
+ "box_blur",
162
+ "bloom",
163
+ "neon_glow",
164
+ "drop_shadow",
165
+ "chromatic_aberration",
166
+ "vignette",
167
+ "film_grain",
168
+ "color_grade",
169
+ "grayscale",
170
+ "invert",
171
+ "sepia",
172
+ "scanlines",
173
+ "glitch_displacement",
174
+ # Motion Graphics & Animation Engine
175
+ "motion",
176
+ "Timeline",
177
+ "Easing",
178
+ "Spring",
179
+ "CubicBezier",
180
+ "trim_path",
181
+ "PathFollower",
182
+ "PathMorph",
183
+ "ParticleSystem",
184
+ "Camera2D",
185
+ "PerspectiveCamera",
186
+ "render_globe",
187
+ "Node",
188
+ "Layer",
189
+ "Scene",
190
+ # Geospatial (GeoPandas & Shapely C++ Engine)
191
+ "shapgeo",
192
+ "geo",
193
+ "GeoCanvas",
194
+ "GeoTransform",
195
+ "from_shapely",
196
+ "from_geojson",
197
+ "from_wkt",
198
+ "render_gdf",
199
+ "auto_bounds",
200
+ "read_file",
201
+ "read_shapefile",
202
+ "read_geojson",
203
+ "proj",
204
+ "Transformer",
205
+ "to_web_mercator",
206
+ "to_wgs84",
207
+ "reproject_gdf",
208
+ "downloader",
209
+ "download_dataset",
210
+ "load_dataset",
211
+ # Video & Native FFmpeg Engine
212
+ "video",
213
+ "VideoWriter",
214
+ "VideoReader",
215
+ "record_animation",
216
+ "detect_hardware_encoders",
217
+ "VideoError",
218
+ "CodecNotFoundError",
219
+ "FrameFormatError",
220
+ # SVG Vector Export
221
+ "svg",
222
+ "SvgContext",
223
+ "export_svg",
224
+ # Diagnostics & Troubleshooting
225
+ "diagnose_environment",
226
+ "print_diagnostic_report",
227
+ "get_error_details",
228
+ "get_runtime_info",
229
+ # Styles
230
+ "Gradient",
231
+ "LinearGradient",
232
+ "RadialGradient",
233
+ "ConicGradient",
234
+ "Pattern",
235
+ # Colors
236
+ "Rgba32",
237
+ "Rgba",
238
+ "parse_color",
239
+ "NAMED_COLORS",
240
+ # Typography
241
+ "FontFace",
242
+ "Font",
243
+ "FontMetrics",
244
+ "TextMetrics",
245
+ # Geometry
246
+ "Point",
247
+ "PointI",
248
+ "Size",
249
+ "SizeI",
250
+ "Rect",
251
+ "RectI",
252
+ "Box",
253
+ "BoxI",
254
+ "Circle",
255
+ "Ellipse",
256
+ "RoundRect",
257
+ "Triangle",
258
+ "Arc",
259
+ "Line",
260
+ "Matrix2D",
261
+ # Enums
262
+ "Format",
263
+ "CompOp",
264
+ "FillRule",
265
+ "GeometryType",
266
+ "ExtendMode",
267
+ "GradientType",
268
+ "StrokeCap",
269
+ "StrokeCapPosition",
270
+ "StrokeJoin",
271
+ "StrokeTransformOrder",
272
+ "TransformOp",
273
+ "ClipOp",
274
+ "FlattenMode",
275
+ "RenderingEngine",
276
+ "ResultCode",
277
+ "ContextHint",
278
+ "RenderingQuality",
279
+ "GradientQuality",
280
+ "PatternQuality",
281
+ "RuntimeInfoType",
282
+ "RuntimeCpuArch",
283
+ "RuntimeCpuFeatures",
284
+ ]
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
blend2d/color.py ADDED
@@ -0,0 +1,202 @@
1
+ """
2
+ Color Representation and Utilities for Blend2D.
3
+ """
4
+
5
+ from __future__ import annotations
6
+ from dataclasses import dataclass
7
+ from typing import Union, Tuple, Sequence
8
+ from blend2d.ffi import BLRgba32, BLRgba64, BLRgba
9
+
10
+
11
+ NAMED_COLORS = {
12
+ "black": 0xFF000000,
13
+ "white": 0xFFFFFFFF,
14
+ "red": 0xFFFF0000,
15
+ "green": 0xFF008000,
16
+ "lime": 0xFF00FF00,
17
+ "blue": 0xFF0000FF,
18
+ "yellow": 0xFFFFFF00,
19
+ "cyan": 0xFF00FFFF,
20
+ "aqua": 0xFF00FFFF,
21
+ "magenta": 0xFFFF00FF,
22
+ "fuchsia": 0xFFFF00FF,
23
+ "transparent": 0x00000000,
24
+ "gray": 0xFF808080,
25
+ "grey": 0xFF808080,
26
+ "darkgray": 0xFFA9A9A9,
27
+ "darkgrey": 0xFFA9A9A9,
28
+ "lightgray": 0xFFD3D3D3,
29
+ "lightgrey": 0xFFD3D3D3,
30
+ "orange": 0xFFFFA500,
31
+ "coral": 0xFFFF7F50,
32
+ "purple": 0xFF800080,
33
+ "pink": 0xFFFFC0CB,
34
+ "navy": 0xFF000080,
35
+ "teal": 0xFF008080,
36
+ "olive": 0xFF808000,
37
+ "maroon": 0xFF800000,
38
+ "silver": 0xFFC0C0C0,
39
+ "gold": 0xFFFFD700,
40
+ "indigo": 0xFF4B0082,
41
+ "violet": 0xFFEE82EE,
42
+ "brown": 0xFFA52A2A,
43
+ "khaki": 0xFFF0E68C,
44
+ "lavender": 0xFFE6E6FA,
45
+ "salmon": 0xFFFA8072,
46
+ "plum": 0xFFDDA0DD,
47
+ "turquoise": 0xFF40E0D0,
48
+ "crimson": 0xFFDC143C,
49
+ }
50
+
51
+
52
+ @dataclass
53
+ class Rgba32:
54
+ """32-bit ARGB color (uint32)."""
55
+ value: int = 0xFF000000
56
+
57
+ def __init__(
58
+ self,
59
+ r_or_value: Union[int, Sequence[int]] = 0xFF000000,
60
+ g: Optional[int] = None,
61
+ b: Optional[int] = None,
62
+ a: Optional[int] = None
63
+ ):
64
+ if isinstance(r_or_value, (tuple, list)):
65
+ vals = r_or_value
66
+ r = vals[0]
67
+ g = vals[1]
68
+ b = vals[2]
69
+ a = vals[3] if len(vals) > 3 else 255
70
+ self.value = ((int(a) & 0xFF) << 24) | ((int(r) & 0xFF) << 16) | ((int(g) & 0xFF) << 8) | (int(b) & 0xFF)
71
+ elif g is not None or b is not None or a is not None:
72
+ r = int(r_or_value)
73
+ g_val = int(g) if g is not None else 0
74
+ b_val = int(b) if b is not None else 0
75
+ a_val = int(a) if a is not None else 255
76
+ self.value = ((a_val & 0xFF) << 24) | ((r & 0xFF) << 16) | ((g_val & 0xFF) << 8) | (b_val & 0xFF)
77
+ else:
78
+ self.value = int(r_or_value) & 0xFFFFFFFF
79
+
80
+ @property
81
+ def a(self) -> int:
82
+ return (self.value >> 24) & 0xFF
83
+
84
+ @property
85
+ def r(self) -> int:
86
+ return (self.value >> 16) & 0xFF
87
+
88
+ @property
89
+ def g(self) -> int:
90
+ return (self.value >> 8) & 0xFF
91
+
92
+ @property
93
+ def b(self) -> int:
94
+ return self.value & 0xFF
95
+
96
+ def to_c(self) -> BLRgba32:
97
+ return BLRgba32(self.value)
98
+
99
+ @classmethod
100
+ def from_c(cls, c: BLRgba32) -> Rgba32:
101
+ return cls(c.value)
102
+
103
+ @classmethod
104
+ def from_rgba(cls, r: int, g: int, b: int, a: int = 255) -> Rgba32:
105
+ val = ((int(a) & 0xFF) << 24) | ((int(r) & 0xFF) << 16) | ((int(g) & 0xFF) << 8) | (int(b) & 0xFF)
106
+ return cls(val)
107
+
108
+ @classmethod
109
+ def from_hex(cls, hex_str: str) -> Rgba32:
110
+ s = hex_str.strip().lstrip("#")
111
+ try:
112
+ if len(s) == 3: # RGB
113
+ r = int(s[0] * 2, 16)
114
+ g = int(s[1] * 2, 16)
115
+ b = int(s[2] * 2, 16)
116
+ return cls.from_rgba(r, g, b, 255)
117
+ elif len(s) == 4: # RGBA
118
+ r = int(s[0] * 2, 16)
119
+ g = int(s[1] * 2, 16)
120
+ b = int(s[2] * 2, 16)
121
+ a = int(s[3] * 2, 16)
122
+ return cls.from_rgba(r, g, b, a)
123
+ elif len(s) == 6: # RRGGBB
124
+ r = int(s[0:2], 16)
125
+ g = int(s[2:4], 16)
126
+ b = int(s[4:6], 16)
127
+ return cls.from_rgba(r, g, b, 255)
128
+ elif len(s) == 8: # RRGGBBAA
129
+ r = int(s[0:2], 16)
130
+ g = int(s[2:4], 16)
131
+ b = int(s[4:6], 16)
132
+ a = int(s[6:8], 16)
133
+ return cls.from_rgba(r, g, b, a)
134
+ except ValueError:
135
+ pass
136
+ raise ValueError(f"Invalid hex color string: '{hex_str}'")
137
+
138
+ def __repr__(self) -> str:
139
+ return f"Rgba32(r={self.r}, g={self.g}, b={self.b}, a={self.a}, hex=#{self.value:08X})"
140
+
141
+
142
+ @dataclass
143
+ class Rgba:
144
+ """Floating point RGBA color (0.0 - 1.0)."""
145
+ r: float = 0.0
146
+ g: float = 0.0
147
+ b: float = 0.0
148
+ a: float = 1.0
149
+
150
+ def to_c(self) -> BLRgba:
151
+ return BLRgba(float(self.r), float(self.g), float(self.b), float(self.a))
152
+
153
+ @classmethod
154
+ def from_c(cls, c: BLRgba) -> Rgba:
155
+ return cls(c.r, c.g, c.b, c.a)
156
+
157
+ def to_rgba32(self) -> Rgba32:
158
+ return Rgba32.from_rgba(
159
+ int(min(max(self.r, 0.0), 1.0) * 255),
160
+ int(min(max(self.g, 0.0), 1.0) * 255),
161
+ int(min(max(self.b, 0.0), 1.0) * 255),
162
+ int(min(max(self.a, 0.0), 1.0) * 255),
163
+ )
164
+
165
+
166
+ ColorLike = Union[Rgba32, Rgba, int, str, Tuple[int, int, int], Tuple[int, int, int, int], Sequence[float]]
167
+
168
+
169
+ def parse_color(color: ColorLike) -> Rgba32:
170
+ """Universal color parser returning a 32-bit Rgba32 instance."""
171
+ if isinstance(color, Rgba32):
172
+ return color
173
+ if isinstance(color, Rgba):
174
+ return color.to_rgba32()
175
+ if isinstance(color, int):
176
+ return Rgba32(color)
177
+ if isinstance(color, str):
178
+ color_lower = color.lower().strip()
179
+ if color_lower in NAMED_COLORS:
180
+ return Rgba32(NAMED_COLORS[color_lower])
181
+ if color.startswith("#"):
182
+ return Rgba32.from_hex(color)
183
+ # Try hex even without # if 6 or 8 hex digits
184
+ if len(color) in (3, 4, 6, 8) and all(c in "0123456789abcdefABCDEF" for c in color):
185
+ return Rgba32.from_hex(color)
186
+ raise ValueError(f"Unknown color name or invalid hex string: '{color}'")
187
+ if isinstance(color, (tuple, list)):
188
+ if all(isinstance(x, float) and 0.0 <= x <= 1.0 for x in color):
189
+ # Float normalized colors
190
+ r = int(color[0] * 255)
191
+ g = int(color[1] * 255)
192
+ b = int(color[2] * 255)
193
+ a = int(color[3] * 255) if len(color) > 3 else 255
194
+ return Rgba32.from_rgba(r, g, b, a)
195
+ else:
196
+ r = int(color[0])
197
+ g = int(color[1])
198
+ b = int(color[2])
199
+ a = int(color[3]) if len(color) > 3 else 255
200
+ return Rgba32.from_rgba(r, g, b, a)
201
+
202
+ raise TypeError(f"Cannot convert type {type(color)} to a valid Blend2D Color.")