diff options
Diffstat (limited to 'lib/svg')
| -rw-r--r-- | lib/svg/__init__.py | 1 | ||||
| -rw-r--r-- | lib/svg/guides.py | 43 | ||||
| -rw-r--r-- | lib/svg/path.py | 16 | ||||
| -rw-r--r-- | lib/svg/tags.py | 2 |
4 files changed, 61 insertions, 1 deletions
diff --git a/lib/svg/__init__.py b/lib/svg/__init__.py index 74a409b6..df76c0d2 100644 --- a/lib/svg/__init__.py +++ b/lib/svg/__init__.py @@ -1,3 +1,4 @@ from .svg import color_block_to_point_lists, render_stitch_plan from .units import * from .path import apply_transforms, get_node_transform, get_correction_transform, line_strings_to_csp, point_lists_to_csp +from .guides import get_guides diff --git a/lib/svg/guides.py b/lib/svg/guides.py new file mode 100644 index 00000000..3e26a90d --- /dev/null +++ b/lib/svg/guides.py @@ -0,0 +1,43 @@ +import simpletransform + +from ..utils import string_to_floats, Point, cache +from .tags import SODIPODI_NAMEDVIEW, SODIPODI_GUIDE, INKSCAPE_LABEL +from .units import get_doc_size, get_viewbox_transform + + +class InkscapeGuide(object): + def __init__(self, node): + self.node = node + self.svg = node.getroottree().getroot() + + self._parse() + + def _parse(self): + self.label = self.node.get(INKSCAPE_LABEL, "") + + doc_size = list(get_doc_size(self.svg)) + + # convert the size from viewbox-relative to real-world pixels + viewbox_transform = get_viewbox_transform(self.svg) + simpletransform.applyTransformToPoint(simpletransform.invertTransform(viewbox_transform), doc_size) + + self.position = Point(*string_to_floats(self.node.get('position'))) + + # inkscape's Y axis is reversed from SVG's, and the guide is in inkscape coordinates + self.position.y = doc_size[1] - self.position.y + + # This one baffles me. I think inkscape might have gotten the order of + # their vector wrong? + parts = string_to_floats(self.node.get('orientation')) + self.direction = Point(parts[1], parts[0]) + + +@cache +def get_guides(svg): + """Find all Inkscape guides and return as InkscapeGuide instances.""" + + namedview = svg.find(SODIPODI_NAMEDVIEW) + if namedview is None: + return [] + + return [InkscapeGuide(node) for node in namedview.findall(SODIPODI_GUIDE)] diff --git a/lib/svg/path.py b/lib/svg/path.py index 6212211f..d2b4aee1 100644 --- a/lib/svg/path.py +++ b/lib/svg/path.py @@ -1,3 +1,4 @@ +import inkex import simpletransform from .units import get_viewbox_transform @@ -12,6 +13,19 @@ def apply_transforms(path, node): return path +def compose_parent_transforms(node, mat): + # This is adapted from Inkscape's simpletransform.py's composeParents() + # function. That one can't handle nodes that are detached from a DOM. + + trans = node.get('transform') + if trans: + mat = simpletransform.composeTransform(simpletransform.parseTransform(trans), mat) + if node.getparent() is not None: + if node.getparent().tag == inkex.addNS('g', 'svg'): + mat = compose_parent_transforms(node.getparent(), mat) + return mat + + def get_node_transform(node): # start with the identity transform transform = [[1.0, 0.0, 0.0], [0.0, 1.0, 0.0]] @@ -19,7 +33,7 @@ def get_node_transform(node): # this if is because sometimes inkscape likes to create paths outside of a layer?! if node.getparent() is not None: # combine this node's transform with all parent groups' transforms - transform = simpletransform.composeParents(node, transform) + transform = compose_parent_transforms(node, transform) # add in the transform implied by the viewBox viewbox_transform = get_viewbox_transform(node.getroottree().getroot()) diff --git a/lib/svg/tags.py b/lib/svg/tags.py index 7eb87540..55352be2 100644 --- a/lib/svg/tags.py +++ b/lib/svg/tags.py @@ -14,5 +14,7 @@ CONNECTION_START = inkex.addNS('connection-start', 'inkscape') CONNECTION_END = inkex.addNS('connection-end', 'inkscape') CONNECTOR_TYPE = inkex.addNS('connector-type', 'inkscape') XLINK_HREF = inkex.addNS('href', 'xlink') +SODIPODI_NAMEDVIEW = inkex.addNS('namedview', 'sodipodi') +SODIPODI_GUIDE = inkex.addNS('guide', 'sodipodi') EMBROIDERABLE_TAGS = (SVG_PATH_TAG, SVG_POLYLINE_TAG) |
