--- SvgParser-alpha1.1.4.lua 2012-04-17 08:27:20.000000000 +0100
+++ SvgParser.lua 2012-04-20 14:08:50.000000000 +0100
@@ -1,6 +1,37 @@
SvgParser = Core.class()
+-- New declarations for SVG symbol processing
+-- Added by AWB 20/APR/2012
+local symbols={}
+function table.deepcopy(object)
+ local lookup_table = {}
+ local function _copy(object)
+ if type(object) ~= "table" then
+ return object
+ elseif lookup_table[object] then
+ return lookup_table[object]
+ end
+ local new_table = {}
+ lookup_table[object] = new_table
+ for index, value in pairs(object) do
+ new_table[_copy(index)] = _copy(value)
+ end
+ return setmetatable(new_table, getmetatable(object))
+ end
+ return _copy(object)
+end
+
+function Matrix:multiply(matrix)
+ local tx = self:getTx() + matrix:getTx()
+ local ty = self:getTy() + matrix:getTy()
+ local m11 = matrix:getM11() * self:getM11() + matrix:getM12() * self:getM21()
+ local m21 = matrix:getM21() * self:getM11() + matrix:getM22() * self:getM21()
+ local m12 = matrix:getM11() * self:getM12() + matrix:getM12() * self:getM22()
+ local m22 = matrix:getM21() * self:getM12() + matrix:getM22() * self:getM22()
+ return Matrix.new(m11, m12, m21, m22, tx, ty)
+end
+--- End AWB 20/APR/2012
-----------------------------------------------------------------------------------------------------------
--[[ PRIVATE ]]
@@ -224,6 +255,54 @@
obj:setMatrix( matrix ) -- Matrix
end
+ --[[ ADDED BY AWB 20/APR/2012 ]]
+ if t.Name == "symbol" then
+ -- Register a Symbol with our symbol table.
+ -- print("symbol", t.Attributes.id, t.Attributes.viewBox, t.ChildNodes)
+
+ for i,child in ipairs( t.ChildNodes ) do -- restart cycle
+ -- I'm not sure if symbols can contain more than one node in their definition
+ -- but here we only allow a single node
+ assert(i==1, "found more than one symbol node")
+
+ -- print( string.format("recording symbol: %s as %s", t.Attributes.id, child.Name ))
+ -- Record the child node in our symbol table
+ symbols["#"..t.Attributes.id]=child
+ end
+ end
+
+ --[[ ADDED BY AWB 20/APR/2012]]
+ if t.Name == "use" then
+ -- Use a pre-registered symbol. Fetch a copy of the definition node from the symbol table.
+ -- We have to make a deep copy because process_data() will modify it. Note, it would
+ -- be more efficient to change process_data() keep the node it is processing intact.
+
+ local symbol=table.deepcopy(symbols[t.Attributes.href])
+ -- print( string.format("use symbol: %s(%s)", t.Attributes.href, symbolChild.Name))
+
+ -- Process the node and retrieve the object instance that has been created
+ process_data( symbol, groups )
+ obj=groups:getChildAt(groups:getNumChildren())
+
+ -- Symbol "use" nodes that have transforms appear to have a coordinate system based around the
+ -- centre of the symbol viewport. Here we must create a translation to account for this.
+ x=Matrix.new()
+ if symbol.Attributes.transform then
+ local w=obj:getWidth()
+ local h=obj:getHeight()
+ local sx=matrix:getM11()
+ local sy=-matrix:getM22()
+ local tx=w/2-w*sx/2
+ local ty=-h/2-h*sy/2
+ local t=Matrix.new(1, 0, 0, 1, tx, ty)
+ x=x:multiply(t)
+ end
+
+ -- Apply the instance transformation and our translation matrix (if any)
+ x=x:multiply(matrix):multiply(obj:getMatrix())
+ obj:setMatrix(x)
+ end
+
-----------------------------------------------------------------------------------------------------------
-----------------------------------------------------------------------------------------------------------