diff options
| author | Liam P. White <inkscapebronyat-signgmaildotcom> | 2014-04-03 02:15:12 +0000 |
|---|---|---|
| committer | Liam P. White <inkscapebronyat-signgmaildotcom> | 2014-04-03 02:15:12 +0000 |
| commit | b6f77fe152a8d73055c8484b2839ade02dc2a4bb (patch) | |
| tree | f48d65c27a9e2bb464d2f35eb9b2b4c29f59c34b | |
| parent | Fix some minor issues (diff) | |
| parent | Fix make check (diff) | |
| download | inkscape-b6f77fe152a8d73055c8484b2839ade02dc2a4bb.tar.gz inkscape-b6f77fe152a8d73055c8484b2839ade02dc2a4bb.zip | |
Update to trunk
(bzr r13090.1.45)
| -rw-r--r-- | po/POTFILES.in | 3 | ||||
| -rw-r--r-- | share/extensions/measure.inx | 7 | ||||
| -rwxr-xr-x | share/extensions/measure.py | 86 | ||||
| -rw-r--r-- | src/color-profile.cpp | 10 |
4 files changed, 78 insertions, 28 deletions
diff --git a/po/POTFILES.in b/po/POTFILES.in index af73041bd..082321236 100644 --- a/po/POTFILES.in +++ b/po/POTFILES.in @@ -1,6 +1,6 @@ # List of source files containing translatable strings. # Please keep this file sorted alphabetically. -# Generated by ./generate_POTFILES.sh at Fri Mar 28 00:52:30 CET 2014 +# Generated by ./generate_POTFILES.sh at Thu Apr 3 00:36:24 CEST 2014 [encoding: UTF-8] inkscape.desktop.in share/filters/filters.svg.h @@ -385,6 +385,7 @@ share/extensions/jessyInk_video.py share/extensions/jessyInk_view.py share/extensions/launch_webbrowser.py share/extensions/markers_strokepaint.py +share/extensions/measure.py share/extensions/pathalongpath.py share/extensions/pathmodifier.py share/extensions/pathscatter.py diff --git a/share/extensions/measure.inx b/share/extensions/measure.inx index cfbc3fce7..8fae020e0 100644 --- a/share/extensions/measure.inx +++ b/share/extensions/measure.inx @@ -9,6 +9,7 @@ <param name="type" type="enum" _gui-text="Measurement Type: "> <_item value="length">Length</_item> <_item msgctxt="measure extension" value="area">Area</_item> + <_item msgctxt="measure extension" value="cofm">Center of Mass</_item> </param> <param name="format" type="enum" _gui-text="Text Orientation: "> <_item msgctxt="measure extension" value="textonpath">Text On Path</_item> @@ -32,9 +33,9 @@ </param> </page> <page name="desc" _gui-text="Help"> - <_param name="measurehelp" type="description" xml:space="preserve">This effect measures the length, or area, of the selected paths and adds it as a text object with the selected units. - - * Display format can be either Text-On-Path, or stand-alone text at a specified angle. + <_param name="measurehelp" type="description" xml:space="preserve">This effect measures the length, area, or center-of-mass of the selected paths. Length and area are added as a text object with the selected units. Center-of-mass is shown as a cross symbol. + + * Text display format can be either Text-On-Path, or stand-alone text at a specified angle. * The number of significant digits can be controlled by the Precision field. * The Offset field controls the distance from the text to the path. * The Scale factor can be used to make measurements in scaled drawings. For example, if 1 cm in the drawing equals 2.5 m in the real world, Scale must be set to 250. diff --git a/share/extensions/measure.py b/share/extensions/measure.py index ca471816f..5c709594f 100755 --- a/share/extensions/measure.py +++ b/share/extensions/measure.py @@ -1,8 +1,9 @@ #!/usr/bin/env python ''' 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. +It adds text to the selected path containing the length in a given unit. +Area and Center of Mass calculated using Green's Theorem: +http://mathworld.wolfram.com/GreensTheorem.html Copyright (C) 2010 Alvin Penner Copyright (C) 2006 Georg Wiora @@ -30,10 +31,31 @@ TODO: 2. check direction >90 or <-90 Degrees 3. rotate by 180 degrees around text center ''' -import inkex, simplestyle, simplepath, simpletransform, sys, cubicsuperpath, bezmisc, locale -# Set current system locale +# standard library +import locale +# local library +import inkex +import simplestyle +import simpletransform +import cubicsuperpath +import bezmisc + +inkex.localize() locale.setlocale(locale.LC_ALL, '') +# third party +try: + import numpy +except: + inkex.errormsg(_("Failed to import the 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 command, sudo apt-get install python-numpy.")) + exit() + +mat_area = numpy.matrix([[ 0, 2, 1, -3],[ -2, 0, 1, 1],[ -1, -1, 0, 2],[ 3, -1, -2, 0]]) +mat_cofm_0 = numpy.matrix([[ 0, 35, 10,-45],[-35, 0, 12, 23],[-10,-12, 0, 22],[ 45,-23,-22, 0]]) +mat_cofm_1 = numpy.matrix([[ 0, 15, 3,-18],[-15, 0, 9, 6],[ -3, -9, 0, 12],[ 18, -6,-12, 0]]) +mat_cofm_2 = numpy.matrix([[ 0, 12, 6,-18],[-12, 0, 9, 3],[ -6, -9, 0, 15],[ 18, -3,-15, 0]]) +mat_cofm_3 = numpy.matrix([[ 0, 22, 23,-45],[-22, 0, 12, 10],[-23,-12, 0, 35],[ 45,-10,-35, 0]]) + def numsegs(csp): return sum([len(p)-1 for p in csp]) def interpcoord(v1,v2,p): @@ -69,20 +91,37 @@ def csplength(csp): for i in xrange(1,len(sp)): l = cspseglength(sp[i-1],sp[i]) lengths[-1].append(l) - total += l + total += l return lengths, total def csparea(csp): area = 0.0 for sp in csp: + if len(sp) < 2: continue 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]) 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) + vec_x = numpy.matrix([sp[i-1][1][0], sp[i-1][2][0], sp[i][0][0], sp[i][1][0]]) + vec_y = numpy.matrix([sp[i-1][1][1], sp[i-1][2][1], sp[i][0][1], sp[i][1][1]]) + area += 0.15*(vec_x*mat_area*vec_y.T)[0,0] + return -area # require positive area for CCW +def cspcofm(csp): + area = csparea(csp) + xc = 0.0 + yc = 0.0 + if abs(area) < 1.e-8: + inkex.errormsg(_("Area is zero, cannot calculate Center of Mass")) + return 0, 0 + for sp in csp: + for i in range(len(sp)): # calculate polygon moment + xc += sp[i-1][1][1]*(sp[i-2][1][0] - sp[i][1][0])*(sp[i-2][1][0] + sp[i-1][1][0] + sp[i][1][0])/6 + yc += sp[i-1][1][0]*(sp[i][1][1] - sp[i-2][1][1])*(sp[i-2][1][1] + sp[i-1][1][1] + sp[i][1][1])/6 + for i in range(1, len(sp)): # add contribution from cubic Bezier + vec_x = numpy.matrix([sp[i-1][1][0], sp[i-1][2][0], sp[i][0][0], sp[i][1][0]]) + vec_y = numpy.matrix([sp[i-1][1][1], sp[i-1][2][1], sp[i][0][1], sp[i][1][1]]) + vec_t = numpy.matrix([(vec_x*mat_cofm_0*vec_y.T)[0,0], (vec_x*mat_cofm_1*vec_y.T)[0,0], (vec_x*mat_cofm_2*vec_y.T)[0,0], (vec_x*mat_cofm_3*vec_y.T)[0,0]]) + xc += (vec_x*vec_t.T)[0,0]/280 + yc += (vec_y*vec_t.T)[0,0]/280 + return -xc/area, -yc/area def appendSuperScript(node, text): super = inkex.etree.SubElement(node, inkex.addNS('tspan', 'svg'), {'style': 'font-size:65%;baseline-shift:super'}) super.text = text @@ -133,12 +172,13 @@ class Length(inkex.Effect): self.OptionParser.add_option("--measurehelp", action="store", type="string", dest="measurehelp", default="", - help="dummy") - + help="dummy") + def effect(self): # get number of digits prec = int(self.options.precision) - self.options.offset *= self.unittouu('1px') + scale = self.unittouu('1px') # convert to document units + self.options.offset *= scale factor = 1.0 doc = self.document.getroot() if doc.get('viewBox'): @@ -150,16 +190,21 @@ class Length(inkex.Effect): # loop over all selected paths for id, node in self.selected.iteritems(): if node.tag == inkex.addNS('path','svg'): - self.group = inkex.etree.SubElement(node.getparent(),inkex.addNS('text','svg')) - a =[] 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) - factor *= self.unittouu('1px')/self.unittouu('1'+self.options.unit) + factor *= scale/self.unittouu('1'+self.options.unit) if self.options.type == "length": slengths, stotal = csplength(p) - else: + self.group = inkex.etree.SubElement(node.getparent(),inkex.addNS('text','svg')) + elif self.options.type == "area": stotal = csparea(p)*factor*self.options.scale + self.group = inkex.etree.SubElement(node.getparent(),inkex.addNS('text','svg')) + else: + xc, yc = cspcofm(p) + self.group = inkex.etree.SubElement(node.getparent(),inkex.addNS('path','svg')) + self.addCross(self.group, xc, yc, scale) + continue # Format the length as string lenstr = locale.format("%(len)25."+str(prec)+"f",{'len':round(stotal*factor*self.options.scale,prec)}).strip() if self.options.format == 'textonpath': @@ -173,6 +218,11 @@ class Length(inkex.Effect): else: self.addTextWithTspan(self.group, p[0][0][1][0], p[0][0][1][1], lenstr+' '+self.options.unit+'^2', id, 'start', -int(self.options.angle), -self.options.offset + self.options.fontsize/2) + def addCross(self, node, x, y, scale): + l = 3*scale # 3 pixels in document units + node.set('d', 'm %s,%s %s,0 m %s,%s 0,%s' % (str(x-l), str(y), str(2*l), str(-l), str(-l), str(2*l))) + node.set('style', 'stroke:#000000;stroke-width:%s' % str(0.5*scale)) + def addTextOnPath(self, node, x, y, text, id, anchor, startOffset, dy = 0): new = inkex.etree.SubElement(node,inkex.addNS('textPath','svg')) s = {'text-align': 'center', 'vertical-align': 'bottom', diff --git a/src/color-profile.cpp b/src/color-profile.cpp index ed4b9029e..aa0750c00 100644 --- a/src/color-profile.cpp +++ b/src/color-profile.cpp @@ -322,17 +322,15 @@ void ColorProfile::set(unsigned key, gchar const *value) { } //# 1. Get complete URI of document gchar const *docbase = doc->getURI(); - if (!docbase) - { - // Normal for files that have not yet been saved. - docbase = ""; - } gchar* escaped = g_uri_escape_string(this->href, "!*'();:@=+$,/?#[]", TRUE); //g_message("docbase:%s\n", docbase); //org::w3c::dom::URI docUri(docbase); - Inkscape::URI docUri(docbase); + Inkscape::URI docUri(""); + if (docbase) { // The file has already been saved + docUri = Inkscape::URI::from_native_filename(docbase); + } //# 2. Get href of icc file. we don't care if it's rel or abs //org::w3c::dom::URI hrefUri(escaped); |
