summaryrefslogtreecommitdiffstats
path: root/share/extensions
diff options
context:
space:
mode:
authorKrzysztof Kosi??ski <tweenk.pl@gmail.com>2010-08-08 17:27:51 +0000
committerKrzysztof KosiƄski <tweenk.pl@gmail.com>2010-08-08 17:27:51 +0000
commit60d3113d1f022a3de7cf04c7979d4751b3fe21f6 (patch)
treeca33e2a9a1af6b5911598fa1c6a1d77087b71dd2 /share/extensions
parentMinor cleanups (diff)
parentAdd a constrained snap method that takes multiple constraints. This reduces t... (diff)
downloadinkscape-60d3113d1f022a3de7cf04c7979d4751b3fe21f6.tar.gz
inkscape-60d3113d1f022a3de7cf04c7979d4751b3fe21f6.zip
merge from trunk
(bzr r9508.1.52)
Diffstat (limited to 'share/extensions')
-rw-r--r--share/extensions/dimension.inx24
-rw-r--r--share/extensions/dimension.py36
-rw-r--r--share/extensions/dxf_input.inx2
-rw-r--r--share/extensions/dxf_input.py43
-rwxr-xr-xshare/extensions/dxf_outlines.py113
-rw-r--r--share/extensions/dxf_templates.py33
-rw-r--r--share/extensions/funcplot.py12
-rw-r--r--share/extensions/generate_voronoi.py8
-rw-r--r--share/extensions/hpgl_output.py68
-rw-r--r--share/extensions/inkscape_help_keys.inx2
-rw-r--r--share/extensions/inkscape_help_relnotes.inx2
-rw-r--r--share/extensions/simpletransform.py41
-rw-r--r--share/extensions/uniconv-ext.py6
-rw-r--r--share/extensions/uniconv_output.py2
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)