From fc1f7bef922dcf33a26727534f3c6241227f7265 Mon Sep 17 00:00:00 2001 From: Peter Mathis Date: Mon, 1 Sep 2025 12:03:05 +0200 Subject: [PATCH 1/4] Fix SVG scaling with fallback when no width/height attributes available --- src/plone/scale/scale.py | 1 + src/plone/scale/tests/data/logo.svg | 48 +++++++++++++++++++ .../scale/tests/data/logo_no_width_height.svg | 48 +++++++++++++++++++ src/plone/scale/tests/test_scale.py | 15 ++++++ 4 files changed, 112 insertions(+) create mode 100644 src/plone/scale/tests/data/logo.svg create mode 100644 src/plone/scale/tests/data/logo_no_width_height.svg diff --git a/src/plone/scale/scale.py b/src/plone/scale/scale.py index 6c2033a..365c1c3 100644 --- a/src/plone/scale/scale.py +++ b/src/plone/scale/scale.py @@ -613,6 +613,7 @@ def scale_svg_image( logger.exception( f"Can not convert source dimensions: '{source_width}':'{source_height}'" ) + image.seek(0) data = image.read() if isinstance(data, str): return data.encode("utf-8"), (int(target_width), int(target_height)) diff --git a/src/plone/scale/tests/data/logo.svg b/src/plone/scale/tests/data/logo.svg new file mode 100644 index 0000000..4405bad --- /dev/null +++ b/src/plone/scale/tests/data/logo.svg @@ -0,0 +1,48 @@ + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/plone/scale/tests/data/logo_no_width_height.svg b/src/plone/scale/tests/data/logo_no_width_height.svg new file mode 100644 index 0000000..7f774ed --- /dev/null +++ b/src/plone/scale/tests/data/logo_no_width_height.svg @@ -0,0 +1,48 @@ + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/plone/scale/tests/test_scale.py b/src/plone/scale/tests/test_scale.py index 8122a65..dfa7177 100644 --- a/src/plone/scale/tests/test_scale.py +++ b/src/plone/scale/tests/test_scale.py @@ -1,5 +1,6 @@ from io import BytesIO as StringIO from plone.scale.scale import calculate_scaled_dimensions +from plone.scale.scale import scale_svg_image from plone.scale.scale import scaleImage from plone.scale.scale import scalePILImage from plone.scale.tests import TEST_DATA_LOCATION @@ -21,6 +22,8 @@ ANIGIF2 = (TEST_DATA_LOCATION / "animated2.gif").read_bytes() GREYSCALE_IMG = (TEST_DATA_LOCATION / "greyscale_image.png").read_bytes() ANIWEBP = (TEST_DATA_LOCATION / "animated.webp").read_bytes() +SVG = (TEST_DATA_LOCATION / "logo.svg").read_bytes() +SVG_NO_WIDTH_HEIGHT = (TEST_DATA_LOCATION / "logo_no_width_height.svg").read_bytes() class ScalingTests(TestCase): @@ -517,6 +520,18 @@ def testCalculateMinimumDimensions(self): self.assertGreaterEqual(dimensions.target_width, 1) self.assertGreaterEqual(dimensions.target_height, 1) + def testScaleSVGImage(self): + # Basic scaling test + scaled_svg = scale_svg_image(StringIO(SVG), 200, 100) + self.assertIn(b'width="200"', scaled_svg[0]) + self.assertIn(b'height="100"', scaled_svg[0]) + + # Scale SVG without width and height attributes + scaled_svg = scale_svg_image(StringIO(SVG_NO_WIDTH_HEIGHT), 100, 100) + self.assertIn(b' Date: Mon, 1 Sep 2025 12:03:53 +0200 Subject: [PATCH 2/4] changenote --- news/119.bugfix | 1 + 1 file changed, 1 insertion(+) create mode 100644 news/119.bugfix diff --git a/news/119.bugfix b/news/119.bugfix new file mode 100644 index 0000000..ca8a3a9 --- /dev/null +++ b/news/119.bugfix @@ -0,0 +1 @@ +Fix SVG scaling when no width/height attributes available. @petschki From 35fffd2dda7fe126c86fa725fcd3761364ce2fdf Mon Sep 17 00:00:00 2001 From: Peter Mathis Date: Mon, 1 Sep 2025 12:05:55 +0200 Subject: [PATCH 3/4] linting --- src/plone/scale/tests/test_scale.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/plone/scale/tests/test_scale.py b/src/plone/scale/tests/test_scale.py index dfa7177..be08641 100644 --- a/src/plone/scale/tests/test_scale.py +++ b/src/plone/scale/tests/test_scale.py @@ -528,7 +528,7 @@ def testScaleSVGImage(self): # Scale SVG without width and height attributes scaled_svg = scale_svg_image(StringIO(SVG_NO_WIDTH_HEIGHT), 100, 100) - self.assertIn(b' Date: Mon, 26 Jan 2026 14:27:28 +0100 Subject: [PATCH 4/4] do not copy image data --- src/plone/scale/scale.py | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/src/plone/scale/scale.py b/src/plone/scale/scale.py index 365c1c3..7541b3c 100644 --- a/src/plone/scale/scale.py +++ b/src/plone/scale/scale.py @@ -613,11 +613,10 @@ def scale_svg_image( logger.exception( f"Can not convert source dimensions: '{source_width}':'{source_height}'" ) - image.seek(0) - data = image.read() - if isinstance(data, str): - return data.encode("utf-8"), (int(target_width), int(target_height)) - return data, (int(target_width), int(target_height)) + return etree.tostring(tree, encoding="utf-8", xml_declaration=True), ( + int(target_width), + int(target_height), + ) source_aspectratio = source_width / source_height target_aspectratio = target_width / target_height