# HG changeset patch
# User wycc
# Date 1293033646 -28800
# Node ID 8f0ee167c5b2f04186ef1f6b4cd76768deac0bf3
# Parent d4dbcb93aee0ab91252afaf06fa01c2d84437ceb# Parent a2b0685944122ba28cf257f34ba08a7243819712
Fix the issue of the new DOM implementation
diff -r a2b068594412 -r 8f0ee167c5b2 pyink/MBScene.py
--- a/pyink/MBScene.py Wed Dec 22 13:27:37 2010 +0800
+++ b/pyink/MBScene.py Thu Dec 23 00:00:46 2010 +0800
@@ -11,6 +11,7 @@
import time
import pybInkscape
import math
+from tween import TweenObject
# Please refer to
# http://www.assembla.com/wiki/show/MadButterfly/Inkscape_extention
@@ -132,33 +133,15 @@
pybInkscape.inkscape.connect('change_selection', self.show_selection)
self.last_select = None
self.lockui=False
+ self.tween=None
+ self.document = None
+ self.dom = None
pass
- def startPolling(self):
- objs = self.desktop.selection.list()
- if len(objs) != 1:
- glib.timeout_add(500,self.startPolling)
- try:
- self.nameEditor.set_text('')
- except:
- traceback.print_exc()
- pass
- return
- o = objs[0]
- if o == self.last_select:
- glib.timeout_add(500,self.startPolling)
- return
- self.last_select = o
- try:
- self.nameEditor.set_text(o.getAttribute("inkscape:label"))
- except:
- self.nameEditor.set_text('')
- pass
- glib.timeout_add(500,self.startPolling)
def show_selection(self,w,obj):
objs = self.desktop.selection.list()
try:
- o = objs[0].repr
+ o = objs[0]
print o.getCenter()
if o == self.last_select:
return
@@ -241,13 +224,14 @@
pass
pass
if self.scenemap==None:
- self.document.root().setAttribute("xmlns:ns0","http://madbutterfly.sourceforge.net/DTD/madbutterfly.dtd")
+ #self.desktop.doc().root().repr.setAttribute("xmlns:ns0","http://madbutterfly.sourceforge.net/DTD/madbutterfly.dtd")
+ self.dom.setAttribute("xmlns:ns0","http://madbutterfly.sourceforge.net/DTD/madbutterfly.dtd")
scenes = self.document.createElement("ns0:scenes")
node.appendChild(scenes)
def update(self):
- root = self.document.root()
+ doc = self.dom
rdoc = self.document
- for node in root.childList():
+ for node in doc.childList():
if node.name() == 'svg:metadata':
for t in node.childList():
if t.name() == "ns0:scenes":
@@ -267,22 +251,22 @@
"""
self.layers = []
self.scenemap = None
- root = self.document.root()
+ doc = self.dom
#obs = pybInkscape.PYNodeObserver()
#obs = LayerAddRemoveWatcher(self)
- #root.addObserver(obs)
- addEventListener(root,'DOMNodeInserted',self.updateUI,None)
- addEventListener(root,'DOMNodeRemoved',self.updateUI,None)
- root.childList()
+ #doc.addObserver(obs)
+ addEventListener(doc,'DOMNodeInserted',self.updateUI,None)
+ addEventListener(doc,'DOMNodeRemoved',self.updateUI,None)
+ doc.childList()
try:
- self.width = float(root.getAttribute("width"))
- self.height= float(root.getAttribute("height"))
+ self.width = float(doc.getAttribute("width"))
+ self.height= float(doc.getAttribute("height"))
except:
self.width = 640
self.height=480
- for node in root.childList():
+ for node in doc.childList():
print node.name()
if node.name() == 'svg:metadata':
self.parseMetadata(node)
@@ -330,7 +314,7 @@
def collectID(self):
self.ID = {}
- root = self.document.root()
+ root = self.dom
for n in root.childList():
self.collectID_recursive(n)
pass
@@ -339,7 +323,7 @@
def collectID_recursive(self,node):
try:
self.ID[node.getAttribute('id')] = 1
- except KeyError:
+ except:
pass
for n in node.childList():
self.collectID_recursive(n)
@@ -388,12 +372,7 @@
txt.setAttribute("height","100")
txt.setAttribute("style","fill:#ff00")
ns.appendChild(txt)
- try:
- gid = self.last_line.node.getAttribute('inkscape:label') + \
- self.newID()
- except KeyError:
- gid = self.newID()
- pass
+ gid = self.last_line.node.label()+self.newID()
self.ID[gid]=1
ns.setAttribute("id",gid)
ns.setAttribute("inkscape:groupmode","layer")
@@ -509,6 +488,8 @@
pass
pass
+
+
def setCurrentScene(self,nth):
"""
Update the scene group according to the curretn scene data. There are a couple of cases.
@@ -524,6 +505,7 @@
available.
"""
self.current = nth
+ self.tween.updateMapping()
for layer in self._framelines:
i=0
@@ -559,255 +541,41 @@
layer.duplicateGroup.setAttribute("sodipodi:insensitive","1")
s.ref.setAttribute("style","display:none")
s.ref.parent().appendChild(layer.duplicateGroup)
- self.updateTweenContent(layer.duplicateGroup, layer.get_tween_type(s.idx),s, layer._keys[i+2], nth)
+ self.tween.updateTweenContent(layer.duplicateGroup, layer.get_tween_type(s.idx),s, layer._keys[i+2], nth)
+ else:
+ layer.duplicateGroup = s.ref.duplicate(self.document)
+ layer.duplicateGroup.setAttribute("style","")
+ layer.duplicateGroup.setAttribute("inkscape:label","dup")
+ layer.duplicateGroup.setAttribute("sodipodi:insensitive","1")
+ s.ref.setAttribute("style","display:none")
+ s.ref.parent().appendChild(layer.duplicateGroup)
else:
s.ref.setAttribute("style","display:none")
i = i + 2
pass
pass
pass
- def updateTweenContent(self,obj, typ, source,dest,cur):
- """
- Update the content of the duplicate scene group. We will use the (start,end) and cur to calculate the percentage of
- the tween motion effect and then use it to update the transform matrix of the duplicated scene group.
+
+ def DOMtoItem(self,obj):
"""
- start = source.idx
- end = dest.idx
- print cur,start,end
- percent = (cur-start)*1.0/(end-start)
- i = 0
- s = source.ref.firstChild()
- d = dest.ref.firstChild()
- sources={}
- dests={}
-
- # Collect all objects
- while d:
- try:
- label = d.getAttribute("inkscape:label")
- except KeyError:
- d = d.next()
- continue
- dests[label] = d
- d = d.next()
- # Check if the object in the source exists in the destination
- s = source.ref.firstChild()
- d = dest.ref.firstChild()
- while s:
- print s,d
- try:
- label = s.getAttribute("inkscape:label")
- # Use i8nkscape:label to identidy the equipvalent objects
- if label:
- if dests.hasattr(label.value()):
- self.updateTweenObject(obj,typ,s,dests[label.value()],percent)
- s = s.next()
- continue
- except:
- pass
- # Search obejcts in the destination
- while d:
- try:
- d.getAttribute("inkscape:label")
- d = d.next()
- continue
- except:
- pass
- if s.name() == d.name():
- self.updateTweenObject(obj,typ,s,d,percent)
- d = d.next()
- break
- d = d.next()
- s = s.next()
- def parseTransform(self,obj):
- """
- Return the transform matrix of an object
- """
- try:
- t = obj.getAttribute("transform")
- print t
- if t[0:9] == 'translate':
- print "translate"
- fields = t[10:].split(',')
- x = float(fields[0])
- fields = fields[1].split(')')
- y = float(fields[0])
- return [1,0,0,1,x,y]
- elif t[0:6] == 'matrix':
- print "matrix"
- fields=t[7:].split(')')
- fields = fields[0].split(',')
- return [float(fields[0]),float(fields[1]),float(fields[2]),float(fields[3]),float(fields[4]),float(fields[5])]
- except:
- #traceback.print_exc()
- return [1,0,0,1,0,0]
-
- def invA(self,m):
- d = m[0]*m[3]-m[2]*m[1]
- return [m[3]/d, -m[1]/d, -m[2]/d, m[0]/d, (m[1]*m[5]-m[4]*m[3])/d, (m[4]*m[2]-m[0]*m[5])/d]
- def mulA(self,a,b):
- return [a[0]*b[0]+a[1]*b[2],
- a[0]*b[1]+a[1]*b[3],
- a[2]*b[0]+a[3]*b[2],
- a[2]*b[1]+a[3]*b[3],
- a[0]*b[4]+a[1]*b[5]+a[4],
- a[2]*b[4]+a[3]*b[5]+a[5]]
- def parseMatrix(self,m):
- d = (1-m[0])*(1-m[3])-m[1]*m[2]
- if d == 0:
- return [1,0,0,1,m[4],m[5]]
- else:
- return [m[0],m[1],m[2],m[3],(m[4]-m[3]*m[4]+m[1]*m[5])/d,(m[5]-m[0]*m[5]+m[2]*m[4])/d]
-
- def decomposition(self,m):
- """
- Decompose the affine matrix into production of translation,rotation,shear and scale.
- The algorithm is documented at http://lists.w3.org/Archives/Public/www-style/2010Jun/0602.html
+ Find the corresponding PYSPObject object for a DOM object.
"""
- if m[0]*m[3] == m[1]*m[2]:
- print "The affine matrix is singular"
- return [1,0,0,1,0,0]
- A=m[0]
- B=m[2]
- C=m[1]
- D=m[3]
- E=m[4]
- F=m[5]
- sx = math.sqrt(A*A+B*B)
- A = A/sx
- B = B/sx
- shear = m[0]*m[1]+m[2]*m[3]
- C = C - A*shear
- D = D - B*shear
- sy = math.sqrt(C*C+D*D)
- C = C/sy
- D = D/sy
- r = A*D-B*C
- if r == -1:
- shear = -shear
- sy = -sy
- R = math.atan2(B,A)
- return [sx,sy, R, E,F]
+ return self.DOMtoItem_recursive(self.desktop.doc().root(),obj)
-
- def updateTweenObject(self,obj,typ,s,d,p):
- """
- Generate tweened object in the @obj by using s and d in the @p percent
- http://lists.w3.org/Archives/Public/www-style/2010Jun/0602.html
- """
- print 'compare',s,d
- if typ == 'relocate':
- print "percent",p
- newobj = s.duplicate(self.document)
- newobj.setAttribute("ref", s.getAttribute('id'))
- top = self.document.createElement("svg:g")
- top.appendChild(newobj)
- obj.appendChild(top)
- print s.name()
- if s.name() == 'svg:g':
- # Parse the translate or matrix
- sm = self.parseTransform(s)
- dm = self.parseTransform(d)
- top.setAttribute("transform","translate(%g,%g)" % ((dm[2]-sm[2])*p,(dm[5]-sm[5])*p))
- else:
- try:
- sx = float(s.getAttribute("x"))
- sy = float(s.getAttribute("y"))
- dx = float(d.getAttribute("x"))
- dy = float(d.getAttribute("y"))
- tx = (dx-sx)*p
- ty = (dy-sy)*p
- print tx,ty
- top.setAttribute("transform","translate(%g,%g)" % (tx,ty))
- except:
- #traceback.print_exc()
- pass
- pass
- elif typ == 'scale':
- newobj = s.duplicate(self.document)
- top = self.document.createElement("svg:g")
- top.appendChild(newobj)
- obj.appendChild(top)
-
- print s,d
- if s.name() == 'svg:g':
- # Parse the translate or matrix
- #
- # D = B inv(A)
- item = s.spitem
- (ox,oy) = item.getCenter()
- item = d.spitem
- (dx,dy) = item.getCenter()
-
- sm = self.parseTransform(s)
- ss = self.decomposition(sm)
- dm = self.parseTransform(d)
- dd = self.decomposition(dm)
- sx = (ss[0]*(1-p)+dd[0]*p)/ss[0]
- sy = (ss[1]*(1-p)+dd[1]*p)/ss[0]
- a = ss[2]*(1-p)+dd[2]*p-ss[2]
- tx = ox*(1-p)+dx*p-ox
- ty = oy*(1-p)+dy*p-oy
- m = [math.cos(a),math.sin(a),-math.sin(a),math.cos(a),0,0]
- m = self.mulA([sx,0,0,sy,0,0],m)
- m = self.mulA(m,[1,0,0,1,-ox,oy-self.height])
- m = self.mulA([1,0,0,1,tx,self.height-ty],m)
+ def DOMtoItem_recursive(self,tree,obj):
+ nodes = tree.childList()
+ for s in nodes:
+ if s.getId() == obj.getAttribute('id'):
+ return s
+ d = self.DOMtoItem_recursive(s,obj)
+ if d != None: return d
+
- top.setAttribute("transform","matrix(%g,%g,%g,%g,%g,%g)" % (m[0],m[2],m[1],m[3],m[4],m[5]))
- else:
- try:
- sw = float(s.getAttribute("width"))
- sh = float(s.getAttribute("height"))
- dw = float(d.getAttribute("width"))
- dh = float(d.getAttribute("height"))
- try:
- item = self.nodeToItem[s.attribute("id")]
- (ox,oy) = item.getCenter()
- except:
- ox = 0
- oy = 0
- try:
- item = self.nodeToItem[d.attribute("id")]
- (dx,dy) = item.getCenter()
- except:
- dx = 0
- dy = 0
- try:
- sm = self.parseTransform(s)
- ss = self.decomposition(sm)
- except:
- ss = [1,1,0,0,0]
- pass
- try:
- dm = self.parseTransform(d)
- dd = self.decomposition(dm)
- except:
- dd = [1,1,0,0,0]
- pass
- dd[0] = ss[0]*dw/sw
- dd[1] = ss[1]*dh/sh
- sx = (ss[0]*(1-p)+dd[0]*p)/ss[0]
- sy = (ss[1]*(1-p)+dd[1]*p)/ss[1]
- a = ss[2]*(1-p)+dd[2]*p-ss[2]
- tx = ox*(1-p)+dx*p
- ty = oy*(1-p)+dy*p
- m = [math.cos(a),math.sin(a),-math.sin(a),math.cos(a),0,0]
- m = self.mulA([sx,0,0,sy,0,0],m)
- m = self.mulA(m,[1,0,0,1,-ox,oy-self.height])
- m = self.mulA([1,0,0,1,tx,self.height-ty],m)
-
- top.setAttribute("transform","matrix(%g,%g,%g,%g,%g,%g)" % (m[0],m[2],m[1],m[3],m[4],m[5]))
- except:
- traceback.print_exc()
- pass
- pass
-
- pass
def enterGroup(self,obj):
for l in self.layers:
for s in l.node.childList():
if s.getAttribute('id') == obj.getAttribute("id"):
- self.desktop.setCurrentLayer(s.spitem)
+ self.desktop.setCurrentLayer(self.DOMtoItem(s))
def selectSceneObject(self,frameline, nth):
i = 0
@@ -898,7 +666,7 @@
for i in range(len(self.layers)-1,-1,-1):
line = frameline.frameline(nframes)
hbox = gtk.HBox()
- label = gtk.Label(self.layers[i].node.getAttribute('inkscape:label'))
+ label = gtk.Label(self.layers[i].node.getAttribute("inkscape:label"))
label.set_size_request(100,0)
hbox.pack_start(label,expand=False,fill=True)
hbox.pack_start(line)
@@ -919,11 +687,10 @@
def _update_framelines(self):
for frameline in self._framelines:
layer = frameline.layer
- try:
- frameline.label.set_text(frameline.node.getAttribute('inkscape:label'))
- except KeyError:
- frameline.label.set_text('???')
- pass
+ if frameline.node.getAttribute("inkscape:label")==None:
+ frameline.label.set_text('???')
+ else:
+ frameline.label.set_text(frameline.node.getAttribute("inkscape:label"))
for scene in layer.scenes:
frameline.add_keyframe(scene.start-1,scene.node)
if scene.start != scene.end:
@@ -964,10 +731,10 @@
i = i + 1
def duplicateSceneGroup(self,gid):
# Search for the duplicated group
- root = self.document.root()
+ doc = self.dom
rdoc = self.document
orig = None
- for node in root.childList():
+ for node in doc.childList():
if node.name() == 'svg:g':
for t in node.childList():
if t.name() == "svg:g":
@@ -977,12 +744,7 @@
if orig == None:
return None
ns = orig.duplicate(rdoc)
- try:
- gid = self.last_line.node.getAttribute('inkscape:label') + \
- self.newID()
- except KeyError:
- gid = self.newID()
- pass
+ gid = self.last_line.node.label()+self.newID()
self.ID[gid]=1
ns.setAttribute("id",gid)
ns.setAttribute("inkscape:groupmode","layer")
@@ -1113,7 +875,9 @@
self.last_update = glib.timeout_add(300,self.show)
def show(self):
self.OK = True
+ self.dom = self.desktop.doc().root().repr
self.document = self.desktop.doc().rdoc
+ self.tween = TweenObject(self.document,self.dom)
self.parseScene()
self._create_framelines()
self._update_framelines()
diff -r a2b068594412 -r 8f0ee167c5b2 pyink/primitive_test.svg
--- a/pyink/primitive_test.svg Wed Dec 22 13:27:37 2010 +0800
+++ b/pyink/primitive_test.svg Thu Dec 23 00:00:46 2010 +0800
@@ -15,7 +15,7 @@
id="svg2"
version="1.1"
inkscape:version="0.48+devel r9774 custom"
- sodipodi:docname="aa.svg">
+ sodipodi:docname="primitive_test.svg">
@@ -84,8 +85,8 @@
id="rect3431"
height="432.13434"
width="64.699173"
- y="213.35323"
- x="9.338623" />
+ y="220.30684"
+ x="3.5009925" />
diff -r a2b068594412 -r 8f0ee167c5b2 pyink/tween.py
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/pyink/tween.py Thu Dec 23 00:00:46 2010 +0800
@@ -0,0 +1,278 @@
+# -*- indent-tabs-mode: t; tab-width: 8; python-indent: 4; -*-
+# vim: sw=4:ts=8:sts=4
+import traceback
+import math
+class TweenObject:
+ def __init__(self,doc,dom):
+ self.document = doc
+ self.dom = dom
+ try:
+ self.width = float(dom.getAttribute("width"))
+ self.height = float(dom.getAttribute("height"))
+ except:
+ self.width = 640
+ self.height = 480
+
+ def updateMapping(self):
+ self.nodeToItem={}
+ root = self.dom
+ self.updateMappingNode(root)
+ def updateMappingNode(self,node):
+ for c in node.childList():
+ self.updateMappingNode(c)
+ try:
+ self.nodeToItem[c.getAttribute("id")] = c
+ except:
+ pass
+ def updateTweenContent(self,obj, typ, source,dest,cur):
+ """
+ Update the content of the duplicate scene group. We will use the (start,end) and cur to calculate the percentage of
+ the tween motion effect and then use it to update the transform matrix of the duplicated scene group.
+ """
+
+ start = source.idx
+ end = dest.idx
+ print cur,start,end
+ percent = (cur-start)*1.0/(end-start)
+ i = 0
+ s = source.ref.firstChild()
+ d = dest.ref.firstChild()
+ sources={}
+ dests={}
+
+ # Collect all objects
+ while d:
+ try:
+ label = d.getAttribute("inkscape:label")
+ except:
+ d = d.next()
+ continue
+ dests[label] = d
+ d = d.next()
+ # Check if the object in the source exists in the destination
+ s = source.ref.firstChild()
+ d = dest.ref.firstChild()
+ while s:
+ print s,d
+ try:
+ label = s.getAttribute("inkscape:label")
+ # Use i8nkscape:label to identidy the equipvalent objects
+ if label:
+ if dests.hasattr(label.value()):
+ self.updateTweenObject(obj,typ,s,dests[label.value()],percent)
+ s = s.next()
+ continue
+ except:
+ pass
+ # Search obejcts in the destination
+ while d:
+ try:
+ d.getAttribute("inkscape:label")
+ d = d.next()
+ continue
+ except:
+ pass
+ if s.name() == d.name():
+ self.updateTweenObject(obj,typ,s,d,percent)
+ d = d.next()
+ break
+ d = d.next()
+ s = s.next()
+
+ def parseTransform(self,obj):
+ """
+ Return the transform matrix of an object
+ """
+ try:
+ t = obj.getAttribute("transform")
+ print t
+ if t[0:9] == 'translate':
+ print "translate"
+ fields = t[10:].split(',')
+ x = float(fields[0])
+ fields = fields[1].split(')')
+ y = float(fields[0])
+ return [1,0,0,1,x,y]
+ elif t[0:6] == 'matrix':
+ print "matrix"
+ fields=t[7:].split(')')
+ fields = fields[0].split(',')
+ return [float(fields[0]),float(fields[1]),float(fields[2]),float(fields[3]),float(fields[4]),float(fields[5])]
+ except:
+ #traceback.print_exc()
+ return [1,0,0,1,0,0]
+
+ def invA(self,m):
+ d = m[0]*m[3]-m[2]*m[1]
+ return [m[3]/d, -m[1]/d, -m[2]/d, m[0]/d, (m[1]*m[5]-m[4]*m[3])/d, (m[4]*m[2]-m[0]*m[5])/d]
+
+ def mulA(self,a,b):
+ return [a[0]*b[0]+a[1]*b[2],
+ a[0]*b[1]+a[1]*b[3],
+ a[2]*b[0]+a[3]*b[2],
+ a[2]*b[1]+a[3]*b[3],
+ a[0]*b[4]+a[1]*b[5]+a[4],
+ a[2]*b[4]+a[3]*b[5]+a[5]]
+
+ def decomposition(self,m):
+ """
+ Decompose the affine matrix into production of translation,rotation,shear and scale.
+ The algorithm is documented at http://lists.w3.org/Archives/Public/www-style/2010Jun/0602.html
+ """
+ if m[0]*m[3] == m[1]*m[2]:
+ print "The affine matrix is singular"
+ return [1,0,0,1,0,0]
+ A=m[0]
+ B=m[2]
+ C=m[1]
+ D=m[3]
+ E=m[4]
+ F=m[5]
+ sx = math.sqrt(A*A+B*B)
+ A = A/sx
+ B = B/sx
+ shear = m[0]*m[1]+m[2]*m[3]
+ C = C - A*shear
+ D = D - B*shear
+ sy = math.sqrt(C*C+D*D)
+ C = C/sy
+ D = D/sy
+ r = A*D-B*C
+ if r == -1:
+ shear = -shear
+ sy = -sy
+ R = math.atan2(B,A)
+ return [sx,sy, R, E,F]
+
+
+ def updateTweenObject(self,obj,typ,s,d,p):
+ """
+ Generate tweened object in the @obj by using s and d in the @p percent
+ http://lists.w3.org/Archives/Public/www-style/2010Jun/0602.html
+ """
+ if typ == 'relocate':
+ newobj = s.duplicate(self.document)
+ newobj.setAttribute("ref", s.getAttribute("id"))
+ top = self.document.createElement("svg:g")
+ top.appendChild(newobj)
+ obj.appendChild(top)
+ if s.name() == 'svg:g':
+ # Parse the translate or matrix
+ sm = self.parseTransform(s)
+ dm = self.parseTransform(d)
+ top.setAttribute("transform","translate(%g,%g)" % ((dm[2]-sm[2])*p,(dm[5]-sm[5])*p))
+ else:
+ try:
+ sx = float(s.getAttribute("x"))
+ sy = float(s.getAttribute("y"))
+ dx = float(d.getAttribute("x"))
+ dy = float(d.getAttribute("y"))
+ tx = (dx-sx)*p
+ ty = (dy-sy)*p
+ print tx,ty
+ top.setAttribute("transform","translate(%g,%g)" % (tx,ty))
+ except:
+ traceback.print_exc()
+ pass
+ pass
+ elif typ == 'scale':
+ self.updateTweenObjectScale(obj,s,d,p)
+ pass
+ elif typ == 'normal':
+ newobj = s.duplicate(self.document)
+ newobj.setAttribute("ref", s.getAttribute("id"))
+ top = self.document.createElement("svg:g")
+ top.appendChild(newobj)
+ obj.appendChild(top)
+ pass
+
+ def updateTweenObjectScale(self,obj,s,d,p):
+ """
+ Generate a new group which contains the original group and then
+ add the transform matrix to generate a tween frame between the
+ origin and destination scene group.
+
+ We will parse the transform matrix of the @s and @d and then
+ generate the matrix which is (1-p) of @s and p percent of @d.
+ """
+ newobj = s.duplicate(self.document)
+ top = self.document.createElement("svg:g")
+ top.appendChild(newobj)
+ obj.appendChild(top)
+
+ if s.name() == 'svg:g':
+ # Parse the translate or matrix
+ #
+ # D = B inv(A)
+ try:
+ item = self.nodeToItem[s.getAttribute("id")]
+ (ox,oy) = item.getCenter()
+ except:
+ ox = 0
+ oy = 0
+ try:
+ item = self.nodeToItem[d.getAttribute("id")]
+ (dx,dy) = item.getCenter()
+ except:
+ dx = 0
+ dy = 0
+
+ sm = self.parseTransform(s)
+ ss = self.decomposition(sm)
+ dm = self.parseTransform(d)
+ dd = self.decomposition(dm)
+ sx = (ss[0]*(1-p)+dd[0]*p)/ss[0]
+ sy = (ss[1]*(1-p)+dd[1]*p)/ss[0]
+ a = ss[2]*(1-p)+dd[2]*p-ss[2]
+ tx = ox*(1-p)+dx*p-ox
+ ty = oy*(1-p)+dy*p-oy
+ m = [math.cos(a),math.sin(a),-math.sin(a),math.cos(a),0,0]
+ m = self.mulA([sx,0,0,sy,0,0],m)
+ m = self.mulA(m,[1,0,0,1,-ox,oy-self.height])
+ m = self.mulA([1,0,0,1,tx,self.height-ty],m)
+
+ top.setAttribute("transform","matrix(%g,%g,%g,%g,%g,%g)" % (m[0],m[2],m[1],m[3],m[4],m[5]))
+ else:
+ try:
+ sw = float(s.getAttribute("width"))
+ sh = float(s.getAttribute("height"))
+ dw = float(d.getAttribute("width"))
+ dh = float(d.getAttribute("height"))
+ try:
+ item = self.nodeToItem[s.getAttribute("id")]
+ (ox,oy) = item.getCenter()
+ except:
+ ox = 0
+ oy = 0
+ try:
+ item = self.nodeToItem[d.getAttribute("id")]
+ (dx,dy) = item.getCenter()
+ except:
+ dx = 0
+ dy = 0
+ try:
+ sm = self.parseTransform(s)
+ ss = self.decomposition(sm)
+ except:
+ ss = [1,1,0,0,0]
+ pass
+ try:
+ dm = self.parseTransform(d)
+ dd = self.decomposition(dm)
+ except:
+ dd = [1,1,0,0,0]
+ dd[0] = ss[0]*dw/sw
+ dd[1] = ss[1]*dh/sh
+ sx = (ss[0]*(1-p)+dd[0]*p)/ss[0]
+ sy = (ss[1]*(1-p)+dd[1]*p)/ss[1]
+ a = ss[2]*(1-p)+dd[2]*p-ss[2]
+ tx = ox*(1-p)+dx*p
+ ty = oy*(1-p)+dy*p
+ m = [math.cos(a),math.sin(a),-math.sin(a),math.cos(a),0,0]
+ m = self.mulA([sx,0,0,sy,0,0],m)
+ m = self.mulA(m,[1,0,0,1,-ox,oy-self.height])
+ m = self.mulA([1,0,0,1,tx,self.height-ty],m)
+
+ top.setAttribute("transform","matrix(%g,%g,%g,%g,%g,%g)" % (m[0],m[2],m[1],m[3],m[4],m[5]))
+ except:
+ traceback.print_exc()