Code

Extensions. XAML export. Blur support (Bug #572965), minor fixes and lots of new...
authorJazzyNico <nicoduf@yahoo.fr>
Mon, 10 May 2010 18:55:22 +0000 (20:55 +0200)
committerJazzyNico <nicoduf@yahoo.fr>
Mon, 10 May 2010 18:55:22 +0000 (20:55 +0200)
share/extensions/svg2xaml.xsl

index ef01e2023233e2b0b8fad01c81142c2246dfe1b6..407819d9e02a4ef417769b937c074243373a66ab 100755 (executable)
@@ -1,7 +1,10 @@
 <?xml version="1.0" encoding="UTF-8"?>\r
 \r
 <!--\r
-Copyright (c) 2005-2007 Toine de Greef (a.degreef@chello.nl)\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
@@ -38,10 +41,353 @@ exclude-result-prefixes="rdf xlink xs exsl libxslt">
 \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
-Values with units (except %) are converted to pixels.\r
-Unknown units are kept.\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
+            <xsl:attribute name="KernelType">Gaussian</xsl:attribute>\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
@@ -66,12 +412,82 @@ Unknown units are kept.
         <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
@@ -117,6 +533,7 @@ Unknown units are kept.
   </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
@@ -135,6 +552,7 @@ Unknown units are kept.
   </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
@@ -149,6 +567,7 @@ Unknown units are kept.
   </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
@@ -166,6 +585,7 @@ Unknown units are kept.
   </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
@@ -186,6 +606,7 @@ Unknown units are kept.
   </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
@@ -204,6 +625,7 @@ Unknown units are kept.
   </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
@@ -218,6 +640,7 @@ Unknown units are kept.
   </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
@@ -231,6 +654,7 @@ Unknown units are kept.
   </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
@@ -252,6 +676,7 @@ Unknown units are kept.
   </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
@@ -268,6 +693,7 @@ Unknown units are kept.
   </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
@@ -285,6 +711,7 @@ Unknown units are kept.
   </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
@@ -301,6 +728,7 @@ Unknown units are kept.
   </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
@@ -310,6 +738,7 @@ Unknown units are kept.
   </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
@@ -333,6 +762,7 @@ Unknown units are kept.
   </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
@@ -342,6 +772,7 @@ Unknown units are kept.
   </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
@@ -379,20 +810,7 @@ Unknown units are kept.
   </xsl:choose>\r
 </xsl:template>\r
 \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
-<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
-<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
+<!-- Gradient stops -->\r
 <xsl:template mode="stop_color" match="*">\r
   <xsl:variable name="Opacity">\r
     <xsl:choose>\r
@@ -441,6 +859,7 @@ Unknown units are kept.
   </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
@@ -457,6 +876,7 @@ Unknown units are kept.
   </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
@@ -481,6 +901,17 @@ Unknown units are kept.
   </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
@@ -531,160 +962,61 @@ Unknown units are kept.
           <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
-<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
-<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
-<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
-<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
-<xsl:template mode="forward" match="defs">\r
-  <xsl:apply-templates mode="forward" />\r
-</xsl:template>\r
-\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"><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="@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="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:when test="not(@transform)">\r
-      <xsl:apply-templates mode="forward" select="*" />\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
@@ -701,13 +1033,35 @@ Unknown units are kept.
   </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"><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="@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
-\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
@@ -728,6 +1082,7 @@ Unknown units are kept.
   </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
@@ -809,12 +1164,18 @@ Unknown units are kept.
             <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"><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="@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
-\r
     <xsl:apply-templates mode="desc" select="." />\r
-\r
     <xsl:apply-templates mode="clip" select="." />\r
     <!--xsl:apply-templates mode="transform" select="." /-->\r
     <!--xsl:apply-templates mode="forward" /-->\r
@@ -822,187 +1183,8 @@ Unknown units are kept.
     <xsl:if test="*[name(.) = 'tspan']/text()"><xsl:value-of select="*[name(.) = 'tspan']/text()" /></xsl:if>\r
   </TextBlock>\r
 </xsl:template>\r
-\r
-<xsl:template mode="forward" match="*[name(.) = 'title' or name(.) = 'desc']">\r
-  <!-- -->\r
-</xsl:template>\r
-\r
-<xsl:template mode="forward" match="*[name(.) = 'marker' or name(.) = 'pattern' or name(.) = 'style']">\r
-  <!-- -->\r
-</xsl:template>\r
-\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
-<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
-<xsl:template mode="forward" match="rdf:RDF | *[name(.) = 'foreignObject']">\r
-  <!-- -->\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
-<!-- BRUSHES -->\r
-\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
-<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
-<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
-<!-- SHAPES -->\r
-\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
@@ -1029,10 +1211,19 @@ Unknown units are kept.
   </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"><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="@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
@@ -1057,11 +1248,9 @@ Unknown units are kept.
     <xsl:apply-templates mode="stroke_dashoffset" select="." />\r
     <xsl:apply-templates mode="stroke_linejoin" select="." />\r
     <xsl:apply-templates mode="stroke_linecap" select="." />\r
-\r
+    <xsl:apply-templates mode="filter_effect" select="." />\r
     <xsl:apply-templates mode="resources" select="." />\r
-\r
     <xsl:apply-templates mode="desc" select="." />\r
-\r
     <xsl:apply-templates mode="clip" select="." />\r
 \r
     <xsl:apply-templates mode="transform" select=".">\r
@@ -1072,6 +1261,7 @@ Unknown units are kept.
   </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
@@ -1096,6 +1286,7 @@ Unknown units are kept.
   </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
@@ -1120,6 +1311,7 @@ Unknown units are kept.
   </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
@@ -1162,6 +1354,7 @@ Unknown units are kept.
   </Path>\r
 </xsl:template>\r
 \r
+<!-- Ellipse -->\r
 <xsl:template mode="forward" match="*[name(.) = 'ellipse']">\r
   <Ellipse>\r
     <xsl:variable name="cx">\r
@@ -1195,7 +1388,6 @@ Unknown units are kept.
     <xsl:apply-templates mode="stroke_linecap" select="." />\r
 \r
     <xsl:apply-templates mode="desc" select="." />\r
-\r
     <xsl:apply-templates mode="clip" select="." />\r
 \r
     <xsl:apply-templates mode="transform" select=".">\r
@@ -1206,6 +1398,7 @@ Unknown units are kept.
   </Ellipse>\r
 </xsl:template>\r
 \r
+<!-- Circle -->\r
 <xsl:template mode="forward" match="*[name(.) = 'circle']">\r
   <Ellipse>\r
     <xsl:variable name="cx">\r
@@ -1221,9 +1414,9 @@ Unknown units are kept.
       </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>
-       <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="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
@@ -1237,7 +1430,6 @@ Unknown units are kept.
     <xsl:apply-templates mode="stroke_linecap" select="." />\r
 \r
     <xsl:apply-templates mode="desc" select="." />\r
-\r
     <xsl:apply-templates mode="clip" select="." />\r
 \r
     <xsl:apply-templates mode="transform" select=".">\r
@@ -1248,10 +1440,19 @@ Unknown units are kept.
   </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
@@ -1263,6 +1464,7 @@ Unknown units are kept.
   </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