svg_path_editor#
Submodules#
- svg_path_editor.geometry
- svg_path_editor.intersect
- svg_path_editor.math
- svg_path_editor.path_change_origin
- svg_path_editor.path_offset
- svg_path_editor.path_operations
- svg_path_editor.path_parser
- svg_path_editor.path_round_corners
- svg_path_editor.path_shade
- svg_path_editor.sub_path_bounds
- svg_path_editor.svg
Attributes#
Classes#
2D point with |
|
Control numerical precision for mixed symbolic/numeric operations. |
|
Planar bevel face containing an elliptical-arc boundary. |
|
Planar bevel face bounded by straight segments. |
|
Abstract RGBA image encoder. |
|
SVG fragments for shaded bevels. |
|
Base class for a single SVG path command and its numeric values. |
|
An SVG path as a sequence of |
Functions#
|
Return a new path where the origin of a (sub)path is moved. |
|
Construct bevel faces for an offset of a simple closed path. |
|
Offset a simple closed SVG path. |
|
Optimize the representation of an SVG path. |
|
Reverse the drawing direction of a path or sub-path. |
|
Round corners between straight segments in closed subpaths. |
|
Lambertian diffuse intensity from a 2D surface normal. |
|
Render a Lambert–shaded elliptical cone; return encoded bytes and base64 URI. |
|
Per-bevel Lambert shading for an SVG path. |
Package Contents#
- class svg_path_editor.Point(x, y)[source]#
2D point with
decimal.Decimalcoordinates.- x: decimal.Decimal#
- y: decimal.Decimal#
- __ne__(value, /)[source]#
Compare coordinates for inequality.
- Parameters:
value (object)
- Return type:
bool
- property vec2: Vec2#
Exact conversion to
Vec2.Coordinates are converted to SymPy rationals via
dec_to_rat().- Return type:
- property length: decimal.Decimal#
Euclidean norm \(‖v‖_2 = \sqrt{x^2 + y^2}\).
- Return type:
decimal.Decimal
- property normalized: Point#
Unit vector \(v / ‖v‖_2\).
The zero vector is returned unchanged.
- Return type:
- class svg_path_editor.Precision[source]#
Control numerical precision for mixed symbolic/numeric operations.
baselinedefines the primary target precision, whileadditionalcan be used to carry extra guard digits during intermediate computations.- Variables:
baseline – Baseline number of significant digits.
additional – Additional guard digits to be used internally.
- baseline: int#
- additional: int#
- property full: int#
Full number of significant digits to use.
- Returns:
baseline + additional.- Return type:
int
- svg_path_editor.change_path_origin(svg, new_origin_index, subpath=None)[source]#
Return a new path where the origin of a (sub)path is moved.
The command at
new_origin_indexbecomes the first command of the affected subpath segment; all items of that subpath are rotated accordingly. IfsubpathisTrue, only the subpath containingnew_origin_indexis transformed; ifFalse/None, the whole path is treated as a single segment.- Parameters:
svg (SvgPath) – Original path to transform.
new_origin_index (int) – Index of the command that should become the new origin within its subpath.
subpath (bool | None) – If
True, restrict the change to the subpath containingnew_origin_index; ifFalseorNone, treat the full path segment as one subpath.
- Returns:
A new
SvgPathinstance with the origin moved and the path representation optimized.- Return type:
- class svg_path_editor.BevelArced[source]#
Bases:
NamedTuplePlanar bevel face containing an elliptical-arc boundary.
The path consists of two corresponding arc segments (original and offset) joined by straight segments.
- Variables:
path – Closed
SvgPathdescribing the bevel face.c – Center of the supporting ellipse.
r – Radii vector of the supporting ellipse.
phi – Rotation of the ellipse in degrees.
locally_convex –
Trueiff the bevel is convex w.r.t. the interior.
- phi: decimal.Decimal#
- locally_convex: bool#
- ante_ext: bool = False#
- post_ext: bool = False#
- class svg_path_editor.BevelPolygon[source]#
Bases:
NamedTuplePlanar bevel face bounded by straight segments.
- Variables:
path – Closed
SvgPathdescribing the bevel polygon.outward_normal – Unit normal pointing out of the filled region.
- ante_ext: bool = False#
- post_ext: bool = False#
- svg_path_editor.bevel_path(path, *, d, prec=None)[source]#
Construct bevel faces for an offset of a simple closed path.
Unlike
offset_path(), this yields only the auxiliary faces that fill the bevel region between the original path and its offset.- Parameters:
path (SvgPath) – Closed
SvgPathwith exactly one subpathM … Z, using only line and elliptical-arc segments.d (Number) – Offset distance. Positive values move edges towards the interior.
prec (Precision | Literal['auto', 'auto-intersections'] | None) – Same semantics as in
offset_path().
- Returns:
Closed paths covering the bevel surface between original and offset.
- Raises:
AssertionError – If
pathis not a single closed subpath of the expected form, or if an offset intersection cannot be computed.- Return type:
collections.abc.Iterable[BevelPolygon | BevelArced]
- svg_path_editor.offset_path(path, *, d, prec=None)[source]#
Offset a simple closed SVG path.
The input must be a single closed subpath
M … Zof straight lines and elliptical arcs. Every segment is offset by distanced(inwards ford > 0), and consecutive offset segments are intersected to form the output path.- Parameters:
path (SvgPath) – Closed
SvgPathwith exactly one subpathM … Z, using only line and elliptical-arc segments.d (Number) – Offset distance. Positive values move edges towards the interior.
prec (Precision | Literal['auto', 'auto-intersections'] | None) –
Intersection and offsetting precision:
"auto": decimal precision +additional_digitsfor both offset geometry and intersections."auto-intersections": same automatic precision for intersections only; offsets remain symbolic.Precision: use this precision everywhere.None: purely symbolic where supported.
- Returns:
The offset closed path.
- Raises:
AssertionError – If
pathis not a single closed subpath of the expected form, or if an offset intersection cannot be computed.- Return type:
- svg_path_editor.optimize_path(svg, *, remove_useless_commands=False, remove_orphan_dots=False, use_shorthands=False, use_horizontal_and_vertical_lines=False, use_relative_absolute=False, use_reverse=False, use_close_path=False)[source]#
Optimize the representation of an SVG path.
The function can apply several optional passes that can be enabled using the parameters.
- Parameters:
svg (SvgPath) – Input path.
remove_useless_commands (bool) – Remove redundant
M/Zcommands and degenerateL/H/Vsegments.remove_orphan_dots (bool) – Remove empty closed subpaths (
Mimmediately followed byZ).use_shorthands (bool) – Convert eligible
C/Qsegments toS/Twhere possible.use_horizontal_and_vertical_lines (bool) – Replace
LwithHorVwhere possible.use_relative_absolute (bool) – Choose between relative and absolute commands per segment to minimize size.
use_reverse (bool) – Reverse the path direction if that yields a shorter minified representation. This can affect stroked paths.
use_close_path (bool) – Convert final line segments that return to start into
Z. This can affect stroked paths.
- Returns:
A new, possibly shorter, but geometrically equivalent path.
- Return type:
- svg_path_editor.reverse_path(svg, subpath_of_item=None)[source]#
Reverse the drawing direction of a path or sub-path.
- Parameters:
svg (SvgPath) – Input path.
subpath_of_item (int | None) – Index of an item within the sub-path to reverse, or
Noneto reverse the entire path.
- Returns:
A new path with the selected segment reversed. Geometry is preserved, but command types and relative/absolute representation may change.
- Return type:
- svg_path_editor.round_corners(path, radius, *, selector=lambda a, b, c: ...)[source]#
Round corners between straight segments in closed subpaths.
The input must be one or more closed subpaths
M … Z. Each corner between two straight segments (L/H/V/Z) at point \(B\) between \(AB\) and \(BC\) is replaced by:a shortened segment from \(A\) to \(P\) on \(AB\),
a circular arc from \(P\) to \(Q\) with radius
radius,a shortened segment from \(Q\) to \(C\) on \(BC\).
Only corners with straight incoming and outgoing segments are modified. The input path is not modified.
- Parameters:
- Returns:
New
SvgPathwith chosen line-line corners rounded by arcs.- Raises:
ValueError – If
radiusis not positive.- Return type:
- svg_path_editor.PNG#
- svg_path_editor.WEBP#
- class svg_path_editor.ImageFormat[source]#
Bases:
ProtocolAbstract RGBA image encoder.
- Variables:
media_type – MIME type of the encoded image.
extension – File extension (without dot).
- media_type: ClassVar[str]#
- extension: ClassVar[str]#
- class svg_path_editor.PathShading[source]#
SVG fragments for shaded bevels.
- Variables:
defs_body – Elements for a document-wide
<defs>(e.g. shared<image>or<clipPath>definitions).body – Per-path drawing elements (e.g.
<path>,<g>,<use>) that referencedefs_body.
- defs_body: list[str]#
- body: list[str]#
- svg_path_editor.lambert_from_angle(normal, *, z_light=1)[source]#
Lambertian diffuse intensity from a 2D surface normal.
The 2D normal is interpreted in the \(xy\)-plane, with an implicit \(z\)-component 1:
\[\mathbf{n} = (n_x, n_y, 1).\]The light position is
\[\mathbf{L}_\text{pos} = (0, 1, z_{\text{light}}),\]and the light direction is
\[\hat{\mathbf{L}} = \frac{\mathbf{L}_\text{pos}}{\|\mathbf{L}_\text{pos}\|}.\]The Lambert intensity is
\[I = \max(0, \hat{\mathbf{n}} \cdot \hat{\mathbf{L}}),\]where \(\hat{\mathbf{n}}\) is the normalized surface normal.
- svg_path_editor.lambert_shading_base64(*, r, phi, locally_convex, resolution, z_light=1.0, t=0.5, format=WEBP, seed=None)[source]#
Render a Lambert–shaded elliptical cone; return encoded bytes and base64 URI.
The cone radii are \(r = (r_x, r_y)\) in image space. For a point \((x, y)\) on the grid
\[(x, y) \in \left[-\frac{1}{r_x}, \frac{1}{r_x}\right] \times \left[-\frac{1}{r_y}, \frac{1}{r_y}\right],\]the unnormalized normal is
\[\mathbf{n}(x, y) = \left(\frac{x}{r_x^2}, \frac{y}{r_y^2}, 1\right).\]The Lambert term is
\[I(x, y) = \max\left(0, \hat{\mathbf{n}}(x, y)\cdot\hat{\mathbf{L}}\right),\]where \(\hat{\mathbf{L}}\) is the unit vector from the light position \((0, s, z_{\text{light}})\) with \(s = -1\) if
locally_convexelse \(+1\), rotated in the \(xy\)-plane by \(-\varphi\) degrees.Grayscale is binary (0 or 255) according to \(I > t\). Alpha is a symmetric remap of \(I\) around \(t\):
\[\begin{split}\alpha(I) = \begin{cases} \dfrac{I - t}{1 - t}, & I \geq t,\\ \dfrac{t - I}{t}, & I < t. \end{cases}\end{split}\]Before 8-bit quantization, uniform noise in \([0, 1]\) is added to alpha for dithering.
The final RGBA image is encoded with
formatand returned both as raw bytes and as adata:...;base64,...URI.- Parameters:
r (Point) – Ellipse radii in \(x\) and \(y\).
phi (decimal.Decimal) – Rotation in degrees of the light direction in image space (clockwise in screen coordinates).
locally_convex (bool) – If true, the base light position is \((0, -1, z_{\text{light}})\), otherwise \((0, 1, z_{\text{light}})\).
resolution (float) – Pixels per SVG unit. Image size is \(\lceil 2 r_x \, \mathrm{resolution} \rceil \times \lceil 2 r_y \, \mathrm{resolution} \rceil\).
z_light (float) – \(z\) height of the light source.
t (float) – Neutral Lambert intensity in \([0, 1]\) (threshold).
format (ImageFormat) – Image format to use.
seed (int | None) – RNG seed for alpha dithering;
Noneis non-deterministic.
- Returns:
(img_bytes, img_data_uri); the URI is suitable for SVGhref.- Return type:
tuple[bytes, str]
- svg_path_editor.shade_path(svg, *, d, resolution, z_light=1, threshold=0.5, max_opacity=1, format=WEBP, shade_offset=0, clip_offset=0, seed=None, prec=None, fmt_spec='')[source]#
Per-bevel Lambert shading for an SVG path.
The path is decomposed into bevel regions via
svg_path_editor.path_offset.bevel_path().Flat bevel polygons are shaded analytically with
lambert_from_angle().Curved bevel arcs are shaded using a small Lambert RGBA texture from
lambert_shading_base64(), referenced by<image>/<use>and clipped to the arc geometry.
For each bevel polygon:
One
<path>is emitted withfill="white"orfill="black"depending on whether the intensity is above or belowthreshold.Opacity is a symmetric remap of the intensity around
thresholdin \([0, 1]\), scaled bymax_opacity.
For each bevel arc:
A Lambert cone texture is generated (or reused from a cache) for
(r.x, r.y, phi, locally_convex).A base
<image>at the origin with size \(2 r_x \times 2 r_y\) is placed inPathShading.defs_bodyonce per unique key.For each occurrence, a
<clipPath>with the bevel geometry and a<use>of the base image are emitted intoPathShading.body, translated so the image origin matches the lower-left corner of the ellipse bounding box, and rotated byphiaround the ellipse center if non-zero.<use>carries opacitymax_opacitywhen it is less than 1.
To integrate into an SVG, place all
defs_bodyentries inside a single document-level<defs>and insertbodywhere the path should render.- Parameters:
svg (SvgPath) – Input path to bevel and shade.
d (Number) – Offset distance for
bevel_path().resolution (float) – Pixels per SVG unit for generated textures.
z_light (Number) – \(z\) height of the light source.
threshold (Number) – Neutral Lambert intensity in \([0, 1]\), shared between flat bevels and textures.
max_opacity (Number) – Global opacity scale in \([0, 1]\).
format (ImageFormat) – Texture format, e.g.
WEBPorPNG.shade_offset (int) – Starting index for generated shade IDs.
clip_offset (int) – Starting index for generated clip-path IDs.
seed (int | None) – RNG seed for alpha dithering in
lambert_shading_base64();Nonefor non-deterministic.prec (Precision | Literal['auto', 'auto-intersections'] | None) – Precision/geometry mode passed to
bevel_path()."auto"and"auto-intersections"select automatic strategies;Noneuses the default.fmt_spec (str) – The formatting specification for the paths.
- Returns:
PathShadingwith SVG fragments for defs and body.- Return type:
- class svg_path_editor.SvgItem(values, relative)[source]#
Bases:
abc.ABCBase class for a single SVG path command and its numeric values.
- Parameters:
values (list[T])
relative (bool)
- _relative: bool#
- values: list[decimal.Decimal]#
- absolute_control_points: list[SvgControlPoint] = []#
- static make(raw_item)[source]#
Construct the appropriate subclass of
SvgItemfrom a parsed command and its parameter strings.- Parameters:
raw_item (list[str]) – List starting with the command letter followed by numeric parameters as strings (e.g.
["M", "0", "0"]).- Raises:
ValueError – If the item is empty or the command is invalid.
- Return type:
- static make_from(origin, previous, new_type)[source]#
Create a new
SvgItemof typenew_typefrom an existing item.The new item preserves the current target location and, where possible, the original control point geometry.
- refresh_absolute_points(origin, previous)[source]#
Recalculate absolute points from stored values and the previous item.
- property relative: bool#
Whether this command is stored in relative coordinates.
- Return type:
bool
- refresh_absolute_control_points(origin, previous_target)[source]#
Recalculate absolute control points.
The default implementation assumes there are no control points.
- reset_control_points(previous_target)[source]#
Reset control points to a default geometry between previous and target.
Subclasses for curve commands override this to compute reasonable defaults.
- Parameters:
previous_target (SvgItem) – Previous item in the path.
- Return type:
None
- clone()[source]#
Return a shallow clone of this item, retaining its subclass.
Values, relativity and
previous_pointare copied. Absolute points and control points need to be recomputed viarefresh(), as is done inSvgPath.clone().- Return type:
Self
- translate(x, y, force=False)[source]#
Translate in place.
Relative items are translated only if
forceis true; otherwise their stored deltas are left unchanged.
- translated(x, y, force=False)[source]#
Return a translated copy. See
translate()for details.
- rotate(ox, oy, degrees, force=False)[source]#
Rotate the item in place around
(ox, oy).For relative items, rotation is performed around
(0, 0)unlessforceis true.
- rotated(ox, oy, degrees, force=False)[source]#
Return a rotated copy around
(ox, oy). Seerotate()for details.
- set_target_location(pt)[source]#
Move the geometric target of this command to
pt.- Parameters:
pt (Point) – New target location in absolute coordinates.
- Return type:
None
- set_control_location(idx, pt)[source]#
Move control point
idxtopt.Only meaningful for commands storing Bézier handles.
- Parameters:
idx (int) – Index of the control point to move.
pt (Point) – New control point location in absolute coordinates.
- Return type:
None
- property control_locations: list[SvgControlPoint]#
Absolute control points associated with this item.
- Return type:
list[SvgControlPoint]
- get_type(ignore_is_relative=False)[source]#
Return the SVG command letter for this item (e.g.
"M"or"l").- Parameters:
ignore_is_relative (bool) – Always return the uppercase key regardless of
relative.- Return type:
str
- as_standalone_string()[source]#
Return a standalone path string for this command.
The result starts with an
Mto this command’sprevious_pointfollowed by the command itself.- Return type:
str
- as_string(decimals=None, minify=False, trailing_items=())[source]#
Serialize this command into an SVG path fragment.
Optionally additional same-typed
trailing_itemscan be appended in a compact form.- Parameters:
decimals (int | None) – Number of decimal places, or
Nonefor default.minify (bool) – Use a more compact numeric representation.
trailing_items (collections.abc.Iterable[SvgItem]) – Additional items of the same type to serialize in the same command group.
- Return type:
str
- __format__(format_spec)[source]#
Format this item using
as_string().The
format_speccan be used to control decimal places and minification:""(empty): useas_string()defaults".3":decimals=3"m":minify=True".3m"or"m.3":decimals=3,minify=True
Any other characters are currently ignored.
- Parameters:
format_spec (str) – Format specification string (e.g.
".3m").- Return type:
str
- __str__()[source]#
Return
as_string()with default options.- Return type:
str
- class svg_path_editor.SvgPath(path)[source]#
An SVG path as a sequence of
SvgItem.- Parameters:
path (str | list[SvgItem])
- clone()[source]#
Return a deep clone of this path.
All contained items are cloned as well, and absolute positions are recomputed.
- Return type:
- rotate(ox, oy, degrees)[source]#
Rotate in place around
(ox, oy).May also normalize horizontal/vertical segments after rotation.
- property relative: bool#
Indicate whether all items are stored as relative commands.
Mixed paths (some absolute, some relative) return
False.- Return type:
bool
- with_relative(new_relative)[source]#
Return a new path with all items converted to the requested representation.
- Parameters:
new_relative (bool) – Target representation (
Truefor relative).- Return type:
- remove(item)[source]#
Remove the given item.
- Parameters:
item (SvgItem) – Item to remove.
- Raises:
ValueError – If the item is not present.
- Return type:
None
- insert(index, item)[source]#
Insert
itembeforeindex.- Parameters:
index (int) – Index before which to insert.
item (SvgItem) – Item to insert.
- Return type:
None
- as_string(decimals=None, minify=False)[source]#
Serialize the entire path to an SVG path data string.
- Parameters:
decimals (int | None) – Number of decimal places, or
Nonefor default.minify (bool) – Use a compact representation.
- Return type:
str
- property target_locations: list[SvgPoint]#
Final absolute points for each item in the path.
- Return type:
list[SvgPoint]
- property control_locations: list[SvgControlPoint]#
Flattened list of all absolute control points for the path.
- Return type:
list[SvgControlPoint]
- set_location(pt_reference, to)[source]#
Move the given point to
to.The reference must come from a previously queried point list (e.g.
target_locationsorcontrol_locations).
- refresh_absolute_positions()[source]#
Recompute absolute positions for all items in the path.
This should be called after structural or coordinate changes.
- Return type:
None
- __format__(format_spec)[source]#
Format this path using
as_string().The
format_speccan be used to control decimal places and minification, following the same rules asSvgItem.__format__():""(empty): useas_string()defaults".3":decimals=3"m":minify=True".3m"or"m.3":decimals=3,minify=True
Any other characters are currently ignored.
- Parameters:
format_spec (str) – Format specification string (e.g.
".3m").- Return type:
str
- __str__()[source]#
Return
as_string()with default options.- Return type:
str