Code

Extensions. XAML export improvements (flowRoot, text decoration, baseline alignement...
[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="2" />
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     <StaticResource>
820       <xsl:if test="@xlink:href">
821         <xsl:attribute name="ResourceKey">
822           <xsl:value-of select="substring-after(@xlink:href, '#')" />
823         </xsl:attribute>
824       </xsl:if>
825       <!--xsl:apply-templates mode="transform" select="." /-->
826       <xsl:apply-templates mode="forward" />
827     </StaticResource>
828   </Canvas>
829 </xsl:template>
831 <!--
832   // RDF and foreign objects //
833 -->
834 <xsl:template mode="forward" match="rdf:RDF | *[name(.) = 'foreignObject']">
836 </xsl:template>
838 <!--
839   // Misc ignored stuff (markers, patterns, styles) //
840 -->
841 <xsl:template mode="forward" match="*[name(.) = 'marker' or name(.) = 'pattern' or name(.) = 'style']">
843 </xsl:template>
845 <!-- 
846   // Unknown tags //
847   With generic and mode="forward" templates
848 -->
849 <xsl:template match="*">
850   <xsl:comment>
851     <xsl:value-of select="concat('Unknown tag: ', name(.))" />
852   </xsl:comment>
853 </xsl:template>
855 <xsl:template mode="forward" match="*">
856   <xsl:comment>
857     <xsl:value-of select="concat('Unknown tag: ', name(.))" />
858   </xsl:comment>
859 </xsl:template>
861 <!--
862 // Colors and patterns //
864 * Generic color template
865 * Object opacity
866 * Fill
867 * Fill opacity
868 * Fill rule
869 * Generic fill template
870 * Stroke
871 * Stroke opacity
872 * Generic stroke template
873 * Stroke width
874 * Stroke mitterlimit
875 * Stroke dasharray
876 * Stroke dashoffset
877 * Linejoin SVG to XAML converter
878 * Stroke linejoin
879 * Linecap SVG to XAML converter
880 * Stroke linecap
881 * Gradient stop
882 * Gradient stop opacity
883 * Gradient stop offset
884 * Image stretch
885 -->
887 <!--
888   // Generic color template //
889 -->
890 <xsl:template name="template_color">
891   <xsl:param name="colorspec" />
892   <xsl:param name="opacityspec" />
893   <xsl:choose>
894     <xsl:when test="starts-with($colorspec, 'rgb(') and not(contains($colorspec , '%'))">
895       <xsl:value-of select="'#'" />
896       <xsl:if test="$opacityspec != '' and number($opacityspec) != 1">
897         <xsl:call-template name="to_hex">
898           <xsl:with-param name="convert">
899             <xsl:value-of select="round(number($opacityspec) * 255)" />
900           </xsl:with-param>
901         </xsl:call-template>
902       </xsl:if>
903       <xsl:call-template name="to_hex">
904         <xsl:with-param name="convert">
905           <xsl:value-of select="substring-before(substring-after($colorspec, 'rgb('), ',')" />
906         </xsl:with-param>
907       </xsl:call-template>
908       <xsl:call-template name="to_hex">
909         <xsl:with-param name="convert">
910           <xsl:value-of select="substring-before(substring-after(substring-after($colorspec, 'rgb('), ','), ',')" />
911         </xsl:with-param>
912       </xsl:call-template>
913       <xsl:call-template name="to_hex">
914         <xsl:with-param name="convert">
915           <xsl:value-of select="substring-before(substring-after(substring-after(substring-after($colorspec, 'rgb('), ','), ','), ')')" />
916         </xsl:with-param>
917       </xsl:call-template>
918     </xsl:when>
919     <xsl:when test="starts-with($colorspec, 'rgb(') and contains($colorspec , '%')">
920       <xsl:value-of select="'#'" />
921       <xsl:if test="$opacityspec != '' and number($opacityspec) != 1">
922         <xsl:call-template name="to_hex">
923           <xsl:with-param name="convert">
924             <xsl:value-of select="round(number($opacityspec) * 255)" />
925           </xsl:with-param>
926         </xsl:call-template>
927       </xsl:if>
928       <xsl:call-template name="to_hex">
929         <xsl:with-param name="convert">
930           <xsl:value-of select="number(substring-before(substring-after($colorspec, 'rgb('), '%,')) * 255 div 100" />
931         </xsl:with-param>
932       </xsl:call-template>
933       <xsl:call-template name="to_hex">
934         <xsl:with-param name="convert">
935           <xsl:value-of select="number(substring-before(substring-after(substring-after($colorspec, 'rgb('), ','), '%,')) * 255 div 100" />
936         </xsl:with-param>
937       </xsl:call-template>
938       <xsl:call-template name="to_hex">
939         <xsl:with-param name="convert">
940           <xsl:value-of select="number(substring-before(substring-after(substring-after(substring-after($colorspec, 'rgb('), ','), ','), '%)')) * 255 div 100" />
941         </xsl:with-param>
942       </xsl:call-template>
943     </xsl:when>
944     <xsl:when test="starts-with($colorspec, '#')">
945       <xsl:value-of select="'#'" />
946       <xsl:if test="$opacityspec != ''">
947         <xsl:call-template name="to_hex">
948           <xsl:with-param name="convert">
949             <xsl:value-of select="round(number($opacityspec) * 255)" />
950           </xsl:with-param>
951         </xsl:call-template>
952       </xsl:if>
953       <xsl:choose>
954         <xsl:when test="string-length(substring-after($colorspec, '#')) = 3">
955           <xsl:variable name="colorspec3">
956             <xsl:value-of select="translate(substring-after($colorspec, '#'), 'abcdefgh', 'ABCDEFGH')" />
957           </xsl:variable>
958           <xsl:value-of select="concat(substring($colorspec3, 1, 1), substring($colorspec3, 1, 1))" />
959           <xsl:value-of select="concat(substring($colorspec3, 2, 1), substring($colorspec3, 2, 1))" />
960           <xsl:value-of select="concat(substring($colorspec3, 3, 1), substring($colorspec3, 3, 1))" />
961         </xsl:when>
962         <xsl:otherwise>
963           <xsl:value-of select="translate(substring-after($colorspec, '#'), 'abcdefgh', 'ABCDEFGH')" />
964         </xsl:otherwise>
965       </xsl:choose>
966     </xsl:when>
967     <xsl:otherwise>
968       <xsl:variable name="named_color_hex" select="document('colors.xml')/colors/color[@name = translate($colorspec, 'ABCDEFGHIJKLMNOPQRSTUVWXYZ', 'abcdefghijklmnopqrstuvwxyz')]/@hex" />
969       <xsl:choose>
970         <xsl:when test="$named_color_hex and $named_color_hex != ''">
971           <xsl:value-of select="'#'" />
972           <xsl:if test="$opacityspec != '' and number($opacityspec) != 1">
973             <xsl:call-template name="to_hex">
974               <xsl:with-param name="convert">
975                 <xsl:value-of select="number($opacityspec) * 255" />
976               </xsl:with-param>
977             </xsl:call-template>
978           </xsl:if>
979           <xsl:value-of select="substring-after($named_color_hex, '#')" />
980         </xsl:when>
981         <xsl:otherwise>
982           <xsl:value-of select="$colorspec" />
983         </xsl:otherwise>
984       </xsl:choose>
985     </xsl:otherwise>
986   </xsl:choose>
987 </xsl:template>
989 <!--
990   // Object opacity //
991 -->
992 <xsl:template mode="object_opacity" match="*">
993   <xsl:if test="@opacity or (@style and (contains(@style, ';opacity:') or starts-with(@style, 'opacity:')))">
994     <xsl:variable name="value">
995     <xsl:choose>
996       <xsl:when test="@opacity">
997         <xsl:value-of select="@opacity" />
998       </xsl:when>
999       <xsl:when test="@style and contains(@style, ';opacity:')">
1000         <xsl:variable name="Opacity" select="substring-after(@style, ';opacity:')" />
1001         <xsl:choose>
1002           <xsl:when test="contains($Opacity, ';')">
1003             <xsl:value-of select="substring-before($Opacity, ';')" />
1004           </xsl:when>
1005           <xsl:otherwise>
1006             <xsl:value-of select="$Opacity" />
1007           </xsl:otherwise>
1008         </xsl:choose>
1009       </xsl:when>
1010       <xsl:when test="@style and starts-with(@style, 'opacity:')">
1011         <xsl:variable name="Opacity" select="substring-after(@style, 'opacity:')" />
1012         <xsl:choose>
1013           <xsl:when test="contains($Opacity, ';')">
1014             <xsl:value-of select="substring-before($Opacity, ';')" />
1015           </xsl:when>
1016           <xsl:otherwise>
1017             <xsl:value-of select="$Opacity" />
1018           </xsl:otherwise>
1019         </xsl:choose>
1020       </xsl:when>
1021       <xsl:when test="name(..) = 'g' or name(..) = 'svg'">
1022         <xsl:apply-templates mode="object_opacity" select="parent::*" />
1023       </xsl:when>
1024       <xsl:otherwise>1</xsl:otherwise>
1025     </xsl:choose>
1026     </xsl:variable>
1027     <xsl:attribute name="Opacity">
1028     <xsl:choose>
1029       <xsl:when test="$value &lt; 0">0</xsl:when>
1030       <xsl:when test="$value &gt; 1">1</xsl:when>
1031       <xsl:otherwise>
1032         <xsl:value-of select="$value" />
1033       </xsl:otherwise>
1034     </xsl:choose>
1035     </xsl:attribute>
1036   </xsl:if>
1037 </xsl:template>
1039 <!--
1040   // Fill //
1041 -->
1042 <xsl:template mode="fill" match="*">
1043   <xsl:variable name="value">
1044     <xsl:choose>
1045       <xsl:when test="@fill and starts-with(@fill, 'url(#')">
1046         <xsl:value-of select="concat('{StaticResource ', substring-before(substring-after(@fill, 'url(#'), ')'), '}')" />
1047       </xsl:when>
1048       <xsl:when test="@fill">
1049         <xsl:value-of select="@fill" />
1050       </xsl:when>
1051       <xsl:when test="@style and contains(@style, 'fill:') and starts-with(substring-after(@style, 'fill:'), 'url(#')">
1052         <xsl:value-of select="concat('{StaticResource ', substring-before(substring-after(@style, 'url(#'), ')'), '}')" />
1053       </xsl:when>
1054       <xsl:when test="@style and contains(@style, 'fill:')">
1055         <xsl:variable name="Fill" select="substring-after(@style, 'fill:')" />
1056         <xsl:choose>
1057           <xsl:when test="contains($Fill, ';')">
1058             <xsl:value-of select="substring-before($Fill, ';')" />
1059           </xsl:when>
1060           <xsl:otherwise>
1061             <xsl:value-of select="$Fill" />
1062           </xsl:otherwise>
1063         </xsl:choose>
1064       </xsl:when>
1065       <xsl:when test="name(..) = 'g' or name(..) = 'svg'">
1066         <xsl:apply-templates mode="fill" select="parent::*"/>
1067       </xsl:when>
1068     </xsl:choose>
1069   </xsl:variable>
1070   <xsl:if test="$value">
1071     <!-- Removes unwanted characters in the color link (TODO: export to a specific template)-->
1072     <xsl:value-of select="normalize-space(translate($value, '&quot;', ''))" />
1073   </xsl:if>
1074 </xsl:template>
1076 <!--
1077   // Fill opacity //
1078 -->
1079 <xsl:template mode="fill_opacity" match="*">
1080   <xsl:variable name="value">
1081   <xsl:choose>
1082     <xsl:when test="@fill-opacity">
1083       <xsl:value-of select="@fill-opacity" />
1084     </xsl:when>
1085     <xsl:when test="@style and contains(@style, 'fill-opacity:')">
1086       <xsl:variable name="Opacity" select="substring-after(@style, 'fill-opacity:')" />
1087       <xsl:choose>
1088         <xsl:when test="contains($Opacity, ';')">
1089           <xsl:value-of select="substring-before($Opacity, ';')" />
1090         </xsl:when>
1091         <xsl:otherwise>
1092           <xsl:value-of select="$Opacity" />
1093         </xsl:otherwise>
1094       </xsl:choose>
1095     </xsl:when>
1096     <xsl:when test="name(..) = 'g' or name(..) = 'svg'">
1097       <xsl:apply-templates mode="fill_opacity" select="parent::*" />
1098     </xsl:when>
1099     <xsl:otherwise>1</xsl:otherwise>
1100   </xsl:choose>
1101   </xsl:variable>
1102   <xsl:choose>
1103     <xsl:when test="$value &lt; 0">0</xsl:when>
1104     <xsl:when test="$value &gt; 1">1</xsl:when>
1105     <xsl:otherwise>
1106       <xsl:value-of select="$value" />
1107     </xsl:otherwise>
1108   </xsl:choose>
1109 </xsl:template>
1111 <!--
1112   // Fill rule //
1113 -->
1114 <xsl:template mode="fill_rule" match="*">
1115   <xsl:choose>
1116     <xsl:when test="@fill-rule and (@fill-rule = 'nonzero' or @fill-rule = 'evenodd')">
1117       <xsl:attribute name="FillRule">
1118         <xsl:value-of select="@fill-rule" />
1119       </xsl:attribute>
1120     </xsl:when>
1121     <xsl:when test="@style and contains(@style, 'fill-rule:')">
1122       <xsl:variable name="FillRule" select="normalize-space(substring-after(@style, 'fill-rule:'))" />
1123       <xsl:choose>
1124         <xsl:when test="contains($FillRule, ';')">
1125           <xsl:if test="substring-before($FillRule, ';') = 'nonzero' or substring-before($FillRule, ';') = 'evenodd'">
1126             <xsl:attribute name="FillRule">
1127               <xsl:value-of select="substring-before($FillRule, ';')" />
1128             </xsl:attribute>
1129           </xsl:if>
1130         </xsl:when>
1131         <xsl:when test="$FillRule = 'nonzero' or $FillRule = 'evenodd'">
1132           <xsl:attribute name="FillRule">
1133             <xsl:value-of select="$FillRule" />
1134           </xsl:attribute>
1135         </xsl:when>
1136       </xsl:choose>
1137     </xsl:when>
1138     <xsl:when test="name(..) = 'g' or name(..) = 'svg'">
1139       <xsl:apply-templates mode="fill_rule" select="parent::*"/>
1140     </xsl:when>
1141     <xsl:otherwise>
1142       <xsl:attribute name="FillRule">NonZero</xsl:attribute>
1143     </xsl:otherwise>
1144   </xsl:choose>
1145 </xsl:template>
1147 <!--
1148   // Generic fill template //
1149 -->
1150 <xsl:template mode="template_fill" match="*">
1151   <xsl:variable name="fill"><xsl:apply-templates mode="fill" select="." /></xsl:variable>
1152   <xsl:variable name="fill_opacity"><xsl:apply-templates mode="fill_opacity" select="." /></xsl:variable>
1153   <xsl:if test="not($fill = 'none')">
1154     <xsl:attribute name="Fill">
1155       <xsl:choose>
1156         <xsl:when test="$fill != ''">
1157           <xsl:call-template name="template_color">
1158             <xsl:with-param name="colorspec">
1159               <xsl:if test="$fill != 'none'">
1160                 <xsl:value-of select="$fill" />
1161               </xsl:if>
1162             </xsl:with-param>
1163             <xsl:with-param name="opacityspec">
1164               <xsl:value-of select="$fill_opacity" />
1165             </xsl:with-param>
1166           </xsl:call-template>
1167         </xsl:when>
1168         <xsl:otherwise>#000000</xsl:otherwise>
1169       </xsl:choose>
1170     </xsl:attribute>
1171   </xsl:if>
1172 </xsl:template>
1174 <!--
1175   // Stroke //
1176 -->
1177 <xsl:template mode="stroke" match="*">
1178   <xsl:choose>
1179     <xsl:when test="@stroke and starts-with(@stroke, 'url(#')">
1180       <xsl:value-of select="concat('{StaticResource ', substring-before(substring-after(@stroke, 'url(#'), ')'), '}')" />
1181     </xsl:when>
1182     <xsl:when test="@stroke and @stroke != 'none'">
1183       <xsl:value-of select="@stroke" />
1184     </xsl:when>
1185     <xsl:when test="@style and contains(@style, 'stroke:') and starts-with(substring-after(@style, 'stroke:'), 'url(#')">
1186       <xsl:value-of select="concat('{StaticResource ', substring-before(substring-after(@style, 'url(#'), ')'), '}')" />
1187     </xsl:when>
1188     <xsl:when test="@style and contains(@style, 'stroke:')">
1189       <xsl:variable name="Stroke" select="substring-after(@style, 'stroke:')" />
1190       <xsl:choose>
1191         <xsl:when test="contains($Stroke, ';')">
1192           <xsl:if test="substring-before($Stroke, ';') != 'none'">
1193             <xsl:value-of select="substring-before($Stroke, ';')" />
1194           </xsl:if>
1195         </xsl:when>
1196         <xsl:when test="$Stroke != 'none'">
1197           <xsl:value-of select="$Stroke" />
1198         </xsl:when>
1199       </xsl:choose>
1200     </xsl:when>
1201     <xsl:when test="name(..) = 'g' or name(..) = 'svg'">
1202       <xsl:apply-templates mode="stroke" select="parent::*"/>
1203     </xsl:when>
1204   </xsl:choose>
1205 </xsl:template>
1207 <!--
1208   // Stroke opacity //
1209 -->
1210 <xsl:template mode="stroke_opacity" match="*">
1211   <xsl:variable name="value">
1212   <xsl:choose>
1213     <xsl:when test="@stroke-opacity">
1214       <xsl:value-of select="@stroke-opacity" />
1215     </xsl:when>
1216     <xsl:when test="@style and contains(@style, 'stroke-opacity:')">
1217       <xsl:variable name="Opacity" select="substring-after(@style, 'stroke-opacity:')" />
1218       <xsl:choose>
1219         <xsl:when test="contains($Opacity, ';')">
1220           <xsl:value-of select="substring-before($Opacity, ';')" />
1221         </xsl:when>
1222         <xsl:otherwise>
1223           <xsl:value-of select="$Opacity" />
1224         </xsl:otherwise>
1225       </xsl:choose>
1226     </xsl:when>
1227     <xsl:when test="name(..) = 'g' or name(..) = 'svg'">
1228       <xsl:apply-templates mode="stroke_opacity" select="parent::*" />
1229     </xsl:when>
1230     <xsl:otherwise>1</xsl:otherwise>
1231   </xsl:choose>
1232   </xsl:variable>
1233   <xsl:choose>
1234     <xsl:when test="$value &lt; 0">0</xsl:when>
1235     <xsl:when test="$value &gt; 1">1</xsl:when>
1236     <xsl:otherwise>
1237       <xsl:value-of select="$value" />
1238     </xsl:otherwise>
1239   </xsl:choose>
1240 </xsl:template>
1242 <!-- 
1243   // Generic stroke template //
1244  -->
1245 <xsl:template mode="template_stroke" match="*">
1246   <xsl:variable name="stroke">
1247     <xsl:apply-templates mode="stroke" select="." />
1248   </xsl:variable>
1249   <xsl:variable name="stroke_opacity">
1250     <xsl:apply-templates mode="stroke_opacity" select="." />
1251   </xsl:variable>
1252   <xsl:variable name="stroke_width">
1253     <xsl:apply-templates mode="stroke_width" select="." />
1254   </xsl:variable>
1255   
1256   <xsl:if test="$stroke_width != ''">
1257     <xsl:attribute name="StrokeThickness">
1258       <xsl:value-of select="$stroke_width" />
1259     </xsl:attribute>
1260   </xsl:if>
1261   <xsl:if test="$stroke != ''">
1262     <xsl:attribute name="Stroke">
1263       <xsl:call-template name="template_color">
1264         <xsl:with-param name="colorspec">
1265           <xsl:value-of select="$stroke" />
1266         </xsl:with-param>
1267         <xsl:with-param name="opacityspec">
1268           <xsl:value-of select="$stroke_opacity" />
1269         </xsl:with-param>
1270       </xsl:call-template>
1271     </xsl:attribute>
1272   </xsl:if>
1273 </xsl:template>
1275 <!--
1276   // Stroke width //
1277 -->
1278 <xsl:template mode="stroke_width" match="*">
1279   <xsl:choose>
1280     <xsl:when test="@stroke-width">
1281       <xsl:call-template name="convert_unit">
1282         <xsl:with-param name="convert_value">
1283           <xsl:value-of select="@stroke-width" />
1284         </xsl:with-param>
1285       </xsl:call-template> 
1286     </xsl:when>
1287     <xsl:when test="@style and contains(@style, 'stroke-width:')">
1288       <xsl:call-template name="convert_unit">
1289         <xsl:with-param name="convert_value">
1290         <xsl:choose>
1291           <xsl:when test="contains(substring-after(@style, 'stroke-width:'), ';')">
1292             <xsl:value-of select="substring-before(substring-after(@style, 'stroke-width:'), ';')" />
1293           </xsl:when>
1294           <xsl:otherwise>
1295             <xsl:value-of select="substring-after(@style, 'stroke-width:')" />
1296           </xsl:otherwise>
1297         </xsl:choose>
1298         </xsl:with-param>
1299       </xsl:call-template> 
1300     </xsl:when>
1301     <xsl:when test="name(..) = 'g' or name(..) = 'svg'">
1302       <xsl:apply-templates mode="stroke_width" select="parent::*"/>
1303     </xsl:when>
1304   </xsl:choose>
1305 </xsl:template>
1307 <!--
1308   // Stroke miterlimit //
1309 -->
1310 <xsl:template mode="stroke_miterlimit" match="*">
1311   <xsl:choose>
1312     <xsl:when test="@stroke-miterlimit">
1313       <xsl:attribute name="StrokeMiterLimit">
1314         <xsl:value-of select="@stroke-miterlimit" />
1315       </xsl:attribute>
1316     </xsl:when>
1317     <xsl:when test="@style and contains(@style, 'stroke-miterlimit:')">
1318       <xsl:variable name="StrokeMiterLimit" select="substring-after(@style, 'stroke-miterlimit:')" />
1319       <xsl:attribute name="StrokeMiterLimit">
1320         <xsl:choose>
1321           <xsl:when test="contains($StrokeMiterLimit, ';')">
1322             <xsl:value-of select="substring-before($StrokeMiterLimit, ';')" />
1323           </xsl:when>
1324           <xsl:otherwise>
1325             <xsl:value-of select="$StrokeMiterLimit" />
1326           </xsl:otherwise>
1327         </xsl:choose>
1328       </xsl:attribute>
1329     </xsl:when>
1330     <xsl:when test="name(..) = 'g' or name(..) = 'svg'">
1331       <xsl:apply-templates mode="stroke_miterlimit" select="parent::*"/>
1332     </xsl:when>
1333   </xsl:choose>
1334 </xsl:template>
1336 <!-- 
1337   // Stroke dasharray //
1338 -->
1339 <xsl:template mode="stroke_dasharray" match="*">
1340   <!-- stroke-dasharray="10,30,20,30" becomes StrokeDashArray="1 3 2 3" ?? -->
1341   <xsl:choose>
1342     <xsl:when test="@stroke-dasharray and @stroke-dasharray != 'none'">
1343       <xsl:attribute name="StrokeDashArray">
1344         <xsl:value-of select="@stroke-dasharray" />
1345       </xsl:attribute>
1346     </xsl:when>
1347     <xsl:when test="@style and contains(@style, 'stroke-dasharray:')">
1348       <xsl:variable name="StrokeDashArray" select="substring-after(@style, 'stroke-dasharray:')" />
1349       <xsl:choose>
1350         <xsl:when test="contains($StrokeDashArray, ';')">
1351           <xsl:if test="substring-before($StrokeDashArray, ';') != 'none'">
1352             <xsl:attribute name="StrokeDashArray">
1353               <xsl:value-of select="substring-before($StrokeDashArray, ';')" />
1354             </xsl:attribute>
1355           </xsl:if>
1356         </xsl:when>
1357         <xsl:when test="$StrokeDashArray != 'none'">
1358           <xsl:attribute name="StrokeDashArray">
1359             <xsl:value-of select="$StrokeDashArray" />
1360           </xsl:attribute>
1361         </xsl:when>
1362       </xsl:choose>
1363     </xsl:when>
1364     <xsl:when test="name(..) = 'g' or name(..) = 'svg'">
1365       <xsl:apply-templates mode="stroke_dasharray" select="parent::*"/>
1366     </xsl:when>
1367   </xsl:choose>
1368 </xsl:template>
1370 <!-- 
1371   // Stroke dashoffset //
1372 -->
1373 <xsl:template mode="stroke_dashoffset" match="*">
1374   <xsl:choose>
1375     <xsl:when test="@stroke-dashoffset">
1376       <xsl:attribute name="StrokeDashOffset">
1377         <xsl:value-of select="@stroke-dashoffset" />
1378       </xsl:attribute>
1379     </xsl:when>
1380     <xsl:when test="@style and contains(@style, 'stroke-dashoffset:')">
1381       <xsl:variable name="StrokeDashOffset" select="substring-after(@style, 'stroke-dashoffset:')" />
1382       <xsl:attribute name="StrokeDashOffset">
1383         <xsl:choose>
1384           <xsl:when test="contains($StrokeDashOffset, ';')">
1385             <xsl:value-of select="substring-before($StrokeDashOffset, ';')" />
1386           </xsl:when>
1387           <xsl:otherwise>
1388             <xsl:value-of select="$StrokeDashOffset" />
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_dashoffset" select="parent::*"/>
1395     </xsl:when>
1396   </xsl:choose>
1397 </xsl:template>
1399 <!-- 
1400   // Linejoin SVG to XAML converter //
1401 -->
1402 <xsl:template name="linejoin_svg_to_xaml">
1403   <xsl:param name="linejoin" />
1404   <xsl:choose>
1405     <xsl:when test="$linejoin = 'bevel'">Bevel</xsl:when>
1406     <xsl:when test="$linejoin = 'round'">Round</xsl:when>
1407     <xsl:otherwise>Miter</xsl:otherwise>
1408   </xsl:choose>
1409 </xsl:template>
1411 <!-- 
1412   // Stroke linejoin //
1413 -->
1414 <xsl:template mode="stroke_linejoin" match="*">
1415   <xsl:choose>
1416     <xsl:when test="@stroke-linejoin">
1417       <xsl:attribute name="StrokeLineJoin">
1418         <xsl:call-template name="linejoin_svg_to_xaml">
1419           <xsl:with-param name="linejoin">
1420             <xsl:value-of select="@stroke-linejoin" />
1421           </xsl:with-param>
1422         </xsl:call-template>
1423       </xsl:attribute>
1424     </xsl:when>
1425     <xsl:when test="@style and contains(@style, 'stroke-linejoin:')">
1426       <xsl:variable name="StrokeLineJoin" select="substring-after(@style, 'stroke-linejoin:')" />
1427       <xsl:attribute name="StrokeLineJoin">
1428         <xsl:choose>
1429           <xsl:when test="contains($StrokeLineJoin, ';')">
1430             <xsl:call-template name="linejoin_svg_to_xaml">
1431               <xsl:with-param name="linejoin">
1432                 <xsl:value-of select="substring-before($StrokeLineJoin, ';')" />
1433               </xsl:with-param>
1434             </xsl:call-template>
1435           </xsl:when>
1436           <xsl:otherwise>
1437             <xsl:call-template name="linejoin_svg_to_xaml">
1438               <xsl:with-param name="linejoin">
1439                 <xsl:value-of select="$StrokeLineJoin" />
1440               </xsl:with-param>
1441             </xsl:call-template>
1442           </xsl:otherwise>
1443         </xsl:choose>
1444       </xsl:attribute>
1445     </xsl:when>
1446     <xsl:when test="name(..) = 'g' or name(..) = 'svg'">
1447       <xsl:apply-templates mode="stroke_linejoin" select="parent::*"/>
1448     </xsl:when>
1449   </xsl:choose>
1450 </xsl:template>
1452 <!-- 
1453   // Linecap SVG to XAML converter //
1454 -->
1455 <xsl:template name="linecap_svg_to_xaml">
1456   <xsl:param name="linecap" />
1457   <xsl:choose>
1458     <xsl:when test="$linecap = 'round'">Round</xsl:when>
1459     <xsl:when test="$linecap = 'square'">Square</xsl:when>
1460     <xsl:otherwise>Flat</xsl:otherwise>
1461   </xsl:choose>
1462 </xsl:template>
1464 <!--
1465   // Stroke linecap //
1466 -->
1467 <xsl:template mode="stroke_linecap" match="*">
1468   <xsl:choose>
1469     <xsl:when test="@stroke-linecap">
1470       <xsl:attribute name="StrokeStartLineCap">
1471         <xsl:call-template name="linecap_svg_to_xaml">
1472           <xsl:with-param name="linecap">
1473             <xsl:value-of select="@stroke-linecap" />
1474           </xsl:with-param>
1475         </xsl:call-template>
1476       </xsl:attribute>
1477       <xsl:attribute name="StrokeEndLineCap">
1478         <xsl:call-template name="linecap_svg_to_xaml">
1479           <xsl:with-param name="linecap">
1480             <xsl:value-of select="@stroke-linecap" />
1481           </xsl:with-param>
1482         </xsl:call-template>
1483       </xsl:attribute>
1484     </xsl:when>
1485     <xsl:when test="@style and contains(@style, 'stroke-linecap:')">
1486       <xsl:variable name="StrokeStartLineCap" select="substring-after(@style, 'stroke-linecap:')" />
1487       <xsl:variable name="StrokeEndLineCap" select="substring-after(@style, 'stroke-linecap:')" />
1488       <xsl:attribute name="StrokeStartLineCap">
1489         <xsl:choose>
1490           <xsl:when test="contains($StrokeStartLineCap, ';')">
1491             <xsl:call-template name="linecap_svg_to_xaml">
1492               <xsl:with-param name="linecap">
1493                 <xsl:value-of select="substring-before($StrokeStartLineCap, ';')" />
1494               </xsl:with-param>
1495             </xsl:call-template>
1496           </xsl:when>
1497           <xsl:otherwise>
1498             <xsl:call-template name="linecap_svg_to_xaml">
1499               <xsl:with-param name="linecap">
1500                 <xsl:value-of select="$StrokeStartLineCap" />
1501               </xsl:with-param>
1502             </xsl:call-template>
1503           </xsl:otherwise>
1504         </xsl:choose>
1505       </xsl:attribute>
1506       <xsl:attribute name="StrokeEndLineCap">
1507         <xsl:choose>
1508           <xsl:when test="contains($StrokeEndLineCap, ';')">
1509             <xsl:call-template name="linecap_svg_to_xaml">
1510               <xsl:with-param name="linecap">
1511                 <xsl:value-of select="substring-before($StrokeEndLineCap, ';')" />
1512               </xsl:with-param>
1513             </xsl:call-template>
1514           </xsl:when>
1515           <xsl:otherwise>
1516             <xsl:call-template name="linecap_svg_to_xaml">
1517               <xsl:with-param name="linecap">
1518                 <xsl:value-of select="$StrokeEndLineCap" />
1519               </xsl:with-param>
1520             </xsl:call-template>
1521           </xsl:otherwise>
1522         </xsl:choose>
1523       </xsl:attribute>
1524     </xsl:when>
1525     <xsl:when test="name(..) = 'g' or name(..) = 'svg'">
1526       <xsl:apply-templates mode="stroke_linecap" select="parent::*"/>
1527     </xsl:when>
1528   </xsl:choose>
1529 </xsl:template>
1531 <!-- 
1532   // Gradient stops //
1533 -->
1534 <xsl:template mode="stop_color" match="*">
1535   <xsl:variable name="Opacity">
1536     <xsl:choose>
1537       <xsl:when test="@stop-opacity">
1538         <xsl:value-of select="@stop-opacity" />
1539       </xsl:when>
1540       <xsl:when test="@style and contains(@style, 'stop-opacity:')">
1541         <xsl:variable name="temp_opacity" select="substring-after(@style, 'stop-opacity:')" />
1542         <xsl:choose>
1543           <xsl:when test="contains($temp_opacity, ';')">
1544             <xsl:value-of select="substring-before($temp_opacity, ';')" />
1545           </xsl:when>
1546           <xsl:otherwise>
1547             <xsl:value-of select="$temp_opacity" />
1548           </xsl:otherwise>
1549         </xsl:choose>
1550       </xsl:when>
1551       <xsl:otherwise>
1552         <xsl:value-of select="''" />
1553       </xsl:otherwise>
1554     </xsl:choose>
1555   </xsl:variable>
1556   <xsl:variable name="hex_opacity">
1557     <xsl:choose>
1558       <xsl:when test="$Opacity != ''">
1559         <xsl:call-template name="to_hex">
1560           <xsl:with-param name="convert">
1561             <xsl:value-of select="number($Opacity) * 255" />
1562           </xsl:with-param>
1563         </xsl:call-template>
1564       </xsl:when>
1565       <xsl:otherwise>
1566         <xsl:value-of select="$Opacity" />
1567       </xsl:otherwise>
1568     </xsl:choose>
1569   </xsl:variable>
1570   <xsl:variable name="stopcolor">
1571     <xsl:choose>
1572       <xsl:when test="@stop-color">
1573         <xsl:call-template name="template_color">
1574           <xsl:with-param name="colorspec">
1575             <xsl:value-of select="@stop-color" />
1576           </xsl:with-param>
1577         </xsl:call-template>
1578       </xsl:when>
1579       <xsl:when test="@style and contains(@style, 'stop-color:')">
1580         <xsl:variable name="Color" select="substring-after(@style, 'stop-color:')" />
1581         <xsl:choose>
1582           <xsl:when test="contains($Color, ';')">
1583             <xsl:call-template name="template_color">
1584               <xsl:with-param name="colorspec">
1585                 <xsl:value-of select="substring-before($Color, ';')" />
1586               </xsl:with-param>
1587             </xsl:call-template>
1588           </xsl:when>
1589           <xsl:otherwise>
1590             <xsl:call-template name="template_color">
1591               <xsl:with-param name="colorspec">
1592                 <xsl:value-of select="$Color" />
1593               </xsl:with-param>
1594             </xsl:call-template>
1595           </xsl:otherwise>
1596         </xsl:choose>
1597       </xsl:when>
1598       <xsl:when test="name(..) = 'g' or name(..) = 'svg'">
1599         <xsl:apply-templates mode="stop_color" select="parent::*"/>
1600       </xsl:when>
1601       <xsl:otherwise>#000</xsl:otherwise>
1602     </xsl:choose>
1603   </xsl:variable>
1604   <xsl:attribute name="Color">
1605     <xsl:choose>
1606       <xsl:when test="$hex_opacity != '' and starts-with($stopcolor, '#')">
1607         <xsl:value-of select="concat('#', $hex_opacity, substring-after($stopcolor, '#'))" />
1608       </xsl:when>
1609       <xsl:otherwise>
1610         <xsl:value-of select="$stopcolor" />
1611       </xsl:otherwise>
1612     </xsl:choose>
1613   </xsl:attribute>
1614 </xsl:template>
1616 <!--
1617   // Gradient stop opacity //
1618 -->
1619 <xsl:template mode="stop_opacity" match="*">
1620   <xsl:choose>
1621     <xsl:when test="@stop-opacity">
1622       <xsl:attribute name="Opacity">
1623         <xsl:value-of select="@stop-opacity" />
1624       </xsl:attribute>
1625     </xsl:when>
1626     <xsl:when test="@style and contains(@style, 'stop-opacity:')">
1627       <xsl:variable name="Opacity" select="substring-after(@style, 'stop-opacity:')" />
1628       <xsl:attribute name="Opacity">
1629         <xsl:choose>
1630           <xsl:when test="contains($Opacity, ';')">
1631             <xsl:value-of select="substring-before($Opacity, ';')" />
1632           </xsl:when>
1633           <xsl:otherwise>
1634             <xsl:value-of select="$Opacity" />
1635           </xsl:otherwise>
1636         </xsl:choose>
1637       </xsl:attribute>
1638     </xsl:when>
1639     <xsl:when test="name(..) = 'g' or name(..) = 'svg'">
1640       <xsl:apply-templates mode="stop_opacity" select="parent::*"/>
1641     </xsl:when>
1642   </xsl:choose>
1643 </xsl:template>
1645 <!--
1646   // Gradient stop offset //
1647 -->
1648 <xsl:template mode="offset" match="*">
1649   <xsl:choose>
1650     <xsl:when test="@offset">
1651       <xsl:attribute name="Offset">
1652         <xsl:choose>
1653           <xsl:when test="contains(@offset, '%')">
1654             <xsl:value-of select="number(substring-before(@offset, '%')) div 100" />
1655           </xsl:when>
1656           <xsl:otherwise>
1657             <xsl:value-of select="@offset" />
1658           </xsl:otherwise>
1659         </xsl:choose>
1660       </xsl:attribute>
1661     </xsl:when>
1662     <xsl:when test="@style and contains(@style, 'offset:')">
1663       <xsl:variable name="Offset" select="substring-after(@style, 'offset:')" />
1664       <xsl:attribute name="Offset">
1665         <xsl:choose>
1666           <xsl:when test="contains($Offset, '%')">
1667             <xsl:value-of select="number(substring-before($Offset, '%')) div 100" />
1668           </xsl:when>        
1669           <xsl:when test="contains($Offset, ';')">
1670             <xsl:value-of select="substring-before($Offset, ';')" />
1671           </xsl:when>
1672           <xsl:otherwise>
1673             <xsl:value-of select="$Offset" />
1674           </xsl:otherwise>
1675         </xsl:choose>
1676       </xsl:attribute>
1677     </xsl:when>
1678     <xsl:when test="name(..) = 'g' or name(..) = 'svg'">
1679       <xsl:apply-templates mode="stop_offset" select="parent::*"/>
1680     </xsl:when>
1681   </xsl:choose>
1682 </xsl:template>
1684 <!-- 
1685   // Image stretch //
1686   SVG: preserveAspectRatio, XAML: Stretch
1687 -->
1688 <xsl:template mode="image_stretch" match="*">
1689   <xsl:variable name="value">
1690     <xsl:choose>
1691       <xsl:when test="@preserveAspectRatio">
1692         <xsl:value-of select="@preserveAspectRatio" />
1693       </xsl:when>
1694       <xsl:when test="@style and contains(@style, 'preserveAspectRatio:')">
1695         <xsl:variable name="ratio" select="normalize-space(substring-after(@style, 'preserveAspectRatio:'))" />
1696         <xsl:choose>
1697           <xsl:when test="contains($ratio, ';')">
1698             <xsl:value-of select="substring-before($ratio, ';')" />
1699           </xsl:when>
1700           <xsl:otherwise>
1701             <xsl:value-of select="$ratio" />
1702           </xsl:otherwise>
1703         </xsl:choose>
1704       </xsl:when>
1705     </xsl:choose>
1706   </xsl:variable>
1707   <xsl:if test="$value = 'none'">  
1708     <xsl:attribute name="Stretch">Fill</xsl:attribute>
1709   </xsl:if>
1710 </xsl:template>
1712 <!-- 
1713   // Text specific templates //
1715   * Text tspan
1716   * Text flowPara
1717   * Text flowRegion (text frame)
1718   * Get font size
1719   * Font size
1720   * Font weight
1721   * Font family
1722   * Font style
1723   * Baseline shift
1724   * Line height
1725   * Writing mode
1726   * Text decoration
1727   * Text fill
1728   * Text direction
1729   * Text size
1730   * Text position
1731   * Text object
1732   * FlowRoot object
1733 -->
1735  <!-- 
1736   // Text span //
1737   SVG: tspan, flowSpan, XAML: Span
1738   
1739   Not supported in XAML:
1740   * span position
1741 -->
1742 <xsl:template mode="forward" match="*[name(.) = 'tspan'  or name(.) = 'flowSpan']">
1743   <Span>
1744     <xsl:if test="../@xml:space='preserve'">
1745       <xsl:attribute name="whiteSpaceCollapse">preserve</xsl:attribute>
1746     </xsl:if>
1747     <xsl:variable name="fill">
1748       <xsl:apply-templates mode="fill" select="." />
1749     </xsl:variable>
1750     <xsl:if test="starts-with($fill, '#') or (not(starts-with($fill, 'url')) and $fill != '' and $fill != 'none')">
1751       <xsl:attribute name="Foreground">
1752         <xsl:call-template name="template_color">
1753           <xsl:with-param name="colorspec">
1754             <xsl:value-of select="$fill" />
1755           </xsl:with-param>
1756         </xsl:call-template>
1757       </xsl:attribute>
1758     </xsl:if>
1759     <xsl:apply-templates mode="font_size" select="." />
1760     <xsl:apply-templates mode="font_weight" select="." />
1761     <xsl:apply-templates mode="font_family" select="." />
1762     <xsl:apply-templates mode="font_style" select="." />
1763     <xsl:apply-templates mode="text_fill" select="." />
1764     <xsl:apply-templates mode="text_decoration" select="." />
1765     <xsl:apply-templates mode="line_height" select="." />
1766     <xsl:apply-templates mode="baseline_shift" select="." />
1767     
1768     <xsl:if test="text()">
1769       <xsl:value-of select="text()" />
1770     </xsl:if>
1771   </Span>
1772 </xsl:template>
1774  <!-- 
1775   // Text flowPara //
1776   SVG: flowPara, flowDiv XAML: ?
1777   
1778 -->
1779 <xsl:template mode="forward" match="*[name(.) = 'flowPara' or name(.) = 'flowDiv']">
1780   <xsl:choose>
1781     <xsl:when test="*[name(.) = 'flowSpan']/text()">
1782       <xsl:apply-templates mode="forward" />
1783     </xsl:when>
1784     <xsl:otherwise>
1785       <xsl:choose>
1786         <xsl:when test="@xml:space='preserve'">
1787           <xsl:copy-of select="translate(text(), '&#x9;&#xA;&#xD;', ' ')" />
1788         </xsl:when>
1789         <xsl:otherwise>
1790           <xsl:copy-of select="normalize-space(translate(text(), '&#x9;&#xA;&#xD;', ' '))" />
1791         </xsl:otherwise>
1792       </xsl:choose>  
1793     </xsl:otherwise>
1794   </xsl:choose>
1795 </xsl:template>
1798  <!-- 
1799   // Text flowRegion //
1800 -->
1801 <xsl:template mode="flow_region" match="*">
1802   <xsl:apply-templates mode="text_size" select="." />
1803   <xsl:apply-templates mode="text_position" select="." />
1804 </xsl:template>
1806 <!-- 
1807   // Get text font size //
1808 -->
1809 <xsl:template mode="get_font_size" match="*">
1810   <xsl:choose>
1811     <xsl:when test="@font-size">
1812       <xsl:value-of select="@font-size" />
1813     </xsl:when>
1814     <xsl:when test="@style and contains(@style, 'font-size:')">
1815       <xsl:variable name="font_size" select="normalize-space(substring-after(@style, 'font-size:'))" />
1816       <xsl:choose>
1817         <xsl:when test="contains($font_size, ';')">
1818           <xsl:value-of select="substring-before($font_size, ';')" />
1819         </xsl:when>
1820         <xsl:otherwise>
1821           <xsl:value-of select="$font_size" />
1822         </xsl:otherwise>
1823       </xsl:choose>
1824     </xsl:when>
1825     <xsl:when test="name(..) = 'g' or name(..) = 'svg' or name(..) = 'text' or name(..) = 'flowPara' or name(..) = 'flowRoot'">
1826       <xsl:apply-templates mode="get_font_size" select="parent::*"/>
1827     </xsl:when>
1828   </xsl:choose>
1829 </xsl:template>
1831 <!-- 
1832   // Text font size //
1833   SVG: font-size, XAML: FontSize
1834 -->
1835 <xsl:template mode="font_size" match="*">
1836   <xsl:variable name="value">
1837     <xsl:apply-templates mode="get_font_size" select="." />
1838   </xsl:variable>
1839   <xsl:if test="$value != ''">
1840     <xsl:attribute name="FontSize">
1841       <xsl:call-template name="convert_unit">
1842         <xsl:with-param name="convert_value" select="$value" />
1843       </xsl:call-template>
1844     </xsl:attribute>
1845   </xsl:if>
1846   <xsl:attribute name="FontSize">
1847     <xsl:choose>
1848       <xsl:when test="$value != ''">
1849         <xsl:call-template name="convert_unit">
1850           <xsl:with-param name="convert_value" select="$value" />
1851         </xsl:call-template>
1852       </xsl:when>
1853       <xsl:otherwise>12</xsl:otherwise>
1854     </xsl:choose>
1855   </xsl:attribute>
1856 </xsl:template>
1858 <!-- 
1859   // Text font weight //
1860   SVG: font-weight, XAML: FontWeight
1861 -->
1862 <xsl:template mode="font_weight" match="*">
1863   <xsl:variable name="value">
1864     <xsl:if test="@font-weight">
1865       <xsl:value-of select="@font-weight" />
1866     </xsl:if>
1867     <xsl:if test="@style and contains(@style, 'font-weight:')">
1868       <xsl:variable name="font_weight" select="normalize-space(substring-after(@style, 'font-weight:'))" />
1869       <xsl:choose>
1870         <xsl:when test="contains($font_weight, ';')">
1871           <xsl:value-of select="substring-before($font_weight, ';')" />
1872         </xsl:when>
1873         <xsl:otherwise>
1874           <xsl:value-of select="$font_weight" />
1875         </xsl:otherwise>
1876       </xsl:choose>
1877     </xsl:if>
1878   </xsl:variable>
1879   <xsl:if test="$value != ''">
1880     <xsl:attribute name="FontWeight">
1881       <xsl:choose>
1882         <xsl:when test="$value &lt;= 100 or $value = 'lighter'">Thin</xsl:when>
1883         <xsl:when test="$value &gt; 100 and $value &lt;= 200">ExtraLight</xsl:when>
1884         <xsl:when test="$value &gt; 200 and $value &lt;= 300">Light</xsl:when>
1885         <xsl:when test="($value &gt; 300 and $value &lt;= 400) or $value ='normal'">Normal</xsl:when>
1886         <xsl:when test="$value &gt; 400 and $value &lt;= 500">Medium</xsl:when>
1887         <xsl:when test="$value &gt; 500 and $value &lt;= 600">SemiBold</xsl:when>
1888         <xsl:when test="($value &gt; 600 and $value &lt;= 700) or $value ='bold'">Bold</xsl:when>
1889         <xsl:when test="$value &gt; 700 and $value &lt;= 800">ExtraBold</xsl:when>
1890         <xsl:when test="$value &gt; 800 and $value &lt;= 900">Black</xsl:when>
1891         <xsl:when test="$value &gt; 900 or $value = 'bolder'">ExtraBlack</xsl:when>
1892         <xsl:otherwise>normal</xsl:otherwise>
1893       </xsl:choose>
1894     </xsl:attribute>
1895   </xsl:if>
1896 </xsl:template>
1898 <!-- 
1899   // Text font family //
1900   SVG: font-family, XAML: FontFamily
1901 -->
1902 <xsl:template mode="font_family" match="*">
1903   <xsl:variable name="value">
1904     <xsl:if test="@font-family">
1905       <xsl:value-of select="translate(@font-family, &quot;'&quot;, '')" />
1906     </xsl:if>
1907     <xsl:if test="@style and contains(@style, 'font-family:')">
1908       <xsl:variable name="font_family" select="normalize-space(substring-after(@style, 'font-family:'))" />
1909       <xsl:choose>
1910         <xsl:when test="contains($font_family, ';')">
1911           <xsl:value-of select="translate(substring-before($font_family, ';'), &quot;'&quot;, '')" />
1912         </xsl:when>
1913         <xsl:otherwise>
1914           <xsl:value-of select="translate($font_family, &quot;'&quot;, '')" />
1915         </xsl:otherwise>
1916       </xsl:choose>
1917     </xsl:if>
1918   </xsl:variable>
1919   <xsl:if test="$value != ''">
1920     <xsl:attribute name="FontFamily">
1921       <xsl:choose>
1922         <xsl:when test="$value='Sans'">Arial</xsl:when>
1923         <xsl:otherwise>
1924           <xsl:value-of select="$value" />
1925         </xsl:otherwise>
1926       </xsl:choose>
1927     </xsl:attribute>
1928   </xsl:if>
1929 </xsl:template>
1931 <!-- 
1932   // Text font style //
1933   SVG: font-style, XAML: FontStyle
1934 -->
1935 <xsl:template mode="font_style" match="*">
1936   <xsl:variable name="value">
1937     <xsl:if test="@font-style">
1938       <xsl:value-of select="@font-style" />
1939     </xsl:if>
1940     <xsl:if test="@style and contains(@style, 'font-style:')">
1941       <xsl:variable name="font_style" select="normalize-space(substring-after(@style, 'font-style:'))" />
1942       <xsl:choose>
1943         <xsl:when test="contains($font_style, ';')">
1944           <xsl:value-of select="substring-before($font_style, ';')" />
1945         </xsl:when>
1946         <xsl:otherwise>
1947           <xsl:value-of select="$font_style" />
1948         </xsl:otherwise>
1949       </xsl:choose>
1950     </xsl:if>
1951   </xsl:variable>
1952   <xsl:if test="$value != ''">
1953     <xsl:attribute name="FontStyle">
1954       <xsl:value-of select="$value" />
1955     </xsl:attribute>
1956   </xsl:if>
1957 </xsl:template>
1959 <!-- 
1960   // Text baseline shift //
1961   SVG: baseline-shift, XAML: BaselineAlignment
1962 -->
1963 <xsl:template mode="baseline_shift" match="*">
1964   <xsl:variable name="value">
1965     <xsl:if test="@baseline-shift">
1966       <xsl:value-of select="@baseline-shift" />
1967     </xsl:if>
1968     <xsl:if test="@style and contains(@style, 'baseline-shift:') and not(contains(substring-after(@style, 'baseline-shift:'), ';'))">
1969       <xsl:value-of select="substring-after(@style, 'baseline-shift:')" />
1970     </xsl:if>
1971     <xsl:if test="@style and contains(@style, 'baseline-shift:') and contains(substring-after(@style, 'baseline-shift:'), ';')">
1972       <xsl:value-of select="substring-before(substring-after(@style, 'baseline-shift:'), ';')" />
1973     </xsl:if>   
1974   </xsl:variable>
1975   <xsl:if test="$value = 'baseline' or $value='super' or $value='sub'">
1976     <xsl:attribute name="BaselineAlignment">  
1977       <xsl:choose>
1978         <xsl:when test="$value='baseline'">Normal</xsl:when>
1979         <xsl:when test="$value='super'">Superscript</xsl:when>
1980         <xsl:when test="$value='sub'">Subscript</xsl:when>
1981       </xsl:choose>  
1982       <xsl:if test="contains($value, '%')">%</xsl:if>
1983     </xsl:attribute>
1984   </xsl:if>
1985 </xsl:template>
1987 <!-- 
1988   // Text line height //
1989   SVG: line-height, FXG: lineHeight
1990 -->
1991 <xsl:template mode="line_height" match="*">
1992   <xsl:variable name="value">
1993     <xsl:if test="@line-height">
1994       <xsl:value-of select="@line-height" />
1995     </xsl:if>
1996     <xsl:if test="@style and contains(@style, 'line-height:')">
1997       <xsl:variable name="line_height" select="normalize-space(substring-after(@style, 'line-height:'))" />
1998       <xsl:choose>
1999         <xsl:when test="contains($line_height, ';')">
2000           <xsl:value-of select="substring-before($line_height, ';')" />
2001         </xsl:when>
2002         <xsl:otherwise>
2003           <xsl:value-of select="$line_height" />
2004         </xsl:otherwise>
2005       </xsl:choose>
2006     </xsl:if>
2007   </xsl:variable>
2008   <xsl:if test="$value != ''">
2009     <xsl:attribute name="lineHeight">
2010       <xsl:call-template name="convert_unit">
2011         <xsl:with-param name="convert_value" select="$value" />
2012       </xsl:call-template>
2013     </xsl:attribute>
2014   </xsl:if>
2015 </xsl:template>
2017 <!-- 
2018   // Text writing mode //
2019   SVG: writing-mode, FXG: blockProgression 
2020   
2021   Values inverted in FXG...
2022 -->
2023 <xsl:template mode="writing_mode" match="*">
2024   <xsl:variable name="value">
2025     <xsl:if test="@writing-mode">
2026       <xsl:value-of select="@writing-mode" />
2027     </xsl:if>
2028     <xsl:if test="@style and contains(@style, 'writing-mode:') and not(contains(substring-after(@style, 'writing-mode:'), ';'))">
2029       <xsl:value-of select="substring-after(@style, 'writing-mode:')" />
2030     </xsl:if>
2031     <xsl:if test="@style and contains(@style, 'writing-mode:') and contains(substring-after(@style, 'writing-mode:'), ';')">
2032       <xsl:value-of select="substring-before(substring-after(@style, 'writing-mode:'), ';')" />
2033     </xsl:if>   
2034   </xsl:variable>
2035   <xsl:if test="$value != ''">
2036     <xsl:attribute name="blockProgression">  
2037       <xsl:choose>
2038         <xsl:when test="$value='tb'">rl</xsl:when>
2039         <xsl:otherwise>tb</xsl:otherwise>
2040       </xsl:choose>  
2041     </xsl:attribute>
2042     <xsl:if test="$value='tb'">
2043       <xsl:attribute name="textRotation">rotate270</xsl:attribute>
2044     </xsl:if>  
2045   </xsl:if>
2046 </xsl:template>
2047   
2048 <!-- 
2049   // Text decoration //
2050   SVG: text-decoration, XAML: TextDecorations 
2051 -->
2052 <xsl:template mode="text_decoration" match="*">
2053   <xsl:variable name="value">
2054     <xsl:if test="@text-decoration">
2055       <xsl:value-of select="@text-decoration" />
2056     </xsl:if>
2057     <xsl:if test="@style and contains(@style, 'text-decoration:') and not(contains(substring-after(@style, 'text-decoration:'), ';'))">
2058       <xsl:value-of select="substring-after(@style, 'text-decoration:')" />
2059     </xsl:if>
2060     <xsl:if test="@style and contains(@style, 'text-decoration:') and contains(substring-after(@style, 'text-decoration:'), ';')">
2061       <xsl:value-of select="substring-before(substring-after(@style, 'text-decoration:'), ';')" />
2062     </xsl:if>   
2063   </xsl:variable>
2064   <xsl:if test="$value != ''">
2065     <xsl:attribute name="TextDecorations">
2066       <xsl:choose>
2067         <xsl:when test="$value='underline'">Underline</xsl:when>
2068         <xsl:when test="$value='line-through'">Strikethrough</xsl:when>
2069         <xsl:when test="$value='overline'">Overline</xsl:when>
2070         <xsl:otherwise>None</xsl:otherwise>
2071       </xsl:choose>  
2072     </xsl:attribute>
2073   </xsl:if>
2074 </xsl:template>
2076 <!-- 
2077   // Text fill //
2078   SVG: fill, fill-opacity, XAML: Foreground
2079 -->
2080 <xsl:template mode="text_fill" match="*">
2081   <xsl:variable name="fill">
2082     <xsl:apply-templates mode="fill" select="." />
2083   </xsl:variable>
2084   <xsl:variable name="fill_opacity">
2085     <xsl:apply-templates mode="fill_opacity" select="." />
2086   </xsl:variable>
2087   <xsl:if test="starts-with($fill, '#') or (not(starts-with($fill, 'url')) and $fill != '' and $fill != 'none')">
2088     <xsl:attribute name="Foreground">
2089       <xsl:call-template name="template_color">
2090         <xsl:with-param name="colorspec">
2091           <xsl:value-of select="$fill" />
2092         </xsl:with-param>
2093         <xsl:with-param name="opacityspec">
2094           <xsl:choose>
2095           <xsl:when test="$fill_opacity">
2096             <xsl:value-of select="$fill_opacity" />
2097           </xsl:when>
2098           <xsl:otherwise>1</xsl:otherwise>
2099           </xsl:choose>
2100         </xsl:with-param>
2101       </xsl:call-template>
2102     </xsl:attribute>
2103   </xsl:if>
2104 </xsl:template>
2106 <!-- 
2107   // Text direction //
2108   SVG: direction, unicode-bidi, XAML: FlowDirection
2109 -->
2110 <xsl:template mode="direction" match="*">
2111   <xsl:variable name="value">
2112     <xsl:if test="@direction">
2113       <xsl:value-of select="@direction" />
2114     </xsl:if>
2115     <xsl:if test="@style and contains(@style, 'direction:') and not(contains(substring-after(@style, 'direction:'), ';'))">
2116       <xsl:value-of select="substring-after(@style, 'direction:')" />
2117     </xsl:if>
2118     <xsl:if test="@style and contains(@style, 'direction:') and contains(substring-after(@style, 'direction:'), ';')">
2119       <xsl:value-of select="substring-before(substring-after(@style, 'direction:'), ';')" />
2120     </xsl:if>   
2121   </xsl:variable>
2122   <xsl:variable name="bidi">
2123     <xsl:if test="@unicode-bidi">
2124       <xsl:value-of select="@unicode-bidi" />
2125     </xsl:if>
2126     <xsl:if test="@style and contains(@style, 'unicode-bidi:') and not(contains(substring-after(@style, 'unicode-bidi:'), ';'))">
2127       <xsl:value-of select="substring-after(@style, 'unicode-bidi:')" />
2128     </xsl:if>
2129     <xsl:if test="@style and contains(@style, 'unicode-bidi:') and contains(substring-after(@style, 'unicode-bidi:'), ';')">
2130       <xsl:value-of select="substring-before(substring-after(@style, 'unicode-bidi:'), ';')" />
2131     </xsl:if>   
2132   </xsl:variable>
2134   <xsl:if test="$value != '' and ($bidi='embed' or $bidi='bidi-override')">  
2135     <xsl:attribute name="FlowDirection">
2136       <xsl:choose>
2137         <xsl:when test="$value='ltr'">LeftToRight</xsl:when>
2138         <xsl:when test="$value='rtl'">RightToLeft</xsl:when>
2139       </xsl:choose>  
2140     </xsl:attribute>
2141   </xsl:if>
2142 </xsl:template>
2144  <!-- 
2145   // Text size //
2146 -->
2147 <xsl:template mode="text_size" match="*">
2148   <xsl:if test="@width">
2149     <xsl:attribute name="Width">
2150       <xsl:call-template name="convert_unit">
2151         <xsl:with-param name="convert_value" select="@width" />
2152       </xsl:call-template>
2153     </xsl:attribute>
2154   </xsl:if>
2155   <xsl:if test="@height">
2156     <xsl:attribute name="Height">
2157       <xsl:call-template name="convert_unit">
2158         <xsl:with-param name="convert_value" select="@height" />
2159       </xsl:call-template>
2160     </xsl:attribute>
2161   </xsl:if>
2162 </xsl:template>
2164  <!-- 
2165   // Text position //
2166 -->
2167 <xsl:template mode="text_position" match="*">
2168   <!-- Keep the first x value only -->
2169   <xsl:if test="@x">
2170     <xsl:attribute name="Canvas.Left">
2171       <xsl:choose>
2172         <xsl:when test="contains(@x, ' ')">
2173           <xsl:call-template name="convert_unit">
2174             <xsl:with-param name="convert_value" select="substring-before(@x, ' ')" />
2175           </xsl:call-template>   
2176           </xsl:when>
2177           <xsl:otherwise>
2178           <xsl:call-template name="convert_unit">
2179             <xsl:with-param name="convert_value" select="@x" />
2180           </xsl:call-template>  
2181         </xsl:otherwise>
2182       </xsl:choose>
2183     </xsl:attribute>
2184   </xsl:if>
2185   <!-- Keep the first y value only -->
2186   <xsl:if test="@y">
2187     <xsl:attribute name="Canvas.Top">
2188       <xsl:variable name="top_val">
2189         <xsl:choose>
2190           <xsl:when test="contains(@y, ' ')">
2191             <xsl:call-template name="convert_unit">
2192               <xsl:with-param name="convert_value" select="substring-before(@y, ' ')" />
2193             </xsl:call-template>   
2194             </xsl:when>
2195             <xsl:otherwise>
2196             <xsl:call-template name="convert_unit">
2197               <xsl:with-param name="convert_value" select="@y" />
2198             </xsl:call-template>  
2199           </xsl:otherwise>
2200         </xsl:choose>
2201       </xsl:variable>
2202       <xsl:variable name="size_val">
2203         <xsl:variable name="value">
2204           <xsl:apply-templates mode="get_font_size" select="." />
2205         </xsl:variable>
2206         <xsl:choose>
2207           <xsl:when test="$value != ''">
2208             <xsl:call-template name="convert_unit">
2209               <xsl:with-param name="convert_value" select="$value" />
2210             </xsl:call-template>
2211           </xsl:when>
2212           <xsl:otherwise>12</xsl:otherwise>
2213         </xsl:choose>
2214       </xsl:variable>
2215       <xsl:if test="$top_val != '' and $size_val != ''">
2216         <xsl:value-of select="$top_val - $size_val" />
2217       </xsl:if>
2218     </xsl:attribute>
2219   </xsl:if>
2220 </xsl:template>
2222 <!-- 
2223   // Objects //
2225   * Text
2226   * Lines
2227   * Rectangle
2228   * Polygon
2229   * Polyline
2230   * Path
2231   * Ellipse
2232   * Circle
2233   * Image
2234 -->
2236 <!-- 
2237   // Text objects //
2238   SVG: text, XAML: TextBlock
2239 -->
2240 <xsl:template mode="forward" match="*[name(.) = 'text' or name(.) = 'flowRoot']">
2241   <TextBlock>
2242     <xsl:apply-templates mode="font_size" select="." />
2243     <xsl:apply-templates mode="font_weight" select="." />
2244     <xsl:apply-templates mode="font_family" select="." />
2245     <xsl:apply-templates mode="font_style" select="." />
2246     <xsl:apply-templates mode="text_fill" select="." />
2247     <xsl:apply-templates mode="text_size" select="." />
2248     <xsl:apply-templates mode="text_decoration" select="." />
2249     <xsl:apply-templates mode="direction" select="." />
2250     <xsl:apply-templates mode="text_position" select="." />
2251     <xsl:if test="name(.) = 'flowRoot'">
2252       <xsl:attribute name="TextWrapping">
2253         <xsl:value-of select="'Wrap'" />
2254       </xsl:attribute>
2255     </xsl:if>
2256     
2257     <xsl:if test="@text-anchor">
2258       <xsl:attribute name="HorizontalAlignment">
2259         <xsl:choose>
2260           <xsl:when test="@text-anchor = 'start'">Left</xsl:when>
2261           <xsl:when test="@text-anchor = 'middle'">Center</xsl:when>
2262           <xsl:when test="@text-anchor = 'end'">Right</xsl:when>
2263         </xsl:choose>
2264       </xsl:attribute>
2265     </xsl:if>
2266     
2267     <xsl:apply-templates mode="object_opacity" select="." />
2268     
2269     <xsl:apply-templates mode="id" select="." />
2270     <xsl:if test="name(.) = 'flowRoot'">
2271       <xsl:apply-templates mode="flow_region" select="*[name(.) = 'flowRegion']/child::node()" />
2272     </xsl:if>
2273     <xsl:apply-templates mode="filter_effect" select="." />
2274     <xsl:apply-templates mode="desc" select="." />
2275     <xsl:apply-templates mode="resources" select="." />
2276     <xsl:apply-templates mode="clip" select="." />
2277     <!--xsl:apply-templates mode="transform" select="." /-->
2278     <!--xsl:apply-templates mode="forward" /-->
2279     
2280     <xsl:choose>
2281       <xsl:when test="*[name(.) = 'tspan' or name(.) = 'flowPara' or name(.) = 'flowDiv']/text()">
2282         <xsl:apply-templates mode="forward" />
2283       </xsl:when>
2284       <xsl:otherwise>
2285         <xsl:choose>
2286           <xsl:when test="@xml:space='preserve'">
2287             <xsl:copy-of select="translate(text(), '&#x9;&#xA;&#xD;', ' ')" />
2288           </xsl:when>
2289           <xsl:otherwise>
2290             <xsl:copy-of select="normalize-space(translate(text(), '&#x9;&#xA;&#xD;', ' '))" />
2291           </xsl:otherwise>
2292         </xsl:choose>  
2293       </xsl:otherwise>
2294     </xsl:choose>
2295     
2296   </TextBlock>
2297 </xsl:template>
2298  
2299 <!-- 
2300   // Line object //
2301   SVG: line, XAML: Line
2302 -->
2303 <xsl:template mode="forward" match="*[name(.) = 'line']">
2304   <Line>
2305     <xsl:if test="@x1">
2306       <xsl:attribute name="X1">
2307         <xsl:value-of select="@x1" />
2308       </xsl:attribute>
2309     </xsl:if> 
2310     <xsl:if test="@y1">
2311       <xsl:attribute name="Y1">
2312         <xsl:value-of select="@y1" />
2313       </xsl:attribute>
2314     </xsl:if> 
2315     <xsl:if test="@x2">
2316       <xsl:attribute name="X2">
2317         <xsl:value-of select="@x2" />
2318       </xsl:attribute>
2319     </xsl:if> 
2320     <xsl:if test="@y2">
2321       <xsl:attribute name="Y2">
2322         <xsl:value-of select="@y2" />
2323       </xsl:attribute>
2324     </xsl:if>
2325     
2326     <xsl:apply-templates mode="id" select="." />
2327     <xsl:apply-templates mode="template_fill" select="." />
2328     <xsl:apply-templates mode="template_stroke" select="." />
2329     <xsl:apply-templates mode="stroke_miterlimit" select="." />
2330     <xsl:apply-templates mode="stroke_dasharray" select="." />
2331     <xsl:apply-templates mode="stroke_dashoffset" select="." />
2332     <xsl:apply-templates mode="stroke_linejoin" select="." />
2333     <xsl:apply-templates mode="stroke_linecap" select="." />
2334     <xsl:apply-templates mode="filter_effect" select="." />
2335     <xsl:apply-templates mode="object_opacity" select="." />
2336     <xsl:apply-templates mode="desc" select="." />
2337     <xsl:apply-templates mode="resources" select="." />
2339     <xsl:apply-templates mode="transform" select=".">
2340       <xsl:with-param name="mapped_type" select="'Line'" />
2341     </xsl:apply-templates>    
2343     <xsl:apply-templates mode="forward" />
2344   </Line>
2345 </xsl:template>
2347 <!-- 
2348   // Rectangle object //
2349   SVG: rect, XAML: Rectangle
2350 -->
2351 <xsl:template mode="forward" match="*[name(.) = 'rect']">
2352   <Rectangle>
2353     <xsl:if test="@x">
2354       <xsl:attribute name="Canvas.Left">
2355         <xsl:call-template name="convert_unit">
2356           <xsl:with-param name="convert_value" select="@x" />
2357         </xsl:call-template>
2358       </xsl:attribute>
2359     </xsl:if>
2360     <xsl:if test="@y">
2361       <xsl:attribute name="Canvas.Top">
2362         <xsl:call-template name="convert_unit">
2363           <xsl:with-param name="convert_value" select="@y" />
2364         </xsl:call-template>
2365       </xsl:attribute>
2366     </xsl:if>
2367     <xsl:if test="@width">
2368       <xsl:attribute name="Width">
2369         <xsl:call-template name="convert_unit">
2370           <xsl:with-param name="convert_value" select="@width" />
2371         </xsl:call-template>
2372       </xsl:attribute>
2373     </xsl:if>
2374     <xsl:if test="@height">
2375       <xsl:attribute name="Height">
2376         <xsl:call-template name="convert_unit">
2377           <xsl:with-param name="convert_value" select="@height" />
2378         </xsl:call-template>
2379       </xsl:attribute>
2380     </xsl:if>
2381     <xsl:if test="@rx">
2382       <xsl:attribute name="RadiusX">
2383         <xsl:value-of select="@rx" />
2384       </xsl:attribute>
2385     </xsl:if>
2386     <xsl:if test="@ry">
2387       <xsl:attribute name="RadiusY">
2388         <xsl:value-of select="@ry" />
2389       </xsl:attribute>
2390     </xsl:if>
2391     <xsl:if test="@rx and not(@ry)">
2392       <xsl:attribute name="RadiusX">
2393         <xsl:value-of select="@rx" />
2394       </xsl:attribute>
2395       <xsl:attribute name="RadiusY">
2396         <xsl:value-of select="@rx" />
2397       </xsl:attribute>
2398     </xsl:if>
2399     <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>
2401     <xsl:apply-templates mode="id" select="." />
2402     <xsl:apply-templates mode="template_fill" select="." />
2403     <xsl:apply-templates mode="template_stroke" select="." />
2404     <xsl:apply-templates mode="stroke_miterlimit" select="." />
2405     <xsl:apply-templates mode="stroke_dasharray" select="." />
2406     <xsl:apply-templates mode="stroke_dashoffset" select="." />
2407     <xsl:apply-templates mode="stroke_linejoin" select="." />
2408     <xsl:apply-templates mode="stroke_linecap" select="." />
2409     <xsl:apply-templates mode="filter_effect" select="." />
2410     <xsl:apply-templates mode="resources" select="." />
2411     <xsl:apply-templates mode="object_opacity" select="." />
2412     <xsl:apply-templates mode="desc" select="." />
2413     <xsl:apply-templates mode="clip" select="." />
2415     <xsl:apply-templates mode="transform" select=".">
2416       <xsl:with-param name="mapped_type" select="'Rectangle'" />
2417     </xsl:apply-templates>
2419     <xsl:apply-templates mode="forward" />
2420   </Rectangle>
2421 </xsl:template>
2423 <!-- 
2424   // Polygon object //
2425   SVG: polygon, XAML: Polygon
2426 -->
2427 <xsl:template mode="forward" match="*[name(.) = 'polygon']">
2428   <Polygon>
2429     <xsl:if test="@points"><xsl:attribute name="Points"><xsl:value-of select="@points" /></xsl:attribute></xsl:if>
2430     <xsl:apply-templates mode="id" select="." />
2431     <xsl:apply-templates mode="fill_rule" select="." />
2432     <xsl:apply-templates mode="template_fill" select="." />
2433     <xsl:apply-templates mode="template_stroke" select="." />
2434     <xsl:apply-templates mode="stroke_miterlimit" select="." />
2435     <xsl:apply-templates mode="stroke_dasharray" select="." />
2436     <xsl:apply-templates mode="stroke_dashoffset" select="." />
2437     <xsl:apply-templates mode="stroke_linejoin" select="." />
2438     <xsl:apply-templates mode="stroke_linecap" select="." />
2439     <xsl:apply-templates mode="filter_effect" select="." />
2440     <xsl:apply-templates mode="object_opacity" select="." />
2441     <xsl:apply-templates mode="desc" select="." />
2442     <xsl:apply-templates mode="resources" select="." />
2444     <xsl:apply-templates mode="transform" select=".">
2445       <xsl:with-param name="mapped_type" select="'Polygon'" />
2446     </xsl:apply-templates>
2448     <xsl:apply-templates mode="forward" />
2449   </Polygon>
2450 </xsl:template>
2452 <!-- 
2453   // Polyline object //
2454   SVG: polyline, XAML: Polyline
2455 -->
2456 <xsl:template mode="forward" match="*[name(.) = 'polyline']">
2457   <Polyline>
2458     <xsl:if test="@points"><xsl:attribute name="Points"><xsl:value-of select="@points" /></xsl:attribute></xsl:if>
2459     <xsl:apply-templates mode="id" select="." />
2460     <xsl:apply-templates mode="fill_rule" select="." />
2461     <xsl:apply-templates mode="template_fill" select="." />
2462     <xsl:apply-templates mode="template_stroke" select="." />
2463     <xsl:apply-templates mode="stroke_miterlimit" select="." />
2464     <xsl:apply-templates mode="stroke_dasharray" select="." />
2465     <xsl:apply-templates mode="stroke_dashoffset" select="." />
2466     <xsl:apply-templates mode="stroke_linejoin" select="." />
2467     <xsl:apply-templates mode="stroke_linecap" select="." />
2468     <xsl:apply-templates mode="filter_effect" select="." />
2469     <xsl:apply-templates mode="object_opacity" select="." />
2470     <xsl:apply-templates mode="desc" select="." />
2472     <xsl:apply-templates mode="transform" select=".">
2473       <xsl:with-param name="mapped_type" select="'Polyline'" />
2474     </xsl:apply-templates>
2476     <xsl:apply-templates mode="forward" />
2477   </Polyline>
2478 </xsl:template>
2480 <!-- 
2481   // Path //
2482   SVG: path, XAML: Path
2483 -->
2484 <xsl:template mode="forward" match="*[name(.) = 'path']">
2485   <Path>
2486     <xsl:apply-templates mode="id" select="." />
2487     <xsl:apply-templates mode="template_fill" select="." />
2488     <xsl:apply-templates mode="template_stroke" select="." />
2489     <xsl:apply-templates mode="stroke_miterlimit" select="." />
2490     <xsl:apply-templates mode="stroke_dasharray" select="." />
2491     <xsl:apply-templates mode="stroke_dashoffset" select="." />
2492     <xsl:apply-templates mode="stroke_linejoin" select="." />
2493     <xsl:apply-templates mode="stroke_linecap" select="." />
2494     <xsl:apply-templates mode="filter_effect" select="." />
2495     <xsl:apply-templates mode="object_opacity" select="." />
2496     <xsl:apply-templates mode="desc" select="." />
2497     <xsl:apply-templates mode="resources" select="." />
2499     <xsl:if test="@d">
2500       <xsl:choose>
2501         <xsl:when test="$silverlight_compatible = 1">
2502           <xsl:attribute name="Data">
2503             <xsl:value-of select="translate(@d , ',', ' ')" />
2504           </xsl:attribute>
2505         </xsl:when>
2506         <xsl:otherwise>
2507           <Path.Data>
2508             <PathGeometry>
2509               <xsl:attribute name="Figures">
2510                 <xsl:value-of select="translate(@d , ',', ' ')" />
2511               </xsl:attribute>
2512               <xsl:apply-templates mode="fill_rule" select="." />
2513             </PathGeometry>
2514           </Path.Data>
2515          </xsl:otherwise>
2516       </xsl:choose>
2517     </xsl:if>
2519     <xsl:apply-templates mode="transform" select=".">
2520       <xsl:with-param name="mapped_type" select="'Path'" />
2521     </xsl:apply-templates>
2523     <xsl:apply-templates mode="forward" />
2524   </Path>
2525 </xsl:template>
2527 <!-- 
2528   // Ellipse object //
2529   SVG: ellipse, XAML: Ellipse
2530 -->
2531 <xsl:template mode="forward" match="*[name(.) = 'ellipse']">
2532   <Ellipse>
2533     <xsl:variable name="cx">
2534       <xsl:choose>
2535         <xsl:when test="@cx"><xsl:value-of select="@cx" /></xsl:when>
2536         <xsl:otherwise>0</xsl:otherwise>
2537       </xsl:choose>
2538     </xsl:variable>
2539     <xsl:variable name="cy">
2540       <xsl:choose>
2541         <xsl:when test="@cy"><xsl:value-of select="@cy" /></xsl:when>
2542         <xsl:otherwise>0</xsl:otherwise>
2543       </xsl:choose>
2544     </xsl:variable>
2545     <xsl:if test="@rx">
2546       <xsl:attribute name="Canvas.Left"><xsl:value-of select='format-number($cx - @rx, "#.#")' /></xsl:attribute>
2547       <xsl:attribute name="Width"><xsl:value-of select='format-number(2 * @rx, "#.#")' /></xsl:attribute>
2548     </xsl:if>
2549     <xsl:if test="@ry">
2550       <xsl:attribute name="Canvas.Top"><xsl:value-of select='format-number($cy - @ry, "#.#")' /></xsl:attribute>
2551       <xsl:attribute name="Height"><xsl:value-of select='format-number(2 * @ry, "#.#")' /></xsl:attribute>
2552     </xsl:if>
2553     <xsl:apply-templates mode="id" select="." />
2554     <xsl:apply-templates mode="template_fill" select="." />
2555     <xsl:apply-templates mode="template_stroke" select="." />
2556     <xsl:apply-templates mode="stroke_miterlimit" select="." />
2557     <xsl:apply-templates mode="stroke_dasharray" select="." />
2558     <xsl:apply-templates mode="stroke_dashoffset" select="." />
2559     <xsl:apply-templates mode="stroke_linejoin" select="." />
2560     <xsl:apply-templates mode="stroke_linecap" select="." />
2561     <xsl:apply-templates mode="filter_effect" select="." />
2562     <xsl:apply-templates mode="object_opacity" select="." />
2563     <xsl:apply-templates mode="desc" select="." />
2564     <xsl:apply-templates mode="resources" select="." />
2565     <xsl:apply-templates mode="clip" select="." />
2567     <xsl:apply-templates mode="transform" select=".">
2568       <xsl:with-param name="mapped_type" select="'Ellipse'" />
2569     </xsl:apply-templates>
2571     <xsl:apply-templates mode="forward" />
2572   </Ellipse>
2573 </xsl:template>
2575 <!-- 
2576   // Circle object //
2577   SVG: circle, XAML: Ellipse
2578 -->
2579 <xsl:template mode="forward" match="*[name(.) = 'circle']">
2580   <Ellipse>
2581     <xsl:variable name="cx">
2582       <xsl:choose>
2583         <xsl:when test="@cx"><xsl:value-of select="@cx" /></xsl:when>
2584         <xsl:otherwise>0</xsl:otherwise>
2585       </xsl:choose>
2586     </xsl:variable>
2587     <xsl:variable name="cy">
2588       <xsl:choose>
2589         <xsl:when test="@cy"><xsl:value-of select="@cy" /></xsl:when>
2590         <xsl:otherwise>0</xsl:otherwise>
2591       </xsl:choose>
2592     </xsl:variable>
2593     <xsl:if test="@r">
2594        <xsl:attribute name="Canvas.Left"><xsl:value-of select='format-number($cx - @r, "#.#")' /></xsl:attribute>
2595        <xsl:attribute name="Canvas.Top"><xsl:value-of select='format-number($cy - @r, "#.#")' /></xsl:attribute>
2596        <xsl:attribute name="Width"><xsl:value-of select='format-number(2 * @r, "#.#")' /></xsl:attribute>
2597        <xsl:attribute name="Height"><xsl:value-of select='format-number(2 * @r, "#.#")' /></xsl:attribute>
2598     </xsl:if>
2599     <xsl:apply-templates mode="id" select="." />
2600     <xsl:apply-templates mode="template_fill" select="." />
2601     <xsl:apply-templates mode="template_stroke" select="." />
2602     <xsl:apply-templates mode="stroke_miterlimit" select="." />
2603     <xsl:apply-templates mode="stroke_dasharray" select="." />
2604     <xsl:apply-templates mode="stroke_dashoffset" select="." />
2605     <xsl:apply-templates mode="stroke_linejoin" select="." />
2606     <xsl:apply-templates mode="stroke_linecap" select="." />
2607     <xsl:apply-templates mode="filter_effect" select="." />
2608     <xsl:apply-templates mode="object_opacity" select="." />
2609     <xsl:apply-templates mode="desc" select="." />
2610     <xsl:apply-templates mode="resources" select="." />
2611     <xsl:apply-templates mode="clip" select="." />
2613     <xsl:apply-templates mode="transform" select=".">
2614       <xsl:with-param name="mapped_type" select="'Ellipse'" />
2615     </xsl:apply-templates>
2617     <xsl:apply-templates mode="forward" />
2618   </Ellipse>
2619 </xsl:template>
2621 <!-- 
2622   // Image object//
2623   SVG: image, FXG: Image
2624 -->
2625 <xsl:template mode="forward" match="*[name(.) = 'image']">
2626   <Image>
2627     <xsl:apply-templates mode="id" select="." />
2628     <xsl:if test="@x">
2629       <xsl:attribute name="Canvas.Left">
2630         <xsl:call-template name="convert_unit">
2631           <xsl:with-param name="convert_value" select="@x" />
2632         </xsl:call-template>
2633       </xsl:attribute>
2634     </xsl:if>
2635     <xsl:if test="@y">
2636       <xsl:attribute name="Canvas.Top">
2637         <xsl:call-template name="convert_unit">
2638           <xsl:with-param name="convert_value" select="@y" />
2639         </xsl:call-template>
2640       </xsl:attribute>
2641     </xsl:if>
2642     <xsl:apply-templates mode="desc" select="." />
2643     <xsl:apply-templates mode="clip" select="." />
2644     <xsl:if test="@xlink:href">
2645       <xsl:attribute name="Source">
2646         <xsl:value-of select="@xlink:href" />
2647       </xsl:attribute>
2648     </xsl:if>
2649     <xsl:if test="@width">
2650       <xsl:attribute name="Width">
2651         <xsl:call-template name="convert_unit">
2652           <xsl:with-param name="convert_value" select="@width" />
2653         </xsl:call-template>
2654       </xsl:attribute>
2655     </xsl:if>
2656     <xsl:if test="@height">
2657       <xsl:attribute name="Height">
2658         <xsl:call-template name="convert_unit">
2659           <xsl:with-param name="convert_value" select="@height" />
2660         </xsl:call-template>
2661       </xsl:attribute>
2662     </xsl:if>
2663     
2664     <xsl:apply-templates mode="image_stretch" select="." />
2665     <xsl:apply-templates mode="object_opacity" select="." />
2666     <xsl:apply-templates mode="resources" select="." />
2667     
2668     <xsl:apply-templates mode="transform" select=".">
2669       <xsl:with-param name="mapped_type" select="'Image'" />
2670     </xsl:apply-templates>
2671     <xsl:apply-templates mode="forward" />
2672   </Image>
2673 </xsl:template>
2675 <!--
2676 // Geometry //
2677 * Generic clip path template
2678 * Geometry for circle
2679 * Geometry for rectangle
2680 -->
2682 <!-- Generic clip path template -->
2683 <xsl:template mode="forward" match="*[name(.) = 'clipPath']">
2684   <xsl:apply-templates mode="geometry" />
2685 </xsl:template>
2687 <!-- Geometry for circle -->
2688 <xsl:template mode="geometry" match="*[name(.) = 'circle']">
2689   <EllipseGeometry>
2690     <xsl:if test="../@id"><xsl:attribute name="x:Key"><xsl:value-of select="../@id" /></xsl:attribute></xsl:if>
2691     <xsl:if test="@cx and @cy"><xsl:attribute name="Center"><xsl:value-of select="concat(@cx, ',', @cy)" /></xsl:attribute></xsl:if>
2692     <xsl:if test="@r">
2693       <xsl:attribute name="RadiusX"><xsl:value-of select="@r" /></xsl:attribute>
2694       <xsl:attribute name="RadiusY"><xsl:value-of select="@r" /></xsl:attribute>
2695     </xsl:if>
2696   </EllipseGeometry>
2697 </xsl:template>
2699 <!-- Geometry for rectangle -->
2700 <xsl:template mode="geometry" match="*[name(.) = 'rect']">
2701   <RectangleGeometry>
2702     <xsl:if test="../@id"><xsl:attribute name="x:Key"><xsl:value-of select="../@id" /></xsl:attribute></xsl:if>
2703     <!--
2704     <xsl:if test="@x"><xsl:attribute name="Canvas.Left"><xsl:value-of select="@x" /></xsl:attribute></xsl:if>
2705     <xsl:if test="@y"><xsl:attribute name="Canvas.Top"><xsl:value-of select="@y" /></xsl:attribute></xsl:if>
2706     <xsl:if test="@width"><xsl:attribute name="Width"><xsl:value-of select="@width" /></xsl:attribute></xsl:if>
2707     <xsl:if test="@height"><xsl:attribute name="Height"><xsl:value-of select="@height" /></xsl:attribute></xsl:if>
2708     <xsl:if test="@rx"><xsl:attribute name="RadiusX"><xsl:value-of select="@rx" /></xsl:attribute></xsl:if>
2709     <xsl:if test="@ry"><xsl:attribute name="RadiusY"><xsl:value-of select="@ry" /></xsl:attribute></xsl:if>
2710     -->
2711     <xsl:attribute name="Rect"><xsl:value-of select="concat('0, 0, ', @width, ', ', @height)" /></xsl:attribute>
2712   </RectangleGeometry>
2713 </xsl:template>
2715 </xsl:stylesheet>