Skip to content

Commit

Permalink
Merge pull request #198 from ptomulik/use-bbox
Browse files Browse the repository at this point in the history
Add Use.bbox()
  • Loading branch information
tatarize authored Sep 26, 2022
2 parents 232ff48 + 40364ba commit e90a2b3
Show file tree
Hide file tree
Showing 2 changed files with 57 additions and 0 deletions.
41 changes: 41 additions & 0 deletions svgelements/svgelements.py
Original file line number Diff line number Diff line change
Expand Up @@ -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):
"""
Expand Down
16 changes: 16 additions & 0 deletions test/test_use.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,22 @@

class TestElementUse(unittest.TestCase):

def test_use_bbox_method(self):
q = io.StringIO(u'''<?xml version="1.0" encoding="utf-8" ?>
<svg viewBox="0, 0, 100, 100" height="100" width="100"
xmlns:xlink="http://www.w3.org/1999/xlink">
<use x="0" y="0" xlink:href="#rect1234"/>
<use x="20" y="20" xlink:href="#rect1234"/>
<defs>
<rect id="rect1234" x="0" y="20" width="50" height="50"/>
</defs>
</svg>''')
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'''<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
Expand Down

0 comments on commit e90a2b3

Please sign in to comment.