__init__.py 1.9 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061
  1. from fontTools.pens.transformPen import TransformPen
  2. from fontTools.misc import etree
  3. from fontTools.misc.textTools import tostr
  4. from .parser import parse_path
  5. from .shapes import PathBuilder
  6. __all__ = [tostr(s) for s in ("SVGPath", "parse_path")]
  7. class SVGPath(object):
  8. """Parse SVG ``path`` elements from a file or string, and draw them
  9. onto a glyph object that supports the FontTools Pen protocol.
  10. For example, reading from an SVG file and drawing to a Defcon Glyph:
  11. import defcon
  12. glyph = defcon.Glyph()
  13. pen = glyph.getPen()
  14. svg = SVGPath("path/to/a.svg")
  15. svg.draw(pen)
  16. Or reading from a string containing SVG data, using the alternative
  17. 'fromstring' (a class method):
  18. data = '<?xml version="1.0" ...'
  19. svg = SVGPath.fromstring(data)
  20. svg.draw(pen)
  21. Both constructors can optionally take a 'transform' matrix (6-float
  22. tuple, or a FontTools Transform object) to modify the draw output.
  23. """
  24. def __init__(self, filename=None, transform=None):
  25. if filename is None:
  26. self.root = etree.ElementTree()
  27. else:
  28. tree = etree.parse(filename)
  29. self.root = tree.getroot()
  30. self.transform = transform
  31. @classmethod
  32. def fromstring(cls, data, transform=None):
  33. self = cls(transform=transform)
  34. self.root = etree.fromstring(data)
  35. return self
  36. def draw(self, pen):
  37. if self.transform:
  38. pen = TransformPen(pen, self.transform)
  39. pb = PathBuilder()
  40. # xpath | doesn't seem to reliable work so just walk it
  41. for el in self.root.iter():
  42. pb.add_path_from_element(el)
  43. original_pen = pen
  44. for path, transform in zip(pb.paths, pb.transforms):
  45. if transform:
  46. pen = TransformPen(original_pen, transform)
  47. else:
  48. pen = original_pen
  49. parse_path(path, pen)