~valavanisalex/ubuntu/oneiric/inkscape/inkscape_0.48.1-2ubuntu4

« back to all changes in this revision

Viewing changes to share/extensions/pathmodifier.py

  • Committer: Bazaar Package Importer
  • Author(s): Kees Cook, Kees Cook, Ted Gould
  • Date: 2008-02-10 14:20:16 UTC
  • mfrom: (1.1.6 upstream)
  • Revision ID: james.westby@ubuntu.com-20080210142016-vcnb2zqyhszu0xvb
Tags: 0.46~pre1-0ubuntu1
[ Kees Cook ]
* debian/control:
  - add libgtkspell-dev build-dep to gain GtkSpell features (LP: #183547).
  - update Standards version (no changes needed).
  - add Vcs and Homepage fields.
  - switch to new python-lxml dep.
* debian/{control,rules}: switch from dpatch to quilt for more sanity.
* debian/patches/20_fix_glib_and_gxx43_ftbfs.patch:
  - merged against upstream fixes.
  - added additional fixes for newly written code.
* debian/rules: enable parallel building.

[ Ted Gould ]
* Updating POTFILES.in to make it so things build correctly.
* debian/control:
  - add ImageMagick++ and libboost-dev to build-deps

Show diffs side-by-side

added added

removed removed

Lines of Context:
16
16
along with this program; if not, write to the Free Software
17
17
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
18
18
barraud@math.univ-lille1.fr
 
19
 
 
20
This code defines a basic class (PathModifier) of effects whose purpose is
 
21
to somehow deform given objects: one common tasks for all such effect is to
 
22
convert shapes, groups, clones to paths. The class has several functions to
 
23
make this (more or less!) easy.
 
24
As an exemple, a second class (Diffeo) is derived from it,
 
25
to implement deformations of the form X=f(x,y), Y=g(x,y)...
 
26
 
 
27
TODO: Several handy functions are defined, that might in fact be of general
 
28
interest and that should be shipped out in separate files...
19
29
'''
20
30
import inkex, cubicsuperpath, bezmisc, simplestyle
21
 
import copy, math, re, random, xml.xpath
22
 
 
23
 
def parseTransform(transf,mat=[[1.0,0.0,0.0],[0.0,1.0,0.0]]):
24
 
    if transf=="":
25
 
        return(mat)
26
 
    result=re.match("(translate|scale|rotate|skewX|skewY|matrix)\(([^)]*)\)",transf)
27
 
#-- translate --
28
 
    if result.group(1)=="translate":
29
 
        args=result.group(2).split(",")
30
 
        dx=float(args[0])
31
 
        if len(args)==1:
32
 
            dy=0.0
33
 
        else:
34
 
            dy=float(args[1])
35
 
        matrix=[[1,0,dx],[0,1,dy]]
36
 
#-- scale --
37
 
    if result.groups(1)=="scale":
38
 
        args=result.group(2).split(",")
39
 
        sx=float(args[0])
40
 
        if len(args)==1:
41
 
            sy=sx
42
 
        else:
43
 
            sy=float(args[1])
44
 
        matrix=[[sx,0,0],[0,sy,0]]
45
 
#-- rotate --
46
 
    if result.groups(1)=="rotate":
47
 
        args=result.group(2).split(",")
48
 
        a=float(args[0])*math.pi/180
49
 
        if len(args)==1:
50
 
            cx,cy=(0.0,0.0)
51
 
        else:
52
 
            cx,cy=args[1:]
53
 
        matrix=[[math.cos(a),-math.sin(a),cx],[math.sin(a),math.cos(a),cy]]
54
 
#-- skewX --
55
 
    if result.groups(1)=="skewX":
56
 
        a=float(result.group(2))*math.pi/180
57
 
        matrix=[[1,math.tan(a),0],[0,1,0]]
58
 
#-- skewX --
59
 
    if result.groups(1)=="skewX":
60
 
        a=float(result.group(2))*math.pi/180
61
 
        matrix=[[1,0,0],[math.tan(a),1,0]]
62
 
#-- matrix --
63
 
    if result.group(1)=="matrix":
64
 
        a11,a21,a12,a22,v1,v2=result.group(2).split(",")
65
 
        matrix=[[float(a11),float(a12),float(v1)],[float(a21),float(a22),float(v2)]]
66
 
    
67
 
    matrix=composeTransform(mat,matrix)
68
 
    if result.end()<len(transf):
69
 
        return(parseTransform(transf[result.end():],matrix))
70
 
    else:
71
 
        return matrix
72
 
 
73
 
def formatTransform(mat):
74
 
    return("matrix(%f,%f,%f,%f,%f,%f)"%(mat[0][0],mat[1][0],mat[0][1],mat[1][1],mat[0][2],mat[1][2]))
75
 
 
76
 
def composeTransform(M1,M2):
77
 
    a11=M1[0][0]*M2[0][0]+M1[0][1]*M2[1][0]
78
 
    a12=M1[0][0]*M2[0][1]+M1[0][1]*M2[1][1]
79
 
    a21=M1[1][0]*M2[0][0]+M1[1][1]*M2[1][0]
80
 
    a22=M1[1][0]*M2[0][1]+M1[1][1]*M2[1][1]
81
 
 
82
 
    v1=M1[0][0]*M2[0][2]+M1[0][1]*M2[1][2]+M1[0][2]
83
 
    v2=M1[1][0]*M2[0][2]+M1[1][1]*M2[1][2]+M1[1][2]
84
 
    return [[a11,a12,v1],[a21,a22,v2]]
85
 
 
86
 
def applyTransformToNode(mat,node):
87
 
    m=parseTransform(node.getAttributeNS(None,"transform"))
88
 
    newtransf=formatTransform(composeTransform(mat,m))
89
 
    node.setAttributeNS(None,"transform", newtransf)
90
 
 
91
 
def applyTransformToPoint(mat,pt):
92
 
    x=mat[0][0]*pt[0]+mat[0][1]*pt[1]+mat[0][2]
93
 
    y=mat[1][0]*pt[0]+mat[1][1]*pt[1]+mat[1][2]
94
 
    pt[0]=x
95
 
    pt[1]=y
96
 
 
97
 
def fuseTransform(node):
98
 
    m=parseTransform(node.getAttributeNS(None,"transform"))
99
 
    d = node.getAttributeNS(None,'d')
100
 
    p=cubicsuperpath.parsePath(d)
101
 
    for comp in p:
102
 
        for ctl in comp:
103
 
            for pt in ctl:
104
 
                applyTransformToPoint(m,pt)
105
 
    node.setAttributeNS(None,'d', cubicsuperpath.formatPath(p))
106
 
    node.removeAttributeNS(None,"transform")
107
 
 
108
 
 
109
 
def boxunion(b1,b2):
110
 
    if b1 is None:
111
 
        return b2
112
 
    elif b2 is None:
113
 
        return b1    
114
 
    else:
115
 
        return((min(b1[0],b2[0]),max(b1[1],b2[1]),min(b1[2],b2[2]),max(b1[3],b2[3])))
116
 
 
117
 
def roughBBox(path):
118
 
    xmin,xMax,ymin,yMax=path[0][0][0][0],path[0][0][0][0],path[0][0][0][1],path[0][0][0][1]
119
 
    for pathcomp in path:
120
 
        for ctl in pathcomp:
121
 
           for pt in ctl:
122
 
               xmin=min(xmin,pt[0])
123
 
               xMax=max(xMax,pt[0])
124
 
               ymin=min(ymin,pt[1])
125
 
               yMax=max(yMax,pt[1])
126
 
    return xmin,xMax,ymin,yMax
 
31
from simpletransform import *
 
32
import copy, math, re, random
 
33
 
 
34
####################################################################
 
35
##-- zOrder computation...
 
36
##-- this should be shipped out in a separate file. inkex.py?
 
37
 
 
38
def zSort(inNode,idList):
 
39
    sortedList=[]
 
40
    theid = inNode.get("id")
 
41
    if theid in idList:
 
42
        sortedList.append(theid)
 
43
    for child in inNode:
 
44
        if len(sortedList)==len(idList):
 
45
            break
 
46
        sortedList+=zSort(child,idList)
 
47
    return sortedList
127
48
 
128
49
 
129
50
class PathModifier(inkex.Effect):
133
54
##################################
134
55
#-- Selectionlists manipulation --
135
56
##################################
136
 
    def computeBBox(self, aList):
137
 
        bbox=None
138
 
        for id, node in aList.iteritems():
139
 
            if node.tagName == 'path':
140
 
                d = node.attributes.getNamedItem('d')
141
 
                p = cubicsuperpath.parsePath(d.value)
142
 
                bbox=boxunion(roughBBox(p),bbox)
143
 
        return bbox
144
57
 
145
58
    def duplicateNodes(self, aList):
146
59
        clones={}
147
60
        for id,node in aList.iteritems():
148
 
            clone=node.cloneNode(True)
149
 
    #!!!--> should it be given an id?
150
 
    #seems to work without this!?!
151
 
            clone.setAttributeNS(None,"id", self.uniqueId(node.tagName))
152
 
            node.parentNode.appendChild(clone)
153
 
            clones[clone.getAttributeNS(None,"id")]=clone
 
61
            clone=copy.deepcopy(node)
 
62
            #!!!--> should it be given an id?
 
63
            #seems to work without this!?!
 
64
            myid = node.tag.split('}')[-1]
 
65
            clone.set("id", self.uniqueId(myid))
 
66
            node.getparent().append(clone)
 
67
            clones[clone.get("id")]=clone
154
68
        return(clones)
155
69
 
156
70
    def uniqueId(self, prefix):
157
71
        id="%s%04i"%(prefix,random.randint(0,9999))
158
 
        while len(xml.xpath.Evaluate('//*[@id="%s"]' % id,self.document)):
 
72
        while len(self.document.getroot().xpath('//*[@id="%s"]' % id,inkex.NSS)):
159
73
            id="%s%04i"%(prefix,random.randint(0,9999))
160
74
        return(id)
161
75
 
162
76
    def expandGroups(self,aList,transferTransform=True):
163
77
        for id, node in aList.items():      
164
 
            if node.tagName == 'g':
165
 
                mat=parseTransform(node.getAttributeNS(None,"transform"))
166
 
                for child in node.childNodes:
167
 
                    if child.nodeType==child.ELEMENT_NODE:
168
 
                        if transferTransform:
169
 
                            applyTransformToNode(mat,child)
170
 
                        aList.update(self.expandGroups({child.getAttribute('id'):child}))
171
 
                if transferTransform:
172
 
                    node.removeAttribute("transform")
 
78
            if node.tag == inkex.addNS('g','svg') or node.tag=='g':
 
79
                mat=parseTransform(node.get("transform"))
 
80
                for child in node:
 
81
                    if transferTransform:
 
82
                        applyTransformToNode(mat,child)
 
83
                    aList.update(self.expandGroups({child.get('id'):child}))
 
84
                if transferTransform and node.get("transform"):
 
85
                    del node.attrib["transform"]
173
86
                del aList[id]
174
 
        return(aList)
 
87
        return(aList)
175
88
 
176
89
    def expandGroupsUnlinkClones(self,aList,transferTransform=True,doReplace=True):
177
90
        for id in aList.keys()[:]:     
178
91
            node=aList[id]
179
 
            if node.tagName == 'g':
 
92
            if node.tag == inkex.addNS('g','svg') or node.tag=='g':
180
93
                self.expandGroups(aList,transferTransform)
181
94
                self.expandGroupsUnlinkClones(aList,transferTransform,doReplace)
182
 
                #Hum... not very efficient if there are many clones of groups...
183
 
            elif node.tagName == 'use':
184
 
                refid=node.getAttributeNS(inkex.NSS[u'xlink'],'href')
185
 
                path = '//*[@id="%s"]' % refid[1:]
186
 
                refnode = xml.xpath.Evaluate(path,self.document)[0]
187
 
                newnode=refnode.cloneNode(True)
188
 
                self.recursNewIds(newnode)
 
95
                #Hum... not very efficient if there are many clones of groups...
189
96
 
190
 
                if node.hasAttributeNS(None,u'style'):
191
 
                    style=simplestyle.parseStyle(node.getAttributeNS(None,u'style'))
192
 
                    refstyle=simplestyle.parseStyle(refnode.getAttributeNS(None,u'style'))
193
 
                    style.update(refstyle)
194
 
                    newnode.setAttributeNS(None,'style',simplestyle.formatStyle(style))
195
 
                applyTransformToNode(parseTransform(node.getAttributeNS(None,'transform')),newnode)
196
 
                if doReplace:
197
 
                    parent=node.parentNode
198
 
                    parent.insertBefore(newnode,node)
199
 
                    parent.removeChild(node)
 
97
            elif node.tag == inkex.addNS('use','svg') or node.tag=='use':
 
98
                refnode=self.refNode(node)
 
99
                newnode=self.unlinkClone(node,doReplace)
200
100
                del aList[id]
201
 
                newid=newnode.getAttributeNS(None,'id')
 
101
 
 
102
                style = simplestyle.parseStyle(node.get('style') or "")
 
103
                refstyle=simplestyle.parseStyle(refnode.get('style') or "")
 
104
                style.update(refstyle)
 
105
                newnode.set('style',simplestyle.formatStyle(style))
 
106
 
 
107
                newid=newnode.get('id')
202
108
                aList.update(self.expandGroupsUnlinkClones({newid:newnode},transferTransform,doReplace))
203
109
        return aList
204
110
    
205
111
    def recursNewIds(self,node):
206
 
        if node.nodeType==node.ELEMENT_NODE and node.hasAttributeNS(None,u'id'):
207
 
            node.setAttributeNS(None,u'id',self.uniqueId(node.tagName))
208
 
        for child in node.childNodes:
209
 
            self.recursNewIds(child)
210
 
                
211
 
 
212
 
        
213
 
 
214
 
#     def makeClonesReal(self,aList,doReplace=True,recursivelytransferTransform=True):
215
 
#         for id in aList.keys():     
216
 
#             node=aList[id]
217
 
#             if node.tagName == 'g':
218
 
#                 childs={}
219
 
#                 for child in node.childNodes:
220
 
#                     if child.nodeType==child.ELEMENT_NODE:
221
 
#                       childid=child.getAttributeNS(None,'id')
222
 
#                       del aList[childid]
223
 
#                         aList.update(self.makeClonesReal({childid:child},doReplace))
224
 
#             elif node.tagName == 'use':
225
 
#                 refid=node.getAttributeNS(inkex.NSS[u'xlink'],'href')
226
 
#                 path = '//*[@id="%s"]' % refid[1:]
227
 
#                 refnode = xml.xpath.Evaluate(path,document)[0]
228
 
#                 clone=refnode.cloneNode(True)
229
 
#               cloneid=self.uniqueId(clone.tagName)
230
 
#                 clone.setAttributeNS(None,'id', cloneid)
231
 
#                 style=simplestyle.parseStyle(node.getAttributeNS(None,u'style'))
232
 
#                 refstyle=simplestyle.parseStyle(refnode.getAttributeNS(None,u'style'))
233
 
#                 style.update(refstyle)
234
 
#                 clone.setAttributeNS(None,'style',simplestyle.formatStyle(style))
235
 
#                 applyTransformToNode(parseTransform(node.getAttributeNS(None,'transform')),clone)
236
 
#                 if doReplace:
237
 
#                     parent=node.parentNode
238
 
#                     parent.insertBefore(clone,node)
239
 
#                     parent.removeChild(node)
240
 
#                 del aList[id]
241
 
#                 aList.update(self.expandGroupsUnlinkClones({cloneid:clone}))
242
 
#         return aList
 
112
        if node.get('id'):
 
113
            node.set('id',self.uniqueId(node.tag))
 
114
        for child in node:
 
115
            self.recursNewIds(child)
 
116
            
 
117
    def refNode(self,node):
 
118
        if node.get(inkex.addNS('href','xlink')):
 
119
            refid=node.get(inkex.addNS('href','xlink'))
 
120
            path = '//*[@id="%s"]' % refid[1:]
 
121
            newNode = self.document.getroot().xpath(path,inkex.NSS)[0]
 
122
            return newNode
 
123
        else:
 
124
            raise AssertionError, "Trying to follow empty xlink.href attribute."
 
125
 
 
126
    def unlinkClone(self,node,doReplace):
 
127
        if node.tag == inkex.addNS('use','svg') or node.tag=='use':
 
128
            newNode = copy.deepcopy(self.refNode(node))
 
129
            self.recursNewIds(newNode)
 
130
            applyTransformToNode(parseTransform(node.get('transform')),newNode)
 
131
 
 
132
            if doReplace:
 
133
                parent=node.getparent()
 
134
                parent.insert(parent.index(node),newNode)
 
135
                parent.remove(node)
 
136
 
 
137
            return newNode
 
138
        else:
 
139
            raise AssertionError, "Only clones can be unlinked..."
 
140
 
 
141
 
243
142
 
244
143
################################
245
144
#-- Object conversion ----------
246
145
################################
247
146
 
248
147
    def rectToPath(self,node,doReplace=True):
249
 
        if node.tagName == 'rect':
250
 
            x =float(node.getAttributeNS(None,u'x'))
251
 
            y =float(node.getAttributeNS(None,u'y'))
 
148
        if node.tag == inkex.addNS('rect','svg'):
 
149
            x =float(node.get('x'))
 
150
            y =float(node.get('y'))
 
151
            #FIXME: no exception anymore and sometimes just one
252
152
            try:
253
 
                rx=float(node.getAttributeNS(None,u'rx'))
254
 
                ry=float(node.getAttributeNS(None,u'ry'))
 
153
                rx=float(node.get('rx'))
 
154
                ry=float(node.get('ry'))
255
155
            except:
256
156
                rx=0
257
157
                ry=0
258
 
            w =float(node.getAttributeNS(None,u'width' ))
259
 
            h =float(node.getAttributeNS(None,u'height'))
 
158
            w =float(node.get('width' ))
 
159
            h =float(node.get('height'))
260
160
            d ='M %f,%f '%(x+rx,y)
261
161
            d+='L %f,%f '%(x+w-rx,y)
262
162
            d+='A %f,%f,%i,%i,%i,%f,%f '%(rx,ry,0,0,1,x+w,y+ry)
267
167
            d+='L %f,%f '%(x,y+ry)
268
168
            d+='A %f,%f,%i,%i,%i,%f,%f '%(rx,ry,0,0,1,x+rx,y)
269
169
 
270
 
            newnode=self.document.createElement('path')
271
 
            newnode.setAttributeNS(None,'d',d)
272
 
            newnode.setAttributeNS(None,'id', self.uniqueId('path'))
273
 
            newnode.setAttributeNS(None,'style',node.getAttributeNS(None,u'style'))
274
 
            newnode.setAttributeNS(None,'transform',node.getAttributeNS(None,u'transform'))
275
 
            fuseTransform(newnode)
 
170
            newnode=inkex.etree.Element('path')
 
171
            newnode.set('d',d)
 
172
            newnode.set('id', self.uniqueId('path'))
 
173
            newnode.set('style',node.get('style'))
 
174
            nnt = node.get('transform')
 
175
            if nnt:
 
176
                newnode.set('transform',nnt)
 
177
                fuseTransform(newnode)
276
178
            if doReplace:
277
 
                parent=node.parentNode
278
 
                parent.insertBefore(newnode,node)
279
 
                parent.removeChild(node)
 
179
                parent=node.getparent()
 
180
                parent.insert(parent.index(node),newnode)
 
181
                parent.remove(node)
280
182
            return newnode
281
183
 
 
184
    def groupToPath(self,node,doReplace=True):
 
185
        if node.tag == inkex.addNS('g','svg'):
 
186
            newNode = inkex.etree.SubElement(self.current_layer,inkex.addNS('path','svg'))    
 
187
 
 
188
            newstyle = simplestyle.parseStyle(node.get('style') or "")
 
189
            newp = []
 
190
            for child in node:
 
191
                childstyle = simplestyle.parseStyle(child.get('style') or "")
 
192
                childstyle.update(newstyle)
 
193
                newstyle.update(childstyle)
 
194
                childAsPath = self.objectToPath(child,False)
 
195
                newp += cubicsuperpath.parsePath(childAsPath.get('d'))
 
196
            newNode.set('d',cubicsuperpath.formatPath(newp))
 
197
            newNode.set('style',simplestyle.formatStyle(newstyle))
 
198
 
 
199
            self.current_layer.remove(newNode)
 
200
            if doReplace:
 
201
                parent=node.getparent()
 
202
                parent.insert(parent.index(node),newNode)
 
203
                parent.remove(node)
 
204
 
 
205
            return newNode
 
206
        else:
 
207
            raise AssertionError
 
208
        
282
209
    def objectToPath(self,node,doReplace=True):
283
 
    #--TODO: support other object types!!!!
284
 
    #--TODO: make sure cubicsuperpath supports A and Q commands... 
285
 
        if node.tagName == 'rect':
286
 
            return(self.rectToPath(node,doReplace))
287
 
        elif node.tagName == 'path':
288
 
            attributes = node.attributes.keys()
289
 
            for uri,attName in attributes:
290
 
                if uri in [inkex.NSS[u'sodipodi'],inkex.NSS[u'inkscape']]:
291
 
#                if attName not in ["d","id","style","transform"]:
292
 
                    node.removeAttributeNS(uri,attName)
 
210
        #--TODO: support other object types!!!!
 
211
        #--TODO: make sure cubicsuperpath supports A and Q commands... 
 
212
        if node.tag == inkex.addNS('rect','svg'):
 
213
            return(self.rectToPath(node,doReplace))
 
214
        if node.tag == inkex.addNS('g','svg'):
 
215
            return(self.groupToPath(node,doReplace))
 
216
        elif node.tag == inkex.addNS('path','svg') or node.tag == 'path':
 
217
            #remove inkscape attributes, otherwise any modif of 'd' will be discarded!
 
218
            for attName in node.attrib.keys():
 
219
                if ("sodipodi" in attName) or ("inkscape" in attName):
 
220
                    del node.attrib[attName]
293
221
            fuseTransform(node)
294
222
            return node
 
223
        elif node.tag == inkex.addNS('use','svg') or node.tag == 'use':
 
224
            newNode = self.unlinkClone(node,doReplace)
 
225
            return self.objectToPath(newNode,doReplace)
295
226
        else:
296
 
            inkex.debug("Please first convert objects to paths!...(got '%s')"%node.tagName)
 
227
            inkex.debug("Please first convert objects to paths!...(got '%s')"%node.tag)
297
228
            return None
298
229
 
299
230
    def objectsToPaths(self,aList,doReplace=True):
300
231
        newSelection={}
301
232
        for id,node in aList.items():
302
 
            newnode=self.objectToPath(node,self.document)
 
233
            newnode=self.objectToPath(node,doReplace)
303
234
            del aList[id]
304
 
            aList[newnode.getAttributeNS(None,u'id')]=newnode
 
235
            aList[newnode.get('id')]=newnode
305
236
 
306
237
 
307
238
################################
308
239
#-- Action ----------
309
240
################################
310
 
            
 
241
        
311
242
    #-- overwrite this method in subclasses...
312
243
    def effect(self):
313
244
        #self.duplicateNodes(self.selected)
314
 
        self.expandGroupsUnlinkClones(self.selected, True)
315
 
        self.objectsToPaths(self.selected, True)
316
 
        self.bbox=self.computeBBox(self.selected)
 
245
        #self.expandGroupsUnlinkClones(self.selected, True)
 
246
        self.objectsToPaths(self.selected, True)
 
247
        self.bbox=computeBBox(self.selected.values())
317
248
        for id, node in self.selected.iteritems():
318
 
            if node.tagName == 'path':
319
 
                d = node.attributes.getNamedItem('d')
320
 
                p = cubicsuperpath.parsePath(d.value)
321
 
 
322
 
                #do what ever you want with p!
323
 
 
324
 
                d.value = cubicsuperpath.formatPath(p)
 
249
            if node.tag == inkex.addNS('path','svg'):
 
250
                d = node.get('d')
 
251
                p = cubicsuperpath.parsePath(d)
 
252
 
 
253
                #do what ever you want with p!
 
254
 
 
255
                node.set('d',cubicsuperpath.formatPath(p))
325
256
 
326
257
 
327
258
class Diffeo(PathModifier):
355
286
 
356
287
    def effect(self):
357
288
        #self.duplicateNodes(self.selected)
358
 
        self.expandGroupsUnlinkClones(self.selected, True)
 
289
        self.expandGroupsUnlinkClones(self.selected, True)
359
290
        self.expandGroups(self.selected, True)
360
 
        self.objectsToPaths(self.selected, True)
361
 
        self.bbox=self.computeBBox(self.selected)
 
291
        self.objectsToPaths(self.selected, True)
 
292
        self.bbox=computeBBox(self.selected.values())
362
293
        for id, node in self.selected.iteritems():
363
 
            if node.tagName == 'path':
364
 
                d = node.attributes.getNamedItem('d')
365
 
                p = cubicsuperpath.parsePath(d.value)
 
294
            if node.tag == inkex.addNS('path','svg') or node.tag=='path':
 
295
                d = node.get('d')
 
296
                p = cubicsuperpath.parsePath(d)
366
297
 
367
298
                for sub in p:
368
299
                    for ctlpt in sub:
369
300
                        self.applyDiffeo(ctlpt[1],(ctlpt[0],ctlpt[2]))
370
301
 
371
 
                d.value = cubicsuperpath.formatPath(p)
 
302
                node.set('d',cubicsuperpath.formatPath(p))
372
303
 
373
304
#e = Diffeo()
374
305
#e.affect()
375
 
 
376
 
                 
 
306
 
 
307