Skip to content

Commit

Permalink
Merge pull request #195 from ptomulik/fix-bbox
Browse files Browse the repository at this point in the history
Fix union_bbox()
  • Loading branch information
tatarize authored Sep 26, 2022
2 parents 3fc3755 + 23eaca2 commit 232ff48
Show file tree
Hide file tree
Showing 2 changed files with 59 additions and 22 deletions.
29 changes: 7 additions & 22 deletions svgelements/svgelements.py
Original file line number Diff line number Diff line change
Expand Up @@ -7584,33 +7584,18 @@ def union_bbox(elements, transformed=True, with_stroke=False):
: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.
"""
boundary_points = []
boxes = []
for e in elements:
if not hasattr(e, "bbox"):
if not hasattr(e, "bbox") or isinstance(e, (Group, Use)):
continue
box = e.bbox(transformed=False, with_stroke=with_stroke)
box = e.bbox(transformed=transformed, with_stroke=with_stroke)
if box is None:
continue
top_left = (box[0], box[1])
top_right = (box[2], box[1])
bottom_left = (box[0], box[3])
bottom_right = (box[2], box[3])
if transformed:
top_left = e.transform.point_in_matrix_space(top_left)
top_right = e.transform.point_in_matrix_space(top_right)
bottom_left = e.transform.point_in_matrix_space(bottom_left)
bottom_right = e.transform.point_in_matrix_space(bottom_right)
boundary_points.append(top_left)
boundary_points.append(top_right)
boundary_points.append(bottom_left)
boundary_points.append(bottom_right)
if len(boundary_points) == 0:
boxes.append(box)
if len(boxes) == 0:
return None
xmin = min([e[0] for e in boundary_points])
ymin = min([e[1] for e in boundary_points])
xmax = max([e[0] for e in boundary_points])
ymax = max([e[1] for e in boundary_points])
return xmin, ymin, xmax, ymax
(xmins, ymins, xmaxs, ymaxs) = zip(*boxes)
return (min(xmins), min(ymins), max(xmaxs), max(ymaxs))

def bbox(self, transformed=True, with_stroke=False):
"""
Expand Down
52 changes: 52 additions & 0 deletions test/test_bbox.py
Original file line number Diff line number Diff line change
Expand Up @@ -275,6 +275,58 @@ def test_bbox_subpath_stroke(self):
61 + (5. / 2.)
))

def test_bbox_rotated_circle(self):
# Rotation of circle must not affect it's bounding box
c = Circle(cx=0, cy=0, r=1, transform="rotate(45)")
(xmin, ymin, xmax, ymax) = c.bbox()
self.assertAlmostEqual(-1, xmin)
self.assertAlmostEqual(-1, ymin)
self.assertAlmostEqual( 1, xmax)
self.assertAlmostEqual( 1, ymax)

def test_bbox_svg_with_rotated_circle(self):
# Rotation of circle within group must not affect it's bounding box
q = io.StringIO(
u'''<?xml version="1.0" encoding="utf-8" ?>
<svg>
<circle cx="0" cy="0" r="1" transform="rotate(45)"/>
</svg>
'''
)
svg = SVG.parse(q)
(xmin, ymin, xmax, ymax) = svg.bbox()
self.assertAlmostEqual(-1, xmin)
self.assertAlmostEqual(-1, ymin)
self.assertAlmostEqual( 1, xmax)
self.assertAlmostEqual( 1, ymax)

def test_bbox_translated_circle(self):
c = Circle(cx=0, cy=0, r=1, transform="translate(-1,-1)")
(xmin, ymin, xmax, ymax) = c.bbox()
self.assertAlmostEqual(-2, xmin)
self.assertAlmostEqual(-2, ymin)
self.assertAlmostEqual( 0, xmax)
self.assertAlmostEqual( 0, ymax)

def test_bbox_svg_with_translated_group_with_circle(self):
# Translation of nested group must be applied correctly
q = io.StringIO(
u'''<?xml version="1.0" encoding="utf-8" ?>
<svg>
<g transform="translate(-1,-1)">
<circle cx="0" cy="0" r="1"/>
</g>
</svg>
'''
)
svg = SVG.parse(q)
(xmin, ymin, xmax, ymax) = svg.bbox()
self.assertAlmostEqual(-2, xmin)
self.assertAlmostEqual(-2, ymin)
self.assertAlmostEqual( 0, xmax)
self.assertAlmostEqual( 0, ymax)


def test_issue_104(self):
"""Testing Issue 104 rotated bbox"""
rect = Rect(10,10,10,10)
Expand Down

0 comments on commit 232ff48

Please sign in to comment.