diff --git a/setup.cfg b/setup.cfg index 8d3cfdc0..060baf42 100644 --- a/setup.cfg +++ b/setup.cfg @@ -1,6 +1,6 @@ [metadata] name = svgelements -version = 1.6.4 +version = 1.6.5 description = Svg Elements Parsing long_description_content_type=text/markdown long_description = file: README.md diff --git a/svgelements/svgelements.py b/svgelements/svgelements.py index 4a06d541..433aedbe 100644 --- a/svgelements/svgelements.py +++ b/svgelements/svgelements.py @@ -43,7 +43,7 @@ and the Arc can do exact arc calculations if scipy is installed. """ -SVGELEMENTS_VERSION = "1.6.4" +SVGELEMENTS_VERSION = "1.6.5" MIN_DEPTH = 5 ERROR = 1e-12 @@ -3727,7 +3727,11 @@ def bbox(self, transformed=True, with_stroke=False): except ValueError: return None # No bounding box items existed. So no bounding box. - if with_stroke and self.stroke_width is not None: + if ( + with_stroke + and self.stroke_width is not None + and not (self.stroke is None or self.stroke.value is None) + ): if transformed: delta = float(self.implicit_stroke_width) / 2.0 else: @@ -7349,7 +7353,11 @@ def bbox(self, transformed=True, with_stroke=False): except ValueError: return None # No bounding box items existed. So no bounding box. - if with_stroke and self._path.stroke_width is not None: + if ( + with_stroke + and self._path.stroke_width is not None + and not (self._path.stroke is None or self._path.stroke.value is None) + ): delta = float(self._path.stroke_width) / 2.0 else: delta = 0.0 @@ -7912,7 +7920,11 @@ def bbox(self, transformed=True, with_stroke=False): xmax = max(p0[0], p1[0], p2[0], p3[0]) ymax = max(p0[1], p1[1], p2[1], p3[1]) - if with_stroke and self.stroke_width is not None: + if ( + with_stroke + and self.stroke_width is not None + and not (self.stroke is None or self.stroke.value is None) + ): if transformed: delta = float(self.implicit_stroke_width) / 2.0 else: @@ -8727,6 +8739,13 @@ def parse( root.objects[attributes[SVG_ATTR_ID]] = s elif event == "end": # End event. # The iterparse spec makes it clear that internal text data is undefined except at the end. + if ( + SVG_ATTR_DISPLAY in values + and values[SVG_ATTR_DISPLAY].lower() == SVG_VALUE_NONE + ): + # We are in a display=none, do not render this. Pop values and continue. + context, values = stack.pop() + continue s = None if tag in ( SVG_TAG_TEXT, @@ -8787,5 +8806,6 @@ def parse( context, values = stack.pop() elif event == "start-ns": if elem[0] != SVG_ATTR_DATA: + # Rare wc3 test uses a 'd' namespace. values[elem[0]] = elem[1] return root diff --git a/test/test_bbox.py b/test/test_bbox.py index 334f7bab..edf978a4 100644 --- a/test/test_bbox.py +++ b/test/test_bbox.py @@ -30,7 +30,8 @@ def test_bbox_rect_stroke(self): 'y': "51", 'width': "20", 'height': "10", - 'stroke-width': "5" + 'stroke-width': "5", + 'stroke': 'red', } e = Rect(values) self.assertEqual(e.bbox(), (50, 51, 70, 61)) @@ -88,7 +89,8 @@ def test_bbox_path_stroke(self): 'y': "51", 'width': "20", 'height': "10", - 'stroke-width': "5" + 'stroke-width': "5", + 'stroke': 'red', } e = Path(Rect(values)) self.assertEqual(e.bbox(), (50, 51, 70, 61)) @@ -122,6 +124,100 @@ def test_bbox_path_stroke(self): 61 + (5. / 2.) )) + def test_bbox_path_stroke_none(self): + """ + Same as test_bbox_path_stroke but stroke is set to none, so the bbox should not change. + """ + values = { + 'tag': 'rect', + 'rx': "4", + 'ry': "2", + 'x': "50", + 'y': "51", + 'width': "20", + 'height': "10", + 'stroke-width': "5", + 'stroke': "none", + } + e = Path(Rect(values)) + self.assertEqual(e.bbox(), (50, 51, 70, 61)) + self.assertEqual(e.bbox(with_stroke=True), ( + 50, + 51, + 70, + 61 + )) + e *= "translate(2)" + self.assertEqual(e.bbox(), (52, 51, 72, 61)) + self.assertEqual(e.bbox(with_stroke=True), ( + 52, + 51, + 72, + 61 + )) + e *= "scale(2)" + self.assertEqual(e.bbox(), (52 * 2, 51 * 2, 72 * 2, 61 * 2)) + self.assertEqual(e.bbox(with_stroke=True), ( + 52 * 2, + 51 * 2, + 72 * 2, + 61 * 2 + )) + self.assertEqual(e.bbox(transformed=False), (50, 51, 70, 61)) + self.assertEqual(e.bbox(transformed=False, with_stroke=True), ( + 50, + 51, + 70, + 61 + )) + + def test_bbox_path_stroke_unset(self): + """ + Same as test_bbox_path_stroke but the stroke is unset and thus shouldn't contribute to the bbox even if + with_stroke is set. + """ + values = { + 'tag': 'rect', + 'rx': "4", + 'ry': "2", + 'x': "50", + 'y': "51", + 'width': "20", + 'height': "10", + 'stroke-width': "5", + } + e = Path(Rect(values)) + self.assertEqual(e.bbox(), (50, 51, 70, 61)) + self.assertEqual(e.bbox(with_stroke=True), ( + 50, + 51, + 70, + 61 + )) + e *= "translate(2)" + self.assertEqual(e.bbox(), (52, 51, 72, 61)) + self.assertEqual(e.bbox(with_stroke=True), ( + 52, + 51, + 72, + 61 + )) + e *= "scale(2)" + self.assertEqual(e.bbox(), (52 * 2, 51 * 2, 72 * 2, 61 * 2)) + self.assertEqual(e.bbox(with_stroke=True), ( + 52 * 2, + 51 * 2, + 72 * 2, + 61 * 2 + )) + self.assertEqual(e.bbox(transformed=False), (50, 51, 70, 61)) + self.assertEqual(e.bbox(transformed=False, with_stroke=True), ( + 50, + 51, + 70, + 61 + )) + def test_bbox_subpath(self): values = { 'tag': 'rect', @@ -147,7 +243,8 @@ def test_bbox_subpath_stroke(self): 'y': "51", 'width': "20", 'height': "10", - 'stroke-width': "5" + 'stroke-width': "5", + 'stroke': 'red', } p = Path(Rect(values)) e = p.subpath(0) diff --git a/test/test_group.py b/test/test_group.py index 50d89fab..17874dd6 100644 --- a/test/test_group.py +++ b/test/test_group.py @@ -69,3 +69,18 @@ def test_issue_107(self): n = m * 'scale(2)' # Test __mult__ self.assertEqual(n[0][0].transform, Matrix("matrix(2,0,0,2,200,200)")) self.assertEqual(m[0][0].transform, Matrix("matrix(1,0,0,1,100,100)")) + + def test_issue_152(self): + """ + Tests issue 152, closed text objects within a group with style:display=None + This should have the SVG element and nothing else. + + https://github.com/meerk40t/svgelements/issues/152 + """ + q = io.StringIO(u''' + + Issue 152 + + ''') + elements = list(SVG.parse(q).elements()) + self.assertEqual(len(elements), 1)