diff options
| author | Krzysztof Kosi??ski <tweenk.pl@gmail.com> | 2010-08-08 17:27:51 +0000 |
|---|---|---|
| committer | Krzysztof KosiĆski <tweenk.pl@gmail.com> | 2010-08-08 17:27:51 +0000 |
| commit | 60d3113d1f022a3de7cf04c7979d4751b3fe21f6 (patch) | |
| tree | ca33e2a9a1af6b5911598fa1c6a1d77087b71dd2 /share/extensions | |
| parent | Minor cleanups (diff) | |
| parent | Add a constrained snap method that takes multiple constraints. This reduces t... (diff) | |
| download | inkscape-60d3113d1f022a3de7cf04c7979d4751b3fe21f6.tar.gz inkscape-60d3113d1f022a3de7cf04c7979d4751b3fe21f6.zip | |
merge from trunk
(bzr r9508.1.52)
Diffstat (limited to 'share/extensions')
| -rw-r--r-- | share/extensions/dimension.inx | 24 | ||||
| -rw-r--r-- | share/extensions/dimension.py | 36 | ||||
| -rw-r--r-- | share/extensions/dxf_input.inx | 2 | ||||
| -rw-r--r-- | share/extensions/dxf_input.py | 43 | ||||
| -rwxr-xr-x | share/extensions/dxf_outlines.py | 113 | ||||
| -rw-r--r-- | share/extensions/dxf_templates.py | 33 | ||||
| -rw-r--r-- | share/extensions/funcplot.py | 12 | ||||
| -rw-r--r-- | share/extensions/generate_voronoi.py | 8 | ||||
| -rw-r--r-- | share/extensions/hpgl_output.py | 68 | ||||
| -rw-r--r-- | share/extensions/inkscape_help_keys.inx | 2 | ||||
| -rw-r--r-- | share/extensions/inkscape_help_relnotes.inx | 2 | ||||
| -rw-r--r-- | share/extensions/simpletransform.py | 41 | ||||
| -rw-r--r-- | share/extensions/uniconv-ext.py | 6 | ||||
| -rw-r--r-- | share/extensions/uniconv_output.py | 2 |
14 files changed, 268 insertions, 124 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/dxf_input.inx b/share/extensions/dxf_input.inx index 70aae46d5..c5cc4da0c 100644 --- a/share/extensions/dxf_input.inx +++ b/share/extensions/dxf_input.inx @@ -8,6 +8,7 @@ <page name="options" _gui-text="Options"> <param name="auto" type="boolean" _gui-text="Use automatic scaling to size A4">true</param> <param name="scale" type="string" _gui-text="Or, use manual scale factor">1.0</param> + <param name="gcodetoolspoints" type="boolean" _gui-text="Gcodetools compatible point import">false</param> <param name="sep1" type="description">-------------------------------------------------------------------------</param> <param name="encoding" type="enum" _gui-text="Character Encoding"> <item value="latin_1">Latin 1</item> @@ -15,6 +16,7 @@ <item value="cp1252">CP 1252</item> <item value="utf_8">UTF 8</item> </param> + <param name="font" type="string" _gui-text="Text Font">Arial</param> </page> <page name="help" _gui-text="Help"> <_param name="inputhelp" type="description" xml:space="preserve">- AutoCAD Release 13 and newer. diff --git a/share/extensions/dxf_input.py b/share/extensions/dxf_input.py index 7c5e4d0f9..f92b1ee82 100644 --- a/share/extensions/dxf_input.py +++ b/share/extensions/dxf_input.py @@ -35,7 +35,7 @@ def export_MTEXT(): size = 12 # default fontsize in px if vals[groups['40']]: size = scale*vals[groups['40']][0] - attribs = {'x': '%f' % x, 'y': '%f' % y, 'style': 'font-size: %.1fpx; fill: %s' % (size, color)} + attribs = {'x': '%f' % x, 'y': '%f' % y, 'style': 'font-size: %.1fpx; fill: %s; font-family: %s' % (size, color, options.font)} angle = 0 # default angle in degrees if vals[groups['50']]: angle = vals[groups['50']][0] @@ -65,7 +65,10 @@ def export_MTEXT(): def export_POINT(): # mandatory group codes : (10, 20) (x, y) if vals[groups['10']] and vals[groups['20']]: - generate_ellipse(vals[groups['10']][0], vals[groups['20']][0], w/2, 0.0, 1.0, 0.0, 0.0) + if options.gcodetoolspoints: + generate_gcodetools_point(vals[groups['10']][0], vals[groups['20']][0]) + else: + generate_ellipse(vals[groups['10']][0], vals[groups['20']][0], w/2, 0.0, 1.0, 0.0, 0.0) def export_LINE(): # mandatory group codes : (10, 11, 20, 21) (x1, x2, y1, y2) @@ -118,6 +121,10 @@ def export_LWPOLYLINE(): # optional group codes : (42) (bulge) iseqs = 0 ibulge = 0 + if vals[groups['70']][0] == 1: # closed path + seqs.append('20') + vals[groups['10']].append(vals[groups['10']][0]) + vals[groups['20']].append(vals[groups['20']][0]) while seqs[iseqs] != '20': iseqs += 1 path = 'M %f,%f' % (vals[groups['10']][0], vals[groups['20']][0]) @@ -154,7 +161,7 @@ def export_LWPOLYLINE(): def export_HATCH(): # mandatory group codes : (10, 20, 70, 72, 92, 93) (x, y, fill, Edge Type, Path Type, Number of edges) if vals[groups['10']] and vals[groups['20']] and vals[groups['70']] and vals[groups['72']] and vals[groups['92']] and vals[groups['93']]: - if vals[groups['70']][0] and len(vals[groups['10']]) > 1 and len(vals[groups['20']]) == len(vals[groups['10']]): + if len(vals[groups['10']]) > 1 and len(vals[groups['20']]) == len(vals[groups['10']]): # optional group codes : (11, 21, 40, 50, 51, 73) (x, y, r, angle1, angle2, CCW) i10 = 1 # count start points i11 = 0 # count line end points @@ -198,7 +205,10 @@ def export_HATCH(): i72 += 1 i10 += 1 path += "z " - style = simplestyle.formatStyle({'fill': '%s' % color}) + if vals[groups['70']][0]: + style = simplestyle.formatStyle({'fill': '%s' % color}) + else: + style = simplestyle.formatStyle({'fill': 'url(#Hatch)', 'fill-opacity': '1.0'}) attribs = {'d': path, 'style': style} inkex.etree.SubElement(layer, 'path', attribs) @@ -217,7 +227,7 @@ def export_DIMENSION(): path = 'M %f,%f %f,%f' % (vals[groups['10']][0], vals[groups['20']][0], vals[groups['10']][0], vals[groups['23']][0]) else: return - attribs = {'d': path, 'style': style + '; marker-start: url(#DistanceX); marker-end: url(#DistanceX)'} + attribs = {'d': path, 'style': style + '; marker-start: url(#DistanceX); marker-end: url(#DistanceX); stroke-width: 0.25px'} inkex.etree.SubElement(layer, 'path', attribs) x = scale*(vals[groups['11']][0] - xmin) y = - scale*(vals[groups['21']][0] - ymax) @@ -227,7 +237,7 @@ def export_DIMENSION(): size = scale*DIMTXT[vals[groups['3']][0]] if size < 2: size = 2 - attribs = {'x': '%f' % x, 'y': '%f' % y, 'style': 'font-size: %.1fpx; fill: %s' % (size, color)} + attribs = {'x': '%f' % x, 'y': '%f' % y, 'style': 'font-size: %.1fpx; fill: %s; font-family: %s; text-anchor: middle; text-align: center' % (size, color, options.font)} if dx == 0: attribs.update({'transform': 'rotate (%f %f %f)' % (-90, x, y)}) node = inkex.etree.SubElement(layer, 'text', attribs) @@ -280,6 +290,11 @@ def generate_ellipse(xc, yc, xm, ym, w, a1, a2): attribs = {'d': path, 'style': style} inkex.etree.SubElement(layer, 'path', attribs) +def generate_gcodetools_point(xc, yc): + path= 'm %s,%s 2.9375,-6.34375 0.8125,1.90625 6.84375,-6.84375 0,0 0.6875,0.6875 -6.84375,6.84375 1.90625,0.8125 z' % (xc,yc) + attribs = {'d': path, inkex.addNS('dxfpoint','inkscape'):'1', 'style': 'stroke:#ff0000;fill:#ff0000'} + inkex.etree.SubElement(layer, 'path', attribs) + def get_line(): return (stream.readline().strip(), stream.readline().strip()) @@ -301,7 +316,9 @@ colors = { 1: '#FF0000', 2: '#FFFF00', 3: '#00FF00', 4: '#00FFFF', 5: ' parser = inkex.optparse.OptionParser(usage="usage: %prog [options] SVGfile", option_class=inkex.InkOption) parser.add_option("--auto", action="store", type="inkbool", dest="auto", default=True) parser.add_option("--scale", action="store", type="string", dest="scale", default="1.0") +parser.add_option("--gcodetoolspoints", action="store", type="inkbool", dest="gcodetoolspoints", default=True) parser.add_option("--encoding", action="store", type="string", dest="input_encode", default="latin_1") +parser.add_option("--font", action="store", type="string", dest="font", default="Arial") parser.add_option("--tab", action="store", type="string", dest="tab", default="Options") parser.add_option("--inputhelp", action="store", type="string", dest="inputhelp", default="") (options, args) = parser.parse_args(inkex.sys.argv[1:]) @@ -310,6 +327,10 @@ desc = inkex.etree.SubElement(doc.getroot(), 'desc', {}) defs = inkex.etree.SubElement(doc.getroot(), 'defs', {}) marker = inkex.etree.SubElement(defs, 'marker', {'id': 'DistanceX', 'orient': 'auto', 'refX': '0.0', 'refY': '0.0', 'style': 'overflow:visible'}) inkex.etree.SubElement(marker, 'path', {'d': 'M 3,-3 L -3,3 M 0,-5 L 0,5', 'style': 'stroke:#000000; stroke-width:0.5'}) +pattern = inkex.etree.SubElement(defs, 'pattern', {'id': 'Hatch', 'patternUnits': 'userSpaceOnUse', 'width': '8', 'height': '8', 'x': '0', 'y': '0'}) +inkex.etree.SubElement(pattern, 'path', {'d': 'M8 4 l-4,4', 'stroke': '#000000', 'stroke-width': '0.25', 'linecap': 'square'}) +inkex.etree.SubElement(pattern, 'path', {'d': 'M6 2 l-4,4', 'stroke': '#000000', 'stroke-width': '0.25', 'linecap': 'square'}) +inkex.etree.SubElement(pattern, 'path', {'d': 'M4 0 l-4,4', 'stroke': '#000000', 'stroke-width': '0.25', 'linecap': 'square'}) stream = open(args[0], 'r') xmax = xmin = 0.0 ymax = 297.0 # default A4 height in mm @@ -369,8 +390,14 @@ if not layer_nodes: for linename in linetypes.keys(): # scale the dashed lines linetype = '' for length in linetypes[linename]: - linetype += '%.4f,' % math.fabs(length*scale) - linetypes[linename] = 'stroke-dasharray:' + linetype + if length == 0: # test for dot + linetype += ' 0.5,' + else: + linetype += '%.4f,' % math.fabs(length*scale) + if linetype == '': + linetypes[linename] = 'stroke-linecap: round' + else: + linetypes[linename] = 'stroke-dasharray:' + linetype entity = '' block = defs # initiallize with dummy diff --git a/share/extensions/dxf_outlines.py b/share/extensions/dxf_outlines.py index 295fc7466..219ee1dda 100755 --- a/share/extensions/dxf_outlines.py +++ b/share/extensions/dxf_outlines.py @@ -1,13 +1,15 @@ #!/usr/bin/env python ''' Copyright (C) 2005,2007,2008 Aaron Spike, aaron@ekips.org -Copyright (C) 2008 Alvin Penner, penner@vaxxine.com +Copyright (C) 2008,2010 Alvin Penner, penner@vaxxine.com - template dxf_outlines.dxf added Feb 2008 by Alvin Penner - ROBO-Master output option added Aug 2008 - ROBO-Master multispline output added Sept 2008 - LWPOLYLINE output modification added Dec 2008 - toggle between LINE/LWPOLYLINE added Jan 2010 +- support for transform elements added July 2010 +- support for layers added July 2010 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 @@ -23,7 +25,7 @@ You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA ''' -import inkex, simplepath, simplestyle, cubicsuperpath, coloreffect, dxf_templates, math +import inkex, simplestyle, simpletransform, cubicsuperpath, coloreffect, dxf_templates, math import gettext _ = gettext.gettext @@ -59,6 +61,8 @@ class MyEffect(inkex.Effect): self.OptionParser.add_option("--inputhelp", action="store", type="string", dest="inputhelp") self.dxf = [] self.handle = 255 # handle for DXF ENTITY + self.layers = ['0'] + self.layer = '0' # mandatory layer self.csp_old = [[0.0,0.0]]*4 # previous spline self.d = array([0], float) # knot vector self.poly = [[0.0,0.0]] # LWPOLYLINE data @@ -68,7 +72,7 @@ class MyEffect(inkex.Effect): self.dxf.append(str) def dxf_line(self,csp): self.handle += 1 - self.dxf_add(" 0\nLINE\n 5\n%x\n100\nAcDbEntity\n 8\n0\n 62\n%d\n100\nAcDbLine\n" % (self.handle, self.color)) + self.dxf_add(" 0\nLINE\n 5\n%x\n100\nAcDbEntity\n 8\n%s\n 62\n%d\n100\nAcDbLine\n" % (self.handle, self.layer, self.color)) self.dxf_add(" 10\n%f\n 20\n%f\n 30\n0.0\n 11\n%f\n 21\n%f\n 31\n0.0\n" % (csp[0][0],csp[0][1],csp[1][0],csp[1][1])) def LWPOLY_line(self,csp): if (abs(csp[0][0] - self.poly[-1][0]) > .0001 @@ -76,19 +80,20 @@ class MyEffect(inkex.Effect): self.LWPOLY_output() # terminate current polyline self.poly = [csp[0]] # initiallize new polyline self.color_LWPOLY = self.color + self.layer_LWPOLY = self.layer self.poly.append(csp[1]) def LWPOLY_output(self): if len(self.poly) == 1: return self.handle += 1 - self.dxf_add(" 0\nLWPOLYLINE\n 5\n%x\n100\nAcDbEntity\n 8\n0\n 62\n%d\n100\nAcDbPolyline\n 90\n%d\n 70\n0\n" % (self.handle, self.color_LWPOLY, len(self.poly))) + self.dxf_add(" 0\nLWPOLYLINE\n 5\n%x\n100\nAcDbEntity\n 8\n%s\n 62\n%d\n100\nAcDbPolyline\n 90\n%d\n 70\n0\n" % (self.handle, self.layer_LWPOLY, self.color_LWPOLY, len(self.poly))) for i in range(len(self.poly)): self.dxf_add(" 10\n%f\n 20\n%f\n 30\n0.0\n" % (self.poly[i][0],self.poly[i][1])) def dxf_spline(self,csp): knots = 8 ctrls = 4 self.handle += 1 - self.dxf_add(" 0\nSPLINE\n 5\n%x\n100\nAcDbEntity\n 8\n0\n 62\n%d\n100\nAcDbSpline\n" % (self.handle, self.color)) + self.dxf_add(" 0\nSPLINE\n 5\n%x\n100\nAcDbEntity\n 8\n%s\n 62\n%d\n100\nAcDbSpline\n" % (self.handle, self.layer, self.color)) self.dxf_add(" 70\n8\n 71\n3\n 72\n%d\n 73\n%d\n 74\n0\n" % (knots, ctrls)) for i in range(2): for j in range(4): @@ -105,6 +110,7 @@ class MyEffect(inkex.Effect): self.yfit = array([csp[0][1]], float) self.d = array([0], float) self.color_ROBO = self.color + self.layer_ROBO = self.layer self.xfit = concatenate((self.xfit, zeros((3)))) # append to current spline self.yfit = concatenate((self.yfit, zeros((3)))) self.d = concatenate((self.d, zeros((3)))) @@ -138,7 +144,7 @@ class MyEffect(inkex.Effect): xctrl = solve(solmatrix, self.xfit) yctrl = solve(solmatrix, self.yfit) self.handle += 1 - self.dxf_add(" 0\nSPLINE\n 5\n%x\n100\nAcDbEntity\n 8\n0\n 62\n%d\n100\nAcDbSpline\n" % (self.handle, self.color_ROBO)) + self.dxf_add(" 0\nSPLINE\n 5\n%x\n100\nAcDbEntity\n 8\n%s\n 62\n%d\n100\nAcDbSpline\n" % (self.handle, self.layer_ROBO, self.color_ROBO)) self.dxf_add(" 70\n0\n 71\n3\n 72\n%d\n 73\n%d\n 74\n%d\n" % (knots, ctrls, fits)) for i in range(knots): self.dxf_add(" 40\n%f\n" % self.d[i-3]) @@ -147,47 +153,78 @@ class MyEffect(inkex.Effect): for i in range(fits): self.dxf_add(" 11\n%f\n 21\n%f\n 31\n0.0\n" % (self.xfit[i],self.yfit[i])) + def process_path(self, node, mat): + rgb = (0,0,0) + style = node.get('style') + if style: + style = simplestyle.parseStyle(style) + if style.has_key('stroke'): + if style['stroke'] and style['stroke'] != 'none': + rgb = simplestyle.parseColor(style['stroke']) + hsl = coloreffect.ColorEffect.rgb_to_hsl(coloreffect.ColorEffect(),rgb[0]/255.0,rgb[1]/255.0,rgb[2]/255.0) + self.color = 7 # default is black + if hsl[2]: + self.color = 1 + (int(6*hsl[0] + 0.5) % 6) # use 6 hues + d = node.get('d') + if d: + p = cubicsuperpath.parsePath(d) + trans = node.get('transform') + if trans: + mat = simpletransform.composeTransform(mat, simpletransform.parseTransform(trans)) + simpletransform.applyTransformToPath(mat, p) + for sub in p: + for i in range(len(sub)-1): + s = sub[i] + e = sub[i+1] + if s[1] == s[2] and e[0] == e[1]: + if (self.options.POLY == 'true'): + self.LWPOLY_line([s[1],e[1]]) + else: + self.dxf_line([s[1],e[1]]) + elif (self.options.ROBO == 'true'): + self.ROBO_spline([s[1],s[2],e[0],e[1]]) + else: + self.dxf_spline([s[1],s[2],e[0],e[1]]) + + def process_group(self, group): + if group.get(inkex.addNS('groupmode', 'inkscape')) == 'layer': + layer = group.get(inkex.addNS('label', 'inkscape')) + layer = layer.replace(' ', '_') + if layer in self.layers: + self.layer = layer + trans = group.get('transform') + if trans: + self.groupmat.append(simpletransform.composeTransform(self.groupmat[-1], simpletransform.parseTransform(trans))) + for node in group: + if node.tag == inkex.addNS('path','svg'): + self.process_path(node, self.groupmat[-1]) + if node.tag == inkex.addNS('g','svg'): + self.process_group(node) + if trans: + self.groupmat.pop() + def effect(self): #References: Minimum Requirements for Creating a DXF File of a 3D Model By Paul Bourke # NURB Curves: A Guide for the Uninitiated By Philip J. Schneider # The NURBS Book By Les Piegl and Wayne Tiller (Springer, 1995) self.dxf_add("999\nDXF created by Inkscape\n") self.dxf_add(dxf_templates.r14_header) + for node in self.document.getroot().xpath('//svg:g', namespaces=inkex.NSS): + if node.get(inkex.addNS('groupmode', 'inkscape')) == 'layer': + layer = node.get(inkex.addNS('label', 'inkscape')) + layer = layer.replace(' ', '_') + if layer and not layer in self.layers: + self.layers.append(layer) + self.dxf_add(" 2\nLAYER\n 5\n2\n100\nAcDbSymbolTable\n 70\n%s\n" % len(self.layers)) + for i in range(len(self.layers)): + self.dxf_add(" 0\nLAYER\n 5\n%x\n100\nAcDbSymbolTableRecord\n100\nAcDbLayerTableRecord\n 2\n%s\n 70\n0\n 6\nCONTINUOUS\n" % (i + 80, self.layers[i])) + self.dxf_add(dxf_templates.r14_style) scale = 25.4/90.0 h = inkex.unittouu(self.document.getroot().xpath('@height', namespaces=inkex.NSS)[0]) - path = '//svg:path' - for node in self.document.getroot().xpath(path, namespaces=inkex.NSS): - rgb = (0,0,0) - style = node.get('style') - if style: - style = simplestyle.parseStyle(style) - if style.has_key('stroke'): - if style['stroke'] and style['stroke'] != 'none': - rgb = simplestyle.parseColor(style['stroke']) - hsl = coloreffect.ColorEffect.rgb_to_hsl(coloreffect.ColorEffect(),rgb[0]/255.0,rgb[1]/255.0,rgb[2]/255.0) - self.color = 7 # default is black - if hsl[2]: - self.color = 1 + (int(6*hsl[0] + 0.5) % 6) # use 6 hues - d = node.get('d') - sim = simplepath.parsePath(d) - if len(sim): - simplepath.scalePath(sim,scale,-scale) - simplepath.translatePath(sim,0,h*scale) - p = cubicsuperpath.CubicSuperPath(sim) - for sub in p: - for i in range(len(sub)-1): - s = sub[i] - e = sub[i+1] - if s[1] == s[2] and e[0] == e[1]: - if (self.options.POLY == 'true'): - self.LWPOLY_line([s[1],e[1]]) - else: - self.dxf_line([s[1],e[1]]) - elif (self.options.ROBO == 'true'): - self.ROBO_spline([s[1],s[2],e[0],e[1]]) - else: - self.dxf_spline([s[1],s[2],e[0],e[1]]) + self.groupmat = [[[scale, 0.0, 0.0], [0.0, -scale, h*scale]]] + doc = self.document.getroot() + self.process_group(doc) if self.options.ROBO == 'true': self.ROBO_output() if self.options.POLY == 'true': diff --git a/share/extensions/dxf_templates.py b/share/extensions/dxf_templates.py index c0a85f6b8..5c027456f 100644 --- a/share/extensions/dxf_templates.py +++ b/share/extensions/dxf_templates.py @@ -196,35 +196,10 @@ Solid line ENDTAB 0 TABLE - 2 -LAYER - 5 -2 -330 -0 -100 -AcDbSymbolTable - 70 -1 - 0 -LAYER - 5 -10 -330 -2 -100 -AcDbSymbolTableRecord -100 -AcDbLayerTableRecord - 2 -0 - 70 - 0 - 62 - 7 - 6 -CONTINUOUS - 0 +''' + + +r14_style = ''' 0 ENDTAB 0 TABLE diff --git a/share/extensions/funcplot.py b/share/extensions/funcplot.py index e5f93d430..126429853 100644 --- a/share/extensions/funcplot.py +++ b/share/extensions/funcplot.py @@ -70,10 +70,14 @@ def drawfunction(xstart, xend, ybottom, ytop, samples, width, height, left, bott ytop = (bottom+height-yzero)/scaley # functions specified by the user - if fx != "": - f = eval('lambda x: ' + fx.strip('"')) - if fpx != "": - fp = eval('lambda x: ' + fpx.strip('"')) + try: + if fx != "": + f = eval('lambda x: ' + fx.strip('"')) + if fpx != "": + fp = eval('lambda x: ' + fpx.strip('"')) + # handle incomplete/invalid function gracefully + except SyntaxError: + return [] # step is the distance between nodes on x step = (xend - xstart) / (samples-1) diff --git a/share/extensions/generate_voronoi.py b/share/extensions/generate_voronoi.py index 3359685fc..3d5d5e9a8 100644 --- a/share/extensions/generate_voronoi.py +++ b/share/extensions/generate_voronoi.py @@ -135,6 +135,7 @@ class Pattern(inkex.Effect): # plot Voronoi diagram sl = voronoi.SiteList(pts) voronoi.voronoi(sl, c) + path = "" for edge in c.edges: if edge[1] >= 0 and edge[2] >= 0: # two vertices [x1, y1, x2, y2] = clip_line(c.vertices[edge[1]][0], c.vertices[edge[1]][1], c.vertices[edge[2]][0], c.vertices[edge[2]][1], q['width'], q['height']) @@ -161,9 +162,10 @@ class Pattern(inkex.Effect): ytemp = c.lines[edge[0]][2]/c.lines[edge[0]][1] [x1, y1, x2, y2] = clip_line(xtemp, ytemp, c.vertices[edge[2]][0], c.vertices[edge[2]][1], q['width'], q['height']) if x1 or x2 or y1 or y2: - path = 'M %f,%f %f,%f' % (x1, y1, x2, y2) - attribs = {'d': path, 'style': 'stroke:#000000'} - inkex.etree.SubElement(pattern, inkex.addNS('path', 'svg'), attribs) + path += 'M %.3f,%.3f %.3f,%.3f ' % (x1, y1, x2, y2) + + attribs = {'d': path, 'style': 'stroke:#000000'} + inkex.etree.SubElement(pattern, inkex.addNS('path', 'svg'), attribs) # link selected object to pattern obj = self.selected[self.options.ids[0]] diff --git a/share/extensions/hpgl_output.py b/share/extensions/hpgl_output.py index 28e123498..4f2eee8f9 100644 --- a/share/extensions/hpgl_output.py +++ b/share/extensions/hpgl_output.py @@ -16,7 +16,7 @@ You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA ''' -import inkex, cubicsuperpath, simplepath, simplestyle, cspsubdiv +import inkex, simpletransform, cubicsuperpath, simplestyle, cspsubdiv class MyEffect(inkex.Effect): def __init__(self): @@ -52,40 +52,58 @@ class MyEffect(inkex.Effect): def output(self): print ''.join(self.hpgl) + + def process_path(self, node, mat): + d = node.get('d') + if d: + p = cubicsuperpath.parsePath(d) + trans = node.get('transform') + if trans: + mat = simpletransform.composeTransform(mat, simpletransform.parseTransform(trans)) + simpletransform.applyTransformToPath(mat, p) + cspsubdiv.cspsubdiv(p, self.options.flat) + for sp in p: + first = True + for csp in sp: + cmd = 'PD' + if first: + cmd = 'PU' + first = False + self.hpgl.append('%s%d,%d;' % (cmd,csp[1][0],csp[1][1])) + + def process_group(self, group): + style = group.get('style') + if style: + style = simplestyle.parseStyle(style) + if style.has_key('display'): + if style['display']=='none': + if not self.options.plotInvisibleLayers: + return + trans = group.get('transform') + if trans: + self.groupmat.append(simpletransform.composeTransform(self.groupmat[-1], simpletransform.parseTransform(trans))) + for node in group: + if node.tag == inkex.addNS('path','svg'): + self.process_path(node, self.groupmat[-1]) + if node.tag == inkex.addNS('g','svg'): + self.process_group(node) + if trans: + self.groupmat.pop() + def effect(self): self.hpgl = ['IN;SP%d;' % self.options.pen] x0 = self.options.xOrigin y0 = self.options.yOrigin scale = float(self.options.resolution)/90 + self.options.flat *= scale mirror = 1.0 if self.options.mirror: mirror = -1.0 if self.document.getroot().get('height'): y0 -= float(self.document.getroot().get('height')) - i = 0 - layerPath = '//svg:g[@inkscape:groupmode="layer"]' - for layer in self.document.getroot().xpath(layerPath, namespaces=inkex.NSS): - i += 1 - style = layer.get('style') - if style: - style = simplestyle.parseStyle(style) - if style['display']=='none': - if not self.options.plotInvisibleLayers: - continue - nodePath = ('//svg:g[@inkscape:groupmode="layer"][%d]/descendant::svg:path') % i - for node in self.document.getroot().xpath(nodePath, namespaces=inkex.NSS): - d = node.get('d') - if len(simplepath.parsePath(d)): - p = cubicsuperpath.parsePath(d) - cspsubdiv.cspsubdiv(p, self.options.flat) - for sp in p: - first = True - for csp in sp: - cmd = 'PD' - if first: - cmd = 'PU' - first = False - self.hpgl.append('%s%d,%d;' % (cmd,(csp[1][0] - x0)*scale,(csp[1][1]*mirror - y0)*scale)) + self.groupmat = [[[scale, 0.0, -x0*scale], [0.0, mirror*scale, -y0*scale]]] + doc = self.document.getroot() + self.process_group(doc) self.hpgl.append('PU;') if __name__ == '__main__': #pragma: no cover diff --git a/share/extensions/inkscape_help_keys.inx b/share/extensions/inkscape_help_keys.inx index c7894a81a..938a11077 100644 --- a/share/extensions/inkscape_help_keys.inx +++ b/share/extensions/inkscape_help_keys.inx @@ -3,7 +3,7 @@ <_name>Keys and Mouse Reference</_name> <id>org.inkscape.help.keys</id> <dependency type="executable" location="extensions">launch_webbrowser.py</dependency> - <param name="url" gui-hidden="true" type="string">http://inkscape.org/doc/keys047.html</param> + <param name="url" gui-hidden="true" type="string">http://inkscape.org/doc/keys048.html</param> <effect needs-document="false"> <object-type>all</object-type> <effects-menu hidden="true"/> diff --git a/share/extensions/inkscape_help_relnotes.inx b/share/extensions/inkscape_help_relnotes.inx index ab790bd9f..881eada0c 100644 --- a/share/extensions/inkscape_help_relnotes.inx +++ b/share/extensions/inkscape_help_relnotes.inx @@ -3,7 +3,7 @@ <_name>New in This Version</_name> <id>org.inkscape.help.relnotes</id> <dependency type="executable" location="extensions">launch_webbrowser.py</dependency> - <param name="url" gui-hidden="true" type="string">http://wiki.inkscape.org/wiki/index.php/ReleaseNotes047</param> + <param name="url" gui-hidden="true" type="string">http://wiki.inkscape.org/wiki/index.php/Release_notes/0.48</param> <effect needs-document="false"> <object-type>all</object-type> <effects-menu hidden="true"/> 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')) diff --git a/share/extensions/uniconv-ext.py b/share/extensions/uniconv-ext.py index 3b248d8b8..d3d69546c 100644 --- a/share/extensions/uniconv-ext.py +++ b/share/extensions/uniconv-ext.py @@ -23,6 +23,8 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA import sys from run_command import run +import gettext +_ = gettext.gettext cmd = None @@ -49,11 +51,11 @@ if cmd == None: import imp imp.find_module("uniconvertor") except ImportError: - sys.stderr.write('You need to install the UniConvertor software.\n'+\ + sys.stderr.write(_('You need to install the UniConvertor software.\n'+\ 'For GNU/Linux: install the package python-uniconvertor.\n'+\ 'For Windows: download it from\n'+\ 'http://sk1project.org/modules.php?name=Products&product=uniconvertor\n'+\ - 'and install into your Inkscape\'s Python location\n') + 'and install into your Inkscape\'s Python location\n')) sys.exit(1) cmd = 'python -c "import uniconvertor"' diff --git a/share/extensions/uniconv_output.py b/share/extensions/uniconv_output.py index 9cdac7fc2..f7746c2f4 100644 --- a/share/extensions/uniconv_output.py +++ b/share/extensions/uniconv_output.py @@ -31,6 +31,8 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA import os import sys import tempfile +import gettext +_ = gettext.gettext def run(command_format, prog_name, uniconv_format): outfile = tempfile.mktemp(uniconv_format) |
