Code

185ebe25d59128288ca197f9acfdffab702cb0c3
[inkscape.git] / share / extensions / svg2xaml.xsl
1 <?xml version="1.0" encoding="UTF-8"?>
3 <!--
4 Copyright (c) 2005-2007 authors:
5 Original version: Toine de Greef (a.degreef@chello.nl)
6 Modified (2010) by Nicolas Dufour (nicoduf@yahoo.fr) (blur support, units
7 convertion, comments, and some other fixes)
9 Permission is hereby granted, free of charge, to any person obtaining a copy
10 of this software and associated documentation files (the "Software"), to deal
11 in the Software without restriction, including without limitation the rights
12 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
13 copies of the Software, and to permit persons to whom the Software is
14 furnished to do so, subject to the following conditions:
16 The above copyright notice and this permission notice shall be included in
17 all copies or substantial portions of the Software.
19 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
20 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
22 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
23 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
24 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
25 THE SOFTWARE.
26 -->
28 <xsl:stylesheet version="1.0"
29 xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
30 xmlns:xlink="http://www.w3.org/1999/xlink"
31 xmlns:xs="http://www.w3.org/2001/XMLSchema"
32 xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
33 xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
34 xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
35 xmlns:exsl="http://exslt.org/common"
36 xmlns:libxslt="http://xmlsoft.org/XSLT/namespace"
37 exclude-result-prefixes="rdf xlink xs exsl libxslt">
39 <xsl:strip-space elements="*" />
40 <xsl:output method="xml" encoding="UTF-8" indent="yes"/>
42 <xsl:param name="silverlight_compatible" select="1" />
44 <!-- Root template.
45 Everything starts here! -->
46 <xsl:template match="/">
47   <xsl:choose>
48     <xsl:when test="$silverlight_compatible = 1">
49       <xsl:apply-templates mode="forward" />
50     </xsl:when>
51     <xsl:otherwise>
52       <Viewbox Stretch="Uniform">
53         <xsl:apply-templates mode="forward" />
54       </Viewbox>
55     </xsl:otherwise>   
56   </xsl:choose>
57 </xsl:template>
59 <!-- SVG and groups
60 (including layers) -->
61 <xsl:template mode="forward" match="*[name(.) = 'svg' or name(.) = 'g']">
62   <xsl:choose>
63     <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']">
64       <Canvas>
65         <xsl:apply-templates mode="id" select="." />
66         <!--
67         <xsl:apply-templates mode="clip" select="." />
68         -->
69         <xsl:if test="@style and contains(@style, 'display:none')"><xsl:attribute name="Visibility">Collapsed</xsl:attribute></xsl:if>
70         <xsl:if test="@style and contains(@style, 'opacity:')">
71         <xsl:attribute name="Opacity">
72             <xsl:choose>
73                 <xsl:when test="contains(substring-after(@style, 'opacity:'), ';')"><xsl:value-of select="substring-before(substring-after(@style, 'opacity:'), ';')" /></xsl:when>
74                   <xsl:otherwise><xsl:value-of select="substring-after(@style, 'opacity:')" /></xsl:otherwise>
75             </xsl:choose>
76         </xsl:attribute>
77         </xsl:if>
78         <xsl:if test="@width and not(contains(@width, '%'))">
79         <xsl:attribute name="Width">
80             <xsl:call-template name="convert_unit">
81                 <xsl:with-param name="convert_value" select="@width" />
82             </xsl:call-template>
83         </xsl:attribute></xsl:if>
84         <xsl:if test="@height and not(contains(@height, '%'))">
85         <xsl:attribute name="Height">
86             <xsl:call-template name="convert_unit">
87                 <xsl:with-param name="convert_value" select="@height" />
88             </xsl:call-template>
89         </xsl:attribute></xsl:if>
90         <xsl:if test="@x">
91         <xsl:attribute name="Canvas.Left">
92             <xsl:call-template name="convert_unit">
93                 <xsl:with-param name="convert_value" select="@x" />
94             </xsl:call-template>
95         </xsl:attribute></xsl:if>
96         <xsl:if test="@y">
97         <xsl:attribute name="Canvas.Top">
98             <xsl:call-template name="convert_unit">
99                 <xsl:with-param name="convert_value" select="@y" />
100             </xsl:call-template>
101         </xsl:attribute></xsl:if>
102         <xsl:if test="@viewBox">
103           <xsl:variable name="viewBox"><xsl:value-of select="normalize-space(translate(@viewBox, ',', ' '))" /></xsl:variable>
104           <xsl:attribute name="Width"><xsl:value-of select="substring-before(substring-after(substring-after($viewBox, ' '), ' '), ' ')" /></xsl:attribute>
105           <xsl:attribute name="Height"><xsl:value-of select="substring-after(substring-after(substring-after($viewBox, ' '), ' '), ' ')" /></xsl:attribute>
106           <Canvas.RenderTransform>
107             <TranslateTransform>
108               <xsl:attribute name="X"><xsl:value-of select="-number(substring-before($viewBox, ' '))" /></xsl:attribute>
109               <xsl:attribute name="Y"><xsl:value-of select="-number(substring-before(substring-after($viewBox, ' '), ' '))" /></xsl:attribute>
110             </TranslateTransform>
111           </Canvas.RenderTransform>
112         </xsl:if>
113     <xsl:if test="@transform">
114       <Canvas>
115         <Canvas.RenderTransform>
116           <TransformGroup><xsl:apply-templates mode="transform" select="." /></TransformGroup>
117         </Canvas.RenderTransform>
118         <xsl:apply-templates mode="forward" select="*" />
119       </Canvas>
120     </xsl:if>
122         <xsl:if test="*[name(.) = 'linearGradient' or name(.) = 'radialGradient' or name(.) = 'defs' or name(.) = 'clipPath']">
123           <Canvas.Resources>
124             <xsl:apply-templates mode="forward" select="*[name(.) = 'linearGradient' or name(.) = 'radialGradient' or name(.) = 'defs' or name(.) = 'clipPath']" />
125           </Canvas.Resources>
126         </xsl:if>
127         <xsl:if test="not(@transform)">
128           <xsl:apply-templates mode="forward" select="*[name(.) != 'linearGradient' and name(.) != 'radialGradient' and name(.) != 'defs' and name(.) != 'clipPath']" />
129         </xsl:if>  
130       </Canvas>
131     </xsl:when>
132     <xsl:when test="not(@transform)">
133       <xsl:apply-templates mode="forward" select="*" />
134     </xsl:when>
135   </xsl:choose>
136 </xsl:template>
138 <!--
139 // Resources (defs) //
141 * Resources ids
142 * Generic defs template
143 * Generic filters template
144 * Filter effects
145 * Linked filter effects
146 * Linear gradients
147 * Radial gradients
148 * Generic gradient stops
149 * Clipping
150 -->
152 <!-- Resources ids -->
153 <xsl:template mode="resources" match="*">
154   <!-- should be in-depth -->
155   <xsl:if test="ancestor::*[name(.) = 'defs']"><xsl:attribute name="x:Key"><xsl:value-of select="@id" /></xsl:attribute></xsl:if>
156 </xsl:template>
158 <!-- Generic defs template -->
159 <xsl:template mode="forward" match="defs">
160   <xsl:apply-templates mode="forward" />
161 </xsl:template>
163 <!-- Generic filters template
164 Limited to one filter (can be improved) -->
165 <xsl:template mode="forward" match="*[name(.) = 'filter']">
166     <xsl:if test="count(*) = 1">
167       <xsl:apply-templates mode="forward" />
168     </xsl:if> 
169 </xsl:template>
171 <!-- Filter effects -->
172 <xsl:template mode="forward" match="*[name(.) = 'feGaussianBlur']">
173         <BlurEffect>
174             <xsl:if test="../@id"><xsl:attribute name="x:Key"><xsl:value-of select="../@id" /></xsl:attribute></xsl:if>
175             <xsl:if test="@stdDeviation"><xsl:attribute name="Radius"><xsl:value-of select="round(@stdDeviation * 3)" /></xsl:attribute></xsl:if>
176         </BlurEffect>  
177 </xsl:template>
179 <!-- Linked filter effect -->
180 <xsl:template mode="filter_effect" match="*">
181 <xsl:choose>
182     <xsl:when test="@filter and starts-with(@filter, 'url(#')">
183         <xsl:attribute name="Effect">
184             <xsl:value-of select="concat('{StaticResource ', substring-before(substring-after(@filter, 'url(#'), ')'), '}')" />
185         </xsl:attribute>
186     </xsl:when>
187     <xsl:when test="@style and contains(@style, 'filter:url(#')">
188         <xsl:attribute name="Effect">
189             <xsl:value-of select="concat('{StaticResource ', substring-before(substring-after(@style, 'filter:url(#'), ')'), '}')" />
190         </xsl:attribute>
191     </xsl:when>
192 </xsl:choose>
193 </xsl:template>
195 <!-- Linear gradient -->
196 <xsl:template mode="forward" match="*[name(.) = 'linearGradient']">
197   <LinearGradientBrush>
198     <xsl:if test="@id"><xsl:attribute name="x:Key"><xsl:value-of select="@id" /></xsl:attribute></xsl:if>
199     <xsl:attribute name="MappingMode">
200       <xsl:choose>
201         <xsl:when test="@gradientUnits = 'userSpaceOnUse' ">Absolute</xsl:when>
202         <xsl:otherwise>RelativeToBoundingBox</xsl:otherwise>
203       </xsl:choose>
204     </xsl:attribute>
205     <xsl:if test="@spreadMethod">
206       <xsl:attribute name="SpreadMethod">
207         <xsl:choose>
208           <xsl:when test="@spreadMethod = 'pad'">Pad</xsl:when>
209           <xsl:when test="@spreadMethod = 'reflect'">Reflect</xsl:when>
210           <xsl:when test="@spreadMethod = 'repeat'">Repeat</xsl:when>
211         </xsl:choose>
212       </xsl:attribute>
213     </xsl:if>
214     <xsl:choose>
215       <xsl:when test="@x1 and @y1 and @x2 and @y2">
216         <xsl:choose>
217           <xsl:when test="contains(@x1, '%') and contains(@y1, '%')">
218             <xsl:attribute name="StartPoint"><xsl:value-of select="concat(substring-before(@x1, '%') div 100, ',', substring-before(@y1,'%') div 100)" /></xsl:attribute>
219           </xsl:when>
220           <xsl:otherwise>
221             <xsl:attribute name="StartPoint"><xsl:value-of select="concat(@x1, ',', @y1)" /></xsl:attribute>
222           </xsl:otherwise>
223         </xsl:choose>
224         <xsl:choose>
225           <xsl:when test="contains(@x2, '%') and contains(@y2, '%')">
226             <xsl:attribute name="EndPoint"><xsl:value-of select="concat(substring-before(@x2, '%') div 100, ',', substring-before(@y2,'%') div 100)" /></xsl:attribute>
227           </xsl:when>
228           <xsl:otherwise>
229             <xsl:attribute name="EndPoint"><xsl:value-of select="concat(@x2, ',', @y2)" /></xsl:attribute>
230           </xsl:otherwise>
231         </xsl:choose>  
232       </xsl:when>
233       <xsl:otherwise>
234         <xsl:attribute name="StartPoint"><xsl:value-of select="'0,0'" /></xsl:attribute>
235         <xsl:attribute name="EndPoint"><xsl:value-of select="'1,1'" /></xsl:attribute>
236       </xsl:otherwise>
237     </xsl:choose>
238     <LinearGradientBrush.GradientStops>
239       <GradientStopCollection>
240         <xsl:choose>
241           <xsl:when test="@xlink:href">
242             <xsl:variable name="reference_id" select="@xlink:href" />
243             <xsl:apply-templates mode="forward" select="//*[name(.) = 'linearGradient' and $reference_id = concat('#', @id)]/*" />
244           </xsl:when>
245           <xsl:otherwise><xsl:apply-templates mode="forward" /></xsl:otherwise>
246         </xsl:choose>
247       </GradientStopCollection>
248     </LinearGradientBrush.GradientStops>
249     <xsl:if test="@gradientTransform">
250     <LinearGradientBrush.Transform>
251       <xsl:apply-templates mode="transform" select="." />
252     </LinearGradientBrush.Transform>
253   </xsl:if>
254   </LinearGradientBrush>
255 </xsl:template>
257 <!-- Radial gradient -->
258 <xsl:template mode="forward" match="*[name(.) = 'radialGradient']">
259   <RadialGradientBrush>
260     <xsl:if test="@id"><xsl:attribute name="x:Key"><xsl:value-of select="@id" /></xsl:attribute></xsl:if>
261     <xsl:attribute name="MappingMode">
262       <xsl:choose>
263         <xsl:when test="@gradientUnits = 'userSpaceOnUse' ">Absolute</xsl:when>
264         <xsl:otherwise>RelativeToBoundingBox</xsl:otherwise>
265       </xsl:choose>
266     </xsl:attribute>
267     <xsl:if test="@spreadMethod">
268       <xsl:attribute name="SpreadMethod">
269         <xsl:choose>
270           <xsl:when test="@spreadMethod = 'pad'">Pad</xsl:when>
271           <xsl:when test="@spreadMethod = 'reflect'">Reflect</xsl:when>
272           <xsl:when test="@spreadMethod = 'repeat'">Repeat</xsl:when>
273         </xsl:choose>
274       </xsl:attribute>
275     </xsl:if>
276     <xsl:if test="@cx and @cy">
277       <xsl:attribute name="Center">
278         <xsl:choose>
279           <xsl:when test="contains(@cx, '%') and contains(@cy, '%')">
280             <xsl:value-of select="concat(number(substring-before(@cx, '%')) div 100, ',', number(substring-before(@cy, '%')) div 100)" />
281           </xsl:when>
282           <xsl:otherwise>
283             <xsl:value-of select="concat(@cx, ',', @cy)" />
284           </xsl:otherwise>
285         </xsl:choose>
286       </xsl:attribute>
287     </xsl:if>  
288     <xsl:if test="@fx and @fy">
289       <xsl:attribute name="GradientOrigin">
290         <xsl:choose>
291           <xsl:when test="contains(@fx, '%') and contains(@fy, '%')">
292             <xsl:value-of select="concat(number(substring-before(@fx, '%')) div 100, ',', number(substring-before(@fy, '%')) div 100)" />
293           </xsl:when>
294           <xsl:otherwise>
295             <xsl:value-of select="concat(@fx, ',', @fy)" />
296           </xsl:otherwise>
297         </xsl:choose>
298       </xsl:attribute>
299     </xsl:if>
300     <xsl:if test="@r">
301       <xsl:choose>
302         <xsl:when test="contains(@r, '%')">
303           <xsl:attribute name="RadiusX"><xsl:value-of select="number(substring-before(@r, '%')) div 100" /></xsl:attribute>
304           <xsl:attribute name="RadiusY"><xsl:value-of select="number(substring-before(@r, '%')) div 100" /></xsl:attribute>
305         </xsl:when>
306         <xsl:otherwise>
307           <xsl:attribute name="RadiusX"><xsl:value-of select="@r" /></xsl:attribute>
308           <xsl:attribute name="RadiusY"><xsl:value-of select="@r" /></xsl:attribute>
309         </xsl:otherwise>
310       </xsl:choose>
311     </xsl:if>
312     <RadialGradientBrush.GradientStops>
313       <GradientStopCollection>
314         <xsl:choose>
315           <xsl:when test="@xlink:href">
316             <xsl:variable name="reference_id" select="@xlink:href" />
317             <xsl:apply-templates mode="forward" select="//*[name(.) = 'linearGradient' and $reference_id = concat('#', @id)]/*" />
318           </xsl:when>
319           <xsl:otherwise><xsl:apply-templates mode="forward" /></xsl:otherwise>
320         </xsl:choose>
321       </GradientStopCollection>
322     </RadialGradientBrush.GradientStops>
323     <xsl:if test="@gradientTransform">
324     <RadialGradientBrush.Transform>
325       <xsl:apply-templates mode="transform" select="." />
326     </RadialGradientBrush.Transform>
327     </xsl:if>
328   </RadialGradientBrush>
329 </xsl:template>
331 <!-- Generic gradient stops -->
332 <xsl:template mode="forward" match="*[name(.) = 'stop']">
333   <GradientStop>
334     <!--xsl:apply-templates mode="stop_opacity" select="." /-->
335     <xsl:apply-templates mode="stop_color" select="." />
336     <xsl:apply-templates mode="offset" select="." />
337     <xsl:apply-templates mode="forward" />
338   </GradientStop>
339 </xsl:template>
341 <!-- Clipping -->
342 <xsl:template mode="clip" match="*">
343   <xsl:choose>
344     <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>
345     <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>
346     <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>
347     <xsl:when test="clipPath"><xsl:apply-templates mode="forward" /></xsl:when>
348   </xsl:choose>
349 </xsl:template>
351 <!--
352 // Misc templates //
354 * Object description
355 * Id converter
356 * Decimal to hexadecimal converter
357 * Unit to pixel converter
358 * Title and description
359 * Misc ignored stuff (markers, patterns, styles)
360 * Symbols
361 * Use
362 * RDF and foreign objects
363 * Unknows tags
364 -->
366 <!-- Object description -->
367 <xsl:template mode="desc" match="*">
368   <xsl:if test="*[name(.) = 'desc']/text()"><xsl:attribute name="Tag"><xsl:value-of select="*[name(.) = 'desc']/text()" /></xsl:attribute></xsl:if>
369 </xsl:template>
371 <!-- Id converter. Removes "-" from the original id. -->
372 <xsl:template mode="id" match="*">
373 <xsl:if test="@id">
374   <xsl:attribute name="Name"><xsl:value-of select="translate(@id, '- ', '')" /></xsl:attribute>
375   <!--
376     <xsl:attribute name="x:Key"><xsl:value-of select="translate(@id, '- ', '')" /></xsl:attribute>
377   -->
378 </xsl:if>
379 </xsl:template>
381 <!-- Decimal to hexadecimal converter -->
382 <xsl:template name="to_hex">
383   <xsl:param name="convert" />
384   <xsl:value-of select="concat(substring('0123456789ABCDEF', 1 + floor(round($convert) div 16), 1), substring('0123456789ABCDEF', 1 + round($convert) mod 16, 1))" />
385 </xsl:template>
387 <!-- Unit to pixel converter
388 Values with units (except %) are converted to pixels and rounded.
389 Unknown units are kept. -->
390 <xsl:template name="convert_unit">
391   <xsl:param name="convert_value" />
392       <xsl:choose>
393         <xsl:when test="contains($convert_value, 'px')">
394             <xsl:value-of select="round(translate($convert_value, 'px', ''))" />
395         </xsl:when>
396         <xsl:when test="contains($convert_value, 'pt')">
397             <xsl:value-of select="round(translate($convert_value, 'pt', '') * 1.25)" />
398         </xsl:when>
399         <xsl:when test="contains($convert_value, 'pc')">
400             <xsl:value-of select="round(translate($convert_value, 'pc', '') * 15)" />
401         </xsl:when>
402         <xsl:when test="contains($convert_value, 'mm')">
403             <xsl:value-of select="round(translate($convert_value, 'mm', '') * 3.543307)" />
404         </xsl:when>
405         <xsl:when test="contains($convert_value, 'cm')">
406             <xsl:value-of select="round(translate($convert_value, 'cm', '') * 35.43307)" />
407         </xsl:when>
408         <xsl:when test="contains($convert_value, 'in')">
409             <xsl:value-of select="round(translate($convert_value, 'in', '') * 90)" />
410         </xsl:when>
411         <xsl:when test="contains($convert_value, 'ft')">
412             <xsl:value-of select="round(translate($convert_value, 'ft', '') * 1080)" />
413         </xsl:when>
414         <xsl:when test="not(string(number($convert_value))='NaN')">
415             <xsl:value-of select="round($convert_value)" />
416         </xsl:when>
417         <xsl:otherwise>
418             <xsl:value-of select="$convert_value" />
419         </xsl:otherwise>
420       </xsl:choose>
421 </xsl:template>
423 <!-- Title and description
424 Blank template. Title is ignored and desc is converted to Tag in the mode="desc" template
425 -->
426 <xsl:template mode="forward" match="*[name(.) = 'title' or name(.) = 'desc']">
427   <!-- -->
428 </xsl:template>
430 <!-- Misc ignored stuff (markers, patterns, styles) -->
431 <xsl:template mode="forward" match="*[name(.) = 'marker' or name(.) = 'pattern' or name(.) = 'style']">
432   <!-- -->
433 </xsl:template>
435 <!-- Symbols -->
436 <xsl:template mode="forward" match="*[name(.) = 'symbol']">
437   <Style>
438     <xsl:if test="@id"><xsl:attribute name="x:Key"><xsl:value-of select="@id" /></xsl:attribute></xsl:if>
439     <Canvas>
440       <xsl:apply-templates mode="forward" />
441     </Canvas>
442   </Style>
443 </xsl:template>
445 <!-- Use -->
446 <xsl:template mode="forward" match="*[name(.) = 'use']">
447   <Canvas>
448     <xsl:if test="@xlink:href"><xsl:attribute name="Style"><xsl:value-of select="@xlink:href" /></xsl:attribute></xsl:if>
449     <!--xsl:apply-templates mode="transform" select="." /-->
450     <xsl:apply-templates mode="forward" />
451   </Canvas>
452 </xsl:template>
454 <!-- RDF and foreign objects -->
455 <xsl:template mode="forward" match="rdf:RDF | *[name(.) = 'foreignObject']">
456   <!-- -->
457 </xsl:template>
459 <!-- Unknown tags -->
460 <xsl:template match="*">
461 <xsl:comment><xsl:value-of select="concat('Unknown tag: ', name(.))" /></xsl:comment>
462 </xsl:template>
465 <!--
466 // Colors and patterns //
468 * Generic color template
469 * Fill
470 * Fill opacity
471 * Fill rule
472 * Generic fill template
473 * Stroke
474 * Stroke opacity
475 * Generic stroke template
476 * Stroke width
477 * Stroke mitterlimit
478 * Stroke dasharray
479 * Stroke dashoffset
480 * Linejoin SVG to XAML converter
481 * Stroke linejoin
482 * Linecap SVG to XAML converter
483 * Stroke linecap
484 * Gradient stop
485 * Gradient stop opacity
486 * Gradient stop offset
487 -->
489 <!-- Generic color template -->
490 <xsl:template name="template_color">
491   <xsl:param name="colorspec" />
492   <xsl:param name="opacityspec" />
493   <xsl:choose>
494     <xsl:when test="starts-with($colorspec, 'rgb(') and not(contains($colorspec , '%'))">
495       <xsl:value-of select="'#'" />
496       <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>
497       <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>
498       <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>
499       <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>
500     </xsl:when>
501     <xsl:when test="starts-with($colorspec, 'rgb(') and contains($colorspec , '%')">
502       <xsl:value-of select="'#'" />
503       <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>
504       <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>
505       <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>
506       <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>
507     </xsl:when>
508     <xsl:when test="starts-with($colorspec, '#')">
509       <xsl:value-of select="'#'" />
510       <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>
511       <xsl:choose>
512         <xsl:when test="string-length(substring-after($colorspec, '#')) = 3">
513           <xsl:variable name="colorspec3"><xsl:value-of select="translate(substring-after($colorspec, '#'), 'abcdefgh', 'ABCDEFGH')" /></xsl:variable>
514           <xsl:value-of select="concat(substring($colorspec3, 1, 1), substring($colorspec3, 1, 1))" />
515           <xsl:value-of select="concat(substring($colorspec3, 2, 1), substring($colorspec3, 2, 1))" />
516           <xsl:value-of select="concat(substring($colorspec3, 3, 1), substring($colorspec3, 3, 1))" />
517         </xsl:when>
518         <xsl:otherwise><xsl:value-of select="translate(substring-after($colorspec, '#'), 'abcdefgh', 'ABCDEFGH')" /></xsl:otherwise>
519       </xsl:choose>
520     </xsl:when>
521     <xsl:otherwise>
522       <xsl:variable name="named_color_hex" select="document('colors.xml')/colors/color[@name = translate($colorspec, 'ABCDEFGHIJKLMNOPQRSTUVWXYZ', 'abcdefghijklmnopqrstuvwxyz')]/@hex" />
523       <xsl:choose>
524         <xsl:when test="$named_color_hex and $named_color_hex != ''">
525           <xsl:value-of select="'#'" />
526           <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>
527           <xsl:value-of select="substring-after($named_color_hex, '#')" />
528         </xsl:when>
529         <xsl:otherwise><xsl:value-of select="$colorspec" /></xsl:otherwise>
530       </xsl:choose>
531     </xsl:otherwise>
532   </xsl:choose>
533 </xsl:template>
535 <!-- Fill -->
536 <xsl:template mode="fill" match="*">
537   <xsl:choose>
538     <xsl:when test="@fill and starts-with(@fill, 'url(#')"><xsl:value-of select="concat('{StaticResource ', substring-before(substring-after(@fill, 'url(#'), ')'), '}')" /></xsl:when>
539     <xsl:when test="@fill"><xsl:value-of select="@fill" /></xsl:when>
540     <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>
541     <xsl:when test="@style and contains(@style, 'fill:')">
542       <xsl:variable name="Fill" select="substring-after(@style, 'fill:')" />
543       <xsl:choose>
544         <xsl:when test="contains($Fill, ';')">
545           <xsl:value-of select="substring-before($Fill, ';')" />
546         </xsl:when>
547         <xsl:otherwise><xsl:value-of select="$Fill" /></xsl:otherwise>
548       </xsl:choose>
549     </xsl:when>
550     <xsl:when test="name(..) = 'g' or name(..) = 'svg'"><xsl:apply-templates mode="fill" select="parent::*"/></xsl:when>
551   </xsl:choose>
552 </xsl:template>
554 <!-- Fill opacity -->
555 <xsl:template mode="fill_opacity" match="*">
556   <xsl:choose>
557     <xsl:when test="@fill-opacity"><xsl:value-of select="@fill-opacity" /></xsl:when>
558     <xsl:when test="@style and contains(@style, 'fill-opacity:')">
559       <xsl:variable name="Opacity" select="substring-after(@style, 'fill-opacity:')" />
560       <xsl:choose>
561         <xsl:when test="contains($Opacity, ';')"><xsl:value-of select="substring-before($Opacity, ';')" /></xsl:when>
562         <xsl:otherwise><xsl:value-of select="$Opacity" /></xsl:otherwise>
563       </xsl:choose>
564     </xsl:when>
565     <xsl:when test="name(..) = 'g' or name(..) = 'svg'"><xsl:apply-templates mode="fill_opacity" select="parent::*" /></xsl:when>
566   </xsl:choose>
567 </xsl:template>
569 <!-- Fill rule -->
570 <xsl:template mode="fill_rule" match="*">
571   <xsl:choose>
572     <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>
573     <xsl:when test="@style and contains(@style, 'fill-rule:')">
574       <xsl:variable name="FillRule" select="substring-after(@style, 'fill-rule:')" />
575       <xsl:choose>
576         <xsl:when test="contains($FillRule, ';')">
577           <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>
578         </xsl:when>
579         <xsl:when test="$FillRule = 'nonzero' or $FillRule = 'evenodd'"><xsl:attribute name="FillRule"><xsl:value-of select="$FillRule" /></xsl:attribute></xsl:when>
580       </xsl:choose>
581     </xsl:when>
582     <xsl:when test="name(..) = 'g' or name(..) = 'svg'"><xsl:apply-templates mode="fill_rule" select="parent::*"/></xsl:when>
583     <xsl:otherwise><xsl:attribute name="FillRule">NonZero</xsl:attribute></xsl:otherwise>
584   </xsl:choose>
585 </xsl:template>
587 <!-- Generic fill template -->
588 <xsl:template mode="template_fill" match="*">
589   <xsl:variable name="fill"><xsl:apply-templates mode="fill" select="." /></xsl:variable>
590   <xsl:variable name="fill_opacity"><xsl:apply-templates mode="fill_opacity" select="." /></xsl:variable>
591   <xsl:if test="not($fill = 'none')">
592     <xsl:attribute name="Fill">
593       <xsl:choose>
594         <xsl:when test="$fill != ''">
595           <xsl:call-template name="template_color">
596             <xsl:with-param name="colorspec">
597               <xsl:if test="$fill != 'none'"><xsl:value-of select="$fill" /></xsl:if>
598             </xsl:with-param>
599             <xsl:with-param name="opacityspec"><xsl:value-of select="$fill_opacity" /></xsl:with-param>
600           </xsl:call-template>
601         </xsl:when>
602         <xsl:otherwise>#000000</xsl:otherwise>
603       </xsl:choose>
604     </xsl:attribute>
605   </xsl:if>
606 </xsl:template>
608 <!-- Stroke -->
609 <xsl:template mode="stroke" match="*">
610   <xsl:choose>
611     <xsl:when test="@stroke and starts-with(@stroke, 'url(#')"><xsl:value-of select="concat('{StaticResource ', substring-before(substring-after(@stroke, 'url(#'), ')'), '}')" /></xsl:when>
612     <xsl:when test="@stroke and @stroke != 'none'"><xsl:value-of select="@stroke" /></xsl:when>
613     <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>
614     <xsl:when test="@style and contains(@style, 'stroke:')">
615       <xsl:variable name="Stroke" select="substring-after(@style, 'stroke:')" />
616       <xsl:choose>
617         <xsl:when test="contains($Stroke, ';')">
618           <xsl:if test="substring-before($Stroke, ';') != 'none'"><xsl:value-of select="substring-before($Stroke, ';')" /></xsl:if>
619         </xsl:when>
620         <xsl:when test="$Stroke != 'none'"><xsl:value-of select="$Stroke" /></xsl:when>
621       </xsl:choose>
622     </xsl:when>
623     <xsl:when test="name(..) = 'g' or name(..) = 'svg'"><xsl:apply-templates mode="stroke" select="parent::*"/></xsl:when>
624   </xsl:choose>
625 </xsl:template>
627 <!-- Stroke opacity -->
628 <xsl:template mode="stroke_opacity" match="*">
629   <xsl:choose>
630     <xsl:when test="@stroke-opacity"><xsl:value-of select="@stroke-opacity" /></xsl:when>
631     <xsl:when test="@style and contains(@style, 'stroke-opacity:')">
632       <xsl:variable name="Opacity" select="substring-after(@style, 'stroke-opacity:')" />
633       <xsl:choose>
634         <xsl:when test="contains($Opacity, ';')"><xsl:value-of select="substring-before($Opacity, ';')" /></xsl:when>
635         <xsl:otherwise><xsl:value-of select="$Opacity" /></xsl:otherwise>
636       </xsl:choose>
637     </xsl:when>
638     <xsl:when test="name(..) = 'g' or name(..) = 'svg'"><xsl:apply-templates mode="stroke_opacity" select="parent::*" /></xsl:when>
639   </xsl:choose>
640 </xsl:template>
642 <!-- Generic stroke template -->
643 <xsl:template mode="template_stroke" match="*">
644   <xsl:variable name="stroke"><xsl:apply-templates mode="stroke" select="." /></xsl:variable>
645   <xsl:variable name="stroke_opacity"><xsl:apply-templates mode="stroke_opacity" select="." /></xsl:variable>
646   <xsl:if test="$stroke != ''">
647     <xsl:attribute name="Stroke">
648       <xsl:call-template name="template_color">
649         <xsl:with-param name="colorspec"><xsl:value-of select="$stroke" /></xsl:with-param>
650         <xsl:with-param name="opacityspec"><xsl:value-of select="$stroke_opacity" /></xsl:with-param>
651       </xsl:call-template>
652     </xsl:attribute>
653   </xsl:if>
654 </xsl:template>
656 <!-- Stroke width -->
657 <xsl:template mode="stroke_width" match="*">
658   <xsl:choose>
659     <xsl:when test="@stroke-width">
660         <xsl:attribute name="StrokeThickness"><xsl:value-of select="@stroke-width" /></xsl:attribute>
661     </xsl:when>
662     <xsl:when test="@style and contains(@style, 'stroke-width:')">
663       <xsl:attribute name="StrokeThickness">
664           <xsl:call-template name="convert_unit">
665             <xsl:with-param name="convert_value">
666             <xsl:choose>
667               <xsl:when test="contains(substring-after(@style, 'stroke-width:'), ';')"><xsl:value-of select="substring-before(substring-after(@style, 'stroke-width:'), ';')" /></xsl:when>
668               <xsl:otherwise><xsl:value-of select="substring-after(@style, 'stroke-width:')" /></xsl:otherwise>
669             </xsl:choose>
670             </xsl:with-param>
671         </xsl:call-template> 
672       </xsl:attribute>
673     </xsl:when>
674     <xsl:when test="name(..) = 'g' or name(..) = 'svg'"><xsl:apply-templates mode="stroke_width" select="parent::*"/></xsl:when>
675   </xsl:choose>
676 </xsl:template>
678 <!-- Stroke miterlimit -->
679 <xsl:template mode="stroke_miterlimit" match="*">
680   <xsl:choose>
681     <xsl:when test="@stroke-miterlimit"><xsl:attribute name="StrokeMiterLimit"><xsl:value-of select="@stroke-miterlimit" /></xsl:attribute></xsl:when>
682     <xsl:when test="@style and contains(@style, 'stroke-miterlimit:')">
683       <xsl:variable name="StrokeMiterLimit" select="substring-after(@style, 'stroke-miterlimit:')" />
684       <xsl:attribute name="StrokeMiterLimit">
685         <xsl:choose>
686           <xsl:when test="contains($StrokeMiterLimit, ';')"><xsl:value-of select="substring-before($StrokeMiterLimit, ';')" /></xsl:when>
687           <xsl:otherwise><xsl:value-of select="$StrokeMiterLimit" /></xsl:otherwise>
688         </xsl:choose>
689       </xsl:attribute>
690     </xsl:when>
691     <xsl:when test="name(..) = 'g' or name(..) = 'svg'"><xsl:apply-templates mode="stroke_miterlimit" select="parent::*"/></xsl:when>
692   </xsl:choose>
693 </xsl:template>
695 <!-- Stroke dasharray -->
696 <xsl:template mode="stroke_dasharray" match="*">
697   <!-- stroke-dasharray="10,30,20,30" becomes StrokeDashArray="1 3 2 3" ?? -->
698   <xsl:choose>
699     <xsl:when test="@stroke-dasharray and @stroke-dasharray != 'none'"><xsl:attribute name="StrokeDashArray"><xsl:value-of select="@stroke-dasharray" /></xsl:attribute></xsl:when>
700     <xsl:when test="@style and contains(@style, 'stroke-dasharray:')">
701       <xsl:variable name="StrokeDashArray" select="substring-after(@style, 'stroke-dasharray:')" />
702       <xsl:choose>
703         <xsl:when test="contains($StrokeDashArray, ';')">
704           <xsl:if test="substring-before($StrokeDashArray, ';') != 'none'"><xsl:attribute name="StrokeDashArray"><xsl:value-of select="substring-before($StrokeDashArray, ';')" /></xsl:attribute></xsl:if>
705         </xsl:when>
706         <xsl:when test="$StrokeDashArray != 'none'"><xsl:attribute name="StrokeDashArray"><xsl:value-of select="$StrokeDashArray" /></xsl:attribute></xsl:when>
707       </xsl:choose>
708     </xsl:when>
709     <xsl:when test="name(..) = 'g' or name(..) = 'svg'"><xsl:apply-templates mode="stroke_dasharray" select="parent::*"/></xsl:when>
710   </xsl:choose>
711 </xsl:template>
713 <!-- Stroke dashoffset -->
714 <xsl:template mode="stroke_dashoffset" match="*">
715   <xsl:choose>
716     <xsl:when test="@stroke-dashoffset"><xsl:attribute name="StrokeDashOffset"><xsl:value-of select="@stroke-dashoffset" /></xsl:attribute></xsl:when>
717     <xsl:when test="@style and contains(@style, 'stroke-dashoffset:')">
718       <xsl:variable name="StrokeDashOffset" select="substring-after(@style, 'stroke-dashoffset:')" />
719       <xsl:attribute name="StrokeDashOffset">
720         <xsl:choose>
721           <xsl:when test="contains($StrokeDashOffset, ';')"><xsl:value-of select="substring-before($StrokeDashOffset, ';')" /></xsl:when>
722           <xsl:otherwise><xsl:value-of select="$StrokeDashOffset" /></xsl:otherwise>
723         </xsl:choose>
724       </xsl:attribute>
725     </xsl:when>
726     <xsl:when test="name(..) = 'g' or name(..) = 'svg'"><xsl:apply-templates mode="stroke_dashoffset" select="parent::*"/></xsl:when>
727   </xsl:choose>
728 </xsl:template>
730 <!-- Linejoin SVG to XAML converter -->
731 <xsl:template name="linejoin_svg_to_xaml">
732   <xsl:param name="linejoin" />
733   <xsl:choose>
734     <xsl:when test="$linejoin = 'bevel'">Bevel</xsl:when>
735     <xsl:when test="$linejoin = 'round'">Round</xsl:when>
736     <xsl:otherwise>Miter</xsl:otherwise>
737   </xsl:choose>
738 </xsl:template>
740 <!-- Stroke linejoin -->
741 <xsl:template mode="stroke_linejoin" match="*">
742   <xsl:choose>
743     <xsl:when test="@stroke-miterlimit">
744       <xsl:attribute name="StrokeLineJoin">
745         <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>
746       </xsl:attribute></xsl:when>
747     <xsl:when test="@style and contains(@style, 'stroke-linejoin:')">
748       <xsl:variable name="StrokeLineJoin" select="substring-after(@style, 'stroke-linejoin:')" />
749       <xsl:attribute name="StrokeLineJoin">
750         <xsl:choose>
751           <xsl:when test="contains($StrokeLineJoin, ';')">
752             <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>
753           </xsl:when>
754           <xsl:otherwise>
755             <xsl:call-template name="linejoin_svg_to_xaml"><xsl:with-param name="linejoin"><xsl:value-of select="$StrokeLineJoin" /></xsl:with-param></xsl:call-template>
756           </xsl:otherwise>
757         </xsl:choose>
758       </xsl:attribute>
759     </xsl:when>
760     <xsl:when test="name(..) = 'g' or name(..) = 'svg'"><xsl:apply-templates mode="stroke_linejoin" select="parent::*"/></xsl:when>
761   </xsl:choose>
762 </xsl:template>
764 <!-- Linecap SVG to XAML converter -->
765 <xsl:template name="linecap_svg_to_xaml">
766   <xsl:param name="linecap" />
767   <xsl:choose>
768     <xsl:when test="$linecap = 'round'">Round</xsl:when>
769     <xsl:when test="$linecap = 'square'">Square</xsl:when>
770     <xsl:otherwise>Flat</xsl:otherwise>
771   </xsl:choose>
772 </xsl:template>
774 <!-- Stroke linecap -->
775 <xsl:template mode="stroke_linecap" match="*">
776   <xsl:choose>
777     <xsl:when test="@stroke-linecap">
778       <xsl:attribute name="StrokeStartLineCap">
779         <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>
780       </xsl:attribute>
781       <xsl:attribute name="StrokeEndLineCap">
782         <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>
783       </xsl:attribute></xsl:when>
784     <xsl:when test="@style and contains(@style, 'stroke-linecap:')">
785       <xsl:variable name="StrokeStartLineCap" select="substring-after(@style, 'stroke-linecap:')" />
786       <xsl:variable name="StrokeEndLineCap" select="substring-after(@style, 'stroke-linecap:')" />
787       <xsl:attribute name="StrokeStartLineCap">
788         <xsl:choose>
789           <xsl:when test="contains($StrokeStartLineCap, ';')">
790             <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>
791           </xsl:when>
792           <xsl:otherwise>
793             <xsl:call-template name="linecap_svg_to_xaml"><xsl:with-param name="linecap"><xsl:value-of select="$StrokeStartLineCap" /></xsl:with-param></xsl:call-template>
794           </xsl:otherwise>
795         </xsl:choose>
796       </xsl:attribute>
797       <xsl:attribute name="StrokeEndLineCap">
798         <xsl:choose>
799           <xsl:when test="contains($StrokeEndLineCap, ';')">
800             <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>
801           </xsl:when>
802           <xsl:otherwise>
803             <xsl:call-template name="linecap_svg_to_xaml"><xsl:with-param name="linecap"><xsl:value-of select="$StrokeEndLineCap" /></xsl:with-param></xsl:call-template>
804           </xsl:otherwise>
805         </xsl:choose>
806       </xsl:attribute>
807     </xsl:when>
808     <xsl:when test="name(..) = 'g' or name(..) = 'svg'"><xsl:apply-templates mode="stroke_linecap" select="parent::*"/></xsl:when>
809   </xsl:choose>
810 </xsl:template>
812 <!-- Gradient stops -->
813 <xsl:template mode="stop_color" match="*">
814   <xsl:variable name="Opacity">
815     <xsl:choose>
816       <xsl:when test="@stop-opacity"><xsl:value-of select="@stop-opacity" /></xsl:when>
817       <xsl:when test="@style and contains(@style, 'stop-opacity:')">
818         <xsl:variable name="temp_opacity" select="substring-after(@style, 'stop-opacity:')" />
819         <xsl:choose>
820           <xsl:when test="contains($temp_opacity, ';')"><xsl:value-of select="substring-before($temp_opacity, ';')" /></xsl:when>
821           <xsl:otherwise><xsl:value-of select="$temp_opacity" /></xsl:otherwise>
822         </xsl:choose>
823       </xsl:when>
824       <xsl:otherwise><xsl:value-of select="''" /></xsl:otherwise>
825     </xsl:choose>
826   </xsl:variable>
827   <xsl:variable name="hex_opacity">
828     <xsl:choose>
829       <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>
830       <xsl:otherwise><xsl:value-of select="$Opacity" /></xsl:otherwise>
831     </xsl:choose>
832   </xsl:variable>
833   <xsl:variable name="stopcolor">
834     <xsl:choose>
835       <xsl:when test="@stop-color">
836         <xsl:call-template name="template_color"><xsl:with-param name="colorspec"><xsl:value-of select="@stop-color" /></xsl:with-param></xsl:call-template>
837       </xsl:when>
838       <xsl:when test="@style and contains(@style, 'stop-color:')">
839         <xsl:variable name="Color" select="substring-after(@style, 'stop-color:')" />
840         <xsl:choose>
841           <xsl:when test="contains($Color, ';')">
842             <xsl:call-template name="template_color"><xsl:with-param name="colorspec"><xsl:value-of select="substring-before($Color, ';')" /></xsl:with-param></xsl:call-template>
843           </xsl:when>
844           <xsl:otherwise>
845             <xsl:call-template name="template_color"><xsl:with-param name="colorspec"><xsl:value-of select="$Color" /></xsl:with-param></xsl:call-template>
846           </xsl:otherwise>
847         </xsl:choose>
848       </xsl:when>
849       <xsl:when test="name(..) = 'g' or name(..) = 'svg'"><xsl:apply-templates mode="stop_color" select="parent::*"/></xsl:when>
850       <xsl:otherwise>#000</xsl:otherwise>
851     </xsl:choose>
852   </xsl:variable>
853   <xsl:attribute name="Color">
854     <xsl:choose>
855       <xsl:when test="$hex_opacity != '' and starts-with($stopcolor, '#')"><xsl:value-of select="concat('#', $hex_opacity, substring-after($stopcolor, '#'))" /></xsl:when>
856       <xsl:otherwise><xsl:value-of select="$stopcolor" /></xsl:otherwise>
857     </xsl:choose>
858   </xsl:attribute>
859 </xsl:template>
861 <!-- Gradient stop opacity -->
862 <xsl:template mode="stop_opacity" match="*">
863   <xsl:choose>
864     <xsl:when test="@stop-opacity"><xsl:attribute name="Opacity"><xsl:value-of select="@stop-opacity" /></xsl:attribute></xsl:when>
865     <xsl:when test="@style and contains(@style, 'stop-opacity:')">
866       <xsl:variable name="Opacity" select="substring-after(@style, 'stop-opacity:')" />
867       <xsl:attribute name="Opacity">
868         <xsl:choose>
869           <xsl:when test="contains($Opacity, ';')"><xsl:value-of select="substring-before($Opacity, ';')" /></xsl:when>
870           <xsl:otherwise><xsl:value-of select="$Opacity" /></xsl:otherwise>
871         </xsl:choose>
872       </xsl:attribute>
873     </xsl:when>
874     <xsl:when test="name(..) = 'g' or name(..) = 'svg'"><xsl:apply-templates mode="stop_opacity" select="parent::*"/></xsl:when>
875   </xsl:choose>
876 </xsl:template>
878 <!-- Gradient stop offset -->
879 <xsl:template mode="offset" match="*">
880   <xsl:choose>
881     <xsl:when test="@offset">
882       <xsl:attribute name="Offset">
883         <xsl:choose>
884           <xsl:when test="contains(@offset, '%')"><xsl:value-of select="number(substring-before(@offset, '%')) div 100" /></xsl:when>
885           <xsl:otherwise><xsl:value-of select="@offset" /></xsl:otherwise>
886         </xsl:choose>
887       </xsl:attribute>
888     </xsl:when>
889     <xsl:when test="@style and contains(@style, 'offset:')">
890       <xsl:variable name="Offset" select="substring-after(@style, 'offset:')" />
891       <xsl:attribute name="Offset">
892         <xsl:choose>
893           <xsl:when test="contains($Offset, '%')"><xsl:value-of select="number(substring-before($Offset, '%')) div 100" /></xsl:when>        
894           <xsl:when test="contains($Offset, ';')"><xsl:value-of select="substring-before($Offset, ';')" /></xsl:when>
895           <xsl:otherwise><xsl:value-of select="$Offset" /></xsl:otherwise>
896         </xsl:choose>
897       </xsl:attribute>
898     </xsl:when>
899     <xsl:when test="name(..) = 'g' or name(..) = 'svg'"><xsl:apply-templates mode="stop_offset" select="parent::*"/></xsl:when>
900   </xsl:choose>
901 </xsl:template>
903 <!-- 
904 // Transforms //
905 All the matrix, translate, rotate... stuff.
906 Fixme: XAML transforms don't show the same result as SVG ones with the same values.
908 * Parse transform
909 * Apply transform
910 * Apply transform v2
911 -->
913 <!-- Parse transform -->
914 <xsl:template name="parse_transform">
915   <xsl:param name="input" />
916   <xsl:choose>
917     <xsl:when test="starts-with($input, 'matrix(')">
918       <MatrixTransform><xsl:attribute name="Matrix"><xsl:value-of select="substring-before(substring-after($input, 'matrix('), ')')" /></xsl:attribute></MatrixTransform>
919       <xsl:call-template name="parse_transform"><xsl:with-param name="input" select="substring-after($input, ') ')" /></xsl:call-template>      
920     </xsl:when>
921     <xsl:when test="starts-with($input, 'scale(')">
922       <ScaleTransform>
923         <xsl:variable name="scale" select="substring-before(substring-after($input, 'scale('), ')')" />
924         <xsl:choose>
925           <xsl:when test="contains($scale, ',')">
926             <xsl:attribute name="ScaleX"><xsl:value-of select="substring-before($scale, ',')" /></xsl:attribute>
927             <xsl:attribute name="ScaleY"><xsl:value-of select="substring-after($scale, ',')" /></xsl:attribute>
928           </xsl:when>
929           <xsl:otherwise>
930             <xsl:attribute name="ScaleX"><xsl:value-of select="$scale" /></xsl:attribute>
931             <xsl:attribute name="ScaleY"><xsl:value-of select="$scale" /></xsl:attribute>
932           </xsl:otherwise>
933         </xsl:choose>
934       </ScaleTransform>
935       <xsl:call-template name="parse_transform"><xsl:with-param name="input" select="substring-after($input, ') ')" /></xsl:call-template>
936     </xsl:when>
937     <xsl:when test="starts-with($input, 'rotate(')">
938       <RotateTransform>
939         <xsl:attribute name="Angle"><xsl:value-of select="substring-before(substring-after($input, 'rotate('), ')')" /></xsl:attribute>
940         <xsl:if test="@rx"><xsl:attribute name="CenterX"><xsl:value-of select="@rx" /></xsl:attribute></xsl:if>
941         <xsl:if test="@ry"><xsl:attribute name="CenterY"><xsl:value-of select="@ry" /></xsl:attribute></xsl:if>
942       </RotateTransform>
943       <xsl:call-template name="parse_transform"><xsl:with-param name="input" select="substring-after($input, ') ')" /></xsl:call-template>
944     </xsl:when>
945     <xsl:when test="starts-with($input, 'skewX(')">
946       <SkewTransform>
947         <xsl:attribute name="AngleX"><xsl:value-of select="substring-before(substring-after($input, 'skewX('), ')')" /></xsl:attribute>
948         <xsl:call-template name="parse_transform"><xsl:with-param name="input" select="substring-after($input, ') ')" /></xsl:call-template>
949       </SkewTransform>
950     </xsl:when>
951     <xsl:when test="starts-with($input, 'skewY(')">
952       <SkewTransform>
953         <xsl:attribute name="AngleY"><xsl:value-of select="substring-before(substring-after($input, 'skewY('), ')')" /></xsl:attribute>
954         <xsl:call-template name="parse_transform"><xsl:with-param name="input" select="substring-after($input, ') ')" /></xsl:call-template>
955       </SkewTransform>
956     </xsl:when>
957     <xsl:when test="starts-with($input, 'translate(')">
958       <TranslateTransform>
959         <xsl:variable name="translate" select="substring-before(substring-after($input, 'translate('), ')')" />
960         <xsl:choose>
961           <xsl:when test="contains($translate, ',')">
962             <xsl:attribute name="X"><xsl:value-of select="substring-before($translate, ',')" /></xsl:attribute>
963             <xsl:attribute name="Y"><xsl:value-of select="substring-after($translate, ',')" /></xsl:attribute>
964           </xsl:when>
965           <xsl:when test="contains($translate, ' ')">
966             <xsl:attribute name="X"><xsl:value-of select="substring-before($translate, ' ')" /></xsl:attribute>
967             <xsl:attribute name="Y"><xsl:value-of select="substring-after($translate, ' ')" /></xsl:attribute>
968           </xsl:when>
969           <xsl:otherwise><xsl:attribute name="X"><xsl:value-of select="$translate" /></xsl:attribute></xsl:otherwise>
970         </xsl:choose>
971       </TranslateTransform>
972       <xsl:call-template name="parse_transform"><xsl:with-param name="input" select="substring-after($input, ') ')" /></xsl:call-template>
973     </xsl:when>
974   </xsl:choose>
975 </xsl:template>
977 <!-- Apply transform -->
978 <xsl:template mode="transform" match="*">
979   <xsl:param name="mapped_type" />
980   <xsl:if test="@transform or @gradientTransform">
981   <xsl:variable name="transform">
982     <xsl:choose>
983        <xsl:when test="@transform"><xsl:value-of select="@transform" /></xsl:when>
984        <xsl:otherwise><xsl:value-of select="@gradientTransform" /></xsl:otherwise>
985     </xsl:choose>
986   </xsl:variable>
987   <xsl:variable name="transform_nodes">
988     <xsl:call-template name="parse_transform">
989       <xsl:with-param name="input" select="$transform" />
990     </xsl:call-template>
991   </xsl:variable>
993   <xsl:comment>
994     <xsl:value-of select="name(.)" />
995   </xsl:comment>
997   <xsl:choose>
998     <xsl:when test="$mapped_type and $mapped_type != ''">
999       <xsl:element name="{$mapped_type}.RenderTransform">
1000         <xsl:choose>
1001           <xsl:when test="count(libxslt:node-set($transform_nodes)/*) = 1"><xsl:copy-of select="libxslt:node-set($transform_nodes)" /></xsl:when>
1002           <xsl:when test="count(libxslt:node-set($transform_nodes)/*) &gt; 1"><TransformGroup><xsl:copy-of select="libxslt:node-set($transform_nodes)" /></TransformGroup></xsl:when>
1003         </xsl:choose>
1004       </xsl:element>
1005     </xsl:when>
1006     <xsl:otherwise>
1007       <!-- For instance LinearGradient.Transform -->
1008       <xsl:choose>
1009           <xsl:when test="count(libxslt:node-set($transform_nodes)/*) = 1"><xsl:copy-of select="libxslt:node-set($transform_nodes)" /></xsl:when>
1010           <xsl:when test="count(libxslt:node-set($transform_nodes)/*) &gt; 1"><TransformGroup><xsl:copy-of select="libxslt:node-set($transform_nodes)" /></TransformGroup></xsl:when>
1011       </xsl:choose>
1012     </xsl:otherwise>
1013   </xsl:choose>
1014   </xsl:if>  
1015 </xsl:template>
1017 <!-- Apply transform v2
1018 Fixme: is this template still in use? -->
1019 <xsl:template mode="transform2" match="*">
1020   <xsl:choose>
1021     <xsl:when test="@transform">
1022       <Canvas>
1023         <Canvas.RenderTransform>
1024           <TransformGroup><xsl:apply-templates mode="transform" select="." /></TransformGroup>
1025         </Canvas.RenderTransform>
1026         <xsl:apply-templates mode="forward" select="." />
1027       </Canvas>
1028     </xsl:when>
1029     <xsl:otherwise>
1030       <xsl:apply-templates mode="forward" select="." />
1031     </xsl:otherwise>
1032   </xsl:choose>
1033 </xsl:template>
1035 <!-- 
1036 // Objects //
1038 * Image
1039 * Text
1040 * Lines
1041 * Rectangle
1042 * Polygon
1043 * Polyline
1044 * Path
1045 * Ellipse
1046 * Circle
1047 -->
1049 <!-- Image -->
1050 <xsl:template mode="forward" match="*[name(.) = 'image']">
1051   <Image>
1052     <xsl:apply-templates mode="id" select="." />
1053     <xsl:if test="@x"><xsl:attribute name="Canvas.Left">
1054         <xsl:call-template name="convert_unit">
1055             <xsl:with-param name="convert_value" select="@x" />
1056         </xsl:call-template>
1057     </xsl:attribute></xsl:if>
1058     <xsl:if test="@y"><xsl:attribute name="Canvas.Top">
1059         <xsl:call-template name="convert_unit">
1060             <xsl:with-param name="convert_value" select="@y" />
1061         </xsl:call-template>
1062     </xsl:attribute></xsl:if>
1063     <xsl:apply-templates mode="desc" select="." />
1064     <xsl:apply-templates mode="clip" select="." />
1065     <xsl:if test="@xlink:href"><xsl:attribute name="Source"><xsl:value-of select="@xlink:href" /></xsl:attribute></xsl:if>
1066     <xsl:if test="@width"><xsl:attribute name="Width">
1067         <xsl:call-template name="convert_unit">
1068             <xsl:with-param name="convert_value" select="@width" />
1069         </xsl:call-template>
1070     </xsl:attribute></xsl:if>
1071     <xsl:if test="@height"><xsl:attribute name="Height">
1072         <xsl:call-template name="convert_unit">
1073             <xsl:with-param name="convert_value" select="@height" />
1074         </xsl:call-template>
1075     </xsl:attribute></xsl:if>
1076     <xsl:apply-templates mode="transform" select=".">
1077       <xsl:with-param name="mapped_type" select="'Image'" />
1078     </xsl:apply-templates>
1079     <!--xsl:apply-templates mode="transform" /-->
1080     <xsl:apply-templates mode="forward" />
1081   </Image>
1082 </xsl:template>
1084 <!-- Text -->
1085 <xsl:template mode="forward" match="*[name(.) = 'text']">
1086   <TextBlock>
1087     <xsl:if test="@font-size"><xsl:attribute name="FontSize"><xsl:value-of select="@font-size" /></xsl:attribute></xsl:if>
1088     <xsl:if test="@style and contains(@style, 'font-size:')">
1089       <xsl:variable name="font_size" select="substring-after(@style, 'font-size:')" />
1090       <xsl:attribute name="FontSize">
1091         <xsl:choose>
1092           <xsl:when test="contains($font_size, ';')">
1093             <xsl:value-of select="substring-before($font_size, ';')" />
1094           </xsl:when>
1095           <xsl:otherwise><xsl:value-of select="$font_size" /></xsl:otherwise>
1096         </xsl:choose>
1097       </xsl:attribute>
1098     </xsl:if>
1099     <xsl:if test="@font-weight"><xsl:attribute name="FontWeight"><xsl:value-of select="@font-weight" /></xsl:attribute></xsl:if>
1100     <xsl:if test="@style and contains(@style, 'font-weight:')">
1101       <xsl:variable name="font_weight" select="substring-after(@style, 'font-weight:')" />
1102       <xsl:attribute name="FontWeight">
1103         <xsl:choose>
1104           <xsl:when test="contains($font_weight, ';')">
1105             <xsl:value-of select="substring-before($font_weight, ';')" />
1106           </xsl:when>
1107           <xsl:otherwise><xsl:value-of select="$font_weight" /></xsl:otherwise>
1108         </xsl:choose>
1109       </xsl:attribute>
1110     </xsl:if>
1111     <xsl:if test="@font-family"><xsl:attribute name="FontFamily"><xsl:value-of select="@font-family" /></xsl:attribute></xsl:if>
1112     <xsl:if test="@style and contains(@style, 'font-family:')">
1113       <xsl:variable name="font_family" select="substring-after(@style, 'font-family:')" />
1114       <xsl:attribute name="FontFamily">
1115         <xsl:choose>
1116           <xsl:when test="contains($font_family, ';')">
1117             <xsl:value-of select="substring-before($font_family, ';')" />
1118           </xsl:when>
1119           <xsl:otherwise><xsl:value-of select="$font_family" /></xsl:otherwise>
1120         </xsl:choose>
1121       </xsl:attribute>
1122     </xsl:if>
1123     <xsl:if test="@font-style"><xsl:attribute name="FontStyle"><xsl:value-of select="@font-style" /></xsl:attribute></xsl:if>
1124     <xsl:if test="@style and contains(@style, 'font-style:')">
1125       <xsl:variable name="font_style" select="substring-after(@style, 'font-style:')" />
1126       <xsl:attribute name="FontStyle">
1127         <xsl:choose>
1128           <xsl:when test="contains($font_style, ';')">
1129             <xsl:value-of select="substring-before($font_style, ';')" />
1130           </xsl:when>
1131           <xsl:otherwise><xsl:value-of select="$font_style" /></xsl:otherwise>
1132         </xsl:choose>
1133       </xsl:attribute>
1134     </xsl:if>
1135     <xsl:if test="@fill"><xsl:attribute name="Foreground"><xsl:value-of select="@fill" /></xsl:attribute></xsl:if>
1136     <xsl:if test="@style and contains(@style, 'fill')">
1137       <xsl:variable name="fill" select="substring-after(@style, 'fill:')" />
1138       <xsl:attribute name="Foreground">
1139         <xsl:choose>
1140           <xsl:when test="contains($fill, ';')">
1141             <xsl:value-of select="substring-before($fill, ';')" />
1142           </xsl:when>
1143           <xsl:otherwise><xsl:value-of select="$fill" /></xsl:otherwise>
1144         </xsl:choose>
1145       </xsl:attribute>
1146     </xsl:if>
1147     <xsl:if test="@text-anchor">
1148       <xsl:attribute name="HorizontalAlignment">
1149         <xsl:choose>
1150           <xsl:when test="@text-anchor = 'start'">Left</xsl:when>
1151           <xsl:when test="@text-anchor = 'middle'">Center</xsl:when>
1152           <xsl:when test="@text-anchor = 'end'">Right</xsl:when>
1153         </xsl:choose>
1154       </xsl:attribute>
1155     </xsl:if>
1156     <xsl:if test="@width"><xsl:attribute name="Width">
1157         <xsl:call-template name="convert_unit">
1158             <xsl:with-param name="convert_value" select="@width" />
1159         </xsl:call-template>
1160     </xsl:attribute></xsl:if>
1161     <xsl:if test="@height"><xsl:attribute name="Height">
1162         <xsl:call-template name="convert_unit">
1163             <xsl:with-param name="convert_value" select="@height" />
1164         </xsl:call-template>
1165     </xsl:attribute></xsl:if>
1166     <xsl:if test="@x"><xsl:attribute name="Canvas.Left">
1167         <xsl:call-template name="convert_unit">
1168             <xsl:with-param name="convert_value" select="@x" />
1169         </xsl:call-template>
1170     </xsl:attribute></xsl:if>
1171     <xsl:if test="@y"><xsl:attribute name="Canvas.Top">
1172         <xsl:call-template name="convert_unit">
1173             <xsl:with-param name="convert_value" select="@y" />
1174         </xsl:call-template>
1175     </xsl:attribute></xsl:if>
1176     <xsl:apply-templates mode="id" select="." />
1177     <xsl:apply-templates mode="filter_effect" select="." />
1178     <xsl:apply-templates mode="desc" select="." />
1179     <xsl:apply-templates mode="clip" select="." />
1180     <!--xsl:apply-templates mode="transform" select="." /-->
1181     <!--xsl:apply-templates mode="forward" /-->
1182     <xsl:if test="text()"><xsl:value-of select="text()" /></xsl:if>
1183     <xsl:if test="*[name(.) = 'tspan']/text()"><xsl:value-of select="*[name(.) = 'tspan']/text()" /></xsl:if>
1184   </TextBlock>
1185 </xsl:template>
1186  
1187 <!-- Lines -->
1188 <xsl:template mode="forward" match="*[name(.) = 'line']">
1189   <Line>
1190     <xsl:if test="@x1"><xsl:attribute name="X1"><xsl:value-of select="@x1" /></xsl:attribute></xsl:if> 
1191     <xsl:if test="@y1"><xsl:attribute name="Y1"><xsl:value-of select="@y1" /></xsl:attribute></xsl:if> 
1192     <xsl:if test="@x2"><xsl:attribute name="X2"><xsl:value-of select="@x2" /></xsl:attribute></xsl:if> 
1193     <xsl:if test="@y2"><xsl:attribute name="Y2"><xsl:value-of select="@y2" /></xsl:attribute></xsl:if>
1194     <xsl:apply-templates mode="id" select="." />
1195     <xsl:apply-templates mode="template_fill" select="." />
1196     <xsl:apply-templates mode="template_stroke" select="." />
1197     <xsl:apply-templates mode="stroke_width" select="." />
1198     <xsl:apply-templates mode="stroke_miterlimit" select="." />
1199     <xsl:apply-templates mode="stroke_dasharray" select="." />
1200     <xsl:apply-templates mode="stroke_dashoffset" select="." />
1201     <xsl:apply-templates mode="stroke_linejoin" select="." />
1202     <xsl:apply-templates mode="stroke_linecap" select="." />
1203     <xsl:apply-templates mode="filter_effect" select="." />
1204     <xsl:apply-templates mode="desc" select="." />
1206     <xsl:apply-templates mode="transform" select=".">
1207       <xsl:with-param name="mapped_type" select="'Line'" />
1208     </xsl:apply-templates>    
1210     <xsl:apply-templates mode="forward" />
1211   </Line>
1212 </xsl:template>
1214 <!-- Rectangle -->
1215 <xsl:template mode="forward" match="*[name(.) = 'rect']">
1216   <Rectangle>
1217     <xsl:if test="@x"><xsl:attribute name="Canvas.Left">
1218         <xsl:call-template name="convert_unit">
1219             <xsl:with-param name="convert_value" select="@x" />
1220         </xsl:call-template>
1221     </xsl:attribute></xsl:if>
1222     <xsl:if test="@y"><xsl:attribute name="Canvas.Top">
1223         <xsl:call-template name="convert_unit">
1224             <xsl:with-param name="convert_value" select="@y" />
1225         </xsl:call-template>
1226     </xsl:attribute></xsl:if>
1227     <xsl:if test="@width"><xsl:attribute name="Width">
1228         <xsl:call-template name="convert_unit">
1229             <xsl:with-param name="convert_value" select="@width" />
1230         </xsl:call-template>
1231     </xsl:attribute></xsl:if>
1232     <xsl:if test="@height"><xsl:attribute name="Height">
1233         <xsl:call-template name="convert_unit">
1234             <xsl:with-param name="convert_value" select="@height" />
1235         </xsl:call-template>
1236     </xsl:attribute></xsl:if>
1237     <xsl:if test="@rx"><xsl:attribute name="RadiusX"><xsl:value-of select="@rx" /></xsl:attribute></xsl:if>
1238     <xsl:if test="@ry"><xsl:attribute name="RadiusY"><xsl:value-of select="@ry" /></xsl:attribute></xsl:if>
1239     <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>
1240     <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>
1242     <xsl:apply-templates mode="id" select="." />
1243     <xsl:apply-templates mode="template_fill" select="." />
1244     <xsl:apply-templates mode="template_stroke" select="." />
1245     <xsl:apply-templates mode="stroke_width" select="." />
1246     <xsl:apply-templates mode="stroke_miterlimit" select="." />
1247     <xsl:apply-templates mode="stroke_dasharray" select="." />
1248     <xsl:apply-templates mode="stroke_dashoffset" select="." />
1249     <xsl:apply-templates mode="stroke_linejoin" select="." />
1250     <xsl:apply-templates mode="stroke_linecap" select="." />
1251     <xsl:apply-templates mode="filter_effect" select="." />
1252     <xsl:apply-templates mode="resources" select="." />
1253     <xsl:apply-templates mode="desc" select="." />
1254     <xsl:apply-templates mode="clip" select="." />
1256     <xsl:apply-templates mode="transform" select=".">
1257       <xsl:with-param name="mapped_type" select="'Rectangle'" />
1258     </xsl:apply-templates>
1260     <xsl:apply-templates mode="forward" />
1261   </Rectangle>
1262 </xsl:template>
1264 <!-- Polygon -->
1265 <xsl:template mode="forward" match="*[name(.) = 'polygon']">
1266   <Polygon>
1267     <xsl:if test="@points"><xsl:attribute name="Points"><xsl:value-of select="@points" /></xsl:attribute></xsl:if>
1268     <xsl:apply-templates mode="id" select="." />
1269     <xsl:apply-templates mode="fill_rule" select="." />
1270     <xsl:apply-templates mode="template_fill" select="." />
1271     <xsl:apply-templates mode="template_stroke" select="." />
1272     <xsl:apply-templates mode="stroke_width" select="." />
1273     <xsl:apply-templates mode="stroke_miterlimit" select="." />
1274     <xsl:apply-templates mode="stroke_dasharray" select="." />
1275     <xsl:apply-templates mode="stroke_dashoffset" select="." />
1276     <xsl:apply-templates mode="stroke_linejoin" select="." />
1277     <xsl:apply-templates mode="stroke_linecap" select="." />
1278     <xsl:apply-templates mode="filter_effect" select="." />
1279     <xsl:apply-templates mode="desc" select="." />
1281     <xsl:apply-templates mode="transform" select=".">
1282       <xsl:with-param name="mapped_type" select="'Polygon'" />
1283     </xsl:apply-templates>
1285     <xsl:apply-templates mode="forward" />
1286   </Polygon>
1287 </xsl:template>
1289 <!-- Polyline -->
1290 <xsl:template mode="forward" match="*[name(.) = 'polyline']">
1291   <Polyline>
1292     <xsl:if test="@points"><xsl:attribute name="Points"><xsl:value-of select="@points" /></xsl:attribute></xsl:if>
1293     <xsl:apply-templates mode="id" select="." />
1294     <xsl:apply-templates mode="fill_rule" select="." />
1295     <xsl:apply-templates mode="template_fill" select="." />
1296     <xsl:apply-templates mode="template_stroke" select="." />
1297     <xsl:apply-templates mode="stroke_width" select="." />
1298     <xsl:apply-templates mode="stroke_miterlimit" select="." />
1299     <xsl:apply-templates mode="stroke_dasharray" select="." />
1300     <xsl:apply-templates mode="stroke_dashoffset" select="." />
1301     <xsl:apply-templates mode="stroke_linejoin" select="." />
1302     <xsl:apply-templates mode="stroke_linecap" select="." />
1303     <xsl:apply-templates mode="filter_effect" select="." />
1304     <xsl:apply-templates mode="desc" select="." />
1306     <xsl:apply-templates mode="transform" select=".">
1307       <xsl:with-param name="mapped_type" select="'Polyline'" />
1308     </xsl:apply-templates>
1310     <xsl:apply-templates mode="forward" />
1311   </Polyline>
1312 </xsl:template>
1314 <!-- Path -->
1315 <xsl:template mode="forward" match="*[name(.) = 'path']">
1316   <Path>
1317     <xsl:apply-templates mode="id" select="." />
1318     <xsl:apply-templates mode="template_fill" select="." />
1319     <xsl:apply-templates mode="template_stroke" select="." />
1320     <xsl:apply-templates mode="stroke_width" select="." />
1321     <xsl:apply-templates mode="stroke_miterlimit" select="." />
1322     <xsl:apply-templates mode="stroke_dasharray" select="." />
1323     <xsl:apply-templates mode="stroke_dashoffset" select="." />
1324     <xsl:apply-templates mode="stroke_linejoin" select="." />
1325     <xsl:apply-templates mode="stroke_linecap" select="." />
1326     <xsl:apply-templates mode="filter_effect" select="." />
1327     <xsl:apply-templates mode="desc" select="." />
1329     <xsl:if test="@d">
1330       <xsl:choose>
1331         <xsl:when test="$silverlight_compatible = 1">
1332           <xsl:attribute name="Data">
1333             <xsl:value-of select="translate(@d , ',', ' ')" />
1334           </xsl:attribute>
1335         </xsl:when>
1336         <xsl:otherwise>
1337           <Path.Data>
1338             <PathGeometry>
1339               <xsl:attribute name="Figures">
1340                 <xsl:value-of select="translate(@d , ',', ' ')" />
1341               </xsl:attribute>
1342               <xsl:apply-templates mode="fill_rule" select="." />
1343             </PathGeometry>
1344           </Path.Data>
1345          </xsl:otherwise>
1346       </xsl:choose>
1347     </xsl:if>
1349     <xsl:apply-templates mode="transform" select=".">
1350       <xsl:with-param name="mapped_type" select="'Path'" />
1351     </xsl:apply-templates>
1353     <xsl:apply-templates mode="forward" />
1354   </Path>
1355 </xsl:template>
1357 <!-- Ellipse -->
1358 <xsl:template mode="forward" match="*[name(.) = 'ellipse']">
1359   <Ellipse>
1360     <xsl:variable name="cx">
1361       <xsl:choose>
1362         <xsl:when test="@cx"><xsl:value-of select="@cx" /></xsl:when>
1363         <xsl:otherwise>0</xsl:otherwise>
1364       </xsl:choose>
1365     </xsl:variable>
1366     <xsl:variable name="cy">
1367       <xsl:choose>
1368         <xsl:when test="@cy"><xsl:value-of select="@cy" /></xsl:when>
1369         <xsl:otherwise>0</xsl:otherwise>
1370       </xsl:choose>
1371     </xsl:variable>
1372     <xsl:if test="@rx">
1373       <xsl:attribute name="Canvas.Left"><xsl:value-of select='format-number($cx - @rx, "#.#")' /></xsl:attribute>
1374       <xsl:attribute name="Width"><xsl:value-of select='format-number(2 * @rx, "#.#")' /></xsl:attribute>
1375     </xsl:if>
1376     <xsl:if test="@ry">
1377       <xsl:attribute name="Canvas.Top"><xsl:value-of select='format-number($cy - @ry, "#.#")' /></xsl:attribute>
1378       <xsl:attribute name="Height"><xsl:value-of select='format-number(2 * @ry, "#.#")' /></xsl:attribute>
1379     </xsl:if>
1380     <xsl:apply-templates mode="id" select="." />
1381     <xsl:apply-templates mode="template_fill" select="." />
1382     <xsl:apply-templates mode="template_stroke" select="." />
1383     <xsl:apply-templates mode="stroke_width" select="." />
1384     <xsl:apply-templates mode="stroke_miterlimit" select="." />
1385     <xsl:apply-templates mode="stroke_dasharray" select="." />
1386     <xsl:apply-templates mode="stroke_dashoffset" select="." />
1387     <xsl:apply-templates mode="stroke_linejoin" select="." />
1388     <xsl:apply-templates mode="stroke_linecap" select="." />
1389     <xsl:apply-templates mode="filter_effect" select="." />
1390     <xsl:apply-templates mode="desc" select="." />
1391     <xsl:apply-templates mode="clip" select="." />
1393     <xsl:apply-templates mode="transform" select=".">
1394       <xsl:with-param name="mapped_type" select="'Ellipse'" />
1395     </xsl:apply-templates>
1397     <xsl:apply-templates mode="forward" />
1398   </Ellipse>
1399 </xsl:template>
1401 <!-- Circle -->
1402 <xsl:template mode="forward" match="*[name(.) = 'circle']">
1403   <Ellipse>
1404     <xsl:variable name="cx">
1405       <xsl:choose>
1406         <xsl:when test="@cx"><xsl:value-of select="@cx" /></xsl:when>
1407         <xsl:otherwise>0</xsl:otherwise>
1408       </xsl:choose>
1409     </xsl:variable>
1410     <xsl:variable name="cy">
1411       <xsl:choose>
1412         <xsl:when test="@cy"><xsl:value-of select="@cy" /></xsl:when>
1413         <xsl:otherwise>0</xsl:otherwise>
1414       </xsl:choose>
1415     </xsl:variable>
1416     <xsl:if test="@r">
1417        <xsl:attribute name="Canvas.Left"><xsl:value-of select='format-number($cx - @r, "#.#")' /></xsl:attribute>
1418        <xsl:attribute name="Canvas.Top"><xsl:value-of select='format-number($cy - @r, "#.#")' /></xsl:attribute>
1419        <xsl:attribute name="Width"><xsl:value-of select='format-number(2 * @r, "#.#")' /></xsl:attribute>
1420        <xsl:attribute name="Height"><xsl:value-of select='format-number(2 * @r, "#.#")' /></xsl:attribute>
1421     </xsl:if>
1422     <xsl:apply-templates mode="id" select="." />
1423     <xsl:apply-templates mode="template_fill" select="." />
1424     <xsl:apply-templates mode="template_stroke" select="." />
1425     <xsl:apply-templates mode="stroke_width" select="." />
1426     <xsl:apply-templates mode="stroke_miterlimit" select="." />
1427     <xsl:apply-templates mode="stroke_dasharray" select="." />
1428     <xsl:apply-templates mode="stroke_dashoffset" select="." />
1429     <xsl:apply-templates mode="stroke_linejoin" select="." />
1430     <xsl:apply-templates mode="stroke_linecap" select="." />
1431     <xsl:apply-templates mode="filter_effect" select="." />
1432     <xsl:apply-templates mode="desc" select="." />
1433     <xsl:apply-templates mode="clip" select="." />
1435     <xsl:apply-templates mode="transform" select=".">
1436       <xsl:with-param name="mapped_type" select="'Ellipse'" />
1437     </xsl:apply-templates>
1439     <xsl:apply-templates mode="forward" />
1440   </Ellipse>
1441 </xsl:template>
1443 <!--
1444 // Geometry //
1445 * Generic clip path template
1446 * Geometry for circle
1447 * Geometry for rectangle
1448 -->
1450 <!-- Generic clip path template -->
1451 <xsl:template mode="forward" match="*[name(.) = 'clipPath']">
1452   <xsl:apply-templates mode="geometry" />
1453 </xsl:template>
1455 <!-- Geometry for circle -->
1456 <xsl:template mode="geometry" match="*[name(.) = 'circle']">
1457   <EllipseGeometry>
1458     <xsl:if test="../@id"><xsl:attribute name="x:Key"><xsl:value-of select="../@id" /></xsl:attribute></xsl:if>
1459     <xsl:if test="@cx and @cy"><xsl:attribute name="Center"><xsl:value-of select="concat(@cx, ',', @cy)" /></xsl:attribute></xsl:if>
1460     <xsl:if test="@r">
1461       <xsl:attribute name="RadiusX"><xsl:value-of select="@r" /></xsl:attribute>
1462       <xsl:attribute name="RadiusY"><xsl:value-of select="@r" /></xsl:attribute>
1463     </xsl:if>
1464   </EllipseGeometry>
1465 </xsl:template>
1467 <!-- Geometry for rectangle -->
1468 <xsl:template mode="geometry" match="*[name(.) = 'rect']">
1469   <RectangleGeometry>
1470     <xsl:if test="../@id"><xsl:attribute name="x:Key"><xsl:value-of select="../@id" /></xsl:attribute></xsl:if>
1471     <!--
1472     <xsl:if test="@x"><xsl:attribute name="Canvas.Left"><xsl:value-of select="@x" /></xsl:attribute></xsl:if>
1473     <xsl:if test="@y"><xsl:attribute name="Canvas.Top"><xsl:value-of select="@y" /></xsl:attribute></xsl:if>
1474     <xsl:if test="@width"><xsl:attribute name="Width"><xsl:value-of select="@width" /></xsl:attribute></xsl:if>
1475     <xsl:if test="@height"><xsl:attribute name="Height"><xsl:value-of select="@height" /></xsl:attribute></xsl:if>
1476     <xsl:if test="@rx"><xsl:attribute name="RadiusX"><xsl:value-of select="@rx" /></xsl:attribute></xsl:if>
1477     <xsl:if test="@ry"><xsl:attribute name="RadiusY"><xsl:value-of select="@ry" /></xsl:attribute></xsl:if>
1478     -->
1479     <xsl:attribute name="Rect"><xsl:value-of select="concat('0, 0, ', @width, ', ', @height)" /></xsl:attribute>
1480   </RectangleGeometry>
1481 </xsl:template>
1483 </xsl:stylesheet>