This repository has been archived on 2023-03-25. You can view files and clone it, but cannot push or open issues or pull requests.
mightyscape-0.92-deprecated/fablabchemnitz_applytransform.py
2019-11-14 20:05:10 +01:00

116 lines
3.9 KiB
Python

#!/usr/bin/env python2
#
# License: GPL2
# Copyright Mark "Klowner" Riedesel
# https://github.com/Klowner/inkscape-applytransforms
#
import sys
sys.path.append('/usr/share/inkscape/extensions')
import inkex
import cubicsuperpath
import math
import simplestyle
from simpletransform import composeTransform, fuseTransform, parseTransform, applyTransformToPath, applyTransformToPoint, formatTransform
class ApplyTransform(inkex.Effect):
def __init__(self):
inkex.Effect.__init__(self)
def effect(self):
self.getselected()
if self.selected:
for id, shape in self.selected.items():
self.recursiveFuseTransform(shape, parseTransform(None))
else:
self.recursiveFuseTransform(self.document.getroot(), parseTransform(None))
@staticmethod
def objectToPath(node):
if node.tag == inkex.addNS('g', 'svg'):
return node
if node.tag == inkex.addNS('path', 'svg') or node.tag == 'path':
for attName in node.attrib.keys():
if ("sodipodi" in attName) or ("inkscape" in attName):
del node.attrib[attName]
return node
return node
def scaleStrokeWidth(self, node, transf):
if 'style' in node.attrib:
style = node.attrib.get('style')
style = simplestyle.parseStyle(style)
update = False
if 'stroke-width' in style:
try:
stroke_width = self.unittouu(style.get('stroke-width').strip())
# pixelsnap ext assumes scaling is similar in x and y
# and uses the x scale...
# let's try to be a bit smarter
# the least terrible option is using the geometric mean
stroke_width *= math.sqrt(transf[0][0] * transf[1][1])
style['stroke-width'] = str(stroke_width)
update = True
except AttributeError:
pass
if update:
style = simplestyle.formatStyle(style)
node.attrib['style'] = style
def recursiveFuseTransform(self, node, transf=[[1.0, 0.0, 0.0], [0.0, 1.0, 0.0]]):
transf = composeTransform(transf, parseTransform(node.get("transform", None)))
if 'transform' in node.attrib:
del node.attrib['transform']
node = ApplyTransform.objectToPath(node)
if 'd' in node.attrib:
d = node.get('d')
p = cubicsuperpath.parsePath(d)
applyTransformToPath(transf, p)
node.set('d', cubicsuperpath.formatPath(p))
self.scaleStrokeWidth(node, transf)
elif node.tag in [inkex.addNS('polygon', 'svg'),
inkex.addNS('polyline', 'svg')]:
points = node.get('points')
points = points.strip().split(' ')
for k,p in enumerate(points):
if ',' in p:
p = p.split(',')
p = [float(p[0]),float(p[1])]
applyTransformToPoint(transf, p)
p = [str(p[0]),str(p[1])]
p = ','.join(p)
points[k] = p
points = ' '.join(points)
node.set('points', points)
self.scaleStrokeWidth(node, transf)
elif node.tag in [inkex.addNS('rect', 'svg'),
inkex.addNS('text', 'svg'),
inkex.addNS('image', 'svg'),
inkex.addNS('use', 'svg'),
inkex.addNS('circle', 'svg')]:
node.set('transform', formatTransform(transf))
else:
# e.g. <g style="...">
self.scaleStrokeWidth(node, transf)
for child in node.getchildren():
self.recursiveFuseTransform(child, transf)
if __name__ == '__main__':
e = ApplyTransform()
e.affect()