From 585c2d1a5b2a24083fddeb27762ead7e8e5bc6d4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pawe=C5=82=20Tomulik?= Date: Mon, 26 Sep 2022 21:43:34 +0200 Subject: [PATCH 1/2] add test for missing Use.bbox() --- test/test_use.py | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/test/test_use.py b/test/test_use.py index 5ed7defb..02fbdf9e 100644 --- a/test/test_use.py +++ b/test/test_use.py @@ -6,6 +6,22 @@ class TestElementUse(unittest.TestCase): + def test_use_bbox_method(self): + q = io.StringIO(u''' + + + + + + + ''') + svg = SVG.parse(q) + use = list(svg.select(lambda e: isinstance(e, Use))) + self.assertEqual(2, len(use)) + self.assertEqual((0.0, 20.0, (0.0 + 50.0), (20.0 + 50.0)), use[0].bbox()) + self.assertEqual((20.0 + 0.0, 20.0 + 20.0, (20.0 + 50.0), (20.0 + 20.0 + 50.0)), use[1].bbox()) + def test_issue_156(self): q1 = io.StringIO(u''' Date: Mon, 26 Sep 2022 21:43:50 +0200 Subject: [PATCH 2/2] add Use.bbox() method --- svgelements/svgelements.py | 41 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 41 insertions(+) diff --git a/svgelements/svgelements.py b/svgelements/svgelements.py index 34c797ec..c8ce5d91 100644 --- a/svgelements/svgelements.py +++ b/svgelements/svgelements.py @@ -7690,6 +7690,47 @@ def select(self, conditional=None): for s in subitem.select(conditional): yield s + @staticmethod + def union_bbox(elements, transformed=True, with_stroke=False): + """ + Returns the union of the bounding boxes for the elements within the iterator. + + :param transformed: Should the children of this object be properly transformed. + :param with_stroke: should the stroke-width be included in the bounds of the elements + :return: union of all bounding boxes of elements within the iterable. + """ + boxes = [] + for e in elements: + if not hasattr(e, "bbox") or isinstance(e, (Group, Use)): + continue + box = e.bbox(transformed=transformed, with_stroke=with_stroke) + if box is None: + continue + boxes.append(box) + if len(boxes) == 0: + return None + (xmins, ymins, xmaxs, ymaxs) = zip(*boxes) + return (min(xmins), min(ymins), max(xmaxs), max(ymaxs)) + + def bbox(self, transformed=True, with_stroke=False): + """ + Returns the bounding box of the given object. + + In the case of groups this is the union of all the bounding boxes of all bound children. + + Setting transformed to false, may yield unexpected results if subitems are transformed in non-uniform + ways. + + :param transformed: bounding box of the properly transformed children. + :param with_stroke: should the stroke-width be included in the bounds. + :return: bounding box of the given element + """ + return Use.union_bbox( + self.select(), + transformed=transformed, + with_stroke=with_stroke, + ) + class ClipPath(SVGElement, list): """