Code

Super duper mega (fun!) commit: replaced encoding=utf-8 with fileencoding=utf-8 in...
[inkscape.git] / share / extensions / measure.py
index b37303f1b28cf972330f05285d45c183c0c201cf..147027fb6d8b971f747af3919554cad1a67505b8 100644 (file)
@@ -4,6 +4,7 @@ This extension module can measure arbitrary path and object length
 It adds a text to the selected path containing the length in a
 given unit.
 
+Copyright (C) 2010 Alvin Penner
 Copyright (C) 2006 Georg Wiora
 Copyright (C) 2006 Nathan Hurst
 Copyright (C) 2005 Aaron Spike, aaron@ekips.org
@@ -29,7 +30,7 @@ TODO:
     2. check direction >90 or <-90 Degrees
     3. rotate by 180 degrees around text center
 '''
-import inkex, simplestyle, simplepath,sys,cubicsuperpath, bezmisc, locale
+import inkex, simplestyle, simplepath, sys, cubicsuperpath, bezmisc, locale
 # Set current system locale
 locale.setlocale(locale.LC_ALL, '')
 
@@ -70,10 +71,33 @@ def csplength(csp):
             lengths[-1].append(l)
             total += l            
     return lengths, total
+def csparea(csp):
+    area = 0.0
+    n0 = 0.0
+    x0 = 0.0
+    y0 = 0.0
+    for sp in csp:
+        for i in range(len(sp)):            # calculate polygon area
+            area += 0.5*sp[i-1][1][0]*(sp[i][1][1] - sp[i-2][1][1])
+            if abs(sp[i-1][1][0]-sp[i][1][0]) > 0.001 or abs(sp[i-1][1][1]-sp[i][1][1]) > 0.001:
+                n0 += 1.0
+                x0 += sp[i][1][0]
+                y0 += sp[i][1][1]
+        for i in range(1, len(sp)):         # add contribution from cubic Bezier
+            bezarea  = ( 0.0*sp[i-1][1][1] + 2.0*sp[i-1][2][1] + 1.0*sp[i][0][1] - 3.0*sp[i][1][1])*sp[i-1][1][0]
+            bezarea += (-2.0*sp[i-1][1][1] + 0.0*sp[i-1][2][1] + 1.0*sp[i][0][1] + 1.0*sp[i][1][1])*sp[i-1][2][0]
+            bezarea += (-1.0*sp[i-1][1][1] - 1.0*sp[i-1][2][1] + 0.0*sp[i][0][1] + 2.0*sp[i][1][1])*sp[i][0][0]
+            bezarea += ( 3.0*sp[i-1][1][1] - 1.0*sp[i-1][2][1] - 2.0*sp[i][0][1] + 0.0*sp[i][1][1])*sp[i][1][0]
+            area += 0.15*bezarea
+    return abs(area), x0/n0, y0/n0
 
 class Length(inkex.Effect):
     def __init__(self):
         inkex.Effect.__init__(self)
+        self.OptionParser.add_option("--type",
+                        action="store", type="string", 
+                        dest="type", default="length",
+                        help="Type of measurement")
         self.OptionParser.add_option("-f", "--fontsize",
                         action="store", type="int", 
                         dest="fontsize", default=20,
@@ -115,40 +139,28 @@ class Length(inkex.Effect):
             if node.tag == inkex.addNS('path','svg'):
                 self.group = inkex.etree.SubElement(node.getparent(),inkex.addNS('text','svg'))
                 
-                t = node.get('transform')\r
-                if t:
-                    self.group.set('transform', t)
+                t = node.get('transform')
+                # Removed to fix LP #308183 
+                # (Measure Path text shifted when used with a copied object)
+                #if t:
+                #    self.group.set('transform', t)
 
 
                 a =[]
                 p = cubicsuperpath.parsePath(node.get('d'))
                 num = 1
-                slengths, stotal = csplength(p)
-                ''' Wio: Umrechnung in unit '''
-                if self.options.unit=="mm":
-                    factor=0.2822219  # px->mm
-                elif self.options.unit=="pt":
-                    factor=0.80       # px->pt
-                elif self.options.unit=="cm":
-                    factor=0.02822219 # px->cm
-                elif self.options.unit=="m":
-                    factor=0.0002822219 # px->m
-                elif self.options.unit=="km":
-                    factor=0.0000002822219 # px->km
-                elif self.options.unit=="in":
-                    factor=0.2822219/25.4 # px->in
-                elif self.options.unit=="ft":
-                    factor=0.2822219/(25.4*12) # px->ft
-                elif self.options.unit=="yd":
-                    factor=0.2822219/(25.4*36) # px->yd
-                else :
-                    ''' Default unit is px'''
-                    factor=1
-                    self.options.unit="px"
-                    
+                factor = 1.0/inkex.unittouu('1'+self.options.unit)
+                if self.options.type == "length":
+                    slengths, stotal = csplength(p)
+                else:
+                    stotal,x0,y0 = csparea(p)
+                    stotal *= factor*self.options.scale
                 # Format the length as string
                 lenstr = locale.format("%(len)25."+str(prec)+"f",{'len':round(stotal*factor*self.options.scale,prec)}).strip()
-                self.addTextOnPath(self.group,0, 0,lenstr+' '+self.options.unit, id, self.options.offset)
+                if self.options.type == "length":
+                    self.addTextOnPath(self.group,0, 0,lenstr+' '+self.options.unit, id, self.options.offset)
+                else:
+                    self.addTextWithTspan(self.group,x0,y0,lenstr+' '+self.options.unit+'^2', id, self.options.offset)
 
 
     def addTextOnPath(self,node,x,y,text, id,dy=0):
@@ -162,10 +174,28 @@ class Length(inkex.Effect):
                 new.set('startOffset', "50%")
                 new.set('dy', str(dy)) # dubious merit
                 #new.append(tp)
-                new.text = str(text)\r
-                #node.set('transform','rotate(180,'+str(-x)+','+str(-y)+')')\r
+                new.text = str(text)
+                #node.set('transform','rotate(180,'+str(-x)+','+str(-y)+')')
+                node.set('x', str(x))
+                node.set('y', str(y))
+
+    def addTextWithTspan(self,node,x,y,text,id,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': 'middle', '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(inkex.addNS('href','xlink'), '#'+id)
+                new.set('startOffset', "50%")
+                new.set('dy', str(dy))
+                new.text = str(text)
                 node.set('x', str(x))
                 node.set('y', str(y))
 
-e = Length()
-e.affect()
+if __name__ == '__main__':
+    e = Length()
+    e.affect()
+
+
+# vim: expandtab shiftwidth=4 tabstop=8 softtabstop=4 fileencoding=utf-8 textwidth=99