[svg] avoid mutating the original library
This commit is contained in:
parent
5c1050b0ff
commit
27e1c23c33
1 changed files with 19 additions and 14 deletions
|
|
@ -45,6 +45,10 @@ def _make_svg_ids(names: Mapping[str, Pattern]) -> dict[str, str]:
|
|||
return svg_ids
|
||||
|
||||
|
||||
def _detached_library(library: Mapping[str, Pattern]) -> dict[str, Pattern]:
|
||||
return {name: pat.deepcopy() for name, pat in library.items()}
|
||||
|
||||
|
||||
def writefile(
|
||||
library: Mapping[str, Pattern],
|
||||
top: str,
|
||||
|
|
@ -53,13 +57,12 @@ def writefile(
|
|||
annotate_ports: bool = False,
|
||||
) -> None:
|
||||
"""
|
||||
Write a Pattern to an SVG file, by first calling .polygonize() on it
|
||||
Write a Pattern to an SVG file, by first calling .polygonize() on a detached
|
||||
materialized copy
|
||||
to change the shapes into polygons, and then writing patterns as SVG
|
||||
groups (<g>, inside <defs>), polygons as paths (<path>), and refs
|
||||
as <use> elements.
|
||||
|
||||
Note that this function modifies the Pattern.
|
||||
|
||||
If `custom_attributes` is `True`, a non-standard `pattern_layer` attribute
|
||||
is written to the relevant elements.
|
||||
|
||||
|
|
@ -71,19 +74,21 @@ def writefile(
|
|||
prior to calling this function.
|
||||
|
||||
Args:
|
||||
pattern: Pattern to write to file. Modified by this function.
|
||||
library: Mapping of pattern names to patterns.
|
||||
top: Name of the top-level pattern to render.
|
||||
filename: Filename to write to.
|
||||
custom_attributes: Whether to write non-standard `pattern_layer` attribute to the
|
||||
SVG elements.
|
||||
annotate_ports: If True, draw an arrow for each port (similar to
|
||||
`Pattern.visualize(..., ports=True)`).
|
||||
"""
|
||||
pattern = library[top]
|
||||
detached = _detached_library(library)
|
||||
pattern = detached[top]
|
||||
|
||||
# Polygonize pattern
|
||||
pattern.polygonize()
|
||||
|
||||
bounds = pattern.get_bounds(library=library)
|
||||
bounds = pattern.get_bounds(library=detached)
|
||||
if bounds is None:
|
||||
bounds_min, bounds_max = numpy.array([[-1, -1], [1, 1]])
|
||||
logger.warning('Pattern had no bounds (empty?); setting arbitrary viewbox', stacklevel=1)
|
||||
|
|
@ -96,10 +101,10 @@ def writefile(
|
|||
# Create file
|
||||
svg = svgwrite.Drawing(filename, profile='full', viewBox=viewbox_string,
|
||||
debug=(not custom_attributes))
|
||||
svg_ids = _make_svg_ids(library)
|
||||
svg_ids = _make_svg_ids(detached)
|
||||
|
||||
# Now create a group for each pattern and add in any Boundary and Use elements
|
||||
for name, pat in library.items():
|
||||
for name, pat in detached.items():
|
||||
svg_group = svg.g(id=svg_ids[name], fill='blue', stroke='red')
|
||||
|
||||
for layer, shapes in pat.shapes.items():
|
||||
|
|
@ -158,21 +163,21 @@ def writefile_inverted(
|
|||
box and drawing the polygons with reverse vertex order inside it, all within
|
||||
one `<path>` element.
|
||||
|
||||
Note that this function modifies the Pattern.
|
||||
|
||||
If you want pattern polygonized with non-default arguments, just call `pattern.polygonize()`
|
||||
prior to calling this function.
|
||||
|
||||
Args:
|
||||
pattern: Pattern to write to file. Modified by this function.
|
||||
library: Mapping of pattern names to patterns.
|
||||
top: Name of the top-level pattern to render.
|
||||
filename: Filename to write to.
|
||||
"""
|
||||
pattern = library[top]
|
||||
detached = _detached_library(library)
|
||||
pattern = detached[top]
|
||||
|
||||
# Polygonize and flatten pattern
|
||||
pattern.polygonize().flatten(library)
|
||||
pattern.polygonize().flatten(detached)
|
||||
|
||||
bounds = pattern.get_bounds(library=library)
|
||||
bounds = pattern.get_bounds(library=detached)
|
||||
if bounds is None:
|
||||
bounds_min, bounds_max = numpy.array([[-1, -1], [1, 1]])
|
||||
logger.warning('Pattern had no bounds (empty?); setting arbitrary viewbox', stacklevel=1)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue