-
Notifications
You must be signed in to change notification settings - Fork 0
/
areas.py
executable file
·118 lines (102 loc) · 4.41 KB
/
areas.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
#! /usr/bin/python
'''
This extension module measures path areas.
'''
# standard library
import locale
import re
# local library
import inkex
import simpletransform
import cubicsuperpath
import measure # TODO drop
import simplestyle
# Turns debugging output on - Use debug = False to turn debugging output 'off'
# debug = inkex.debug
debug = lambda x: None
nspath = inkex.addNS('path','svg')
# On darwin, fall back to C in cases of
# - incorrect locale IDs (see comments in bug #406662)
# - https://bugs.python.org/issue18378
try:
locale.setlocale(locale.LC_ALL, '')
except locale.Error:
locale.setlocale(locale.LC_ALL, 'C')
# Initialize gettext for messages outside an inkex derived class
inkex.localize()
# third party
try:
import numpy
import svgwrite
import svgpathtools
except:
inkex.errormsg(_("Failed to import the svgpathtools, svgwrite and numpy modules. These modules are required by this extension. Please install them and try again. On a Debian-like system this can be done with the commands: `sudo apt-get install python-numpy; sudo pip install svgpathtools svgwrite`."))
exit()
class Areas(inkex.Effect):
def __init__(self):
inkex.Effect.__init__(self)
self.OptionParser.add_option("--tab",
action="store", type="string",
dest="tab", default="sampling",
help="The selected UI-tab when OK was pressed")
def effect(self):
# if self.options.mformat == '"presets"':
# self.setPreset()
# njj: hack some options
# get number of digits
# prec = int(self.options.precision)
prec = 2
self.options.fontsize = 20
self.options.unit = 'mm'
self.options.scale = 1
self.options.angle = 0
self.options.offset = -6
scale = self.unittouu('1px') # convert to document units
# self.options.offset *= scale
factor = 1.0
doc = self.document.getroot()
if doc.get('viewBox'):
(viewx, viewy, vieww, viewh) = re.sub(' +|, +|,',' ',doc.get('viewBox')).strip().split(' ', 4)
factor = self.unittouu(doc.get('width'))/float(vieww)
if self.unittouu(doc.get('height'))/float(viewh) < factor:
factor = self.unittouu(doc.get('height'))/float(viewh)
factor /= self.unittouu('1px')
self.options.fontsize /= factor
factor *= scale/self.unittouu('1'+self.options.unit)
# Gather paths
debug(dir(self))
paths = self.document.findall('.//{0}'.format(nspath))
# Act on paths
for node in paths:
mat = simpletransform.composeParents(node, [[1.0, 0.0, 0.0], [0.0, 1.0, 0.0]])
p = cubicsuperpath.parsePath(node.get('d'))
simpletransform.applyTransformToPath(mat, p)
stotal = abs(measure.csparea(p)*factor*self.options.scale)
self.group = inkex.etree.SubElement(node.getparent(),inkex.addNS('text','svg'))
# Format the area as string
resultstr = locale.format("%(len)25."+str(prec)+"f",{'len':round(stotal*factor*self.options.scale,prec)}).strip()
# Fixed text, in the center of each path
bbox = simpletransform.computeBBox([node])
tx = bbox[0] + (bbox[1] - bbox[0])/2.0
ty = bbox[2] + (bbox[3] - bbox[2])/2.0
anchor = 'middle'
self.addTextWithTspan(self.group, tx, ty, resultstr+' '+self.options.unit+'^2', id, anchor, -int(self.options.angle), -self.options.offset + self.options.fontsize/2)
def addTextWithTspan(self, node, x, y, text, id, anchor, angle, dy = 0):
new = inkex.etree.SubElement(node,inkex.addNS('tspan','svg'), {inkex.addNS('role','sodipodi'): 'line'})
s = {'text-align': 'center', 'vertical-align': 'bottom',
'text-anchor': anchor, 'font-size': str(self.options.fontsize),
'fill-opacity': '1.0', 'stroke': 'none',
'font-weight': 'normal', 'font-style': 'normal', 'fill': '#000000'}
new.set('style', simplestyle.formatStyle(s))
new.set('dy', str(dy))
if text[-2:] == "^2":
measure.appendSuperScript(new, "2")
new.text = str(text)[:-2]
else:
new.text = str(text)
node.set('x', str(x))
node.set('y', str(y))
node.set('transform', 'rotate(%s, %s, %s)' % (angle, x, y))
if __name__ == '__main__':
e = Areas()
e.affect()