svg2xaml.xsl revision b1c372edfc964321a8f7a9c3487e24bb9b170b98
2f5f997e354e7f4a02b6818bdc68fbece5cb237dJohn Smith<?xml version="1.0" encoding="UTF-8"?>
2f5f997e354e7f4a02b6818bdc68fbece5cb237dJohn Smith
2f5f997e354e7f4a02b6818bdc68fbece5cb237dJohn Smith<!--
2f5f997e354e7f4a02b6818bdc68fbece5cb237dJohn SmithCopyright (c) 2005-2007 authors:
2f5f997e354e7f4a02b6818bdc68fbece5cb237dJohn SmithOriginal version: Toine de Greef (a.degreef@chello.nl)
2f5f997e354e7f4a02b6818bdc68fbece5cb237dJohn SmithModified (2010-2011) by Nicolas Dufour (nicoduf@yahoo.fr) (blur support, units
2f5f997e354e7f4a02b6818bdc68fbece5cb237dJohn Smithconvertion, comments, and some other fixes)
2f5f997e354e7f4a02b6818bdc68fbece5cb237dJohn Smith
2f5f997e354e7f4a02b6818bdc68fbece5cb237dJohn SmithPermission is hereby granted, free of charge, to any person obtaining a copy
2f5f997e354e7f4a02b6818bdc68fbece5cb237dJohn Smithof this software and associated documentation files (the "Software"), to deal
2f5f997e354e7f4a02b6818bdc68fbece5cb237dJohn Smithin the Software without restriction, including without limitation the rights
2f5f997e354e7f4a02b6818bdc68fbece5cb237dJohn Smithto use, copy, modify, merge, publish, distribute, sublicense, and/or sell
2f5f997e354e7f4a02b6818bdc68fbece5cb237dJohn Smithcopies of the Software, and to permit persons to whom the Software is
2f5f997e354e7f4a02b6818bdc68fbece5cb237dJohn Smithfurnished to do so, subject to the following conditions:
2f5f997e354e7f4a02b6818bdc68fbece5cb237dJohn Smith
2f5f997e354e7f4a02b6818bdc68fbece5cb237dJohn SmithThe above copyright notice and this permission notice shall be included in
2f5f997e354e7f4a02b6818bdc68fbece5cb237dJohn Smithall copies or substantial portions of the Software.
2f5f997e354e7f4a02b6818bdc68fbece5cb237dJohn Smith
2f5f997e354e7f4a02b6818bdc68fbece5cb237dJohn SmithTHE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
2f5f997e354e7f4a02b6818bdc68fbece5cb237dJohn SmithIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
2f5f997e354e7f4a02b6818bdc68fbece5cb237dJohn SmithFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
2f5f997e354e7f4a02b6818bdc68fbece5cb237dJohn SmithAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
2f5f997e354e7f4a02b6818bdc68fbece5cb237dJohn SmithLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
2f5f997e354e7f4a02b6818bdc68fbece5cb237dJohn SmithOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
2f5f997e354e7f4a02b6818bdc68fbece5cb237dJohn SmithTHE SOFTWARE.
2f5f997e354e7f4a02b6818bdc68fbece5cb237dJohn Smith-->
2f5f997e354e7f4a02b6818bdc68fbece5cb237dJohn Smith
2f5f997e354e7f4a02b6818bdc68fbece5cb237dJohn Smith<xsl:stylesheet version="1.0"
2f5f997e354e7f4a02b6818bdc68fbece5cb237dJohn Smithxmlns:xsl="http://www.w3.org/1999/XSL/Transform"
715757c20baad0e8e8b54e8ad6742565f923b74cAlex Valavanisxmlns:xlink="http://www.w3.org/1999/xlink"
2f5f997e354e7f4a02b6818bdc68fbece5cb237dJohn Smithxmlns:xs="http://www.w3.org/2001/XMLSchema"
a4142717644b885998f4de2b27be4e8648315decMarkus Engelxmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
a4142717644b885998f4de2b27be4e8648315decMarkus Engelxmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
a4142717644b885998f4de2b27be4e8648315decMarkus Engelxmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
2f5f997e354e7f4a02b6818bdc68fbece5cb237dJohn Smithxmlns:exsl="http://exslt.org/common"
2f5f997e354e7f4a02b6818bdc68fbece5cb237dJohn Smithxmlns:libxslt="http://xmlsoft.org/XSLT/namespace"
2f5f997e354e7f4a02b6818bdc68fbece5cb237dJohn Smithexclude-result-prefixes="rdf xlink xs exsl libxslt">
<xsl:strip-space elements="*" />
<xsl:output method="xml" encoding="UTF-8" indent="yes"/>
<xsl:param name="silverlight_compatible" select="1" />
<!--
// Containers //
* Root templace
* Groups
-->
<!--
// Root template //
-->
<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>
<!--
// 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
-->
<!--
// Parse transform //
-->
<xsl:template name="parse_transform">
<xsl:param name="input" />
<xsl:choose>
<!-- Matrix transform -->
<xsl:when test="starts-with($input, 'matrix(')">
<MatrixTransform>
<xsl:attribute name="Matrix">
<xsl:value-of select="normalize-space(translate(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>
<!-- Scale transform -->
<xsl:when test="starts-with($input, 'scale(')">
<ScaleTransform>
<xsl:variable name="scale" select="normalize-space(translate(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>
<!-- Rotate transform -->
<xsl:when test="starts-with($input, 'rotate(')">
<RotateTransform>
<xsl:attribute name="Angle">
<xsl:value-of select="normalize-space(translate(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>
<!-- Skew transform -->
<xsl:when test="starts-with($input, 'skewX(')">
<SkewTransform>
<xsl:attribute name="AngleX">
<xsl:value-of select="normalize-space(translate(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="normalize-space(translate(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>
<!-- Translate transform -->
<xsl:when test="starts-with($input, 'translate(')">
<TranslateTransform>
<xsl:variable name="translate" select="normalize-space(translate(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: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: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>
<!--
// 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="*[name(.) = '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>
<!--
// GaussianBlur filter effects //
Blur values approximated with d = floor(s * 3*sqrt(2*pi)/4 + 0.5) from:
http://www.w3.org/TR/SVG/filters.html#feGaussianBlurElement
Not supported by XAML:
* Horizontal and vertical blur.
-->
<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:variable name="blur" select="normalize-space(translate(@stdDeviation, ',', ' '))" />
<xsl:choose>
<xsl:when test="not(contains($blur, ' '))">
<xsl:attribute name="Radius">
<xsl:value-of select="floor($blur * 1.88 + 0.5)" />
</xsl:attribute>
</xsl:when>
<xsl:otherwise>
<xsl:attribute name="Radius">
<xsl:value-of select="floor(substring-before($blur, ' ') * 1.88 + 0.5)" />
</xsl:attribute>
</xsl:otherwise>
</xsl:choose>
</xsl:if>
</BlurEffect>
</xsl:template>
<!--
// Linked filter effect //
Only supports blurs
-->
<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>
<!--
// Gradient stop //
-->
<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 //
* Id converter
* Decimal to hexadecimal converter
* Unit to pixel converter
* Object description
* Title and description
* Switch
* Symbols
* Use
* RDF and foreign objects
* Misc ignored stuff (markers, patterns, styles)
* Unknows tags
-->
<!--
// 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.
em, ex and % not implemented
-->
<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>
<!--
// 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>
<!--
// Title and description //
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>
<!--
// Switch //
-->
<xsl:template mode="forward" match="*[name(.) = 'switch']">
<xsl:apply-templates mode="forward" />
</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 //
(since it is not supported by Inkscape, not implemented yet)
-->
<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>
<!--
// Misc ignored stuff (markers, patterns, styles) //
-->
<xsl:template mode="forward" match="*[name(.) = 'marker' or name(.) = 'pattern' or name(.) = 'style']">
</xsl:template>
<!--
// Unknown tags //
With generic and mode="forward" templates
-->
<xsl:template match="*">
<xsl:comment>
<xsl:value-of select="concat('Unknown tag: ', name(.))" />
</xsl:comment>
</xsl:template>
<xsl:template mode="forward" 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:variable name="value">
<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:variable>
<xsl:if test="$value">
<!-- Removes unwanted characters in the color link (TODO: export to a specific template)-->
<xsl:value-of select="normalize-space(translate($value, '&quot;', ''))" />
</xsl:if>
</xsl:template>
<!--
// Fill opacity //
-->
<xsl:template mode="fill_opacity" match="*">
<xsl:variable name="value">
<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:otherwise>1</xsl:otherwise>
</xsl:choose>
</xsl:variable>
<xsl:choose>
<xsl:when test="$value &lt; 0">0</xsl:when>
<xsl:when test="$value &gt; 1">1</xsl:when>
<xsl:otherwise>
<xsl:value-of select="$value" />
</xsl:otherwise>
</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="normalize-space(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:variable name="value">
<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:otherwise>1</xsl:otherwise>
</xsl:choose>
</xsl:variable>
<xsl:choose>
<xsl:when test="$value &lt; 0">0</xsl:when>
<xsl:when test="$value &gt; 1">1</xsl:when>
<xsl:otherwise>
<xsl:value-of select="$value" />
</xsl:otherwise>
</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:variable name="stroke_width">
<xsl:apply-templates mode="stroke_width" select="." />
</xsl:variable>
<xsl:if test="$stroke_width != ''">
<xsl:attribute name="StrokeThickness">
<xsl:value-of select="$stroke_width" />
</xsl:attribute>
</xsl:if>
<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:call-template name="convert_unit">
<xsl:with-param name="convert_value">
<xsl:value-of select="@stroke-width" />
</xsl:with-param>
</xsl:call-template>
</xsl:when>
<xsl:when test="@style and contains(@style, 'stroke-width:')">
<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: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>
<!--
// Text specific templates //
* Text tspan
* Text flowPara
* Text flowRegion (text frame)
* Get font size
* Font size
* Font weight
* Font family
* Font style
* Baseline shift
* Line height
* Writing mode
* Text decoration
* Text fill
* Text direction
* Text size
* Text position
* Text object
* FlowRoot object
-->
<!--
// Text span //
SVG: tspan, flowSpan, FXG: span
Not supported in FXG:
* span position
-->
<xsl:template mode="forward" match="*[name(.) = 'tspan' or name(.) = 'flowSpan']">
<span>
<xsl:if test="../@xml:space='preserve'">
<xsl:attribute name="whiteSpaceCollapse">preserve</xsl:attribute>
</xsl:if>
<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="starts-with($fill, '#') or (not(starts-with($fill, 'url')) and $fill != '' and $fill != 'none')">
<xsl:attribute name="color">
<xsl:call-template name="template_color">
<xsl:with-param name="colorspec">
<xsl:value-of select="$fill" />
</xsl:with-param>
</xsl:call-template>
</xsl:attribute>
<xsl:attribute name="textAlpha">
<xsl:value-of select="$fill_opacity" />
</xsl:attribute>
</xsl:if>
<xsl:apply-templates mode="font_size" select="." />
<xsl:apply-templates mode="font_weight" select="." />
<xsl:apply-templates mode="font_family" select="." />
<xsl:apply-templates mode="font_style" select="." />
<xsl:apply-templates mode="text_fill" select="." />
<xsl:apply-templates mode="text_decoration" select="." />
<xsl:apply-templates mode="line_height" select="." />
<xsl:apply-templates mode="baseline_shift" select="." />
<xsl:if test="text()">
<xsl:value-of select="text()" />
</xsl:if>
</span>
</xsl:template>
<!--
// Text flowPara //
SVG: flowPara, flowDiv FXG: p
Not supported in FXG:
* paragraph position
-->
<xsl:template mode="forward" match="*[name(.) = 'flowPara' or name(.) = 'flowDiv']">
<p>
<xsl:if test="../@xml:space='preserve'">
<xsl:attribute name="whiteSpaceCollapse">preserve</xsl:attribute>
</xsl:if>
<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="starts-with($fill, '#') or (not(starts-with($fill, 'url')) and $fill != '' and $fill != 'none')">
<xsl:attribute name="color">
<xsl:call-template name="template_color">
<xsl:with-param name="colorspec">
<xsl:value-of select="$fill" />
</xsl:with-param>
</xsl:call-template>
</xsl:attribute>
<xsl:attribute name="textAlpha">
<xsl:value-of select="$fill_opacity" />
</xsl:attribute>
</xsl:if>
<xsl:apply-templates mode="font_size" select="." />
<xsl:apply-templates mode="font_weight" select="." />
<xsl:apply-templates mode="font_family" select="." />
<xsl:apply-templates mode="font_style" select="." />
<xsl:apply-templates mode="text_fill" select="." />
<xsl:apply-templates mode="text_decoration" select="." />
<xsl:apply-templates mode="line_height" select="." />
<xsl:apply-templates mode="baseline_shift" select="." />
<xsl:choose>
<xsl:when test="*[name(.) = 'flowSpan']/text()">
<xsl:apply-templates mode="forward" />
</xsl:when>
<xsl:otherwise>
<xsl:choose>
<xsl:when test="@xml:space='preserve'">
<xsl:copy-of select="translate(text(), '&#x9;&#xA;&#xD;', ' ')" />
</xsl:when>
<xsl:otherwise>
<xsl:copy-of select="normalize-space(translate(text(), '&#x9;&#xA;&#xD;', ' '))" />
</xsl:otherwise>
</xsl:choose>
</xsl:otherwise>
</xsl:choose>
</p>
</xsl:template>
<!--
// Text flowRegion //
-->
<xsl:template mode="flow_region" match="*">
<xsl:apply-templates mode="text_size" select="." />
<xsl:apply-templates mode="text_position" select="." />
</xsl:template>
<!--
// Get text font size //
-->
<xsl:template mode="get_font_size" match="*">
<xsl:choose>
<xsl:when test="@font-size">
<xsl:value-of select="@font-size" />
</xsl:when>
<xsl:when test="@style and contains(@style, 'font-size:')">
<xsl:variable name="font_size" select="normalize-space(substring-after(@style, 'font-size:'))" />
<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:when>
<xsl:when test="name(..) = 'g' or name(..) = 'svg'">
<xsl:apply-templates mode="get_font_size" select="parent::*"/>
</xsl:when>
</xsl:choose>
</xsl:template>
<!--
// Text font size //
SVG: font-size, XAML: FontSize
-->
<xsl:template mode="font_size" match="*">
<xsl:variable name="value">
<xsl:apply-templates mode="get_font_size" select="." />
</xsl:variable>
<xsl:if test="$value != ''">
<xsl:attribute name="FontSize">
<xsl:call-template name="convert_unit">
<xsl:with-param name="convert_value" select="$value" />
</xsl:call-template>
</xsl:attribute>
</xsl:if>
<xsl:attribute name="FontSize">
<xsl:choose>
<xsl:when test="$value != ''">
<xsl:call-template name="convert_unit">
<xsl:with-param name="convert_value" select="$value" />
</xsl:call-template>
</xsl:when>
<xsl:otherwise>12</xsl:otherwise>
</xsl:choose>
</xsl:attribute>
</xsl:template>
<!--
// Text font weight //
SVG: font-weight, XAML: FontWeight
-->
<xsl:template mode="font_weight" match="*">
<xsl:variable name="value">
<xsl:if test="@font-weight">
<xsl:value-of select="@font-weight" />
</xsl:if>
<xsl:if test="@style and contains(@style, 'font-weight:')">
<xsl:variable name="font_weight" select="normalize-space(substring-after(@style, 'font-weight:'))" />
<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:if>
</xsl:variable>
<xsl:if test="$value != ''">
<xsl:attribute name="FontWeight">
<xsl:choose>
<xsl:when test="$value &lt;= 100 or $value = 'lighter'">Thin</xsl:when>
<xsl:when test="$value &gt; 100 and $value &lt;= 200">ExtraLight</xsl:when>
<xsl:when test="$value &gt; 200 and $value &lt;= 300">Light</xsl:when>
<xsl:when test="($value &gt; 300 and $value &lt;= 400) or $value ='normal'">Normal</xsl:when>
<xsl:when test="$value &gt; 400 and $value &lt;= 500">Medium</xsl:when>
<xsl:when test="$value &gt; 500 and $value &lt;= 600">SemiBold</xsl:when>
<xsl:when test="($value &gt; 600 and $value &lt;= 700) or $value ='bold'">Bold</xsl:when>
<xsl:when test="$value &gt; 700 and $value &lt;= 800">ExtraBold</xsl:when>
<xsl:when test="$value &gt; 800 and $value &lt;= 900">Black</xsl:when>
<xsl:when test="$value &gt; 900 or $value = 'bolder'">ExtraBlack</xsl:when>
<xsl:otherwise>normal</xsl:otherwise>
</xsl:choose>
</xsl:attribute>
</xsl:if>
</xsl:template>
<!--
// Text font family //
SVG: font-family, XAML: FontFamily
-->
<xsl:template mode="font_family" match="*">
<xsl:variable name="value">
<xsl:if test="@font-family">
<xsl:value-of select="translate(@font-family, &quot;'&quot;, '')" />
</xsl:if>
<xsl:if test="@style and contains(@style, 'font-family:')">
<xsl:variable name="font_family" select="normalize-space(substring-after(@style, 'font-family:'))" />
<xsl:choose>
<xsl:when test="contains($font_family, ';')">
<xsl:value-of select="translate(substring-before($font_family, ';'), &quot;'&quot;, '')" />
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="translate($font_family, &quot;'&quot;, '')" />
</xsl:otherwise>
</xsl:choose>
</xsl:if>
</xsl:variable>
<xsl:if test="$value != ''">
<xsl:attribute name="FontFamily">
<xsl:choose>
<xsl:when test="$value='Sans'">Arial</xsl:when>
<xsl:otherwise>
<xsl:value-of select="$value" />
</xsl:otherwise>
</xsl:choose>
</xsl:attribute>
</xsl:if>
</xsl:template>
<!--
// Text font style //
SVG: font-style, XAML: FontStyle
-->
<xsl:template mode="font_style" match="*">
<xsl:variable name="value">
<xsl:if test="@font-style">
<xsl:value-of select="@font-style" />
</xsl:if>
<xsl:if test="@style and contains(@style, 'font-style:')">
<xsl:variable name="font_style" select="normalize-space(substring-after(@style, 'font-style:'))" />
<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:if>
</xsl:variable>
<xsl:if test="$value != ''">
<xsl:attribute name="FontStyle">
<xsl:value-of select="$value" />
</xsl:attribute>
</xsl:if>
</xsl:template>
<!--
// Text baseline shift //
SVG: baseline-shift, FXG: baselineShift
-->
<xsl:template mode="baseline_shift" match="*">
<xsl:variable name="value">
<xsl:if test="@baseline-shift">
<xsl:value-of select="@baseline-shift" />
</xsl:if>
<xsl:if test="@style and contains(@style, 'baseline-shift:') and not(contains(substring-after(@style, 'baseline-shift:'), ';'))">
<xsl:value-of select="substring-after(@style, 'baseline-shift:')" />
</xsl:if>
<xsl:if test="@style and contains(@style, 'baseline-shift:') and contains(substring-after(@style, 'baseline-shift:'), ';')">
<xsl:value-of select="substring-before(substring-after(@style, 'baseline-shift:'), ';')" />
</xsl:if>
</xsl:variable>
<xsl:if test="$value != ''">
<xsl:attribute name="baselineShift">
<xsl:choose>
<xsl:when test="$value='baseline'">0</xsl:when>
<xsl:when test="$value='super'">superscript</xsl:when>
<xsl:when test="$value='sub'">subscript</xsl:when>
<xsl:when test="translate($value, '%', '') &lt; -1000">-1000</xsl:when>
<xsl:when test="translate($value, '%', '') &gt; 1000">1000</xsl:when>
<xsl:otherwise>
<xsl:value-of select="translate($value, '%', '')" />
</xsl:otherwise>
</xsl:choose>
<xsl:if test="contains($value, '%')">%</xsl:if>
</xsl:attribute>
</xsl:if>
</xsl:template>
<!--
// Text line height //
SVG: line-height, FXG: lineHeight
-->
<xsl:template mode="line_height" match="*">
<xsl:variable name="value">
<xsl:if test="@line-height">
<xsl:value-of select="@line-height" />
</xsl:if>
<xsl:if test="@style and contains(@style, 'line-height:')">
<xsl:variable name="line_height" select="normalize-space(substring-after(@style, 'line-height:'))" />
<xsl:choose>
<xsl:when test="contains($line_height, ';')">
<xsl:value-of select="substring-before($line_height, ';')" />
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="$line_height" />
</xsl:otherwise>
</xsl:choose>
</xsl:if>
</xsl:variable>
<xsl:if test="$value != ''">
<xsl:attribute name="lineHeight">
<xsl:call-template name="convert_unit">
<xsl:with-param name="convert_value" select="$value" />
</xsl:call-template>
</xsl:attribute>
</xsl:if>
</xsl:template>
<!--
// Text writing mode //
SVG: writing-mode, FXG: blockProgression
Values inverted in FXG...
-->
<xsl:template mode="writing_mode" match="*">
<xsl:variable name="value">
<xsl:if test="@writing-mode">
<xsl:value-of select="@writing-mode" />
</xsl:if>
<xsl:if test="@style and contains(@style, 'writing-mode:') and not(contains(substring-after(@style, 'writing-mode:'), ';'))">
<xsl:value-of select="substring-after(@style, 'writing-mode:')" />
</xsl:if>
<xsl:if test="@style and contains(@style, 'writing-mode:') and contains(substring-after(@style, 'writing-mode:'), ';')">
<xsl:value-of select="substring-before(substring-after(@style, 'writing-mode:'), ';')" />
</xsl:if>
</xsl:variable>
<xsl:if test="$value != ''">
<xsl:attribute name="blockProgression">
<xsl:choose>
<xsl:when test="$value='tb'">rl</xsl:when>
<xsl:otherwise>tb</xsl:otherwise>
</xsl:choose>
</xsl:attribute>
<xsl:if test="$value='tb'">
<xsl:attribute name="textRotation">rotate270</xsl:attribute>
</xsl:if>
</xsl:if>
</xsl:template>
<!--
// Text decoration //
SVG: text-decoration, FXG: textDecoration, lineThrough
-->
<xsl:template mode="text_decoration" match="*">
<xsl:variable name="value">
<xsl:if test="@text-decoration">
<xsl:value-of select="@text-decoration" />
</xsl:if>
<xsl:if test="@style and contains(@style, 'text-decoration:') and not(contains(substring-after(@style, 'text-decoration:'), ';'))">
<xsl:value-of select="substring-after(@style, 'text-decoration:')" />
</xsl:if>
<xsl:if test="@style and contains(@style, 'text-decoration:') and contains(substring-after(@style, 'text-decoration:'), ';')">
<xsl:value-of select="substring-before(substring-after(@style, 'text-decoration:'), ';')" />
</xsl:if>
</xsl:variable>
<xsl:if test="$value != ''">
<xsl:choose>
<xsl:when test="$value='underline'">
<xsl:attribute name="textDecoration">underline</xsl:attribute>
</xsl:when>
<xsl:when test="$value='line-through'">
<xsl:attribute name="lineThrough">true</xsl:attribute>
</xsl:when>
</xsl:choose>
</xsl:if>
</xsl:template>
<!--
// Text fill //
SVG: fill, fill-opacity, XAML: Foreground
-->
<xsl:template mode="text_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="starts-with($fill, '#') or (not(starts-with($fill, 'url')) and $fill != '' and $fill != 'none')">
<xsl:attribute name="Foreground">
<xsl:call-template name="template_color">
<xsl:with-param name="colorspec">
<xsl:value-of select="$fill" />
</xsl:with-param>
<xsl:with-param name="opacityspec">
<xsl:choose>
<xsl:when test="$fill_opacity">
<xsl:value-of select="$fill_opacity" />
</xsl:when>
<xsl:otherwise>1</xsl:otherwise>
</xsl:choose>
</xsl:with-param>
</xsl:call-template>
</xsl:attribute>
</xsl:if>
</xsl:template>
<!--
// Text direction //
SVG: direction, unicode-bidi, FXG: direction
-->
<xsl:template mode="direction" match="*">
<xsl:variable name="value">
<xsl:if test="@direction">
<xsl:value-of select="@direction" />
</xsl:if>
<xsl:if test="@style and contains(@style, 'direction:') and not(contains(substring-after(@style, 'direction:'), ';'))">
<xsl:value-of select="substring-after(@style, 'direction:')" />
</xsl:if>
<xsl:if test="@style and contains(@style, 'direction:') and contains(substring-after(@style, 'direction:'), ';')">
<xsl:value-of select="substring-before(substring-after(@style, 'direction:'), ';')" />
</xsl:if>
</xsl:variable>
<xsl:variable name="bidi">
<xsl:if test="@unicode-bidi">
<xsl:value-of select="@unicode-bidi" />
</xsl:if>
<xsl:if test="@style and contains(@style, 'unicode-bidi:') and not(contains(substring-after(@style, 'unicode-bidi:'), ';'))">
<xsl:value-of select="substring-after(@style, 'unicode-bidi:')" />
</xsl:if>
<xsl:if test="@style and contains(@style, 'unicode-bidi:') and contains(substring-after(@style, 'unicode-bidi:'), ';')">
<xsl:value-of select="substring-before(substring-after(@style, 'unicode-bidi:'), ';')" />
</xsl:if>
</xsl:variable>
<xsl:if test="$value != '' and ($bidi='embed' or $bidi='bidi-override')">
<xsl:attribute name="direction">
<xsl:choose>
<xsl:when test="$value='ltr'">ltr</xsl:when>
<xsl:when test="$value='rtl'">rtl</xsl:when>
</xsl:choose>
</xsl:attribute>
</xsl:if>
</xsl:template>
<!--
// Text size //
-->
<xsl:template mode="text_size" match="*">
<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:template>
<!--
// Text position //
-->
<xsl:template mode="text_position" match="*">
<!-- Keep the first x value only -->
<xsl:if test="@x">
<xsl:attribute name="Canvas.Left">
<xsl:choose>
<xsl:when test="contains(@x, ' ')">
<xsl:call-template name="convert_unit">
<xsl:with-param name="convert_value" select="substring-before(@x, ' ')" />
</xsl:call-template>
</xsl:when>
<xsl:otherwise>
<xsl:call-template name="convert_unit">
<xsl:with-param name="convert_value" select="@x" />
</xsl:call-template>
</xsl:otherwise>
</xsl:choose>
</xsl:attribute>
</xsl:if>
<!-- Keep the first y value only -->
<xsl:if test="@y">
<xsl:attribute name="Canvas.Top">
<xsl:variable name="top_val">
<xsl:choose>
<xsl:when test="contains(@y, ' ')">
<xsl:call-template name="convert_unit">
<xsl:with-param name="convert_value" select="substring-before(@y, ' ')" />
</xsl:call-template>
</xsl:when>
<xsl:otherwise>
<xsl:call-template name="convert_unit">
<xsl:with-param name="convert_value" select="@y" />
</xsl:call-template>
</xsl:otherwise>
</xsl:choose>
</xsl:variable>
<xsl:variable name="size_val">
<xsl:variable name="value">
<xsl:apply-templates mode="get_font_size" select="." />
</xsl:variable>
<xsl:choose>
<xsl:when test="$value != ''">
<xsl:call-template name="convert_unit">
<xsl:with-param name="convert_value" select="$value" />
</xsl:call-template>
</xsl:when>
<xsl:otherwise>12</xsl:otherwise>
</xsl:choose>
</xsl:variable>
<xsl:if test="$top_val != '' and $size_val != ''">
<xsl:value-of select="$top_val - $size_val" />
</xsl:if>
</xsl:attribute>
</xsl:if>
</xsl:template>
<!--
// Objects //
* Text
* Lines
* Rectangle
* Polygon
* Polyline
* Path
* Ellipse
* Circle
* Image
-->
<!--
// Text objects //
SVG: text, XAML: TextBlock
-->
<xsl:template mode="forward" match="*[name(.) = 'text']">
<TextBlock>
<xsl:apply-templates mode="font_size" select="." />
<xsl:apply-templates mode="font_weight" select="." />
<xsl:apply-templates mode="font_family" select="." />
<xsl:apply-templates mode="font_style" select="." />
<xsl:apply-templates mode="text_fill" select="." />
<xsl:apply-templates mode="text_size" select="." />
<xsl:apply-templates mode="text_position" select="." />
<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: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:choose>
<xsl:when test="*[name(.) = 'tspan']/text()">
<xsl:apply-templates mode="forward" />
</xsl:when>
<xsl:otherwise>
<xsl:choose>
<xsl:when test="@xml:space='preserve'">
<xsl:copy-of select="translate(text(), '&#x9;&#xA;&#xD;', ' ')" />
</xsl:when>
<xsl:otherwise>
<xsl:copy-of select="normalize-space(translate(text(), '&#x9;&#xA;&#xD;', ' '))" />
</xsl:otherwise>
</xsl:choose>
</xsl:otherwise>
</xsl:choose>
</TextBlock>
</xsl:template>
<!--
// Line object //
SVG: line, XAML: Line
-->
<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_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 object //
SVG: rect, XAML: 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_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 object //
SVG: polygon, XAML: 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_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 object //
SVG: polyline, XAML: 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_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 //
SVG: path, XAML: 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_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 object //
SVG: ellipse, XAML: 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_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 object //
SVG: circle, XAML: Ellipse
-->
<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_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>
<!--
// Image object//
SVG: image, FXG: 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="forward" />
</Image>
</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>