Code

Extensions. XAML export improvements.
[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-2011) 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="0" />
44 <!-- 
45   // Containers //
47   * Root templace
48   * Groups
49 -->
51 <!-- 
52   // Root template //
53 -->
54 <xsl:template match="/">
55   <xsl:choose>
56     <xsl:when test="$silverlight_compatible = 1">
57       <xsl:apply-templates mode="forward" />
58     </xsl:when>
59     <xsl:otherwise>
60       <Viewbox Stretch="Uniform">
61         <xsl:apply-templates mode="forward" />
62       </Viewbox>
63     </xsl:otherwise>   
64   </xsl:choose>
65 </xsl:template>
67 <!-- 
68   // SVG and groups //  
69   (including layers)
70 -->
71 <xsl:template mode="forward" match="*[name(.) = 'svg' or name(.) = 'g']">
72   <xsl:choose>
73     <xsl:when test="name(.) = 'svg' or @transform or @viewBox or @id or @clip-path or @filter 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']">
74       <Canvas>
75         <xsl:apply-templates mode="id" select="." />
76         <xsl:apply-templates mode="filter_effect" select="." />
77         <!--
78         <xsl:apply-templates mode="clip" select="." />
79         -->
80         <xsl:if test="@style and contains(@style, 'display:none')">
81           <xsl:attribute name="Visibility">Collapsed</xsl:attribute>
82         </xsl:if>
83         <xsl:if test="@style and contains(@style, 'opacity:')">
84           <xsl:attribute name="Opacity">
85             <xsl:choose>
86               <xsl:when test="contains(substring-after(@style, 'opacity:'), ';')">
87                 <xsl:value-of select="substring-before(substring-after(@style, 'opacity:'), ';')" />
88               </xsl:when>
89               <xsl:otherwise>
90                 <xsl:value-of select="substring-after(@style, 'opacity:')" />
91               </xsl:otherwise>
92             </xsl:choose>
93           </xsl:attribute>
94         </xsl:if>
95         <xsl:if test="@width and not(contains(@width, '%'))">
96           <xsl:attribute name="Width">
97             <xsl:call-template name="convert_unit">
98               <xsl:with-param name="convert_value" select="@width" />
99             </xsl:call-template>
100           </xsl:attribute>
101         </xsl:if>
102           <xsl:if test="@height and not(contains(@height, '%'))">
103           <xsl:attribute name="Height">
104             <xsl:call-template name="convert_unit">
105               <xsl:with-param name="convert_value" select="@height" />
106             </xsl:call-template>
107           </xsl:attribute>
108         </xsl:if>
109         <xsl:if test="@x">
110           <xsl:attribute name="Canvas.Left">
111             <xsl:call-template name="convert_unit">
112               <xsl:with-param name="convert_value" select="@x" />
113             </xsl:call-template>
114           </xsl:attribute></xsl:if>
115         <xsl:if test="@y">
116           <xsl:attribute name="Canvas.Top">
117             <xsl:call-template name="convert_unit">
118               <xsl:with-param name="convert_value" select="@y" />
119             </xsl:call-template>
120           </xsl:attribute>
121         </xsl:if>
123         <xsl:if test="@viewBox">
124           <xsl:variable name="viewBox">
125             <xsl:value-of select="normalize-space(translate(@viewBox, ',', ' '))" />
126           </xsl:variable>
127           <xsl:attribute name="Width">
128             <xsl:value-of select="substring-before(substring-after(substring-after($viewBox, ' '), ' '), ' ')" />
129           </xsl:attribute>
130           <xsl:attribute name="Height">
131             <xsl:value-of select="substring-after(substring-after(substring-after($viewBox, ' '), ' '), ' ')" />
132           </xsl:attribute>
133           <Canvas.RenderTransform>
134             <TranslateTransform>
135               <xsl:attribute name="X">
136                 <xsl:value-of select="-number(substring-before($viewBox, ' '))" />
137               </xsl:attribute>
138               <xsl:attribute name="Y">
139                 <xsl:value-of select="-number(substring-before(substring-after($viewBox, ' '), ' '))" />
140               </xsl:attribute>
141             </TranslateTransform>
142           </Canvas.RenderTransform>
143         </xsl:if>
144         <xsl:if test="@transform">
145             <xsl:apply-templates mode="transform" select=".">
146               <xsl:with-param name="mapped_type" select="'Canvas'" />
147             </xsl:apply-templates>
148             <xsl:apply-templates mode="forward" select="*" />
149         </xsl:if>
151         <xsl:if test="*[name(.) = 'linearGradient' or name(.) = 'radialGradient' or name(.) = 'defs' or name(.) = 'clipPath']">
152           <Canvas.Resources>
153             <xsl:apply-templates mode="forward" select="*[name(.) = 'linearGradient' or name(.) = 'radialGradient' or name(.) = 'defs' or name(.) = 'clipPath']" />
154           </Canvas.Resources>
155         </xsl:if>
156         <xsl:if test="not(@transform)">
157           <xsl:apply-templates mode="forward" select="*[name(.) != 'linearGradient' and name(.) != 'radialGradient' and name(.) != 'defs' and name(.) != 'clipPath']" />
158         </xsl:if>  
159       </Canvas>
160     </xsl:when>
161     <xsl:when test="not(@transform)">
162       <xsl:apply-templates mode="forward" select="*" />
163     </xsl:when>
164   </xsl:choose>
165 </xsl:template>
167 <!-- 
168   // Transforms //
169   All the matrix, translate, rotate... stuff.
170   Fixme: XAML transforms don't show the same result as SVG ones with the same values.
172   * Parse transform
173   * Apply transform
174 -->
176 <!-- 
177   // Parse transform //
178 -->
179 <xsl:template name="parse_transform">
180   <xsl:param name="input" />
181   <xsl:choose>
182   
183     <!-- Matrix transform -->
184     <xsl:when test="starts-with($input, 'matrix(')">
185       <MatrixTransform>
186         <xsl:attribute name="Matrix">
187           <xsl:value-of select="normalize-space(translate(substring-before(substring-after($input, 'matrix('), ')'), ',', ' '))" />
188         </xsl:attribute>
189       </MatrixTransform>
190       <xsl:call-template name="parse_transform">
191         <xsl:with-param name="input" select="substring-after($input, ') ')" />
192       </xsl:call-template>      
193     </xsl:when>
194     
195     <!-- Scale transform -->
196     <xsl:when test="starts-with($input, 'scale(')">
197       <ScaleTransform>
198         <xsl:variable name="scale" select="normalize-space(translate(substring-before(substring-after($input, 'scale('), ')'), ',', ' '))" />
199         <xsl:choose>
200           <xsl:when test="contains($scale, ' ')">
201             <xsl:attribute name="ScaleX">
202               <xsl:value-of select="substring-before($scale, ' ')" />
203             </xsl:attribute>
204             <xsl:attribute name="ScaleY">
205               <xsl:value-of select="substring-after($scale, ' ')" />
206             </xsl:attribute>
207           </xsl:when>
208           <xsl:otherwise>
209             <xsl:attribute name="ScaleX">
210               <xsl:value-of select="$scale" />
211             </xsl:attribute>
212             <xsl:attribute name="ScaleY">
213               <xsl:value-of select="$scale" />
214             </xsl:attribute>
215           </xsl:otherwise>
216         </xsl:choose>
217       </ScaleTransform>
218       <xsl:call-template name="parse_transform">
219         <xsl:with-param name="input" select="substring-after($input, ') ')" />
220       </xsl:call-template>
221     </xsl:when>
222     
223     <!-- Rotate transform -->
224     <xsl:when test="starts-with($input, 'rotate(')">
225       <RotateTransform>
226         <xsl:attribute name="Angle">
227           <xsl:value-of select="normalize-space(translate(substring-before(substring-after($input, 'rotate('), ')'), ',', ' '))" />
228         </xsl:attribute>
229         <xsl:if test="@rx">
230           <xsl:attribute name="CenterX">
231             <xsl:value-of select="@rx" />
232           </xsl:attribute>
233         </xsl:if>
234         <xsl:if test="@ry">
235           <xsl:attribute name="CenterY">
236             <xsl:value-of select="@ry" />
237           </xsl:attribute>
238         </xsl:if>
239       </RotateTransform>
240       <xsl:call-template name="parse_transform">
241         <xsl:with-param name="input" select="substring-after($input, ') ')" />
242       </xsl:call-template>
243     </xsl:when>
244     
245     <!-- Skew transform -->
246     <xsl:when test="starts-with($input, 'skewX(')">
247       <SkewTransform>
248         <xsl:attribute name="AngleX">
249           <xsl:value-of select="normalize-space(translate(substring-before(substring-after($input, 'skewX('), ')'), ',', ' '))" />
250         </xsl:attribute>
251         <xsl:call-template name="parse_transform">
252           <xsl:with-param name="input" select="substring-after($input, ') ')" />
253         </xsl:call-template>
254       </SkewTransform>
255     </xsl:when>
256     <xsl:when test="starts-with($input, 'skewY(')">
257       <SkewTransform>
258         <xsl:attribute name="AngleY">
259           <xsl:value-of select="normalize-space(translate(substring-before(substring-after($input, 'skewY('), ')'), ',', ' '))" />
260         </xsl:attribute>
261         <xsl:call-template name="parse_transform">
262           <xsl:with-param name="input" select="substring-after($input, ') ')" />
263         </xsl:call-template>
264       </SkewTransform>
265     </xsl:when>
266     
267     <!-- Translate transform -->
268     <xsl:when test="starts-with($input, 'translate(')">
269       <TranslateTransform>
270       <xsl:variable name="translate" select="normalize-space(translate(substring-before(substring-after($input, 'translate('), ')'), ',', ' '))" />
271         <xsl:choose>
272           <xsl:when test="contains($translate, ' ')">
273             <xsl:attribute name="X">
274               <xsl:value-of select="substring-before($translate, ' ')" />
275             </xsl:attribute>
276             <xsl:attribute name="Y">
277               <xsl:value-of select="substring-after($translate, ' ')" />
278             </xsl:attribute>
279           </xsl:when>
280           <xsl:otherwise>
281             <xsl:attribute name="X">
282               <xsl:value-of select="$translate" />
283             </xsl:attribute>
284           </xsl:otherwise>
285         </xsl:choose>
286       </TranslateTransform>
287       <xsl:call-template name="parse_transform">
288         <xsl:with-param name="input" select="substring-after($input, ') ')" />
289       </xsl:call-template>
290     </xsl:when>
291   </xsl:choose>
292 </xsl:template>
294 <!-- 
295   // Apply transform //
296 -->
297 <xsl:template mode="transform" match="*">
298   <xsl:param name="mapped_type" />
299   
300   <xsl:if test="@transform or @gradientTransform">
301     <xsl:variable name="transform">
302       <xsl:choose>
303         <xsl:when test="@transform">
304           <xsl:value-of select="@transform" />
305         </xsl:when>
306         <xsl:otherwise>
307           <xsl:value-of select="@gradientTransform" />
308         </xsl:otherwise>
309       </xsl:choose>
310     </xsl:variable>
312     <xsl:variable name="values" select="normalize-space(translate($transform, ',', ' '))" />
313     <xsl:variable name="value1">
314       <xsl:choose>
315         <xsl:when test="contains($values, ') ')">
316           <xsl:value-of select="concat(substring-before($values, ') '), ')')" />
317         </xsl:when>
318         <xsl:otherwise>
319           <xsl:value-of select="$values" />
320         </xsl:otherwise>
321       </xsl:choose>
322     </xsl:variable>
323     <xsl:variable name="value2">
324       <xsl:if test="substring-after($values, $value1) != ''">
325         <xsl:choose>
326           <xsl:when test="contains(substring-after($values, $value1), ') ')">
327             <xsl:value-of select="normalize-space(concat(substring-before(substring-after($values, $value1), ') '), ')'))" />
328           </xsl:when>
329           <xsl:otherwise>
330             <xsl:value-of select="normalize-space(substring-after($values, $value1))" />
331           </xsl:otherwise>
332         </xsl:choose>
333       </xsl:if>
334     </xsl:variable>
335     <xsl:variable name="value3">
336       <xsl:if test="$value2 != '' and substring-after($values, $value2) != ''">
337         <xsl:choose>
338           <xsl:when test="contains(substring-after($values, $value2), ') ')">
339             <xsl:value-of select="normalize-space(concat(substring-before(substring-after($values, $value2), ') '), ')'))" />
340           </xsl:when>
341           <xsl:otherwise>
342             <xsl:value-of select="normalize-space(substring-after($values, $value2))" />
343           </xsl:otherwise>
344         </xsl:choose>
345       </xsl:if>
346     </xsl:variable>
348     <xsl:variable name="transform_nodes">
349       <xsl:if test="$value3 !=''">
350         <xsl:call-template name="parse_transform">
351           <xsl:with-param name="input" select="$value3" />
352         </xsl:call-template>
353       </xsl:if>
354       <xsl:if test="$value2 !=''">
355         <xsl:call-template name="parse_transform">
356           <xsl:with-param name="input" select="$value2" />
357         </xsl:call-template>
358       </xsl:if>
359       <xsl:if test="$value1 !=''">
360         <xsl:call-template name="parse_transform">
361           <xsl:with-param name="input" select="$value1" />
362         </xsl:call-template>
363       </xsl:if>
364     </xsl:variable>
366     <xsl:choose>
367       <xsl:when test="$mapped_type and $mapped_type != ''">
368         <xsl:element name="{$mapped_type}.RenderTransform">
369           <xsl:choose>
370             <xsl:when test="count(libxslt:node-set($transform_nodes)/*) = 1">
371               <xsl:copy-of select="libxslt:node-set($transform_nodes)" />
372             </xsl:when>
373             <xsl:when test="count(libxslt:node-set($transform_nodes)/*) &gt; 1">
374               <TransformGroup>
375                 <xsl:copy-of select="libxslt:node-set($transform_nodes)" />
376               </TransformGroup>
377             </xsl:when>
378           </xsl:choose>
379         </xsl:element>
380       </xsl:when>
381       <xsl:otherwise>
382         <!-- For instance LinearGradient.Transform -->
383         <xsl:choose>
384           <xsl:when test="count(libxslt:node-set($transform_nodes)/*) = 1">
385             <xsl:copy-of select="libxslt:node-set($transform_nodes)" />
386           </xsl:when>
387           <xsl:when test="count(libxslt:node-set($transform_nodes)/*) &gt; 1">
388             <TransformGroup>
389               <xsl:copy-of select="libxslt:node-set($transform_nodes)" />
390             </TransformGroup>
391           </xsl:when>
392         </xsl:choose>
393       </xsl:otherwise>
394     </xsl:choose>
395   </xsl:if>  
396 </xsl:template>
398 <!--
399   // Resources (defs) //
401   * Resources ids
402   * Generic defs template
403   * Generic filters template
404   * Filter effects
405   * Linked filter effects
406   * Linear gradients
407   * Radial gradients
408   * Generic gradient stops
409   * Clipping
410 -->
412 <!-- 
413   // Resources ids //
414 -->
415 <xsl:template mode="resources" match="*">
416   <!-- should be in-depth -->
417   <xsl:if test="ancestor::*[name(.) = 'defs']"><xsl:attribute name="x:Key"><xsl:value-of select="@id" /></xsl:attribute></xsl:if>
418 </xsl:template>
420 <!--
421   // Generic defs template //
422 -->
423 <xsl:template mode="forward" match="*[name(.) = 'defs']">
424   <xsl:apply-templates mode="forward" />
425 </xsl:template>
427 <!--
428   // Generic filters template //
429   Limited to one filter (can be improved)
430 -->
431 <xsl:template mode="forward" match="*[name(.) = 'filter']">
432     <xsl:if test="count(*) = 1">
433       <xsl:apply-templates mode="forward" />
434     </xsl:if> 
435 </xsl:template>
437 <!--
438   // GaussianBlur filter effects //
439   Blur values approximated with d = floor(s * 3*sqrt(2*pi)/4 + 0.5) from:
440     http://www.w3.org/TR/SVG/filters.html#feGaussianBlurElement
441     
442   Not supported by XAML:
443   * Horizontal and vertical blur.
444 -->
445 <xsl:template mode="forward" match="*[name(.) = 'feGaussianBlur']">
446   <BlurEffect>
447     <xsl:if test="../@id"><xsl:attribute name="x:Key"><xsl:value-of select="../@id" /></xsl:attribute></xsl:if>
448     <xsl:if test="@stdDeviation">
449       <xsl:variable name="blur" select="normalize-space(translate(@stdDeviation, ',', ' '))" />
450       <xsl:choose>
451         <xsl:when test="not(contains($blur, ' '))">
452           <xsl:attribute name="Radius">
453             <xsl:value-of select="floor($blur * 1.88 + 0.5)" />
454           </xsl:attribute>
455         </xsl:when>
456         <xsl:otherwise>
457           <xsl:attribute name="Radius">
458             <xsl:value-of select="floor(substring-before($blur, ' ') * 1.88 + 0.5)" />
459           </xsl:attribute>
460         </xsl:otherwise>
461       </xsl:choose>          
462     </xsl:if>
463   </BlurEffect>  
464 </xsl:template>
466 <!--
467   // Linked filter effect //
468   Only supports blurs
469 -->
470 <xsl:template mode="filter_effect" match="*">
471   <xsl:choose>
472     <xsl:when test="@filter and starts-with(@filter, 'url(#')">
473       <xsl:attribute name="Effect">
474         <xsl:value-of select="concat('{StaticResource ', substring-before(substring-after(@filter, 'url(#'), ')'), '}')" />
475       </xsl:attribute>
476     </xsl:when>
477     <xsl:when test="@style and contains(@style, 'filter:url(#')">
478       <xsl:attribute name="Effect">
479         <xsl:value-of select="concat('{StaticResource ', substring-before(substring-after(@style, 'filter:url(#'), ')'), '}')" />
480       </xsl:attribute>
481     </xsl:when>
482   </xsl:choose>
483 </xsl:template>
485 <!--
486   // Linear gradient //
487 -->
488 <xsl:template mode="forward" match="*[name(.) = 'linearGradient']">
489   <LinearGradientBrush>
490     <xsl:if test="@id">
491       <xsl:attribute name="x:Key">
492         <xsl:value-of select="@id" />
493       </xsl:attribute>
494     </xsl:if>
495     <xsl:attribute name="MappingMode">
496       <xsl:choose>
497         <xsl:when test="@gradientUnits = 'userSpaceOnUse' ">Absolute</xsl:when>
498         <xsl:otherwise>RelativeToBoundingBox</xsl:otherwise>
499       </xsl:choose>
500     </xsl:attribute>
501     <xsl:if test="@spreadMethod">
502       <xsl:attribute name="SpreadMethod">
503         <xsl:choose>
504           <xsl:when test="@spreadMethod = 'pad'">Pad</xsl:when>
505           <xsl:when test="@spreadMethod = 'reflect'">Reflect</xsl:when>
506           <xsl:when test="@spreadMethod = 'repeat'">Repeat</xsl:when>
507         </xsl:choose>
508       </xsl:attribute>
509     </xsl:if>
510     <xsl:choose>
511       <xsl:when test="@x1 and @y1 and @x2 and @y2">
512         <xsl:choose>
513           <xsl:when test="contains(@x1, '%') and contains(@y1, '%')">
514             <xsl:attribute name="StartPoint">
515               <xsl:value-of select="concat(substring-before(@x1, '%') div 100, ',', substring-before(@y1,'%') div 100)" />
516             </xsl:attribute>
517           </xsl:when>
518           <xsl:otherwise>
519             <xsl:attribute name="StartPoint">
520               <xsl:value-of select="concat(@x1, ',', @y1)" />
521             </xsl:attribute>
522           </xsl:otherwise>
523         </xsl:choose>
524         <xsl:choose>
525           <xsl:when test="contains(@x2, '%') and contains(@y2, '%')">
526             <xsl:attribute name="EndPoint">
527               <xsl:value-of select="concat(substring-before(@x2, '%') div 100, ',', substring-before(@y2,'%') div 100)" />
528             </xsl:attribute>
529           </xsl:when>
530           <xsl:otherwise>
531             <xsl:attribute name="EndPoint">
532               <xsl:value-of select="concat(@x2, ',', @y2)" />
533             </xsl:attribute>
534           </xsl:otherwise>
535         </xsl:choose>  
536       </xsl:when>
537       <xsl:otherwise>
538         <xsl:attribute name="StartPoint">
539           <xsl:value-of select="'0,0'" />
540         </xsl:attribute>
541         <xsl:attribute name="EndPoint">
542           <xsl:value-of select="'1,1'" />
543         </xsl:attribute>
544       </xsl:otherwise>
545     </xsl:choose>
546     <LinearGradientBrush.GradientStops>
547       <GradientStopCollection>
548         <xsl:choose>
549           <xsl:when test="@xlink:href">
550             <xsl:variable name="reference_id" select="@xlink:href" />
551             <xsl:apply-templates mode="forward" select="//*[name(.) = 'linearGradient' and $reference_id = concat('#', @id)]/*" />
552           </xsl:when>
553           <xsl:otherwise>
554             <xsl:apply-templates mode="forward" />
555           </xsl:otherwise>
556         </xsl:choose>
557       </GradientStopCollection>
558     </LinearGradientBrush.GradientStops>
559     <xsl:if test="@gradientTransform">
560       <LinearGradientBrush.Transform>
561         <xsl:apply-templates mode="transform" select="." />
562       </LinearGradientBrush.Transform>
563     </xsl:if>
564   </LinearGradientBrush>
565 </xsl:template>
567 <!--
568   // Radial gradient //
569 -->
570 <xsl:template mode="forward" match="*[name(.) = 'radialGradient']">
571   <RadialGradientBrush>
572     <xsl:if test="@id">
573       <xsl:attribute name="x:Key">
574         <xsl:value-of select="@id" />
575       </xsl:attribute>
576     </xsl:if>
577     <xsl:attribute name="MappingMode">
578       <xsl:choose>
579         <xsl:when test="@gradientUnits = 'userSpaceOnUse' ">Absolute</xsl:when>
580         <xsl:otherwise>RelativeToBoundingBox</xsl:otherwise>
581       </xsl:choose>
582     </xsl:attribute>
583     <xsl:if test="@spreadMethod">
584       <xsl:attribute name="SpreadMethod">
585         <xsl:choose>
586           <xsl:when test="@spreadMethod = 'pad'">Pad</xsl:when>
587           <xsl:when test="@spreadMethod = 'reflect'">Reflect</xsl:when>
588           <xsl:when test="@spreadMethod = 'repeat'">Repeat</xsl:when>
589         </xsl:choose>
590       </xsl:attribute>
591     </xsl:if>
592     <xsl:if test="@cx and @cy">
593       <xsl:attribute name="Center">
594         <xsl:choose>
595           <xsl:when test="contains(@cx, '%') and contains(@cy, '%')">
596             <xsl:value-of select="concat(number(substring-before(@cx, '%')) div 100, ',', number(substring-before(@cy, '%')) div 100)" />
597           </xsl:when>
598           <xsl:otherwise>
599             <xsl:value-of select="concat(@cx, ',', @cy)" />
600           </xsl:otherwise>
601         </xsl:choose>
602       </xsl:attribute>
603     </xsl:if>  
604     <xsl:if test="@fx and @fy">
605       <xsl:attribute name="GradientOrigin">
606         <xsl:choose>
607           <xsl:when test="contains(@fx, '%') and contains(@fy, '%')">
608             <xsl:value-of select="concat(number(substring-before(@fx, '%')) div 100, ',', number(substring-before(@fy, '%')) div 100)" />
609           </xsl:when>
610           <xsl:otherwise>
611             <xsl:value-of select="concat(@fx, ',', @fy)" />
612           </xsl:otherwise>
613         </xsl:choose>
614       </xsl:attribute>
615     </xsl:if>
616     <xsl:if test="@r">
617       <xsl:choose>
618         <xsl:when test="contains(@r, '%')">
619           <xsl:attribute name="RadiusX">
620             <xsl:value-of select="number(substring-before(@r, '%')) div 100" />
621           </xsl:attribute>
622           <xsl:attribute name="RadiusY">
623             <xsl:value-of select="number(substring-before(@r, '%')) div 100" />
624           </xsl:attribute>
625         </xsl:when>
626         <xsl:otherwise>
627           <xsl:attribute name="RadiusX">
628             <xsl:value-of select="@r" />
629           </xsl:attribute>
630           <xsl:attribute name="RadiusY">
631             <xsl:value-of select="@r" />
632           </xsl:attribute>
633         </xsl:otherwise>
634       </xsl:choose>
635     </xsl:if>
636     <RadialGradientBrush.GradientStops>
637       <GradientStopCollection>
638         <xsl:choose>
639           <xsl:when test="@xlink:href">
640             <xsl:variable name="reference_id" select="@xlink:href" />
641             <xsl:apply-templates mode="forward" select="//*[name(.) = 'linearGradient' and $reference_id = concat('#', @id)]/*" />
642           </xsl:when>
643           <xsl:otherwise>
644             <xsl:apply-templates mode="forward" />
645           </xsl:otherwise>
646         </xsl:choose>
647       </GradientStopCollection>
648     </RadialGradientBrush.GradientStops>
649     <xsl:if test="@gradientTransform">
650       <RadialGradientBrush.Transform>
651         <xsl:apply-templates mode="transform" select="." />
652       </RadialGradientBrush.Transform>
653     </xsl:if>
654   </RadialGradientBrush>
655 </xsl:template>
657 <!--
658   // Gradient stop //
659 -->
660 <xsl:template mode="forward" match="*[name(.) = 'stop']">
661   <GradientStop>
662     <!--xsl:apply-templates mode="stop_opacity" select="." /-->
663     <xsl:apply-templates mode="stop_color" select="." />
664     <xsl:apply-templates mode="offset" select="." />
665     <xsl:apply-templates mode="forward" />
666   </GradientStop>
667 </xsl:template>
669 <!-- 
670   // Clipping //
671 -->
672 <xsl:template mode="clip" match="*">
673   <xsl:choose>
674     <xsl:when test="@clip-path and defs/clipPath/path/@d">
675       <xsl:attribute name="Clip">
676         <xsl:value-of select="defs/clipPath/path/@d" />
677       </xsl:attribute>
678     </xsl:when>
679     <xsl:when test="@clip-path and starts-with(@clip-path, 'url(#')">
680       <xsl:attribute name="Clip">
681         <xsl:value-of select="concat('{StaticResource ', substring-before(substring-after(@clip-path, 'url(#'), ')'), '}')" />
682       </xsl:attribute>
683     </xsl:when>
684     <xsl:when test="@style and contains(@style, 'clip-path:url(#')">
685       <xsl:attribute name="Clip">
686         <xsl:value-of select="concat('{StaticResource ', substring-before(substring-after(@style, 'url(#'), ')'), '}')" />
687       </xsl:attribute>
688     </xsl:when>
689     <xsl:when test="clipPath">
690       <xsl:apply-templates mode="forward" />
691     </xsl:when>
692   </xsl:choose>
693 </xsl:template>
695 <!--
696 // Misc templates //
698   * Id converter
699   * Decimal to hexadecimal converter
700   * Unit to pixel converter
701   * Object description
702   * Title and description
703   * Switch
704   * Symbols
705   * Use
706   * RDF and foreign objects
707   * Misc ignored stuff (markers, patterns, styles)
708   * Unknows tags
709 -->
711 <!--
712   // Id converter //
713   Removes "-" from the original id
714 -->
715 <xsl:template mode="id" match="*">
716 <xsl:if test="@id">
717   <xsl:attribute name="Name"><xsl:value-of select="translate(@id, '- ', '')" /></xsl:attribute>
718   <!--
719     <xsl:attribute name="x:Key"><xsl:value-of select="translate(@id, '- ', '')" /></xsl:attribute>
720   -->
721 </xsl:if>
722 </xsl:template>
724 <!--
725   // Decimal to hexadecimal converter //
726 -->
727 <xsl:template name="to_hex">
728   <xsl:param name="convert" />
729   <xsl:value-of select="concat(substring('0123456789ABCDEF', 1 + floor(round($convert) div 16), 1), substring('0123456789ABCDEF', 1 + round($convert) mod 16, 1))" />
730 </xsl:template>
732 <!-- 
733   // Unit to pixel converter //
734   Values with units (except %) are converted to pixels and rounded.
735   Unknown units are kept.
736   em, ex and % not implemented
737 -->
738 <xsl:template name="convert_unit">
739   <xsl:param name="convert_value" />
740   <xsl:choose>
741     <xsl:when test="contains($convert_value, 'px')">
742       <xsl:value-of select="round(translate($convert_value, 'px', ''))" />
743     </xsl:when>
744     <xsl:when test="contains($convert_value, 'pt')">
745       <xsl:value-of select="round(translate($convert_value, 'pt', '') * 1.25)" />
746     </xsl:when>
747     <xsl:when test="contains($convert_value, 'pc')">
748       <xsl:value-of select="round(translate($convert_value, 'pc', '') * 15)" />
749     </xsl:when>
750     <xsl:when test="contains($convert_value, 'mm')">
751       <xsl:value-of select="round(translate($convert_value, 'mm', '') * 3.543307)" />
752     </xsl:when>
753     <xsl:when test="contains($convert_value, 'cm')">
754       <xsl:value-of select="round(translate($convert_value, 'cm', '') * 35.43307)" />
755     </xsl:when>
756     <xsl:when test="contains($convert_value, 'in')">
757       <xsl:value-of select="round(translate($convert_value, 'in', '') * 90)" />
758     </xsl:when>
759     <xsl:when test="contains($convert_value, 'ft')">
760       <xsl:value-of select="round(translate($convert_value, 'ft', '') * 1080)" />
761     </xsl:when>
762     <xsl:when test="not(string(number($convert_value))='NaN')">
763       <xsl:value-of select="round($convert_value)" />
764     </xsl:when>
765     <xsl:otherwise>
766       <xsl:value-of select="$convert_value" />
767     </xsl:otherwise>
768   </xsl:choose>
769 </xsl:template>
771 <!-- 
772   // Object description //
773 -->
774 <xsl:template mode="desc" match="*">
775   <xsl:if test="*[name(.) = 'desc']/text()">
776     <xsl:attribute name="Tag">
777       <xsl:value-of select="*[name(.) = 'desc']/text()" />
778     </xsl:attribute>
779   </xsl:if>
780 </xsl:template>
782 <!-- 
783   // Title and description //
784   Title is ignored and desc is converted to Tag in the mode="desc" template
785 -->
786 <xsl:template mode="forward" match="*[name(.) = 'title' or name(.) = 'desc']">
788 </xsl:template>
790 <!--
791   // Switch //
792 -->
793 <xsl:template mode="forward" match="*[name(.) = 'switch']">
794   <xsl:apply-templates mode="forward" />
795 </xsl:template>
797 <!--
798   // Symbols //
799 -->
800 <xsl:template mode="forward" match="*[name(.) = 'symbol']">
801   <Style>
802     <xsl:if test="@id">
803       <xsl:attribute name="x:Key">
804         <xsl:value-of select="@id" />
805       </xsl:attribute>
806     </xsl:if>
807     <Canvas>
808       <xsl:apply-templates mode="forward" />
809     </Canvas>
810   </Style>
811 </xsl:template>
813 <!--
814   // Use //
815   (since it is not supported by Inkscape, not implemented yet)
816 -->
817 <xsl:template mode="forward" match="*[name(.) = 'use']">
818   <Canvas>
819     <xsl:if test="@xlink:href">
820       <xsl:attribute name="Style">
821         <xsl:value-of select="@xlink:href" />
822       </xsl:attribute>
823     </xsl:if>
824     <!--xsl:apply-templates mode="transform" select="." /-->
825     <xsl:apply-templates mode="forward" />
826   </Canvas>
827 </xsl:template>
829 <!--
830   // RDF and foreign objects //
831 -->
832 <xsl:template mode="forward" match="rdf:RDF | *[name(.) = 'foreignObject']">
834 </xsl:template>
836 <!--
837   // Misc ignored stuff (markers, patterns, styles) //
838 -->
839 <xsl:template mode="forward" match="*[name(.) = 'marker' or name(.) = 'pattern' or name(.) = 'style']">
841 </xsl:template>
843 <!-- 
844   // Unknown tags //
845   With generic and mode="forward" templates
846 -->
847 <xsl:template match="*">
848   <xsl:comment>
849     <xsl:value-of select="concat('Unknown tag: ', name(.))" />
850   </xsl:comment>
851 </xsl:template>
853 <xsl:template mode="forward" match="*">
854   <xsl:comment>
855     <xsl:value-of select="concat('Unknown tag: ', name(.))" />
856   </xsl:comment>
857 </xsl:template>
859 <!--
860 // Colors and patterns //
862 * Generic color template
863 * Fill
864 * Fill opacity
865 * Fill rule
866 * Generic fill template
867 * Stroke
868 * Stroke opacity
869 * Generic stroke template
870 * Stroke width
871 * Stroke mitterlimit
872 * Stroke dasharray
873 * Stroke dashoffset
874 * Linejoin SVG to XAML converter
875 * Stroke linejoin
876 * Linecap SVG to XAML converter
877 * Stroke linecap
878 * Gradient stop
879 * Gradient stop opacity
880 * Gradient stop offset
881 * Image stretch
882 -->
884 <!--
885   // Generic color template //
886 -->
887 <xsl:template name="template_color">
888   <xsl:param name="colorspec" />
889   <xsl:param name="opacityspec" />
890   <xsl:choose>
891     <xsl:when test="starts-with($colorspec, 'rgb(') and not(contains($colorspec , '%'))">
892       <xsl:value-of select="'#'" />
893       <xsl:if test="$opacityspec != '' and number($opacityspec) != 1">
894         <xsl:call-template name="to_hex">
895           <xsl:with-param name="convert">
896             <xsl:value-of select="round(number($opacityspec) * 255)" />
897           </xsl:with-param>
898         </xsl:call-template>
899       </xsl:if>
900       <xsl:call-template name="to_hex">
901         <xsl:with-param name="convert">
902           <xsl:value-of select="substring-before(substring-after($colorspec, 'rgb('), ',')" />
903         </xsl:with-param>
904       </xsl:call-template>
905       <xsl:call-template name="to_hex">
906         <xsl:with-param name="convert">
907           <xsl:value-of select="substring-before(substring-after(substring-after($colorspec, 'rgb('), ','), ',')" />
908         </xsl:with-param>
909       </xsl:call-template>
910       <xsl:call-template name="to_hex">
911         <xsl:with-param name="convert">
912           <xsl:value-of select="substring-before(substring-after(substring-after(substring-after($colorspec, 'rgb('), ','), ','), ')')" />
913         </xsl:with-param>
914       </xsl:call-template>
915     </xsl:when>
916     <xsl:when test="starts-with($colorspec, 'rgb(') and contains($colorspec , '%')">
917       <xsl:value-of select="'#'" />
918       <xsl:if test="$opacityspec != '' and number($opacityspec) != 1">
919         <xsl:call-template name="to_hex">
920           <xsl:with-param name="convert">
921             <xsl:value-of select="round(number($opacityspec) * 255)" />
922           </xsl:with-param>
923         </xsl:call-template>
924       </xsl:if>
925       <xsl:call-template name="to_hex">
926         <xsl:with-param name="convert">
927           <xsl:value-of select="number(substring-before(substring-after($colorspec, 'rgb('), '%,')) * 255 div 100" />
928         </xsl:with-param>
929       </xsl:call-template>
930       <xsl:call-template name="to_hex">
931         <xsl:with-param name="convert">
932           <xsl:value-of select="number(substring-before(substring-after(substring-after($colorspec, 'rgb('), ','), '%,')) * 255 div 100" />
933         </xsl:with-param>
934       </xsl:call-template>
935       <xsl:call-template name="to_hex">
936         <xsl:with-param name="convert">
937           <xsl:value-of select="number(substring-before(substring-after(substring-after(substring-after($colorspec, 'rgb('), ','), ','), '%)')) * 255 div 100" />
938         </xsl:with-param>
939       </xsl:call-template>
940     </xsl:when>
941     <xsl:when test="starts-with($colorspec, '#')">
942       <xsl:value-of select="'#'" />
943       <xsl:if test="$opacityspec != ''">
944         <xsl:call-template name="to_hex">
945           <xsl:with-param name="convert">
946             <xsl:value-of select="round(number($opacityspec) * 255)" />
947           </xsl:with-param>
948         </xsl:call-template>
949       </xsl:if>
950       <xsl:choose>
951         <xsl:when test="string-length(substring-after($colorspec, '#')) = 3">
952           <xsl:variable name="colorspec3">
953             <xsl:value-of select="translate(substring-after($colorspec, '#'), 'abcdefgh', 'ABCDEFGH')" />
954           </xsl:variable>
955           <xsl:value-of select="concat(substring($colorspec3, 1, 1), substring($colorspec3, 1, 1))" />
956           <xsl:value-of select="concat(substring($colorspec3, 2, 1), substring($colorspec3, 2, 1))" />
957           <xsl:value-of select="concat(substring($colorspec3, 3, 1), substring($colorspec3, 3, 1))" />
958         </xsl:when>
959         <xsl:otherwise>
960           <xsl:value-of select="translate(substring-after($colorspec, '#'), 'abcdefgh', 'ABCDEFGH')" />
961         </xsl:otherwise>
962       </xsl:choose>
963     </xsl:when>
964     <xsl:otherwise>
965       <xsl:variable name="named_color_hex" select="document('colors.xml')/colors/color[@name = translate($colorspec, 'ABCDEFGHIJKLMNOPQRSTUVWXYZ', 'abcdefghijklmnopqrstuvwxyz')]/@hex" />
966       <xsl:choose>
967         <xsl:when test="$named_color_hex and $named_color_hex != ''">
968           <xsl:value-of select="'#'" />
969           <xsl:if test="$opacityspec != '' and number($opacityspec) != 1">
970             <xsl:call-template name="to_hex">
971               <xsl:with-param name="convert">
972                 <xsl:value-of select="number($opacityspec) * 255" />
973               </xsl:with-param>
974             </xsl:call-template>
975           </xsl:if>
976           <xsl:value-of select="substring-after($named_color_hex, '#')" />
977         </xsl:when>
978         <xsl:otherwise>
979           <xsl:value-of select="$colorspec" />
980         </xsl:otherwise>
981       </xsl:choose>
982     </xsl:otherwise>
983   </xsl:choose>
984 </xsl:template>
986 <!--
987   // Fill //
988 -->
989 <xsl:template mode="fill" match="*">
990   <xsl:variable name="value">
991     <xsl:choose>
992       <xsl:when test="@fill and starts-with(@fill, 'url(#')">
993         <xsl:value-of select="concat('{StaticResource ', substring-before(substring-after(@fill, 'url(#'), ')'), '}')" />
994       </xsl:when>
995       <xsl:when test="@fill">
996         <xsl:value-of select="@fill" />
997       </xsl:when>
998       <xsl:when test="@style and contains(@style, 'fill:') and starts-with(substring-after(@style, 'fill:'), 'url(#')">
999         <xsl:value-of select="concat('{StaticResource ', substring-before(substring-after(@style, 'url(#'), ')'), '}')" />
1000       </xsl:when>
1001       <xsl:when test="@style and contains(@style, 'fill:')">
1002         <xsl:variable name="Fill" select="substring-after(@style, 'fill:')" />
1003         <xsl:choose>
1004           <xsl:when test="contains($Fill, ';')">
1005             <xsl:value-of select="substring-before($Fill, ';')" />
1006           </xsl:when>
1007           <xsl:otherwise>
1008             <xsl:value-of select="$Fill" />
1009           </xsl:otherwise>
1010         </xsl:choose>
1011       </xsl:when>
1012       <xsl:when test="name(..) = 'g' or name(..) = 'svg'">
1013         <xsl:apply-templates mode="fill" select="parent::*"/>
1014       </xsl:when>
1015     </xsl:choose>
1016   </xsl:variable>
1017   <xsl:if test="$value">
1018     <!-- Removes unwanted characters in the color link (TODO: export to a specific template)-->
1019     <xsl:value-of select="normalize-space(translate($value, '&quot;', ''))" />
1020   </xsl:if>
1021 </xsl:template>
1023 <!--
1024   // Fill opacity //
1025 -->
1026 <xsl:template mode="fill_opacity" match="*">
1027   <xsl:variable name="value">
1028   <xsl:choose>
1029     <xsl:when test="@fill-opacity">
1030       <xsl:value-of select="@fill-opacity" />
1031     </xsl:when>
1032     <xsl:when test="@style and contains(@style, 'fill-opacity:')">
1033       <xsl:variable name="Opacity" select="substring-after(@style, 'fill-opacity:')" />
1034       <xsl:choose>
1035         <xsl:when test="contains($Opacity, ';')">
1036           <xsl:value-of select="substring-before($Opacity, ';')" />
1037         </xsl:when>
1038         <xsl:otherwise>
1039           <xsl:value-of select="$Opacity" />
1040         </xsl:otherwise>
1041       </xsl:choose>
1042     </xsl:when>
1043     <xsl:when test="name(..) = 'g' or name(..) = 'svg'">
1044       <xsl:apply-templates mode="fill_opacity" select="parent::*" />
1045     </xsl:when>
1046     <xsl:otherwise>1</xsl:otherwise>
1047   </xsl:choose>
1048   </xsl:variable>
1049   <xsl:choose>
1050     <xsl:when test="$value &lt; 0">0</xsl:when>
1051     <xsl:when test="$value &gt; 1">1</xsl:when>
1052     <xsl:otherwise>
1053       <xsl:value-of select="$value" />
1054     </xsl:otherwise>
1055   </xsl:choose>
1056 </xsl:template>
1058 <!--
1059   // Fill rule //
1060 -->
1061 <xsl:template mode="fill_rule" match="*">
1062   <xsl:choose>
1063     <xsl:when test="@fill-rule and (@fill-rule = 'nonzero' or @fill-rule = 'evenodd')">
1064       <xsl:attribute name="FillRule">
1065         <xsl:value-of select="@fill-rule" />
1066       </xsl:attribute>
1067     </xsl:when>
1068     <xsl:when test="@style and contains(@style, 'fill-rule:')">
1069       <xsl:variable name="FillRule" select="normalize-space(substring-after(@style, 'fill-rule:'))" />
1070       <xsl:choose>
1071         <xsl:when test="contains($FillRule, ';')">
1072           <xsl:if test="substring-before($FillRule, ';') = 'nonzero' or substring-before($FillRule, ';') = 'evenodd'">
1073             <xsl:attribute name="FillRule">
1074               <xsl:value-of select="substring-before($FillRule, ';')" />
1075             </xsl:attribute>
1076           </xsl:if>
1077         </xsl:when>
1078         <xsl:when test="$FillRule = 'nonzero' or $FillRule = 'evenodd'">
1079           <xsl:attribute name="FillRule">
1080             <xsl:value-of select="$FillRule" />
1081           </xsl:attribute>
1082         </xsl:when>
1083       </xsl:choose>
1084     </xsl:when>
1085     <xsl:when test="name(..) = 'g' or name(..) = 'svg'">
1086       <xsl:apply-templates mode="fill_rule" select="parent::*"/>
1087     </xsl:when>
1088     <xsl:otherwise>
1089       <xsl:attribute name="FillRule">NonZero</xsl:attribute>
1090     </xsl:otherwise>
1091   </xsl:choose>
1092 </xsl:template>
1094 <!--
1095   // Generic fill template //
1096 -->
1097 <xsl:template mode="template_fill" match="*">
1098   <xsl:variable name="fill"><xsl:apply-templates mode="fill" select="." /></xsl:variable>
1099   <xsl:variable name="fill_opacity"><xsl:apply-templates mode="fill_opacity" select="." /></xsl:variable>
1100   <xsl:if test="not($fill = 'none')">
1101     <xsl:attribute name="Fill">
1102       <xsl:choose>
1103         <xsl:when test="$fill != ''">
1104           <xsl:call-template name="template_color">
1105             <xsl:with-param name="colorspec">
1106               <xsl:if test="$fill != 'none'">
1107                 <xsl:value-of select="$fill" />
1108               </xsl:if>
1109             </xsl:with-param>
1110             <xsl:with-param name="opacityspec">
1111               <xsl:value-of select="$fill_opacity" />
1112             </xsl:with-param>
1113           </xsl:call-template>
1114         </xsl:when>
1115         <xsl:otherwise>#000000</xsl:otherwise>
1116       </xsl:choose>
1117     </xsl:attribute>
1118   </xsl:if>
1119 </xsl:template>
1121 <!--
1122   // Stroke //
1123 -->
1124 <xsl:template mode="stroke" match="*">
1125   <xsl:choose>
1126     <xsl:when test="@stroke and starts-with(@stroke, 'url(#')">
1127       <xsl:value-of select="concat('{StaticResource ', substring-before(substring-after(@stroke, 'url(#'), ')'), '}')" />
1128     </xsl:when>
1129     <xsl:when test="@stroke and @stroke != 'none'">
1130       <xsl:value-of select="@stroke" />
1131     </xsl:when>
1132     <xsl:when test="@style and contains(@style, 'stroke:') and starts-with(substring-after(@style, 'stroke:'), 'url(#')">
1133       <xsl:value-of select="concat('{StaticResource ', substring-before(substring-after(@style, 'url(#'), ')'), '}')" />
1134     </xsl:when>
1135     <xsl:when test="@style and contains(@style, 'stroke:')">
1136       <xsl:variable name="Stroke" select="substring-after(@style, 'stroke:')" />
1137       <xsl:choose>
1138         <xsl:when test="contains($Stroke, ';')">
1139           <xsl:if test="substring-before($Stroke, ';') != 'none'">
1140             <xsl:value-of select="substring-before($Stroke, ';')" />
1141           </xsl:if>
1142         </xsl:when>
1143         <xsl:when test="$Stroke != 'none'">
1144           <xsl:value-of select="$Stroke" />
1145         </xsl:when>
1146       </xsl:choose>
1147     </xsl:when>
1148     <xsl:when test="name(..) = 'g' or name(..) = 'svg'">
1149       <xsl:apply-templates mode="stroke" select="parent::*"/>
1150     </xsl:when>
1151   </xsl:choose>
1152 </xsl:template>
1154 <!--
1155   // Stroke opacity //
1156 -->
1157 <xsl:template mode="stroke_opacity" match="*">
1158   <xsl:variable name="value">
1159   <xsl:choose>
1160     <xsl:when test="@stroke-opacity">
1161       <xsl:value-of select="@stroke-opacity" />
1162     </xsl:when>
1163     <xsl:when test="@style and contains(@style, 'stroke-opacity:')">
1164       <xsl:variable name="Opacity" select="substring-after(@style, 'stroke-opacity:')" />
1165       <xsl:choose>
1166         <xsl:when test="contains($Opacity, ';')">
1167           <xsl:value-of select="substring-before($Opacity, ';')" />
1168         </xsl:when>
1169         <xsl:otherwise>
1170           <xsl:value-of select="$Opacity" />
1171         </xsl:otherwise>
1172       </xsl:choose>
1173     </xsl:when>
1174     <xsl:when test="name(..) = 'g' or name(..) = 'svg'">
1175       <xsl:apply-templates mode="stroke_opacity" select="parent::*" />
1176     </xsl:when>
1177     <xsl:otherwise>1</xsl:otherwise>
1178   </xsl:choose>
1179   </xsl:variable>
1180   <xsl:choose>
1181     <xsl:when test="$value &lt; 0">0</xsl:when>
1182     <xsl:when test="$value &gt; 1">1</xsl:when>
1183     <xsl:otherwise>
1184       <xsl:value-of select="$value" />
1185     </xsl:otherwise>
1186   </xsl:choose>
1187 </xsl:template>
1189 <!-- 
1190   // Generic stroke template //
1191  -->
1192 <xsl:template mode="template_stroke" match="*">
1193   <xsl:variable name="stroke">
1194     <xsl:apply-templates mode="stroke" select="." />
1195   </xsl:variable>
1196   <xsl:variable name="stroke_opacity">
1197     <xsl:apply-templates mode="stroke_opacity" select="." />
1198   </xsl:variable>
1199   <xsl:variable name="stroke_width">
1200     <xsl:apply-templates mode="stroke_width" select="." />
1201   </xsl:variable>
1202   
1203   <xsl:if test="$stroke_width != ''">
1204     <xsl:attribute name="StrokeThickness">
1205       <xsl:value-of select="$stroke_width" />
1206     </xsl:attribute>
1207   </xsl:if>
1208   <xsl:if test="$stroke != ''">
1209     <xsl:attribute name="Stroke">
1210       <xsl:call-template name="template_color">
1211         <xsl:with-param name="colorspec">
1212           <xsl:value-of select="$stroke" />
1213         </xsl:with-param>
1214         <xsl:with-param name="opacityspec">
1215           <xsl:value-of select="$stroke_opacity" />
1216         </xsl:with-param>
1217       </xsl:call-template>
1218     </xsl:attribute>
1219   </xsl:if>
1220 </xsl:template>
1222 <!--
1223   // Stroke width //
1224 -->
1225 <xsl:template mode="stroke_width" match="*">
1226   <xsl:choose>
1227     <xsl:when test="@stroke-width">
1228       <xsl:call-template name="convert_unit">
1229         <xsl:with-param name="convert_value">
1230           <xsl:value-of select="@stroke-width" />
1231         </xsl:with-param>
1232       </xsl:call-template> 
1233     </xsl:when>
1234     <xsl:when test="@style and contains(@style, 'stroke-width:')">
1235       <xsl:call-template name="convert_unit">
1236         <xsl:with-param name="convert_value">
1237         <xsl:choose>
1238           <xsl:when test="contains(substring-after(@style, 'stroke-width:'), ';')">
1239             <xsl:value-of select="substring-before(substring-after(@style, 'stroke-width:'), ';')" />
1240           </xsl:when>
1241           <xsl:otherwise>
1242             <xsl:value-of select="substring-after(@style, 'stroke-width:')" />
1243           </xsl:otherwise>
1244         </xsl:choose>
1245         </xsl:with-param>
1246       </xsl:call-template> 
1247     </xsl:when>
1248     <xsl:when test="name(..) = 'g' or name(..) = 'svg'">
1249       <xsl:apply-templates mode="stroke_width" select="parent::*"/>
1250     </xsl:when>
1251   </xsl:choose>
1252 </xsl:template>
1254 <!--
1255   // Stroke miterlimit //
1256 -->
1257 <xsl:template mode="stroke_miterlimit" match="*">
1258   <xsl:choose>
1259     <xsl:when test="@stroke-miterlimit">
1260       <xsl:attribute name="StrokeMiterLimit">
1261         <xsl:value-of select="@stroke-miterlimit" />
1262       </xsl:attribute>
1263     </xsl:when>
1264     <xsl:when test="@style and contains(@style, 'stroke-miterlimit:')">
1265       <xsl:variable name="StrokeMiterLimit" select="substring-after(@style, 'stroke-miterlimit:')" />
1266       <xsl:attribute name="StrokeMiterLimit">
1267         <xsl:choose>
1268           <xsl:when test="contains($StrokeMiterLimit, ';')">
1269             <xsl:value-of select="substring-before($StrokeMiterLimit, ';')" />
1270           </xsl:when>
1271           <xsl:otherwise>
1272             <xsl:value-of select="$StrokeMiterLimit" />
1273           </xsl:otherwise>
1274         </xsl:choose>
1275       </xsl:attribute>
1276     </xsl:when>
1277     <xsl:when test="name(..) = 'g' or name(..) = 'svg'">
1278       <xsl:apply-templates mode="stroke_miterlimit" select="parent::*"/>
1279     </xsl:when>
1280   </xsl:choose>
1281 </xsl:template>
1283 <!-- 
1284   // Stroke dasharray //
1285 -->
1286 <xsl:template mode="stroke_dasharray" match="*">
1287   <!-- stroke-dasharray="10,30,20,30" becomes StrokeDashArray="1 3 2 3" ?? -->
1288   <xsl:choose>
1289     <xsl:when test="@stroke-dasharray and @stroke-dasharray != 'none'">
1290       <xsl:attribute name="StrokeDashArray">
1291         <xsl:value-of select="@stroke-dasharray" />
1292       </xsl:attribute>
1293     </xsl:when>
1294     <xsl:when test="@style and contains(@style, 'stroke-dasharray:')">
1295       <xsl:variable name="StrokeDashArray" select="substring-after(@style, 'stroke-dasharray:')" />
1296       <xsl:choose>
1297         <xsl:when test="contains($StrokeDashArray, ';')">
1298           <xsl:if test="substring-before($StrokeDashArray, ';') != 'none'">
1299             <xsl:attribute name="StrokeDashArray">
1300               <xsl:value-of select="substring-before($StrokeDashArray, ';')" />
1301             </xsl:attribute>
1302           </xsl:if>
1303         </xsl:when>
1304         <xsl:when test="$StrokeDashArray != 'none'">
1305           <xsl:attribute name="StrokeDashArray">
1306             <xsl:value-of select="$StrokeDashArray" />
1307           </xsl:attribute>
1308         </xsl:when>
1309       </xsl:choose>
1310     </xsl:when>
1311     <xsl:when test="name(..) = 'g' or name(..) = 'svg'">
1312       <xsl:apply-templates mode="stroke_dasharray" select="parent::*"/>
1313     </xsl:when>
1314   </xsl:choose>
1315 </xsl:template>
1317 <!-- 
1318   // Stroke dashoffset //
1319 -->
1320 <xsl:template mode="stroke_dashoffset" match="*">
1321   <xsl:choose>
1322     <xsl:when test="@stroke-dashoffset">
1323       <xsl:attribute name="StrokeDashOffset">
1324         <xsl:value-of select="@stroke-dashoffset" />
1325       </xsl:attribute>
1326     </xsl:when>
1327     <xsl:when test="@style and contains(@style, 'stroke-dashoffset:')">
1328       <xsl:variable name="StrokeDashOffset" select="substring-after(@style, 'stroke-dashoffset:')" />
1329       <xsl:attribute name="StrokeDashOffset">
1330         <xsl:choose>
1331           <xsl:when test="contains($StrokeDashOffset, ';')">
1332             <xsl:value-of select="substring-before($StrokeDashOffset, ';')" />
1333           </xsl:when>
1334           <xsl:otherwise>
1335             <xsl:value-of select="$StrokeDashOffset" />
1336           </xsl:otherwise>
1337         </xsl:choose>
1338       </xsl:attribute>
1339     </xsl:when>
1340     <xsl:when test="name(..) = 'g' or name(..) = 'svg'">
1341       <xsl:apply-templates mode="stroke_dashoffset" select="parent::*"/>
1342     </xsl:when>
1343   </xsl:choose>
1344 </xsl:template>
1346 <!-- 
1347   // Linejoin SVG to XAML converter //
1348 -->
1349 <xsl:template name="linejoin_svg_to_xaml">
1350   <xsl:param name="linejoin" />
1351   <xsl:choose>
1352     <xsl:when test="$linejoin = 'bevel'">Bevel</xsl:when>
1353     <xsl:when test="$linejoin = 'round'">Round</xsl:when>
1354     <xsl:otherwise>Miter</xsl:otherwise>
1355   </xsl:choose>
1356 </xsl:template>
1358 <!-- 
1359   // Stroke linejoin //
1360 -->
1361 <xsl:template mode="stroke_linejoin" match="*">
1362   <xsl:choose>
1363     <xsl:when test="@stroke-linejoin">
1364       <xsl:attribute name="StrokeLineJoin">
1365         <xsl:call-template name="linejoin_svg_to_xaml">
1366           <xsl:with-param name="linejoin">
1367             <xsl:value-of select="@stroke-linejoin" />
1368           </xsl:with-param>
1369         </xsl:call-template>
1370       </xsl:attribute>
1371     </xsl:when>
1372     <xsl:when test="@style and contains(@style, 'stroke-linejoin:')">
1373       <xsl:variable name="StrokeLineJoin" select="substring-after(@style, 'stroke-linejoin:')" />
1374       <xsl:attribute name="StrokeLineJoin">
1375         <xsl:choose>
1376           <xsl:when test="contains($StrokeLineJoin, ';')">
1377             <xsl:call-template name="linejoin_svg_to_xaml">
1378               <xsl:with-param name="linejoin">
1379                 <xsl:value-of select="substring-before($StrokeLineJoin, ';')" />
1380               </xsl:with-param>
1381             </xsl:call-template>
1382           </xsl:when>
1383           <xsl:otherwise>
1384             <xsl:call-template name="linejoin_svg_to_xaml">
1385               <xsl:with-param name="linejoin">
1386                 <xsl:value-of select="$StrokeLineJoin" />
1387               </xsl:with-param>
1388             </xsl:call-template>
1389           </xsl:otherwise>
1390         </xsl:choose>
1391       </xsl:attribute>
1392     </xsl:when>
1393     <xsl:when test="name(..) = 'g' or name(..) = 'svg'">
1394       <xsl:apply-templates mode="stroke_linejoin" select="parent::*"/>
1395     </xsl:when>
1396   </xsl:choose>
1397 </xsl:template>
1399 <!-- 
1400   // Linecap SVG to XAML converter //
1401 -->
1402 <xsl:template name="linecap_svg_to_xaml">
1403   <xsl:param name="linecap" />
1404   <xsl:choose>
1405     <xsl:when test="$linecap = 'round'">Round</xsl:when>
1406     <xsl:when test="$linecap = 'square'">Square</xsl:when>
1407     <xsl:otherwise>Flat</xsl:otherwise>
1408   </xsl:choose>
1409 </xsl:template>
1411 <!--
1412   // Stroke linecap //
1413 -->
1414 <xsl:template mode="stroke_linecap" match="*">
1415   <xsl:choose>
1416     <xsl:when test="@stroke-linecap">
1417       <xsl:attribute name="StrokeStartLineCap">
1418         <xsl:call-template name="linecap_svg_to_xaml">
1419           <xsl:with-param name="linecap">
1420             <xsl:value-of select="@stroke-linecap" />
1421           </xsl:with-param>
1422         </xsl:call-template>
1423       </xsl:attribute>
1424       <xsl:attribute name="StrokeEndLineCap">
1425         <xsl:call-template name="linecap_svg_to_xaml">
1426           <xsl:with-param name="linecap">
1427             <xsl:value-of select="@stroke-linecap" />
1428           </xsl:with-param>
1429         </xsl:call-template>
1430       </xsl:attribute>
1431     </xsl:when>
1432     <xsl:when test="@style and contains(@style, 'stroke-linecap:')">
1433       <xsl:variable name="StrokeStartLineCap" select="substring-after(@style, 'stroke-linecap:')" />
1434       <xsl:variable name="StrokeEndLineCap" select="substring-after(@style, 'stroke-linecap:')" />
1435       <xsl:attribute name="StrokeStartLineCap">
1436         <xsl:choose>
1437           <xsl:when test="contains($StrokeStartLineCap, ';')">
1438             <xsl:call-template name="linecap_svg_to_xaml">
1439               <xsl:with-param name="linecap">
1440                 <xsl:value-of select="substring-before($StrokeStartLineCap, ';')" />
1441               </xsl:with-param>
1442             </xsl:call-template>
1443           </xsl:when>
1444           <xsl:otherwise>
1445             <xsl:call-template name="linecap_svg_to_xaml">
1446               <xsl:with-param name="linecap">
1447                 <xsl:value-of select="$StrokeStartLineCap" />
1448               </xsl:with-param>
1449             </xsl:call-template>
1450           </xsl:otherwise>
1451         </xsl:choose>
1452       </xsl:attribute>
1453       <xsl:attribute name="StrokeEndLineCap">
1454         <xsl:choose>
1455           <xsl:when test="contains($StrokeEndLineCap, ';')">
1456             <xsl:call-template name="linecap_svg_to_xaml">
1457               <xsl:with-param name="linecap">
1458                 <xsl:value-of select="substring-before($StrokeEndLineCap, ';')" />
1459               </xsl:with-param>
1460             </xsl:call-template>
1461           </xsl:when>
1462           <xsl:otherwise>
1463             <xsl:call-template name="linecap_svg_to_xaml">
1464               <xsl:with-param name="linecap">
1465                 <xsl:value-of select="$StrokeEndLineCap" />
1466               </xsl:with-param>
1467             </xsl:call-template>
1468           </xsl:otherwise>
1469         </xsl:choose>
1470       </xsl:attribute>
1471     </xsl:when>
1472     <xsl:when test="name(..) = 'g' or name(..) = 'svg'">
1473       <xsl:apply-templates mode="stroke_linecap" select="parent::*"/>
1474     </xsl:when>
1475   </xsl:choose>
1476 </xsl:template>
1478 <!-- 
1479   // Gradient stops //
1480 -->
1481 <xsl:template mode="stop_color" match="*">
1482   <xsl:variable name="Opacity">
1483     <xsl:choose>
1484       <xsl:when test="@stop-opacity">
1485         <xsl:value-of select="@stop-opacity" />
1486       </xsl:when>
1487       <xsl:when test="@style and contains(@style, 'stop-opacity:')">
1488         <xsl:variable name="temp_opacity" select="substring-after(@style, 'stop-opacity:')" />
1489         <xsl:choose>
1490           <xsl:when test="contains($temp_opacity, ';')">
1491             <xsl:value-of select="substring-before($temp_opacity, ';')" />
1492           </xsl:when>
1493           <xsl:otherwise>
1494             <xsl:value-of select="$temp_opacity" />
1495           </xsl:otherwise>
1496         </xsl:choose>
1497       </xsl:when>
1498       <xsl:otherwise>
1499         <xsl:value-of select="''" />
1500       </xsl:otherwise>
1501     </xsl:choose>
1502   </xsl:variable>
1503   <xsl:variable name="hex_opacity">
1504     <xsl:choose>
1505       <xsl:when test="$Opacity != ''">
1506         <xsl:call-template name="to_hex">
1507           <xsl:with-param name="convert">
1508             <xsl:value-of select="number($Opacity) * 255" />
1509           </xsl:with-param>
1510         </xsl:call-template>
1511       </xsl:when>
1512       <xsl:otherwise>
1513         <xsl:value-of select="$Opacity" />
1514       </xsl:otherwise>
1515     </xsl:choose>
1516   </xsl:variable>
1517   <xsl:variable name="stopcolor">
1518     <xsl:choose>
1519       <xsl:when test="@stop-color">
1520         <xsl:call-template name="template_color">
1521           <xsl:with-param name="colorspec">
1522             <xsl:value-of select="@stop-color" />
1523           </xsl:with-param>
1524         </xsl:call-template>
1525       </xsl:when>
1526       <xsl:when test="@style and contains(@style, 'stop-color:')">
1527         <xsl:variable name="Color" select="substring-after(@style, 'stop-color:')" />
1528         <xsl:choose>
1529           <xsl:when test="contains($Color, ';')">
1530             <xsl:call-template name="template_color">
1531               <xsl:with-param name="colorspec">
1532                 <xsl:value-of select="substring-before($Color, ';')" />
1533               </xsl:with-param>
1534             </xsl:call-template>
1535           </xsl:when>
1536           <xsl:otherwise>
1537             <xsl:call-template name="template_color">
1538               <xsl:with-param name="colorspec">
1539                 <xsl:value-of select="$Color" />
1540               </xsl:with-param>
1541             </xsl:call-template>
1542           </xsl:otherwise>
1543         </xsl:choose>
1544       </xsl:when>
1545       <xsl:when test="name(..) = 'g' or name(..) = 'svg'">
1546         <xsl:apply-templates mode="stop_color" select="parent::*"/>
1547       </xsl:when>
1548       <xsl:otherwise>#000</xsl:otherwise>
1549     </xsl:choose>
1550   </xsl:variable>
1551   <xsl:attribute name="Color">
1552     <xsl:choose>
1553       <xsl:when test="$hex_opacity != '' and starts-with($stopcolor, '#')">
1554         <xsl:value-of select="concat('#', $hex_opacity, substring-after($stopcolor, '#'))" />
1555       </xsl:when>
1556       <xsl:otherwise>
1557         <xsl:value-of select="$stopcolor" />
1558       </xsl:otherwise>
1559     </xsl:choose>
1560   </xsl:attribute>
1561 </xsl:template>
1563 <!--
1564   // Gradient stop opacity //
1565 -->
1566 <xsl:template mode="stop_opacity" match="*">
1567   <xsl:choose>
1568     <xsl:when test="@stop-opacity">
1569       <xsl:attribute name="Opacity">
1570         <xsl:value-of select="@stop-opacity" />
1571       </xsl:attribute>
1572     </xsl:when>
1573     <xsl:when test="@style and contains(@style, 'stop-opacity:')">
1574       <xsl:variable name="Opacity" select="substring-after(@style, 'stop-opacity:')" />
1575       <xsl:attribute name="Opacity">
1576         <xsl:choose>
1577           <xsl:when test="contains($Opacity, ';')">
1578             <xsl:value-of select="substring-before($Opacity, ';')" />
1579           </xsl:when>
1580           <xsl:otherwise>
1581             <xsl:value-of select="$Opacity" />
1582           </xsl:otherwise>
1583         </xsl:choose>
1584       </xsl:attribute>
1585     </xsl:when>
1586     <xsl:when test="name(..) = 'g' or name(..) = 'svg'">
1587       <xsl:apply-templates mode="stop_opacity" select="parent::*"/>
1588     </xsl:when>
1589   </xsl:choose>
1590 </xsl:template>
1592 <!--
1593   // Gradient stop offset //
1594 -->
1595 <xsl:template mode="offset" match="*">
1596   <xsl:choose>
1597     <xsl:when test="@offset">
1598       <xsl:attribute name="Offset">
1599         <xsl:choose>
1600           <xsl:when test="contains(@offset, '%')">
1601             <xsl:value-of select="number(substring-before(@offset, '%')) div 100" />
1602           </xsl:when>
1603           <xsl:otherwise>
1604             <xsl:value-of select="@offset" />
1605           </xsl:otherwise>
1606         </xsl:choose>
1607       </xsl:attribute>
1608     </xsl:when>
1609     <xsl:when test="@style and contains(@style, 'offset:')">
1610       <xsl:variable name="Offset" select="substring-after(@style, 'offset:')" />
1611       <xsl:attribute name="Offset">
1612         <xsl:choose>
1613           <xsl:when test="contains($Offset, '%')">
1614             <xsl:value-of select="number(substring-before($Offset, '%')) div 100" />
1615           </xsl:when>        
1616           <xsl:when test="contains($Offset, ';')">
1617             <xsl:value-of select="substring-before($Offset, ';')" />
1618           </xsl:when>
1619           <xsl:otherwise>
1620             <xsl:value-of select="$Offset" />
1621           </xsl:otherwise>
1622         </xsl:choose>
1623       </xsl:attribute>
1624     </xsl:when>
1625     <xsl:when test="name(..) = 'g' or name(..) = 'svg'">
1626       <xsl:apply-templates mode="stop_offset" select="parent::*"/>
1627     </xsl:when>
1628   </xsl:choose>
1629 </xsl:template>
1631 <!-- 
1632   // Image stretch //
1633   SVG: preserveAspectRatio, XAML: Stretch
1634 -->
1635 <xsl:template mode="image_stretch" match="*">
1636   <xsl:variable name="value">
1637     <xsl:choose>
1638       <xsl:when test="@preserveAspectRatio">
1639         <xsl:value-of select="@preserveAspectRatio" />
1640       </xsl:when>
1641       <xsl:when test="@style and contains(@style, 'preserveAspectRatio:')">
1642         <xsl:variable name="ratio" select="normalize-space(substring-after(@style, 'preserveAspectRatio:'))" />
1643         <xsl:choose>
1644           <xsl:when test="contains($ratio, ';')">
1645             <xsl:value-of select="substring-before($ratio, ';')" />
1646           </xsl:when>
1647           <xsl:otherwise>
1648             <xsl:value-of select="$ratio" />
1649           </xsl:otherwise>
1650         </xsl:choose>
1651       </xsl:when>
1652     </xsl:choose>
1653   </xsl:variable>
1654   <xsl:if test="$value = 'none'">  
1655     <xsl:attribute name="Stretch">Fill</xsl:attribute>
1656   </xsl:if>
1657 </xsl:template>
1659 <!-- 
1660   // Text specific templates //
1662   * Text tspan
1663   * Text flowPara
1664   * Text flowRegion (text frame)
1665   * Get font size
1666   * Font size
1667   * Font weight
1668   * Font family
1669   * Font style
1670   * Baseline shift
1671   * Line height
1672   * Writing mode
1673   * Text decoration
1674   * Text fill
1675   * Text direction
1676   * Text size
1677   * Text position
1678   * Text object
1679   * FlowRoot object
1680 -->
1682  <!-- 
1683   // Text span //
1684   SVG: tspan, flowSpan, FXG: span
1685   
1686   Not supported in FXG:
1687   * span position
1688 -->
1689 <xsl:template mode="forward" match="*[name(.) = 'tspan'  or name(.) = 'flowSpan']">
1690   <span>
1691     <xsl:if test="../@xml:space='preserve'">
1692       <xsl:attribute name="whiteSpaceCollapse">preserve</xsl:attribute>
1693     </xsl:if>
1694     <xsl:variable name="fill">
1695       <xsl:apply-templates mode="fill" select="." />
1696     </xsl:variable>
1697     <xsl:variable name="fill_opacity">
1698       <xsl:apply-templates mode="fill_opacity" select="." />
1699     </xsl:variable>
1700     <xsl:if test="starts-with($fill, '#') or (not(starts-with($fill, 'url')) and $fill != '' and $fill != 'none')">
1701       <xsl:attribute name="color">
1702         <xsl:call-template name="template_color">
1703           <xsl:with-param name="colorspec">
1704             <xsl:value-of select="$fill" />
1705           </xsl:with-param>
1706         </xsl:call-template>
1707       </xsl:attribute>
1708       <xsl:attribute name="textAlpha">
1709         <xsl:value-of select="$fill_opacity" />
1710       </xsl:attribute>
1711     </xsl:if>
1712     <xsl:apply-templates mode="font_size" select="." />
1713     <xsl:apply-templates mode="font_weight" select="." />
1714     <xsl:apply-templates mode="font_family" select="." />
1715     <xsl:apply-templates mode="font_style" select="." />
1716     <xsl:apply-templates mode="text_fill" select="." />
1717     <xsl:apply-templates mode="text_decoration" select="." />
1718     <xsl:apply-templates mode="line_height" select="." />
1719     <xsl:apply-templates mode="baseline_shift" select="." />
1720     
1721     <xsl:if test="text()">
1722       <xsl:value-of select="text()" />
1723     </xsl:if>
1724   </span>
1725 </xsl:template>
1727  <!-- 
1728   // Text flowPara //
1729   SVG: flowPara, flowDiv FXG: p
1730   
1731   Not supported in FXG:
1732   * paragraph position
1733 -->
1734 <xsl:template mode="forward" match="*[name(.) = 'flowPara' or name(.) = 'flowDiv']">
1735   <p>
1736     <xsl:if test="../@xml:space='preserve'">
1737       <xsl:attribute name="whiteSpaceCollapse">preserve</xsl:attribute>
1738     </xsl:if>
1739     <xsl:variable name="fill">
1740       <xsl:apply-templates mode="fill" select="." />
1741     </xsl:variable>
1742     <xsl:variable name="fill_opacity">
1743       <xsl:apply-templates mode="fill_opacity" select="." />
1744     </xsl:variable>
1745     <xsl:if test="starts-with($fill, '#') or (not(starts-with($fill, 'url')) and $fill != '' and $fill != 'none')">
1746       <xsl:attribute name="color">
1747         <xsl:call-template name="template_color">
1748           <xsl:with-param name="colorspec">
1749             <xsl:value-of select="$fill" />
1750           </xsl:with-param>
1751         </xsl:call-template>
1752       </xsl:attribute>
1753       <xsl:attribute name="textAlpha">
1754         <xsl:value-of select="$fill_opacity" />
1755       </xsl:attribute>
1756     </xsl:if>
1757     <xsl:apply-templates mode="font_size" select="." />
1758     <xsl:apply-templates mode="font_weight" select="." />
1759     <xsl:apply-templates mode="font_family" select="." />
1760     <xsl:apply-templates mode="font_style" select="." />
1761     <xsl:apply-templates mode="text_fill" select="." />
1762     <xsl:apply-templates mode="text_decoration" select="." />
1763     <xsl:apply-templates mode="line_height" select="." />
1764     <xsl:apply-templates mode="baseline_shift" select="." />
1766     <xsl:choose>
1767       <xsl:when test="*[name(.) = 'flowSpan']/text()">
1768         <xsl:apply-templates mode="forward" />
1769       </xsl:when>
1770       <xsl:otherwise>
1771         <xsl:choose>
1772           <xsl:when test="@xml:space='preserve'">
1773             <xsl:copy-of select="translate(text(), '&#x9;&#xA;&#xD;', ' ')" />
1774           </xsl:when>
1775           <xsl:otherwise>
1776             <xsl:copy-of select="normalize-space(translate(text(), '&#x9;&#xA;&#xD;', ' '))" />
1777           </xsl:otherwise>
1778         </xsl:choose>  
1779       </xsl:otherwise>
1780     </xsl:choose>
1781   </p>
1782 </xsl:template>
1785  <!-- 
1786   // Text flowRegion //
1787 -->
1788 <xsl:template mode="flow_region" match="*">
1789   <xsl:apply-templates mode="text_size" select="." />
1790   <xsl:apply-templates mode="text_position" select="." />
1791 </xsl:template>
1793 <!-- 
1794   // Get text font size //
1795 -->
1796 <xsl:template mode="get_font_size" match="*">
1797   <xsl:choose>
1798     <xsl:when test="@font-size">
1799       <xsl:value-of select="@font-size" />
1800     </xsl:when>
1801     <xsl:when test="@style and contains(@style, 'font-size:')">
1802       <xsl:variable name="font_size" select="normalize-space(substring-after(@style, 'font-size:'))" />
1803       <xsl:choose>
1804         <xsl:when test="contains($font_size, ';')">
1805           <xsl:value-of select="substring-before($font_size, ';')" />
1806         </xsl:when>
1807         <xsl:otherwise>
1808           <xsl:value-of select="$font_size" />
1809         </xsl:otherwise>
1810       </xsl:choose>
1811     </xsl:when>
1812     <xsl:when test="name(..) = 'g' or name(..) = 'svg'">
1813       <xsl:apply-templates mode="get_font_size" select="parent::*"/>
1814     </xsl:when>
1815   </xsl:choose>
1816 </xsl:template>
1818 <!-- 
1819   // Text font size //
1820   SVG: font-size, XAML: FontSize
1821 -->
1822 <xsl:template mode="font_size" match="*">
1823   <xsl:variable name="value">
1824     <xsl:apply-templates mode="get_font_size" select="." />
1825   </xsl:variable>
1826   <xsl:if test="$value != ''">
1827     <xsl:attribute name="FontSize">
1828       <xsl:call-template name="convert_unit">
1829         <xsl:with-param name="convert_value" select="$value" />
1830       </xsl:call-template>
1831     </xsl:attribute>
1832   </xsl:if>
1833   <xsl:attribute name="FontSize">
1834     <xsl:choose>
1835       <xsl:when test="$value != ''">
1836         <xsl:call-template name="convert_unit">
1837           <xsl:with-param name="convert_value" select="$value" />
1838         </xsl:call-template>
1839       </xsl:when>
1840       <xsl:otherwise>12</xsl:otherwise>
1841     </xsl:choose>
1842   </xsl:attribute>
1843 </xsl:template>
1845 <!-- 
1846   // Text font weight //
1847   SVG: font-weight, XAML: FontWeight
1848 -->
1849 <xsl:template mode="font_weight" match="*">
1850   <xsl:variable name="value">
1851     <xsl:if test="@font-weight">
1852       <xsl:value-of select="@font-weight" />
1853     </xsl:if>
1854     <xsl:if test="@style and contains(@style, 'font-weight:')">
1855       <xsl:variable name="font_weight" select="normalize-space(substring-after(@style, 'font-weight:'))" />
1856       <xsl:choose>
1857         <xsl:when test="contains($font_weight, ';')">
1858           <xsl:value-of select="substring-before($font_weight, ';')" />
1859         </xsl:when>
1860         <xsl:otherwise>
1861           <xsl:value-of select="$font_weight" />
1862         </xsl:otherwise>
1863       </xsl:choose>
1864     </xsl:if>
1865   </xsl:variable>
1866   <xsl:if test="$value != ''">
1867     <xsl:attribute name="FontWeight">
1868       <xsl:choose>
1869         <xsl:when test="$value &lt;= 100 or $value = 'lighter'">Thin</xsl:when>
1870         <xsl:when test="$value &gt; 100 and $value &lt;= 200">ExtraLight</xsl:when>
1871         <xsl:when test="$value &gt; 200 and $value &lt;= 300">Light</xsl:when>
1872         <xsl:when test="($value &gt; 300 and $value &lt;= 400) or $value ='normal'">Normal</xsl:when>
1873         <xsl:when test="$value &gt; 400 and $value &lt;= 500">Medium</xsl:when>
1874         <xsl:when test="$value &gt; 500 and $value &lt;= 600">SemiBold</xsl:when>
1875         <xsl:when test="($value &gt; 600 and $value &lt;= 700) or $value ='bold'">Bold</xsl:when>
1876         <xsl:when test="$value &gt; 700 and $value &lt;= 800">ExtraBold</xsl:when>
1877         <xsl:when test="$value &gt; 800 and $value &lt;= 900">Black</xsl:when>
1878         <xsl:when test="$value &gt; 900 or $value = 'bolder'">ExtraBlack</xsl:when>
1879         <xsl:otherwise>normal</xsl:otherwise>
1880       </xsl:choose>
1881     </xsl:attribute>
1882   </xsl:if>
1883 </xsl:template>
1885 <!-- 
1886   // Text font family //
1887   SVG: font-family, XAML: FontFamily
1888 -->
1889 <xsl:template mode="font_family" match="*">
1890   <xsl:variable name="value">
1891     <xsl:if test="@font-family">
1892       <xsl:value-of select="translate(@font-family, &quot;'&quot;, '')" />
1893     </xsl:if>
1894     <xsl:if test="@style and contains(@style, 'font-family:')">
1895       <xsl:variable name="font_family" select="normalize-space(substring-after(@style, 'font-family:'))" />
1896       <xsl:choose>
1897         <xsl:when test="contains($font_family, ';')">
1898           <xsl:value-of select="translate(substring-before($font_family, ';'), &quot;'&quot;, '')" />
1899         </xsl:when>
1900         <xsl:otherwise>
1901           <xsl:value-of select="translate($font_family, &quot;'&quot;, '')" />
1902         </xsl:otherwise>
1903       </xsl:choose>
1904     </xsl:if>
1905   </xsl:variable>
1906   <xsl:if test="$value != ''">
1907     <xsl:attribute name="FontFamily">
1908       <xsl:choose>
1909         <xsl:when test="$value='Sans'">Arial</xsl:when>
1910         <xsl:otherwise>
1911           <xsl:value-of select="$value" />
1912         </xsl:otherwise>
1913       </xsl:choose>
1914     </xsl:attribute>
1915   </xsl:if>
1916 </xsl:template>
1918 <!-- 
1919   // Text font style //
1920   SVG: font-style, XAML: FontStyle
1921 -->
1922 <xsl:template mode="font_style" match="*">
1923   <xsl:variable name="value">
1924     <xsl:if test="@font-style">
1925       <xsl:value-of select="@font-style" />
1926     </xsl:if>
1927     <xsl:if test="@style and contains(@style, 'font-style:')">
1928       <xsl:variable name="font_style" select="normalize-space(substring-after(@style, 'font-style:'))" />
1929       <xsl:choose>
1930         <xsl:when test="contains($font_style, ';')">
1931           <xsl:value-of select="substring-before($font_style, ';')" />
1932         </xsl:when>
1933         <xsl:otherwise>
1934           <xsl:value-of select="$font_style" />
1935         </xsl:otherwise>
1936       </xsl:choose>
1937     </xsl:if>
1938   </xsl:variable>
1939   <xsl:if test="$value != ''">
1940     <xsl:attribute name="FontStyle">
1941       <xsl:value-of select="$value" />
1942     </xsl:attribute>
1943   </xsl:if>
1944 </xsl:template>
1946 <!-- 
1947   // Text baseline shift //
1948   SVG: baseline-shift, FXG: baselineShift
1949 -->
1950 <xsl:template mode="baseline_shift" match="*">
1951   <xsl:variable name="value">
1952     <xsl:if test="@baseline-shift">
1953       <xsl:value-of select="@baseline-shift" />
1954     </xsl:if>
1955     <xsl:if test="@style and contains(@style, 'baseline-shift:') and not(contains(substring-after(@style, 'baseline-shift:'), ';'))">
1956       <xsl:value-of select="substring-after(@style, 'baseline-shift:')" />
1957     </xsl:if>
1958     <xsl:if test="@style and contains(@style, 'baseline-shift:') and contains(substring-after(@style, 'baseline-shift:'), ';')">
1959       <xsl:value-of select="substring-before(substring-after(@style, 'baseline-shift:'), ';')" />
1960     </xsl:if>   
1961   </xsl:variable>
1962   <xsl:if test="$value != ''">
1963     <xsl:attribute name="baselineShift">  
1964       <xsl:choose>
1965         <xsl:when test="$value='baseline'">0</xsl:when>
1966         <xsl:when test="$value='super'">superscript</xsl:when>
1967         <xsl:when test="$value='sub'">subscript</xsl:when>
1968         <xsl:when test="translate($value, '%', '') &lt; -1000">-1000</xsl:when>
1969         <xsl:when test="translate($value, '%', '') &gt; 1000">1000</xsl:when>
1970         <xsl:otherwise>
1971           <xsl:value-of select="translate($value, '%', '')" />
1972         </xsl:otherwise>
1973       </xsl:choose>  
1974       <xsl:if test="contains($value, '%')">%</xsl:if>
1975     </xsl:attribute>
1976   </xsl:if>
1977 </xsl:template>
1979 <!-- 
1980   // Text line height //
1981   SVG: line-height, FXG: lineHeight
1982 -->
1983 <xsl:template mode="line_height" match="*">
1984   <xsl:variable name="value">
1985     <xsl:if test="@line-height">
1986       <xsl:value-of select="@line-height" />
1987     </xsl:if>
1988     <xsl:if test="@style and contains(@style, 'line-height:')">
1989       <xsl:variable name="line_height" select="normalize-space(substring-after(@style, 'line-height:'))" />
1990       <xsl:choose>
1991         <xsl:when test="contains($line_height, ';')">
1992           <xsl:value-of select="substring-before($line_height, ';')" />
1993         </xsl:when>
1994         <xsl:otherwise>
1995           <xsl:value-of select="$line_height" />
1996         </xsl:otherwise>
1997       </xsl:choose>
1998     </xsl:if>
1999   </xsl:variable>
2000   <xsl:if test="$value != ''">
2001     <xsl:attribute name="lineHeight">
2002       <xsl:call-template name="convert_unit">
2003         <xsl:with-param name="convert_value" select="$value" />
2004       </xsl:call-template>
2005     </xsl:attribute>
2006   </xsl:if>
2007 </xsl:template>
2009 <!-- 
2010   // Text writing mode //
2011   SVG: writing-mode, FXG: blockProgression 
2012   
2013   Values inverted in FXG...
2014 -->
2015 <xsl:template mode="writing_mode" match="*">
2016   <xsl:variable name="value">
2017     <xsl:if test="@writing-mode">
2018       <xsl:value-of select="@writing-mode" />
2019     </xsl:if>
2020     <xsl:if test="@style and contains(@style, 'writing-mode:') and not(contains(substring-after(@style, 'writing-mode:'), ';'))">
2021       <xsl:value-of select="substring-after(@style, 'writing-mode:')" />
2022     </xsl:if>
2023     <xsl:if test="@style and contains(@style, 'writing-mode:') and contains(substring-after(@style, 'writing-mode:'), ';')">
2024       <xsl:value-of select="substring-before(substring-after(@style, 'writing-mode:'), ';')" />
2025     </xsl:if>   
2026   </xsl:variable>
2027   <xsl:if test="$value != ''">
2028     <xsl:attribute name="blockProgression">  
2029       <xsl:choose>
2030         <xsl:when test="$value='tb'">rl</xsl:when>
2031         <xsl:otherwise>tb</xsl:otherwise>
2032       </xsl:choose>  
2033     </xsl:attribute>
2034     <xsl:if test="$value='tb'">
2035       <xsl:attribute name="textRotation">rotate270</xsl:attribute>
2036     </xsl:if>  
2037   </xsl:if>
2038 </xsl:template>
2039   
2040 <!-- 
2041   // Text decoration //
2042   SVG: text-decoration, FXG: textDecoration, lineThrough 
2043 -->
2044 <xsl:template mode="text_decoration" match="*">
2045   <xsl:variable name="value">
2046     <xsl:if test="@text-decoration">
2047       <xsl:value-of select="@text-decoration" />
2048     </xsl:if>
2049     <xsl:if test="@style and contains(@style, 'text-decoration:') and not(contains(substring-after(@style, 'text-decoration:'), ';'))">
2050       <xsl:value-of select="substring-after(@style, 'text-decoration:')" />
2051     </xsl:if>
2052     <xsl:if test="@style and contains(@style, 'text-decoration:') and contains(substring-after(@style, 'text-decoration:'), ';')">
2053       <xsl:value-of select="substring-before(substring-after(@style, 'text-decoration:'), ';')" />
2054     </xsl:if>   
2055   </xsl:variable>
2056   <xsl:if test="$value != ''">  
2057     <xsl:choose>
2058       <xsl:when test="$value='underline'">
2059         <xsl:attribute name="textDecoration">underline</xsl:attribute>
2060       </xsl:when>
2061       <xsl:when test="$value='line-through'">
2062         <xsl:attribute name="lineThrough">true</xsl:attribute>
2063       </xsl:when>
2064     </xsl:choose>  
2065   </xsl:if>
2066 </xsl:template>
2068 <!-- 
2069   // Text fill //
2070   SVG: fill, fill-opacity, XAML: Foreground
2071 -->
2072 <xsl:template mode="text_fill" match="*">
2073   <xsl:variable name="fill">
2074     <xsl:apply-templates mode="fill" select="." />
2075   </xsl:variable>
2076   <xsl:variable name="fill_opacity">
2077     <xsl:apply-templates mode="fill_opacity" select="." />
2078   </xsl:variable>
2079   <xsl:if test="starts-with($fill, '#') or (not(starts-with($fill, 'url')) and $fill != '' and $fill != 'none')">
2080     <xsl:attribute name="Foreground">
2081       <xsl:call-template name="template_color">
2082         <xsl:with-param name="colorspec">
2083           <xsl:value-of select="$fill" />
2084         </xsl:with-param>
2085         <xsl:with-param name="opacityspec">
2086           <xsl:choose>
2087           <xsl:when test="$fill_opacity">
2088             <xsl:value-of select="$fill_opacity" />
2089           </xsl:when>
2090           <xsl:otherwise>1</xsl:otherwise>
2091           </xsl:choose>
2092         </xsl:with-param>
2093       </xsl:call-template>
2094     </xsl:attribute>
2095   </xsl:if>
2096 </xsl:template>
2098 <!-- 
2099   // Text direction //
2100   SVG: direction, unicode-bidi, FXG: direction
2101 -->
2102 <xsl:template mode="direction" match="*">
2103   <xsl:variable name="value">
2104     <xsl:if test="@direction">
2105       <xsl:value-of select="@direction" />
2106     </xsl:if>
2107     <xsl:if test="@style and contains(@style, 'direction:') and not(contains(substring-after(@style, 'direction:'), ';'))">
2108       <xsl:value-of select="substring-after(@style, 'direction:')" />
2109     </xsl:if>
2110     <xsl:if test="@style and contains(@style, 'direction:') and contains(substring-after(@style, 'direction:'), ';')">
2111       <xsl:value-of select="substring-before(substring-after(@style, 'direction:'), ';')" />
2112     </xsl:if>   
2113   </xsl:variable>
2114   <xsl:variable name="bidi">
2115     <xsl:if test="@unicode-bidi">
2116       <xsl:value-of select="@unicode-bidi" />
2117     </xsl:if>
2118     <xsl:if test="@style and contains(@style, 'unicode-bidi:') and not(contains(substring-after(@style, 'unicode-bidi:'), ';'))">
2119       <xsl:value-of select="substring-after(@style, 'unicode-bidi:')" />
2120     </xsl:if>
2121     <xsl:if test="@style and contains(@style, 'unicode-bidi:') and contains(substring-after(@style, 'unicode-bidi:'), ';')">
2122       <xsl:value-of select="substring-before(substring-after(@style, 'unicode-bidi:'), ';')" />
2123     </xsl:if>   
2124   </xsl:variable>
2126   <xsl:if test="$value != '' and ($bidi='embed' or $bidi='bidi-override')">  
2127     <xsl:attribute name="direction">
2128       <xsl:choose>
2129         <xsl:when test="$value='ltr'">ltr</xsl:when>
2130         <xsl:when test="$value='rtl'">rtl</xsl:when>
2131       </xsl:choose>  
2132     </xsl:attribute>
2133   </xsl:if>
2134 </xsl:template>
2136  <!-- 
2137   // Text size //
2138 -->
2139 <xsl:template mode="text_size" match="*">
2140   <xsl:if test="@width">
2141     <xsl:attribute name="Width">
2142       <xsl:call-template name="convert_unit">
2143         <xsl:with-param name="convert_value" select="@width" />
2144       </xsl:call-template>
2145     </xsl:attribute>
2146   </xsl:if>
2147   <xsl:if test="@height">
2148     <xsl:attribute name="Height">
2149       <xsl:call-template name="convert_unit">
2150         <xsl:with-param name="convert_value" select="@height" />
2151       </xsl:call-template>
2152     </xsl:attribute>
2153   </xsl:if>
2154 </xsl:template>
2156  <!-- 
2157   // Text position //
2158 -->
2159 <xsl:template mode="text_position" match="*">
2160   <!-- Keep the first x value only -->
2161   <xsl:if test="@x">
2162     <xsl:attribute name="Canvas.Left">
2163       <xsl:choose>
2164         <xsl:when test="contains(@x, ' ')">
2165           <xsl:call-template name="convert_unit">
2166             <xsl:with-param name="convert_value" select="substring-before(@x, ' ')" />
2167           </xsl:call-template>   
2168           </xsl:when>
2169           <xsl:otherwise>
2170           <xsl:call-template name="convert_unit">
2171             <xsl:with-param name="convert_value" select="@x" />
2172           </xsl:call-template>  
2173         </xsl:otherwise>
2174       </xsl:choose>
2175     </xsl:attribute>
2176   </xsl:if>
2177   <!-- Keep the first y value only -->
2178   <xsl:if test="@y">
2179     <xsl:attribute name="Canvas.Top">
2180       <xsl:variable name="top_val">
2181         <xsl:choose>
2182           <xsl:when test="contains(@y, ' ')">
2183             <xsl:call-template name="convert_unit">
2184               <xsl:with-param name="convert_value" select="substring-before(@y, ' ')" />
2185             </xsl:call-template>   
2186             </xsl:when>
2187             <xsl:otherwise>
2188             <xsl:call-template name="convert_unit">
2189               <xsl:with-param name="convert_value" select="@y" />
2190             </xsl:call-template>  
2191           </xsl:otherwise>
2192         </xsl:choose>
2193       </xsl:variable>
2194       <xsl:variable name="size_val">
2195         <xsl:variable name="value">
2196           <xsl:apply-templates mode="get_font_size" select="." />
2197         </xsl:variable>
2198         <xsl:choose>
2199           <xsl:when test="$value != ''">
2200             <xsl:call-template name="convert_unit">
2201               <xsl:with-param name="convert_value" select="$value" />
2202             </xsl:call-template>
2203           </xsl:when>
2204           <xsl:otherwise>12</xsl:otherwise>
2205         </xsl:choose>
2206       </xsl:variable>
2207       <xsl:if test="$top_val != '' and $size_val != ''">
2208         <xsl:value-of select="$top_val - $size_val" />
2209       </xsl:if>
2210     </xsl:attribute>
2211   </xsl:if>
2212 </xsl:template>
2214 <!-- 
2215   // Objects //
2217   * Text
2218   * Lines
2219   * Rectangle
2220   * Polygon
2221   * Polyline
2222   * Path
2223   * Ellipse
2224   * Circle
2225   * Image
2226 -->
2228 <!-- 
2229   // Text objects //
2230   SVG: text, XAML: TextBlock
2231 -->
2232 <xsl:template mode="forward" match="*[name(.) = 'text']">
2233   <TextBlock>
2234     <xsl:apply-templates mode="font_size" select="." />
2235     <xsl:apply-templates mode="font_weight" select="." />
2236     <xsl:apply-templates mode="font_family" select="." />
2237     <xsl:apply-templates mode="font_style" select="." />
2238     <xsl:apply-templates mode="text_fill" select="." />
2239     <xsl:apply-templates mode="text_size" select="." />
2240     <xsl:apply-templates mode="text_position" select="." />
2241     
2242     <xsl:if test="@text-anchor">
2243       <xsl:attribute name="HorizontalAlignment">
2244         <xsl:choose>
2245           <xsl:when test="@text-anchor = 'start'">Left</xsl:when>
2246           <xsl:when test="@text-anchor = 'middle'">Center</xsl:when>
2247           <xsl:when test="@text-anchor = 'end'">Right</xsl:when>
2248         </xsl:choose>
2249       </xsl:attribute>
2250     </xsl:if>
2251     
2252     <xsl:apply-templates mode="id" select="." />
2253     <xsl:apply-templates mode="filter_effect" select="." />
2254     <xsl:apply-templates mode="desc" select="." />
2255     <xsl:apply-templates mode="clip" select="." />
2256     <!--xsl:apply-templates mode="transform" select="." /-->
2257     <!--xsl:apply-templates mode="forward" /-->
2258     
2259     <xsl:choose>
2260       <xsl:when test="*[name(.) = 'tspan']/text()">
2261         <xsl:apply-templates mode="forward" />
2262       </xsl:when>
2263       <xsl:otherwise>
2264         <xsl:choose>
2265           <xsl:when test="@xml:space='preserve'">
2266             <xsl:copy-of select="translate(text(), '&#x9;&#xA;&#xD;', ' ')" />
2267           </xsl:when>
2268           <xsl:otherwise>
2269             <xsl:copy-of select="normalize-space(translate(text(), '&#x9;&#xA;&#xD;', ' '))" />
2270           </xsl:otherwise>
2271         </xsl:choose>  
2272       </xsl:otherwise>
2273     </xsl:choose>
2274     
2275   </TextBlock>
2276 </xsl:template>
2277  
2278 <!-- 
2279   // Line object //
2280   SVG: line, XAML: Line
2281 -->
2282 <xsl:template mode="forward" match="*[name(.) = 'line']">
2283   <Line>
2284     <xsl:if test="@x1">
2285       <xsl:attribute name="X1">
2286         <xsl:value-of select="@x1" />
2287       </xsl:attribute>
2288     </xsl:if> 
2289     <xsl:if test="@y1">
2290       <xsl:attribute name="Y1">
2291         <xsl:value-of select="@y1" />
2292       </xsl:attribute>
2293     </xsl:if> 
2294     <xsl:if test="@x2">
2295       <xsl:attribute name="X2">
2296         <xsl:value-of select="@x2" />
2297       </xsl:attribute>
2298     </xsl:if> 
2299     <xsl:if test="@y2">
2300       <xsl:attribute name="Y2">
2301         <xsl:value-of select="@y2" />
2302       </xsl:attribute>
2303     </xsl:if>
2304     <xsl:apply-templates mode="id" select="." />
2305     <xsl:apply-templates mode="template_fill" select="." />
2306     <xsl:apply-templates mode="template_stroke" select="." />
2307     <xsl:apply-templates mode="stroke_miterlimit" select="." />
2308     <xsl:apply-templates mode="stroke_dasharray" select="." />
2309     <xsl:apply-templates mode="stroke_dashoffset" select="." />
2310     <xsl:apply-templates mode="stroke_linejoin" select="." />
2311     <xsl:apply-templates mode="stroke_linecap" select="." />
2312     <xsl:apply-templates mode="filter_effect" select="." />
2313     <xsl:apply-templates mode="desc" select="." />
2315     <xsl:apply-templates mode="transform" select=".">
2316       <xsl:with-param name="mapped_type" select="'Line'" />
2317     </xsl:apply-templates>    
2319     <xsl:apply-templates mode="forward" />
2320   </Line>
2321 </xsl:template>
2323 <!-- 
2324   // Rectangle object //
2325   SVG: rect, XAML: Rectangle
2326 -->
2327 <xsl:template mode="forward" match="*[name(.) = 'rect']">
2328   <Rectangle>
2329     <xsl:if test="@x">
2330       <xsl:attribute name="Canvas.Left">
2331         <xsl:call-template name="convert_unit">
2332           <xsl:with-param name="convert_value" select="@x" />
2333         </xsl:call-template>
2334       </xsl:attribute>
2335     </xsl:if>
2336     <xsl:if test="@y">
2337       <xsl:attribute name="Canvas.Top">
2338         <xsl:call-template name="convert_unit">
2339           <xsl:with-param name="convert_value" select="@y" />
2340         </xsl:call-template>
2341       </xsl:attribute>
2342     </xsl:if>
2343     <xsl:if test="@width">
2344       <xsl:attribute name="Width">
2345         <xsl:call-template name="convert_unit">
2346           <xsl:with-param name="convert_value" select="@width" />
2347         </xsl:call-template>
2348       </xsl:attribute>
2349     </xsl:if>
2350     <xsl:if test="@height">
2351       <xsl:attribute name="Height">
2352         <xsl:call-template name="convert_unit">
2353           <xsl:with-param name="convert_value" select="@height" />
2354         </xsl:call-template>
2355       </xsl:attribute>
2356     </xsl:if>
2357     <xsl:if test="@rx">
2358       <xsl:attribute name="RadiusX">
2359         <xsl:value-of select="@rx" />
2360       </xsl:attribute>
2361     </xsl:if>
2362     <xsl:if test="@ry">
2363       <xsl:attribute name="RadiusY">
2364         <xsl:value-of select="@ry" />
2365       </xsl:attribute>
2366     </xsl:if>
2367     <xsl:if test="@rx and not(@ry)">
2368       <xsl:attribute name="RadiusX">
2369         <xsl:value-of select="@rx" />
2370       </xsl:attribute>
2371       <xsl:attribute name="RadiusY">
2372         <xsl:value-of select="@rx" />
2373       </xsl:attribute>
2374     </xsl:if>
2375     <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>
2377     <xsl:apply-templates mode="id" select="." />
2378     <xsl:apply-templates mode="template_fill" select="." />
2379     <xsl:apply-templates mode="template_stroke" select="." />
2380     <xsl:apply-templates mode="stroke_miterlimit" select="." />
2381     <xsl:apply-templates mode="stroke_dasharray" select="." />
2382     <xsl:apply-templates mode="stroke_dashoffset" select="." />
2383     <xsl:apply-templates mode="stroke_linejoin" select="." />
2384     <xsl:apply-templates mode="stroke_linecap" select="." />
2385     <xsl:apply-templates mode="filter_effect" select="." />
2386     <xsl:apply-templates mode="resources" select="." />
2387     <xsl:apply-templates mode="desc" select="." />
2388     <xsl:apply-templates mode="clip" select="." />
2390     <xsl:apply-templates mode="transform" select=".">
2391       <xsl:with-param name="mapped_type" select="'Rectangle'" />
2392     </xsl:apply-templates>
2394     <xsl:apply-templates mode="forward" />
2395   </Rectangle>
2396 </xsl:template>
2398 <!-- 
2399   // Polygon object //
2400   SVG: polygon, XAML: Polygon
2401 -->
2402 <xsl:template mode="forward" match="*[name(.) = 'polygon']">
2403   <Polygon>
2404     <xsl:if test="@points"><xsl:attribute name="Points"><xsl:value-of select="@points" /></xsl:attribute></xsl:if>
2405     <xsl:apply-templates mode="id" select="." />
2406     <xsl:apply-templates mode="fill_rule" select="." />
2407     <xsl:apply-templates mode="template_fill" select="." />
2408     <xsl:apply-templates mode="template_stroke" select="." />
2409     <xsl:apply-templates mode="stroke_miterlimit" select="." />
2410     <xsl:apply-templates mode="stroke_dasharray" select="." />
2411     <xsl:apply-templates mode="stroke_dashoffset" select="." />
2412     <xsl:apply-templates mode="stroke_linejoin" select="." />
2413     <xsl:apply-templates mode="stroke_linecap" select="." />
2414     <xsl:apply-templates mode="filter_effect" select="." />
2415     <xsl:apply-templates mode="desc" select="." />
2417     <xsl:apply-templates mode="transform" select=".">
2418       <xsl:with-param name="mapped_type" select="'Polygon'" />
2419     </xsl:apply-templates>
2421     <xsl:apply-templates mode="forward" />
2422   </Polygon>
2423 </xsl:template>
2425 <!-- 
2426   // Polyline object //
2427   SVG: polyline, XAML: Polyline
2428 -->
2429 <xsl:template mode="forward" match="*[name(.) = 'polyline']">
2430   <Polyline>
2431     <xsl:if test="@points"><xsl:attribute name="Points"><xsl:value-of select="@points" /></xsl:attribute></xsl:if>
2432     <xsl:apply-templates mode="id" select="." />
2433     <xsl:apply-templates mode="fill_rule" select="." />
2434     <xsl:apply-templates mode="template_fill" select="." />
2435     <xsl:apply-templates mode="template_stroke" select="." />
2436     <xsl:apply-templates mode="stroke_miterlimit" select="." />
2437     <xsl:apply-templates mode="stroke_dasharray" select="." />
2438     <xsl:apply-templates mode="stroke_dashoffset" select="." />
2439     <xsl:apply-templates mode="stroke_linejoin" select="." />
2440     <xsl:apply-templates mode="stroke_linecap" select="." />
2441     <xsl:apply-templates mode="filter_effect" select="." />
2442     <xsl:apply-templates mode="desc" select="." />
2444     <xsl:apply-templates mode="transform" select=".">
2445       <xsl:with-param name="mapped_type" select="'Polyline'" />
2446     </xsl:apply-templates>
2448     <xsl:apply-templates mode="forward" />
2449   </Polyline>
2450 </xsl:template>
2452 <!-- 
2453   // Path //
2454   SVG: path, XAML: Path
2455 -->
2456 <xsl:template mode="forward" match="*[name(.) = 'path']">
2457   <Path>
2458     <xsl:apply-templates mode="id" select="." />
2459     <xsl:apply-templates mode="template_fill" select="." />
2460     <xsl:apply-templates mode="template_stroke" select="." />
2461     <xsl:apply-templates mode="stroke_miterlimit" select="." />
2462     <xsl:apply-templates mode="stroke_dasharray" select="." />
2463     <xsl:apply-templates mode="stroke_dashoffset" select="." />
2464     <xsl:apply-templates mode="stroke_linejoin" select="." />
2465     <xsl:apply-templates mode="stroke_linecap" select="." />
2466     <xsl:apply-templates mode="filter_effect" select="." />
2467     <xsl:apply-templates mode="desc" select="." />
2469     <xsl:if test="@d">
2470       <xsl:choose>
2471         <xsl:when test="$silverlight_compatible = 1">
2472           <xsl:attribute name="Data">
2473             <xsl:value-of select="translate(@d , ',', ' ')" />
2474           </xsl:attribute>
2475         </xsl:when>
2476         <xsl:otherwise>
2477           <Path.Data>
2478             <PathGeometry>
2479               <xsl:attribute name="Figures">
2480                 <xsl:value-of select="translate(@d , ',', ' ')" />
2481               </xsl:attribute>
2482               <xsl:apply-templates mode="fill_rule" select="." />
2483             </PathGeometry>
2484           </Path.Data>
2485          </xsl:otherwise>
2486       </xsl:choose>
2487     </xsl:if>
2489     <xsl:apply-templates mode="transform" select=".">
2490       <xsl:with-param name="mapped_type" select="'Path'" />
2491     </xsl:apply-templates>
2493     <xsl:apply-templates mode="forward" />
2494   </Path>
2495 </xsl:template>
2497 <!-- 
2498   // Ellipse object //
2499   SVG: ellipse, XAML: Ellipse
2500 -->
2501 <xsl:template mode="forward" match="*[name(.) = 'ellipse']">
2502   <Ellipse>
2503     <xsl:variable name="cx">
2504       <xsl:choose>
2505         <xsl:when test="@cx"><xsl:value-of select="@cx" /></xsl:when>
2506         <xsl:otherwise>0</xsl:otherwise>
2507       </xsl:choose>
2508     </xsl:variable>
2509     <xsl:variable name="cy">
2510       <xsl:choose>
2511         <xsl:when test="@cy"><xsl:value-of select="@cy" /></xsl:when>
2512         <xsl:otherwise>0</xsl:otherwise>
2513       </xsl:choose>
2514     </xsl:variable>
2515     <xsl:if test="@rx">
2516       <xsl:attribute name="Canvas.Left"><xsl:value-of select='format-number($cx - @rx, "#.#")' /></xsl:attribute>
2517       <xsl:attribute name="Width"><xsl:value-of select='format-number(2 * @rx, "#.#")' /></xsl:attribute>
2518     </xsl:if>
2519     <xsl:if test="@ry">
2520       <xsl:attribute name="Canvas.Top"><xsl:value-of select='format-number($cy - @ry, "#.#")' /></xsl:attribute>
2521       <xsl:attribute name="Height"><xsl:value-of select='format-number(2 * @ry, "#.#")' /></xsl:attribute>
2522     </xsl:if>
2523     <xsl:apply-templates mode="id" select="." />
2524     <xsl:apply-templates mode="template_fill" select="." />
2525     <xsl:apply-templates mode="template_stroke" select="." />
2526     <xsl:apply-templates mode="stroke_miterlimit" select="." />
2527     <xsl:apply-templates mode="stroke_dasharray" select="." />
2528     <xsl:apply-templates mode="stroke_dashoffset" select="." />
2529     <xsl:apply-templates mode="stroke_linejoin" select="." />
2530     <xsl:apply-templates mode="stroke_linecap" select="." />
2531     <xsl:apply-templates mode="filter_effect" select="." />
2532     <xsl:apply-templates mode="desc" select="." />
2533     <xsl:apply-templates mode="clip" select="." />
2535     <xsl:apply-templates mode="transform" select=".">
2536       <xsl:with-param name="mapped_type" select="'Ellipse'" />
2537     </xsl:apply-templates>
2539     <xsl:apply-templates mode="forward" />
2540   </Ellipse>
2541 </xsl:template>
2543 <!-- 
2544   // Circle object //
2545   SVG: circle, XAML: Ellipse
2546 -->
2547 <xsl:template mode="forward" match="*[name(.) = 'circle']">
2548   <Ellipse>
2549     <xsl:variable name="cx">
2550       <xsl:choose>
2551         <xsl:when test="@cx"><xsl:value-of select="@cx" /></xsl:when>
2552         <xsl:otherwise>0</xsl:otherwise>
2553       </xsl:choose>
2554     </xsl:variable>
2555     <xsl:variable name="cy">
2556       <xsl:choose>
2557         <xsl:when test="@cy"><xsl:value-of select="@cy" /></xsl:when>
2558         <xsl:otherwise>0</xsl:otherwise>
2559       </xsl:choose>
2560     </xsl:variable>
2561     <xsl:if test="@r">
2562        <xsl:attribute name="Canvas.Left"><xsl:value-of select='format-number($cx - @r, "#.#")' /></xsl:attribute>
2563        <xsl:attribute name="Canvas.Top"><xsl:value-of select='format-number($cy - @r, "#.#")' /></xsl:attribute>
2564        <xsl:attribute name="Width"><xsl:value-of select='format-number(2 * @r, "#.#")' /></xsl:attribute>
2565        <xsl:attribute name="Height"><xsl:value-of select='format-number(2 * @r, "#.#")' /></xsl:attribute>
2566     </xsl:if>
2567     <xsl:apply-templates mode="id" select="." />
2568     <xsl:apply-templates mode="template_fill" select="." />
2569     <xsl:apply-templates mode="template_stroke" select="." />
2570     <xsl:apply-templates mode="stroke_miterlimit" select="." />
2571     <xsl:apply-templates mode="stroke_dasharray" select="." />
2572     <xsl:apply-templates mode="stroke_dashoffset" select="." />
2573     <xsl:apply-templates mode="stroke_linejoin" select="." />
2574     <xsl:apply-templates mode="stroke_linecap" select="." />
2575     <xsl:apply-templates mode="filter_effect" select="." />
2576     <xsl:apply-templates mode="desc" select="." />
2577     <xsl:apply-templates mode="clip" select="." />
2579     <xsl:apply-templates mode="transform" select=".">
2580       <xsl:with-param name="mapped_type" select="'Ellipse'" />
2581     </xsl:apply-templates>
2583     <xsl:apply-templates mode="forward" />
2584   </Ellipse>
2585 </xsl:template>
2587 <!-- 
2588   // Image object//
2589   SVG: image, FXG: Image
2590 -->
2591 <xsl:template mode="forward" match="*[name(.) = 'image']">
2592   <Image>
2593     <xsl:apply-templates mode="id" select="." />
2594     <xsl:if test="@x">
2595       <xsl:attribute name="Canvas.Left">
2596         <xsl:call-template name="convert_unit">
2597           <xsl:with-param name="convert_value" select="@x" />
2598         </xsl:call-template>
2599       </xsl:attribute>
2600     </xsl:if>
2601     <xsl:if test="@y">
2602       <xsl:attribute name="Canvas.Top">
2603         <xsl:call-template name="convert_unit">
2604           <xsl:with-param name="convert_value" select="@y" />
2605         </xsl:call-template>
2606       </xsl:attribute>
2607     </xsl:if>
2608     <xsl:apply-templates mode="desc" select="." />
2609     <xsl:apply-templates mode="clip" select="." />
2610     <xsl:if test="@xlink:href">
2611       <xsl:attribute name="Source">
2612         <xsl:value-of select="@xlink:href" />
2613       </xsl:attribute>
2614     </xsl:if>
2615     <xsl:if test="@width">
2616       <xsl:attribute name="Width">
2617         <xsl:call-template name="convert_unit">
2618           <xsl:with-param name="convert_value" select="@width" />
2619         </xsl:call-template>
2620       </xsl:attribute>
2621     </xsl:if>
2622     <xsl:if test="@height">
2623       <xsl:attribute name="Height">
2624         <xsl:call-template name="convert_unit">
2625           <xsl:with-param name="convert_value" select="@height" />
2626         </xsl:call-template>
2627       </xsl:attribute>
2628     </xsl:if>
2629     
2630     <xsl:apply-templates mode="image_stretch" select="." />
2631     <xsl:apply-templates mode="transform" select=".">
2632       <xsl:with-param name="mapped_type" select="'Image'" />
2633     </xsl:apply-templates>
2634     <xsl:apply-templates mode="forward" />
2635   </Image>
2636 </xsl:template>
2638 <!--
2639 // Geometry //
2640 * Generic clip path template
2641 * Geometry for circle
2642 * Geometry for rectangle
2643 -->
2645 <!-- Generic clip path template -->
2646 <xsl:template mode="forward" match="*[name(.) = 'clipPath']">
2647   <xsl:apply-templates mode="geometry" />
2648 </xsl:template>
2650 <!-- Geometry for circle -->
2651 <xsl:template mode="geometry" match="*[name(.) = 'circle']">
2652   <EllipseGeometry>
2653     <xsl:if test="../@id"><xsl:attribute name="x:Key"><xsl:value-of select="../@id" /></xsl:attribute></xsl:if>
2654     <xsl:if test="@cx and @cy"><xsl:attribute name="Center"><xsl:value-of select="concat(@cx, ',', @cy)" /></xsl:attribute></xsl:if>
2655     <xsl:if test="@r">
2656       <xsl:attribute name="RadiusX"><xsl:value-of select="@r" /></xsl:attribute>
2657       <xsl:attribute name="RadiusY"><xsl:value-of select="@r" /></xsl:attribute>
2658     </xsl:if>
2659   </EllipseGeometry>
2660 </xsl:template>
2662 <!-- Geometry for rectangle -->
2663 <xsl:template mode="geometry" match="*[name(.) = 'rect']">
2664   <RectangleGeometry>
2665     <xsl:if test="../@id"><xsl:attribute name="x:Key"><xsl:value-of select="../@id" /></xsl:attribute></xsl:if>
2666     <!--
2667     <xsl:if test="@x"><xsl:attribute name="Canvas.Left"><xsl:value-of select="@x" /></xsl:attribute></xsl:if>
2668     <xsl:if test="@y"><xsl:attribute name="Canvas.Top"><xsl:value-of select="@y" /></xsl:attribute></xsl:if>
2669     <xsl:if test="@width"><xsl:attribute name="Width"><xsl:value-of select="@width" /></xsl:attribute></xsl:if>
2670     <xsl:if test="@height"><xsl:attribute name="Height"><xsl:value-of select="@height" /></xsl:attribute></xsl:if>
2671     <xsl:if test="@rx"><xsl:attribute name="RadiusX"><xsl:value-of select="@rx" /></xsl:attribute></xsl:if>
2672     <xsl:if test="@ry"><xsl:attribute name="RadiusY"><xsl:value-of select="@ry" /></xsl:attribute></xsl:if>
2673     -->
2674     <xsl:attribute name="Rect"><xsl:value-of select="concat('0, 0, ', @width, ', ', @height)" /></xsl:attribute>
2675   </RectangleGeometry>
2676 </xsl:template>
2678 </xsl:stylesheet>