__init__.py 1.9 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465
  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. .. code-block::
  12. import defcon
  13. glyph = defcon.Glyph()
  14. pen = glyph.getPen()
  15. svg = SVGPath("path/to/a.svg")
  16. svg.draw(pen)
  17. Or reading from a string containing SVG data, using the alternative
  18. 'fromstring' (a class method):
  19. .. code-block::
  20. data = '<?xml version="1.0" ...'
  21. svg = SVGPath.fromstring(data)
  22. svg.draw(pen)
  23. Both constructors can optionally take a 'transform' matrix (6-float
  24. tuple, or a FontTools Transform object) to modify the draw output.
  25. """
  26. def __init__(self, filename=None, transform=None):
  27. if filename is None:
  28. self.root = etree.ElementTree()
  29. else:
  30. tree = etree.parse(filename)
  31. self.root = tree.getroot()
  32. self.transform = transform
  33. @classmethod
  34. def fromstring(cls, data, transform=None):
  35. self = cls(transform=transform)
  36. self.root = etree.fromstring(data)
  37. return self
  38. def draw(self, pen):
  39. if self.transform:
  40. pen = TransformPen(pen, self.transform)
  41. pb = PathBuilder()
  42. # xpath | doesn't seem to reliable work so just walk it
  43. for el in self.root.iter():
  44. pb.add_path_from_element(el)
  45. original_pen = pen
  46. for path, transform in zip(pb.paths, pb.transforms):
  47. if transform:
  48. pen = TransformPen(original_pen, transform)
  49. else:
  50. pen = original_pen
  51. parse_path(path, pen)