summaryrefslogtreecommitdiff
path: root/lib/svg
diff options
context:
space:
mode:
Diffstat (limited to 'lib/svg')
-rw-r--r--lib/svg/__init__.py1
-rw-r--r--lib/svg/guides.py43
-rw-r--r--lib/svg/path.py16
-rw-r--r--lib/svg/tags.py2
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)