Code

Extensions. Fix EOL inconsistencies (Bug #314381).
authorJazzyNico <nicoduf@yahoo.fr>
Mon, 30 Aug 2010 11:29:57 +0000 (13:29 +0200)
committerJazzyNico <nicoduf@yahoo.fr>
Mon, 30 Aug 2010 11:29:57 +0000 (13:29 +0200)
share/extensions/aisvg.xslt
share/extensions/colors.xml
share/extensions/convert2dashes.inx
share/extensions/guillotine.inx
share/extensions/guillotine.py
share/extensions/param_curves.inx
share/extensions/param_curves.py
share/extensions/render_alphabetsoup.py
share/extensions/svg2xaml.xsl
share/extensions/xaml2svg.xsl

index 62a10ee935fadcf05a2d3468ad660c97651cf140..2faebc7f34238bc192f4cc26f008971f0f23c818 100644 (file)
@@ -1,36 +1,36 @@
-<?xml version="1.0"?>\r
-<xsl:stylesheet  xml:space="default" version="1.0" \r
-xmlns:xsl="http://www.w3.org/1999/XSL/Transform"\r
-xmlns="http://www.w3.org/2000/svg"\r
-xmlns:svg="http://www.w3.org/2000/svg"\r
-xmlns:xlink="http://www.w3.org/1999/xlink"\r
-xmlns:x="http://ns.adobe.com/Extensibility/1.0/" \r
-xmlns:i="http://ns.adobe.com/AdobeIllustrator/10.0/" \r
-xmlns:graph="http://ns.adobe.com/Graphs/1.0/" \r
-xmlns:a="http://ns.adobe.com/AdobeSVGViewerExtensions/3.0/" \r
-xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"\r
->\r
-<xsl:output indent="yes"/>\r
-       <xsl:template match="/">\r
-                       <xsl:apply-templates />\r
-       </xsl:template>\r
-  <xsl:template match="svg:svg/svg:switch[count(*)=2][name(*[1])='foreignObject']">\r
-               <xsl:apply-templates select="*[not(name()='foreignObject')]/*"/>\r
-  </xsl:template>\r
-       <xsl:template match="svg:svg/svg:g | svg:g[@i:extraneous='self']/svg:g">\r
-               <xsl:copy>\r
-      <xsl:attribute name="inkscape:groupmode">layer</xsl:attribute>\r
-                       <xsl:apply-templates select="@*|*"/>\r
-    </xsl:copy>\r
-  </xsl:template>\r
-       <xsl:template match="*">\r
-               <xsl:copy>\r
-               <xsl:apply-templates select="@*|node()|text"/>\r
-               </xsl:copy>\r
-       </xsl:template>\r
-       <xsl:template match="@*">\r
-               <xsl:copy/>\r
-       </xsl:template>\r
-       <xsl:template match="i:*|@i:*|x:*|@x:*|graph:*|@graph:*|a:*|@a:*">\r
-       </xsl:template>\r
-</xsl:stylesheet>\r
+<?xml version="1.0"?>
+<xsl:stylesheet  xml:space="default" version="1.0" 
+xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
+xmlns="http://www.w3.org/2000/svg"
+xmlns:svg="http://www.w3.org/2000/svg"
+xmlns:xlink="http://www.w3.org/1999/xlink"
+xmlns:x="http://ns.adobe.com/Extensibility/1.0/" 
+xmlns:i="http://ns.adobe.com/AdobeIllustrator/10.0/" 
+xmlns:graph="http://ns.adobe.com/Graphs/1.0/" 
+xmlns:a="http://ns.adobe.com/AdobeSVGViewerExtensions/3.0/" 
+xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+>
+<xsl:output indent="yes"/>
+       <xsl:template match="/">
+                       <xsl:apply-templates />
+       </xsl:template>
+  <xsl:template match="svg:svg/svg:switch[count(*)=2][name(*[1])='foreignObject']">
+               <xsl:apply-templates select="*[not(name()='foreignObject')]/*"/>
+  </xsl:template>
+       <xsl:template match="svg:svg/svg:g | svg:g[@i:extraneous='self']/svg:g">
+               <xsl:copy>
+      <xsl:attribute name="inkscape:groupmode">layer</xsl:attribute>
+                       <xsl:apply-templates select="@*|*"/>
+    </xsl:copy>
+  </xsl:template>
+       <xsl:template match="*">
+               <xsl:copy>
+               <xsl:apply-templates select="@*|node()|text"/>
+               </xsl:copy>
+       </xsl:template>
+       <xsl:template match="@*">
+               <xsl:copy/>
+       </xsl:template>
+       <xsl:template match="i:*|@i:*|x:*|@x:*|graph:*|@graph:*|a:*|@a:*">
+       </xsl:template>
+</xsl:stylesheet>
index d877113d79bf0ae3aae6653844b37ff32a2f171c..51167fdd7fe11d49907555641fe60929e1738475 100644 (file)
-<?xml version="1.0" encoding="UTF-8"?>\r
-<colors>\r
-<color name="aliceblue" hex="#f0f8ff" rgb="240,248,255" />\r
-<color name="antiquewhite" hex="#faebd7" rgb="250,235,215" />\r
-<color name="aqua" hex="#00ffff" rgb="0,255,255" />\r
-<color name="aquamarine" hex="#7fffd4" rgb="127,255,212" />\r
-<color name="azure" hex="#f0ffff" rgb="240,255,255" />\r
-<color name="beige" hex="#f5f5dc" rgb="245,245,220" />\r
-<color name="bisque" hex="#ffe4c4" rgb="255,228,196" />\r
-<color name="black" hex="#000000" rgb="0,0,0" />\r
-<color name="blanchedalmond" hex="#ffebcd" rgb="255,235,205" />\r
-<color name="blue" hex="#0000ff" rgb="0,0,255" />\r
-<color name="blueviolet" hex="#8a2be2" rgb="138,43,226" />\r
-<color name="brown" hex="#a52a2a" rgb="165,42,42" />\r
-<color name="burlywood" hex="#deb887" rgb="222,184,135" />\r
-<color name="cadetblue" hex="#5f9ea0" rgb="95,158,160" />\r
-<color name="chartreuse" hex="#7fff00" rgb="127,255,0" />\r
-<color name="chocolate" hex="#d2691e" rgb="210,105,30" />\r
-<color name="coral" hex="#ff7f50" rgb="255,127,80" />\r
-<color name="cornflowerblue" hex="#6495ed" rgb="100,149,237" />\r
-<color name="cornsilk" hex="#fff8dc" rgb="255,248,220" />\r
-<color name="crimson" hex="#dc143c" rgb="220,20,60" />\r
-<color name="cyan" hex="#00ffff" rgb="0,255,255" />\r
-<color name="darkblue" hex="#00008b" rgb="0,0,139" />\r
-<color name="darkcyan" hex="#008b8b" rgb="0,139,139" />\r
-<color name="darkgoldenrod" hex="#b8860b" rgb="184,134,11" />\r
-<color name="darkgray" hex="#a9a9a9" rgb="169,169,169" />\r
-<color name="darkgreen" hex="#006400" rgb="0,100,0" />\r
-<color name="darkgrey" hex="#a9a9a9" rgb="169,169,169" />\r
-<color name="darkkhaki" hex="#bdb76b" rgb="189,183,107" />\r
-<color name="darkmagenta" hex="#8b008b" rgb="139,0,139" />\r
-<color name="darkolivegreen" hex="#556b2f" rgb="85,107,47" />\r
-<color name="darkorange" hex="#ff8c00" rgb="255,140,0" />\r
-<color name="darkorchid" hex="#9932cc" rgb="153,50,204" />\r
-<color name="darkred" hex="#8b0000" rgb="139,0,0" />\r
-<color name="darksalmon" hex="#e9967a" rgb="233,150,122" />\r
-<color name="darkseagreen" hex="#8fbc8f" rgb="143,188,143" />\r
-<color name="darkslateblue" hex="#483d8b" rgb="72,61,139" />\r
-<color name="darkslategray" hex="#2f4f4f" rgb="47,79,79" />\r
-<color name="darkslategrey" hex="#2f4f4f" rgb="47,79,79" />\r
-<color name="darkturquoise" hex="#00ced1" rgb="0,206,209" />\r
-<color name="darkviolet" hex="#9400d3" rgb="148,0,211" />\r
-<color name="deeppink" hex="#ff1493" rgb="255,20,147" />\r
-<color name="deepskyblue" hex="#00bfff" rgb="0,191,255" />\r
-<color name="dimgray" hex="#696969" rgb="105,105,105" />\r
-<color name="dimgrey" hex="#696969" rgb="105,105,105" />\r
-<color name="dodgerblue" hex="#1e90ff" rgb="30,144,255" />\r
-<color name="firebrick" hex="#b22222" rgb="178,34,34" />\r
-<color name="floralwhite" hex="#fffaf0" rgb="255,250,240" />\r
-<color name="forestgreen" hex="#228b22" rgb="34,139,34" />\r
-<color name="fuchsia" hex="#ff00ff" rgb="255,0,255" />\r
-<color name="gainsboro" hex="#dcdcdc" rgb="220,220,220" />\r
-<color name="ghostwhite" hex="#f8f8ff" rgb="248,248,255" />\r
-<color name="gold" hex="#ffd700" rgb="255,215,0" />\r
-<color name="goldenrod" hex="#daa520" rgb="218,165,32" />\r
-<color name="gray" hex="#808080" rgb="128,128,128" />\r
-<color name="green" hex="#008000" rgb="0,128,0" />\r
-<color name="greenyellow" hex="#adff2f" rgb="173,255,47" />\r
-<color name="grey" hex="#808080" rgb="128,128,128" />\r
-<color name="honeydew" hex="#f0fff0" rgb="240,255,240" />\r
-<color name="hotpink" hex="#ff69b4" rgb="255,105,180" />\r
-<color name="indianred" hex="#cd5c5c" rgb="205,92,92" />\r
-<color name="indigo" hex="#4b0082" rgb="75,0,130" />\r
-<color name="ivory" hex="#fffff0" rgb="255,255,240" />\r
-<color name="khaki" hex="#f0e68c" rgb="240,230,140" />\r
-<color name="lavender" hex="#e6e6fa" rgb="230,230,250" />\r
-<color name="lavenderblush" hex="#fff0f5" rgb="255,240,245" />\r
-<color name="lawngreen" hex="#7cfc00" rgb="124,252,0" />\r
-<color name="lemonchiffon" hex="#fffacd" rgb="255,250,205" />\r
-<color name="lightblue" hex="#add8e6" rgb="173,216,230" />\r
-<color name="lightcoral" hex="#f08080" rgb="240,128,128" />\r
-<color name="lightcyan" hex="#e0ffff" rgb="224,255,255" />\r
-<color name="lightgoldenrodyellow" hex="#fafad2" rgb="250,250,210" />\r
-<color name="lightgray" hex="#d3d3d3" rgb="211,211,211" />\r
-<color name="lightgreen" hex="#90ee90" rgb="144,238,144" />\r
-<color name="lightgrey" hex="#d3d3d3" rgb="211,211,211" />\r
-<color name="lightpink" hex="#ffb6c1" rgb="255,182,193" />\r
-<color name="lightsalmon" hex="#ffa07a" rgb="255,160,122" />\r
-<color name="lightseagreen" hex="#20b2aa" rgb="32,178,170" />\r
-<color name="lightskyblue" hex="#87cefa" rgb="135,206,250" />\r
-<color name="lightslategray" hex="#778899" rgb="119,136,153" />\r
-<color name="lightslategrey" hex="#778899" rgb="119,136,153" />\r
-<color name="lightsteelblue" hex="#b0c4de" rgb="176,196,222" />\r
-<color name="lightyellow" hex="#ffffe0" rgb="255,255,224" />\r
-<color name="lime" hex="#00ff00" rgb="0,255,0" />\r
-<color name="limegreen" hex="#32cd32" rgb="50,205,50" />\r
-<color name="linen" hex="#faf0e6" rgb="250,240,230" />\r
-<color name="magenta" hex="#ff00ff" rgb="255,0,255" />\r
-<color name="maroon" hex="#800000" rgb="128,0,0" />\r
-<color name="mediumaquamarine" hex="#66cdaa" rgb="102,205,170" />\r
-<color name="mediumblue" hex="#0000cd" rgb="0,0,205" />\r
-<color name="mediumorchid" hex="#ba55d3" rgb="186,85,211" />\r
-<color name="mediumpurple" hex="#9370db" rgb="147,112,219" />\r
-<color name="mediumseagreen" hex="#3cb371" rgb="60,179,113" />\r
-<color name="mediumslateblue" hex="#7b68ee" rgb="123,104,238" />\r
-<color name="mediumspringgreen" hex="#00fa9a" rgb="0,250,154" />\r
-<color name="mediumturquoise" hex="#48d1cc" rgb="72,209,204" />\r
-<color name="mediumvioletred" hex="#c71585" rgb="199,21,133" />\r
-<color name="midnightblue" hex="#191970" rgb="25,25,112" />\r
-<color name="mintcream" hex="#f5fffa" rgb="245,255,250" />\r
-<color name="mistyrose" hex="#ffe4e1" rgb="255,228,225" />\r
-<color name="moccasin" hex="#ffe4b5" rgb="255,228,181" />\r
-<color name="navajowhite" hex="#ffdead" rgb="255,222,173" />\r
-<color name="navy" hex="#000080" rgb="0,0,128" />\r
-<color name="oldlace" hex="#fdf5e6" rgb="253,245,230" />\r
-<color name="olive" hex="#808000" rgb="128,128,0" />\r
-<color name="olivedrab" hex="#6b8e23" rgb="107,142,35" />\r
-<color name="orange" hex="#ffa500" rgb="255,165,0" />\r
-<color name="orangered" hex="#ff4500" rgb="255,69,0" />\r
-<color name="orchid" hex="#da70d6" rgb="218,112,214" />\r
-<color name="palegoldenrod" hex="#eee8aa" rgb="238,232,170" />\r
-<color name="palegreen" hex="#98fb98" rgb="152,251,152" />\r
-<color name="paleturquoise" hex="#afeeee" rgb="175,238,238" />\r
-<color name="palevioletred" hex="#db7093" rgb="219,112,147" />\r
-<color name="papayawhip" hex="#ffefd5" rgb="255,239,213" />\r
-<color name="peachpuff" hex="#ffdab9" rgb="255,218,185" />\r
-<color name="peru" hex="#cd853f" rgb="205,133,63" />\r
-<color name="pink" hex="#ffc0cb" rgb="255,192,203" />\r
-<color name="plum" hex="#dda0dd" rgb="221,160,221" />\r
-<color name="powderblue" hex="#b0e0e6" rgb="176,224,230" />\r
-<color name="purple" hex="#800080" rgb="128,0,128" />\r
-<color name="red" hex="#ff0000" rgb="255,0,0" />\r
-<color name="rosybrown" hex="#bc8f8f" rgb="188,143,143" />\r
-<color name="royalblue" hex="#4169e1" rgb="65,105,225" />\r
-<color name="saddlebrown" hex="#8b4513" rgb="139,69,19" />\r
-<color name="salmon" hex="#fa8072" rgb="250,128,114" />\r
-<color name="sandybrown" hex="#f4a460" rgb="244,164,96" />\r
-<color name="seagreen" hex="#2e8b57" rgb="46,139,87" />\r
-<color name="seashell" hex="#fff5ee" rgb="255,245,238" />\r
-<color name="sienna" hex="#a0522d" rgb="160,82,45" />\r
-<color name="silver" hex="#c0c0c0" rgb="192,192,192" />\r
-<color name="skyblue" hex="#87ceeb" rgb="135,206,235" />\r
-<color name="slateblue" hex="#6a5acd" rgb="106,90,205" />\r
-<color name="slategray" hex="#708090" rgb="112,128,144" />\r
-<color name="slategrey" hex="#708090" rgb="112,128,144" />\r
-<color name="snow" hex="#fffafa" rgb="255,250,250" />\r
-<color name="springgreen" hex="#00ff7f" rgb="0,255,127" />\r
-<color name="steelblue" hex="#4682b4" rgb="70,130,180" />\r
-<color name="tan" hex="#d2b48c" rgb="210,180,140" />\r
-<color name="teal" hex="#008080" rgb="0,128,128" />\r
-<color name="thistle" hex="#d8bfd8" rgb="216,191,216" />\r
-<color name="tomato" hex="#ff6347" rgb="255,99,71" />\r
-<color name="turquoise" hex="#40e0d0" rgb="64,224,208" />\r
-<color name="violet" hex="#ee82ee" rgb="238,130,238" />\r
-<color name="wheat" hex="#f5deb3" rgb="245,222,179" />\r
-<color name="white" hex="#ffffff" rgb="255,255,255" />\r
-<color name="whitesmoke" hex="#f5f5f5" rgb="245,245,245" />\r
-<color name="yellow" hex="#ffff00" rgb="255,255,0" />\r
-<color name="yellowgreen" hex="#9acd32" rgb="154,205,50" />\r
-</colors>\r
+<?xml version="1.0" encoding="UTF-8"?>
+<colors>
+<color name="aliceblue" hex="#f0f8ff" rgb="240,248,255" />
+<color name="antiquewhite" hex="#faebd7" rgb="250,235,215" />
+<color name="aqua" hex="#00ffff" rgb="0,255,255" />
+<color name="aquamarine" hex="#7fffd4" rgb="127,255,212" />
+<color name="azure" hex="#f0ffff" rgb="240,255,255" />
+<color name="beige" hex="#f5f5dc" rgb="245,245,220" />
+<color name="bisque" hex="#ffe4c4" rgb="255,228,196" />
+<color name="black" hex="#000000" rgb="0,0,0" />
+<color name="blanchedalmond" hex="#ffebcd" rgb="255,235,205" />
+<color name="blue" hex="#0000ff" rgb="0,0,255" />
+<color name="blueviolet" hex="#8a2be2" rgb="138,43,226" />
+<color name="brown" hex="#a52a2a" rgb="165,42,42" />
+<color name="burlywood" hex="#deb887" rgb="222,184,135" />
+<color name="cadetblue" hex="#5f9ea0" rgb="95,158,160" />
+<color name="chartreuse" hex="#7fff00" rgb="127,255,0" />
+<color name="chocolate" hex="#d2691e" rgb="210,105,30" />
+<color name="coral" hex="#ff7f50" rgb="255,127,80" />
+<color name="cornflowerblue" hex="#6495ed" rgb="100,149,237" />
+<color name="cornsilk" hex="#fff8dc" rgb="255,248,220" />
+<color name="crimson" hex="#dc143c" rgb="220,20,60" />
+<color name="cyan" hex="#00ffff" rgb="0,255,255" />
+<color name="darkblue" hex="#00008b" rgb="0,0,139" />
+<color name="darkcyan" hex="#008b8b" rgb="0,139,139" />
+<color name="darkgoldenrod" hex="#b8860b" rgb="184,134,11" />
+<color name="darkgray" hex="#a9a9a9" rgb="169,169,169" />
+<color name="darkgreen" hex="#006400" rgb="0,100,0" />
+<color name="darkgrey" hex="#a9a9a9" rgb="169,169,169" />
+<color name="darkkhaki" hex="#bdb76b" rgb="189,183,107" />
+<color name="darkmagenta" hex="#8b008b" rgb="139,0,139" />
+<color name="darkolivegreen" hex="#556b2f" rgb="85,107,47" />
+<color name="darkorange" hex="#ff8c00" rgb="255,140,0" />
+<color name="darkorchid" hex="#9932cc" rgb="153,50,204" />
+<color name="darkred" hex="#8b0000" rgb="139,0,0" />
+<color name="darksalmon" hex="#e9967a" rgb="233,150,122" />
+<color name="darkseagreen" hex="#8fbc8f" rgb="143,188,143" />
+<color name="darkslateblue" hex="#483d8b" rgb="72,61,139" />
+<color name="darkslategray" hex="#2f4f4f" rgb="47,79,79" />
+<color name="darkslategrey" hex="#2f4f4f" rgb="47,79,79" />
+<color name="darkturquoise" hex="#00ced1" rgb="0,206,209" />
+<color name="darkviolet" hex="#9400d3" rgb="148,0,211" />
+<color name="deeppink" hex="#ff1493" rgb="255,20,147" />
+<color name="deepskyblue" hex="#00bfff" rgb="0,191,255" />
+<color name="dimgray" hex="#696969" rgb="105,105,105" />
+<color name="dimgrey" hex="#696969" rgb="105,105,105" />
+<color name="dodgerblue" hex="#1e90ff" rgb="30,144,255" />
+<color name="firebrick" hex="#b22222" rgb="178,34,34" />
+<color name="floralwhite" hex="#fffaf0" rgb="255,250,240" />
+<color name="forestgreen" hex="#228b22" rgb="34,139,34" />
+<color name="fuchsia" hex="#ff00ff" rgb="255,0,255" />
+<color name="gainsboro" hex="#dcdcdc" rgb="220,220,220" />
+<color name="ghostwhite" hex="#f8f8ff" rgb="248,248,255" />
+<color name="gold" hex="#ffd700" rgb="255,215,0" />
+<color name="goldenrod" hex="#daa520" rgb="218,165,32" />
+<color name="gray" hex="#808080" rgb="128,128,128" />
+<color name="green" hex="#008000" rgb="0,128,0" />
+<color name="greenyellow" hex="#adff2f" rgb="173,255,47" />
+<color name="grey" hex="#808080" rgb="128,128,128" />
+<color name="honeydew" hex="#f0fff0" rgb="240,255,240" />
+<color name="hotpink" hex="#ff69b4" rgb="255,105,180" />
+<color name="indianred" hex="#cd5c5c" rgb="205,92,92" />
+<color name="indigo" hex="#4b0082" rgb="75,0,130" />
+<color name="ivory" hex="#fffff0" rgb="255,255,240" />
+<color name="khaki" hex="#f0e68c" rgb="240,230,140" />
+<color name="lavender" hex="#e6e6fa" rgb="230,230,250" />
+<color name="lavenderblush" hex="#fff0f5" rgb="255,240,245" />
+<color name="lawngreen" hex="#7cfc00" rgb="124,252,0" />
+<color name="lemonchiffon" hex="#fffacd" rgb="255,250,205" />
+<color name="lightblue" hex="#add8e6" rgb="173,216,230" />
+<color name="lightcoral" hex="#f08080" rgb="240,128,128" />
+<color name="lightcyan" hex="#e0ffff" rgb="224,255,255" />
+<color name="lightgoldenrodyellow" hex="#fafad2" rgb="250,250,210" />
+<color name="lightgray" hex="#d3d3d3" rgb="211,211,211" />
+<color name="lightgreen" hex="#90ee90" rgb="144,238,144" />
+<color name="lightgrey" hex="#d3d3d3" rgb="211,211,211" />
+<color name="lightpink" hex="#ffb6c1" rgb="255,182,193" />
+<color name="lightsalmon" hex="#ffa07a" rgb="255,160,122" />
+<color name="lightseagreen" hex="#20b2aa" rgb="32,178,170" />
+<color name="lightskyblue" hex="#87cefa" rgb="135,206,250" />
+<color name="lightslategray" hex="#778899" rgb="119,136,153" />
+<color name="lightslategrey" hex="#778899" rgb="119,136,153" />
+<color name="lightsteelblue" hex="#b0c4de" rgb="176,196,222" />
+<color name="lightyellow" hex="#ffffe0" rgb="255,255,224" />
+<color name="lime" hex="#00ff00" rgb="0,255,0" />
+<color name="limegreen" hex="#32cd32" rgb="50,205,50" />
+<color name="linen" hex="#faf0e6" rgb="250,240,230" />
+<color name="magenta" hex="#ff00ff" rgb="255,0,255" />
+<color name="maroon" hex="#800000" rgb="128,0,0" />
+<color name="mediumaquamarine" hex="#66cdaa" rgb="102,205,170" />
+<color name="mediumblue" hex="#0000cd" rgb="0,0,205" />
+<color name="mediumorchid" hex="#ba55d3" rgb="186,85,211" />
+<color name="mediumpurple" hex="#9370db" rgb="147,112,219" />
+<color name="mediumseagreen" hex="#3cb371" rgb="60,179,113" />
+<color name="mediumslateblue" hex="#7b68ee" rgb="123,104,238" />
+<color name="mediumspringgreen" hex="#00fa9a" rgb="0,250,154" />
+<color name="mediumturquoise" hex="#48d1cc" rgb="72,209,204" />
+<color name="mediumvioletred" hex="#c71585" rgb="199,21,133" />
+<color name="midnightblue" hex="#191970" rgb="25,25,112" />
+<color name="mintcream" hex="#f5fffa" rgb="245,255,250" />
+<color name="mistyrose" hex="#ffe4e1" rgb="255,228,225" />
+<color name="moccasin" hex="#ffe4b5" rgb="255,228,181" />
+<color name="navajowhite" hex="#ffdead" rgb="255,222,173" />
+<color name="navy" hex="#000080" rgb="0,0,128" />
+<color name="oldlace" hex="#fdf5e6" rgb="253,245,230" />
+<color name="olive" hex="#808000" rgb="128,128,0" />
+<color name="olivedrab" hex="#6b8e23" rgb="107,142,35" />
+<color name="orange" hex="#ffa500" rgb="255,165,0" />
+<color name="orangered" hex="#ff4500" rgb="255,69,0" />
+<color name="orchid" hex="#da70d6" rgb="218,112,214" />
+<color name="palegoldenrod" hex="#eee8aa" rgb="238,232,170" />
+<color name="palegreen" hex="#98fb98" rgb="152,251,152" />
+<color name="paleturquoise" hex="#afeeee" rgb="175,238,238" />
+<color name="palevioletred" hex="#db7093" rgb="219,112,147" />
+<color name="papayawhip" hex="#ffefd5" rgb="255,239,213" />
+<color name="peachpuff" hex="#ffdab9" rgb="255,218,185" />
+<color name="peru" hex="#cd853f" rgb="205,133,63" />
+<color name="pink" hex="#ffc0cb" rgb="255,192,203" />
+<color name="plum" hex="#dda0dd" rgb="221,160,221" />
+<color name="powderblue" hex="#b0e0e6" rgb="176,224,230" />
+<color name="purple" hex="#800080" rgb="128,0,128" />
+<color name="red" hex="#ff0000" rgb="255,0,0" />
+<color name="rosybrown" hex="#bc8f8f" rgb="188,143,143" />
+<color name="royalblue" hex="#4169e1" rgb="65,105,225" />
+<color name="saddlebrown" hex="#8b4513" rgb="139,69,19" />
+<color name="salmon" hex="#fa8072" rgb="250,128,114" />
+<color name="sandybrown" hex="#f4a460" rgb="244,164,96" />
+<color name="seagreen" hex="#2e8b57" rgb="46,139,87" />
+<color name="seashell" hex="#fff5ee" rgb="255,245,238" />
+<color name="sienna" hex="#a0522d" rgb="160,82,45" />
+<color name="silver" hex="#c0c0c0" rgb="192,192,192" />
+<color name="skyblue" hex="#87ceeb" rgb="135,206,235" />
+<color name="slateblue" hex="#6a5acd" rgb="106,90,205" />
+<color name="slategray" hex="#708090" rgb="112,128,144" />
+<color name="slategrey" hex="#708090" rgb="112,128,144" />
+<color name="snow" hex="#fffafa" rgb="255,250,250" />
+<color name="springgreen" hex="#00ff7f" rgb="0,255,127" />
+<color name="steelblue" hex="#4682b4" rgb="70,130,180" />
+<color name="tan" hex="#d2b48c" rgb="210,180,140" />
+<color name="teal" hex="#008080" rgb="0,128,128" />
+<color name="thistle" hex="#d8bfd8" rgb="216,191,216" />
+<color name="tomato" hex="#ff6347" rgb="255,99,71" />
+<color name="turquoise" hex="#40e0d0" rgb="64,224,208" />
+<color name="violet" hex="#ee82ee" rgb="238,130,238" />
+<color name="wheat" hex="#f5deb3" rgb="245,222,179" />
+<color name="white" hex="#ffffff" rgb="255,255,255" />
+<color name="whitesmoke" hex="#f5f5f5" rgb="245,245,245" />
+<color name="yellow" hex="#ffff00" rgb="255,255,0" />
+<color name="yellowgreen" hex="#9acd32" rgb="154,205,50" />
+</colors>
index 9f3ff365ea4d2ef9f6912323a9dbbde9ca37adfb..1230ff2d89632312a3d0c0f419ca1da5914a0b5b 100644 (file)
@@ -1,16 +1,16 @@
-<?xml version="1.0" encoding="UTF-8"?>\r
-<inkscape-extension xmlns="http://www.inkscape.org/namespace/inkscape/extension">\r
-       <_name>Convert to Dashes</_name>\r
-       <id>com.vaxxine.filter.dashes</id>\r
-       <dependency type="executable" location="extensions">convert2dashes.py</dependency>\r
-       <dependency type="executable" location="extensions">inkex.py</dependency>\r
-       <effect>\r
-               <object-type>path</object-type>\r
-               <effects-menu>\r
-                       <submenu _name="Modify Path"/>\r
-               </effects-menu>\r
-       </effect>\r
-       <script>\r
-               <command reldir="extensions" interpreter="python">convert2dashes.py</command>\r
-       </script>\r
-</inkscape-extension>\r
+<?xml version="1.0" encoding="UTF-8"?>
+<inkscape-extension xmlns="http://www.inkscape.org/namespace/inkscape/extension">
+       <_name>Convert to Dashes</_name>
+       <id>com.vaxxine.filter.dashes</id>
+       <dependency type="executable" location="extensions">convert2dashes.py</dependency>
+       <dependency type="executable" location="extensions">inkex.py</dependency>
+       <effect>
+               <object-type>path</object-type>
+               <effects-menu>
+                       <submenu _name="Modify Path"/>
+               </effects-menu>
+       </effect>
+       <script>
+               <command reldir="extensions" interpreter="python">convert2dashes.py</command>
+       </script>
+</inkscape-extension>
index ba88f668c32054aca721a03bbdac153e38b24a94..6e2aa000eaaaefde92e256048fefba77e9fef7c0 100644 (file)
@@ -1,26 +1,26 @@
-<?xml version="1.0" encoding="UTF-8"?>\r
-<inkscape-extension xmlns="http://www.inkscape.org/namespace/inkscape/extension">\r
-    <_name>Guillotine</_name>\r
-    <id>org.inkscape.guillotine</id>\r
-    \r
-       <dependency type="extension">org.inkscape.output.svg.inkscape</dependency>\r
-       \r
-       <dependency type="executable" location="extensions">guillotine.py</dependency>\r
-       <dependency type="executable" location="extensions">inkex.py</dependency>\r
-       \r
-       <param name="directory" type="string" _gui-text="Directory to save images to">~/</param>\r
-       <param name="image" type="string" _gui-text="Image name (without extension)">guillotined</param>\r
-       <param name="ignore" type="boolean" _gui-text="Ignore these settings and use export hints?">false</param>\r
-       \r
-    <effect needs-live-preview="false">\r
-                <object-type>all</object-type>\r
-                <effects-menu>\r
-                      <submenu _name="Export"/>\r
-                </effects-menu>\r
-    </effect>\r
-    \r
-    <script>\r
-        <command reldir="extensions" interpreter="python">guillotine.py</command>\r
-    </script>\r
-    \r
-</inkscape-extension>\r
+<?xml version="1.0" encoding="UTF-8"?>
+<inkscape-extension xmlns="http://www.inkscape.org/namespace/inkscape/extension">
+    <_name>Guillotine</_name>
+    <id>org.inkscape.guillotine</id>
+    
+       <dependency type="extension">org.inkscape.output.svg.inkscape</dependency>
+       
+       <dependency type="executable" location="extensions">guillotine.py</dependency>
+       <dependency type="executable" location="extensions">inkex.py</dependency>
+       
+       <param name="directory" type="string" _gui-text="Directory to save images to">~/</param>
+       <param name="image" type="string" _gui-text="Image name (without extension)">guillotined</param>
+       <param name="ignore" type="boolean" _gui-text="Ignore these settings and use export hints?">false</param>
+       
+    <effect needs-live-preview="false">
+                <object-type>all</object-type>
+                <effects-menu>
+                      <submenu _name="Export"/>
+                </effects-menu>
+    </effect>
+    
+    <script>
+        <command reldir="extensions" interpreter="python">guillotine.py</command>
+    </script>
+    
+</inkscape-extension>
index 7c43daa6d3950e37fdfe3f34700159ee5ab285d6..f0e3f4aaae0944a59cb99697c8a2d3b688221139 100644 (file)
-#!/usr/bin/env python \r
-'''\r
-guillotine.py\r
-\r
-Copyright (C) 2010 Craig Marshall, craig9 [at] gmail.com\r
-\r
-This program is free software; you can redistribute it and/or modify\r
-it under the terms of the GNU General Public License as published by\r
-the Free Software Foundation; either version 2 of the License, or\r
-(at your option) any later version.\r
-\r
-This program is distributed in the hope that it will be useful,\r
-but WITHOUT ANY WARRANTY; without even the implied warranty of\r
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
-GNU General Public License for more details.\r
-\r
-You should have received a copy of the GNU General Public License\r
-along with this program; if not, write to the Free Software\r
-Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA\r
-\r
------------------------\r
-\r
-This script slices an inkscape drawing along the guides, similarly to \r
-the GIMP plugin called "guillotine". It can optionally export to the \r
-same directory as the SVG file with the same name, but with a number\r
-suffix. e.g. \r
-\r
-/home/foo/drawing.svg\r
-\r
-will export to:\r
-\r
-/home/foo/drawing0.png\r
-/home/foo/drawing1.png\r
-/home/foo/drawing2.png\r
-/home/foo/drawing3.png\r
-\r
-etc.\r
-\r
-'''\r
-\r
-import os\r
-import sys\r
-import inkex\r
-import simplestyle\r
-import locale\r
-\r
-locale.setlocale(locale.LC_ALL, '')\r
-\r
-try:\r
-    from subprocess import Popen, PIPE\r
-    bsubprocess = True\r
-except:\r
-    bsubprocess = False\r
-\r
-def float_sort(a, b):\r
-    '''\r
-    This is used to sort the horizontal and vertical guide positions,\r
-    which are floating point numbers, but which are held as text.\r
-    '''\r
-    return cmp(float(a), float(b))\r
-\r
-class Guillotine(inkex.Effect):\r
-    """Exports slices made using guides"""\r
-    def __init__(self):\r
-        inkex.Effect.__init__(self)    \r
-        self.OptionParser.add_option("--directory", action="store", \r
-                                        type="string", dest="directory",\r
-                                        default=None, help="")\r
-                                        \r
-        self.OptionParser.add_option("--image", action="store", \r
-                                        type="string", dest="image", \r
-                                        default=None, help="")\r
-                                        \r
-        self.OptionParser.add_option("--ignore", action="store", \r
-                                        type="inkbool", dest="ignore", \r
-                                        default=None, help="")\r
-        \r
-    def get_guides(self):\r
-        '''\r
-        Returns all guide elements as an iterable collection\r
-        '''\r
-        root = self.document.getroot()\r
-        guides = []\r
-        xpath = self.document.xpath("//sodipodi:guide", \r
-                                    namespaces=inkex.NSS)\r
-        for g in xpath:\r
-            guide = {}\r
-            (x, y) = g.attrib['position'].split(',')\r
-            if g.attrib['orientation'] == '0,1':\r
-                guide['orientation'] = 'horizontal'\r
-                guide['position'] = y\r
-                guides.append(guide)\r
-            elif g.attrib['orientation'] == '1,0':\r
-                guide['orientation'] = 'vertical'\r
-                guide['position'] = x\r
-                guides.append(guide)\r
-        return guides\r
-    \r
-    def get_all_horizontal_guides(self):\r
-        '''\r
-        Returns all horizontal guides as a list of floats stored as \r
-        strings. Each value is the position from 0 in pixels.\r
-        '''\r
-        guides = []\r
-        for g in self.get_guides():\r
-            if g['orientation'] == 'horizontal':\r
-                guides.append(g['position'])\r
-        return guides\r
-\r
-    def get_all_vertical_guides(self):\r
-        '''\r
-        Returns all vertical guides as a list of floats stored as\r
-        strings. Each value is the position from 0 in pixels.\r
-        '''\r
-        guides = []\r
-        for g in self.get_guides():\r
-            if g['orientation'] == 'vertical':\r
-                guides.append(g['position'])\r
-        return guides        \r
-        \r
-    def get_horizontal_slice_positions(self):\r
-        '''\r
-        Make a sorted list of all horizontal guide positions, \r
-        including 0 and the document height, but not including\r
-        those outside of the canvas\r
-        '''\r
-        root = self.document.getroot()\r
-        horizontals = ['0']\r
-        height = inkex.unittouu(root.attrib['height'])\r
-        for h in self.get_all_horizontal_guides():\r
-            if h >= 0 and float(h) <= float(height):\r
-                horizontals.append(h)\r
-        horizontals.append(height)\r
-        horizontals.sort(cmp=float_sort)    \r
-        return horizontals\r
-        \r
-    def get_vertical_slice_positions(self):\r
-        '''\r
-        Make a sorted list of all vertical guide positions,\r
-        including 0 and the document width, but not including\r
-        those outside of the canvas. \r
-        '''\r
-        root = self.document.getroot()\r
-        verticals = ['0']\r
-        width = inkex.unittouu(root.attrib['width'])\r
-        for v in self.get_all_vertical_guides():\r
-            if v >= 0 and float(v) <= float(width):\r
-                verticals.append(v)\r
-        verticals.append(width)\r
-        verticals.sort(cmp=float_sort)\r
-        return verticals\r
-    \r
-    def get_slices(self):\r
-        '''\r
-        Returns a list of all "slices" as denoted by the guides\r
-        on the page. Each slice is really just a 4 element list of \r
-        floats (stored as strings), consisting of the X and Y start \r
-        position and the X and Y end position.\r
-        '''\r
-        hs = self.get_horizontal_slice_positions()\r
-        vs = self.get_vertical_slice_positions()\r
-        slices = []\r
-        for i in range(len(hs)-1):\r
-            for j in range(len(vs)-1):\r
-                slices.append([vs[j], hs[i], vs[j+1], hs[i+1]])\r
-        return slices\r
-        \r
-    def get_filename_parts(self):\r
-        '''\r
-        Attempts to get directory and image as passed in by the inkscape \r
-        dialog. If the boolean ignore flag is set, then it will ignore\r
-        these settings and try to use the settings from the export\r
-        filename.\r
-        '''\r
-        \r
-        if self.options.ignore == False:\r
-            return (self.options.directory, self.options.image)\r
-        else:\r
-            '''\r
-            First get the export-filename from the document, if the \r
-            document has been exported before (TODO: Will not work if it\r
-            hasn't been exported yet), then uses this to return a tuple \r
-            consisting of the directory to export to, and the filename \r
-            without extension.\r
-            '''\r
-            svg = self.document.getroot()\r
-            att = '{http://www.inkscape.org/namespaces/inkscape}export-filename'\r
-            try:\r
-                export_file = svg.attrib[att]\r
-            except KeyError:\r
-                inkex.errormsg("To use the export hints option, you " +\r
-                "need to have previously exported the document. " + \r
-                "Otherwise no export hints exist!")\r
-                sys.exit(-1)\r
-            dirname, filename = os.path.split(export_file)\r
-            filename = filename.rsplit(".", 1)[0] # Without extension\r
-            return (dirname, filename)    \r
-\r
-    def check_dir_exists(self, dir):\r
-        if not os.path.isdir(dir):\r
-            os.makedirs(dir)\r
-\r
-    def get_localised_string(self, str):\r
-        return locale.format("%.f", float(str), 0)\r
-\r
-    def export_slice(self, s, filename):\r
-        '''\r
-        Runs inkscape's command line interface and exports the image \r
-        slice from the 4 coordinates in s, and saves as the filename \r
-        given.\r
-        '''\r
-        svg_file = self.args[-1]\r
-        command = "inkscape -a %s:%s:%s:%s -e \"%s\" \"%s\" " % (self.get_localised_string(s[0]), self.get_localised_string(s[1]), self.get_localised_string(s[2]), self.get_localised_string(s[3]), filename, svg_file)\r
-        if bsubprocess:\r
-            p = Popen(command, shell=True, stdout=PIPE, stderr=PIPE)\r
-            return_code = p.wait()\r
-            f = p.stdout\r
-            err = p.stderr\r
-        else:\r
-            _, f, err = os.open3(command)\r
-        f.close()\r
-        \r
-    def export_slices(self, slices):\r
-        '''\r
-        Takes the slices list and passes each one with a calculated \r
-        filename/directory into export_slice.\r
-        '''\r
-        dirname, filename = self.get_filename_parts()\r
-        if dirname == '' or dirname == None:\r
-            dirname = './'\r
-        inkex.errormsg(dirname)\r
-        dirname = os.path.expanduser(dirname)\r
-        dirname = os.path.expandvars(dirname)\r
-        self.check_dir_exists(dirname)\r
-        i = 0\r
-        for s in slices:\r
-            f = dirname + os.path.sep + filename + str(i) + ".png"\r
-            self.export_slice(s, f)\r
-            i += 1\r
-    \r
-    def effect(self):\r
-        slices = self.get_slices()\r
-        self.export_slices(slices)\r
-    \r
-if __name__ == "__main__":\r
-    e = Guillotine()\r
-    e.affect()\r
-\r
+#!/usr/bin/env python 
+'''
+guillotine.py
+
+Copyright (C) 2010 Craig Marshall, craig9 [at] gmail.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
+the Free Software Foundation; either version 2 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+
+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
+
+-----------------------
+
+This script slices an inkscape drawing along the guides, similarly to 
+the GIMP plugin called "guillotine". It can optionally export to the 
+same directory as the SVG file with the same name, but with a number
+suffix. e.g. 
+
+/home/foo/drawing.svg
+
+will export to:
+
+/home/foo/drawing0.png
+/home/foo/drawing1.png
+/home/foo/drawing2.png
+/home/foo/drawing3.png
+
+etc.
+
+'''
+
+import os
+import sys
+import inkex
+import simplestyle
+import locale
+
+locale.setlocale(locale.LC_ALL, '')
+
+try:
+    from subprocess import Popen, PIPE
+    bsubprocess = True
+except:
+    bsubprocess = False
+
+def float_sort(a, b):
+    '''
+    This is used to sort the horizontal and vertical guide positions,
+    which are floating point numbers, but which are held as text.
+    '''
+    return cmp(float(a), float(b))
+
+class Guillotine(inkex.Effect):
+    """Exports slices made using guides"""
+    def __init__(self):
+        inkex.Effect.__init__(self)    
+        self.OptionParser.add_option("--directory", action="store", 
+                                        type="string", dest="directory",
+                                        default=None, help="")
+                                        
+        self.OptionParser.add_option("--image", action="store", 
+                                        type="string", dest="image", 
+                                        default=None, help="")
+                                        
+        self.OptionParser.add_option("--ignore", action="store", 
+                                        type="inkbool", dest="ignore", 
+                                        default=None, help="")
+        
+    def get_guides(self):
+        '''
+        Returns all guide elements as an iterable collection
+        '''
+        root = self.document.getroot()
+        guides = []
+        xpath = self.document.xpath("//sodipodi:guide", 
+                                    namespaces=inkex.NSS)
+        for g in xpath:
+            guide = {}
+            (x, y) = g.attrib['position'].split(',')
+            if g.attrib['orientation'] == '0,1':
+                guide['orientation'] = 'horizontal'
+                guide['position'] = y
+                guides.append(guide)
+            elif g.attrib['orientation'] == '1,0':
+                guide['orientation'] = 'vertical'
+                guide['position'] = x
+                guides.append(guide)
+        return guides
+    
+    def get_all_horizontal_guides(self):
+        '''
+        Returns all horizontal guides as a list of floats stored as 
+        strings. Each value is the position from 0 in pixels.
+        '''
+        guides = []
+        for g in self.get_guides():
+            if g['orientation'] == 'horizontal':
+                guides.append(g['position'])
+        return guides
+
+    def get_all_vertical_guides(self):
+        '''
+        Returns all vertical guides as a list of floats stored as
+        strings. Each value is the position from 0 in pixels.
+        '''
+        guides = []
+        for g in self.get_guides():
+            if g['orientation'] == 'vertical':
+                guides.append(g['position'])
+        return guides        
+        
+    def get_horizontal_slice_positions(self):
+        '''
+        Make a sorted list of all horizontal guide positions, 
+        including 0 and the document height, but not including
+        those outside of the canvas
+        '''
+        root = self.document.getroot()
+        horizontals = ['0']
+        height = inkex.unittouu(root.attrib['height'])
+        for h in self.get_all_horizontal_guides():
+            if h >= 0 and float(h) <= float(height):
+                horizontals.append(h)
+        horizontals.append(height)
+        horizontals.sort(cmp=float_sort)    
+        return horizontals
+        
+    def get_vertical_slice_positions(self):
+        '''
+        Make a sorted list of all vertical guide positions,
+        including 0 and the document width, but not including
+        those outside of the canvas. 
+        '''
+        root = self.document.getroot()
+        verticals = ['0']
+        width = inkex.unittouu(root.attrib['width'])
+        for v in self.get_all_vertical_guides():
+            if v >= 0 and float(v) <= float(width):
+                verticals.append(v)
+        verticals.append(width)
+        verticals.sort(cmp=float_sort)
+        return verticals
+    
+    def get_slices(self):
+        '''
+        Returns a list of all "slices" as denoted by the guides
+        on the page. Each slice is really just a 4 element list of 
+        floats (stored as strings), consisting of the X and Y start 
+        position and the X and Y end position.
+        '''
+        hs = self.get_horizontal_slice_positions()
+        vs = self.get_vertical_slice_positions()
+        slices = []
+        for i in range(len(hs)-1):
+            for j in range(len(vs)-1):
+                slices.append([vs[j], hs[i], vs[j+1], hs[i+1]])
+        return slices
+        
+    def get_filename_parts(self):
+        '''
+        Attempts to get directory and image as passed in by the inkscape 
+        dialog. If the boolean ignore flag is set, then it will ignore
+        these settings and try to use the settings from the export
+        filename.
+        '''
+        
+        if self.options.ignore == False:
+            return (self.options.directory, self.options.image)
+        else:
+            '''
+            First get the export-filename from the document, if the 
+            document has been exported before (TODO: Will not work if it
+            hasn't been exported yet), then uses this to return a tuple 
+            consisting of the directory to export to, and the filename 
+            without extension.
+            '''
+            svg = self.document.getroot()
+            att = '{http://www.inkscape.org/namespaces/inkscape}export-filename'
+            try:
+                export_file = svg.attrib[att]
+            except KeyError:
+                inkex.errormsg("To use the export hints option, you " +
+                "need to have previously exported the document. " + 
+                "Otherwise no export hints exist!")
+                sys.exit(-1)
+            dirname, filename = os.path.split(export_file)
+            filename = filename.rsplit(".", 1)[0] # Without extension
+            return (dirname, filename)    
+
+    def check_dir_exists(self, dir):
+        if not os.path.isdir(dir):
+            os.makedirs(dir)
+
+    def get_localised_string(self, str):
+        return locale.format("%.f", float(str), 0)
+
+    def export_slice(self, s, filename):
+        '''
+        Runs inkscape's command line interface and exports the image 
+        slice from the 4 coordinates in s, and saves as the filename 
+        given.
+        '''
+        svg_file = self.args[-1]
+        command = "inkscape -a %s:%s:%s:%s -e \"%s\" \"%s\" " % (self.get_localised_string(s[0]), self.get_localised_string(s[1]), self.get_localised_string(s[2]), self.get_localised_string(s[3]), filename, svg_file)
+        if bsubprocess:
+            p = Popen(command, shell=True, stdout=PIPE, stderr=PIPE)
+            return_code = p.wait()
+            f = p.stdout
+            err = p.stderr
+        else:
+            _, f, err = os.open3(command)
+        f.close()
+        
+    def export_slices(self, slices):
+        '''
+        Takes the slices list and passes each one with a calculated 
+        filename/directory into export_slice.
+        '''
+        dirname, filename = self.get_filename_parts()
+        if dirname == '' or dirname == None:
+            dirname = './'
+        inkex.errormsg(dirname)
+        dirname = os.path.expanduser(dirname)
+        dirname = os.path.expandvars(dirname)
+        self.check_dir_exists(dirname)
+        i = 0
+        for s in slices:
+            f = dirname + os.path.sep + filename + str(i) + ".png"
+            self.export_slice(s, f)
+            i += 1
+    
+    def effect(self):
+        slices = self.get_slices()
+        self.export_slices(slices)
+    
+if __name__ == "__main__":
+    e = Guillotine()
+    e.affect()
+
index 0d21329cd29c488a5466d4ab75bac157765f5ace..e9d734fe17bc859d8a5deaa02548ebb3979a8aeb 100644 (file)
@@ -1,28 +1,28 @@
-<?xml version="1.0" encoding="UTF-8"?>\r
-<inkscape-extension xmlns="http://www.inkscape.org/namespace/inkscape/extension">\r
-  <_name>Parametric Curves</_name>\r
-  <id>org.inkscape.effect.param_curves</id>\r
-  <dependency type="executable" location="extensions">param_curves.py</dependency>\r
-  <dependency type="executable" location="extensions">inkex.py</dependency>\r
-  <param name="tab" type="notebook">\r
-    <page name="sampling"  _gui-text="Range and Sampling">\r
-      <param name="t_start"  type="float" min="-1000.0" max="1000.0" _gui-text="Start t-value">0.0</param>\r
-      <param name="t_end"    type="float" min="-1000.0" max="1000.0" _gui-text="End t-value">1.0</param>\r
-      <param name="times2pi" type="boolean"                          _gui-text="Multiply t-range by 2*pi">true</param>\r
-      <param name="xleft"    type="float" min="-1000.0" max="1000.0" _gui-text="x-value of rectangle's left">-1.0</param>\r
-      <param name="xright"   type="float" min="-1000.0" max="1000.0" _gui-text="x-value of rectangle's right">1.0</param>\r
-      <param name="ybottom"  type="float" min="-1000.0" max="1000.0" _gui-text="y-value of rectangle's bottom">-1.0</param>\r
-      <param name="ytop"     type="float" min="-1000.0" max="1000.0" _gui-text="y-value of rectangle's top">1.0</param>\r
-      <param name="samples"  type="int"   min="2"       max="1000"   _gui-text="Samples">30</param>\r
-      <param name="isoscale" type="boolean" _gui-text="Isotropic scaling (uses smallest: width/xrange or height/yrange)">false</param>\r
-    </page>\r
-    <page name="use" _gui-text="Use">\r
+<?xml version="1.0" encoding="UTF-8"?>
+<inkscape-extension xmlns="http://www.inkscape.org/namespace/inkscape/extension">
+  <_name>Parametric Curves</_name>
+  <id>org.inkscape.effect.param_curves</id>
+  <dependency type="executable" location="extensions">param_curves.py</dependency>
+  <dependency type="executable" location="extensions">inkex.py</dependency>
+  <param name="tab" type="notebook">
+    <page name="sampling"  _gui-text="Range and Sampling">
+      <param name="t_start"  type="float" min="-1000.0" max="1000.0" _gui-text="Start t-value">0.0</param>
+      <param name="t_end"    type="float" min="-1000.0" max="1000.0" _gui-text="End t-value">1.0</param>
+      <param name="times2pi" type="boolean"                          _gui-text="Multiply t-range by 2*pi">true</param>
+      <param name="xleft"    type="float" min="-1000.0" max="1000.0" _gui-text="x-value of rectangle's left">-1.0</param>
+      <param name="xright"   type="float" min="-1000.0" max="1000.0" _gui-text="x-value of rectangle's right">1.0</param>
+      <param name="ybottom"  type="float" min="-1000.0" max="1000.0" _gui-text="y-value of rectangle's bottom">-1.0</param>
+      <param name="ytop"     type="float" min="-1000.0" max="1000.0" _gui-text="y-value of rectangle's top">1.0</param>
+      <param name="samples"  type="int"   min="2"       max="1000"   _gui-text="Samples">30</param>
+      <param name="isoscale" type="boolean" _gui-text="Isotropic scaling (uses smallest: width/xrange or height/yrange)">false</param>
+    </page>
+    <page name="use" _gui-text="Use">
       <_param name="funcplotuse" type="description" xml:space="preserve">Select a rectangle before calling the extension,
 it will determine X and Y scales.
 
-First derivatives are always determined numerically.</_param>\r
-    </page>\r
-    <page name="desc" _gui-text="Functions">\r
+First derivatives are always determined numerically.</_param>
+    </page>
+    <page name="desc" _gui-text="Functions">
       <_param name="pythonfunctions" type="description" xml:space="preserve">Standard Python math functions are available:
 
 ceil(x); fabs(x); floor(x); fmod(x,y); frexp(x); ldexp(x,i); 
@@ -31,20 +31,20 @@ acos(x); asin(x); atan(x); atan2(y,x); hypot(x,y);
 cos(x); sin(x); tan(x); degrees(x); radians(x); 
 cosh(x); sinh(x); tanh(x).
 
-The constants pi and e are also available.</_param>\r
-    </page>\r
-  </param>\r
-  <param name="fofx"     type="string"  _gui-text="x-Function">cos(3*t)</param>\r
-  <param name="fofy"     type="string"  _gui-text="y-Function">sin(5*t)</param>\r
-  <param name="remove"   type="boolean" _gui-text="Remove rectangle">true</param>\r
-  <param name="drawaxis" type="boolean" _gui-text="Draw Axes">false</param>\r
-  <effect>\r
-    <object-type>rect</object-type>\r
-    <effects-menu>\r
-            <submenu _name="Render"/>\r
-    </effects-menu>\r
-  </effect>\r
-  <script>\r
-    <command reldir="extensions" interpreter="python">param_curves.py</command>\r
-  </script>\r
-</inkscape-extension>\r
+The constants pi and e are also available.</_param>
+    </page>
+  </param>
+  <param name="fofx"     type="string"  _gui-text="x-Function">cos(3*t)</param>
+  <param name="fofy"     type="string"  _gui-text="y-Function">sin(5*t)</param>
+  <param name="remove"   type="boolean" _gui-text="Remove rectangle">true</param>
+  <param name="drawaxis" type="boolean" _gui-text="Draw Axes">false</param>
+  <effect>
+    <object-type>rect</object-type>
+    <effects-menu>
+            <submenu _name="Render"/>
+    </effects-menu>
+  </effect>
+  <script>
+    <command reldir="extensions" interpreter="python">param_curves.py</command>
+  </script>
+</inkscape-extension>
index 32f4b8c800bd79806ae94785428d1c1edfdc67f9..7a8f384aabb60d58704713c221383ccfe0b1f804 100644 (file)
-#!/usr/bin/env python\r
-'''\r
-Copyright (C) 2009 Michel Chatelain.\r
-Copyright (C) 2007 Tavmjong Bah, tavmjong@free.fr\r
-Copyright (C) 2006 Georg Wiora, xorx@quarkbox.de\r
-Copyright (C) 2006 Johan Engelen, johan@shouraizou.nl\r
-Copyright (C) 2005 Aaron Spike, aaron@ekips.org\r
-\r
-This program is free software; you can redistribute it and/or modify\r
-it under the terms of the GNU General Public License as published by\r
-the Free Software Foundation; either version 2 of the License, or\r
-(at your option) any later version.\r
-\r
-This program is distributed in the hope that it will be useful,\r
-but WITHOUT ANY WARRANTY; without even the implied warranty of\r
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
-GNU General Public License for more details.\r
-\r
-You should have received a copy of the GNU General Public License\r
-along with this program; if not, write to the Free Software\r
-Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA\r
-\r
-Changes:\r
- * This program is derived by Michel Chatelain from funcplot.py. His changes are in the Public Domain.\r
- * Michel Chatelain, 17-18 janvier 2009, a partir de funcplot.py\r
- * 20 janvier 2009 : adaptation a la version 0.46 a partir de la nouvelle version de funcplot.py\r
-\r
-'''\r
-\r
-import inkex, simplepath, simplestyle\r
-from math import *\r
-from random import *\r
-\r
-def drawfunction(t_start, t_end, xleft, xright, ybottom, ytop, samples, width, height, left, bottom,\r
-    fx = "cos(3*t)", fy = "sin(5*t)", times2pi = False, isoscale = True, drawaxis = True):\r
-\r
-    if times2pi == True:\r
-        t_start = 2 * pi * t_start\r
-        t_end   = 2 * pi * t_end\r
-\r
-    # coords and scales based on the source rect\r
-    scalex = width / (xright - xleft)\r
-    xoff = left\r
-    coordx = lambda x: (x - xleft) * scalex + xoff  #convert x-value to coordinate\r
-    scaley = height / (ytop - ybottom)\r
-    yoff = bottom\r
-    coordy = lambda y: (ybottom - y) * scaley + yoff  #convert y-value to coordinate\r
-\r
-    # Check for isotropic scaling and use smaller of the two scales, correct ranges\r
-    if isoscale:\r
-      if scaley<scalex:\r
-        # compute zero location\r
-        xzero = coordx(0)\r
-        # set scale\r
-        scalex = scaley\r
-        # correct x-offset\r
-        xleft = (left-xzero)/scalex\r
-        xright = (left+width-xzero)/scalex\r
-      else :\r
-        # compute zero location\r
-        yzero = coordy(0)\r
-        # set scale\r
-        scaley = scalex\r
-        # correct x-offset\r
-        ybottom = (yzero-bottom)/scaley\r
-        ytop = (bottom+height-yzero)/scaley\r
-\r
-    # functions specified by the user\r
-    if fx != "":\r
-        f1 = eval('lambda t: ' + fx.strip('"'))\r
-    if fy != "":\r
-        f2 = eval('lambda t: ' + fy.strip('"'))\r
-\r
-    # step is increment of t\r
-    step = (t_end - t_start) / (samples-1)\r
-    third = step / 3.0\r
-    ds = step * 0.001 # Step used in calculating derivatives\r
-\r
-    a = [] # path array\r
-    # add axis\r
-    if drawaxis :\r
-      # check for visibility of x-axis\r
-      if ybottom<=0 and ytop>=0:\r
-        # xaxis\r
-        a.append(['M ',[left, coordy(0)]])\r
-        a.append([' l ',[width, 0]])\r
-      # check for visibility of y-axis\r
-      if xleft<=0 and xright>=0:\r
-        # xaxis\r
-        a.append([' M ',[coordx(0),bottom]])\r
-        a.append([' l ',[0, -height]])\r
-\r
-    # initialize functions and derivatives for 0;\r
-    # they are carried over from one iteration to the next, to avoid extra function calculations.\r
-    x0 = f1(t_start)\r
-    y0 = f2(t_start)\r
-\r
-    # numerical derivatives, using 0.001*step as the small differential\r
-    t1 = t_start + ds # Second point AFTER first point (Good for first point)\r
-    x1 = f1(t1)\r
-    y1 = f2(t1)\r
-    dx0 = (x1 - x0)/ds\r
-    dy0 = (y1 - y0)/ds\r
-\r
-    # Start curve\r
-    a.append([' M ',[coordx(x0), coordy(y0)]]) # initial moveto\r
-    for i in range(int(samples-1)):\r
-        t1 = (i+1) * step + t_start\r
-        t2 = t1 - ds # Second point BEFORE first point (Good for last point)\r
-        x1 = f1(t1)\r
-        x2 = f1(t2)\r
-        y1 = f2(t1)\r
-        y2 = f2(t2)\r
-\r
-        # numerical derivatives\r
-        dx1 = (x1 - x2)/ds\r
-        dy1 = (y1 - y2)/ds\r
-\r
-        # create curve\r
-        a.append([' C ',\r
-                  [coordx(x0 + (dx0 * third)), coordy(y0 + (dy0 * third)),\r
-                   coordx(x1 - (dx1 * third)), coordy(y1 - (dy1 * third)),\r
-                   coordx(x1),                 coordy(y1)]\r
-                  ])\r
-        t0  = t1  # Next segment's start is this segments end\r
-        x0  = x1\r
-        y0  = y1\r
-        dx0 = dx1 # Assume the functions are smooth everywhere, so carry over the derivatives too\r
-        dy0 = dy1\r
-    return a\r
-\r
-class ParamCurves(inkex.Effect):\r
-    def __init__(self):\r
-        inkex.Effect.__init__(self)\r
-        self.OptionParser.add_option("--t_start",\r
-                        action="store", type="float",\r
-                        dest="t_start", default=0.0,\r
-                        help="Start t-value")\r
-        self.OptionParser.add_option("--t_end",\r
-                        action="store", type="float",\r
-                        dest="t_end", default=1.0,\r
-                        help="End t-value")\r
-        self.OptionParser.add_option("--times2pi",\r
-                        action="store", type="inkbool",\r
-                        dest="times2pi", default=True,\r
-                        help="Multiply t-range by 2*pi")\r
-        self.OptionParser.add_option("--xleft",\r
-                        action="store", type="float",\r
-                        dest="xleft", default=-1.0,\r
-                        help="x-value of rectangle's left")\r
-        self.OptionParser.add_option("--xright",\r
-                        action="store", type="float",\r
-                        dest="xright", default=1.0,\r
-                        help="x-value of rectangle's right")\r
-        self.OptionParser.add_option("--ybottom",\r
-                        action="store", type="float",\r
-                        dest="ybottom", default=-1.0,\r
-                        help="y-value of rectangle's bottom")\r
-        self.OptionParser.add_option("--ytop",\r
-                        action="store", type="float",\r
-                        dest="ytop", default=1.0,\r
-                        help="y-value of rectangle's top")\r
-        self.OptionParser.add_option("-s", "--samples",\r
-                        action="store", type="int",\r
-                        dest="samples", default=8,\r
-                        help="Samples")\r
-        self.OptionParser.add_option("--fofx",\r
-                        action="store", type="string",\r
-                        dest="fofx", default="cos(3*t)",\r
-                        help="fx(t) for plotting")\r
-        self.OptionParser.add_option("--fofy",\r
-                        action="store", type="string",\r
-                        dest="fofy", default="sin(5*t)",\r
-                        help="fy(t) for plotting")\r
-        self.OptionParser.add_option("--remove",\r
-                        action="store", type="inkbool",\r
-                        dest="remove", default=True,\r
-                        help="If True, source rectangle is removed")\r
-        self.OptionParser.add_option("--isoscale",\r
-                        action="store", type="inkbool",\r
-                        dest="isoscale", default=True,\r
-                        help="If True, isotropic scaling is used")\r
-        self.OptionParser.add_option("--drawaxis",\r
-                        action="store", type="inkbool",\r
-                        dest="drawaxis", default=True,\r
-                        help="If True, axis are drawn")\r
-        self.OptionParser.add_option("--tab",\r
-                        action="store", type="string",\r
-                        dest="tab", default="sampling",\r
-                        help="The selected UI-tab when OK was pressed")\r
-        self.OptionParser.add_option("--paramcurvesuse",\r
-                        action="store", type="string",\r
-                        dest="paramcurvesuse", default="",\r
-                        help="dummy")\r
-        self.OptionParser.add_option("--pythonfunctions",\r
-                        action="store", type="string",\r
-                        dest="pythonfunctions", default="",\r
-                        help="dummy")\r
-\r
-    def effect(self):\r
-        for id, node in self.selected.iteritems():\r
-            if node.tag == inkex.addNS('rect','svg'):\r
-                # create new path with basic dimensions of selected rectangle\r
-                newpath = inkex.etree.Element(inkex.addNS('path','svg'))\r
-                x = float(node.get('x'))\r
-                y = float(node.get('y'))\r
-                w = float(node.get('width'))\r
-                h = float(node.get('height'))\r
-\r
-                #copy attributes of rect\r
-                s = node.get('style')\r
-                if s:\r
-                    newpath.set('style', s)\r
-\r
-                t = node.get('transform')\r
-                if t:\r
-                    newpath.set('transform', t)\r
-\r
-                # top and bottom were exchanged\r
-                newpath.set('d', simplepath.formatPath(\r
-                            drawfunction(self.options.t_start,\r
-                                self.options.t_end,\r
-                                self.options.xleft,\r
-                                self.options.xright,\r
-                                self.options.ybottom,\r
-                                self.options.ytop,\r
-                                self.options.samples,\r
-                                w,h,x,y+h,\r
-                                self.options.fofx,\r
-                                self.options.fofy,\r
-                                self.options.times2pi,\r
-                                self.options.isoscale,\r
-                                self.options.drawaxis)))\r
-                newpath.set('title', self.options.fofx + " " + self.options.fofy)\r
-\r
-                #newpath.set('desc', '!func;' + self.options.fofx + ';' + self.options.fofy + ';'\r
-                #                                      + `self.options.t_start` + ';'\r
-                #                                      + `self.options.t_end` + ';'\r
-                #                                      + `self.options.samples`)\r
-\r
-                # add path into SVG structure\r
-                node.getparent().append(newpath)\r
-                # option wether to remove the rectangle or not.\r
-                if self.options.remove:\r
-                  node.getparent().remove(node)\r
-\r
-if __name__ == '__main__':\r
-    e = ParamCurves()\r
-    e.affect()\r
-\r
-\r
-# vim: expandtab shiftwidth=4 tabstop=8 softtabstop=4 encoding=utf-8 textwidth=99\r
+#!/usr/bin/env python
+'''
+Copyright (C) 2009 Michel Chatelain.
+Copyright (C) 2007 Tavmjong Bah, tavmjong@free.fr
+Copyright (C) 2006 Georg Wiora, xorx@quarkbox.de
+Copyright (C) 2006 Johan Engelen, johan@shouraizou.nl
+Copyright (C) 2005 Aaron Spike, aaron@ekips.org
+
+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
+the Free Software Foundation; either version 2 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+
+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
+
+Changes:
+ * This program is derived by Michel Chatelain from funcplot.py. His changes are in the Public Domain.
+ * Michel Chatelain, 17-18 janvier 2009, a partir de funcplot.py
+ * 20 janvier 2009 : adaptation a la version 0.46 a partir de la nouvelle version de funcplot.py
+
+'''
+
+import inkex, simplepath, simplestyle
+from math import *
+from random import *
+
+def drawfunction(t_start, t_end, xleft, xright, ybottom, ytop, samples, width, height, left, bottom,
+    fx = "cos(3*t)", fy = "sin(5*t)", times2pi = False, isoscale = True, drawaxis = True):
+
+    if times2pi == True:
+        t_start = 2 * pi * t_start
+        t_end   = 2 * pi * t_end
+
+    # coords and scales based on the source rect
+    scalex = width / (xright - xleft)
+    xoff = left
+    coordx = lambda x: (x - xleft) * scalex + xoff  #convert x-value to coordinate
+    scaley = height / (ytop - ybottom)
+    yoff = bottom
+    coordy = lambda y: (ybottom - y) * scaley + yoff  #convert y-value to coordinate
+
+    # Check for isotropic scaling and use smaller of the two scales, correct ranges
+    if isoscale:
+      if scaley<scalex:
+        # compute zero location
+        xzero = coordx(0)
+        # set scale
+        scalex = scaley
+        # correct x-offset
+        xleft = (left-xzero)/scalex
+        xright = (left+width-xzero)/scalex
+      else :
+        # compute zero location
+        yzero = coordy(0)
+        # set scale
+        scaley = scalex
+        # correct x-offset
+        ybottom = (yzero-bottom)/scaley
+        ytop = (bottom+height-yzero)/scaley
+
+    # functions specified by the user
+    if fx != "":
+        f1 = eval('lambda t: ' + fx.strip('"'))
+    if fy != "":
+        f2 = eval('lambda t: ' + fy.strip('"'))
+
+    # step is increment of t
+    step = (t_end - t_start) / (samples-1)
+    third = step / 3.0
+    ds = step * 0.001 # Step used in calculating derivatives
+
+    a = [] # path array
+    # add axis
+    if drawaxis :
+      # check for visibility of x-axis
+      if ybottom<=0 and ytop>=0:
+        # xaxis
+        a.append(['M ',[left, coordy(0)]])
+        a.append([' l ',[width, 0]])
+      # check for visibility of y-axis
+      if xleft<=0 and xright>=0:
+        # xaxis
+        a.append([' M ',[coordx(0),bottom]])
+        a.append([' l ',[0, -height]])
+
+    # initialize functions and derivatives for 0;
+    # they are carried over from one iteration to the next, to avoid extra function calculations.
+    x0 = f1(t_start)
+    y0 = f2(t_start)
+
+    # numerical derivatives, using 0.001*step as the small differential
+    t1 = t_start + ds # Second point AFTER first point (Good for first point)
+    x1 = f1(t1)
+    y1 = f2(t1)
+    dx0 = (x1 - x0)/ds
+    dy0 = (y1 - y0)/ds
+
+    # Start curve
+    a.append([' M ',[coordx(x0), coordy(y0)]]) # initial moveto
+    for i in range(int(samples-1)):
+        t1 = (i+1) * step + t_start
+        t2 = t1 - ds # Second point BEFORE first point (Good for last point)
+        x1 = f1(t1)
+        x2 = f1(t2)
+        y1 = f2(t1)
+        y2 = f2(t2)
+
+        # numerical derivatives
+        dx1 = (x1 - x2)/ds
+        dy1 = (y1 - y2)/ds
+
+        # create curve
+        a.append([' C ',
+                  [coordx(x0 + (dx0 * third)), coordy(y0 + (dy0 * third)),
+                   coordx(x1 - (dx1 * third)), coordy(y1 - (dy1 * third)),
+                   coordx(x1),                 coordy(y1)]
+                  ])
+        t0  = t1  # Next segment's start is this segments end
+        x0  = x1
+        y0  = y1
+        dx0 = dx1 # Assume the functions are smooth everywhere, so carry over the derivatives too
+        dy0 = dy1
+    return a
+
+class ParamCurves(inkex.Effect):
+    def __init__(self):
+        inkex.Effect.__init__(self)
+        self.OptionParser.add_option("--t_start",
+                        action="store", type="float",
+                        dest="t_start", default=0.0,
+                        help="Start t-value")
+        self.OptionParser.add_option("--t_end",
+                        action="store", type="float",
+                        dest="t_end", default=1.0,
+                        help="End t-value")
+        self.OptionParser.add_option("--times2pi",
+                        action="store", type="inkbool",
+                        dest="times2pi", default=True,
+                        help="Multiply t-range by 2*pi")
+        self.OptionParser.add_option("--xleft",
+                        action="store", type="float",
+                        dest="xleft", default=-1.0,
+                        help="x-value of rectangle's left")
+        self.OptionParser.add_option("--xright",
+                        action="store", type="float",
+                        dest="xright", default=1.0,
+                        help="x-value of rectangle's right")
+        self.OptionParser.add_option("--ybottom",
+                        action="store", type="float",
+                        dest="ybottom", default=-1.0,
+                        help="y-value of rectangle's bottom")
+        self.OptionParser.add_option("--ytop",
+                        action="store", type="float",
+                        dest="ytop", default=1.0,
+                        help="y-value of rectangle's top")
+        self.OptionParser.add_option("-s", "--samples",
+                        action="store", type="int",
+                        dest="samples", default=8,
+                        help="Samples")
+        self.OptionParser.add_option("--fofx",
+                        action="store", type="string",
+                        dest="fofx", default="cos(3*t)",
+                        help="fx(t) for plotting")
+        self.OptionParser.add_option("--fofy",
+                        action="store", type="string",
+                        dest="fofy", default="sin(5*t)",
+                        help="fy(t) for plotting")
+        self.OptionParser.add_option("--remove",
+                        action="store", type="inkbool",
+                        dest="remove", default=True,
+                        help="If True, source rectangle is removed")
+        self.OptionParser.add_option("--isoscale",
+                        action="store", type="inkbool",
+                        dest="isoscale", default=True,
+                        help="If True, isotropic scaling is used")
+        self.OptionParser.add_option("--drawaxis",
+                        action="store", type="inkbool",
+                        dest="drawaxis", default=True,
+                        help="If True, axis are drawn")
+        self.OptionParser.add_option("--tab",
+                        action="store", type="string",
+                        dest="tab", default="sampling",
+                        help="The selected UI-tab when OK was pressed")
+        self.OptionParser.add_option("--paramcurvesuse",
+                        action="store", type="string",
+                        dest="paramcurvesuse", default="",
+                        help="dummy")
+        self.OptionParser.add_option("--pythonfunctions",
+                        action="store", type="string",
+                        dest="pythonfunctions", default="",
+                        help="dummy")
+
+    def effect(self):
+        for id, node in self.selected.iteritems():
+            if node.tag == inkex.addNS('rect','svg'):
+                # create new path with basic dimensions of selected rectangle
+                newpath = inkex.etree.Element(inkex.addNS('path','svg'))
+                x = float(node.get('x'))
+                y = float(node.get('y'))
+                w = float(node.get('width'))
+                h = float(node.get('height'))
+
+                #copy attributes of rect
+                s = node.get('style')
+                if s:
+                    newpath.set('style', s)
+
+                t = node.get('transform')
+                if t:
+                    newpath.set('transform', t)
+
+                # top and bottom were exchanged
+                newpath.set('d', simplepath.formatPath(
+                            drawfunction(self.options.t_start,
+                                self.options.t_end,
+                                self.options.xleft,
+                                self.options.xright,
+                                self.options.ybottom,
+                                self.options.ytop,
+                                self.options.samples,
+                                w,h,x,y+h,
+                                self.options.fofx,
+                                self.options.fofy,
+                                self.options.times2pi,
+                                self.options.isoscale,
+                                self.options.drawaxis)))
+                newpath.set('title', self.options.fofx + " " + self.options.fofy)
+
+                #newpath.set('desc', '!func;' + self.options.fofx + ';' + self.options.fofy + ';'
+                #                                      + `self.options.t_start` + ';'
+                #                                      + `self.options.t_end` + ';'
+                #                                      + `self.options.samples`)
+
+                # add path into SVG structure
+                node.getparent().append(newpath)
+                # option wether to remove the rectangle or not.
+                if self.options.remove:
+                  node.getparent().remove(node)
+
+if __name__ == '__main__':
+    e = ParamCurves()
+    e.affect()
+
+
+# vim: expandtab shiftwidth=4 tabstop=8 softtabstop=4 encoding=utf-8 textwidth=99
index 7e400932813a070fdb30d6ecb58d13fd7c62dfa8..ffc20323b86e01b41736b0fbcf4c257e43f4c13e 100644 (file)
-#!/usr/bin/env python \r
-'''\r
-Copyright (C) 2001-2002 Matt Chisholm matt@theory.org\r
-Copyright (C) 2008 Joel Holdsworth joel@airwebreathe.org.uk\r
-    for AP\r
-\r
-This program is free software; you can redistribute it and/or modify\r
-it under the terms of the GNU General Public License as published by\r
-the Free Software Foundation; either version 2 of the License, or\r
-(at your option) any later version.\r
-\r
-This program is distributed in the hope that it will be useful,\r
-but WITHOUT ANY WARRANTY; without even the implied warranty of\r
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
-GNU General Public License for more details.\r
-\r
-You should have received a copy of the GNU General Public License\r
-along with this program; if not, write to the Free Software\r
-Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA\r
-'''\r
-\r
-import copy\r
-import inkex\r
-import simplestyle\r
-import math\r
-import cmath\r
-import string\r
-import random\r
-import render_alphabetsoup_config\r
-import bezmisc\r
-import simplepath\r
-import os\r
-import sys\r
-import gettext\r
-_ = gettext.gettext\r
-\r
-syntax   = render_alphabetsoup_config.syntax\r
-alphabet = render_alphabetsoup_config.alphabet\r
-units  = render_alphabetsoup_config.units\r
-font    = render_alphabetsoup_config.font\r
-\r
-# Loads a super-path from a given SVG file\r
-def loadPath( svgPath ):\r
-       extensionDir = os.path.normpath(\r
-                           os.path.join( os.getcwd(), os.path.dirname(__file__) )\r
-                         )\r
-       # __file__ is better then sys.argv[0] because this file may be a module\r
-       # for another one.\r
-       tree = inkex.etree.parse( extensionDir + "/" + svgPath )\r
-       root = tree.getroot()\r
-       pathElement = root.find('{http://www.w3.org/2000/svg}path')\r
-       if pathElement == None:\r
-               return None, 0, 0\r
-       d = pathElement.get("d")\r
-       width = float(root.get("width"))\r
-       height = float(root.get("height"))\r
-       return simplepath.parsePath(d), width, height # Currently we only support a single path\r
-\r
-def combinePaths( pathA, pathB ):\r
-       if pathA == None and pathB == None:\r
-               return None\r
-       elif pathA == None:\r
-               return pathB\r
-       elif pathB == None:\r
-               return pathA\r
-       else:\r
-               return pathA + pathB\r
-\r
-def flipLeftRight( sp, width ):\r
-       for cmd,params in sp:\r
-               defs = simplepath.pathdefs[cmd]\r
-               for i in range(defs[1]):\r
-                       if defs[3][i] == 'x':\r
-                               params[i] = width - params[i]\r
-\r
-def flipTopBottom( sp, height ):\r
-       for cmd,params in sp:\r
-               defs = simplepath.pathdefs[cmd]\r
-               for i in range(defs[1]):\r
-                       if defs[3][i] == 'y':\r
-                               params[i] = height - params[i]\r
-\r
-def solveQuadratic(a, b, c):\r
-       det = b*b - 4.0*a*c\r
-       if det >= 0: # real roots\r
-               sdet = math.sqrt(det)\r
-       else: # complex roots\r
-               sdet = cmath.sqrt(det)\r
-       return (-b + sdet) / (2*a), (-b - sdet) / (2*a)\r
-\r
-def cbrt(x): \r
-       if x >= 0:\r
-               return x**(1.0/3.0)\r
-       else:\r
-               return -((-x)**(1.0/3.0))\r
-\r
-def findRealRoots(a,b,c,d):\r
-       if a != 0:\r
-               a, b, c, d = 1, b/float(a), c/float(a), d/float(a)      # Divide through by a\r
-               t = b / 3.0\r
-               p, q = c - 3 * t**2, d - c * t + 2 * t**3\r
-               u, v = solveQuadratic(1, q, -(p/3.0)**3)\r
-               if type(u) == type(0j):                 # Complex Cubic Root\r
-                       r = math.sqrt(u.real**2 + u.imag**2)\r
-                       w = math.atan2(u.imag, u.real)\r
-                       y1 = 2 * cbrt(r) * math.cos(w / 3.0)\r
-               else:           # Complex Real Root\r
-                       y1 = cbrt(u) + cbrt(v)\r
-               \r
-               y2, y3 = solveQuadratic(1, y1, p + y1**2)\r
-\r
-               if type(y2) == type(0j):        # Are y2 and y3 complex?\r
-                       return [y1 - t]\r
-               return [y1 - t, y2 - t, y3 - t]\r
-       elif b != 0:\r
-               det=c*c - 4.0*b*d\r
-               if det >= 0:\r
-                       return [(-c + math.sqrt(det))/(2.0*b),(-c - math.sqrt(det))/(2.0*b)]\r
-       elif c != 0:\r
-               return [-d/c]\r
-       return []\r
-\r
-def getPathBoundingBox( sp ):\r
-       \r
-       box = None\r
-       last = None\r
-       lostctrl = None\r
-\r
-       for cmd,params in sp:\r
-\r
-               segmentBox = None\r
-\r
-               if cmd == 'M':\r
-                       # A move cannot contribute to the bounding box\r
-                       last = params[:]\r
-                       lastctrl = params[:]\r
-               elif cmd == 'L':\r
-                       if last:\r
-                               segmentBox = (min(params[0], last[0]), max(params[0], last[0]), min(params[1], last[1]), max(params[1], last[1]))\r
-                       last = params[:]\r
-                       lastctrl = params[:]\r
-               elif cmd == 'C':\r
-                       if last:                \r
-                               segmentBox = (min(params[4], last[0]), max(params[4], last[0]), min(params[5], last[1]), max(params[5], last[1]))\r
-                               \r
-                               bx0, by0 = last[:]\r
-                               bx1, by1, bx2, by2, bx3, by3 = params[:]\r
-\r
-                               # Compute the x limits\r
-                               a = (-bx0 + 3*bx1 - 3*bx2 + bx3)*3\r
-                               b = (3*bx0 - 6*bx1  + 3*bx2)*2\r
-                               c = (-3*bx0 + 3*bx1)\r
-                               ts = findRealRoots(0, a, b, c)\r
-                               for t in ts:\r
-                                       if t >= 0 and t <= 1:           \r
-                                               x = (-bx0 + 3*bx1 - 3*bx2 + bx3)*(t**3) + \\r
-                                                       (3*bx0 - 6*bx1 + 3*bx2)*(t**2) + \\r
-                                                       (-3*bx0 + 3*bx1)*t + \\r
-                                                       bx0\r
-                                               segmentBox = (min(segmentBox[0], x), max(segmentBox[1], x), segmentBox[2], segmentBox[3])\r
-\r
-                               # Compute the y limits\r
-                               a = (-by0 + 3*by1 - 3*by2 + by3)*3\r
-                               b = (3*by0 - 6*by1  + 3*by2)*2\r
-                               c = (-3*by0 + 3*by1)\r
-                               ts = findRealRoots(0, a, b, c)\r
-                               for t in ts:\r
-                                       if t >= 0 and t <= 1:           \r
-                                               y = (-by0 + 3*by1 - 3*by2 + by3)*(t**3) + \\r
-                                                       (3*by0 - 6*by1 + 3*by2)*(t**2) + \\r
-                                                       (-3*by0 + 3*by1)*t + \\r
-                                                       by0\r
-                                               segmentBox = (segmentBox[0], segmentBox[1], min(segmentBox[2], y), max(segmentBox[3], y))\r
-\r
-                       last = params[-2:]\r
-                       lastctrl = params[2:4]\r
-\r
-               elif cmd == 'Q':\r
-                       # Provisional\r
-                       if last:\r
-                               segmentBox = (min(params[0], last[0]), max(params[0], last[0]), min(params[1], last[1]), max(params[1], last[1]))\r
-                       last = params[-2:]\r
-                       lastctrl = params[2:4]\r
-\r
-               elif cmd == 'A':\r
-                       # Provisional\r
-                       if last:\r
-                               segmentBox = (min(params[0], last[0]), max(params[0], last[0]), min(params[1], last[1]), max(params[1], last[1]))\r
-                       last = params[-2:]\r
-                       lastctrl = params[2:4]\r
-\r
-               if segmentBox:\r
-                       if box:\r
-                               box = (min(segmentBox[0],box[0]), max(segmentBox[1],box[1]), min(segmentBox[2],box[2]), max(segmentBox[3],box[3]))\r
-                       else:\r
-                               box = segmentBox                        \r
-       return box\r
-\r
-def mxfm( image, width, height, stack ):                                                               # returns possibly transformed image\r
-       tbimage = image \r
-       if ( stack[0] == "-" ):                                                   # top-bottom flip\r
-               flipTopBottom(tbimage, height)\r
-               stack.pop( 0 )\r
-\r
-       lrimage = tbimage\r
-       if ( stack[0] == "|" ):                                                   # left-right flip\r
-               flipLeftRight(tbimage, width)\r
-               stack.pop( 0 )\r
-       return lrimage\r
-\r
-def comparerule( rule, nodes ):                                                  # compare node list to nodes in rule\r
-       for i in range( 0, len(nodes)):                                   # range( a, b ) = (a, a+1, a+2 ... b-2, b-1)\r
-               if (nodes[i] == rule[i][0]):\r
-                       pass\r
-               else: return 0\r
-       return 1\r
-\r
-def findrule( state, nodes ):                                                  # find the rule which generated this subtree\r
-       ruleset = syntax[state][1]\r
-       nodelen = len(nodes)\r
-       for rule in ruleset:\r
-               rulelen = len(rule)\r
-               if ((rulelen == nodelen) and (comparerule( rule, nodes ))):\r
-                       return rule\r
-       return \r
-\r
-def generate( state ):                                                            # generate a random tree (in stack form)\r
-       stack  = [ state ]\r
-       if ( len(syntax[state]) == 1 ):                                         # if this is a stop symbol\r
-               return stack\r
-       else:\r
-               stack.append( "[" )\r
-               path = random.randint(0, (len(syntax[state][1])-1)) # choose randomly from next states\r
-               for symbol in syntax[state][1][path]:                   # recurse down each non-terminal\r
-                       if ( symbol != 0 ):                                               # 0 denotes end of list ###\r
-                               substack = generate( symbol[0] )                 # get subtree\r
-                               for elt in substack:       \r
-                                       stack.append( elt )\r
-                               if (symbol[3]):stack.append( "-" )         # top-bottom flip\r
-                               if (symbol[4]):stack.append( "|" )         # left-right flip\r
-                       #else:\r
-                               #inkex.debug("found end of list in generate( state =", state, ")") # this should be deprecated/never happen\r
-               stack.append("]")\r
-               return stack\r
-\r
-def draw( stack ):                                                                        # draw a character based on a tree stack\r
-       state = stack.pop(0)\r
-       #print state,\r
-\r
-       image, width, height = loadPath( font+syntax[state][0] )                  # load the image\r
-       if (stack[0] != "["):                                                           # terminal stack element\r
-               if (len(syntax[state]) == 1):                                     # this state is a terminal node\r
-                       return image, width, height\r
-               else:\r
-                       substack = generate( state )                             # generate random substack\r
-                       return draw( substack )                                   # draw random substack\r
-       else:\r
-               #inkex.debug("[")\r
-               stack.pop(0)\r
-               images = []                                                               # list of daughter images\r
-               nodes  = []                                                               # list of daughter names\r
-               while (stack[0] != "]"):                                         # for all nodes in stack\r
-                       newstate = stack[0]                                       # the new state\r
-                       newimage, width, height = draw( stack )                          # draw the daughter state\r
-                       if (newimage):\r
-                               tfimage = mxfm( newimage, width, height, stack )        # maybe transform daughter state\r
-                               images.append( [tfimage, width, height] )                        # list of daughter images\r
-                               nodes.append( newstate )                         # list of daughter nodes\r
-                       else:\r
-                               #inkex.debug(("recurse on",newstate,"failed")) # this should never happen\r
-                               return None, 0, 0\r
-               rule = findrule( state, nodes )                   # find the rule for this subtree\r
-\r
-               for i in range( 0, len(images)):\r
-                       currimg, width, height = images[i]\r
-\r
-                       if currimg:\r
-                               #box = getPathBoundingBox(currimg)\r
-                               dx = rule[i][1]*units\r
-                               dy = rule[i][2]*units\r
-                               #newbox = ((box[0]+dx),(box[1]+dy),(box[2]+dx),(box[3]+dy))\r
-                               simplepath.translatePath(currimg, dx, dy)\r
-                               image = combinePaths( image, currimg )\r
-\r
-               stack.pop( 0 )\r
-               return image, width, height\r
-\r
-def draw_crop_scale( stack, zoom ):                                                    # draw, crop and scale letter image\r
-       image, width, height = draw(stack)\r
-       bbox = getPathBoundingBox(image)                        \r
-       simplepath.translatePath(image, -bbox[0], 0)    \r
-       simplepath.scalePath(image, zoom/units, zoom/units)\r
-       return image, bbox[1] - bbox[0], bbox[3] - bbox[2]\r
-\r
-def randomize_input_string( str, zoom ):                                          # generate list of images based on input string\r
-       imagelist = []\r
-\r
-       for i in range(0,len(str)):\r
-               char = str[i]\r
-               #if ( re.match("[a-zA-Z0-9?]", char)):\r
-               if ( alphabet.has_key(char)):\r
-                       if ((i > 0) and (char == str[i-1])):             # if this letter matches previous letter\r
-                               imagelist.append(imagelist[len(stack)-1])# make them the same image\r
-                       else:                                                                           # generate image for letter\r
-                               stack = string.split( alphabet[char][random.randint(0,(len(alphabet[char])-1))] , "." )\r
-                               #stack = string.split( alphabet[char][random.randint(0,(len(alphabet[char])-2))] , "." ) \r
-                               imagelist.append( draw_crop_scale( stack, zoom ))\r
-               elif( char == " "):                                                       # add a " " space to the image list\r
-                       imagelist.append( " " )\r
-               else:                                                                                   # this character is not in config.alphabet, skip it\r
-                       inkex.errormsg(_("bad character") + " = 0x%x" % ord(char))\r
-       return imagelist\r
-\r
-def optikern( image, width, zoom ):                                   # optical kerning algorithm\r
-       left  = []\r
-       right = []\r
-\r
-       for i in range( 0, 36 ):\r
-               y = 0.5 * (i + 0.5) * zoom\r
-               xmin = None\r
-               xmax = None\r
-\r
-               for cmd,params in image:\r
-\r
-                       segmentBox = None\r
-\r
-                       if cmd == 'M':\r
-                               # A move cannot contribute to the bounding box\r
-                               last = params[:]\r
-                               lastctrl = params[:]\r
-                       elif cmd == 'L':\r
-                               if (y >= last[1] and y <= params[1]) or (y >= params[1] and y <= last[1]):\r
-                                       if params[0] == last[0]:\r
-                                               x = params[0]\r
-                                       else:\r
-                                               a = (params[1] - last[1]) / (params[0] - last[0])\r
-                                               b = last[1] - a * last[0]\r
-                                               if a != 0:\r
-                                                       x = (y - b) / a\r
-                                               else: x = None\r
-                                       \r
-                                       if x:\r
-                                               if xmin == None or x < xmin: xmin = x\r
-                                               if xmax == None or x > xmax: xmax = x\r
-\r
-                               last = params[:]\r
-                               lastctrl = params[:]\r
-                       elif cmd == 'C':\r
-                               if last:                \r
-                                       bx0, by0 = last[:]\r
-                                       bx1, by1, bx2, by2, bx3, by3 = params[:]\r
-\r
-                                       d = by0 - y\r
-                                       c = -3*by0 + 3*by1\r
-                                       b = 3*by0 - 6*by1 + 3*by2\r
-                                       a = -by0 + 3*by1 - 3*by2 + by3\r
-                                       \r
-                                       ts = findRealRoots(a, b, c, d)\r
-\r
-                                       for t in ts:\r
-                                               if t >= 0 and t <= 1:           \r
-                                                       x = (-bx0 + 3*bx1 - 3*bx2 + bx3)*(t**3) + \\r
-                                                               (3*bx0 - 6*bx1 + 3*bx2)*(t**2) + \\r
-                                                               (-3*bx0 + 3*bx1)*t + \\r
-                                                               bx0\r
-                                                       if xmin == None or x < xmin: xmin = x\r
-                                                       if xmax == None or x > xmax: xmax = x\r
-\r
-                               last = params[-2:]\r
-                               lastctrl = params[2:4]\r
-\r
-                       elif cmd == 'Q':\r
-                               # Quadratic beziers are ignored\r
-                               last = params[-2:]\r
-                               lastctrl = params[2:4]\r
-\r
-                       elif cmd == 'A':\r
-                               # Arcs are ignored\r
-                               last = params[-2:]\r
-                               lastctrl = params[2:4]\r
-\r
-\r
-               if xmin != None and xmax != None:\r
-                       left.append( xmin )                        # distance from left edge of region to left edge of bbox\r
-                       right.append( width - xmax )               # distance from right edge of region to right edge of bbox\r
-               else:\r
-                       left.append(  width )\r
-                       right.append( width )\r
-\r
-       return (left, right)\r
-\r
-def layoutstring( imagelist, zoom ):                                    # layout string of letter-images using optical kerning\r
-       kernlist  = []\r
-       length = zoom\r
-       for entry in imagelist:\r
-               if (entry == " "):                                                         # leaving room for " " space characters\r
-                       length = length + (zoom * render_alphabetsoup_config.space)\r
-               else:\r
-                       image, width, height = entry\r
-                       length = length + width + zoom   # add letter length to overall length\r
-                       kernlist.append( optikern(image, width, zoom) )            # append kerning data for this image \r
-\r
-       workspace = None\r
-\r
-       position = zoom\r
-       for i in range(0, len(kernlist)):\r
-               while(imagelist[i] == " "):\r
-                       position = position + (zoom * render_alphabetsoup_config.space )\r
-                       imagelist.pop(i)\r
-               image, width, height = imagelist[i]\r
-\r
-               # set the kerning\r
-               if i == 0: kern = 0                                               # for first image, kerning is zero\r
-               else:\r
-                       kerncompare = []                                                         # kerning comparison array\r
-                       for j in range( 0, len(kernlist[i][0])):\r
-                               kerncompare.append( kernlist[i][0][j]+kernlist[i-1][1][j] )\r
-                       kern = min( kerncompare )\r
-\r
-               position = position - kern                                         # move position back by kern amount\r
-               thisimage = copy.deepcopy(image)                \r
-               simplepath.translatePath(thisimage, position, 0)\r
-               workspace = combinePaths(workspace, thisimage)\r
-               position = position + width + zoom      # advance position by letter width\r
-\r
-       return workspace\r
-\r
-class AlphabetSoup(inkex.Effect):\r
-       def __init__(self):\r
-               inkex.Effect.__init__(self)\r
-               self.OptionParser.add_option("-t", "--text",\r
-                                               action="store", type="string", \r
-                                               dest="text", default="Inkscape",\r
-                                               help="The text for alphabet soup")\r
-               self.OptionParser.add_option("-z", "--zoom",\r
-                                               action="store", type="float", \r
-                                               dest="zoom", default="8.0",\r
-                                               help="The zoom on the output graphics")\r
-               self.OptionParser.add_option("-s", "--seed",\r
-                                               action="store", type="int", \r
-                                               dest="seed", default="0",\r
-                                               help="The random seed for the soup")\r
-\r
-       def effect(self):\r
-               zoom = self.options.zoom\r
-               random.seed(self.options.seed)\r
-\r
-               imagelist = randomize_input_string(self.options.text, zoom)\r
-               image = layoutstring( imagelist, zoom )\r
-\r
-               if image:\r
-                       s = { 'stroke': 'none', 'fill': '#000000' }\r
-\r
-                       new = inkex.etree.Element(inkex.addNS('path','svg'))\r
-                       new.set('style', simplestyle.formatStyle(s))\r
-\r
-                       new.set('d', simplepath.formatPath(image))\r
-                       self.current_layer.append(new)\r
-\r
-if __name__ == '__main__':\r
-    e = AlphabetSoup()\r
-    e.affect()\r
-\r
+#!/usr/bin/env python 
+'''
+Copyright (C) 2001-2002 Matt Chisholm matt@theory.org
+Copyright (C) 2008 Joel Holdsworth joel@airwebreathe.org.uk
+    for AP
+
+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
+the Free Software Foundation; either version 2 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+
+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 copy
+import inkex
+import simplestyle
+import math
+import cmath
+import string
+import random
+import render_alphabetsoup_config
+import bezmisc
+import simplepath
+import os
+import sys
+import gettext
+_ = gettext.gettext
+
+syntax   = render_alphabetsoup_config.syntax
+alphabet = render_alphabetsoup_config.alphabet
+units  = render_alphabetsoup_config.units
+font    = render_alphabetsoup_config.font
+
+# Loads a super-path from a given SVG file
+def loadPath( svgPath ):
+       extensionDir = os.path.normpath(
+                           os.path.join( os.getcwd(), os.path.dirname(__file__) )
+                         )
+       # __file__ is better then sys.argv[0] because this file may be a module
+       # for another one.
+       tree = inkex.etree.parse( extensionDir + "/" + svgPath )
+       root = tree.getroot()
+       pathElement = root.find('{http://www.w3.org/2000/svg}path')
+       if pathElement == None:
+               return None, 0, 0
+       d = pathElement.get("d")
+       width = float(root.get("width"))
+       height = float(root.get("height"))
+       return simplepath.parsePath(d), width, height # Currently we only support a single path
+
+def combinePaths( pathA, pathB ):
+       if pathA == None and pathB == None:
+               return None
+       elif pathA == None:
+               return pathB
+       elif pathB == None:
+               return pathA
+       else:
+               return pathA + pathB
+
+def flipLeftRight( sp, width ):
+       for cmd,params in sp:
+               defs = simplepath.pathdefs[cmd]
+               for i in range(defs[1]):
+                       if defs[3][i] == 'x':
+                               params[i] = width - params[i]
+
+def flipTopBottom( sp, height ):
+       for cmd,params in sp:
+               defs = simplepath.pathdefs[cmd]
+               for i in range(defs[1]):
+                       if defs[3][i] == 'y':
+                               params[i] = height - params[i]
+
+def solveQuadratic(a, b, c):
+       det = b*b - 4.0*a*c
+       if det >= 0: # real roots
+               sdet = math.sqrt(det)
+       else: # complex roots
+               sdet = cmath.sqrt(det)
+       return (-b + sdet) / (2*a), (-b - sdet) / (2*a)
+
+def cbrt(x): 
+       if x >= 0:
+               return x**(1.0/3.0)
+       else:
+               return -((-x)**(1.0/3.0))
+
+def findRealRoots(a,b,c,d):
+       if a != 0:
+               a, b, c, d = 1, b/float(a), c/float(a), d/float(a)      # Divide through by a
+               t = b / 3.0
+               p, q = c - 3 * t**2, d - c * t + 2 * t**3
+               u, v = solveQuadratic(1, q, -(p/3.0)**3)
+               if type(u) == type(0j):                 # Complex Cubic Root
+                       r = math.sqrt(u.real**2 + u.imag**2)
+                       w = math.atan2(u.imag, u.real)
+                       y1 = 2 * cbrt(r) * math.cos(w / 3.0)
+               else:           # Complex Real Root
+                       y1 = cbrt(u) + cbrt(v)
+               
+               y2, y3 = solveQuadratic(1, y1, p + y1**2)
+
+               if type(y2) == type(0j):        # Are y2 and y3 complex?
+                       return [y1 - t]
+               return [y1 - t, y2 - t, y3 - t]
+       elif b != 0:
+               det=c*c - 4.0*b*d
+               if det >= 0:
+                       return [(-c + math.sqrt(det))/(2.0*b),(-c - math.sqrt(det))/(2.0*b)]
+       elif c != 0:
+               return [-d/c]
+       return []
+
+def getPathBoundingBox( sp ):
+       
+       box = None
+       last = None
+       lostctrl = None
+
+       for cmd,params in sp:
+
+               segmentBox = None
+
+               if cmd == 'M':
+                       # A move cannot contribute to the bounding box
+                       last = params[:]
+                       lastctrl = params[:]
+               elif cmd == 'L':
+                       if last:
+                               segmentBox = (min(params[0], last[0]), max(params[0], last[0]), min(params[1], last[1]), max(params[1], last[1]))
+                       last = params[:]
+                       lastctrl = params[:]
+               elif cmd == 'C':
+                       if last:                
+                               segmentBox = (min(params[4], last[0]), max(params[4], last[0]), min(params[5], last[1]), max(params[5], last[1]))
+                               
+                               bx0, by0 = last[:]
+                               bx1, by1, bx2, by2, bx3, by3 = params[:]
+
+                               # Compute the x limits
+                               a = (-bx0 + 3*bx1 - 3*bx2 + bx3)*3
+                               b = (3*bx0 - 6*bx1  + 3*bx2)*2
+                               c = (-3*bx0 + 3*bx1)
+                               ts = findRealRoots(0, a, b, c)
+                               for t in ts:
+                                       if t >= 0 and t <= 1:           
+                                               x = (-bx0 + 3*bx1 - 3*bx2 + bx3)*(t**3) + \
+                                                       (3*bx0 - 6*bx1 + 3*bx2)*(t**2) + \
+                                                       (-3*bx0 + 3*bx1)*t + \
+                                                       bx0
+                                               segmentBox = (min(segmentBox[0], x), max(segmentBox[1], x), segmentBox[2], segmentBox[3])
+
+                               # Compute the y limits
+                               a = (-by0 + 3*by1 - 3*by2 + by3)*3
+                               b = (3*by0 - 6*by1  + 3*by2)*2
+                               c = (-3*by0 + 3*by1)
+                               ts = findRealRoots(0, a, b, c)
+                               for t in ts:
+                                       if t >= 0 and t <= 1:           
+                                               y = (-by0 + 3*by1 - 3*by2 + by3)*(t**3) + \
+                                                       (3*by0 - 6*by1 + 3*by2)*(t**2) + \
+                                                       (-3*by0 + 3*by1)*t + \
+                                                       by0
+                                               segmentBox = (segmentBox[0], segmentBox[1], min(segmentBox[2], y), max(segmentBox[3], y))
+
+                       last = params[-2:]
+                       lastctrl = params[2:4]
+
+               elif cmd == 'Q':
+                       # Provisional
+                       if last:
+                               segmentBox = (min(params[0], last[0]), max(params[0], last[0]), min(params[1], last[1]), max(params[1], last[1]))
+                       last = params[-2:]
+                       lastctrl = params[2:4]
+
+               elif cmd == 'A':
+                       # Provisional
+                       if last:
+                               segmentBox = (min(params[0], last[0]), max(params[0], last[0]), min(params[1], last[1]), max(params[1], last[1]))
+                       last = params[-2:]
+                       lastctrl = params[2:4]
+
+               if segmentBox:
+                       if box:
+                               box = (min(segmentBox[0],box[0]), max(segmentBox[1],box[1]), min(segmentBox[2],box[2]), max(segmentBox[3],box[3]))
+                       else:
+                               box = segmentBox                        
+       return box
+
+def mxfm( image, width, height, stack ):                                                               # returns possibly transformed image
+       tbimage = image 
+       if ( stack[0] == "-" ):                                                   # top-bottom flip
+               flipTopBottom(tbimage, height)
+               stack.pop( 0 )
+
+       lrimage = tbimage
+       if ( stack[0] == "|" ):                                                   # left-right flip
+               flipLeftRight(tbimage, width)
+               stack.pop( 0 )
+       return lrimage
+
+def comparerule( rule, nodes ):                                                  # compare node list to nodes in rule
+       for i in range( 0, len(nodes)):                                   # range( a, b ) = (a, a+1, a+2 ... b-2, b-1)
+               if (nodes[i] == rule[i][0]):
+                       pass
+               else: return 0
+       return 1
+
+def findrule( state, nodes ):                                                  # find the rule which generated this subtree
+       ruleset = syntax[state][1]
+       nodelen = len(nodes)
+       for rule in ruleset:
+               rulelen = len(rule)
+               if ((rulelen == nodelen) and (comparerule( rule, nodes ))):
+                       return rule
+       return 
+
+def generate( state ):                                                            # generate a random tree (in stack form)
+       stack  = [ state ]
+       if ( len(syntax[state]) == 1 ):                                         # if this is a stop symbol
+               return stack
+       else:
+               stack.append( "[" )
+               path = random.randint(0, (len(syntax[state][1])-1)) # choose randomly from next states
+               for symbol in syntax[state][1][path]:                   # recurse down each non-terminal
+                       if ( symbol != 0 ):                                               # 0 denotes end of list ###
+                               substack = generate( symbol[0] )                 # get subtree
+                               for elt in substack:       
+                                       stack.append( elt )
+                               if (symbol[3]):stack.append( "-" )         # top-bottom flip
+                               if (symbol[4]):stack.append( "|" )         # left-right flip
+                       #else:
+                               #inkex.debug("found end of list in generate( state =", state, ")") # this should be deprecated/never happen
+               stack.append("]")
+               return stack
+
+def draw( stack ):                                                                        # draw a character based on a tree stack
+       state = stack.pop(0)
+       #print state,
+
+       image, width, height = loadPath( font+syntax[state][0] )                  # load the image
+       if (stack[0] != "["):                                                           # terminal stack element
+               if (len(syntax[state]) == 1):                                     # this state is a terminal node
+                       return image, width, height
+               else:
+                       substack = generate( state )                             # generate random substack
+                       return draw( substack )                                   # draw random substack
+       else:
+               #inkex.debug("[")
+               stack.pop(0)
+               images = []                                                               # list of daughter images
+               nodes  = []                                                               # list of daughter names
+               while (stack[0] != "]"):                                         # for all nodes in stack
+                       newstate = stack[0]                                       # the new state
+                       newimage, width, height = draw( stack )                          # draw the daughter state
+                       if (newimage):
+                               tfimage = mxfm( newimage, width, height, stack )        # maybe transform daughter state
+                               images.append( [tfimage, width, height] )                        # list of daughter images
+                               nodes.append( newstate )                         # list of daughter nodes
+                       else:
+                               #inkex.debug(("recurse on",newstate,"failed")) # this should never happen
+                               return None, 0, 0
+               rule = findrule( state, nodes )                   # find the rule for this subtree
+
+               for i in range( 0, len(images)):
+                       currimg, width, height = images[i]
+
+                       if currimg:
+                               #box = getPathBoundingBox(currimg)
+                               dx = rule[i][1]*units
+                               dy = rule[i][2]*units
+                               #newbox = ((box[0]+dx),(box[1]+dy),(box[2]+dx),(box[3]+dy))
+                               simplepath.translatePath(currimg, dx, dy)
+                               image = combinePaths( image, currimg )
+
+               stack.pop( 0 )
+               return image, width, height
+
+def draw_crop_scale( stack, zoom ):                                                    # draw, crop and scale letter image
+       image, width, height = draw(stack)
+       bbox = getPathBoundingBox(image)                        
+       simplepath.translatePath(image, -bbox[0], 0)    
+       simplepath.scalePath(image, zoom/units, zoom/units)
+       return image, bbox[1] - bbox[0], bbox[3] - bbox[2]
+
+def randomize_input_string( str, zoom ):                                          # generate list of images based on input string
+       imagelist = []
+
+       for i in range(0,len(str)):
+               char = str[i]
+               #if ( re.match("[a-zA-Z0-9?]", char)):
+               if ( alphabet.has_key(char)):
+                       if ((i > 0) and (char == str[i-1])):             # if this letter matches previous letter
+                               imagelist.append(imagelist[len(stack)-1])# make them the same image
+                       else:                                                                           # generate image for letter
+                               stack = string.split( alphabet[char][random.randint(0,(len(alphabet[char])-1))] , "." )
+                               #stack = string.split( alphabet[char][random.randint(0,(len(alphabet[char])-2))] , "." ) 
+                               imagelist.append( draw_crop_scale( stack, zoom ))
+               elif( char == " "):                                                       # add a " " space to the image list
+                       imagelist.append( " " )
+               else:                                                                                   # this character is not in config.alphabet, skip it
+                       inkex.errormsg(_("bad character") + " = 0x%x" % ord(char))
+       return imagelist
+
+def optikern( image, width, zoom ):                                   # optical kerning algorithm
+       left  = []
+       right = []
+
+       for i in range( 0, 36 ):
+               y = 0.5 * (i + 0.5) * zoom
+               xmin = None
+               xmax = None
+
+               for cmd,params in image:
+
+                       segmentBox = None
+
+                       if cmd == 'M':
+                               # A move cannot contribute to the bounding box
+                               last = params[:]
+                               lastctrl = params[:]
+                       elif cmd == 'L':
+                               if (y >= last[1] and y <= params[1]) or (y >= params[1] and y <= last[1]):
+                                       if params[0] == last[0]:
+                                               x = params[0]
+                                       else:
+                                               a = (params[1] - last[1]) / (params[0] - last[0])
+                                               b = last[1] - a * last[0]
+                                               if a != 0:
+                                                       x = (y - b) / a
+                                               else: x = None
+                                       
+                                       if x:
+                                               if xmin == None or x < xmin: xmin = x
+                                               if xmax == None or x > xmax: xmax = x
+
+                               last = params[:]
+                               lastctrl = params[:]
+                       elif cmd == 'C':
+                               if last:                
+                                       bx0, by0 = last[:]
+                                       bx1, by1, bx2, by2, bx3, by3 = params[:]
+
+                                       d = by0 - y
+                                       c = -3*by0 + 3*by1
+                                       b = 3*by0 - 6*by1 + 3*by2
+                                       a = -by0 + 3*by1 - 3*by2 + by3
+                                       
+                                       ts = findRealRoots(a, b, c, d)
+
+                                       for t in ts:
+                                               if t >= 0 and t <= 1:           
+                                                       x = (-bx0 + 3*bx1 - 3*bx2 + bx3)*(t**3) + \
+                                                               (3*bx0 - 6*bx1 + 3*bx2)*(t**2) + \
+                                                               (-3*bx0 + 3*bx1)*t + \
+                                                               bx0
+                                                       if xmin == None or x < xmin: xmin = x
+                                                       if xmax == None or x > xmax: xmax = x
+
+                               last = params[-2:]
+                               lastctrl = params[2:4]
+
+                       elif cmd == 'Q':
+                               # Quadratic beziers are ignored
+                               last = params[-2:]
+                               lastctrl = params[2:4]
+
+                       elif cmd == 'A':
+                               # Arcs are ignored
+                               last = params[-2:]
+                               lastctrl = params[2:4]
+
+
+               if xmin != None and xmax != None:
+                       left.append( xmin )                        # distance from left edge of region to left edge of bbox
+                       right.append( width - xmax )               # distance from right edge of region to right edge of bbox
+               else:
+                       left.append(  width )
+                       right.append( width )
+
+       return (left, right)
+
+def layoutstring( imagelist, zoom ):                                    # layout string of letter-images using optical kerning
+       kernlist  = []
+       length = zoom
+       for entry in imagelist:
+               if (entry == " "):                                                         # leaving room for " " space characters
+                       length = length + (zoom * render_alphabetsoup_config.space)
+               else:
+                       image, width, height = entry
+                       length = length + width + zoom   # add letter length to overall length
+                       kernlist.append( optikern(image, width, zoom) )            # append kerning data for this image 
+
+       workspace = None
+
+       position = zoom
+       for i in range(0, len(kernlist)):
+               while(imagelist[i] == " "):
+                       position = position + (zoom * render_alphabetsoup_config.space )
+                       imagelist.pop(i)
+               image, width, height = imagelist[i]
+
+               # set the kerning
+               if i == 0: kern = 0                                               # for first image, kerning is zero
+               else:
+                       kerncompare = []                                                         # kerning comparison array
+                       for j in range( 0, len(kernlist[i][0])):
+                               kerncompare.append( kernlist[i][0][j]+kernlist[i-1][1][j] )
+                       kern = min( kerncompare )
+
+               position = position - kern                                         # move position back by kern amount
+               thisimage = copy.deepcopy(image)                
+               simplepath.translatePath(thisimage, position, 0)
+               workspace = combinePaths(workspace, thisimage)
+               position = position + width + zoom      # advance position by letter width
+
+       return workspace
+
+class AlphabetSoup(inkex.Effect):
+       def __init__(self):
+               inkex.Effect.__init__(self)
+               self.OptionParser.add_option("-t", "--text",
+                                               action="store", type="string", 
+                                               dest="text", default="Inkscape",
+                                               help="The text for alphabet soup")
+               self.OptionParser.add_option("-z", "--zoom",
+                                               action="store", type="float", 
+                                               dest="zoom", default="8.0",
+                                               help="The zoom on the output graphics")
+               self.OptionParser.add_option("-s", "--seed",
+                                               action="store", type="int", 
+                                               dest="seed", default="0",
+                                               help="The random seed for the soup")
+
+       def effect(self):
+               zoom = self.options.zoom
+               random.seed(self.options.seed)
+
+               imagelist = randomize_input_string(self.options.text, zoom)
+               image = layoutstring( imagelist, zoom )
+
+               if image:
+                       s = { 'stroke': 'none', 'fill': '#000000' }
+
+                       new = inkex.etree.Element(inkex.addNS('path','svg'))
+                       new.set('style', simplestyle.formatStyle(s))
+
+                       new.set('d', simplepath.formatPath(image))
+                       self.current_layer.append(new)
+
+if __name__ == '__main__':
+    e = AlphabetSoup()
+    e.affect()
+
index cda6c7a9745f45950f3f42823a39890d47efc2d4..1c663c11c954f254f8c61b9fc2d572d0272b5c1b 100755 (executable)
-<?xml version="1.0" encoding="UTF-8"?>\r
-\r
-<!--\r
-Copyright (c) 2005-2007 authors:\r
-Original version: Toine de Greef (a.degreef@chello.nl)\r
-Modified (2010) by Nicolas Dufour (nicoduf@yahoo.fr) (blur support, units\r
-convertion, comments, and some other fixes)\r
-\r
-Permission is hereby granted, free of charge, to any person obtaining a copy\r
-of this software and associated documentation files (the "Software"), to deal\r
-in the Software without restriction, including without limitation the rights\r
-to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\r
-copies of the Software, and to permit persons to whom the Software is\r
-furnished to do so, subject to the following conditions:\r
-\r
-The above copyright notice and this permission notice shall be included in\r
-all copies or substantial portions of the Software.\r
-\r
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\r
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\r
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\r
-AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\r
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\r
-OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\r
-THE SOFTWARE.\r
--->\r
-\r
-<xsl:stylesheet version="1.0"\r
-xmlns:xsl="http://www.w3.org/1999/XSL/Transform"\r
-xmlns:xlink="http://www.w3.org/1999/xlink"\r
-xmlns:xs="http://www.w3.org/2001/XMLSchema"\r
-xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"\r
-xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"\r
-xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"\r
-xmlns:exsl="http://exslt.org/common"\r
-xmlns:libxslt="http://xmlsoft.org/XSLT/namespace"\r
-exclude-result-prefixes="rdf xlink xs exsl libxslt">\r
-\r
-<xsl:strip-space elements="*" />\r
-<xsl:output method="xml" encoding="UTF-8"/>\r
-\r
-<xsl:param name="silverlight_compatible" select="1" />\r
-\r
-<!-- Root template.\r
-Everything starts here! -->\r
-<xsl:template match="/">\r
-  <xsl:choose>\r
-    <xsl:when test="$silverlight_compatible = 1">\r
-      <xsl:apply-templates mode="forward" />\r
-    </xsl:when>\r
-    <xsl:otherwise>\r
-      <Viewbox Stretch="Uniform">\r
-        <xsl:apply-templates mode="forward" />\r
-      </Viewbox>\r
-    </xsl:otherwise>   \r
-  </xsl:choose>\r
-</xsl:template>\r
-\r
-<!-- SVG and groups\r
-(including layers) -->\r
-<xsl:template mode="forward" match="*[name(.) = 'svg' or name(.) = 'g']">\r
-  <xsl:choose>\r
-    <xsl:when test="name(.) = 'svg' or @transform or @viewBox or @id or @clip-path or (@style and contains(@style, 'clip-path:url(#')) or (@width and not(contains(@width, '%'))) or @x or @y or (@height and not(contains(@height, '%'))) or *[name(.) = 'linearGradient' or name(.) = 'radialGradient' or name(.) = 'defs' or name(.) = 'clipPath']">\r
-      <Canvas>\r
-        <xsl:apply-templates mode="id" select="." />\r
-        <!--\r
-        <xsl:apply-templates mode="clip" select="." />\r
-        -->\r
-        <xsl:if test="@style and contains(@style, 'display:none')"><xsl:attribute name="Visibility">Collapsed</xsl:attribute></xsl:if>\r
-        <xsl:if test="@style and contains(@style, 'opacity:')">\r
-        <xsl:attribute name="Opacity">\r
-            <xsl:choose>\r
-                <xsl:when test="contains(substring-after(@style, 'opacity:'), ';')"><xsl:value-of select="substring-before(substring-after(@style, 'opacity:'), ';')" /></xsl:when>\r
-                  <xsl:otherwise><xsl:value-of select="substring-after(@style, 'opacity:')" /></xsl:otherwise>\r
-            </xsl:choose>\r
-        </xsl:attribute>\r
-        </xsl:if>\r
-        <xsl:if test="@width and not(contains(@width, '%'))">\r
-        <xsl:attribute name="Width">\r
-            <xsl:call-template name="convert_unit">\r
-                <xsl:with-param name="convert_value" select="@width" />\r
-            </xsl:call-template>\r
-        </xsl:attribute></xsl:if>\r
-        <xsl:if test="@height and not(contains(@height, '%'))">\r
-        <xsl:attribute name="Height">\r
-            <xsl:call-template name="convert_unit">\r
-                <xsl:with-param name="convert_value" select="@height" />\r
-            </xsl:call-template>\r
-        </xsl:attribute></xsl:if>\r
-        <xsl:if test="@x">\r
-       <xsl:attribute name="Canvas.Left">\r
-            <xsl:call-template name="convert_unit">\r
-                <xsl:with-param name="convert_value" select="@x" />\r
-            </xsl:call-template>\r
-       </xsl:attribute></xsl:if>\r
-        <xsl:if test="@y">\r
-       <xsl:attribute name="Canvas.Top">\r
-            <xsl:call-template name="convert_unit">\r
-                <xsl:with-param name="convert_value" select="@y" />\r
-            </xsl:call-template>\r
-       </xsl:attribute></xsl:if>\r
-        <xsl:if test="@viewBox">\r
-          <xsl:variable name="viewBox"><xsl:value-of select="normalize-space(translate(@viewBox, ',', ' '))" /></xsl:variable>\r
-          <xsl:attribute name="Width"><xsl:value-of select="substring-before(substring-after(substring-after($viewBox, ' '), ' '), ' ')" /></xsl:attribute>\r
-          <xsl:attribute name="Height"><xsl:value-of select="substring-after(substring-after(substring-after($viewBox, ' '), ' '), ' ')" /></xsl:attribute>\r
-          <Canvas.RenderTransform>\r
-            <TranslateTransform>\r
-              <xsl:attribute name="X"><xsl:value-of select="-number(substring-before($viewBox, ' '))" /></xsl:attribute>\r
-              <xsl:attribute name="Y"><xsl:value-of select="-number(substring-before(substring-after($viewBox, ' '), ' '))" /></xsl:attribute>\r
-            </TranslateTransform>\r
-          </Canvas.RenderTransform>\r
-        </xsl:if>\r
-    <xsl:if test="@transform">\r
-      <Canvas>\r
-        <Canvas.RenderTransform>\r
-          <TransformGroup><xsl:apply-templates mode="transform" select="." /></TransformGroup>\r
-        </Canvas.RenderTransform>\r
-        <xsl:apply-templates mode="forward" select="*" />\r
-      </Canvas>\r
-    </xsl:if>\r
-\r
-        <xsl:if test="*[name(.) = 'linearGradient' or name(.) = 'radialGradient' or name(.) = 'defs' or name(.) = 'clipPath']">\r
-          <Canvas.Resources>\r
-            <xsl:apply-templates mode="forward" select="*[name(.) = 'linearGradient' or name(.) = 'radialGradient' or name(.) = 'defs' or name(.) = 'clipPath']" />\r
-          </Canvas.Resources>\r
-        </xsl:if>\r
-        <xsl:if test="not(@transform)">\r
-          <xsl:apply-templates mode="forward" select="*[name(.) != 'linearGradient' and name(.) != 'radialGradient' and name(.) != 'defs' and name(.) != 'clipPath']" />\r
-        </xsl:if>  \r
-      </Canvas>\r
-    </xsl:when>\r
-    <xsl:when test="not(@transform)">\r
-      <xsl:apply-templates mode="forward" select="*" />\r
-    </xsl:when>\r
-  </xsl:choose>\r
-</xsl:template>\r
-\r
-<!--\r
-// Resources (defs) //\r
-\r
-* Resources ids\r
-* Generic defs template\r
-* Generic filters template\r
-* Filter effects\r
-* Linked filter effects\r
-* Linear gradients\r
-* Radial gradients\r
-* Generic gradient stops\r
-* Clipping\r
--->\r
-\r
-<!-- Resources ids -->\r
-<xsl:template mode="resources" match="*">\r
-  <!-- should be in-depth -->\r
-  <xsl:if test="ancestor::*[name(.) = 'defs']"><xsl:attribute name="x:Key"><xsl:value-of select="@id" /></xsl:attribute></xsl:if>\r
-</xsl:template>\r
-\r
-<!-- Generic defs template -->\r
-<xsl:template mode="forward" match="defs">\r
-  <xsl:apply-templates mode="forward" />\r
-</xsl:template>\r
-\r
-<!-- Generic filters template\r
-Limited to one filter (can be improved) -->\r
-<xsl:template mode="forward" match="*[name(.) = 'filter']">\r
-    <xsl:if test="count(*) = 1">\r
-      <xsl:apply-templates mode="forward" />\r
-    </xsl:if> \r
-</xsl:template>\r
-\r
-<!-- Filter effects -->\r
-<xsl:template mode="forward" match="*[name(.) = 'feGaussianBlur']">\r
-        <BlurEffect>\r
-            <xsl:if test="../@id"><xsl:attribute name="x:Key"><xsl:value-of select="../@id" /></xsl:attribute></xsl:if>\r
-            <xsl:if test="@stdDeviation"><xsl:attribute name="Radius"><xsl:value-of select="round(@stdDeviation * 3)" /></xsl:attribute></xsl:if>\r
-        </BlurEffect>  \r
-</xsl:template>\r
-\r
-<!-- Linked filter effect -->\r
-<xsl:template mode="filter_effect" match="*">\r
-<xsl:choose>\r
-    <xsl:when test="@filter and starts-with(@filter, 'url(#')">\r
-        <xsl:attribute name="Effect">\r
-            <xsl:value-of select="concat('{StaticResource ', substring-before(substring-after(@filter, 'url(#'), ')'), '}')" />\r
-        </xsl:attribute>\r
-    </xsl:when>\r
-    <xsl:when test="@style and contains(@style, 'filter:url(#')">\r
-        <xsl:attribute name="Effect">\r
-            <xsl:value-of select="concat('{StaticResource ', substring-before(substring-after(@style, 'filter:url(#'), ')'), '}')" />\r
-        </xsl:attribute>\r
-    </xsl:when>\r
-</xsl:choose>\r
-</xsl:template>\r
-\r
-<!-- Linear gradient -->\r
-<xsl:template mode="forward" match="*[name(.) = 'linearGradient']">\r
-  <LinearGradientBrush>\r
-    <xsl:if test="@id"><xsl:attribute name="x:Key"><xsl:value-of select="@id" /></xsl:attribute></xsl:if>\r
-    <xsl:attribute name="MappingMode">\r
-      <xsl:choose>\r
-        <xsl:when test="@gradientUnits = 'userSpaceOnUse' ">Absolute</xsl:when>\r
-        <xsl:otherwise>RelativeToBoundingBox</xsl:otherwise>\r
-      </xsl:choose>\r
-    </xsl:attribute>\r
-    <xsl:if test="@spreadMethod">\r
-      <xsl:attribute name="SpreadMethod">\r
-        <xsl:choose>\r
-          <xsl:when test="@spreadMethod = 'pad'">Pad</xsl:when>\r
-          <xsl:when test="@spreadMethod = 'reflect'">Reflect</xsl:when>\r
-          <xsl:when test="@spreadMethod = 'repeat'">Repeat</xsl:when>\r
-        </xsl:choose>\r
-      </xsl:attribute>\r
-    </xsl:if>\r
-    <xsl:choose>\r
-      <xsl:when test="@x1 and @y1 and @x2 and @y2">\r
-        <xsl:choose>\r
-          <xsl:when test="contains(@x1, '%') and contains(@y1, '%')">\r
-            <xsl:attribute name="StartPoint"><xsl:value-of select="concat(substring-before(@x1, '%') div 100, ',', substring-before(@y1,'%') div 100)" /></xsl:attribute>\r
-          </xsl:when>\r
-          <xsl:otherwise>\r
-            <xsl:attribute name="StartPoint"><xsl:value-of select="concat(@x1, ',', @y1)" /></xsl:attribute>\r
-          </xsl:otherwise>\r
-        </xsl:choose>\r
-        <xsl:choose>\r
-          <xsl:when test="contains(@x2, '%') and contains(@y2, '%')">\r
-            <xsl:attribute name="EndPoint"><xsl:value-of select="concat(substring-before(@x2, '%') div 100, ',', substring-before(@y2,'%') div 100)" /></xsl:attribute>\r
-          </xsl:when>\r
-          <xsl:otherwise>\r
-            <xsl:attribute name="EndPoint"><xsl:value-of select="concat(@x2, ',', @y2)" /></xsl:attribute>\r
-          </xsl:otherwise>\r
-        </xsl:choose>  \r
-      </xsl:when>\r
-      <xsl:otherwise>\r
-        <xsl:attribute name="StartPoint"><xsl:value-of select="'0,0'" /></xsl:attribute>\r
-        <xsl:attribute name="EndPoint"><xsl:value-of select="'1,1'" /></xsl:attribute>\r
-      </xsl:otherwise>\r
-    </xsl:choose>\r
-    <LinearGradientBrush.GradientStops>\r
-      <GradientStopCollection>\r
-        <xsl:choose>\r
-          <xsl:when test="@xlink:href">\r
-            <xsl:variable name="reference_id" select="@xlink:href" />\r
-            <xsl:apply-templates mode="forward" select="//*[name(.) = 'linearGradient' and $reference_id = concat('#', @id)]/*" />\r
-          </xsl:when>\r
-          <xsl:otherwise><xsl:apply-templates mode="forward" /></xsl:otherwise>\r
-        </xsl:choose>\r
-      </GradientStopCollection>\r
-    </LinearGradientBrush.GradientStops>\r
-    <xsl:if test="@gradientTransform">\r
-    <LinearGradientBrush.Transform>\r
-      <xsl:apply-templates mode="transform" select="." />\r
-    </LinearGradientBrush.Transform>\r
-  </xsl:if>\r
-  </LinearGradientBrush>\r
-</xsl:template>\r
-\r
-<!-- Radial gradient -->\r
-<xsl:template mode="forward" match="*[name(.) = 'radialGradient']">\r
-  <RadialGradientBrush>\r
-    <xsl:if test="@id"><xsl:attribute name="x:Key"><xsl:value-of select="@id" /></xsl:attribute></xsl:if>\r
-    <xsl:attribute name="MappingMode">\r
-      <xsl:choose>\r
-        <xsl:when test="@gradientUnits = 'userSpaceOnUse' ">Absolute</xsl:when>\r
-        <xsl:otherwise>RelativeToBoundingBox</xsl:otherwise>\r
-      </xsl:choose>\r
-    </xsl:attribute>\r
-    <xsl:if test="@spreadMethod">\r
-      <xsl:attribute name="SpreadMethod">\r
-        <xsl:choose>\r
-          <xsl:when test="@spreadMethod = 'pad'">Pad</xsl:when>\r
-          <xsl:when test="@spreadMethod = 'reflect'">Reflect</xsl:when>\r
-          <xsl:when test="@spreadMethod = 'repeat'">Repeat</xsl:when>\r
-        </xsl:choose>\r
-      </xsl:attribute>\r
-    </xsl:if>\r
-    <xsl:if test="@cx and @cy">\r
-      <xsl:attribute name="Center">\r
-        <xsl:choose>\r
-          <xsl:when test="contains(@cx, '%') and contains(@cy, '%')">\r
-            <xsl:value-of select="concat(number(substring-before(@cx, '%')) div 100, ',', number(substring-before(@cy, '%')) div 100)" />\r
-          </xsl:when>\r
-          <xsl:otherwise>\r
-            <xsl:value-of select="concat(@cx, ',', @cy)" />\r
-          </xsl:otherwise>\r
-        </xsl:choose>\r
-      </xsl:attribute>\r
-    </xsl:if>  \r
-    <xsl:if test="@fx and @fy">\r
-      <xsl:attribute name="GradientOrigin">\r
-        <xsl:choose>\r
-          <xsl:when test="contains(@fx, '%') and contains(@fy, '%')">\r
-            <xsl:value-of select="concat(number(substring-before(@fx, '%')) div 100, ',', number(substring-before(@fy, '%')) div 100)" />\r
-          </xsl:when>\r
-          <xsl:otherwise>\r
-            <xsl:value-of select="concat(@fx, ',', @fy)" />\r
-          </xsl:otherwise>\r
-        </xsl:choose>\r
-      </xsl:attribute>\r
-    </xsl:if>\r
-    <xsl:if test="@r">\r
-      <xsl:choose>\r
-        <xsl:when test="contains(@r, '%')">\r
-          <xsl:attribute name="RadiusX"><xsl:value-of select="number(substring-before(@r, '%')) div 100" /></xsl:attribute>\r
-          <xsl:attribute name="RadiusY"><xsl:value-of select="number(substring-before(@r, '%')) div 100" /></xsl:attribute>\r
-        </xsl:when>\r
-        <xsl:otherwise>\r
-          <xsl:attribute name="RadiusX"><xsl:value-of select="@r" /></xsl:attribute>\r
-          <xsl:attribute name="RadiusY"><xsl:value-of select="@r" /></xsl:attribute>\r
-        </xsl:otherwise>\r
-      </xsl:choose>\r
-    </xsl:if>\r
-    <RadialGradientBrush.GradientStops>\r
-      <GradientStopCollection>\r
-        <xsl:choose>\r
-          <xsl:when test="@xlink:href">\r
-            <xsl:variable name="reference_id" select="@xlink:href" />\r
-            <xsl:apply-templates mode="forward" select="//*[name(.) = 'linearGradient' and $reference_id = concat('#', @id)]/*" />\r
-          </xsl:when>\r
-          <xsl:otherwise><xsl:apply-templates mode="forward" /></xsl:otherwise>\r
-        </xsl:choose>\r
-      </GradientStopCollection>\r
-    </RadialGradientBrush.GradientStops>\r
-    <xsl:if test="@gradientTransform">\r
-    <RadialGradientBrush.Transform>\r
-      <xsl:apply-templates mode="transform" select="." />\r
-    </RadialGradientBrush.Transform>\r
-    </xsl:if>\r
-  </RadialGradientBrush>\r
-</xsl:template>\r
-\r
-<!-- Generic gradient stops -->\r
-<xsl:template mode="forward" match="*[name(.) = 'stop']">\r
-  <GradientStop>\r
-    <!--xsl:apply-templates mode="stop_opacity" select="." /-->\r
-    <xsl:apply-templates mode="stop_color" select="." />\r
-    <xsl:apply-templates mode="offset" select="." />\r
-    <xsl:apply-templates mode="forward" />\r
-  </GradientStop>\r
-</xsl:template>\r
-\r
-<!-- Clipping -->\r
-<xsl:template mode="clip" match="*">\r
-  <xsl:choose>\r
-    <xsl:when test="@clip-path and defs/clipPath/path/@d"><xsl:attribute name="Clip"><xsl:value-of select="defs/clipPath/path/@d" /></xsl:attribute></xsl:when>\r
-    <xsl:when test="@clip-path and starts-with(@clip-path, 'url(#')"><xsl:attribute name="Clip"><xsl:value-of select="concat('{StaticResource ', substring-before(substring-after(@clip-path, 'url(#'), ')'), '}')" /></xsl:attribute></xsl:when>\r
-    <xsl:when test="@style and contains(@style, 'clip-path:url(#')"><xsl:attribute name="Clip"><xsl:value-of select="concat('{StaticResource ', substring-before(substring-after(@style, 'url(#'), ')'), '}')" /></xsl:attribute></xsl:when>\r
-    <xsl:when test="clipPath"><xsl:apply-templates mode="forward" /></xsl:when>\r
-  </xsl:choose>\r
-</xsl:template>\r
-\r
-<!--\r
-// Misc templates //\r
-\r
-* Object description\r
-* Id converter\r
-* Decimal to hexadecimal converter\r
-* Unit to pixel converter\r
-* Title and description\r
-* Misc ignored stuff (markers, patterns, styles)\r
-* Symbols\r
-* Use\r
-* RDF and foreign objects\r
-* Unknows tags\r
--->\r
-\r
-<!-- Object description -->\r
-<xsl:template mode="desc" match="*">\r
-  <xsl:if test="*[name(.) = 'desc']/text()"><xsl:attribute name="Tag"><xsl:value-of select="*[name(.) = 'desc']/text()" /></xsl:attribute></xsl:if>\r
-</xsl:template>\r
-\r
-<!-- Id converter. Removes "-" from the original id. -->\r
-<xsl:template mode="id" match="*">\r
-<xsl:if test="@id">\r
-  <xsl:attribute name="Name"><xsl:value-of select="translate(@id, '- ', '')" /></xsl:attribute>\r
-  <!--\r
-    <xsl:attribute name="x:Key"><xsl:value-of select="translate(@id, '- ', '')" /></xsl:attribute>\r
-  -->\r
-</xsl:if>\r
-</xsl:template>\r
-\r
-<!-- Decimal to hexadecimal converter -->\r
-<xsl:template name="to_hex">\r
-  <xsl:param name="convert" />\r
-  <xsl:value-of select="concat(substring('0123456789ABCDEF', 1 + floor(round($convert) div 16), 1), substring('0123456789ABCDEF', 1 + round($convert) mod 16, 1))" />\r
-</xsl:template>\r
-\r
-<!-- Unit to pixel converter\r
-Values with units (except %) are converted to pixels and rounded.\r
-Unknown units are kept. -->\r
-<xsl:template name="convert_unit">\r
-  <xsl:param name="convert_value" />\r
-      <xsl:choose>\r
-        <xsl:when test="contains($convert_value, 'px')">\r
-            <xsl:value-of select="round(translate($convert_value, 'px', ''))" />\r
-        </xsl:when>\r
-        <xsl:when test="contains($convert_value, 'pt')">\r
-            <xsl:value-of select="round(translate($convert_value, 'pt', '') * 1.25)" />\r
-        </xsl:when>\r
-        <xsl:when test="contains($convert_value, 'pc')">\r
-            <xsl:value-of select="round(translate($convert_value, 'pc', '') * 15)" />\r
-        </xsl:when>\r
-        <xsl:when test="contains($convert_value, 'mm')">\r
-            <xsl:value-of select="round(translate($convert_value, 'mm', '') * 3.543307)" />\r
-        </xsl:when>\r
-        <xsl:when test="contains($convert_value, 'cm')">\r
-            <xsl:value-of select="round(translate($convert_value, 'cm', '') * 35.43307)" />\r
-        </xsl:when>\r
-        <xsl:when test="contains($convert_value, 'in')">\r
-            <xsl:value-of select="round(translate($convert_value, 'in', '') * 90)" />\r
-        </xsl:when>\r
-        <xsl:when test="contains($convert_value, 'ft')">\r
-            <xsl:value-of select="round(translate($convert_value, 'ft', '') * 1080)" />\r
-        </xsl:when>\r
-        <xsl:when test="not(string(number($convert_value))='NaN')">\r
-            <xsl:value-of select="round($convert_value)" />\r
-        </xsl:when>\r
-        <xsl:otherwise>\r
-            <xsl:value-of select="$convert_value" />\r
-        </xsl:otherwise>\r
-      </xsl:choose>\r
-</xsl:template>\r
-\r
-<!-- Title and description\r
-Blank template. Title is ignored and desc is converted to Tag in the mode="desc" template\r
--->\r
-<xsl:template mode="forward" match="*[name(.) = 'title' or name(.) = 'desc']">\r
-  <!-- -->\r
-</xsl:template>\r
-\r
-<!-- Misc ignored stuff (markers, patterns, styles) -->\r
-<xsl:template mode="forward" match="*[name(.) = 'marker' or name(.) = 'pattern' or name(.) = 'style']">\r
-  <!-- -->\r
-</xsl:template>\r
-\r
-<!-- Symbols -->\r
-<xsl:template mode="forward" match="*[name(.) = 'symbol']">\r
-  <Style>\r
-    <xsl:if test="@id"><xsl:attribute name="x:Key"><xsl:value-of select="@id" /></xsl:attribute></xsl:if>\r
-    <Canvas>\r
-      <xsl:apply-templates mode="forward" />\r
-    </Canvas>\r
-  </Style>\r
-</xsl:template>\r
-\r
-<!-- Use -->\r
-<xsl:template mode="forward" match="*[name(.) = 'use']">\r
-  <Canvas>\r
-    <xsl:if test="@xlink:href"><xsl:attribute name="Style"><xsl:value-of select="@xlink:href" /></xsl:attribute></xsl:if>\r
-    <!--xsl:apply-templates mode="transform" select="." /-->\r
-    <xsl:apply-templates mode="forward" />\r
-  </Canvas>\r
-</xsl:template>\r
-\r
-<!-- RDF and foreign objects -->\r
-<xsl:template mode="forward" match="rdf:RDF | *[name(.) = 'foreignObject']">\r
-  <!-- -->\r
-</xsl:template>\r
-\r
-<!-- Unknown tags -->\r
-<xsl:template match="*">\r
-<xsl:comment><xsl:value-of select="concat('Unknown tag: ', name(.))" /></xsl:comment>\r
-</xsl:template>\r
-\r
-\r
-<!--\r
-// Colors and patterns //\r
-\r
-* Generic color template\r
-* Fill\r
-* Fill opacity\r
-* Fill rule\r
-* Generic fill template\r
-* Stroke\r
-* Stroke opacity\r
-* Generic stroke template\r
-* Stroke width\r
-* Stroke mitterlimit\r
-* Stroke dasharray\r
-* Stroke dashoffset\r
-* Linejoin SVG to XAML converter\r
-* Stroke linejoin\r
-* Linecap SVG to XAML converter\r
-* Stroke linecap\r
-* Gradient stop\r
-* Gradient stop opacity\r
-* Gradient stop offset\r
--->\r
-\r
-<!-- Generic color template -->\r
-<xsl:template name="template_color">\r
-  <xsl:param name="colorspec" />\r
-  <xsl:param name="opacityspec" />\r
-  <xsl:choose>\r
-    <xsl:when test="starts-with($colorspec, 'rgb(') and not(contains($colorspec , '%'))">\r
-      <xsl:value-of select="'#'" />\r
-      <xsl:if test="$opacityspec != '' and number($opacityspec) != 1"><xsl:call-template name="to_hex"><xsl:with-param name="convert"><xsl:value-of select="round(number($opacityspec) * 255)" /></xsl:with-param></xsl:call-template></xsl:if>\r
-      <xsl:call-template name="to_hex"><xsl:with-param name="convert"><xsl:value-of select="substring-before(substring-after($colorspec, 'rgb('), ',')" /></xsl:with-param></xsl:call-template>\r
-      <xsl:call-template name="to_hex"><xsl:with-param name="convert"><xsl:value-of select="substring-before(substring-after(substring-after($colorspec, 'rgb('), ','), ',')" /></xsl:with-param></xsl:call-template>\r
-      <xsl:call-template name="to_hex"><xsl:with-param name="convert"><xsl:value-of select="substring-before(substring-after(substring-after(substring-after($colorspec, 'rgb('), ','), ','), ')')" /></xsl:with-param></xsl:call-template>\r
-    </xsl:when>\r
-    <xsl:when test="starts-with($colorspec, 'rgb(') and contains($colorspec , '%')">\r
-      <xsl:value-of select="'#'" />\r
-      <xsl:if test="$opacityspec != '' and number($opacityspec) != 1"><xsl:call-template name="to_hex"><xsl:with-param name="convert"><xsl:value-of select="round(number($opacityspec) * 255)" /></xsl:with-param></xsl:call-template></xsl:if>\r
-      <xsl:call-template name="to_hex"><xsl:with-param name="convert"><xsl:value-of select="number(substring-before(substring-after($colorspec, 'rgb('), '%,')) * 255 div 100" /></xsl:with-param></xsl:call-template>\r
-      <xsl:call-template name="to_hex"><xsl:with-param name="convert"><xsl:value-of select="number(substring-before(substring-after(substring-after($colorspec, 'rgb('), ','), '%,')) * 255 div 100" /></xsl:with-param></xsl:call-template>\r
-      <xsl:call-template name="to_hex"><xsl:with-param name="convert"><xsl:value-of select="number(substring-before(substring-after(substring-after(substring-after($colorspec, 'rgb('), ','), ','), '%)')) * 255 div 100" /></xsl:with-param></xsl:call-template>\r
-    </xsl:when>\r
-    <xsl:when test="starts-with($colorspec, '#')">\r
-      <xsl:value-of select="'#'" />\r
-      <xsl:if test="$opacityspec != ''"><xsl:call-template name="to_hex"><xsl:with-param name="convert"><xsl:value-of select="round(number($opacityspec) * 255)" /></xsl:with-param></xsl:call-template></xsl:if>\r
-      <xsl:choose>\r
-        <xsl:when test="string-length(substring-after($colorspec, '#')) = 3">\r
-          <xsl:variable name="colorspec3"><xsl:value-of select="translate(substring-after($colorspec, '#'), 'abcdefgh', 'ABCDEFGH')" /></xsl:variable>\r
-          <xsl:value-of select="concat(substring($colorspec3, 1, 1), substring($colorspec3, 1, 1))" />\r
-          <xsl:value-of select="concat(substring($colorspec3, 2, 1), substring($colorspec3, 2, 1))" />\r
-          <xsl:value-of select="concat(substring($colorspec3, 3, 1), substring($colorspec3, 3, 1))" />\r
-        </xsl:when>\r
-        <xsl:otherwise><xsl:value-of select="translate(substring-after($colorspec, '#'), 'abcdefgh', 'ABCDEFGH')" /></xsl:otherwise>\r
-      </xsl:choose>\r
-    </xsl:when>\r
-    <xsl:otherwise>\r
-      <xsl:variable name="named_color_hex" select="document('colors.xml')/colors/color[@name = translate($colorspec, 'ABCDEFGHIJKLMNOPQRSTUVWXYZ', 'abcdefghijklmnopqrstuvwxyz')]/@hex" />\r
-      <xsl:choose>\r
-        <xsl:when test="$named_color_hex and $named_color_hex != ''">\r
-          <xsl:value-of select="'#'" />\r
-          <xsl:if test="$opacityspec != '' and number($opacityspec) != 1"><xsl:call-template name="to_hex"><xsl:with-param name="convert"><xsl:value-of select="number($opacityspec) * 255" /></xsl:with-param></xsl:call-template></xsl:if>\r
-          <xsl:value-of select="substring-after($named_color_hex, '#')" />\r
-        </xsl:when>\r
-        <xsl:otherwise><xsl:value-of select="$colorspec" /></xsl:otherwise>\r
-      </xsl:choose>\r
-    </xsl:otherwise>\r
-  </xsl:choose>\r
-</xsl:template>\r
-\r
-<!-- Fill -->\r
-<xsl:template mode="fill" match="*">\r
-  <xsl:choose>\r
-    <xsl:when test="@fill and starts-with(@fill, 'url(#')"><xsl:value-of select="concat('{StaticResource ', substring-before(substring-after(@fill, 'url(#'), ')'), '}')" /></xsl:when>\r
-    <xsl:when test="@fill"><xsl:value-of select="@fill" /></xsl:when>\r
-    <xsl:when test="@style and contains(@style, 'fill:') and starts-with(substring-after(@style, 'fill:'), 'url(#')"><xsl:value-of select="concat('{StaticResource ', substring-before(substring-after(@style, 'url(#'), ')'), '}')" /></xsl:when>\r
-    <xsl:when test="@style and contains(@style, 'fill:')">\r
-      <xsl:variable name="Fill" select="substring-after(@style, 'fill:')" />\r
-      <xsl:choose>\r
-        <xsl:when test="contains($Fill, ';')">\r
-          <xsl:value-of select="substring-before($Fill, ';')" />\r
-        </xsl:when>\r
-        <xsl:otherwise><xsl:value-of select="$Fill" /></xsl:otherwise>\r
-      </xsl:choose>\r
-    </xsl:when>\r
-    <xsl:when test="name(..) = 'g' or name(..) = 'svg'"><xsl:apply-templates mode="fill" select="parent::*"/></xsl:when>\r
-  </xsl:choose>\r
-</xsl:template>\r
-\r
-<!-- Fill opacity -->\r
-<xsl:template mode="fill_opacity" match="*">\r
-  <xsl:choose>\r
-    <xsl:when test="@fill-opacity"><xsl:value-of select="@fill-opacity" /></xsl:when>\r
-    <xsl:when test="@style and contains(@style, 'fill-opacity:')">\r
-      <xsl:variable name="Opacity" select="substring-after(@style, 'fill-opacity:')" />\r
-      <xsl:choose>\r
-        <xsl:when test="contains($Opacity, ';')"><xsl:value-of select="substring-before($Opacity, ';')" /></xsl:when>\r
-        <xsl:otherwise><xsl:value-of select="$Opacity" /></xsl:otherwise>\r
-      </xsl:choose>\r
-    </xsl:when>\r
-    <xsl:when test="name(..) = 'g' or name(..) = 'svg'"><xsl:apply-templates mode="fill_opacity" select="parent::*" /></xsl:when>\r
-  </xsl:choose>\r
-</xsl:template>\r
-\r
-<!-- Fill rule -->\r
-<xsl:template mode="fill_rule" match="*">\r
-  <xsl:choose>\r
-    <xsl:when test="@fill-rule and (@fill-rule = 'nonzero' or @fill-rule = 'evenodd')"><xsl:attribute name="FillRule"><xsl:value-of select="@fill-rule" /></xsl:attribute></xsl:when>\r
-    <xsl:when test="@style and contains(@style, 'fill-rule:')">\r
-      <xsl:variable name="FillRule" select="substring-after(@style, 'fill-rule:')" />\r
-      <xsl:choose>\r
-        <xsl:when test="contains($FillRule, ';')">\r
-          <xsl:if test="substring-before($FillRule, ';') = 'nonzero' or substring-before($FillRule, ';') = 'evenodd'"><xsl:attribute name="FillRule"><xsl:value-of select="substring-before($FillRule, ';')" /></xsl:attribute></xsl:if>\r
-        </xsl:when>\r
-        <xsl:when test="$FillRule = 'nonzero' or $FillRule = 'evenodd'"><xsl:attribute name="FillRule"><xsl:value-of select="$FillRule" /></xsl:attribute></xsl:when>\r
-      </xsl:choose>\r
-    </xsl:when>\r
-    <xsl:when test="name(..) = 'g' or name(..) = 'svg'"><xsl:apply-templates mode="fill_rule" select="parent::*"/></xsl:when>\r
-    <xsl:otherwise><xsl:attribute name="FillRule">NonZero</xsl:attribute></xsl:otherwise>\r
-  </xsl:choose>\r
-</xsl:template>\r
-\r
-<!-- Generic fill template -->\r
-<xsl:template mode="template_fill" match="*">\r
-  <xsl:variable name="fill"><xsl:apply-templates mode="fill" select="." /></xsl:variable>\r
-  <xsl:variable name="fill_opacity"><xsl:apply-templates mode="fill_opacity" select="." /></xsl:variable>\r
-  <xsl:if test="not($fill = 'none')">\r
-    <xsl:attribute name="Fill">\r
-      <xsl:choose>\r
-        <xsl:when test="$fill != ''">\r
-          <xsl:call-template name="template_color">\r
-            <xsl:with-param name="colorspec">\r
-              <xsl:if test="$fill != 'none'"><xsl:value-of select="$fill" /></xsl:if>\r
-            </xsl:with-param>\r
-            <xsl:with-param name="opacityspec"><xsl:value-of select="$fill_opacity" /></xsl:with-param>\r
-          </xsl:call-template>\r
-        </xsl:when>\r
-        <xsl:otherwise>#000000</xsl:otherwise>\r
-      </xsl:choose>\r
-    </xsl:attribute>\r
-  </xsl:if>\r
-</xsl:template>\r
-\r
-<!-- Stroke -->\r
-<xsl:template mode="stroke" match="*">\r
-  <xsl:choose>\r
-    <xsl:when test="@stroke and starts-with(@stroke, 'url(#')"><xsl:value-of select="concat('{StaticResource ', substring-before(substring-after(@stroke, 'url(#'), ')'), '}')" /></xsl:when>\r
-    <xsl:when test="@stroke and @stroke != 'none'"><xsl:value-of select="@stroke" /></xsl:when>\r
-    <xsl:when test="@style and contains(@style, 'stroke:') and starts-with(substring-after(@style, 'stroke:'), 'url(#')"><xsl:value-of select="concat('{StaticResource ', substring-before(substring-after(@style, 'url(#'), ')'), '}')" /></xsl:when>\r
-    <xsl:when test="@style and contains(@style, 'stroke:')">\r
-      <xsl:variable name="Stroke" select="substring-after(@style, 'stroke:')" />\r
-      <xsl:choose>\r
-        <xsl:when test="contains($Stroke, ';')">\r
-          <xsl:if test="substring-before($Stroke, ';') != 'none'"><xsl:value-of select="substring-before($Stroke, ';')" /></xsl:if>\r
-        </xsl:when>\r
-        <xsl:when test="$Stroke != 'none'"><xsl:value-of select="$Stroke" /></xsl:when>\r
-      </xsl:choose>\r
-    </xsl:when>\r
-    <xsl:when test="name(..) = 'g' or name(..) = 'svg'"><xsl:apply-templates mode="stroke" select="parent::*"/></xsl:when>\r
-  </xsl:choose>\r
-</xsl:template>\r
-\r
-<!-- Stroke opacity -->\r
-<xsl:template mode="stroke_opacity" match="*">\r
-  <xsl:choose>\r
-    <xsl:when test="@stroke-opacity"><xsl:value-of select="@stroke-opacity" /></xsl:when>\r
-    <xsl:when test="@style and contains(@style, 'stroke-opacity:')">\r
-      <xsl:variable name="Opacity" select="substring-after(@style, 'stroke-opacity:')" />\r
-      <xsl:choose>\r
-        <xsl:when test="contains($Opacity, ';')"><xsl:value-of select="substring-before($Opacity, ';')" /></xsl:when>\r
-        <xsl:otherwise><xsl:value-of select="$Opacity" /></xsl:otherwise>\r
-      </xsl:choose>\r
-    </xsl:when>\r
-    <xsl:when test="name(..) = 'g' or name(..) = 'svg'"><xsl:apply-templates mode="stroke_opacity" select="parent::*" /></xsl:when>\r
-  </xsl:choose>\r
-</xsl:template>\r
-\r
-<!-- Generic stroke template -->\r
-<xsl:template mode="template_stroke" match="*">\r
-  <xsl:variable name="stroke"><xsl:apply-templates mode="stroke" select="." /></xsl:variable>\r
-  <xsl:variable name="stroke_opacity"><xsl:apply-templates mode="stroke_opacity" select="." /></xsl:variable>\r
-  <xsl:if test="$stroke != ''">\r
-    <xsl:attribute name="Stroke">\r
-      <xsl:call-template name="template_color">\r
-        <xsl:with-param name="colorspec"><xsl:value-of select="$stroke" /></xsl:with-param>\r
-        <xsl:with-param name="opacityspec"><xsl:value-of select="$stroke_opacity" /></xsl:with-param>\r
-      </xsl:call-template>\r
-    </xsl:attribute>\r
-  </xsl:if>\r
-</xsl:template>\r
-\r
-<!-- Stroke width -->\r
-<xsl:template mode="stroke_width" match="*">\r
-  <xsl:choose>\r
-    <xsl:when test="@stroke-width">\r
-        <xsl:attribute name="StrokeThickness"><xsl:value-of select="@stroke-width" /></xsl:attribute>\r
-    </xsl:when>\r
-    <xsl:when test="@style and contains(@style, 'stroke-width:')">\r
-      <xsl:attribute name="StrokeThickness">\r
-          <xsl:call-template name="convert_unit">\r
-            <xsl:with-param name="convert_value">\r
-            <xsl:choose>\r
-              <xsl:when test="contains(substring-after(@style, 'stroke-width:'), ';')"><xsl:value-of select="substring-before(substring-after(@style, 'stroke-width:'), ';')" /></xsl:when>\r
-              <xsl:otherwise><xsl:value-of select="substring-after(@style, 'stroke-width:')" /></xsl:otherwise>\r
-            </xsl:choose>\r
-            </xsl:with-param>\r
-        </xsl:call-template> \r
-      </xsl:attribute>\r
-    </xsl:when>\r
-    <xsl:when test="name(..) = 'g' or name(..) = 'svg'"><xsl:apply-templates mode="stroke_width" select="parent::*"/></xsl:when>\r
-  </xsl:choose>\r
-</xsl:template>\r
-\r
-<!-- Stroke miterlimit -->\r
-<xsl:template mode="stroke_miterlimit" match="*">\r
-  <xsl:choose>\r
-    <xsl:when test="@stroke-miterlimit"><xsl:attribute name="StrokeMiterLimit"><xsl:value-of select="@stroke-miterlimit" /></xsl:attribute></xsl:when>\r
-    <xsl:when test="@style and contains(@style, 'stroke-miterlimit:')">\r
-      <xsl:variable name="StrokeMiterLimit" select="substring-after(@style, 'stroke-miterlimit:')" />\r
-      <xsl:attribute name="StrokeMiterLimit">\r
-        <xsl:choose>\r
-          <xsl:when test="contains($StrokeMiterLimit, ';')"><xsl:value-of select="substring-before($StrokeMiterLimit, ';')" /></xsl:when>\r
-          <xsl:otherwise><xsl:value-of select="$StrokeMiterLimit" /></xsl:otherwise>\r
-        </xsl:choose>\r
-      </xsl:attribute>\r
-    </xsl:when>\r
-    <xsl:when test="name(..) = 'g' or name(..) = 'svg'"><xsl:apply-templates mode="stroke_miterlimit" select="parent::*"/></xsl:when>\r
-  </xsl:choose>\r
-</xsl:template>\r
-\r
-<!-- Stroke dasharray -->\r
-<xsl:template mode="stroke_dasharray" match="*">\r
-  <!-- stroke-dasharray="10,30,20,30" becomes StrokeDashArray="1 3 2 3" ?? -->\r
-  <xsl:choose>\r
-    <xsl:when test="@stroke-dasharray and @stroke-dasharray != 'none'"><xsl:attribute name="StrokeDashArray"><xsl:value-of select="@stroke-dasharray" /></xsl:attribute></xsl:when>\r
-    <xsl:when test="@style and contains(@style, 'stroke-dasharray:')">\r
-      <xsl:variable name="StrokeDashArray" select="substring-after(@style, 'stroke-dasharray:')" />\r
-      <xsl:choose>\r
-        <xsl:when test="contains($StrokeDashArray, ';')">\r
-          <xsl:if test="substring-before($StrokeDashArray, ';') != 'none'"><xsl:attribute name="StrokeDashArray"><xsl:value-of select="substring-before($StrokeDashArray, ';')" /></xsl:attribute></xsl:if>\r
-        </xsl:when>\r
-        <xsl:when test="$StrokeDashArray != 'none'"><xsl:attribute name="StrokeDashArray"><xsl:value-of select="$StrokeDashArray" /></xsl:attribute></xsl:when>\r
-      </xsl:choose>\r
-    </xsl:when>\r
-    <xsl:when test="name(..) = 'g' or name(..) = 'svg'"><xsl:apply-templates mode="stroke_dasharray" select="parent::*"/></xsl:when>\r
-  </xsl:choose>\r
-</xsl:template>\r
-\r
-<!-- Stroke dashoffset -->\r
-<xsl:template mode="stroke_dashoffset" match="*">\r
-  <xsl:choose>\r
-    <xsl:when test="@stroke-dashoffset"><xsl:attribute name="StrokeDashOffset"><xsl:value-of select="@stroke-dashoffset" /></xsl:attribute></xsl:when>\r
-    <xsl:when test="@style and contains(@style, 'stroke-dashoffset:')">\r
-      <xsl:variable name="StrokeDashOffset" select="substring-after(@style, 'stroke-dashoffset:')" />\r
-      <xsl:attribute name="StrokeDashOffset">\r
-        <xsl:choose>\r
-          <xsl:when test="contains($StrokeDashOffset, ';')"><xsl:value-of select="substring-before($StrokeDashOffset, ';')" /></xsl:when>\r
-          <xsl:otherwise><xsl:value-of select="$StrokeDashOffset" /></xsl:otherwise>\r
-        </xsl:choose>\r
-      </xsl:attribute>\r
-    </xsl:when>\r
-    <xsl:when test="name(..) = 'g' or name(..) = 'svg'"><xsl:apply-templates mode="stroke_dashoffset" select="parent::*"/></xsl:when>\r
-  </xsl:choose>\r
-</xsl:template>\r
-\r
-<!-- Linejoin SVG to XAML converter -->\r
-<xsl:template name="linejoin_svg_to_xaml">\r
-  <xsl:param name="linejoin" />\r
-  <xsl:choose>\r
-    <xsl:when test="$linejoin = 'bevel'">Bevel</xsl:when>\r
-    <xsl:when test="$linejoin = 'round'">Round</xsl:when>\r
-    <xsl:otherwise>Miter</xsl:otherwise>\r
-  </xsl:choose>\r
-</xsl:template>\r
-\r
-<!-- Stroke linejoin -->\r
-<xsl:template mode="stroke_linejoin" match="*">\r
-  <xsl:choose>\r
-    <xsl:when test="@stroke-miterlimit">\r
-      <xsl:attribute name="StrokeLineJoin">\r
-        <xsl:call-template name="linejoin_svg_to_xaml"><xsl:with-param name="linejoin"><xsl:value-of select="@stroke-linejoin" /></xsl:with-param></xsl:call-template>\r
-      </xsl:attribute></xsl:when>\r
-    <xsl:when test="@style and contains(@style, 'stroke-linejoin:')">\r
-      <xsl:variable name="StrokeLineJoin" select="substring-after(@style, 'stroke-linejoin:')" />\r
-      <xsl:attribute name="StrokeLineJoin">\r
-        <xsl:choose>\r
-          <xsl:when test="contains($StrokeLineJoin, ';')">\r
-            <xsl:call-template name="linejoin_svg_to_xaml"><xsl:with-param name="linejoin"><xsl:value-of select="substring-before($StrokeLineJoin, ';')" /></xsl:with-param></xsl:call-template>\r
-          </xsl:when>\r
-          <xsl:otherwise>\r
-            <xsl:call-template name="linejoin_svg_to_xaml"><xsl:with-param name="linejoin"><xsl:value-of select="$StrokeLineJoin" /></xsl:with-param></xsl:call-template>\r
-          </xsl:otherwise>\r
-        </xsl:choose>\r
-      </xsl:attribute>\r
-    </xsl:when>\r
-    <xsl:when test="name(..) = 'g' or name(..) = 'svg'"><xsl:apply-templates mode="stroke_linejoin" select="parent::*"/></xsl:when>\r
-  </xsl:choose>\r
-</xsl:template>\r
-\r
-<!-- Linecap SVG to XAML converter -->\r
-<xsl:template name="linecap_svg_to_xaml">\r
-  <xsl:param name="linecap" />\r
-  <xsl:choose>\r
-    <xsl:when test="$linecap = 'round'">Round</xsl:when>\r
-    <xsl:when test="$linecap = 'square'">Square</xsl:when>\r
-    <xsl:otherwise>Flat</xsl:otherwise>\r
-  </xsl:choose>\r
-</xsl:template>\r
-\r
-<!-- Stroke linecap -->\r
-<xsl:template mode="stroke_linecap" match="*">\r
-  <xsl:choose>\r
-    <xsl:when test="@stroke-linecap">\r
-      <xsl:attribute name="StrokeStartLineCap">\r
-        <xsl:call-template name="linecap_svg_to_xaml"><xsl:with-param name="linecap"><xsl:value-of select="@stroke-linecap" /></xsl:with-param></xsl:call-template>\r
-      </xsl:attribute>\r
-      <xsl:attribute name="StrokeEndLineCap">\r
-        <xsl:call-template name="linecap_svg_to_xaml"><xsl:with-param name="linecap"><xsl:value-of select="@stroke-linecap" /></xsl:with-param></xsl:call-template>\r
-      </xsl:attribute></xsl:when>\r
-    <xsl:when test="@style and contains(@style, 'stroke-linecap:')">\r
-      <xsl:variable name="StrokeStartLineCap" select="substring-after(@style, 'stroke-linecap:')" />\r
-      <xsl:variable name="StrokeEndLineCap" select="substring-after(@style, 'stroke-linecap:')" />\r
-      <xsl:attribute name="StrokeStartLineCap">\r
-        <xsl:choose>\r
-          <xsl:when test="contains($StrokeStartLineCap, ';')">\r
-            <xsl:call-template name="linecap_svg_to_xaml"><xsl:with-param name="linecap"><xsl:value-of select="substring-before($StrokeStartLineCap, ';')" /></xsl:with-param></xsl:call-template>\r
-          </xsl:when>\r
-          <xsl:otherwise>\r
-            <xsl:call-template name="linecap_svg_to_xaml"><xsl:with-param name="linecap"><xsl:value-of select="$StrokeStartLineCap" /></xsl:with-param></xsl:call-template>\r
-          </xsl:otherwise>\r
-        </xsl:choose>\r
-      </xsl:attribute>\r
-      <xsl:attribute name="StrokeEndLineCap">\r
-        <xsl:choose>\r
-          <xsl:when test="contains($StrokeEndLineCap, ';')">\r
-            <xsl:call-template name="linecap_svg_to_xaml"><xsl:with-param name="linecap"><xsl:value-of select="substring-before($StrokeEndLineCap, ';')" /></xsl:with-param></xsl:call-template>\r
-          </xsl:when>\r
-          <xsl:otherwise>\r
-            <xsl:call-template name="linecap_svg_to_xaml"><xsl:with-param name="linecap"><xsl:value-of select="$StrokeEndLineCap" /></xsl:with-param></xsl:call-template>\r
-          </xsl:otherwise>\r
-        </xsl:choose>\r
-      </xsl:attribute>\r
-    </xsl:when>\r
-    <xsl:when test="name(..) = 'g' or name(..) = 'svg'"><xsl:apply-templates mode="stroke_linecap" select="parent::*"/></xsl:when>\r
-  </xsl:choose>\r
-</xsl:template>\r
-\r
-<!-- Gradient stops -->\r
-<xsl:template mode="stop_color" match="*">\r
-  <xsl:variable name="Opacity">\r
-    <xsl:choose>\r
-      <xsl:when test="@stop-opacity"><xsl:value-of select="@stop-opacity" /></xsl:when>\r
-      <xsl:when test="@style and contains(@style, 'stop-opacity:')">\r
-        <xsl:variable name="temp_opacity" select="substring-after(@style, 'stop-opacity:')" />\r
-        <xsl:choose>\r
-          <xsl:when test="contains($temp_opacity, ';')"><xsl:value-of select="substring-before($temp_opacity, ';')" /></xsl:when>\r
-          <xsl:otherwise><xsl:value-of select="$temp_opacity" /></xsl:otherwise>\r
-        </xsl:choose>\r
-      </xsl:when>\r
-      <xsl:otherwise><xsl:value-of select="''" /></xsl:otherwise>\r
-    </xsl:choose>\r
-  </xsl:variable>\r
-  <xsl:variable name="hex_opacity">\r
-    <xsl:choose>\r
-      <xsl:when test="$Opacity != ''"><xsl:call-template name="to_hex"><xsl:with-param name="convert"><xsl:value-of select="number($Opacity) * 255" /></xsl:with-param></xsl:call-template>  </xsl:when>\r
-      <xsl:otherwise><xsl:value-of select="$Opacity" /></xsl:otherwise>\r
-    </xsl:choose>\r
-  </xsl:variable>\r
-  <xsl:variable name="stopcolor">\r
-    <xsl:choose>\r
-      <xsl:when test="@stop-color">\r
-        <xsl:call-template name="template_color"><xsl:with-param name="colorspec"><xsl:value-of select="@stop-color" /></xsl:with-param></xsl:call-template>\r
-      </xsl:when>\r
-      <xsl:when test="@style and contains(@style, 'stop-color:')">\r
-        <xsl:variable name="Color" select="substring-after(@style, 'stop-color:')" />\r
-        <xsl:choose>\r
-          <xsl:when test="contains($Color, ';')">\r
-            <xsl:call-template name="template_color"><xsl:with-param name="colorspec"><xsl:value-of select="substring-before($Color, ';')" /></xsl:with-param></xsl:call-template>\r
-          </xsl:when>\r
-          <xsl:otherwise>\r
-            <xsl:call-template name="template_color"><xsl:with-param name="colorspec"><xsl:value-of select="$Color" /></xsl:with-param></xsl:call-template>\r
-          </xsl:otherwise>\r
-        </xsl:choose>\r
-      </xsl:when>\r
-      <xsl:when test="name(..) = 'g' or name(..) = 'svg'"><xsl:apply-templates mode="stop_color" select="parent::*"/></xsl:when>\r
-      <xsl:otherwise>#000</xsl:otherwise>\r
-    </xsl:choose>\r
-  </xsl:variable>\r
-  <xsl:attribute name="Color">\r
-    <xsl:choose>\r
-      <xsl:when test="$hex_opacity != '' and starts-with($stopcolor, '#')"><xsl:value-of select="concat('#', $hex_opacity, substring-after($stopcolor, '#'))" /></xsl:when>\r
-      <xsl:otherwise><xsl:value-of select="$stopcolor" /></xsl:otherwise>\r
-    </xsl:choose>\r
-  </xsl:attribute>\r
-</xsl:template>\r
-\r
-<!-- Gradient stop opacity -->\r
-<xsl:template mode="stop_opacity" match="*">\r
-  <xsl:choose>\r
-    <xsl:when test="@stop-opacity"><xsl:attribute name="Opacity"><xsl:value-of select="@stop-opacity" /></xsl:attribute></xsl:when>\r
-    <xsl:when test="@style and contains(@style, 'stop-opacity:')">\r
-      <xsl:variable name="Opacity" select="substring-after(@style, 'stop-opacity:')" />\r
-      <xsl:attribute name="Opacity">\r
-        <xsl:choose>\r
-          <xsl:when test="contains($Opacity, ';')"><xsl:value-of select="substring-before($Opacity, ';')" /></xsl:when>\r
-          <xsl:otherwise><xsl:value-of select="$Opacity" /></xsl:otherwise>\r
-        </xsl:choose>\r
-      </xsl:attribute>\r
-    </xsl:when>\r
-    <xsl:when test="name(..) = 'g' or name(..) = 'svg'"><xsl:apply-templates mode="stop_opacity" select="parent::*"/></xsl:when>\r
-  </xsl:choose>\r
-</xsl:template>\r
-\r
-<!-- Gradient stop offset -->\r
-<xsl:template mode="offset" match="*">\r
-  <xsl:choose>\r
-    <xsl:when test="@offset">\r
-      <xsl:attribute name="Offset">\r
-        <xsl:choose>\r
-          <xsl:when test="contains(@offset, '%')"><xsl:value-of select="number(substring-before(@offset, '%')) div 100" /></xsl:when>\r
-          <xsl:otherwise><xsl:value-of select="@offset" /></xsl:otherwise>\r
-        </xsl:choose>\r
-      </xsl:attribute>\r
-    </xsl:when>\r
-    <xsl:when test="@style and contains(@style, 'offset:')">\r
-      <xsl:variable name="Offset" select="substring-after(@style, 'offset:')" />\r
-      <xsl:attribute name="Offset">\r
-        <xsl:choose>\r
-          <xsl:when test="contains($Offset, '%')"><xsl:value-of select="number(substring-before($Offset, '%')) div 100" /></xsl:when>        \r
-          <xsl:when test="contains($Offset, ';')"><xsl:value-of select="substring-before($Offset, ';')" /></xsl:when>\r
-          <xsl:otherwise><xsl:value-of select="$Offset" /></xsl:otherwise>\r
-        </xsl:choose>\r
-      </xsl:attribute>\r
-    </xsl:when>\r
-    <xsl:when test="name(..) = 'g' or name(..) = 'svg'"><xsl:apply-templates mode="stop_offset" select="parent::*"/></xsl:when>\r
-  </xsl:choose>\r
-</xsl:template>\r
-\r
-<!-- \r
-// Transforms //\r
-All the matrix, translate, rotate... stuff.\r
-Fixme: XAML transforms don't show the same result as SVG ones with the same values.\r
-\r
-* Parse transform\r
-* Apply transform\r
-* Apply transform v2\r
--->\r
-\r
-<!-- Parse transform -->\r
-<xsl:template name="parse_transform">\r
-  <xsl:param name="input" />\r
-  <xsl:choose>\r
-    <xsl:when test="starts-with($input, 'matrix(')">\r
-      <MatrixTransform><xsl:attribute name="Matrix"><xsl:value-of select="substring-before(substring-after($input, 'matrix('), ')')" /></xsl:attribute></MatrixTransform>\r
-      <xsl:call-template name="parse_transform"><xsl:with-param name="input" select="substring-after($input, ') ')" /></xsl:call-template>      \r
-    </xsl:when>\r
-    <xsl:when test="starts-with($input, 'scale(')">\r
-      <ScaleTransform>\r
-        <xsl:variable name="scale" select="substring-before(substring-after($input, 'scale('), ')')" />\r
-        <xsl:choose>\r
-          <xsl:when test="contains($scale, ',')">\r
-            <xsl:attribute name="ScaleX"><xsl:value-of select="substring-before($scale, ',')" /></xsl:attribute>\r
-            <xsl:attribute name="ScaleY"><xsl:value-of select="substring-after($scale, ',')" /></xsl:attribute>\r
-          </xsl:when>\r
-          <xsl:otherwise>\r
-            <xsl:attribute name="ScaleX"><xsl:value-of select="$scale" /></xsl:attribute>\r
-            <xsl:attribute name="ScaleY"><xsl:value-of select="$scale" /></xsl:attribute>\r
-          </xsl:otherwise>\r
-        </xsl:choose>\r
-      </ScaleTransform>\r
-      <xsl:call-template name="parse_transform"><xsl:with-param name="input" select="substring-after($input, ') ')" /></xsl:call-template>\r
-    </xsl:when>\r
-    <xsl:when test="starts-with($input, 'rotate(')">\r
-      <RotateTransform>\r
-        <xsl:attribute name="Angle"><xsl:value-of select="substring-before(substring-after($input, 'rotate('), ')')" /></xsl:attribute>\r
-        <xsl:if test="@rx"><xsl:attribute name="CenterX"><xsl:value-of select="@rx" /></xsl:attribute></xsl:if>\r
-        <xsl:if test="@ry"><xsl:attribute name="CenterY"><xsl:value-of select="@ry" /></xsl:attribute></xsl:if>\r
-      </RotateTransform>\r
-      <xsl:call-template name="parse_transform"><xsl:with-param name="input" select="substring-after($input, ') ')" /></xsl:call-template>\r
-    </xsl:when>\r
-    <xsl:when test="starts-with($input, 'skewX(')">\r
-      <SkewTransform>\r
-        <xsl:attribute name="AngleX"><xsl:value-of select="substring-before(substring-after($input, 'skewX('), ')')" /></xsl:attribute>\r
-        <xsl:call-template name="parse_transform"><xsl:with-param name="input" select="substring-after($input, ') ')" /></xsl:call-template>\r
-      </SkewTransform>\r
-    </xsl:when>\r
-    <xsl:when test="starts-with($input, 'skewY(')">\r
-      <SkewTransform>\r
-        <xsl:attribute name="AngleY"><xsl:value-of select="substring-before(substring-after($input, 'skewY('), ')')" /></xsl:attribute>\r
-        <xsl:call-template name="parse_transform"><xsl:with-param name="input" select="substring-after($input, ') ')" /></xsl:call-template>\r
-      </SkewTransform>\r
-    </xsl:when>\r
-    <xsl:when test="starts-with($input, 'translate(')">\r
-      <TranslateTransform>\r
-        <xsl:variable name="translate" select="substring-before(substring-after($input, 'translate('), ')')" />\r
-        <xsl:choose>\r
-          <xsl:when test="contains($translate, ',')">\r
-            <xsl:attribute name="X"><xsl:value-of select="substring-before($translate, ',')" /></xsl:attribute>\r
-            <xsl:attribute name="Y"><xsl:value-of select="substring-after($translate, ',')" /></xsl:attribute>\r
-          </xsl:when>\r
-          <xsl:when test="contains($translate, ' ')">\r
-            <xsl:attribute name="X"><xsl:value-of select="substring-before($translate, ' ')" /></xsl:attribute>\r
-            <xsl:attribute name="Y"><xsl:value-of select="substring-after($translate, ' ')" /></xsl:attribute>\r
-          </xsl:when>\r
-          <xsl:otherwise><xsl:attribute name="X"><xsl:value-of select="$translate" /></xsl:attribute></xsl:otherwise>\r
-        </xsl:choose>\r
-      </TranslateTransform>\r
-      <xsl:call-template name="parse_transform"><xsl:with-param name="input" select="substring-after($input, ') ')" /></xsl:call-template>\r
-    </xsl:when>\r
-  </xsl:choose>\r
-</xsl:template>\r
-\r
-<!-- Apply transform -->\r
-<xsl:template mode="transform" match="*">\r
-  <xsl:param name="mapped_type" />\r
-  <xsl:if test="@transform or @gradientTransform">\r
-  <xsl:variable name="transform">\r
-    <xsl:choose>\r
-       <xsl:when test="@transform"><xsl:value-of select="@transform" /></xsl:when>\r
-       <xsl:otherwise><xsl:value-of select="@gradientTransform" /></xsl:otherwise>\r
-    </xsl:choose>\r
-  </xsl:variable>\r
-  <xsl:variable name="transform_nodes">\r
-    <xsl:call-template name="parse_transform">\r
-      <xsl:with-param name="input" select="$transform" />\r
-    </xsl:call-template>\r
-  </xsl:variable>\r
-\r
-  <xsl:comment>\r
-    <xsl:value-of select="name(.)" />\r
-  </xsl:comment>\r
-\r
-  <xsl:choose>\r
-    <xsl:when test="$mapped_type and $mapped_type != ''">\r
-      <xsl:element name="{$mapped_type}.RenderTransform">\r
-        <xsl:choose>\r
-          <xsl:when test="count(libxslt:node-set($transform_nodes)/*) = 1"><xsl:copy-of select="libxslt:node-set($transform_nodes)" /></xsl:when>\r
-          <xsl:when test="count(libxslt:node-set($transform_nodes)/*) &gt; 1"><TransformGroup><xsl:copy-of select="libxslt:node-set($transform_nodes)" /></TransformGroup></xsl:when>\r
-        </xsl:choose>\r
-      </xsl:element>\r
-    </xsl:when>\r
-    <xsl:otherwise>\r
-      <!-- For instance LinearGradient.Transform -->\r
-      <xsl:choose>\r
-          <xsl:when test="count(libxslt:node-set($transform_nodes)/*) = 1"><xsl:copy-of select="libxslt:node-set($transform_nodes)" /></xsl:when>\r
-          <xsl:when test="count(libxslt:node-set($transform_nodes)/*) &gt; 1"><TransformGroup><xsl:copy-of select="libxslt:node-set($transform_nodes)" /></TransformGroup></xsl:when>\r
-      </xsl:choose>\r
-    </xsl:otherwise>\r
-  </xsl:choose>\r
-  </xsl:if>  \r
-</xsl:template>\r
-\r
-<!-- Apply transform v2\r
-Fixme: is this template still in use? -->\r
-<xsl:template mode="transform2" match="*">\r
-  <xsl:choose>\r
-    <xsl:when test="@transform">\r
-      <Canvas>\r
-        <Canvas.RenderTransform>\r
-          <TransformGroup><xsl:apply-templates mode="transform" select="." /></TransformGroup>\r
-        </Canvas.RenderTransform>\r
-        <xsl:apply-templates mode="forward" select="." />\r
-      </Canvas>\r
-    </xsl:when>\r
-    <xsl:otherwise>\r
-      <xsl:apply-templates mode="forward" select="." />\r
-    </xsl:otherwise>\r
-  </xsl:choose>\r
-</xsl:template>\r
-\r
-<!-- \r
-// Objects //\r
-\r
-* Image\r
-* Text\r
-* Lines\r
-* Rectangle\r
-* Polygon\r
-* Polyline\r
-* Path\r
-* Ellipse\r
-* Circle\r
--->\r
-\r
-<!-- Image -->\r
-<xsl:template mode="forward" match="*[name(.) = 'image']">\r
-  <Image>\r
-    <xsl:apply-templates mode="id" select="." />\r
-    <xsl:if test="@x"><xsl:attribute name="Canvas.Left">\r
-       <xsl:call-template name="convert_unit">\r
-            <xsl:with-param name="convert_value" select="@x" />\r
-        </xsl:call-template>\r
-    </xsl:attribute></xsl:if>\r
-    <xsl:if test="@y"><xsl:attribute name="Canvas.Top">\r
-       <xsl:call-template name="convert_unit">\r
-           <xsl:with-param name="convert_value" select="@y" />\r
-       </xsl:call-template>\r
-    </xsl:attribute></xsl:if>\r
-    <xsl:apply-templates mode="desc" select="." />\r
-    <xsl:apply-templates mode="clip" select="." />\r
-    <xsl:if test="@xlink:href"><xsl:attribute name="Source"><xsl:value-of select="@xlink:href" /></xsl:attribute></xsl:if>\r
-    <xsl:if test="@width"><xsl:attribute name="Width">\r
-        <xsl:call-template name="convert_unit">\r
-            <xsl:with-param name="convert_value" select="@width" />\r
-        </xsl:call-template>\r
-    </xsl:attribute></xsl:if>\r
-    <xsl:if test="@height"><xsl:attribute name="Height">\r
-        <xsl:call-template name="convert_unit">\r
-            <xsl:with-param name="convert_value" select="@height" />\r
-        </xsl:call-template>\r
-    </xsl:attribute></xsl:if>\r
-    <xsl:apply-templates mode="transform" select=".">\r
-      <xsl:with-param name="mapped_type" select="'Image'" />\r
-    </xsl:apply-templates>\r
-    <!--xsl:apply-templates mode="transform" /-->\r
-    <xsl:apply-templates mode="forward" />\r
-  </Image>\r
-</xsl:template>\r
-\r
-<!-- Text -->\r
-<xsl:template mode="forward" match="*[name(.) = 'text']">\r
-  <TextBlock>\r
-    <xsl:if test="@font-size"><xsl:attribute name="FontSize"><xsl:value-of select="@font-size" /></xsl:attribute></xsl:if>\r
-    <xsl:if test="@style and contains(@style, 'font-size:')">\r
-      <xsl:variable name="font_size" select="substring-after(@style, 'font-size:')" />\r
-      <xsl:attribute name="FontSize">\r
-        <xsl:choose>\r
-          <xsl:when test="contains($font_size, ';')">\r
-            <xsl:value-of select="substring-before($font_size, ';')" />\r
-          </xsl:when>\r
-          <xsl:otherwise><xsl:value-of select="$font_size" /></xsl:otherwise>\r
-        </xsl:choose>\r
-      </xsl:attribute>\r
-    </xsl:if>\r
-    <xsl:if test="@font-weight"><xsl:attribute name="FontWeight"><xsl:value-of select="@font-weight" /></xsl:attribute></xsl:if>\r
-    <xsl:if test="@style and contains(@style, 'font-weight:')">\r
-      <xsl:variable name="font_weight" select="substring-after(@style, 'font-weight:')" />\r
-      <xsl:attribute name="FontWeight">\r
-        <xsl:choose>\r
-          <xsl:when test="contains($font_weight, ';')">\r
-            <xsl:value-of select="substring-before($font_weight, ';')" />\r
-          </xsl:when>\r
-          <xsl:otherwise><xsl:value-of select="$font_weight" /></xsl:otherwise>\r
-        </xsl:choose>\r
-      </xsl:attribute>\r
-    </xsl:if>\r
-    <xsl:if test="@font-family"><xsl:attribute name="FontFamily"><xsl:value-of select="@font-family" /></xsl:attribute></xsl:if>\r
-    <xsl:if test="@style and contains(@style, 'font-family:')">\r
-      <xsl:variable name="font_family" select="substring-after(@style, 'font-family:')" />\r
-      <xsl:attribute name="FontFamily">\r
-        <xsl:choose>\r
-          <xsl:when test="contains($font_family, ';')">\r
-            <xsl:value-of select="substring-before($font_family, ';')" />\r
-          </xsl:when>\r
-          <xsl:otherwise><xsl:value-of select="$font_family" /></xsl:otherwise>\r
-        </xsl:choose>\r
-      </xsl:attribute>\r
-    </xsl:if>\r
-    <xsl:if test="@font-style"><xsl:attribute name="FontStyle"><xsl:value-of select="@font-style" /></xsl:attribute></xsl:if>\r
-    <xsl:if test="@style and contains(@style, 'font-style:')">\r
-      <xsl:variable name="font_style" select="substring-after(@style, 'font-style:')" />\r
-      <xsl:attribute name="FontStyle">\r
-        <xsl:choose>\r
-          <xsl:when test="contains($font_style, ';')">\r
-            <xsl:value-of select="substring-before($font_style, ';')" />\r
-          </xsl:when>\r
-          <xsl:otherwise><xsl:value-of select="$font_style" /></xsl:otherwise>\r
-        </xsl:choose>\r
-      </xsl:attribute>\r
-    </xsl:if>\r
-    <xsl:if test="@fill"><xsl:attribute name="Foreground"><xsl:value-of select="@fill" /></xsl:attribute></xsl:if>\r
-    <xsl:if test="@style and contains(@style, 'fill')">\r
-      <xsl:variable name="fill" select="substring-after(@style, 'fill:')" />\r
-      <xsl:attribute name="Foreground">\r
-        <xsl:choose>\r
-          <xsl:when test="contains($fill, ';')">\r
-            <xsl:value-of select="substring-before($fill, ';')" />\r
-          </xsl:when>\r
-          <xsl:otherwise><xsl:value-of select="$fill" /></xsl:otherwise>\r
-        </xsl:choose>\r
-      </xsl:attribute>\r
-    </xsl:if>\r
-    <xsl:if test="@text-anchor">\r
-      <xsl:attribute name="HorizontalAlignment">\r
-        <xsl:choose>\r
-          <xsl:when test="@text-anchor = 'start'">Left</xsl:when>\r
-          <xsl:when test="@text-anchor = 'middle'">Center</xsl:when>\r
-          <xsl:when test="@text-anchor = 'end'">Right</xsl:when>\r
-        </xsl:choose>\r
-      </xsl:attribute>\r
-    </xsl:if>\r
-    <xsl:if test="@width"><xsl:attribute name="Width">\r
-        <xsl:call-template name="convert_unit">\r
-            <xsl:with-param name="convert_value" select="@width" />\r
-        </xsl:call-template>\r
-    </xsl:attribute></xsl:if>\r
-    <xsl:if test="@height"><xsl:attribute name="Height">\r
-        <xsl:call-template name="convert_unit">\r
-            <xsl:with-param name="convert_value" select="@height" />\r
-        </xsl:call-template>\r
-    </xsl:attribute></xsl:if>\r
-    <xsl:if test="@x"><xsl:attribute name="Canvas.Left">\r
-       <xsl:call-template name="convert_unit">\r
-            <xsl:with-param name="convert_value" select="@x" />\r
-        </xsl:call-template>\r
-    </xsl:attribute></xsl:if>\r
-    <xsl:if test="@y"><xsl:attribute name="Canvas.Top">\r
-       <xsl:call-template name="convert_unit">\r
-           <xsl:with-param name="convert_value" select="@y" />\r
-       </xsl:call-template>\r
-    </xsl:attribute></xsl:if>\r
-    <xsl:apply-templates mode="id" select="." />\r
-    <xsl:apply-templates mode="filter_effect" select="." />\r
-    <xsl:apply-templates mode="desc" select="." />\r
-    <xsl:apply-templates mode="clip" select="." />\r
-    <!--xsl:apply-templates mode="transform" select="." /-->\r
-    <!--xsl:apply-templates mode="forward" /-->\r
-    <xsl:if test="text()"><xsl:value-of select="text()" /></xsl:if>\r
-    <xsl:if test="*[name(.) = 'tspan']/text()"><xsl:value-of select="*[name(.) = 'tspan']/text()" /></xsl:if>\r
-  </TextBlock>\r
-</xsl:template>\r
\r
-<!-- Lines -->\r
-<xsl:template mode="forward" match="*[name(.) = 'line']">\r
-  <Line>\r
-    <xsl:if test="@x1"><xsl:attribute name="X1"><xsl:value-of select="@x1" /></xsl:attribute></xsl:if> \r
-    <xsl:if test="@y1"><xsl:attribute name="Y1"><xsl:value-of select="@y1" /></xsl:attribute></xsl:if> \r
-    <xsl:if test="@x2"><xsl:attribute name="X2"><xsl:value-of select="@x2" /></xsl:attribute></xsl:if> \r
-    <xsl:if test="@y2"><xsl:attribute name="Y2"><xsl:value-of select="@y2" /></xsl:attribute></xsl:if>\r
-    <xsl:apply-templates mode="id" select="." />\r
-    <xsl:apply-templates mode="template_fill" select="." />\r
-    <xsl:apply-templates mode="template_stroke" select="." />\r
-    <xsl:apply-templates mode="stroke_width" select="." />\r
-    <xsl:apply-templates mode="stroke_miterlimit" select="." />\r
-    <xsl:apply-templates mode="stroke_dasharray" select="." />\r
-    <xsl:apply-templates mode="stroke_dashoffset" select="." />\r
-    <xsl:apply-templates mode="stroke_linejoin" select="." />\r
-    <xsl:apply-templates mode="stroke_linecap" select="." />\r
-    <xsl:apply-templates mode="filter_effect" select="." />\r
-    <xsl:apply-templates mode="desc" select="." />\r
-\r
-    <xsl:apply-templates mode="transform" select=".">\r
-      <xsl:with-param name="mapped_type" select="'Line'" />\r
-    </xsl:apply-templates>    \r
-\r
-    <xsl:apply-templates mode="forward" />\r
-  </Line>\r
-</xsl:template>\r
-\r
-<!-- Rectangle -->\r
-<xsl:template mode="forward" match="*[name(.) = 'rect']">\r
-  <Rectangle>\r
-    <xsl:if test="@x"><xsl:attribute name="Canvas.Left">\r
-       <xsl:call-template name="convert_unit">\r
-            <xsl:with-param name="convert_value" select="@x" />\r
-        </xsl:call-template>\r
-    </xsl:attribute></xsl:if>\r
-    <xsl:if test="@y"><xsl:attribute name="Canvas.Top">\r
-       <xsl:call-template name="convert_unit">\r
-           <xsl:with-param name="convert_value" select="@y" />\r
-       </xsl:call-template>\r
-    </xsl:attribute></xsl:if>\r
-    <xsl:if test="@width"><xsl:attribute name="Width">\r
-        <xsl:call-template name="convert_unit">\r
-            <xsl:with-param name="convert_value" select="@width" />\r
-        </xsl:call-template>\r
-    </xsl:attribute></xsl:if>\r
-    <xsl:if test="@height"><xsl:attribute name="Height">\r
-        <xsl:call-template name="convert_unit">\r
-            <xsl:with-param name="convert_value" select="@height" />\r
-        </xsl:call-template>\r
-    </xsl:attribute></xsl:if>\r
-    <xsl:if test="@rx"><xsl:attribute name="RadiusX"><xsl:value-of select="@rx" /></xsl:attribute></xsl:if>\r
-    <xsl:if test="@ry"><xsl:attribute name="RadiusY"><xsl:value-of select="@ry" /></xsl:attribute></xsl:if>\r
-    <xsl:if test="@rx and not(@ry)"><xsl:attribute name="RadiusX"><xsl:value-of select="@rx" /></xsl:attribute><xsl:attribute name="RadiusY"><xsl:value-of select="@rx" /></xsl:attribute></xsl:if>\r
-    <xsl:if test="@ry and not(@rx)"><xsl:attribute name="RadiusX"><xsl:value-of select="@ry" /></xsl:attribute><xsl:attribute name="RadiusY"><xsl:value-of select="@ry" /></xsl:attribute></xsl:if>\r
-\r
-    <xsl:apply-templates mode="id" select="." />\r
-    <xsl:apply-templates mode="template_fill" select="." />\r
-    <xsl:apply-templates mode="template_stroke" select="." />\r
-    <xsl:apply-templates mode="stroke_width" select="." />\r
-    <xsl:apply-templates mode="stroke_miterlimit" select="." />\r
-    <xsl:apply-templates mode="stroke_dasharray" select="." />\r
-    <xsl:apply-templates mode="stroke_dashoffset" select="." />\r
-    <xsl:apply-templates mode="stroke_linejoin" select="." />\r
-    <xsl:apply-templates mode="stroke_linecap" select="." />\r
-    <xsl:apply-templates mode="filter_effect" select="." />\r
-    <xsl:apply-templates mode="resources" select="." />\r
-    <xsl:apply-templates mode="desc" select="." />\r
-    <xsl:apply-templates mode="clip" select="." />\r
-\r
-    <xsl:apply-templates mode="transform" select=".">\r
-      <xsl:with-param name="mapped_type" select="'Rectangle'" />\r
-    </xsl:apply-templates>\r
-\r
-    <xsl:apply-templates mode="forward" />\r
-  </Rectangle>\r
-</xsl:template>\r
-\r
-<!-- Polygon -->\r
-<xsl:template mode="forward" match="*[name(.) = 'polygon']">\r
-  <Polygon>\r
-    <xsl:if test="@points"><xsl:attribute name="Points"><xsl:value-of select="@points" /></xsl:attribute></xsl:if>\r
-    <xsl:apply-templates mode="id" select="." />\r
-    <xsl:apply-templates mode="fill_rule" select="." />\r
-    <xsl:apply-templates mode="template_fill" select="." />\r
-    <xsl:apply-templates mode="template_stroke" select="." />\r
-    <xsl:apply-templates mode="stroke_width" select="." />\r
-    <xsl:apply-templates mode="stroke_miterlimit" select="." />\r
-    <xsl:apply-templates mode="stroke_dasharray" select="." />\r
-    <xsl:apply-templates mode="stroke_dashoffset" select="." />\r
-    <xsl:apply-templates mode="stroke_linejoin" select="." />\r
-    <xsl:apply-templates mode="stroke_linecap" select="." />\r
-    <xsl:apply-templates mode="filter_effect" select="." />\r
-    <xsl:apply-templates mode="desc" select="." />\r
-\r
-    <xsl:apply-templates mode="transform" select=".">\r
-      <xsl:with-param name="mapped_type" select="'Polygon'" />\r
-    </xsl:apply-templates>\r
-\r
-    <xsl:apply-templates mode="forward" />\r
-  </Polygon>\r
-</xsl:template>\r
-\r
-<!-- Polyline -->\r
-<xsl:template mode="forward" match="*[name(.) = 'polyline']">\r
-  <Polyline>\r
-    <xsl:if test="@points"><xsl:attribute name="Points"><xsl:value-of select="@points" /></xsl:attribute></xsl:if>\r
-    <xsl:apply-templates mode="id" select="." />\r
-    <xsl:apply-templates mode="fill_rule" select="." />\r
-    <xsl:apply-templates mode="template_fill" select="." />\r
-    <xsl:apply-templates mode="template_stroke" select="." />\r
-    <xsl:apply-templates mode="stroke_width" select="." />\r
-    <xsl:apply-templates mode="stroke_miterlimit" select="." />\r
-    <xsl:apply-templates mode="stroke_dasharray" select="." />\r
-    <xsl:apply-templates mode="stroke_dashoffset" select="." />\r
-    <xsl:apply-templates mode="stroke_linejoin" select="." />\r
-    <xsl:apply-templates mode="stroke_linecap" select="." />\r
-    <xsl:apply-templates mode="filter_effect" select="." />\r
-    <xsl:apply-templates mode="desc" select="." />\r
-\r
-    <xsl:apply-templates mode="transform" select=".">\r
-      <xsl:with-param name="mapped_type" select="'Polyline'" />\r
-    </xsl:apply-templates>\r
-\r
-    <xsl:apply-templates mode="forward" />\r
-  </Polyline>\r
-</xsl:template>\r
-\r
-<!-- Path -->\r
-<xsl:template mode="forward" match="*[name(.) = 'path']">\r
-  <Path>\r
-    <xsl:apply-templates mode="id" select="." />\r
-    <xsl:apply-templates mode="template_fill" select="." />\r
-    <xsl:apply-templates mode="template_stroke" select="." />\r
-    <xsl:apply-templates mode="stroke_width" select="." />\r
-    <xsl:apply-templates mode="stroke_miterlimit" select="." />\r
-    <xsl:apply-templates mode="stroke_dasharray" select="." />\r
-    <xsl:apply-templates mode="stroke_dashoffset" select="." />\r
-    <xsl:apply-templates mode="stroke_linejoin" select="." />\r
-    <xsl:apply-templates mode="stroke_linecap" select="." />\r
-    <xsl:apply-templates mode="filter_effect" select="." />\r
-    <xsl:apply-templates mode="desc" select="." />\r
-\r
-    <xsl:if test="@d">\r
-      <xsl:choose>\r
-        <xsl:when test="$silverlight_compatible = 1">\r
-          <xsl:attribute name="Data">\r
-           <xsl:value-of select="translate(@d , ',', ' ')" />\r
-          </xsl:attribute>\r
-        </xsl:when>\r
-        <xsl:otherwise>\r
-          <Path.Data>\r
-            <PathGeometry>\r
-              <xsl:attribute name="Figures">\r
-                <xsl:value-of select="translate(@d , ',', ' ')" />\r
-              </xsl:attribute>\r
-              <xsl:apply-templates mode="fill_rule" select="." />\r
-            </PathGeometry>\r
-          </Path.Data>\r
-         </xsl:otherwise>\r
-      </xsl:choose>\r
-    </xsl:if>\r
-\r
-    <xsl:apply-templates mode="transform" select=".">\r
-      <xsl:with-param name="mapped_type" select="'Path'" />\r
-    </xsl:apply-templates>\r
-\r
-    <xsl:apply-templates mode="forward" />\r
-  </Path>\r
-</xsl:template>\r
-\r
-<!-- Ellipse -->\r
-<xsl:template mode="forward" match="*[name(.) = 'ellipse']">\r
-  <Ellipse>\r
-    <xsl:variable name="cx">\r
-      <xsl:choose>\r
-        <xsl:when test="@cx"><xsl:value-of select="@cx" /></xsl:when>\r
-        <xsl:otherwise>0</xsl:otherwise>\r
-      </xsl:choose>\r
-    </xsl:variable>\r
-    <xsl:variable name="cy">\r
-      <xsl:choose>\r
-        <xsl:when test="@cy"><xsl:value-of select="@cy" /></xsl:when>\r
-        <xsl:otherwise>0</xsl:otherwise>\r
-      </xsl:choose>\r
-    </xsl:variable>\r
-    <xsl:if test="@rx">\r
-      <xsl:attribute name="Canvas.Left"><xsl:value-of select='format-number($cx - @rx, "#.#")' /></xsl:attribute>\r
-      <xsl:attribute name="Width"><xsl:value-of select='format-number(2 * @rx, "#.#")' /></xsl:attribute>\r
-    </xsl:if>\r
-    <xsl:if test="@ry">\r
-      <xsl:attribute name="Canvas.Top"><xsl:value-of select='format-number($cy - @ry, "#.#")' /></xsl:attribute>\r
-      <xsl:attribute name="Height"><xsl:value-of select='format-number(2 * @ry, "#.#")' /></xsl:attribute>\r
-    </xsl:if>\r
-    <xsl:apply-templates mode="id" select="." />\r
-    <xsl:apply-templates mode="template_fill" select="." />\r
-    <xsl:apply-templates mode="template_stroke" select="." />\r
-    <xsl:apply-templates mode="stroke_width" select="." />\r
-    <xsl:apply-templates mode="stroke_miterlimit" select="." />\r
-    <xsl:apply-templates mode="stroke_dasharray" select="." />\r
-    <xsl:apply-templates mode="stroke_dashoffset" select="." />\r
-    <xsl:apply-templates mode="stroke_linejoin" select="." />\r
-    <xsl:apply-templates mode="stroke_linecap" select="." />\r
-    <xsl:apply-templates mode="filter_effect" select="." />\r
-    <xsl:apply-templates mode="desc" select="." />\r
-    <xsl:apply-templates mode="clip" select="." />\r
-\r
-    <xsl:apply-templates mode="transform" select=".">\r
-      <xsl:with-param name="mapped_type" select="'Ellipse'" />\r
-    </xsl:apply-templates>\r
-\r
-    <xsl:apply-templates mode="forward" />\r
-  </Ellipse>\r
-</xsl:template>\r
-\r
-<!-- Circle -->\r
-<xsl:template mode="forward" match="*[name(.) = 'circle']">\r
-  <Ellipse>\r
-    <xsl:variable name="cx">\r
-      <xsl:choose>\r
-        <xsl:when test="@cx"><xsl:value-of select="@cx" /></xsl:when>\r
-        <xsl:otherwise>0</xsl:otherwise>\r
-      </xsl:choose>\r
-    </xsl:variable>\r
-    <xsl:variable name="cy">\r
-      <xsl:choose>\r
-        <xsl:when test="@cy"><xsl:value-of select="@cy" /></xsl:when>\r
-        <xsl:otherwise>0</xsl:otherwise>\r
-      </xsl:choose>\r
-    </xsl:variable>\r
-    <xsl:if test="@r">\r
-       <xsl:attribute name="Canvas.Left"><xsl:value-of select='format-number($cx - @r, "#.#")' /></xsl:attribute>\r
-       <xsl:attribute name="Canvas.Top"><xsl:value-of select='format-number($cy - @r, "#.#")' /></xsl:attribute>\r
-       <xsl:attribute name="Width"><xsl:value-of select='format-number(2 * @r, "#.#")' /></xsl:attribute>\r
-       <xsl:attribute name="Height"><xsl:value-of select='format-number(2 * @r, "#.#")' /></xsl:attribute>\r
-    </xsl:if>\r
-    <xsl:apply-templates mode="id" select="." />\r
-    <xsl:apply-templates mode="template_fill" select="." />\r
-    <xsl:apply-templates mode="template_stroke" select="." />\r
-    <xsl:apply-templates mode="stroke_width" select="." />\r
-    <xsl:apply-templates mode="stroke_miterlimit" select="." />\r
-    <xsl:apply-templates mode="stroke_dasharray" select="." />\r
-    <xsl:apply-templates mode="stroke_dashoffset" select="." />\r
-    <xsl:apply-templates mode="stroke_linejoin" select="." />\r
-    <xsl:apply-templates mode="stroke_linecap" select="." />\r
-    <xsl:apply-templates mode="filter_effect" select="." />\r
-    <xsl:apply-templates mode="desc" select="." />\r
-    <xsl:apply-templates mode="clip" select="." />\r
-\r
-    <xsl:apply-templates mode="transform" select=".">\r
-      <xsl:with-param name="mapped_type" select="'Ellipse'" />\r
-    </xsl:apply-templates>\r
-\r
-    <xsl:apply-templates mode="forward" />\r
-  </Ellipse>\r
-</xsl:template>\r
-\r
-<!--\r
-// Geometry //\r
-* Generic clip path template\r
-* Geometry for circle\r
-* Geometry for rectangle\r
--->\r
-\r
-<!-- Generic clip path template -->\r
-<xsl:template mode="forward" match="*[name(.) = 'clipPath']">\r
-  <xsl:apply-templates mode="geometry" />\r
-</xsl:template>\r
-\r
-<!-- Geometry for circle -->\r
-<xsl:template mode="geometry" match="*[name(.) = 'circle']">\r
-  <EllipseGeometry>\r
-    <xsl:if test="../@id"><xsl:attribute name="x:Key"><xsl:value-of select="../@id" /></xsl:attribute></xsl:if>\r
-    <xsl:if test="@cx and @cy"><xsl:attribute name="Center"><xsl:value-of select="concat(@cx, ',', @cy)" /></xsl:attribute></xsl:if>\r
-    <xsl:if test="@r">\r
-      <xsl:attribute name="RadiusX"><xsl:value-of select="@r" /></xsl:attribute>\r
-      <xsl:attribute name="RadiusY"><xsl:value-of select="@r" /></xsl:attribute>\r
-    </xsl:if>\r
-  </EllipseGeometry>\r
-</xsl:template>\r
-\r
-<!-- Geometry for rectangle -->\r
-<xsl:template mode="geometry" match="*[name(.) = 'rect']">\r
-  <RectangleGeometry>\r
-    <xsl:if test="../@id"><xsl:attribute name="x:Key"><xsl:value-of select="../@id" /></xsl:attribute></xsl:if>\r
-    <!--\r
-    <xsl:if test="@x"><xsl:attribute name="Canvas.Left"><xsl:value-of select="@x" /></xsl:attribute></xsl:if>\r
-    <xsl:if test="@y"><xsl:attribute name="Canvas.Top"><xsl:value-of select="@y" /></xsl:attribute></xsl:if>\r
-    <xsl:if test="@width"><xsl:attribute name="Width"><xsl:value-of select="@width" /></xsl:attribute></xsl:if>\r
-    <xsl:if test="@height"><xsl:attribute name="Height"><xsl:value-of select="@height" /></xsl:attribute></xsl:if>\r
-    <xsl:if test="@rx"><xsl:attribute name="RadiusX"><xsl:value-of select="@rx" /></xsl:attribute></xsl:if>\r
-    <xsl:if test="@ry"><xsl:attribute name="RadiusY"><xsl:value-of select="@ry" /></xsl:attribute></xsl:if>\r
-    -->\r
-    <xsl:attribute name="Rect"><xsl:value-of select="concat('0, 0, ', @width, ', ', @height)" /></xsl:attribute>\r
-  </RectangleGeometry>\r
-</xsl:template>\r
-\r
-</xsl:stylesheet>\r
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!--
+Copyright (c) 2005-2007 authors:
+Original version: Toine de Greef (a.degreef@chello.nl)
+Modified (2010) by Nicolas Dufour (nicoduf@yahoo.fr) (blur support, units
+convertion, comments, and some other fixes)
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
+-->
+
+<xsl:stylesheet version="1.0"
+xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
+xmlns:xlink="http://www.w3.org/1999/xlink"
+xmlns:xs="http://www.w3.org/2001/XMLSchema"
+xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
+xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
+xmlns:exsl="http://exslt.org/common"
+xmlns:libxslt="http://xmlsoft.org/XSLT/namespace"
+exclude-result-prefixes="rdf xlink xs exsl libxslt">
+
+<xsl:strip-space elements="*" />
+<xsl:output method="xml" encoding="UTF-8"/>
+
+<xsl:param name="silverlight_compatible" select="1" />
+
+<!-- Root template.
+Everything starts here! -->
+<xsl:template match="/">
+  <xsl:choose>
+    <xsl:when test="$silverlight_compatible = 1">
+      <xsl:apply-templates mode="forward" />
+    </xsl:when>
+    <xsl:otherwise>
+      <Viewbox Stretch="Uniform">
+        <xsl:apply-templates mode="forward" />
+      </Viewbox>
+    </xsl:otherwise>   
+  </xsl:choose>
+</xsl:template>
+
+<!-- SVG and groups
+(including layers) -->
+<xsl:template mode="forward" match="*[name(.) = 'svg' or name(.) = 'g']">
+  <xsl:choose>
+    <xsl:when test="name(.) = 'svg' or @transform or @viewBox or @id or @clip-path or (@style and contains(@style, 'clip-path:url(#')) or (@width and not(contains(@width, '%'))) or @x or @y or (@height and not(contains(@height, '%'))) or *[name(.) = 'linearGradient' or name(.) = 'radialGradient' or name(.) = 'defs' or name(.) = 'clipPath']">
+      <Canvas>
+        <xsl:apply-templates mode="id" select="." />
+        <!--
+        <xsl:apply-templates mode="clip" select="." />
+        -->
+        <xsl:if test="@style and contains(@style, 'display:none')"><xsl:attribute name="Visibility">Collapsed</xsl:attribute></xsl:if>
+        <xsl:if test="@style and contains(@style, 'opacity:')">
+        <xsl:attribute name="Opacity">
+            <xsl:choose>
+                <xsl:when test="contains(substring-after(@style, 'opacity:'), ';')"><xsl:value-of select="substring-before(substring-after(@style, 'opacity:'), ';')" /></xsl:when>
+                  <xsl:otherwise><xsl:value-of select="substring-after(@style, 'opacity:')" /></xsl:otherwise>
+            </xsl:choose>
+        </xsl:attribute>
+        </xsl:if>
+        <xsl:if test="@width and not(contains(@width, '%'))">
+        <xsl:attribute name="Width">
+            <xsl:call-template name="convert_unit">
+                <xsl:with-param name="convert_value" select="@width" />
+            </xsl:call-template>
+        </xsl:attribute></xsl:if>
+        <xsl:if test="@height and not(contains(@height, '%'))">
+        <xsl:attribute name="Height">
+            <xsl:call-template name="convert_unit">
+                <xsl:with-param name="convert_value" select="@height" />
+            </xsl:call-template>
+        </xsl:attribute></xsl:if>
+        <xsl:if test="@x">
+       <xsl:attribute name="Canvas.Left">
+            <xsl:call-template name="convert_unit">
+                <xsl:with-param name="convert_value" select="@x" />
+            </xsl:call-template>
+       </xsl:attribute></xsl:if>
+        <xsl:if test="@y">
+       <xsl:attribute name="Canvas.Top">
+            <xsl:call-template name="convert_unit">
+                <xsl:with-param name="convert_value" select="@y" />
+            </xsl:call-template>
+       </xsl:attribute></xsl:if>
+        <xsl:if test="@viewBox">
+          <xsl:variable name="viewBox"><xsl:value-of select="normalize-space(translate(@viewBox, ',', ' '))" /></xsl:variable>
+          <xsl:attribute name="Width"><xsl:value-of select="substring-before(substring-after(substring-after($viewBox, ' '), ' '), ' ')" /></xsl:attribute>
+          <xsl:attribute name="Height"><xsl:value-of select="substring-after(substring-after(substring-after($viewBox, ' '), ' '), ' ')" /></xsl:attribute>
+          <Canvas.RenderTransform>
+            <TranslateTransform>
+              <xsl:attribute name="X"><xsl:value-of select="-number(substring-before($viewBox, ' '))" /></xsl:attribute>
+              <xsl:attribute name="Y"><xsl:value-of select="-number(substring-before(substring-after($viewBox, ' '), ' '))" /></xsl:attribute>
+            </TranslateTransform>
+          </Canvas.RenderTransform>
+        </xsl:if>
+    <xsl:if test="@transform">
+      <Canvas>
+        <Canvas.RenderTransform>
+          <TransformGroup><xsl:apply-templates mode="transform" select="." /></TransformGroup>
+        </Canvas.RenderTransform>
+        <xsl:apply-templates mode="forward" select="*" />
+      </Canvas>
+    </xsl:if>
+
+        <xsl:if test="*[name(.) = 'linearGradient' or name(.) = 'radialGradient' or name(.) = 'defs' or name(.) = 'clipPath']">
+          <Canvas.Resources>
+            <xsl:apply-templates mode="forward" select="*[name(.) = 'linearGradient' or name(.) = 'radialGradient' or name(.) = 'defs' or name(.) = 'clipPath']" />
+          </Canvas.Resources>
+        </xsl:if>
+        <xsl:if test="not(@transform)">
+          <xsl:apply-templates mode="forward" select="*[name(.) != 'linearGradient' and name(.) != 'radialGradient' and name(.) != 'defs' and name(.) != 'clipPath']" />
+        </xsl:if>  
+      </Canvas>
+    </xsl:when>
+    <xsl:when test="not(@transform)">
+      <xsl:apply-templates mode="forward" select="*" />
+    </xsl:when>
+  </xsl:choose>
+</xsl:template>
+
+<!--
+// Resources (defs) //
+
+* Resources ids
+* Generic defs template
+* Generic filters template
+* Filter effects
+* Linked filter effects
+* Linear gradients
+* Radial gradients
+* Generic gradient stops
+* Clipping
+-->
+
+<!-- Resources ids -->
+<xsl:template mode="resources" match="*">
+  <!-- should be in-depth -->
+  <xsl:if test="ancestor::*[name(.) = 'defs']"><xsl:attribute name="x:Key"><xsl:value-of select="@id" /></xsl:attribute></xsl:if>
+</xsl:template>
+
+<!-- Generic defs template -->
+<xsl:template mode="forward" match="defs">
+  <xsl:apply-templates mode="forward" />
+</xsl:template>
+
+<!-- Generic filters template
+Limited to one filter (can be improved) -->
+<xsl:template mode="forward" match="*[name(.) = 'filter']">
+    <xsl:if test="count(*) = 1">
+      <xsl:apply-templates mode="forward" />
+    </xsl:if> 
+</xsl:template>
+
+<!-- Filter effects -->
+<xsl:template mode="forward" match="*[name(.) = 'feGaussianBlur']">
+        <BlurEffect>
+            <xsl:if test="../@id"><xsl:attribute name="x:Key"><xsl:value-of select="../@id" /></xsl:attribute></xsl:if>
+            <xsl:if test="@stdDeviation"><xsl:attribute name="Radius"><xsl:value-of select="round(@stdDeviation * 3)" /></xsl:attribute></xsl:if>
+        </BlurEffect>  
+</xsl:template>
+
+<!-- Linked filter effect -->
+<xsl:template mode="filter_effect" match="*">
+<xsl:choose>
+    <xsl:when test="@filter and starts-with(@filter, 'url(#')">
+        <xsl:attribute name="Effect">
+            <xsl:value-of select="concat('{StaticResource ', substring-before(substring-after(@filter, 'url(#'), ')'), '}')" />
+        </xsl:attribute>
+    </xsl:when>
+    <xsl:when test="@style and contains(@style, 'filter:url(#')">
+        <xsl:attribute name="Effect">
+            <xsl:value-of select="concat('{StaticResource ', substring-before(substring-after(@style, 'filter:url(#'), ')'), '}')" />
+        </xsl:attribute>
+    </xsl:when>
+</xsl:choose>
+</xsl:template>
+
+<!-- Linear gradient -->
+<xsl:template mode="forward" match="*[name(.) = 'linearGradient']">
+  <LinearGradientBrush>
+    <xsl:if test="@id"><xsl:attribute name="x:Key"><xsl:value-of select="@id" /></xsl:attribute></xsl:if>
+    <xsl:attribute name="MappingMode">
+      <xsl:choose>
+        <xsl:when test="@gradientUnits = 'userSpaceOnUse' ">Absolute</xsl:when>
+        <xsl:otherwise>RelativeToBoundingBox</xsl:otherwise>
+      </xsl:choose>
+    </xsl:attribute>
+    <xsl:if test="@spreadMethod">
+      <xsl:attribute name="SpreadMethod">
+        <xsl:choose>
+          <xsl:when test="@spreadMethod = 'pad'">Pad</xsl:when>
+          <xsl:when test="@spreadMethod = 'reflect'">Reflect</xsl:when>
+          <xsl:when test="@spreadMethod = 'repeat'">Repeat</xsl:when>
+        </xsl:choose>
+      </xsl:attribute>
+    </xsl:if>
+    <xsl:choose>
+      <xsl:when test="@x1 and @y1 and @x2 and @y2">
+        <xsl:choose>
+          <xsl:when test="contains(@x1, '%') and contains(@y1, '%')">
+            <xsl:attribute name="StartPoint"><xsl:value-of select="concat(substring-before(@x1, '%') div 100, ',', substring-before(@y1,'%') div 100)" /></xsl:attribute>
+          </xsl:when>
+          <xsl:otherwise>
+            <xsl:attribute name="StartPoint"><xsl:value-of select="concat(@x1, ',', @y1)" /></xsl:attribute>
+          </xsl:otherwise>
+        </xsl:choose>
+        <xsl:choose>
+          <xsl:when test="contains(@x2, '%') and contains(@y2, '%')">
+            <xsl:attribute name="EndPoint"><xsl:value-of select="concat(substring-before(@x2, '%') div 100, ',', substring-before(@y2,'%') div 100)" /></xsl:attribute>
+          </xsl:when>
+          <xsl:otherwise>
+            <xsl:attribute name="EndPoint"><xsl:value-of select="concat(@x2, ',', @y2)" /></xsl:attribute>
+          </xsl:otherwise>
+        </xsl:choose>  
+      </xsl:when>
+      <xsl:otherwise>
+        <xsl:attribute name="StartPoint"><xsl:value-of select="'0,0'" /></xsl:attribute>
+        <xsl:attribute name="EndPoint"><xsl:value-of select="'1,1'" /></xsl:attribute>
+      </xsl:otherwise>
+    </xsl:choose>
+    <LinearGradientBrush.GradientStops>
+      <GradientStopCollection>
+        <xsl:choose>
+          <xsl:when test="@xlink:href">
+            <xsl:variable name="reference_id" select="@xlink:href" />
+            <xsl:apply-templates mode="forward" select="//*[name(.) = 'linearGradient' and $reference_id = concat('#', @id)]/*" />
+          </xsl:when>
+          <xsl:otherwise><xsl:apply-templates mode="forward" /></xsl:otherwise>
+        </xsl:choose>
+      </GradientStopCollection>
+    </LinearGradientBrush.GradientStops>
+    <xsl:if test="@gradientTransform">
+    <LinearGradientBrush.Transform>
+      <xsl:apply-templates mode="transform" select="." />
+    </LinearGradientBrush.Transform>
+  </xsl:if>
+  </LinearGradientBrush>
+</xsl:template>
+
+<!-- Radial gradient -->
+<xsl:template mode="forward" match="*[name(.) = 'radialGradient']">
+  <RadialGradientBrush>
+    <xsl:if test="@id"><xsl:attribute name="x:Key"><xsl:value-of select="@id" /></xsl:attribute></xsl:if>
+    <xsl:attribute name="MappingMode">
+      <xsl:choose>
+        <xsl:when test="@gradientUnits = 'userSpaceOnUse' ">Absolute</xsl:when>
+        <xsl:otherwise>RelativeToBoundingBox</xsl:otherwise>
+      </xsl:choose>
+    </xsl:attribute>
+    <xsl:if test="@spreadMethod">
+      <xsl:attribute name="SpreadMethod">
+        <xsl:choose>
+          <xsl:when test="@spreadMethod = 'pad'">Pad</xsl:when>
+          <xsl:when test="@spreadMethod = 'reflect'">Reflect</xsl:when>
+          <xsl:when test="@spreadMethod = 'repeat'">Repeat</xsl:when>
+        </xsl:choose>
+      </xsl:attribute>
+    </xsl:if>
+    <xsl:if test="@cx and @cy">
+      <xsl:attribute name="Center">
+        <xsl:choose>
+          <xsl:when test="contains(@cx, '%') and contains(@cy, '%')">
+            <xsl:value-of select="concat(number(substring-before(@cx, '%')) div 100, ',', number(substring-before(@cy, '%')) div 100)" />
+          </xsl:when>
+          <xsl:otherwise>
+            <xsl:value-of select="concat(@cx, ',', @cy)" />
+          </xsl:otherwise>
+        </xsl:choose>
+      </xsl:attribute>
+    </xsl:if>  
+    <xsl:if test="@fx and @fy">
+      <xsl:attribute name="GradientOrigin">
+        <xsl:choose>
+          <xsl:when test="contains(@fx, '%') and contains(@fy, '%')">
+            <xsl:value-of select="concat(number(substring-before(@fx, '%')) div 100, ',', number(substring-before(@fy, '%')) div 100)" />
+          </xsl:when>
+          <xsl:otherwise>
+            <xsl:value-of select="concat(@fx, ',', @fy)" />
+          </xsl:otherwise>
+        </xsl:choose>
+      </xsl:attribute>
+    </xsl:if>
+    <xsl:if test="@r">
+      <xsl:choose>
+        <xsl:when test="contains(@r, '%')">
+          <xsl:attribute name="RadiusX"><xsl:value-of select="number(substring-before(@r, '%')) div 100" /></xsl:attribute>
+          <xsl:attribute name="RadiusY"><xsl:value-of select="number(substring-before(@r, '%')) div 100" /></xsl:attribute>
+        </xsl:when>
+        <xsl:otherwise>
+          <xsl:attribute name="RadiusX"><xsl:value-of select="@r" /></xsl:attribute>
+          <xsl:attribute name="RadiusY"><xsl:value-of select="@r" /></xsl:attribute>
+        </xsl:otherwise>
+      </xsl:choose>
+    </xsl:if>
+    <RadialGradientBrush.GradientStops>
+      <GradientStopCollection>
+        <xsl:choose>
+          <xsl:when test="@xlink:href">
+            <xsl:variable name="reference_id" select="@xlink:href" />
+            <xsl:apply-templates mode="forward" select="//*[name(.) = 'linearGradient' and $reference_id = concat('#', @id)]/*" />
+          </xsl:when>
+          <xsl:otherwise><xsl:apply-templates mode="forward" /></xsl:otherwise>
+        </xsl:choose>
+      </GradientStopCollection>
+    </RadialGradientBrush.GradientStops>
+    <xsl:if test="@gradientTransform">
+    <RadialGradientBrush.Transform>
+      <xsl:apply-templates mode="transform" select="." />
+    </RadialGradientBrush.Transform>
+    </xsl:if>
+  </RadialGradientBrush>
+</xsl:template>
+
+<!-- Generic gradient stops -->
+<xsl:template mode="forward" match="*[name(.) = 'stop']">
+  <GradientStop>
+    <!--xsl:apply-templates mode="stop_opacity" select="." /-->
+    <xsl:apply-templates mode="stop_color" select="." />
+    <xsl:apply-templates mode="offset" select="." />
+    <xsl:apply-templates mode="forward" />
+  </GradientStop>
+</xsl:template>
+
+<!-- Clipping -->
+<xsl:template mode="clip" match="*">
+  <xsl:choose>
+    <xsl:when test="@clip-path and defs/clipPath/path/@d"><xsl:attribute name="Clip"><xsl:value-of select="defs/clipPath/path/@d" /></xsl:attribute></xsl:when>
+    <xsl:when test="@clip-path and starts-with(@clip-path, 'url(#')"><xsl:attribute name="Clip"><xsl:value-of select="concat('{StaticResource ', substring-before(substring-after(@clip-path, 'url(#'), ')'), '}')" /></xsl:attribute></xsl:when>
+    <xsl:when test="@style and contains(@style, 'clip-path:url(#')"><xsl:attribute name="Clip"><xsl:value-of select="concat('{StaticResource ', substring-before(substring-after(@style, 'url(#'), ')'), '}')" /></xsl:attribute></xsl:when>
+    <xsl:when test="clipPath"><xsl:apply-templates mode="forward" /></xsl:when>
+  </xsl:choose>
+</xsl:template>
+
+<!--
+// Misc templates //
+
+* Object description
+* Id converter
+* Decimal to hexadecimal converter
+* Unit to pixel converter
+* Title and description
+* Misc ignored stuff (markers, patterns, styles)
+* Symbols
+* Use
+* RDF and foreign objects
+* Unknows tags
+-->
+
+<!-- Object description -->
+<xsl:template mode="desc" match="*">
+  <xsl:if test="*[name(.) = 'desc']/text()"><xsl:attribute name="Tag"><xsl:value-of select="*[name(.) = 'desc']/text()" /></xsl:attribute></xsl:if>
+</xsl:template>
+
+<!-- Id converter. Removes "-" from the original id. -->
+<xsl:template mode="id" match="*">
+<xsl:if test="@id">
+  <xsl:attribute name="Name"><xsl:value-of select="translate(@id, '- ', '')" /></xsl:attribute>
+  <!--
+    <xsl:attribute name="x:Key"><xsl:value-of select="translate(@id, '- ', '')" /></xsl:attribute>
+  -->
+</xsl:if>
+</xsl:template>
+
+<!-- Decimal to hexadecimal converter -->
+<xsl:template name="to_hex">
+  <xsl:param name="convert" />
+  <xsl:value-of select="concat(substring('0123456789ABCDEF', 1 + floor(round($convert) div 16), 1), substring('0123456789ABCDEF', 1 + round($convert) mod 16, 1))" />
+</xsl:template>
+
+<!-- Unit to pixel converter
+Values with units (except %) are converted to pixels and rounded.
+Unknown units are kept. -->
+<xsl:template name="convert_unit">
+  <xsl:param name="convert_value" />
+      <xsl:choose>
+        <xsl:when test="contains($convert_value, 'px')">
+            <xsl:value-of select="round(translate($convert_value, 'px', ''))" />
+        </xsl:when>
+        <xsl:when test="contains($convert_value, 'pt')">
+            <xsl:value-of select="round(translate($convert_value, 'pt', '') * 1.25)" />
+        </xsl:when>
+        <xsl:when test="contains($convert_value, 'pc')">
+            <xsl:value-of select="round(translate($convert_value, 'pc', '') * 15)" />
+        </xsl:when>
+        <xsl:when test="contains($convert_value, 'mm')">
+            <xsl:value-of select="round(translate($convert_value, 'mm', '') * 3.543307)" />
+        </xsl:when>
+        <xsl:when test="contains($convert_value, 'cm')">
+            <xsl:value-of select="round(translate($convert_value, 'cm', '') * 35.43307)" />
+        </xsl:when>
+        <xsl:when test="contains($convert_value, 'in')">
+            <xsl:value-of select="round(translate($convert_value, 'in', '') * 90)" />
+        </xsl:when>
+        <xsl:when test="contains($convert_value, 'ft')">
+            <xsl:value-of select="round(translate($convert_value, 'ft', '') * 1080)" />
+        </xsl:when>
+        <xsl:when test="not(string(number($convert_value))='NaN')">
+            <xsl:value-of select="round($convert_value)" />
+        </xsl:when>
+        <xsl:otherwise>
+            <xsl:value-of select="$convert_value" />
+        </xsl:otherwise>
+      </xsl:choose>
+</xsl:template>
+
+<!-- Title and description
+Blank template. Title is ignored and desc is converted to Tag in the mode="desc" template
+-->
+<xsl:template mode="forward" match="*[name(.) = 'title' or name(.) = 'desc']">
+  <!-- -->
+</xsl:template>
+
+<!-- Misc ignored stuff (markers, patterns, styles) -->
+<xsl:template mode="forward" match="*[name(.) = 'marker' or name(.) = 'pattern' or name(.) = 'style']">
+  <!-- -->
+</xsl:template>
+
+<!-- Symbols -->
+<xsl:template mode="forward" match="*[name(.) = 'symbol']">
+  <Style>
+    <xsl:if test="@id"><xsl:attribute name="x:Key"><xsl:value-of select="@id" /></xsl:attribute></xsl:if>
+    <Canvas>
+      <xsl:apply-templates mode="forward" />
+    </Canvas>
+  </Style>
+</xsl:template>
+
+<!-- Use -->
+<xsl:template mode="forward" match="*[name(.) = 'use']">
+  <Canvas>
+    <xsl:if test="@xlink:href"><xsl:attribute name="Style"><xsl:value-of select="@xlink:href" /></xsl:attribute></xsl:if>
+    <!--xsl:apply-templates mode="transform" select="." /-->
+    <xsl:apply-templates mode="forward" />
+  </Canvas>
+</xsl:template>
+
+<!-- RDF and foreign objects -->
+<xsl:template mode="forward" match="rdf:RDF | *[name(.) = 'foreignObject']">
+  <!-- -->
+</xsl:template>
+
+<!-- Unknown tags -->
+<xsl:template match="*">
+<xsl:comment><xsl:value-of select="concat('Unknown tag: ', name(.))" /></xsl:comment>
+</xsl:template>
+
+
+<!--
+// Colors and patterns //
+
+* Generic color template
+* Fill
+* Fill opacity
+* Fill rule
+* Generic fill template
+* Stroke
+* Stroke opacity
+* Generic stroke template
+* Stroke width
+* Stroke mitterlimit
+* Stroke dasharray
+* Stroke dashoffset
+* Linejoin SVG to XAML converter
+* Stroke linejoin
+* Linecap SVG to XAML converter
+* Stroke linecap
+* Gradient stop
+* Gradient stop opacity
+* Gradient stop offset
+-->
+
+<!-- Generic color template -->
+<xsl:template name="template_color">
+  <xsl:param name="colorspec" />
+  <xsl:param name="opacityspec" />
+  <xsl:choose>
+    <xsl:when test="starts-with($colorspec, 'rgb(') and not(contains($colorspec , '%'))">
+      <xsl:value-of select="'#'" />
+      <xsl:if test="$opacityspec != '' and number($opacityspec) != 1"><xsl:call-template name="to_hex"><xsl:with-param name="convert"><xsl:value-of select="round(number($opacityspec) * 255)" /></xsl:with-param></xsl:call-template></xsl:if>
+      <xsl:call-template name="to_hex"><xsl:with-param name="convert"><xsl:value-of select="substring-before(substring-after($colorspec, 'rgb('), ',')" /></xsl:with-param></xsl:call-template>
+      <xsl:call-template name="to_hex"><xsl:with-param name="convert"><xsl:value-of select="substring-before(substring-after(substring-after($colorspec, 'rgb('), ','), ',')" /></xsl:with-param></xsl:call-template>
+      <xsl:call-template name="to_hex"><xsl:with-param name="convert"><xsl:value-of select="substring-before(substring-after(substring-after(substring-after($colorspec, 'rgb('), ','), ','), ')')" /></xsl:with-param></xsl:call-template>
+    </xsl:when>
+    <xsl:when test="starts-with($colorspec, 'rgb(') and contains($colorspec , '%')">
+      <xsl:value-of select="'#'" />
+      <xsl:if test="$opacityspec != '' and number($opacityspec) != 1"><xsl:call-template name="to_hex"><xsl:with-param name="convert"><xsl:value-of select="round(number($opacityspec) * 255)" /></xsl:with-param></xsl:call-template></xsl:if>
+      <xsl:call-template name="to_hex"><xsl:with-param name="convert"><xsl:value-of select="number(substring-before(substring-after($colorspec, 'rgb('), '%,')) * 255 div 100" /></xsl:with-param></xsl:call-template>
+      <xsl:call-template name="to_hex"><xsl:with-param name="convert"><xsl:value-of select="number(substring-before(substring-after(substring-after($colorspec, 'rgb('), ','), '%,')) * 255 div 100" /></xsl:with-param></xsl:call-template>
+      <xsl:call-template name="to_hex"><xsl:with-param name="convert"><xsl:value-of select="number(substring-before(substring-after(substring-after(substring-after($colorspec, 'rgb('), ','), ','), '%)')) * 255 div 100" /></xsl:with-param></xsl:call-template>
+    </xsl:when>
+    <xsl:when test="starts-with($colorspec, '#')">
+      <xsl:value-of select="'#'" />
+      <xsl:if test="$opacityspec != ''"><xsl:call-template name="to_hex"><xsl:with-param name="convert"><xsl:value-of select="round(number($opacityspec) * 255)" /></xsl:with-param></xsl:call-template></xsl:if>
+      <xsl:choose>
+        <xsl:when test="string-length(substring-after($colorspec, '#')) = 3">
+          <xsl:variable name="colorspec3"><xsl:value-of select="translate(substring-after($colorspec, '#'), 'abcdefgh', 'ABCDEFGH')" /></xsl:variable>
+          <xsl:value-of select="concat(substring($colorspec3, 1, 1), substring($colorspec3, 1, 1))" />
+          <xsl:value-of select="concat(substring($colorspec3, 2, 1), substring($colorspec3, 2, 1))" />
+          <xsl:value-of select="concat(substring($colorspec3, 3, 1), substring($colorspec3, 3, 1))" />
+        </xsl:when>
+        <xsl:otherwise><xsl:value-of select="translate(substring-after($colorspec, '#'), 'abcdefgh', 'ABCDEFGH')" /></xsl:otherwise>
+      </xsl:choose>
+    </xsl:when>
+    <xsl:otherwise>
+      <xsl:variable name="named_color_hex" select="document('colors.xml')/colors/color[@name = translate($colorspec, 'ABCDEFGHIJKLMNOPQRSTUVWXYZ', 'abcdefghijklmnopqrstuvwxyz')]/@hex" />
+      <xsl:choose>
+        <xsl:when test="$named_color_hex and $named_color_hex != ''">
+          <xsl:value-of select="'#'" />
+          <xsl:if test="$opacityspec != '' and number($opacityspec) != 1"><xsl:call-template name="to_hex"><xsl:with-param name="convert"><xsl:value-of select="number($opacityspec) * 255" /></xsl:with-param></xsl:call-template></xsl:if>
+          <xsl:value-of select="substring-after($named_color_hex, '#')" />
+        </xsl:when>
+        <xsl:otherwise><xsl:value-of select="$colorspec" /></xsl:otherwise>
+      </xsl:choose>
+    </xsl:otherwise>
+  </xsl:choose>
+</xsl:template>
+
+<!-- Fill -->
+<xsl:template mode="fill" match="*">
+  <xsl:choose>
+    <xsl:when test="@fill and starts-with(@fill, 'url(#')"><xsl:value-of select="concat('{StaticResource ', substring-before(substring-after(@fill, 'url(#'), ')'), '}')" /></xsl:when>
+    <xsl:when test="@fill"><xsl:value-of select="@fill" /></xsl:when>
+    <xsl:when test="@style and contains(@style, 'fill:') and starts-with(substring-after(@style, 'fill:'), 'url(#')"><xsl:value-of select="concat('{StaticResource ', substring-before(substring-after(@style, 'url(#'), ')'), '}')" /></xsl:when>
+    <xsl:when test="@style and contains(@style, 'fill:')">
+      <xsl:variable name="Fill" select="substring-after(@style, 'fill:')" />
+      <xsl:choose>
+        <xsl:when test="contains($Fill, ';')">
+          <xsl:value-of select="substring-before($Fill, ';')" />
+        </xsl:when>
+        <xsl:otherwise><xsl:value-of select="$Fill" /></xsl:otherwise>
+      </xsl:choose>
+    </xsl:when>
+    <xsl:when test="name(..) = 'g' or name(..) = 'svg'"><xsl:apply-templates mode="fill" select="parent::*"/></xsl:when>
+  </xsl:choose>
+</xsl:template>
+
+<!-- Fill opacity -->
+<xsl:template mode="fill_opacity" match="*">
+  <xsl:choose>
+    <xsl:when test="@fill-opacity"><xsl:value-of select="@fill-opacity" /></xsl:when>
+    <xsl:when test="@style and contains(@style, 'fill-opacity:')">
+      <xsl:variable name="Opacity" select="substring-after(@style, 'fill-opacity:')" />
+      <xsl:choose>
+        <xsl:when test="contains($Opacity, ';')"><xsl:value-of select="substring-before($Opacity, ';')" /></xsl:when>
+        <xsl:otherwise><xsl:value-of select="$Opacity" /></xsl:otherwise>
+      </xsl:choose>
+    </xsl:when>
+    <xsl:when test="name(..) = 'g' or name(..) = 'svg'"><xsl:apply-templates mode="fill_opacity" select="parent::*" /></xsl:when>
+  </xsl:choose>
+</xsl:template>
+
+<!-- Fill rule -->
+<xsl:template mode="fill_rule" match="*">
+  <xsl:choose>
+    <xsl:when test="@fill-rule and (@fill-rule = 'nonzero' or @fill-rule = 'evenodd')"><xsl:attribute name="FillRule"><xsl:value-of select="@fill-rule" /></xsl:attribute></xsl:when>
+    <xsl:when test="@style and contains(@style, 'fill-rule:')">
+      <xsl:variable name="FillRule" select="substring-after(@style, 'fill-rule:')" />
+      <xsl:choose>
+        <xsl:when test="contains($FillRule, ';')">
+          <xsl:if test="substring-before($FillRule, ';') = 'nonzero' or substring-before($FillRule, ';') = 'evenodd'"><xsl:attribute name="FillRule"><xsl:value-of select="substring-before($FillRule, ';')" /></xsl:attribute></xsl:if>
+        </xsl:when>
+        <xsl:when test="$FillRule = 'nonzero' or $FillRule = 'evenodd'"><xsl:attribute name="FillRule"><xsl:value-of select="$FillRule" /></xsl:attribute></xsl:when>
+      </xsl:choose>
+    </xsl:when>
+    <xsl:when test="name(..) = 'g' or name(..) = 'svg'"><xsl:apply-templates mode="fill_rule" select="parent::*"/></xsl:when>
+    <xsl:otherwise><xsl:attribute name="FillRule">NonZero</xsl:attribute></xsl:otherwise>
+  </xsl:choose>
+</xsl:template>
+
+<!-- Generic fill template -->
+<xsl:template mode="template_fill" match="*">
+  <xsl:variable name="fill"><xsl:apply-templates mode="fill" select="." /></xsl:variable>
+  <xsl:variable name="fill_opacity"><xsl:apply-templates mode="fill_opacity" select="." /></xsl:variable>
+  <xsl:if test="not($fill = 'none')">
+    <xsl:attribute name="Fill">
+      <xsl:choose>
+        <xsl:when test="$fill != ''">
+          <xsl:call-template name="template_color">
+            <xsl:with-param name="colorspec">
+              <xsl:if test="$fill != 'none'"><xsl:value-of select="$fill" /></xsl:if>
+            </xsl:with-param>
+            <xsl:with-param name="opacityspec"><xsl:value-of select="$fill_opacity" /></xsl:with-param>
+          </xsl:call-template>
+        </xsl:when>
+        <xsl:otherwise>#000000</xsl:otherwise>
+      </xsl:choose>
+    </xsl:attribute>
+  </xsl:if>
+</xsl:template>
+
+<!-- Stroke -->
+<xsl:template mode="stroke" match="*">
+  <xsl:choose>
+    <xsl:when test="@stroke and starts-with(@stroke, 'url(#')"><xsl:value-of select="concat('{StaticResource ', substring-before(substring-after(@stroke, 'url(#'), ')'), '}')" /></xsl:when>
+    <xsl:when test="@stroke and @stroke != 'none'"><xsl:value-of select="@stroke" /></xsl:when>
+    <xsl:when test="@style and contains(@style, 'stroke:') and starts-with(substring-after(@style, 'stroke:'), 'url(#')"><xsl:value-of select="concat('{StaticResource ', substring-before(substring-after(@style, 'url(#'), ')'), '}')" /></xsl:when>
+    <xsl:when test="@style and contains(@style, 'stroke:')">
+      <xsl:variable name="Stroke" select="substring-after(@style, 'stroke:')" />
+      <xsl:choose>
+        <xsl:when test="contains($Stroke, ';')">
+          <xsl:if test="substring-before($Stroke, ';') != 'none'"><xsl:value-of select="substring-before($Stroke, ';')" /></xsl:if>
+        </xsl:when>
+        <xsl:when test="$Stroke != 'none'"><xsl:value-of select="$Stroke" /></xsl:when>
+      </xsl:choose>
+    </xsl:when>
+    <xsl:when test="name(..) = 'g' or name(..) = 'svg'"><xsl:apply-templates mode="stroke" select="parent::*"/></xsl:when>
+  </xsl:choose>
+</xsl:template>
+
+<!-- Stroke opacity -->
+<xsl:template mode="stroke_opacity" match="*">
+  <xsl:choose>
+    <xsl:when test="@stroke-opacity"><xsl:value-of select="@stroke-opacity" /></xsl:when>
+    <xsl:when test="@style and contains(@style, 'stroke-opacity:')">
+      <xsl:variable name="Opacity" select="substring-after(@style, 'stroke-opacity:')" />
+      <xsl:choose>
+        <xsl:when test="contains($Opacity, ';')"><xsl:value-of select="substring-before($Opacity, ';')" /></xsl:when>
+        <xsl:otherwise><xsl:value-of select="$Opacity" /></xsl:otherwise>
+      </xsl:choose>
+    </xsl:when>
+    <xsl:when test="name(..) = 'g' or name(..) = 'svg'"><xsl:apply-templates mode="stroke_opacity" select="parent::*" /></xsl:when>
+  </xsl:choose>
+</xsl:template>
+
+<!-- Generic stroke template -->
+<xsl:template mode="template_stroke" match="*">
+  <xsl:variable name="stroke"><xsl:apply-templates mode="stroke" select="." /></xsl:variable>
+  <xsl:variable name="stroke_opacity"><xsl:apply-templates mode="stroke_opacity" select="." /></xsl:variable>
+  <xsl:if test="$stroke != ''">
+    <xsl:attribute name="Stroke">
+      <xsl:call-template name="template_color">
+        <xsl:with-param name="colorspec"><xsl:value-of select="$stroke" /></xsl:with-param>
+        <xsl:with-param name="opacityspec"><xsl:value-of select="$stroke_opacity" /></xsl:with-param>
+      </xsl:call-template>
+    </xsl:attribute>
+  </xsl:if>
+</xsl:template>
+
+<!-- Stroke width -->
+<xsl:template mode="stroke_width" match="*">
+  <xsl:choose>
+    <xsl:when test="@stroke-width">
+        <xsl:attribute name="StrokeThickness"><xsl:value-of select="@stroke-width" /></xsl:attribute>
+    </xsl:when>
+    <xsl:when test="@style and contains(@style, 'stroke-width:')">
+      <xsl:attribute name="StrokeThickness">
+          <xsl:call-template name="convert_unit">
+            <xsl:with-param name="convert_value">
+            <xsl:choose>
+              <xsl:when test="contains(substring-after(@style, 'stroke-width:'), ';')"><xsl:value-of select="substring-before(substring-after(@style, 'stroke-width:'), ';')" /></xsl:when>
+              <xsl:otherwise><xsl:value-of select="substring-after(@style, 'stroke-width:')" /></xsl:otherwise>
+            </xsl:choose>
+            </xsl:with-param>
+        </xsl:call-template> 
+      </xsl:attribute>
+    </xsl:when>
+    <xsl:when test="name(..) = 'g' or name(..) = 'svg'"><xsl:apply-templates mode="stroke_width" select="parent::*"/></xsl:when>
+  </xsl:choose>
+</xsl:template>
+
+<!-- Stroke miterlimit -->
+<xsl:template mode="stroke_miterlimit" match="*">
+  <xsl:choose>
+    <xsl:when test="@stroke-miterlimit"><xsl:attribute name="StrokeMiterLimit"><xsl:value-of select="@stroke-miterlimit" /></xsl:attribute></xsl:when>
+    <xsl:when test="@style and contains(@style, 'stroke-miterlimit:')">
+      <xsl:variable name="StrokeMiterLimit" select="substring-after(@style, 'stroke-miterlimit:')" />
+      <xsl:attribute name="StrokeMiterLimit">
+        <xsl:choose>
+          <xsl:when test="contains($StrokeMiterLimit, ';')"><xsl:value-of select="substring-before($StrokeMiterLimit, ';')" /></xsl:when>
+          <xsl:otherwise><xsl:value-of select="$StrokeMiterLimit" /></xsl:otherwise>
+        </xsl:choose>
+      </xsl:attribute>
+    </xsl:when>
+    <xsl:when test="name(..) = 'g' or name(..) = 'svg'"><xsl:apply-templates mode="stroke_miterlimit" select="parent::*"/></xsl:when>
+  </xsl:choose>
+</xsl:template>
+
+<!-- Stroke dasharray -->
+<xsl:template mode="stroke_dasharray" match="*">
+  <!-- stroke-dasharray="10,30,20,30" becomes StrokeDashArray="1 3 2 3" ?? -->
+  <xsl:choose>
+    <xsl:when test="@stroke-dasharray and @stroke-dasharray != 'none'"><xsl:attribute name="StrokeDashArray"><xsl:value-of select="@stroke-dasharray" /></xsl:attribute></xsl:when>
+    <xsl:when test="@style and contains(@style, 'stroke-dasharray:')">
+      <xsl:variable name="StrokeDashArray" select="substring-after(@style, 'stroke-dasharray:')" />
+      <xsl:choose>
+        <xsl:when test="contains($StrokeDashArray, ';')">
+          <xsl:if test="substring-before($StrokeDashArray, ';') != 'none'"><xsl:attribute name="StrokeDashArray"><xsl:value-of select="substring-before($StrokeDashArray, ';')" /></xsl:attribute></xsl:if>
+        </xsl:when>
+        <xsl:when test="$StrokeDashArray != 'none'"><xsl:attribute name="StrokeDashArray"><xsl:value-of select="$StrokeDashArray" /></xsl:attribute></xsl:when>
+      </xsl:choose>
+    </xsl:when>
+    <xsl:when test="name(..) = 'g' or name(..) = 'svg'"><xsl:apply-templates mode="stroke_dasharray" select="parent::*"/></xsl:when>
+  </xsl:choose>
+</xsl:template>
+
+<!-- Stroke dashoffset -->
+<xsl:template mode="stroke_dashoffset" match="*">
+  <xsl:choose>
+    <xsl:when test="@stroke-dashoffset"><xsl:attribute name="StrokeDashOffset"><xsl:value-of select="@stroke-dashoffset" /></xsl:attribute></xsl:when>
+    <xsl:when test="@style and contains(@style, 'stroke-dashoffset:')">
+      <xsl:variable name="StrokeDashOffset" select="substring-after(@style, 'stroke-dashoffset:')" />
+      <xsl:attribute name="StrokeDashOffset">
+        <xsl:choose>
+          <xsl:when test="contains($StrokeDashOffset, ';')"><xsl:value-of select="substring-before($StrokeDashOffset, ';')" /></xsl:when>
+          <xsl:otherwise><xsl:value-of select="$StrokeDashOffset" /></xsl:otherwise>
+        </xsl:choose>
+      </xsl:attribute>
+    </xsl:when>
+    <xsl:when test="name(..) = 'g' or name(..) = 'svg'"><xsl:apply-templates mode="stroke_dashoffset" select="parent::*"/></xsl:when>
+  </xsl:choose>
+</xsl:template>
+
+<!-- Linejoin SVG to XAML converter -->
+<xsl:template name="linejoin_svg_to_xaml">
+  <xsl:param name="linejoin" />
+  <xsl:choose>
+    <xsl:when test="$linejoin = 'bevel'">Bevel</xsl:when>
+    <xsl:when test="$linejoin = 'round'">Round</xsl:when>
+    <xsl:otherwise>Miter</xsl:otherwise>
+  </xsl:choose>
+</xsl:template>
+
+<!-- Stroke linejoin -->
+<xsl:template mode="stroke_linejoin" match="*">
+  <xsl:choose>
+    <xsl:when test="@stroke-miterlimit">
+      <xsl:attribute name="StrokeLineJoin">
+        <xsl:call-template name="linejoin_svg_to_xaml"><xsl:with-param name="linejoin"><xsl:value-of select="@stroke-linejoin" /></xsl:with-param></xsl:call-template>
+      </xsl:attribute></xsl:when>
+    <xsl:when test="@style and contains(@style, 'stroke-linejoin:')">
+      <xsl:variable name="StrokeLineJoin" select="substring-after(@style, 'stroke-linejoin:')" />
+      <xsl:attribute name="StrokeLineJoin">
+        <xsl:choose>
+          <xsl:when test="contains($StrokeLineJoin, ';')">
+            <xsl:call-template name="linejoin_svg_to_xaml"><xsl:with-param name="linejoin"><xsl:value-of select="substring-before($StrokeLineJoin, ';')" /></xsl:with-param></xsl:call-template>
+          </xsl:when>
+          <xsl:otherwise>
+            <xsl:call-template name="linejoin_svg_to_xaml"><xsl:with-param name="linejoin"><xsl:value-of select="$StrokeLineJoin" /></xsl:with-param></xsl:call-template>
+          </xsl:otherwise>
+        </xsl:choose>
+      </xsl:attribute>
+    </xsl:when>
+    <xsl:when test="name(..) = 'g' or name(..) = 'svg'"><xsl:apply-templates mode="stroke_linejoin" select="parent::*"/></xsl:when>
+  </xsl:choose>
+</xsl:template>
+
+<!-- Linecap SVG to XAML converter -->
+<xsl:template name="linecap_svg_to_xaml">
+  <xsl:param name="linecap" />
+  <xsl:choose>
+    <xsl:when test="$linecap = 'round'">Round</xsl:when>
+    <xsl:when test="$linecap = 'square'">Square</xsl:when>
+    <xsl:otherwise>Flat</xsl:otherwise>
+  </xsl:choose>
+</xsl:template>
+
+<!-- Stroke linecap -->
+<xsl:template mode="stroke_linecap" match="*">
+  <xsl:choose>
+    <xsl:when test="@stroke-linecap">
+      <xsl:attribute name="StrokeStartLineCap">
+        <xsl:call-template name="linecap_svg_to_xaml"><xsl:with-param name="linecap"><xsl:value-of select="@stroke-linecap" /></xsl:with-param></xsl:call-template>
+      </xsl:attribute>
+      <xsl:attribute name="StrokeEndLineCap">
+        <xsl:call-template name="linecap_svg_to_xaml"><xsl:with-param name="linecap"><xsl:value-of select="@stroke-linecap" /></xsl:with-param></xsl:call-template>
+      </xsl:attribute></xsl:when>
+    <xsl:when test="@style and contains(@style, 'stroke-linecap:')">
+      <xsl:variable name="StrokeStartLineCap" select="substring-after(@style, 'stroke-linecap:')" />
+      <xsl:variable name="StrokeEndLineCap" select="substring-after(@style, 'stroke-linecap:')" />
+      <xsl:attribute name="StrokeStartLineCap">
+        <xsl:choose>
+          <xsl:when test="contains($StrokeStartLineCap, ';')">
+            <xsl:call-template name="linecap_svg_to_xaml"><xsl:with-param name="linecap"><xsl:value-of select="substring-before($StrokeStartLineCap, ';')" /></xsl:with-param></xsl:call-template>
+          </xsl:when>
+          <xsl:otherwise>
+            <xsl:call-template name="linecap_svg_to_xaml"><xsl:with-param name="linecap"><xsl:value-of select="$StrokeStartLineCap" /></xsl:with-param></xsl:call-template>
+          </xsl:otherwise>
+        </xsl:choose>
+      </xsl:attribute>
+      <xsl:attribute name="StrokeEndLineCap">
+        <xsl:choose>
+          <xsl:when test="contains($StrokeEndLineCap, ';')">
+            <xsl:call-template name="linecap_svg_to_xaml"><xsl:with-param name="linecap"><xsl:value-of select="substring-before($StrokeEndLineCap, ';')" /></xsl:with-param></xsl:call-template>
+          </xsl:when>
+          <xsl:otherwise>
+            <xsl:call-template name="linecap_svg_to_xaml"><xsl:with-param name="linecap"><xsl:value-of select="$StrokeEndLineCap" /></xsl:with-param></xsl:call-template>
+          </xsl:otherwise>
+        </xsl:choose>
+      </xsl:attribute>
+    </xsl:when>
+    <xsl:when test="name(..) = 'g' or name(..) = 'svg'"><xsl:apply-templates mode="stroke_linecap" select="parent::*"/></xsl:when>
+  </xsl:choose>
+</xsl:template>
+
+<!-- Gradient stops -->
+<xsl:template mode="stop_color" match="*">
+  <xsl:variable name="Opacity">
+    <xsl:choose>
+      <xsl:when test="@stop-opacity"><xsl:value-of select="@stop-opacity" /></xsl:when>
+      <xsl:when test="@style and contains(@style, 'stop-opacity:')">
+        <xsl:variable name="temp_opacity" select="substring-after(@style, 'stop-opacity:')" />
+        <xsl:choose>
+          <xsl:when test="contains($temp_opacity, ';')"><xsl:value-of select="substring-before($temp_opacity, ';')" /></xsl:when>
+          <xsl:otherwise><xsl:value-of select="$temp_opacity" /></xsl:otherwise>
+        </xsl:choose>
+      </xsl:when>
+      <xsl:otherwise><xsl:value-of select="''" /></xsl:otherwise>
+    </xsl:choose>
+  </xsl:variable>
+  <xsl:variable name="hex_opacity">
+    <xsl:choose>
+      <xsl:when test="$Opacity != ''"><xsl:call-template name="to_hex"><xsl:with-param name="convert"><xsl:value-of select="number($Opacity) * 255" /></xsl:with-param></xsl:call-template>  </xsl:when>
+      <xsl:otherwise><xsl:value-of select="$Opacity" /></xsl:otherwise>
+    </xsl:choose>
+  </xsl:variable>
+  <xsl:variable name="stopcolor">
+    <xsl:choose>
+      <xsl:when test="@stop-color">
+        <xsl:call-template name="template_color"><xsl:with-param name="colorspec"><xsl:value-of select="@stop-color" /></xsl:with-param></xsl:call-template>
+      </xsl:when>
+      <xsl:when test="@style and contains(@style, 'stop-color:')">
+        <xsl:variable name="Color" select="substring-after(@style, 'stop-color:')" />
+        <xsl:choose>
+          <xsl:when test="contains($Color, ';')">
+            <xsl:call-template name="template_color"><xsl:with-param name="colorspec"><xsl:value-of select="substring-before($Color, ';')" /></xsl:with-param></xsl:call-template>
+          </xsl:when>
+          <xsl:otherwise>
+            <xsl:call-template name="template_color"><xsl:with-param name="colorspec"><xsl:value-of select="$Color" /></xsl:with-param></xsl:call-template>
+          </xsl:otherwise>
+        </xsl:choose>
+      </xsl:when>
+      <xsl:when test="name(..) = 'g' or name(..) = 'svg'"><xsl:apply-templates mode="stop_color" select="parent::*"/></xsl:when>
+      <xsl:otherwise>#000</xsl:otherwise>
+    </xsl:choose>
+  </xsl:variable>
+  <xsl:attribute name="Color">
+    <xsl:choose>
+      <xsl:when test="$hex_opacity != '' and starts-with($stopcolor, '#')"><xsl:value-of select="concat('#', $hex_opacity, substring-after($stopcolor, '#'))" /></xsl:when>
+      <xsl:otherwise><xsl:value-of select="$stopcolor" /></xsl:otherwise>
+    </xsl:choose>
+  </xsl:attribute>
+</xsl:template>
+
+<!-- Gradient stop opacity -->
+<xsl:template mode="stop_opacity" match="*">
+  <xsl:choose>
+    <xsl:when test="@stop-opacity"><xsl:attribute name="Opacity"><xsl:value-of select="@stop-opacity" /></xsl:attribute></xsl:when>
+    <xsl:when test="@style and contains(@style, 'stop-opacity:')">
+      <xsl:variable name="Opacity" select="substring-after(@style, 'stop-opacity:')" />
+      <xsl:attribute name="Opacity">
+        <xsl:choose>
+          <xsl:when test="contains($Opacity, ';')"><xsl:value-of select="substring-before($Opacity, ';')" /></xsl:when>
+          <xsl:otherwise><xsl:value-of select="$Opacity" /></xsl:otherwise>
+        </xsl:choose>
+      </xsl:attribute>
+    </xsl:when>
+    <xsl:when test="name(..) = 'g' or name(..) = 'svg'"><xsl:apply-templates mode="stop_opacity" select="parent::*"/></xsl:when>
+  </xsl:choose>
+</xsl:template>
+
+<!-- Gradient stop offset -->
+<xsl:template mode="offset" match="*">
+  <xsl:choose>
+    <xsl:when test="@offset">
+      <xsl:attribute name="Offset">
+        <xsl:choose>
+          <xsl:when test="contains(@offset, '%')"><xsl:value-of select="number(substring-before(@offset, '%')) div 100" /></xsl:when>
+          <xsl:otherwise><xsl:value-of select="@offset" /></xsl:otherwise>
+        </xsl:choose>
+      </xsl:attribute>
+    </xsl:when>
+    <xsl:when test="@style and contains(@style, 'offset:')">
+      <xsl:variable name="Offset" select="substring-after(@style, 'offset:')" />
+      <xsl:attribute name="Offset">
+        <xsl:choose>
+          <xsl:when test="contains($Offset, '%')"><xsl:value-of select="number(substring-before($Offset, '%')) div 100" /></xsl:when>        
+          <xsl:when test="contains($Offset, ';')"><xsl:value-of select="substring-before($Offset, ';')" /></xsl:when>
+          <xsl:otherwise><xsl:value-of select="$Offset" /></xsl:otherwise>
+        </xsl:choose>
+      </xsl:attribute>
+    </xsl:when>
+    <xsl:when test="name(..) = 'g' or name(..) = 'svg'"><xsl:apply-templates mode="stop_offset" select="parent::*"/></xsl:when>
+  </xsl:choose>
+</xsl:template>
+
+<!-- 
+// Transforms //
+All the matrix, translate, rotate... stuff.
+Fixme: XAML transforms don't show the same result as SVG ones with the same values.
+
+* Parse transform
+* Apply transform
+* Apply transform v2
+-->
+
+<!-- Parse transform -->
+<xsl:template name="parse_transform">
+  <xsl:param name="input" />
+  <xsl:choose>
+    <xsl:when test="starts-with($input, 'matrix(')">
+      <MatrixTransform><xsl:attribute name="Matrix"><xsl:value-of select="substring-before(substring-after($input, 'matrix('), ')')" /></xsl:attribute></MatrixTransform>
+      <xsl:call-template name="parse_transform"><xsl:with-param name="input" select="substring-after($input, ') ')" /></xsl:call-template>      
+    </xsl:when>
+    <xsl:when test="starts-with($input, 'scale(')">
+      <ScaleTransform>
+        <xsl:variable name="scale" select="substring-before(substring-after($input, 'scale('), ')')" />
+        <xsl:choose>
+          <xsl:when test="contains($scale, ',')">
+            <xsl:attribute name="ScaleX"><xsl:value-of select="substring-before($scale, ',')" /></xsl:attribute>
+            <xsl:attribute name="ScaleY"><xsl:value-of select="substring-after($scale, ',')" /></xsl:attribute>
+          </xsl:when>
+          <xsl:otherwise>
+            <xsl:attribute name="ScaleX"><xsl:value-of select="$scale" /></xsl:attribute>
+            <xsl:attribute name="ScaleY"><xsl:value-of select="$scale" /></xsl:attribute>
+          </xsl:otherwise>
+        </xsl:choose>
+      </ScaleTransform>
+      <xsl:call-template name="parse_transform"><xsl:with-param name="input" select="substring-after($input, ') ')" /></xsl:call-template>
+    </xsl:when>
+    <xsl:when test="starts-with($input, 'rotate(')">
+      <RotateTransform>
+        <xsl:attribute name="Angle"><xsl:value-of select="substring-before(substring-after($input, 'rotate('), ')')" /></xsl:attribute>
+        <xsl:if test="@rx"><xsl:attribute name="CenterX"><xsl:value-of select="@rx" /></xsl:attribute></xsl:if>
+        <xsl:if test="@ry"><xsl:attribute name="CenterY"><xsl:value-of select="@ry" /></xsl:attribute></xsl:if>
+      </RotateTransform>
+      <xsl:call-template name="parse_transform"><xsl:with-param name="input" select="substring-after($input, ') ')" /></xsl:call-template>
+    </xsl:when>
+    <xsl:when test="starts-with($input, 'skewX(')">
+      <SkewTransform>
+        <xsl:attribute name="AngleX"><xsl:value-of select="substring-before(substring-after($input, 'skewX('), ')')" /></xsl:attribute>
+        <xsl:call-template name="parse_transform"><xsl:with-param name="input" select="substring-after($input, ') ')" /></xsl:call-template>
+      </SkewTransform>
+    </xsl:when>
+    <xsl:when test="starts-with($input, 'skewY(')">
+      <SkewTransform>
+        <xsl:attribute name="AngleY"><xsl:value-of select="substring-before(substring-after($input, 'skewY('), ')')" /></xsl:attribute>
+        <xsl:call-template name="parse_transform"><xsl:with-param name="input" select="substring-after($input, ') ')" /></xsl:call-template>
+      </SkewTransform>
+    </xsl:when>
+    <xsl:when test="starts-with($input, 'translate(')">
+      <TranslateTransform>
+        <xsl:variable name="translate" select="substring-before(substring-after($input, 'translate('), ')')" />
+        <xsl:choose>
+          <xsl:when test="contains($translate, ',')">
+            <xsl:attribute name="X"><xsl:value-of select="substring-before($translate, ',')" /></xsl:attribute>
+            <xsl:attribute name="Y"><xsl:value-of select="substring-after($translate, ',')" /></xsl:attribute>
+          </xsl:when>
+          <xsl:when test="contains($translate, ' ')">
+            <xsl:attribute name="X"><xsl:value-of select="substring-before($translate, ' ')" /></xsl:attribute>
+            <xsl:attribute name="Y"><xsl:value-of select="substring-after($translate, ' ')" /></xsl:attribute>
+          </xsl:when>
+          <xsl:otherwise><xsl:attribute name="X"><xsl:value-of select="$translate" /></xsl:attribute></xsl:otherwise>
+        </xsl:choose>
+      </TranslateTransform>
+      <xsl:call-template name="parse_transform"><xsl:with-param name="input" select="substring-after($input, ') ')" /></xsl:call-template>
+    </xsl:when>
+  </xsl:choose>
+</xsl:template>
+
+<!-- Apply transform -->
+<xsl:template mode="transform" match="*">
+  <xsl:param name="mapped_type" />
+  <xsl:if test="@transform or @gradientTransform">
+  <xsl:variable name="transform">
+    <xsl:choose>
+       <xsl:when test="@transform"><xsl:value-of select="@transform" /></xsl:when>
+       <xsl:otherwise><xsl:value-of select="@gradientTransform" /></xsl:otherwise>
+    </xsl:choose>
+  </xsl:variable>
+  <xsl:variable name="transform_nodes">
+    <xsl:call-template name="parse_transform">
+      <xsl:with-param name="input" select="$transform" />
+    </xsl:call-template>
+  </xsl:variable>
+
+  <xsl:comment>
+    <xsl:value-of select="name(.)" />
+  </xsl:comment>
+
+  <xsl:choose>
+    <xsl:when test="$mapped_type and $mapped_type != ''">
+      <xsl:element name="{$mapped_type}.RenderTransform">
+        <xsl:choose>
+          <xsl:when test="count(libxslt:node-set($transform_nodes)/*) = 1"><xsl:copy-of select="libxslt:node-set($transform_nodes)" /></xsl:when>
+          <xsl:when test="count(libxslt:node-set($transform_nodes)/*) &gt; 1"><TransformGroup><xsl:copy-of select="libxslt:node-set($transform_nodes)" /></TransformGroup></xsl:when>
+        </xsl:choose>
+      </xsl:element>
+    </xsl:when>
+    <xsl:otherwise>
+      <!-- For instance LinearGradient.Transform -->
+      <xsl:choose>
+          <xsl:when test="count(libxslt:node-set($transform_nodes)/*) = 1"><xsl:copy-of select="libxslt:node-set($transform_nodes)" /></xsl:when>
+          <xsl:when test="count(libxslt:node-set($transform_nodes)/*) &gt; 1"><TransformGroup><xsl:copy-of select="libxslt:node-set($transform_nodes)" /></TransformGroup></xsl:when>
+      </xsl:choose>
+    </xsl:otherwise>
+  </xsl:choose>
+  </xsl:if>  
+</xsl:template>
+
+<!-- Apply transform v2
+Fixme: is this template still in use? -->
+<xsl:template mode="transform2" match="*">
+  <xsl:choose>
+    <xsl:when test="@transform">
+      <Canvas>
+        <Canvas.RenderTransform>
+          <TransformGroup><xsl:apply-templates mode="transform" select="." /></TransformGroup>
+        </Canvas.RenderTransform>
+        <xsl:apply-templates mode="forward" select="." />
+      </Canvas>
+    </xsl:when>
+    <xsl:otherwise>
+      <xsl:apply-templates mode="forward" select="." />
+    </xsl:otherwise>
+  </xsl:choose>
+</xsl:template>
+
+<!-- 
+// Objects //
+
+* Image
+* Text
+* Lines
+* Rectangle
+* Polygon
+* Polyline
+* Path
+* Ellipse
+* Circle
+-->
+
+<!-- Image -->
+<xsl:template mode="forward" match="*[name(.) = 'image']">
+  <Image>
+    <xsl:apply-templates mode="id" select="." />
+    <xsl:if test="@x"><xsl:attribute name="Canvas.Left">
+       <xsl:call-template name="convert_unit">
+            <xsl:with-param name="convert_value" select="@x" />
+        </xsl:call-template>
+    </xsl:attribute></xsl:if>
+    <xsl:if test="@y"><xsl:attribute name="Canvas.Top">
+       <xsl:call-template name="convert_unit">
+           <xsl:with-param name="convert_value" select="@y" />
+       </xsl:call-template>
+    </xsl:attribute></xsl:if>
+    <xsl:apply-templates mode="desc" select="." />
+    <xsl:apply-templates mode="clip" select="." />
+    <xsl:if test="@xlink:href"><xsl:attribute name="Source"><xsl:value-of select="@xlink:href" /></xsl:attribute></xsl:if>
+    <xsl:if test="@width"><xsl:attribute name="Width">
+        <xsl:call-template name="convert_unit">
+            <xsl:with-param name="convert_value" select="@width" />
+        </xsl:call-template>
+    </xsl:attribute></xsl:if>
+    <xsl:if test="@height"><xsl:attribute name="Height">
+        <xsl:call-template name="convert_unit">
+            <xsl:with-param name="convert_value" select="@height" />
+        </xsl:call-template>
+    </xsl:attribute></xsl:if>
+    <xsl:apply-templates mode="transform" select=".">
+      <xsl:with-param name="mapped_type" select="'Image'" />
+    </xsl:apply-templates>
+    <!--xsl:apply-templates mode="transform" /-->
+    <xsl:apply-templates mode="forward" />
+  </Image>
+</xsl:template>
+
+<!-- Text -->
+<xsl:template mode="forward" match="*[name(.) = 'text']">
+  <TextBlock>
+    <xsl:if test="@font-size"><xsl:attribute name="FontSize"><xsl:value-of select="@font-size" /></xsl:attribute></xsl:if>
+    <xsl:if test="@style and contains(@style, 'font-size:')">
+      <xsl:variable name="font_size" select="substring-after(@style, 'font-size:')" />
+      <xsl:attribute name="FontSize">
+        <xsl:choose>
+          <xsl:when test="contains($font_size, ';')">
+            <xsl:value-of select="substring-before($font_size, ';')" />
+          </xsl:when>
+          <xsl:otherwise><xsl:value-of select="$font_size" /></xsl:otherwise>
+        </xsl:choose>
+      </xsl:attribute>
+    </xsl:if>
+    <xsl:if test="@font-weight"><xsl:attribute name="FontWeight"><xsl:value-of select="@font-weight" /></xsl:attribute></xsl:if>
+    <xsl:if test="@style and contains(@style, 'font-weight:')">
+      <xsl:variable name="font_weight" select="substring-after(@style, 'font-weight:')" />
+      <xsl:attribute name="FontWeight">
+        <xsl:choose>
+          <xsl:when test="contains($font_weight, ';')">
+            <xsl:value-of select="substring-before($font_weight, ';')" />
+          </xsl:when>
+          <xsl:otherwise><xsl:value-of select="$font_weight" /></xsl:otherwise>
+        </xsl:choose>
+      </xsl:attribute>
+    </xsl:if>
+    <xsl:if test="@font-family"><xsl:attribute name="FontFamily"><xsl:value-of select="@font-family" /></xsl:attribute></xsl:if>
+    <xsl:if test="@style and contains(@style, 'font-family:')">
+      <xsl:variable name="font_family" select="substring-after(@style, 'font-family:')" />
+      <xsl:attribute name="FontFamily">
+        <xsl:choose>
+          <xsl:when test="contains($font_family, ';')">
+            <xsl:value-of select="substring-before($font_family, ';')" />
+          </xsl:when>
+          <xsl:otherwise><xsl:value-of select="$font_family" /></xsl:otherwise>
+        </xsl:choose>
+      </xsl:attribute>
+    </xsl:if>
+    <xsl:if test="@font-style"><xsl:attribute name="FontStyle"><xsl:value-of select="@font-style" /></xsl:attribute></xsl:if>
+    <xsl:if test="@style and contains(@style, 'font-style:')">
+      <xsl:variable name="font_style" select="substring-after(@style, 'font-style:')" />
+      <xsl:attribute name="FontStyle">
+        <xsl:choose>
+          <xsl:when test="contains($font_style, ';')">
+            <xsl:value-of select="substring-before($font_style, ';')" />
+          </xsl:when>
+          <xsl:otherwise><xsl:value-of select="$font_style" /></xsl:otherwise>
+        </xsl:choose>
+      </xsl:attribute>
+    </xsl:if>
+    <xsl:if test="@fill"><xsl:attribute name="Foreground"><xsl:value-of select="@fill" /></xsl:attribute></xsl:if>
+    <xsl:if test="@style and contains(@style, 'fill')">
+      <xsl:variable name="fill" select="substring-after(@style, 'fill:')" />
+      <xsl:attribute name="Foreground">
+        <xsl:choose>
+          <xsl:when test="contains($fill, ';')">
+            <xsl:value-of select="substring-before($fill, ';')" />
+          </xsl:when>
+          <xsl:otherwise><xsl:value-of select="$fill" /></xsl:otherwise>
+        </xsl:choose>
+      </xsl:attribute>
+    </xsl:if>
+    <xsl:if test="@text-anchor">
+      <xsl:attribute name="HorizontalAlignment">
+        <xsl:choose>
+          <xsl:when test="@text-anchor = 'start'">Left</xsl:when>
+          <xsl:when test="@text-anchor = 'middle'">Center</xsl:when>
+          <xsl:when test="@text-anchor = 'end'">Right</xsl:when>
+        </xsl:choose>
+      </xsl:attribute>
+    </xsl:if>
+    <xsl:if test="@width"><xsl:attribute name="Width">
+        <xsl:call-template name="convert_unit">
+            <xsl:with-param name="convert_value" select="@width" />
+        </xsl:call-template>
+    </xsl:attribute></xsl:if>
+    <xsl:if test="@height"><xsl:attribute name="Height">
+        <xsl:call-template name="convert_unit">
+            <xsl:with-param name="convert_value" select="@height" />
+        </xsl:call-template>
+    </xsl:attribute></xsl:if>
+    <xsl:if test="@x"><xsl:attribute name="Canvas.Left">
+       <xsl:call-template name="convert_unit">
+            <xsl:with-param name="convert_value" select="@x" />
+        </xsl:call-template>
+    </xsl:attribute></xsl:if>
+    <xsl:if test="@y"><xsl:attribute name="Canvas.Top">
+       <xsl:call-template name="convert_unit">
+           <xsl:with-param name="convert_value" select="@y" />
+       </xsl:call-template>
+    </xsl:attribute></xsl:if>
+    <xsl:apply-templates mode="id" select="." />
+    <xsl:apply-templates mode="filter_effect" select="." />
+    <xsl:apply-templates mode="desc" select="." />
+    <xsl:apply-templates mode="clip" select="." />
+    <!--xsl:apply-templates mode="transform" select="." /-->
+    <!--xsl:apply-templates mode="forward" /-->
+    <xsl:if test="text()"><xsl:value-of select="text()" /></xsl:if>
+    <xsl:if test="*[name(.) = 'tspan']/text()"><xsl:value-of select="*[name(.) = 'tspan']/text()" /></xsl:if>
+  </TextBlock>
+</xsl:template>
+<!-- Lines -->
+<xsl:template mode="forward" match="*[name(.) = 'line']">
+  <Line>
+    <xsl:if test="@x1"><xsl:attribute name="X1"><xsl:value-of select="@x1" /></xsl:attribute></xsl:if> 
+    <xsl:if test="@y1"><xsl:attribute name="Y1"><xsl:value-of select="@y1" /></xsl:attribute></xsl:if> 
+    <xsl:if test="@x2"><xsl:attribute name="X2"><xsl:value-of select="@x2" /></xsl:attribute></xsl:if> 
+    <xsl:if test="@y2"><xsl:attribute name="Y2"><xsl:value-of select="@y2" /></xsl:attribute></xsl:if>
+    <xsl:apply-templates mode="id" select="." />
+    <xsl:apply-templates mode="template_fill" select="." />
+    <xsl:apply-templates mode="template_stroke" select="." />
+    <xsl:apply-templates mode="stroke_width" select="." />
+    <xsl:apply-templates mode="stroke_miterlimit" select="." />
+    <xsl:apply-templates mode="stroke_dasharray" select="." />
+    <xsl:apply-templates mode="stroke_dashoffset" select="." />
+    <xsl:apply-templates mode="stroke_linejoin" select="." />
+    <xsl:apply-templates mode="stroke_linecap" select="." />
+    <xsl:apply-templates mode="filter_effect" select="." />
+    <xsl:apply-templates mode="desc" select="." />
+
+    <xsl:apply-templates mode="transform" select=".">
+      <xsl:with-param name="mapped_type" select="'Line'" />
+    </xsl:apply-templates>    
+
+    <xsl:apply-templates mode="forward" />
+  </Line>
+</xsl:template>
+
+<!-- Rectangle -->
+<xsl:template mode="forward" match="*[name(.) = 'rect']">
+  <Rectangle>
+    <xsl:if test="@x"><xsl:attribute name="Canvas.Left">
+       <xsl:call-template name="convert_unit">
+            <xsl:with-param name="convert_value" select="@x" />
+        </xsl:call-template>
+    </xsl:attribute></xsl:if>
+    <xsl:if test="@y"><xsl:attribute name="Canvas.Top">
+       <xsl:call-template name="convert_unit">
+           <xsl:with-param name="convert_value" select="@y" />
+       </xsl:call-template>
+    </xsl:attribute></xsl:if>
+    <xsl:if test="@width"><xsl:attribute name="Width">
+        <xsl:call-template name="convert_unit">
+            <xsl:with-param name="convert_value" select="@width" />
+        </xsl:call-template>
+    </xsl:attribute></xsl:if>
+    <xsl:if test="@height"><xsl:attribute name="Height">
+        <xsl:call-template name="convert_unit">
+            <xsl:with-param name="convert_value" select="@height" />
+        </xsl:call-template>
+    </xsl:attribute></xsl:if>
+    <xsl:if test="@rx"><xsl:attribute name="RadiusX"><xsl:value-of select="@rx" /></xsl:attribute></xsl:if>
+    <xsl:if test="@ry"><xsl:attribute name="RadiusY"><xsl:value-of select="@ry" /></xsl:attribute></xsl:if>
+    <xsl:if test="@rx and not(@ry)"><xsl:attribute name="RadiusX"><xsl:value-of select="@rx" /></xsl:attribute><xsl:attribute name="RadiusY"><xsl:value-of select="@rx" /></xsl:attribute></xsl:if>
+    <xsl:if test="@ry and not(@rx)"><xsl:attribute name="RadiusX"><xsl:value-of select="@ry" /></xsl:attribute><xsl:attribute name="RadiusY"><xsl:value-of select="@ry" /></xsl:attribute></xsl:if>
+
+    <xsl:apply-templates mode="id" select="." />
+    <xsl:apply-templates mode="template_fill" select="." />
+    <xsl:apply-templates mode="template_stroke" select="." />
+    <xsl:apply-templates mode="stroke_width" select="." />
+    <xsl:apply-templates mode="stroke_miterlimit" select="." />
+    <xsl:apply-templates mode="stroke_dasharray" select="." />
+    <xsl:apply-templates mode="stroke_dashoffset" select="." />
+    <xsl:apply-templates mode="stroke_linejoin" select="." />
+    <xsl:apply-templates mode="stroke_linecap" select="." />
+    <xsl:apply-templates mode="filter_effect" select="." />
+    <xsl:apply-templates mode="resources" select="." />
+    <xsl:apply-templates mode="desc" select="." />
+    <xsl:apply-templates mode="clip" select="." />
+
+    <xsl:apply-templates mode="transform" select=".">
+      <xsl:with-param name="mapped_type" select="'Rectangle'" />
+    </xsl:apply-templates>
+
+    <xsl:apply-templates mode="forward" />
+  </Rectangle>
+</xsl:template>
+
+<!-- Polygon -->
+<xsl:template mode="forward" match="*[name(.) = 'polygon']">
+  <Polygon>
+    <xsl:if test="@points"><xsl:attribute name="Points"><xsl:value-of select="@points" /></xsl:attribute></xsl:if>
+    <xsl:apply-templates mode="id" select="." />
+    <xsl:apply-templates mode="fill_rule" select="." />
+    <xsl:apply-templates mode="template_fill" select="." />
+    <xsl:apply-templates mode="template_stroke" select="." />
+    <xsl:apply-templates mode="stroke_width" select="." />
+    <xsl:apply-templates mode="stroke_miterlimit" select="." />
+    <xsl:apply-templates mode="stroke_dasharray" select="." />
+    <xsl:apply-templates mode="stroke_dashoffset" select="." />
+    <xsl:apply-templates mode="stroke_linejoin" select="." />
+    <xsl:apply-templates mode="stroke_linecap" select="." />
+    <xsl:apply-templates mode="filter_effect" select="." />
+    <xsl:apply-templates mode="desc" select="." />
+
+    <xsl:apply-templates mode="transform" select=".">
+      <xsl:with-param name="mapped_type" select="'Polygon'" />
+    </xsl:apply-templates>
+
+    <xsl:apply-templates mode="forward" />
+  </Polygon>
+</xsl:template>
+
+<!-- Polyline -->
+<xsl:template mode="forward" match="*[name(.) = 'polyline']">
+  <Polyline>
+    <xsl:if test="@points"><xsl:attribute name="Points"><xsl:value-of select="@points" /></xsl:attribute></xsl:if>
+    <xsl:apply-templates mode="id" select="." />
+    <xsl:apply-templates mode="fill_rule" select="." />
+    <xsl:apply-templates mode="template_fill" select="." />
+    <xsl:apply-templates mode="template_stroke" select="." />
+    <xsl:apply-templates mode="stroke_width" select="." />
+    <xsl:apply-templates mode="stroke_miterlimit" select="." />
+    <xsl:apply-templates mode="stroke_dasharray" select="." />
+    <xsl:apply-templates mode="stroke_dashoffset" select="." />
+    <xsl:apply-templates mode="stroke_linejoin" select="." />
+    <xsl:apply-templates mode="stroke_linecap" select="." />
+    <xsl:apply-templates mode="filter_effect" select="." />
+    <xsl:apply-templates mode="desc" select="." />
+
+    <xsl:apply-templates mode="transform" select=".">
+      <xsl:with-param name="mapped_type" select="'Polyline'" />
+    </xsl:apply-templates>
+
+    <xsl:apply-templates mode="forward" />
+  </Polyline>
+</xsl:template>
+
+<!-- Path -->
+<xsl:template mode="forward" match="*[name(.) = 'path']">
+  <Path>
+    <xsl:apply-templates mode="id" select="." />
+    <xsl:apply-templates mode="template_fill" select="." />
+    <xsl:apply-templates mode="template_stroke" select="." />
+    <xsl:apply-templates mode="stroke_width" select="." />
+    <xsl:apply-templates mode="stroke_miterlimit" select="." />
+    <xsl:apply-templates mode="stroke_dasharray" select="." />
+    <xsl:apply-templates mode="stroke_dashoffset" select="." />
+    <xsl:apply-templates mode="stroke_linejoin" select="." />
+    <xsl:apply-templates mode="stroke_linecap" select="." />
+    <xsl:apply-templates mode="filter_effect" select="." />
+    <xsl:apply-templates mode="desc" select="." />
+
+    <xsl:if test="@d">
+      <xsl:choose>
+        <xsl:when test="$silverlight_compatible = 1">
+          <xsl:attribute name="Data">
+           <xsl:value-of select="translate(@d , ',', ' ')" />
+          </xsl:attribute>
+        </xsl:when>
+        <xsl:otherwise>
+          <Path.Data>
+            <PathGeometry>
+              <xsl:attribute name="Figures">
+                <xsl:value-of select="translate(@d , ',', ' ')" />
+              </xsl:attribute>
+              <xsl:apply-templates mode="fill_rule" select="." />
+            </PathGeometry>
+          </Path.Data>
+         </xsl:otherwise>
+      </xsl:choose>
+    </xsl:if>
+
+    <xsl:apply-templates mode="transform" select=".">
+      <xsl:with-param name="mapped_type" select="'Path'" />
+    </xsl:apply-templates>
+
+    <xsl:apply-templates mode="forward" />
+  </Path>
+</xsl:template>
+
+<!-- Ellipse -->
+<xsl:template mode="forward" match="*[name(.) = 'ellipse']">
+  <Ellipse>
+    <xsl:variable name="cx">
+      <xsl:choose>
+        <xsl:when test="@cx"><xsl:value-of select="@cx" /></xsl:when>
+        <xsl:otherwise>0</xsl:otherwise>
+      </xsl:choose>
+    </xsl:variable>
+    <xsl:variable name="cy">
+      <xsl:choose>
+        <xsl:when test="@cy"><xsl:value-of select="@cy" /></xsl:when>
+        <xsl:otherwise>0</xsl:otherwise>
+      </xsl:choose>
+    </xsl:variable>
+    <xsl:if test="@rx">
+      <xsl:attribute name="Canvas.Left"><xsl:value-of select='format-number($cx - @rx, "#.#")' /></xsl:attribute>
+      <xsl:attribute name="Width"><xsl:value-of select='format-number(2 * @rx, "#.#")' /></xsl:attribute>
+    </xsl:if>
+    <xsl:if test="@ry">
+      <xsl:attribute name="Canvas.Top"><xsl:value-of select='format-number($cy - @ry, "#.#")' /></xsl:attribute>
+      <xsl:attribute name="Height"><xsl:value-of select='format-number(2 * @ry, "#.#")' /></xsl:attribute>
+    </xsl:if>
+    <xsl:apply-templates mode="id" select="." />
+    <xsl:apply-templates mode="template_fill" select="." />
+    <xsl:apply-templates mode="template_stroke" select="." />
+    <xsl:apply-templates mode="stroke_width" select="." />
+    <xsl:apply-templates mode="stroke_miterlimit" select="." />
+    <xsl:apply-templates mode="stroke_dasharray" select="." />
+    <xsl:apply-templates mode="stroke_dashoffset" select="." />
+    <xsl:apply-templates mode="stroke_linejoin" select="." />
+    <xsl:apply-templates mode="stroke_linecap" select="." />
+    <xsl:apply-templates mode="filter_effect" select="." />
+    <xsl:apply-templates mode="desc" select="." />
+    <xsl:apply-templates mode="clip" select="." />
+
+    <xsl:apply-templates mode="transform" select=".">
+      <xsl:with-param name="mapped_type" select="'Ellipse'" />
+    </xsl:apply-templates>
+
+    <xsl:apply-templates mode="forward" />
+  </Ellipse>
+</xsl:template>
+
+<!-- Circle -->
+<xsl:template mode="forward" match="*[name(.) = 'circle']">
+  <Ellipse>
+    <xsl:variable name="cx">
+      <xsl:choose>
+        <xsl:when test="@cx"><xsl:value-of select="@cx" /></xsl:when>
+        <xsl:otherwise>0</xsl:otherwise>
+      </xsl:choose>
+    </xsl:variable>
+    <xsl:variable name="cy">
+      <xsl:choose>
+        <xsl:when test="@cy"><xsl:value-of select="@cy" /></xsl:when>
+        <xsl:otherwise>0</xsl:otherwise>
+      </xsl:choose>
+    </xsl:variable>
+    <xsl:if test="@r">
+       <xsl:attribute name="Canvas.Left"><xsl:value-of select='format-number($cx - @r, "#.#")' /></xsl:attribute>
+       <xsl:attribute name="Canvas.Top"><xsl:value-of select='format-number($cy - @r, "#.#")' /></xsl:attribute>
+       <xsl:attribute name="Width"><xsl:value-of select='format-number(2 * @r, "#.#")' /></xsl:attribute>
+       <xsl:attribute name="Height"><xsl:value-of select='format-number(2 * @r, "#.#")' /></xsl:attribute>
+    </xsl:if>
+    <xsl:apply-templates mode="id" select="." />
+    <xsl:apply-templates mode="template_fill" select="." />
+    <xsl:apply-templates mode="template_stroke" select="." />
+    <xsl:apply-templates mode="stroke_width" select="." />
+    <xsl:apply-templates mode="stroke_miterlimit" select="." />
+    <xsl:apply-templates mode="stroke_dasharray" select="." />
+    <xsl:apply-templates mode="stroke_dashoffset" select="." />
+    <xsl:apply-templates mode="stroke_linejoin" select="." />
+    <xsl:apply-templates mode="stroke_linecap" select="." />
+    <xsl:apply-templates mode="filter_effect" select="." />
+    <xsl:apply-templates mode="desc" select="." />
+    <xsl:apply-templates mode="clip" select="." />
+
+    <xsl:apply-templates mode="transform" select=".">
+      <xsl:with-param name="mapped_type" select="'Ellipse'" />
+    </xsl:apply-templates>
+
+    <xsl:apply-templates mode="forward" />
+  </Ellipse>
+</xsl:template>
+
+<!--
+// Geometry //
+* Generic clip path template
+* Geometry for circle
+* Geometry for rectangle
+-->
+
+<!-- Generic clip path template -->
+<xsl:template mode="forward" match="*[name(.) = 'clipPath']">
+  <xsl:apply-templates mode="geometry" />
+</xsl:template>
+
+<!-- Geometry for circle -->
+<xsl:template mode="geometry" match="*[name(.) = 'circle']">
+  <EllipseGeometry>
+    <xsl:if test="../@id"><xsl:attribute name="x:Key"><xsl:value-of select="../@id" /></xsl:attribute></xsl:if>
+    <xsl:if test="@cx and @cy"><xsl:attribute name="Center"><xsl:value-of select="concat(@cx, ',', @cy)" /></xsl:attribute></xsl:if>
+    <xsl:if test="@r">
+      <xsl:attribute name="RadiusX"><xsl:value-of select="@r" /></xsl:attribute>
+      <xsl:attribute name="RadiusY"><xsl:value-of select="@r" /></xsl:attribute>
+    </xsl:if>
+  </EllipseGeometry>
+</xsl:template>
+
+<!-- Geometry for rectangle -->
+<xsl:template mode="geometry" match="*[name(.) = 'rect']">
+  <RectangleGeometry>
+    <xsl:if test="../@id"><xsl:attribute name="x:Key"><xsl:value-of select="../@id" /></xsl:attribute></xsl:if>
+    <!--
+    <xsl:if test="@x"><xsl:attribute name="Canvas.Left"><xsl:value-of select="@x" /></xsl:attribute></xsl:if>
+    <xsl:if test="@y"><xsl:attribute name="Canvas.Top"><xsl:value-of select="@y" /></xsl:attribute></xsl:if>
+    <xsl:if test="@width"><xsl:attribute name="Width"><xsl:value-of select="@width" /></xsl:attribute></xsl:if>
+    <xsl:if test="@height"><xsl:attribute name="Height"><xsl:value-of select="@height" /></xsl:attribute></xsl:if>
+    <xsl:if test="@rx"><xsl:attribute name="RadiusX"><xsl:value-of select="@rx" /></xsl:attribute></xsl:if>
+    <xsl:if test="@ry"><xsl:attribute name="RadiusY"><xsl:value-of select="@ry" /></xsl:attribute></xsl:if>
+    -->
+    <xsl:attribute name="Rect"><xsl:value-of select="concat('0, 0, ', @width, ', ', @height)" /></xsl:attribute>
+  </RectangleGeometry>
+</xsl:template>
+
+</xsl:stylesheet>
index c5f1cfd75f995a34ac3da230b45463b494937a5d..8c0e4a5c9860fc118b10d298a0423ab0ba89c93b 100644 (file)
-<?xml version="1.0" encoding="UTF-8"?>\r
-\r
-<!--\r
-Copyright (c) 2005-2007 Toine de Greef (a.degreef@chello.nl)\r
-\r
-Permission is hereby granted, free of charge, to any person obtaining a copy\r
-of this software and associated documentation files (the "Software"), to deal\r
-in the Software without restriction, including without limitation the rights\r
-to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\r
-copies of the Software, and to permit persons to whom the Software is\r
-furnished to do so, subject to the following conditions:\r
-\r
-The above copyright notice and this permission notice shall be included in\r
-all copies or substantial portions of the Software.\r
-\r
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\r
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\r
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\r
-AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\r
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\r
-OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\r
-THE SOFTWARE.\r
-\r
-Version history:\r
-\r
-20070907 Initial release\r
-20070912 Removed NaN as viewBox values\r
-\r
--->\r
-\r
-<xsl:stylesheet version="1.0"\r
-xmlns:xsl="http://www.w3.org/1999/XSL/Transform"\r
-xmlns:xlink="http://www.w3.org/1999/xlink"\r
-xmlns:svg="http://www.w3.org/2000/svg"\r
-xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"\r
-xmlns:msxsl="urn:schemas-microsoft-com:xslt">\r
-<xsl:strip-space elements="*" />\r
-<xsl:output method="xml" encoding="UTF-8"/>\r
-<xsl:include href="xaml2svg/animation.xsl" />\r
-<xsl:include href="xaml2svg/brushes.xsl" />\r
-<xsl:include href="xaml2svg/canvas.xsl" />\r
-<xsl:include href="xaml2svg/geometry.xsl" />\r
-<xsl:include href="xaml2svg/properties.xsl" />\r
-<xsl:include href="xaml2svg/shapes.xsl" />\r
-<xsl:include href="xaml2svg/transform.xsl" />\r
-\r
-<xsl:template match="/">\r
-  <svg>\r
-    <xsl:attribute name="overflow">visible</xsl:attribute>\r
-    <xsl:variable name="viewBox"><xsl:apply-templates mode="boundingbox" /></xsl:variable>\r
-    <xsl:if test="system-property('xsl:vendor') = 'Microsoft' and (msxsl:node-set($viewBox)/boundingbox/@x1 != '') and (msxsl:node-set($viewBox)/boundingbox/@x2 != '') and (msxsl:node-set($viewBox)/boundingbox/@y1 != '') and (msxsl:node-set($viewBox)/boundingbox/@y2 != '')">\r
-      <xsl:attribute name="viewBox">\r
-        <xsl:value-of select="concat(msxsl:node-set($viewBox)/boundingbox/@x1, ' ')" />\r
-        <xsl:value-of select="concat(msxsl:node-set($viewBox)/boundingbox/@y1, ' ')" />\r
-        <xsl:value-of select="concat(msxsl:node-set($viewBox)/boundingbox/@x2 - msxsl:node-set($viewBox)/boundingbox/@x1, ' ')" />\r
-        <xsl:value-of select="msxsl:node-set($viewBox)/boundingbox/@y2 - msxsl:node-set($viewBox)/boundingbox/@y1" />\r
-      </xsl:attribute>\r
-    </xsl:if>  \r
-    <xsl:apply-templates mode="svg" />\r
-  </svg>\r
-</xsl:template>\r
-\r
-<xsl:template mode="forward" match="*[name(.) = 'Image']">\r
-  <xsl:if test="@Canvas.Left or @Canvas.Top"><xsl:value-of disable-output-escaping="yes" select="concat('&lt;svg x=&quot;', @Canvas.Left, '&quot; y=&quot;', @Canvas.Top, '&quot;&gt;')" /></xsl:if>\r
-  <image>\r
-    <xsl:if test="@Source"><xsl:attribute name="xlink:href"><xsl:value-of select="@Source" /></xsl:attribute></xsl:if>\r
-    <xsl:if test="@Width"><xsl:attribute name="width"><xsl:value-of select="@Width" /></xsl:attribute></xsl:if>\r
-    <xsl:if test="@Height"><xsl:attribute name="height"><xsl:value-of select="@Height" /></xsl:attribute></xsl:if>\r
-    <xsl:call-template name="template_properties" />\r
-    <xsl:call-template name="template_transform" />\r
-    <xsl:apply-templates mode="forward" />\r
-  </image>\r
-  <xsl:if test="@Canvas.Left or @Canvas.Top"><xsl:value-of disable-output-escaping="yes" select="'&lt;/svg&gt;&#13;'" /></xsl:if>\r
-</xsl:template>\r
-\r
-<xsl:template mode="forward" match="*[name(.) = 'TextBlock']">\r
-  <xsl:if test="@Canvas.Left or @Canvas.Top"><xsl:value-of disable-output-escaping="yes" select="concat('&lt;svg x=&quot;', @Canvas.Left, '&quot; y=&quot;', @Canvas.Top, '&quot;&gt;')" /></xsl:if>\r
-  <text>\r
-    <xsl:if test="@FontSize"><xsl:attribute name="font-size"><xsl:value-of select="@FontSize" /></xsl:attribute></xsl:if>\r
-    <xsl:if test="@FontWeight"><xsl:attribute name="font-weight"><xsl:value-of select="@FontWeight" /></xsl:attribute></xsl:if>\r
-    <xsl:if test="@FontFamily"><xsl:attribute name="font-family"><xsl:value-of select="@FontFamily" /></xsl:attribute></xsl:if>\r
-    <xsl:if test="@FontStyle"><xsl:attribute name="font-style"><xsl:value-of select="@FontStyle" /></xsl:attribute></xsl:if>\r
-    <xsl:if test="@Foreground"><xsl:attribute name="fill"><xsl:value-of select="@Foreground" /></xsl:attribute></xsl:if>\r
-    <xsl:if test="@Width"><xsl:attribute name="width"><xsl:value-of select="@Width" /></xsl:attribute></xsl:if>\r
-    <xsl:if test="@Height"><xsl:attribute name="height"><xsl:value-of select="@Height" /></xsl:attribute></xsl:if>\r
-    <xsl:if test="@HorizontalAlignment">\r
-      <xsl:attribute name="text-anchor">\r
-        <xsl:choose>\r
-          <xsl:when test="@HorizontalAlignment = 'Left'">start</xsl:when>\r
-          <xsl:when test="@HorizontalAlignment = 'Center'">middle</xsl:when>\r
-          <xsl:when test="@HorizontalAlignment = 'Right'">end</xsl:when>\r
-        </xsl:choose>\r
-      </xsl:attribute>\r
-    </xsl:if>\r
-    <xsl:attribute name="dominant-baseline">hanging</xsl:attribute>\r
-    <xsl:call-template name="template_properties" />\r
-    <xsl:call-template name="template_transform" />\r
-    <xsl:apply-templates />\r
-  </text>\r
-  <xsl:if test="@Canvas.Left or @Canvas.Top"><xsl:value-of disable-output-escaping="yes" select="'&lt;/svg&gt;&#13;'" /></xsl:if>\r
-</xsl:template>\r
-\r
-<xsl:template match="*">\r
-<xsl:comment><xsl:value-of select="concat('Unknown tag: ', name(.))" /></xsl:comment>\r
-</xsl:template>\r
-\r
-</xsl:stylesheet>\r
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!--
+Copyright (c) 2005-2007 Toine de Greef (a.degreef@chello.nl)
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
+
+Version history:
+
+20070907 Initial release
+20070912 Removed NaN as viewBox values
+
+-->
+
+<xsl:stylesheet version="1.0"
+xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
+xmlns:xlink="http://www.w3.org/1999/xlink"
+xmlns:svg="http://www.w3.org/2000/svg"
+xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
+xmlns:msxsl="urn:schemas-microsoft-com:xslt">
+<xsl:strip-space elements="*" />
+<xsl:output method="xml" encoding="UTF-8"/>
+<xsl:include href="xaml2svg/animation.xsl" />
+<xsl:include href="xaml2svg/brushes.xsl" />
+<xsl:include href="xaml2svg/canvas.xsl" />
+<xsl:include href="xaml2svg/geometry.xsl" />
+<xsl:include href="xaml2svg/properties.xsl" />
+<xsl:include href="xaml2svg/shapes.xsl" />
+<xsl:include href="xaml2svg/transform.xsl" />
+
+<xsl:template match="/">
+  <svg>
+    <xsl:attribute name="overflow">visible</xsl:attribute>
+    <xsl:variable name="viewBox"><xsl:apply-templates mode="boundingbox" /></xsl:variable>
+    <xsl:if test="system-property('xsl:vendor') = 'Microsoft' and (msxsl:node-set($viewBox)/boundingbox/@x1 != '') and (msxsl:node-set($viewBox)/boundingbox/@x2 != '') and (msxsl:node-set($viewBox)/boundingbox/@y1 != '') and (msxsl:node-set($viewBox)/boundingbox/@y2 != '')">
+      <xsl:attribute name="viewBox">
+        <xsl:value-of select="concat(msxsl:node-set($viewBox)/boundingbox/@x1, ' ')" />
+        <xsl:value-of select="concat(msxsl:node-set($viewBox)/boundingbox/@y1, ' ')" />
+        <xsl:value-of select="concat(msxsl:node-set($viewBox)/boundingbox/@x2 - msxsl:node-set($viewBox)/boundingbox/@x1, ' ')" />
+        <xsl:value-of select="msxsl:node-set($viewBox)/boundingbox/@y2 - msxsl:node-set($viewBox)/boundingbox/@y1" />
+      </xsl:attribute>
+    </xsl:if>  
+    <xsl:apply-templates mode="svg" />
+  </svg>
+</xsl:template>
+
+<xsl:template mode="forward" match="*[name(.) = 'Image']">
+  <xsl:if test="@Canvas.Left or @Canvas.Top"><xsl:value-of disable-output-escaping="yes" select="concat('&lt;svg x=&quot;', @Canvas.Left, '&quot; y=&quot;', @Canvas.Top, '&quot;&gt;')" /></xsl:if>
+  <image>
+    <xsl:if test="@Source"><xsl:attribute name="xlink:href"><xsl:value-of select="@Source" /></xsl:attribute></xsl:if>
+    <xsl:if test="@Width"><xsl:attribute name="width"><xsl:value-of select="@Width" /></xsl:attribute></xsl:if>
+    <xsl:if test="@Height"><xsl:attribute name="height"><xsl:value-of select="@Height" /></xsl:attribute></xsl:if>
+    <xsl:call-template name="template_properties" />
+    <xsl:call-template name="template_transform" />
+    <xsl:apply-templates mode="forward" />
+  </image>
+  <xsl:if test="@Canvas.Left or @Canvas.Top"><xsl:value-of disable-output-escaping="yes" select="'&lt;/svg&gt;&#13;'" /></xsl:if>
+</xsl:template>
+
+<xsl:template mode="forward" match="*[name(.) = 'TextBlock']">
+  <xsl:if test="@Canvas.Left or @Canvas.Top"><xsl:value-of disable-output-escaping="yes" select="concat('&lt;svg x=&quot;', @Canvas.Left, '&quot; y=&quot;', @Canvas.Top, '&quot;&gt;')" /></xsl:if>
+  <text>
+    <xsl:if test="@FontSize"><xsl:attribute name="font-size"><xsl:value-of select="@FontSize" /></xsl:attribute></xsl:if>
+    <xsl:if test="@FontWeight"><xsl:attribute name="font-weight"><xsl:value-of select="@FontWeight" /></xsl:attribute></xsl:if>
+    <xsl:if test="@FontFamily"><xsl:attribute name="font-family"><xsl:value-of select="@FontFamily" /></xsl:attribute></xsl:if>
+    <xsl:if test="@FontStyle"><xsl:attribute name="font-style"><xsl:value-of select="@FontStyle" /></xsl:attribute></xsl:if>
+    <xsl:if test="@Foreground"><xsl:attribute name="fill"><xsl:value-of select="@Foreground" /></xsl:attribute></xsl:if>
+    <xsl:if test="@Width"><xsl:attribute name="width"><xsl:value-of select="@Width" /></xsl:attribute></xsl:if>
+    <xsl:if test="@Height"><xsl:attribute name="height"><xsl:value-of select="@Height" /></xsl:attribute></xsl:if>
+    <xsl:if test="@HorizontalAlignment">
+      <xsl:attribute name="text-anchor">
+        <xsl:choose>
+          <xsl:when test="@HorizontalAlignment = 'Left'">start</xsl:when>
+          <xsl:when test="@HorizontalAlignment = 'Center'">middle</xsl:when>
+          <xsl:when test="@HorizontalAlignment = 'Right'">end</xsl:when>
+        </xsl:choose>
+      </xsl:attribute>
+    </xsl:if>
+    <xsl:attribute name="dominant-baseline">hanging</xsl:attribute>
+    <xsl:call-template name="template_properties" />
+    <xsl:call-template name="template_transform" />
+    <xsl:apply-templates />
+  </text>
+  <xsl:if test="@Canvas.Left or @Canvas.Top"><xsl:value-of disable-output-escaping="yes" select="'&lt;/svg&gt;&#13;'" /></xsl:if>
+</xsl:template>
+
+<xsl:template match="*">
+<xsl:comment><xsl:value-of select="concat('Unknown tag: ', name(.))" /></xsl:comment>
+</xsl:template>
+
+</xsl:stylesheet>