summaryrefslogtreecommitdiff
path: root/lib/svg
diff options
context:
space:
mode:
Diffstat (limited to 'lib/svg')
-rw-r--r--lib/svg/guides.py8
-rw-r--r--lib/svg/path.py29
-rw-r--r--lib/svg/rendering.py59
-rw-r--r--lib/svg/svg.py3
-rw-r--r--lib/svg/tags.py5
-rw-r--r--lib/svg/units.py25
6 files changed, 66 insertions, 63 deletions
diff --git a/lib/svg/guides.py b/lib/svg/guides.py
index 3e26a90d..255b3e6a 100644
--- a/lib/svg/guides.py
+++ b/lib/svg/guides.py
@@ -1,7 +1,7 @@
-import simpletransform
+from inkex import transforms
-from ..utils import string_to_floats, Point, cache
-from .tags import SODIPODI_NAMEDVIEW, SODIPODI_GUIDE, INKSCAPE_LABEL
+from ..utils import Point, cache, string_to_floats
+from .tags import INKSCAPE_LABEL, SODIPODI_GUIDE, SODIPODI_NAMEDVIEW
from .units import get_doc_size, get_viewbox_transform
@@ -19,7 +19,7 @@ class InkscapeGuide(object):
# 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)
+ viewbox_transform = transforms.Transform(-transforms.Transform(viewbox_transform)).apply_to_point(doc_size)
self.position = Point(*string_to_floats(self.node.get('position')))
diff --git a/lib/svg/path.py b/lib/svg/path.py
index cc4b8cbb..baa93443 100644
--- a/lib/svg/path.py
+++ b/lib/svg/path.py
@@ -1,8 +1,7 @@
-import cubicsuperpath
import inkex
-import simpletransform
-from tags import SVG_GROUP_TAG, SVG_LINK_TAG
+from lxml import etree
+from .tags import SVG_GROUP_TAG, SVG_LINK_TAG
from .units import get_viewbox_transform
@@ -10,7 +9,7 @@ def apply_transforms(path, node):
transform = get_node_transform(node)
# apply the combined transform to this node's path
- simpletransform.applyTransformToPath(transform, path)
+ path = path.transform(transform)
return path
@@ -21,7 +20,7 @@ def compose_parent_transforms(node, mat):
trans = node.get('transform')
if trans:
- mat = simpletransform.composeTransform(simpletransform.parseTransform(trans), mat)
+ mat = inkex.transforms.Transform(trans) * mat
if node.getparent() is not None:
if node.getparent().tag in [SVG_GROUP_TAG, SVG_LINK_TAG]:
mat = compose_parent_transforms(node.getparent(), mat)
@@ -29,20 +28,22 @@ def compose_parent_transforms(node, mat):
def get_node_transform(node):
+ """
+ if getattr(node, "composed_transform", None):
+ return node.composed_transform()
+ """
+
# start with the identity transform
- transform = [[1.0, 0.0, 0.0], [0.0, 1.0, 0.0]]
+ transform = inkex.transforms.Transform([[1.0, 0.0, 0.0], [0.0, 1.0, 0.0]])
# 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 = compose_parent_transforms(node, transform)
- if node.get('id', '').startswith('clone_'):
- transform = simpletransform.parseTransform(node.get('transform', ''))
-
# add in the transform implied by the viewBox
viewbox_transform = get_viewbox_transform(node.getroottree().getroot())
- transform = simpletransform.composeTransform(viewbox_transform, transform)
+ transform = viewbox_transform * transform
return transform
@@ -63,9 +64,9 @@ def get_correction_transform(node, child=False):
# now invert it, so that we can position our objects in absolute
# coordinates
- transform = simpletransform.invertTransform(transform)
+ transform = -transform
- return simpletransform.formatTransform(transform)
+ return str(transform)
def line_strings_to_csp(line_strings):
@@ -90,6 +91,6 @@ def point_lists_to_csp(point_lists):
def line_strings_to_path(line_strings):
csp = line_strings_to_csp(line_strings)
- return inkex.etree.Element("path", {
- "d": cubicsuperpath.formatPath(csp)
+ return etree.Element("path", {
+ "d": str(inkex.paths.CubicSuperPath(csp))
})
diff --git a/lib/svg/rendering.py b/lib/svg/rendering.py
index 5860ceef..ced7d4f1 100644
--- a/lib/svg/rendering.py
+++ b/lib/svg/rendering.py
@@ -1,9 +1,8 @@
import math
import inkex
-import simplepath
-import simplestyle
-import simpletransform
+from lxml import etree
+from math import pi
from ..i18n import _
from ..utils import Point, cache
@@ -116,24 +115,25 @@ def realistic_stitch(start, end):
start = Point(*start)
stitch_length = (end - start).length()
- stitch_center = (end + start) / 2.0
+ stitch_center = Point((end.x+start.x)/2.0, (end[1]+start[1])/2.0)
stitch_direction = (end - start)
- stitch_angle = math.atan2(stitch_direction.y, stitch_direction.x)
+ stitch_angle = math.atan2(stitch_direction.y, stitch_direction.x) * (180 / pi)
stitch_length = max(0, stitch_length - 0.2 * PIXELS_PER_MM)
# create the path by filling in the length in the template
- path = simplepath.parsePath(stitch_path % stitch_length)
+ path = inkex.Path(stitch_path % stitch_length).to_arrays()
# rotate the path to match the stitch
rotation_center_x = -stitch_length / 2.0
rotation_center_y = stitch_height / 2.0
- simplepath.rotatePath(path, stitch_angle, cx=rotation_center_x, cy=rotation_center_y)
+
+ path = inkex.Path(path).rotate(stitch_angle, (rotation_center_x, rotation_center_y))
# move the path to the location of the stitch
- simplepath.translatePath(path, stitch_center.x - rotation_center_x, stitch_center.y - rotation_center_y)
+ path = inkex.Path(path).translate(stitch_center.x - rotation_center_x, stitch_center.y - rotation_center_y)
- return simplepath.formatPath(path)
+ return str(path)
def color_block_to_point_lists(color_block):
@@ -159,10 +159,9 @@ def get_correction_transform(svg):
transform = get_viewbox_transform(svg)
# we need to correct for the viewbox
- transform = simpletransform.invertTransform(transform)
- transform = simpletransform.formatTransform(transform)
+ transform = -inkex.transforms.Transform(transform)
- return transform
+ return str(transform)
def color_block_to_realistic_stitches(color_block, svg, destination):
@@ -170,12 +169,8 @@ def color_block_to_realistic_stitches(color_block, svg, destination):
color = color_block.color.visible_on_white.darker.to_hex_str()
start = point_list[0]
for point in point_list[1:]:
- destination.append(inkex.etree.Element(SVG_PATH_TAG, {
- 'style': simplestyle.formatStyle({
- 'fill': color,
- 'stroke': 'none',
- 'filter': 'url(#realistic-stitch-filter)'
- }),
+ destination.append(etree.Element(SVG_PATH_TAG, {
+ 'style': "fill: %s; stroke: none; filter: url(#realistic-stitch-filter);" % color,
'd': realistic_stitch(start, point),
'transform': get_correction_transform(svg)
}))
@@ -200,12 +195,8 @@ def color_block_to_paths(color_block, svg, destination, visual_commands):
color = color_block.color.visible_on_white.to_hex_str()
- path = inkex.etree.Element(SVG_PATH_TAG, {
- 'style': simplestyle.formatStyle({
- 'stroke': color,
- 'stroke-width': "0.4",
- 'fill': 'none'
- }),
+ path = etree.Element(SVG_PATH_TAG, {
+ 'style': "stroke: %s; stroke-width: 0.4; fill: none;" % color,
'd': "M" + " ".join(" ".join(str(coord) for coord in point) for point in point_list),
'transform': get_correction_transform(svg),
INKSTITCH_ATTRIBS['manual_stitch']: 'true'
@@ -223,10 +214,10 @@ def color_block_to_paths(color_block, svg, destination, visual_commands):
def render_stitch_plan(svg, stitch_plan, realistic=False, visual_commands=True):
layer = svg.find(".//*[@id='__inkstitch_stitch_plan__']")
if layer is None:
- layer = inkex.etree.Element(SVG_GROUP_TAG,
- {'id': '__inkstitch_stitch_plan__',
- INKSCAPE_LABEL: _('Stitch Plan'),
- INKSCAPE_GROUPMODE: 'layer'})
+ layer = etree.Element(SVG_GROUP_TAG,
+ {'id': '__inkstitch_stitch_plan__',
+ INKSCAPE_LABEL: _('Stitch Plan'),
+ INKSCAPE_GROUPMODE: 'layer'})
else:
# delete old stitch plan
del layer[:]
@@ -237,10 +228,10 @@ def render_stitch_plan(svg, stitch_plan, realistic=False, visual_commands=True):
svg.append(layer)
for i, color_block in enumerate(stitch_plan):
- group = inkex.etree.SubElement(layer,
- SVG_GROUP_TAG,
- {'id': '__color_block_%d__' % i,
- INKSCAPE_LABEL: "color block %d" % (i + 1)})
+ group = etree.SubElement(layer,
+ SVG_GROUP_TAG,
+ {'id': '__color_block_%d__' % i,
+ INKSCAPE_LABEL: "color block %d" % (i + 1)})
if realistic:
color_block_to_realistic_stitches(color_block, svg, group)
else:
@@ -250,6 +241,6 @@ def render_stitch_plan(svg, stitch_plan, realistic=False, visual_commands=True):
defs = svg.find(SVG_DEFS_TAG)
if defs is None:
- defs = inkex.etree.SubElement(svg, SVG_DEFS_TAG)
+ defs = etree.SubElement(svg, SVG_DEFS_TAG)
- defs.append(inkex.etree.fromstring(realistic_filter))
+ defs.append(etree.fromstring(realistic_filter))
diff --git a/lib/svg/svg.py b/lib/svg/svg.py
index 3cf7f017..1a6b10e8 100644
--- a/lib/svg/svg.py
+++ b/lib/svg/svg.py
@@ -1,4 +1,5 @@
-from inkex import NSS, etree
+from inkex import NSS
+from lxml import etree
from ..utils import cache
diff --git a/lib/svg/tags.py b/lib/svg/tags.py
index 810924a6..6fa47aa0 100644
--- a/lib/svg/tags.py
+++ b/lib/svg/tags.py
@@ -1,10 +1,9 @@
import inkex
+from lxml import etree
-
-# This is used below and added to the document in ../extensions/base.py.
+etree.register_namespace("inkstitch", "http://inkstitch.org/namespace")
inkex.NSS['inkstitch'] = 'http://inkstitch.org/namespace'
-
SVG_PATH_TAG = inkex.addNS('path', 'svg')
SVG_POLYLINE_TAG = inkex.addNS('polyline', 'svg')
SVG_RECT_TAG = inkex.addNS('rect', 'svg')
diff --git a/lib/svg/units.py b/lib/svg/units.py
index 319e018b..6f16d7fb 100644
--- a/lib/svg/units.py
+++ b/lib/svg/units.py
@@ -1,4 +1,4 @@
-import simpletransform
+import inkex
from ..i18n import _
from ..utils import cache
@@ -6,10 +6,14 @@ from ..utils import cache
# modern versions of Inkscape use 96 pixels per inch as per the CSS standard
PIXELS_PER_MM = 96 / 25.4
-# cribbed from inkscape-silhouette
-
def parse_length_with_units(str):
+ value, unit = inkex.units.parse_unit(str)
+ if not unit:
+ raise ValueError(_("parseLengthWithUnits: unknown unit %s") % str)
+ return value, unit
+
+ """
'''
Parse an SVG value which may or may not have units attached
This version is greatly simplified in that it only allows: no units,
@@ -18,6 +22,8 @@ def parse_length_with_units(str):
generality is ever needed.
'''
+ # cribbed from inkscape-silhouette
+
u = 'px'
s = str.strip()
if s[-2:] == 'px':
@@ -46,11 +52,15 @@ def parse_length_with_units(str):
raise ValueError(_("parseLengthWithUnits: unknown unit %s") % s)
return v, u
+ """
def convert_length(length):
value, units = parse_length_with_units(length)
+ return inkex.units.convert_unit(str(value) + units, 'px')
+
+ """
if not units or units == "px":
return value
@@ -67,7 +77,7 @@ def convert_length(length):
units = 'mm'
if units == 'mm':
- value = value / 25.4
+ value /= 25.4
units = 'in'
if units == 'in':
@@ -76,6 +86,7 @@ def convert_length(length):
return value * 96
raise ValueError(_("Unknown unit: %s") % units)
+ """
@cache
@@ -121,7 +132,7 @@ def get_viewbox_transform(node):
dx = -float(viewbox[0])
dy = -float(viewbox[1])
- transform = simpletransform.parseTransform("translate(%f, %f)" % (dx, dy))
+ transform = inkex.transforms.Transform("translate(%f, %f)" % (dx, dy))
try:
sx = doc_width / float(viewbox[2])
@@ -132,8 +143,8 @@ def get_viewbox_transform(node):
if aspect_ratio != 'none':
sx = sy = max(sx, sy) if 'slice' in aspect_ratio else min(sx, sy)
- scale_transform = simpletransform.parseTransform("scale(%f, %f)" % (sx, sy))
- transform = simpletransform.composeTransform(transform, scale_transform)
+ scale_transform = inkex.transforms.Transform("scale(%f, %f)" % (sx, sy))
+ transform = transform * scale_transform
except ZeroDivisionError:
pass