Add basic <symbol> support in SVG #1819
Conversation
|
Thank you for your feedback @andersonhc ! I think I've finally solved the scaling issue with Please let me know what you think. |
| viewbox = symbol.attrib.get("viewBox") | ||
| if viewbox: | ||
| parts = viewbox.replace(",", " ").split() | ||
| if len(parts) >= 4: | ||
| setattr(group, "_vw", float(parts[2])) | ||
| setattr(group, "_vh", float(parts[3])) |
There was a problem hiding this comment.
Right now the test is failing:
@force_nodocument
def build_symbol(self, symbol: "Element") -> GraphicsContext:
"""Parse <symbol> as reusable content, not rendered directly."""
group = self.build_group(symbol)
viewbox = symbol.attrib.get("viewBox")
if viewbox:
parts = viewbox.replace(",", " ").split()
if len(parts) >= 4:
> setattr(group, "_vw", float(parts[2]))
E AttributeError: 'GraphicsContext' object has no attribute '_vw'
I don't think adding the viewbox attribute to the GraphicsContext is the best approach.
I recommend looking into using the GaphicsContext's transform to apply the viewbox.
Apply translate(-vx, -vy) @ scale(1 / vw, 1 / vh) to the symbol group should make it normalized to unit coordinates. In build_xref(), apply scale(width, height) @ translate(x, y).
There was a problem hiding this comment.
Hi @andersonhc , I've implemented your suggestion using transforms. The viewBox is now applied in build_symbol with scale(1/vw, 1/vh) @ translate(-vx, -vy), and build_xref applies scale(width, height) when specified. I also ignore percentage values for width/height. I tested it and it should be working now. Let me know what you think !
andersonhc
left a comment
There was a problem hiding this comment.
Please see suggested changes.
I would also add you to add a new item on test/svg/parameters.py on the test_svg_sources set:
pytest.param(svgfile("symbol.svg"), id="symbol reused in different placements"),
then create the file test/svg/svg_sources/symbol.svg with the content below:
<svg viewBox="0 0 80 20" xmlns="http://www.w3.org/2000/svg">
<!-- Our symbol in its own coordinate system -->
<symbol id="myDot" width="10" height="10" viewBox="0 0 2 2">
<circle cx="1" cy="1" r="1" />
</symbol>
<!-- A grid to materialize our symbol positioning -->
<path
d="M0,10 h80 M10,0 v20 M25,0 v20 M40,0 v20 M55,0 v20 M70,0 v20"
fill="none"
stroke="pink" />
<!-- All instances of our symbol -->
<use href="#myDot" x="5" y="5" opacity="1.0" />
<use href="#myDot" x="20" y="5" opacity="0.8" />
<use href="#myDot" x="35" y="5" opacity="0.6" />
<use href="#myDot" x="50" y="5" opacity="0.4" />
<use href="#myDot" x="65" y="5" opacity="0.2" />
</svg>
After that you will need to execute test_svg_conversion() once adding generate=True to assert_pdf_equal so it can generate the new PDF reference file.
|
Thanks for the detailed feedback! I will implement your suggestions and get back to you once it's done, or if I don't understand some details. |
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
|
Hi @andersonhc, thank you again! I've implemented all your suggestions, let me know what you think. |
|
@allcontributors please add @Theo1335 for code |
|
I've put up a pull request to add @Theo1335! 🎉 |
|
Thank you for the contribution @Theo1335 |

Add basic support in SVG parsing
This PR adds support for SVG
<symbol>elements.Checklist:
A unit test is covering the code added / modified by this PR
In case of a new feature, docstrings have been added, with also some documentation in the
docs/folder (N/A)A mention of the change is present in
CHANGELOG.mdThis PR is ready to be merged
By submitting this pull request, I confirm that my contribution is made under the terms of the GNU LGPL 3.0 license.