diff --git a/Lib/fontTools/svgLib/path/__init__.py b/Lib/fontTools/svgLib/path/__init__.py index 690475f28..311329798 100644 --- a/Lib/fontTools/svgLib/path/__init__.py +++ b/Lib/fontTools/svgLib/path/__init__.py @@ -5,6 +5,7 @@ from fontTools.misc.py23 import * from fontTools.pens.transformPen import TransformPen from fontTools.misc import etree from .parser import parse_path +from .shapes import PathBuilder __all__ = [tostr(s) for s in ("SVGPath", "parse_path")] @@ -50,5 +51,10 @@ class SVGPath(object): def draw(self, pen): if self.transform: pen = TransformPen(pen, self.transform) - for el in self.root.findall(".//{http://www.w3.org/2000/svg}path[@d]"): - parse_path(el.get("d"), pen) + pb = PathBuilder() + # xpath | doesn't seem to reliable work so just walk it + for el in self.root.iter(): + pb.AddPathFromElement(el) + for path in pb.pathes: + parse_path(path, pen) + diff --git a/Lib/fontTools/svgLib/path/shapes.py b/Lib/fontTools/svgLib/path/shapes.py index ba77a0312..bb4f93acf 100644 --- a/Lib/fontTools/svgLib/path/shapes.py +++ b/Lib/fontTools/svgLib/path/shapes.py @@ -9,8 +9,8 @@ class PathBuilder(object): def __init__(self): self.pathes = [] - def StartPath(self): - self.pathes.append('') + def StartPath(self, initial_path=''): + self.pathes.append(initial_path) def EndPath(self): self._Add('z') @@ -56,7 +56,7 @@ class PathBuilder(object): def v(self, x): self._vhline('v', y) - def Rect(self, rect): + def _ParseRect(self, rect): # TODO what format(s) do these #s come in? x = float(rect.attrib.get('x', 0)) y = float(rect.attrib.get('y', 0)) @@ -82,3 +82,15 @@ class PathBuilder(object): if rx > 0: self.A(rx, ry, x + rx, y) self.EndPath() + + def _ParsePath(self, path): + if 'd' in path.attrib: + self.StartPath(initial_path=path.attrib['d']) + + def AddPathFromElement(self, el): + tag = el.tag + if '}' in el.tag: + tag = el.tag.split('}', 1)[1] # from https://bugs.python.org/issue18304 + parse_fn = getattr(self, '_Parse%s' % tag.lower().capitalize(), None) + if callable(parse_fn): + parse_fn(el) diff --git a/Tests/svgLib/path/shapes_test.py b/Tests/svgLib/path/shapes_test.py index 7611f58f0..b1ae7e0bd 100644 --- a/Tests/svgLib/path/shapes_test.py +++ b/Tests/svgLib/path/shapes_test.py @@ -8,27 +8,41 @@ import pytest @pytest.mark.parametrize( - "rect, expected_path", + "svg_xml, expected_path", [ - # minimal valid example + # path: direct passthrough + ( + "", + "I love kittens" + ), + # path no @d + ( + "", + None + ), + # rect: minimal valid example ( "", "M0,0 H1 V1 H0 V0 z", ), - # sharp corners + # rect: sharp corners ( "", "M10,11 H27 V22 H10 V11 z", ), - # round corners + # rect: round corners ( "", "M11,9 H18 A2,2 0 0 1 20,11 V14 A2,2 0 0 1 18,16 H11" " A2,2 0 0 1 9,14 V11 A2,2 0 0 1 11,9 z", - ) + ), ] ) -def test_rect_to_path(rect, expected_path): +def test_el_to_path(svg_xml, expected_path): pb = shapes.PathBuilder() - pb.Rect(etree.fromstring(rect)) - assert [expected_path] == pb.pathes + pb.AddPathFromElement(etree.fromstring(svg_xml)) + if expected_path: + expected = [expected_path] + else: + expected = [] + assert pb.pathes == expected