diff options
| -rw-r--r-- | share/extensions/dimension.inx | 24 | ||||
| -rw-r--r-- | share/extensions/dimension.py | 36 | ||||
| -rw-r--r-- | share/extensions/simpletransform.py | 41 |
3 files changed, 88 insertions, 13 deletions
diff --git a/share/extensions/dimension.inx b/share/extensions/dimension.inx index 114a3688e..cce244d4a 100644 --- a/share/extensions/dimension.inx +++ b/share/extensions/dimension.inx @@ -1,19 +1,23 @@ <?xml version="1.0" encoding="UTF-8"?> <inkscape-extension xmlns="http://www.inkscape.org/namespace/inkscape/extension"> - <_name>Dimensions</_name> - <id>se.lewerin.filter.dimension</id> + <_name>Dimensions</_name> + <id>se.lewerin.filter.dimension</id> <dependency type="executable" location="extensions">dimension.py</dependency> <dependency type="executable" location="extensions">inkex.py</dependency> <dependency type="executable" location="extensions">pathmodifier.py</dependency> <param name="xoffset" type="float" min="0" max="1000" _gui-text="X Offset">50</param> <param name="yoffset" type="float" min="0" max="1000" _gui-text="Y Offset">50</param> - <effect> + <param name="type" type="optiongroup" _gui-text="Bounding box type : "> + <_option value="geometric">Geometric</_option> + <_option value="visual">Visual</_option> + </param> + <effect> <object-type>path</object-type> - <effects-menu> - <submenu _name="Visualize Path"/> - </effects-menu> - </effect> - <script> - <command reldir="extensions" interpreter="python">dimension.py</command> - </script> + <effects-menu> + <submenu _name="Visualize Path"/> + </effects-menu> + </effect> + <script> + <command reldir="extensions" interpreter="python">dimension.py</command> + </script> </inkscape-extension> diff --git a/share/extensions/dimension.py b/share/extensions/dimension.py index cda3a96fd..1b84642ea 100644 --- a/share/extensions/dimension.py +++ b/share/extensions/dimension.py @@ -37,6 +37,12 @@ from simpletransform import * import gettext _ = gettext.gettext +try: + from subprocess import Popen, PIPE + bsubprocess = True +except: + bsubprocess = False + class Dimension(pathmodifier.PathModifier): def __init__(self): inkex.Effect.__init__(self) @@ -48,6 +54,10 @@ class Dimension(pathmodifier.PathModifier): action="store", type="float", dest="yoffset", default=100.0, help="y offset of the horizontal dimension arrow") + self.OptionParser.add_option("-t", "--type", + action="store", type="string", + dest="type", default="geometric", + help="Bounding box type") def addMarker(self, name, rotate): defs = self.xpathSingle('/svg:svg//svg:defs') @@ -90,7 +100,28 @@ class Dimension(pathmodifier.PathModifier): self.xoffset = self.options.xoffset self.yoffset = self.options.yoffset - self.bbox = computeBBox(self.selected.values()) + # query inkscape about the bounding box + if len(self.options.ids) == 0: + inkex.errormsg(_("Please select an object.")) + exit() + if self.options.type == "geometric": + self.bbox = computeBBox(self.selected.values()) + else: + q = {'x':0,'y':0,'width':0,'height':0} + file = self.args[-1] + id = self.options.ids[0] + for query in q.keys(): + if bsubprocess: + p = Popen('inkscape --query-%s --query-id=%s "%s"' % (query,id,file), shell=True, stdout=PIPE, stderr=PIPE) + rc = p.wait() + q[query] = float(p.stdout.read()) + err = p.stderr.read() + else: + f,err = os.popen3('inkscape --query-%s --query-id=%s "%s"' % (query,id,file))[1:] + q[query] = float(f.read()) + f.close() + err.close() + self.bbox = (q['x'], q['x']+q['width'], q['y'], q['y']+q['height']) # Avoid ugly failure on rects and texts. try: @@ -103,7 +134,8 @@ class Dimension(pathmodifier.PathModifier): self.addMarker('Arrow1Lstart', False) self.addMarker('Arrow1Lend', True) - group = inkex.etree.Element("g") + group = inkex.etree.SubElement(layer, 'g') + # group = inkex.etree.Element("g") group.set('fill', 'none') group.set('stroke', 'black') diff --git a/share/extensions/simpletransform.py b/share/extensions/simpletransform.py index c89d771ec..08aa4c55f 100644 --- a/share/extensions/simpletransform.py +++ b/share/extensions/simpletransform.py @@ -1,6 +1,7 @@ #!/usr/bin/env python ''' Copyright (C) 2006 Jean-Francois Barraud, barraud@math.univ-lille1.fr +Copyright (C) 2010 Alvin Penner, penner@vaxxine.com This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -142,6 +143,44 @@ def roughBBox(path): yMax = max(yMax,pt[1]) return xmin,xMax,ymin,yMax +def refinedBBox(path): + xmin,xMax,ymin,yMax = path[0][0][1][0],path[0][0][1][0],path[0][0][1][1],path[0][0][1][1] + for pathcomp in path: + for i in range(1, len(pathcomp)): + cmin, cmax = cubicExtrema(pathcomp[i-1][1][0], pathcomp[i-1][2][0], pathcomp[i][0][0], pathcomp[i][1][0]) + xmin = min(xmin, cmin) + xMax = max(xMax, cmax) + cmin, cmax = cubicExtrema(pathcomp[i-1][1][1], pathcomp[i-1][2][1], pathcomp[i][0][1], pathcomp[i][1][1]) + ymin = min(ymin, cmin) + yMax = max(yMax, cmax) + return xmin,xMax,ymin,yMax + +def cubicExtrema(y0, y1, y2, y3): + cmin = min(y0, y3) + cmax = max(y0, y3) + d1 = y1 - y0 + d2 = y2 - y1 + d3 = y3 - y2 + if (d1 - 2*d2 + d3): + if (d2*d2 > d1*d3): + t = (d1 - d2 + math.sqrt(d2*d2 - d1*d3))/(d1 - 2*d2 + d3) + if (t > 0) and (t < 1): + y = y0*(1-t)*(1-t)*(1-t) + 3*y1*t*(1-t)*(1-t) + 3*y2*t*t*(1-t) + y3*t*t*t + cmin = min(cmin, y) + cmax = max(cmax, y) + t = (d1 - d2 - math.sqrt(d2*d2 - d1*d3))/(d1 - 2*d2 + d3) + if (t > 0) and (t < 1): + y = y0*(1-t)*(1-t)*(1-t) + 3*y1*t*(1-t)*(1-t) + 3*y2*t*t*(1-t) + y3*t*t*t + cmin = min(cmin, y) + cmax = max(cmax, y) + elif (d3 - d1): + t = -d1/(d3 - d1) + if (t > 0) and (t < 1): + y = y0*(1-t)*(1-t)*(1-t) + 3*y1*t*(1-t)*(1-t) + 3*y2*t*t*(1-t) + y3*t*t*t + cmin = min(cmin, y) + cmax = max(cmax, y) + return cmin, cmax + def computeBBox(aList,mat=[[1,0,0],[0,1,0]]): bbox=None for node in aList: @@ -179,7 +218,7 @@ def computeBBox(aList,mat=[[1,0,0],[0,1,0]]): if d is not None: p = cubicsuperpath.parsePath(d) applyTransformToPath(m,p) - bbox=boxunion(roughBBox(p),bbox) + bbox=boxunion(refinedBBox(p),bbox) elif node.tag == inkex.addNS('use','svg') or node.tag=='use': refid=node.get(inkex.addNS('href','xlink')) |
