Code

Fixed some extensions (.inx files) to cater for localization better and added two...
[inkscape.git] / share / extensions / dimension.py
1 #!/usr/bin/env python 
2 '''
3 dimension.py
4 An Inkscape effect for adding CAD style dimensions to selected objects
5 in a drawing.
7 It uses the selection's bounding box, so if the bounding box has empty
8 space in the x- or y-direction (such as with some stars) the results
9 will look strange.  Strokes might also overlap the edge of the 
10 bounding box.
12 The dimension arrows aren't measured: use the "Visualize Path/Measure
13 Path" effect to add measurements.
15 This code contains snippets from existing effects in the Inkscape
16 extensions library, and marker data from markers.svg.
18 Copyright (C) 2007 Peter Lewerin, peter.lewerin@tele2.se
20 This program is free software; you can redistribute it and/or modify
21 it under the terms of the GNU General Public License as published by
22 the Free Software Foundation; either version 2 of the License, or
23 (at your option) any later version.
25 This program is distributed in the hope that it will be useful,
26 but WITHOUT ANY WARRANTY; without even the implied warranty of
27 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
28 GNU General Public License for more details.
30 You should have received a copy of the GNU General Public License
31 along with this program; if not, write to the Free Software
32 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
33 '''
35 import sys, inkex, pathmodifier
36 from simpletransform import *
38 class Dimension(pathmodifier.PathModifier):
39     def __init__(self):
40         inkex.Effect.__init__(self)
41         self.OptionParser.add_option("-x", "--xoffset",
42                         action="store", type="float", 
43                         dest="xoffset", default=100.0,
44                         help="x offset of the vertical dimension arrow")    
45         self.OptionParser.add_option("-y", "--yoffset",
46                         action="store", type="float", 
47                         dest="yoffset", default=100.0,
48                         help="y offset of the horizontal dimension arrow")    
50     def addMarker(self, name, rotate):
51         defs = self.xpathSingle('/svg:svg//svg:defs')
52         if not defs:
53             defs = inkex.etree.SubElement(self.document.getroot(),inkex.addNS('defs','svg'))
54         marker = inkex.etree.SubElement(defs ,inkex.addNS('marker','svg'))
55         marker.set('id', name)
56         marker.set('orient', 'auto')
57         marker.set('refX', '0.0')
58         marker.set('refY', '0.0')
59         marker.set('style', 'overflow:visible')
60         marker.set('inkscape:stockid', name)
62         arrow = inkex.etree.Element("path")
63         arrow.set('d', 'M 0.0,0.0 L 5.0,-5.0 L -12.5,0.0 L 5.0,5.0 L 0.0,0.0 z ')
64         if rotate:
65                 arrow.set('transform', 'scale(0.8) rotate(180) translate(12.5,0)')
66         else:
67                 arrow.set('transform', 'scale(0.8) translate(12.5,0)')
68         arrow.set('style', 'fill-rule:evenodd;stroke:#000000;stroke-width:1.0pt;marker-start:none')
69         marker.append(arrow)
71     def dimHLine(self, y, xlat):
72         line = inkex.etree.Element("path")
73         x1 = self.bbox[0] - xlat[0] * self.xoffset
74         x2 = self.bbox[1]
75         y = y - xlat[1] * self.yoffset
76         line.set('d', 'M %f %f H %f' % (x1, y, x2))
77         return line
79     def dimVLine(self, x, xlat):
80         line = inkex.etree.Element("path")
81         x = x - xlat[0] * self.xoffset
82         y1 = self.bbox[2] - xlat[1] * self.yoffset
83         y2 = self.bbox[3]
84         line.set('d', 'M %f %f V %f' % (x, y1, y2))
85         return line
87     def effect(self):
88         self.xoffset = self.options.xoffset
89         self.yoffset = self.options.yoffset
91         self.bbox = computeBBox(self.selected.values())
93         # Avoid ugly failure on rects and texts.
94         try:
95                 testing_the_water = self.bbox[0]
96         except TypeError:
97                 sys.exit('Unable to process this object.  Try changing it into a path first.')
99         layer = self.current_layer
101         self.addMarker('Arrow1Lstart', False)
102         self.addMarker('Arrow1Lend',  True)
104         group = inkex.etree.Element("g")
105         group.set('fill', 'none')
106         group.set('stroke', 'black')
108         line = self.dimHLine(self.bbox[2], [0, 1])
109         line.set('marker-start', 'url(#Arrow1Lstart)')
110         line.set('marker-end', 'url(#Arrow1Lend)')
111         line.set('stroke-width', '1')
112         group.append(line)
114         line = self.dimVLine(self.bbox[0], [0, 2])
115         line.set('stroke-width', '0.5')
116         group.append(line)
117         
118         line = self.dimVLine(self.bbox[1], [0, 2])
119         line.set('stroke-width', '0.5')
120         group.append(line)
121         
122         line = self.dimVLine(self.bbox[0], [1, 0])
123         line.set('marker-start', 'url(#Arrow1Lstart)')
124         line.set('marker-end', 'url(#Arrow1Lend)')
125         line.set('stroke-width', '1')
126         group.append(line)
127         
128         line = self.dimHLine(self.bbox[2], [2, 0])
129         line.set('stroke-width', '0.5')
130         group.append(line)
132         line = self.dimHLine(self.bbox[3], [2, 0])
133         line.set('stroke-width', '0.5')
134         group.append(line)
136         for id, node in self.selected.iteritems():
137                 group.append(node)
138         
139         layer.append(group)
141 e = Dimension()
142 e.affect()