7569d0db7deadc3a3ee44c1ccf9cd296e3eb0255
1 <?xml version="1.0" encoding="UTF-8"?>
3 <!--
4 Authors:
5 Nicolas Dufour <nicoduf@yahoo.fr>
7 Copyright (c) 2010 authors
9 Released under GNU GPL, read the file 'COPYING' for more information
10 -->
12 <xsl:stylesheet version="1.0"
13 xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
14 xmlns:xlink="http://www.w3.org/1999/xlink"
15 xmlns:xs="http://www.w3.org/2001/XMLSchema"
16 xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
17 xmlns="http://ns.adobe.com/fxg/2008"
18 xmlns:fxg="http://ns.adobe.com/fxg/2008"
19 xmlns:d="http://ns.adobe.com/fxg/2008/dt"
20 xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
21 xmlns:exsl="http://exslt.org/common"
22 xmlns:math="http://exslt.org/math"
23 xmlns:libxslt="http://xmlsoft.org/XSLT/namespace"
24 xmlns:svg="http://www.w3.org/Graphics/SVG/1.1/DTD/svg11-tiny.dtd"
25 exclude-result-prefixes="rdf xlink xs exsl libxslt"
26 extension-element-prefixes="math">
28 <xsl:strip-space elements="*" />
29 <xsl:output method="xml" encoding="UTF-8" indent="yes"/>
31 <!--
32 // Containers //
34 * Root templace
35 * Graphic attributes
36 * Groups
37 -->
39 <!--
40 // Root template //
41 -->
42 <xsl:template match="/">
43 <xsl:apply-templates mode="forward" />
44 </xsl:template>
45 <!--
46 // Graphic //
47 First SVG element is converted to Graphic
48 -->
49 <xsl:template mode="forward" match="/*[name(.) = 'svg']" priority="1">
50 <Graphic>
51 <xsl:attribute name="version">2.0</xsl:attribute>
52 <xsl:if test="@width and not(contains(@width, '%'))">
53 <xsl:attribute name="viewWidth">
54 <xsl:call-template name="convert_unit">
55 <xsl:with-param name="convert_value" select="@width" />
56 </xsl:call-template>
57 </xsl:attribute>
58 </xsl:if>
59 <xsl:if test="@height and not(contains(@height, '%'))">
60 <xsl:attribute name="viewHeight">
61 <xsl:call-template name="convert_unit">
62 <xsl:with-param name="convert_value" select="@height" />
63 </xsl:call-template>
64 </xsl:attribute>
65 </xsl:if>
66 <xsl:if test="@width and not(contains(@width, '%')) and @height and not(contains(@height, '%'))">
67 <mask>
68 <Group>
69 <Rect>
70 <xsl:attribute name="width">
71 <xsl:call-template name="convert_unit">
72 <xsl:with-param name="convert_value" select="@width" />
73 </xsl:call-template>
74 </xsl:attribute>
75 <xsl:attribute name="height">
76 <xsl:call-template name="convert_unit">
77 <xsl:with-param name="convert_value" select="@height" />
78 </xsl:call-template>
79 </xsl:attribute>
80 <fill>
81 <SolidColor color="#ffffff" alpha="1"/>
82 </fill>
83 </Rect>
84 </Group>
85 </mask>
86 </xsl:if>
87 <xsl:apply-templates mode="forward" />
88 </Graphic>
89 </xsl:template>
91 <!--
92 // inner SVG elements //
93 Converted to groups
94 -->
95 <xsl:template mode="forward" match="*[name(.) = 'svg']">
96 <Group>
97 <xsl:if test="@x">
98 <xsl:attribute name="x">
99 <xsl:call-template name="convert_unit">
100 <xsl:with-param name="convert_value" select="@x" />
101 </xsl:call-template>
102 </xsl:attribute>
103 </xsl:if>
104 <xsl:if test="@y">
105 <xsl:attribute name="y">
106 <xsl:call-template name="convert_unit">
107 <xsl:with-param name="convert_value" select="@y" />
108 </xsl:call-template>
109 </xsl:attribute>
110 </xsl:if>
111 <xsl:if test="@width and not(contains(@width, '%')) and @height and not(contains(@height, '%'))">
112 <xsl:attribute name="maskType"><xsl:value-of select="'clip'"/></xsl:attribute>
113 <mask>
114 <Group>
115 <Rect>
116 <xsl:attribute name="width">
117 <xsl:call-template name="convert_unit">
118 <xsl:with-param name="convert_value" select="@width" />
119 </xsl:call-template>
120 </xsl:attribute>
121 <xsl:attribute name="height">
122 <xsl:call-template name="convert_unit">
123 <xsl:with-param name="convert_value" select="@height" />
124 </xsl:call-template>
125 </xsl:attribute>
126 <fill>
127 <SolidColor color="#ffffff" alpha="1"/>
128 </fill>
129 </Rect>
130 </Group>
131 </mask>
132 </xsl:if>
133 <xsl:apply-templates mode="forward" />
134 </Group>
135 </xsl:template>
137 <!--
138 // Groups //
139 (including layers)
141 FXG's Group doesn't support other elements attributes (such as font-size, etc.)
142 -->
143 <xsl:template mode="forward" match="*[name(.) = 'g']">
144 <xsl:variable name="object">
145 <Group>
146 <xsl:if test="@style and contains(@style, 'display:none')">
147 <xsl:attribute name="Visibility">Collapsed</xsl:attribute>
148 </xsl:if>
149 <xsl:if test="@width and not(contains(@width, '%'))">
150 <xsl:attribute name="width">
151 <xsl:call-template name="convert_unit">
152 <xsl:with-param name="convert_value" select="@width" />
153 </xsl:call-template>
154 </xsl:attribute>
155 </xsl:if>
156 <xsl:if test="@height and not(contains(@height, '%'))">
157 <xsl:attribute name="height">
158 <xsl:call-template name="convert_unit">
159 <xsl:with-param name="convert_value" select="@height" />
160 </xsl:call-template>
161 </xsl:attribute>
162 </xsl:if>
163 <xsl:if test="@x">
164 <xsl:attribute name="x">
165 <xsl:call-template name="convert_unit">
166 <xsl:with-param name="convert_value" select="@x" />
167 </xsl:call-template>
168 </xsl:attribute>
169 </xsl:if>
170 <xsl:if test="@y">
171 <xsl:attribute name="y">
172 <xsl:call-template name="convert_unit">
173 <xsl:with-param name="convert_value" select="@y" />
174 </xsl:call-template>
175 </xsl:attribute>
176 </xsl:if>
177 <xsl:apply-templates mode="object_opacity" select="." />
178 <xsl:apply-templates mode="id" select="." />
180 <xsl:apply-templates mode="layer_blend" select="." />
181 <xsl:apply-templates mode="filter_effect" select="." />
182 <xsl:apply-templates mode="forward" select="*" />
183 </Group>
184 </xsl:variable>
186 <xsl:variable name="clipped_object">
187 <xsl:apply-templates mode="clip" select="." >
188 <xsl:with-param name="object" select="$object" />
189 <xsl:with-param name="clip_type" select="'clip'" />
190 </xsl:apply-templates>
191 </xsl:variable>
193 <xsl:variable name="masked_object">
194 <xsl:apply-templates mode="clip" select="." >
195 <xsl:with-param name="object" select="$clipped_object" />
196 <xsl:with-param name="clip_type" select="'mask'" />
197 </xsl:apply-templates>
198 </xsl:variable>
200 <xsl:choose>
201 <xsl:when test="@transform">
202 <Group>
203 <xsl:call-template name="object_transform">
204 <xsl:with-param name="object" select="$masked_object" />
205 <xsl:with-param name="transform" select="@transform" />
206 </xsl:call-template>
207 </Group>
208 </xsl:when>
209 <xsl:otherwise>
210 <xsl:copy-of select="$masked_object" />
211 </xsl:otherwise>
212 </xsl:choose>
213 </xsl:template>
215 <!--
216 // Transforms //
217 All the matrix, translate, rotate... stuff.
218 * Parse objects transform
219 * Object transform
220 * Parse gradient transform
221 * Gradient transform
223 Not supported by FXG:
224 * Skew transform.
225 * Multiple values rotation.
226 -->
228 <!--
229 // Parse object transform //
230 -->
231 <xsl:template name="parse_object_transform">
232 <xsl:param name="input" />
233 <xsl:choose>
234 <!-- Matrix transform -->
235 <xsl:when test="starts-with($input, 'matrix(')">
236 <transform>
237 <Transform>
238 <matrix>
239 <Matrix>
240 <xsl:variable name="matrix" select="normalize-space(translate(substring-before(substring-after($input, 'matrix('), ')'), ',', ' '))" />
241 <xsl:variable name="a" select="substring-before($matrix, ' ')"/>
242 <xsl:variable name="ra" select="substring-after($matrix, ' ')"/>
243 <xsl:variable name="b" select="substring-before($ra, ' ')"/>
244 <xsl:variable name="rb" select="substring-after($ra, ' ')"/>
245 <xsl:variable name="c" select="substring-before($rb, ' ')"/>
246 <xsl:variable name="rc" select="substring-after($rb, ' ')"/>
247 <xsl:variable name="d" select="substring-before($rc, ' ')"/>
248 <xsl:variable name="rd" select="substring-after($rc, ' ')"/>
249 <xsl:variable name="tx" select="substring-before($rd, ' ')"/>
250 <xsl:variable name="ty" select="substring-after($rd, ' ')"/>
251 <xsl:attribute name="a"><xsl:value-of select="$a" /></xsl:attribute>
252 <xsl:attribute name="b"><xsl:value-of select="$b" /></xsl:attribute>
253 <xsl:attribute name="c"><xsl:value-of select="$c" /></xsl:attribute>
254 <xsl:attribute name="d"><xsl:value-of select="$d" /></xsl:attribute>
255 <xsl:attribute name="tx"><xsl:value-of select='format-number($tx, "#.##")' /></xsl:attribute>
256 <xsl:attribute name="ty"><xsl:value-of select='format-number($ty, "#.##")' /></xsl:attribute>
257 </Matrix>
258 </matrix>
259 </Transform>
260 </transform>
261 </xsl:when>
263 <!-- Scale transform -->
264 <xsl:when test="starts-with($input, 'scale(')">
265 <xsl:variable name="scale" select="normalize-space(translate(substring-before(substring-after($input, 'scale('), ')'), ',', ' '))" />
266 <xsl:choose>
267 <xsl:when test="contains($scale, ' ')">
268 <xsl:attribute name="scaleX">
269 <xsl:value-of select="substring-before($scale, ' ')" />
270 </xsl:attribute>
271 <xsl:attribute name="scaleY">
272 <xsl:value-of select="substring-after($scale, ' ')" />
273 </xsl:attribute>
274 </xsl:when>
275 <xsl:otherwise>
276 <xsl:attribute name="scaleX">
277 <xsl:value-of select="$scale" />
278 </xsl:attribute>
279 <xsl:attribute name="scaleY">
280 <xsl:value-of select="$scale" />
281 </xsl:attribute>
282 </xsl:otherwise>
283 </xsl:choose>
284 </xsl:when>
286 <!-- Rotate transform -->
287 <xsl:when test="starts-with($input, 'rotate(')">
288 <xsl:variable name="rotate" select="normalize-space(translate(substring-before(substring-after($input, 'rotate('), ')'), ',', ' '))" />
289 <xsl:attribute name="rotation">
290 <xsl:choose>
291 <xsl:when test="contains($rotate, ' ')">
292 <xsl:value-of select="substring-before($rotate, ' ')" />
293 </xsl:when>
294 <xsl:otherwise>
295 <xsl:value-of select="$rotate" />
296 </xsl:otherwise>
297 </xsl:choose>
298 </xsl:attribute>
299 <xsl:if test="@rx">
300 <xsl:attribute name="CenterX">
301 <xsl:value-of select="@rx" />
302 </xsl:attribute>
303 </xsl:if>
304 <xsl:if test="@ry">
305 <xsl:attribute name="CenterY">
306 <xsl:value-of select="@ry" />
307 </xsl:attribute>
308 </xsl:if>
309 </xsl:when>
311 <!-- Translate transform -->
312 <xsl:when test="starts-with($input, 'translate(')">
313 <xsl:variable name="translate" select="normalize-space(translate(substring-before(substring-after($input, 'translate('), ')'), ',', ' '))" />
314 <xsl:choose>
315 <xsl:when test="contains($translate, ' ')">
316 <xsl:attribute name="x">
317 <xsl:value-of select="substring-before($translate, ' ')" />
318 </xsl:attribute>
319 <xsl:attribute name="y">
320 <xsl:value-of select="substring-after($translate, ' ')" />
321 </xsl:attribute>
322 </xsl:when>
323 <xsl:otherwise>
324 <xsl:attribute name="x">
325 <xsl:value-of select="$translate" />
326 </xsl:attribute>
327 </xsl:otherwise>
328 </xsl:choose>
329 </xsl:when>
330 </xsl:choose>
331 </xsl:template>
333 <!--
334 // Object transform //
335 FXG needs a separate group for each transform type in the transform attribute (scale+translate != translate+scale)
336 -->
337 <xsl:template name="object_transform">
338 <xsl:param name="object" />
339 <xsl:param name="transform" />
341 <xsl:variable name="values" select="normalize-space(translate($transform, ',', ' '))" />
342 <xsl:choose>
343 <xsl:when test="contains($values, ') ')">
344 <xsl:call-template name="parse_object_transform">
345 <xsl:with-param name="input" select="concat(substring-before($values, ') '), ')')" />
346 </xsl:call-template>
347 <xsl:variable name="values2" select="substring-after($values, ') ')" />
348 <Group>
349 <xsl:choose>
350 <xsl:when test="contains($values2, ') ')">
351 <xsl:call-template name="parse_object_transform">
352 <xsl:with-param name="input" select="concat(substring-before($values2, ') '), ')')" />
353 </xsl:call-template>
354 <xsl:variable name="values3" select="substring-after($values2, ') ')" />
355 <Group>
356 <xsl:call-template name="parse_object_transform">
357 <xsl:with-param name="input" select="concat($values3, ')')" />
358 </xsl:call-template>
359 <xsl:copy-of select="$object" />
360 </Group>
361 </xsl:when>
362 <xsl:otherwise>
363 <xsl:call-template name="parse_object_transform">
364 <xsl:with-param name="input" select="$values2" />
365 </xsl:call-template>
366 <xsl:copy-of select="$object" />
367 </xsl:otherwise>
368 </xsl:choose>
369 </Group>
370 </xsl:when>
371 <xsl:otherwise>
372 <xsl:call-template name="parse_object_transform">
373 <xsl:with-param name="input" select="$values" />
374 </xsl:call-template>
375 <xsl:copy-of select="$object" />
376 </xsl:otherwise>
377 </xsl:choose>
378 </xsl:template>
380 <!--
381 // Parse gradient transform //
382 -->
383 <xsl:template name="parse_gradient_transform">
384 <xsl:param name="input" />
385 <xsl:param name="type" />
386 <xsl:choose>
387 <!-- Scale transform -->
388 <xsl:when test="starts-with($input, 'scale(')">
389 <xsl:variable name="scale" select="normalize-space(translate(substring-before(substring-after($input, 'scale('), ')'), ',', ' '))" />
390 <xsl:choose>
391 <xsl:when test="$type='radial'">
392 <xsl:choose>
393 <xsl:when test="contains($scale, ' ')">
394 <xsl:attribute name="scaleX">
395 <xsl:value-of select="substring-before($scale, ' ')" />
396 </xsl:attribute>
397 <xsl:attribute name="scaleY">
398 <xsl:value-of select="substring-after($scale, ' ')" />
399 </xsl:attribute>
400 </xsl:when>
401 <xsl:otherwise>
402 <xsl:attribute name="scaleX">
403 <xsl:value-of select="$scale" />
404 </xsl:attribute>
405 <xsl:attribute name="scaleY">
406 <xsl:value-of select="$scale" />
407 </xsl:attribute>
408 </xsl:otherwise>
409 </xsl:choose>
410 </xsl:when>
411 <xsl:otherwise>
412 <xsl:attribute name="scaleX">
413 <xsl:value-of select="$scale" />
414 </xsl:attribute>
415 </xsl:otherwise>
416 </xsl:choose>
417 </xsl:when>
419 <!-- Rotate transform -->
420 <xsl:when test="starts-with($input, 'rotate(')">
421 <xsl:variable name="rotate" select="normalize-space(translate(substring-before(substring-after($input, 'rotate('), ')'), ',', ' '))" />
422 <xsl:attribute name="rotation">
423 <xsl:choose>
424 <xsl:when test="contains($rotate, ' ')">
425 <xsl:value-of select="substring-before($rotate, ' ')" />
426 </xsl:when>
427 <xsl:otherwise>
428 <xsl:value-of select="$rotate" />
429 </xsl:otherwise>
430 </xsl:choose>
431 </xsl:attribute>
432 </xsl:when>
434 <!-- Translate transform -->
435 <xsl:when test="starts-with($input, 'translate(')">
436 <xsl:variable name="translate" select="normalize-space(translate(substring-before(substring-after($input, 'translate('), ')'), ',', ' '))" />
437 <xsl:choose>
438 <xsl:when test="contains($translate, ' ')">
439 <xsl:attribute name="x">
440 <xsl:value-of select="substring-before($translate, ' ')" />
441 </xsl:attribute>
442 <xsl:attribute name="y">
443 <xsl:value-of select="substring-after($translate, ' ')" />
444 </xsl:attribute>
445 </xsl:when>
446 <xsl:otherwise>
447 <xsl:attribute name="x">
448 <xsl:value-of select="$translate" />
449 </xsl:attribute>
450 </xsl:otherwise>
451 </xsl:choose>
452 </xsl:when>
453 </xsl:choose>
454 </xsl:template>
456 <!--
457 // Gradient transform //
458 Not implemented yet
459 Gradient positioning and tranformation are very different in FXG
460 -->
461 <xsl:template name="gradient_transform">
462 <xsl:param name="transform" />
463 <xsl:param name="type" />
465 <xsl:if test="contains($transform, 'translate')">
466 <xsl:call-template name="parse_gradient_transform">
467 <xsl:with-param name="input" select="concat('translate(', substring-before(substring-after($transform, 'translate('), ')'), ')')" />
468 <xsl:with-param name="type" select="$type" />
469 </xsl:call-template>
470 </xsl:if>
471 </xsl:template>
473 <!--
474 // Resources (defs) //
476 * Resources ids
477 * Generic defs template
478 * Defs gradients
479 * Layers blend mode
480 * Generic filters template
481 * Filter effects
482 * Linked filter effects
483 * Linear gradients
484 * Radial gradients
485 * Gradient stops list
486 * Gradient stop
487 * Clipping
488 -->
490 <!--
491 // Resources ids //
492 -->
493 <xsl:template mode="resources" match="*">
494 <!-- should be in-depth -->
495 <xsl:if test="ancestor::*[name(.) = 'defs']"><xsl:attribute name="id"><xsl:value-of select="@id" /></xsl:attribute></xsl:if>
496 </xsl:template>
498 <!--
499 // Generic defs template //
500 -->
501 <xsl:template mode="forward" match="defs">
502 <!-- Ignoring defs, do nothing
503 <xsl:apply-templates mode="forward" />
504 -->
505 </xsl:template>
507 <!--
508 // Defs gradients //
509 ignored
510 -->
511 <xsl:template mode="forward" match="*[name(.) = 'linearGradient' or name(.) = 'radialGradient']">
513 </xsl:template>
515 <!--
516 // Layers blend mode //
518 Partial support
519 Looks good with normal, multiply, and darken
520 -->
521 <xsl:template mode="layer_blend" match="*">
522 <xsl:if test="@inkscape:groupmode='layer' and @style and contains(@style, 'filter:url(#')">
523 <xsl:variable name="id" select="substring-before(substring-after(@style, 'filter:url(#'), ')')" />
524 <xsl:for-each select="//*[@id=$id]">
525 <xsl:if test="name(child::node()) = 'feBlend'">
526 <xsl:attribute name="blendMode">
527 <xsl:value-of select="child::node()/@mode"/>
528 </xsl:attribute>
529 </xsl:if>
530 </xsl:for-each>
531 </xsl:if>
532 </xsl:template>
534 <!--
535 // Generic filters template //
536 Limited to one filter (can be improved)
537 -->
538 <xsl:template mode="forward" match="*[name(.) = 'filter']">
539 <xsl:if test="count(*) = 1">
540 <xsl:apply-templates mode="forward" />
541 </xsl:if>
542 </xsl:template>
544 <!--
545 // GaussianBlur filter effects //
546 Blur values approximated with d = floor(s * 3*sqrt(2*pi)/4 + 0.5) from:
547 http://www.w3.org/TR/SVG/filters.html#feGaussianBlurElement
548 Blur quality=2 recommended by the FXG specifications:
549 http://opensource.adobe.com/wiki/display/flexsdk/FXG+2.0+Specification#FXG2.0Specification-FilterEffects
550 -->
551 <xsl:template mode="forward" match="*[name(.) = 'feGaussianBlur']">
552 <xsl:if test="name(.)='feGaussianBlur'">
553 <filters>
554 <BlurFilter>
555 <xsl:attribute name="quality">2</xsl:attribute>
556 <xsl:if test="@stdDeviation">
557 <xsl:variable name="blur" select="normalize-space(translate(@stdDeviation, ',', ' '))" />
558 <xsl:choose>
559 <xsl:when test="not(contains($blur, ' '))">
560 <xsl:attribute name="blurX">
561 <xsl:value-of select="floor($blur * 1.88 + 0.5)" />
562 </xsl:attribute>
563 <xsl:attribute name="blurY">
564 <xsl:value-of select="floor($blur * 1.88 + 0.5)" />
565 </xsl:attribute>
566 </xsl:when>
567 <xsl:otherwise>
568 <xsl:attribute name="blurX">
569 <xsl:value-of select="floor(substring-before($blur, ' ') * 1.88 + 0.5)" />
570 </xsl:attribute>
571 <xsl:attribute name="blurY">
572 <xsl:value-of select="floor(substring-after($blur, ' ') * 1.88 + 0.5)" />
573 </xsl:attribute>
574 </xsl:otherwise>
575 </xsl:choose>
576 </xsl:if>
577 </BlurFilter>
578 </filters>
579 </xsl:if>
580 </xsl:template>
582 <!--
583 // Linked filter effect //
584 Only supports blurs
585 -->
586 <xsl:template mode="filter_effect" match="*">
587 <xsl:variable name="id">
588 <xsl:choose>
589 <xsl:when test="@filter and starts-with(@filter, 'url(#')">
590 <xsl:value-of select="substring-before(substring-after(@filter, 'url(#'), ')')" />
591 </xsl:when>
592 <xsl:when test="@style and contains(@style, 'filter:url(#')">
593 <xsl:value-of select="substring-before(substring-after(@style, 'filter:url(#'), ')')" />
594 </xsl:when>
595 </xsl:choose>
596 </xsl:variable>
598 <xsl:for-each select="//*[@id=$id]">
599 <xsl:apply-templates mode="forward" />
600 </xsl:for-each>
601 </xsl:template>
603 <!--
604 // Linear gradient //
605 Full convertion to FXG would require some math.
606 -->
607 <xsl:template name="linearGradient">
608 <xsl:param name="id" />
609 <xsl:for-each select="//*[@id=$id]">
610 <xsl:if test="@id">
611 <xsl:attribute name="id">
612 <xsl:value-of select="@id" />
613 </xsl:attribute>
614 </xsl:if>
615 <xsl:if test="@spreadMethod">
616 <xsl:attribute name="spreadMethod">
617 <xsl:choose>
618 <xsl:when test="@spreadMethod = 'pad'">pad</xsl:when>
619 <xsl:when test="@spreadMethod = 'reflect'">reflect</xsl:when>
620 <xsl:when test="@spreadMethod = 'repeat'">repeat</xsl:when>
621 </xsl:choose>
622 </xsl:attribute>
623 </xsl:if>
624 <xsl:if test="@color-interpolation">
625 <xsl:attribute name="interpolationMethod">
626 <xsl:choose>
627 <xsl:when test="@color-interpolation = 'linearRGB'">linearRGB</xsl:when>
628 <xsl:otherwise>rgb</xsl:otherwise>
629 </xsl:choose>
630 </xsl:attribute>
631 </xsl:if>
632 <xsl:if test="@x1 and @x2 and @y1 and @y2 and function-available('math:atan')">
633 <xsl:attribute name="rotation">
634 <xsl:value-of select="57.3 * math:atan((@y2 - @y1) div (@x2 - @x1))" />
635 </xsl:attribute>
636 </xsl:if>
637 <xsl:if test="@gradientTransform">
638 <xsl:call-template name="gradient_transform">
639 <xsl:with-param name="transform" select="@gradientTransform" />
640 <xsl:with-param name="type" select="linear" />
641 </xsl:call-template>
642 </xsl:if>
643 <xsl:choose>
644 <xsl:when test="@xlink:href">
645 <xsl:variable name="reference_id" select="@xlink:href" />
646 <xsl:call-template name="gradientStops" >
647 <xsl:with-param name="id">
648 <xsl:value-of select="substring-after($reference_id, '#')" />
649 </xsl:with-param>
650 </xsl:call-template>
651 </xsl:when>
652 <xsl:otherwise><xsl:apply-templates mode="forward" /></xsl:otherwise>
653 </xsl:choose>
654 </xsl:for-each>
655 </xsl:template>
657 <!--
658 // Radial gradient //
660 Full convertion to FXG would require some math.
661 -->
662 <xsl:template name="radialGradient">
663 <xsl:param name="id" />
664 <xsl:for-each select="//*[@id=$id]">
665 <xsl:if test="@id">
666 <xsl:attribute name="id">
667 <xsl:value-of select="@id" />
668 </xsl:attribute>
669 </xsl:if>
670 <xsl:if test="@spreadMethod">
671 <xsl:attribute name="spreadMethod">
672 <xsl:choose>
673 <xsl:when test="@spreadMethod = 'pad'">pad</xsl:when>
674 <xsl:when test="@spreadMethod = 'reflect'">reflect</xsl:when>
675 <xsl:when test="@spreadMethod = 'repeat'">repeat</xsl:when>
676 </xsl:choose>
677 </xsl:attribute>
678 </xsl:if>
679 <xsl:if test="@color-interpolation">
680 <xsl:attribute name="interpolationMethod">
681 <xsl:choose>
682 <xsl:when test="@color-interpolation = 'linearRGB'">linearRGB</xsl:when>
683 <xsl:otherwise>rgb</xsl:otherwise>
684 </xsl:choose>
685 </xsl:attribute>
686 </xsl:if>
687 <xsl:if test="@gradientTransform">
688 <xsl:call-template name="gradient_transform">
689 <xsl:with-param name="transform" select="@gradientTransform" />
690 <xsl:with-param name="type" select="radial" />
691 </xsl:call-template>
692 </xsl:if>
693 <xsl:choose>
694 <xsl:when test="@xlink:href">
695 <xsl:variable name="reference_id" select="@xlink:href" />
696 <xsl:call-template name="gradientStops" >
697 <xsl:with-param name="id">
698 <xsl:value-of select="substring-after($reference_id, '#')" />
699 </xsl:with-param>
700 </xsl:call-template>
701 </xsl:when>
702 <xsl:otherwise><xsl:apply-templates mode="forward" /></xsl:otherwise>
703 </xsl:choose>
704 </xsl:for-each>
705 </xsl:template>
707 <!--
708 // Gradient stops list //
710 TODO: Find a way to test the existence of the node-set
711 -->
712 <xsl:template name="gradientStops">
713 <xsl:param name="id" />
714 <xsl:variable name="stops">
715 <xsl:for-each select="//*[@id=$id]">
716 <xsl:apply-templates mode="forward" />
717 </xsl:for-each>
718 </xsl:variable>
719 <xsl:choose>
720 <xsl:when test="not($stops)">
721 <GradientEntry>
722 <xsl:attribute name="alpha">0</xsl:attribute>
723 </GradientEntry>
724 </xsl:when>
725 <xsl:otherwise><xsl:copy-of select="$stops" /></xsl:otherwise>
726 </xsl:choose>
727 </xsl:template>
729 <!--
730 // Gradient stop //
731 -->
732 <xsl:template mode="forward" match="*[name(.) = 'stop']">
733 <GradientEntry>
734 <!--xsl:apply-templates mode="stop_opacity" select="." /-->
735 <xsl:apply-templates mode="stop_color" select="." />
736 <xsl:apply-templates mode="offset" select="." />
737 <xsl:apply-templates mode="forward" />
738 </GradientEntry>
739 </xsl:template>
741 <!--
742 // Clipping and masking//
743 -->
744 <xsl:template mode="clip" match="*">
745 <xsl:param name="object" />
746 <xsl:param name="clip_type" />
748 <xsl:choose>
749 <xsl:when test="$clip_type='clip' and @clip-path and contains(@clip-path, 'url')">
750 <Group>
751 <xsl:attribute name="maskType"><xsl:value-of select="'clip'"/></xsl:attribute>
752 <mask>
753 <Group>
754 <xsl:variable name="clip_id" select="substring-before(substring-after(@clip-path, 'url(#'), ')')"/>
755 <xsl:for-each select="//*[@id=$clip_id]">
756 <xsl:if test="not(@clipPathUnits) or @clipPathUnits != 'objectBoundingBox'">
757 <xsl:apply-templates mode="forward" />
758 </xsl:if>
759 </xsl:for-each>
760 </Group>
761 </mask>
762 <xsl:copy-of select="$object"/>
763 </Group>
764 </xsl:when>
765 <xsl:when test="$clip_type='mask' and @mask and contains(@mask, 'url')">
766 <Group>
767 <xsl:attribute name="maskType"><xsl:value-of select="'alpha'"/></xsl:attribute>
768 <mask>
769 <Group>
770 <xsl:variable name="mask_id" select="substring-before(substring-after(@mask, 'url(#'), ')')"/>
771 <xsl:for-each select="//*[@id=$mask_id]">
772 <xsl:if test="not(@maskUnits) or @maskUnits != 'objectBoundingBox'">
773 <xsl:apply-templates mode="forward" />
774 </xsl:if>
775 </xsl:for-each>
776 </Group>
777 </mask>
778 <xsl:copy-of select="$object"/>
779 </Group>
780 </xsl:when>
781 <xsl:otherwise>
782 <xsl:copy-of select="$object" />
783 </xsl:otherwise>
784 </xsl:choose>
785 </xsl:template>
787 <!--
788 // Misc templates //
790 * Id converter
791 * Decimal to hexadecimal converter
792 * Unit to pixel converter
793 * Switch
794 * Unknows tags
795 * Object description (not supported)
796 * Title and description (not supported)
797 * Symbols (not supported)
798 * Use (not supported)
799 * RDF and foreign objects (not supported)
800 * Misc ignored stuff (markers, patterns, styles)
801 -->
803 <!--
804 // Id converter //
805 Removes "-" from the original id
806 (Not sure FXG really needs it)
807 -->
808 <xsl:template mode="id" match="*">
809 <xsl:if test="@id">
810 <xsl:attribute name="id"><xsl:value-of select="translate(@id, '- ', '')" /></xsl:attribute>
811 </xsl:if>
812 </xsl:template>
814 <!--
815 // Decimal to hexadecimal converter //
816 -->
817 <xsl:template name="to_hex">
818 <xsl:param name="convert" />
819 <xsl:value-of select="concat(substring('0123456789ABCDEF', 1 + floor(round($convert) div 16), 1), substring('0123456789ABCDEF', 1 + round($convert) mod 16, 1))" />
820 </xsl:template>
822 <!--
823 // Unit to pixel converter //
824 Values with units (except %) are converted to pixels and rounded.
825 Unknown units are kept.
826 em, ex and % not implemented
827 -->
828 <xsl:template name="convert_unit">
829 <xsl:param name="convert_value" />
830 <xsl:choose>
831 <xsl:when test="contains($convert_value, 'px')">
832 <xsl:value-of select="round(translate($convert_value, 'px', ''))" />
833 </xsl:when>
834 <xsl:when test="contains($convert_value, 'pt')">
835 <xsl:value-of select="round(translate($convert_value, 'pt', '') * 1.25)" />
836 </xsl:when>
837 <xsl:when test="contains($convert_value, 'pc')">
838 <xsl:value-of select="round(translate($convert_value, 'pc', '') * 15)" />
839 </xsl:when>
840 <xsl:when test="contains($convert_value, 'mm')">
841 <xsl:value-of select="round(translate($convert_value, 'mm', '') * 3.543307)" />
842 </xsl:when>
843 <xsl:when test="contains($convert_value, 'cm')">
844 <xsl:value-of select="round(translate($convert_value, 'cm', '') * 35.43307)" />
845 </xsl:when>
846 <xsl:when test="contains($convert_value, 'in')">
847 <xsl:value-of select="round(translate($convert_value, 'in', '') * 90)" />
848 </xsl:when>
849 <xsl:when test="contains($convert_value, 'ft')">
850 <xsl:value-of select="round(translate($convert_value, 'ft', '') * 1080)" />
851 </xsl:when>
852 <xsl:when test="not(string(number($convert_value))='NaN')">
853 <xsl:value-of select="round($convert_value)" />
854 </xsl:when>
855 <xsl:otherwise>
856 <xsl:value-of select="$convert_value" />
857 </xsl:otherwise>
858 </xsl:choose>
859 </xsl:template>
861 <!--
862 // Switch //
863 -->
864 <xsl:template mode="forward" match="*[name(.) = 'switch']">
865 <xsl:apply-templates mode="forward" />
866 </xsl:template>
868 <!--
869 // Unknown tags //
870 With generic and mode="forward" templates
871 -->
872 <xsl:template match="*">
873 <xsl:comment><xsl:value-of select="concat('Unknown tag: ', name(.))" /></xsl:comment>
874 </xsl:template>
876 <xsl:template mode="forward" match="*">
877 <xsl:comment><xsl:value-of select="concat('Unknown tag: ', name(.))" /></xsl:comment>
878 </xsl:template>
880 <!--
881 // Object description //
882 -->
883 <xsl:template mode="desc" match="*">
885 </xsl:template>
887 <!--
888 // Title and description //
889 Title is ignored and desc is converted to Tag in the mode="desc" template
890 -->
891 <xsl:template mode="forward" match="*[name(.) = 'title' or name(.) = 'desc']">
893 </xsl:template>
895 <!--
896 // Symbols //
897 -->
898 <xsl:template mode="forward" match="*[name(.) = 'symbol']">
900 </xsl:template>
902 <!--
903 // Use //
904 Could be implemented via librairies
905 (but since it is not supported by Inkscape, not implemented yet)
906 -->
907 <xsl:template mode="forward" match="*[name(.) = 'use']">
909 </xsl:template>
911 <!--
912 // RDF and foreign objects //
913 -->
914 <xsl:template mode="forward" match="rdf:RDF | *[name(.) = 'foreignObject']">
916 </xsl:template>
918 <!--
919 // Misc ignored stuff (markers, patterns, styles) //
920 -->
921 <xsl:template mode="forward" match="*[name(.) = 'marker' or name(.) = 'pattern' or name(.) = 'style']">
923 </xsl:template>
925 <!--
926 // Colors and patterns //
928 * Generic color template
929 * Object opacity
930 * Fill
931 * Fill opacity
932 * Fill rule
933 * Generic fill template
934 * Stroke
935 * Stroke opacity
936 * Generic stroke template
937 * Stroke width
938 * Stroke mitterlimit
939 * Stroke dasharray (not supported in FXG)
940 * Stroke dashoffset (not supported in FXG)
941 * Linejoin SVG to FxG converter
942 * Stroke linejoin
943 * Linecap SVG to FXG converter
944 * Stroke linecap
945 * Gradient stop
946 * Gradient stop opacity
947 * Gradient stop offset
948 -->
950 <!--
951 // Generic color template //
952 -->
953 <xsl:template name="template_color">
954 <xsl:param name="colorspec" />
955 <xsl:choose>
956 <xsl:when test="starts-with($colorspec, 'rgb(') and not(contains($colorspec , '%'))">
957 <xsl:value-of select="'#'" />
958 <xsl:call-template name="to_hex">
959 <xsl:with-param name="convert">
960 <xsl:value-of select="substring-before(substring-after($colorspec, 'rgb('), ',')" />
961 </xsl:with-param>
962 </xsl:call-template>
963 <xsl:call-template name="to_hex">
964 <xsl:with-param name="convert">
965 <xsl:value-of select="substring-before(substring-after(substring-after($colorspec, 'rgb('), ','), ',')" />
966 </xsl:with-param>
967 </xsl:call-template>
968 <xsl:call-template name="to_hex">
969 <xsl:with-param name="convert">
970 <xsl:value-of select="substring-before(substring-after(substring-after(substring-after($colorspec, 'rgb('), ','), ','), ')')" />
971 </xsl:with-param>
972 </xsl:call-template>
973 </xsl:when>
974 <xsl:when test="starts-with($colorspec, 'rgb(') and contains($colorspec , '%')">
975 <xsl:value-of select="'#'" />
976 <xsl:call-template name="to_hex">
977 <xsl:with-param name="convert">
978 <xsl:value-of select="number(substring-before(substring-after($colorspec, 'rgb('), '%,')) * 255 div 100" />
979 </xsl:with-param>
980 </xsl:call-template>
981 <xsl:call-template name="to_hex">
982 <xsl:with-param name="convert">
983 <xsl:value-of select="number(substring-before(substring-after(substring-after($colorspec, 'rgb('), ','), '%,')) * 255 div 100" />
984 </xsl:with-param>
985 </xsl:call-template>
986 <xsl:call-template name="to_hex">
987 <xsl:with-param name="convert">
988 <xsl:value-of select="number(substring-before(substring-after(substring-after(substring-after($colorspec, 'rgb('), ','), ','), '%)')) * 255 div 100" />
989 </xsl:with-param>
990 </xsl:call-template>
991 </xsl:when>
992 <xsl:when test="starts-with($colorspec, '#')">
993 <xsl:value-of select="'#'" />
994 <xsl:choose>
995 <xsl:when test="string-length(substring-after($colorspec, '#')) = 3">
996 <xsl:variable name="colorspec3">
997 <xsl:value-of select="translate(substring-after($colorspec, '#'), 'abcdefgh', 'ABCDEFGH')" />
998 </xsl:variable>
999 <xsl:value-of select="concat(substring($colorspec3, 1, 1), substring($colorspec3, 1, 1))" />
1000 <xsl:value-of select="concat(substring($colorspec3, 2, 1), substring($colorspec3, 2, 1))" />
1001 <xsl:value-of select="concat(substring($colorspec3, 3, 1), substring($colorspec3, 3, 1))" />
1002 </xsl:when>
1003 <xsl:otherwise>
1004 <xsl:value-of select="translate(substring-after($colorspec, '#'), 'abcdefgh', 'ABCDEFGH')" />
1005 </xsl:otherwise>
1006 </xsl:choose>
1007 </xsl:when>
1008 <xsl:otherwise>
1009 <xsl:variable name="named_color_hex" select="document('colors.xml')/colors/color[@name = translate($colorspec, 'ABCDEFGHIJKLMNOPQRSTUVWXYZ', 'abcdefghijklmnopqrstuvwxyz')]/@hex" />
1010 <xsl:choose>
1011 <xsl:when test="$named_color_hex and $named_color_hex != ''">
1012 <xsl:value-of select="'#'" />
1013 <xsl:value-of select="substring-after($named_color_hex, '#')" />
1014 </xsl:when>
1015 <xsl:otherwise>
1016 <xsl:value-of select="$colorspec" />
1017 </xsl:otherwise>
1018 </xsl:choose>
1019 </xsl:otherwise>
1020 </xsl:choose>
1021 </xsl:template>
1023 <!--
1024 // Object opacity //
1025 -->
1026 <xsl:template mode="object_opacity" match="*">
1027 <xsl:if test="@opacity or (@style and (contains(@style, ';opacity:') or starts-with(@style, 'opacity:')))">
1028 <xsl:variable name="value">
1029 <xsl:choose>
1030 <xsl:when test="@opacity">
1031 <xsl:value-of select="@opacity" />
1032 </xsl:when>
1033 <xsl:when test="@style and contains(@style, ';opacity:')">
1034 <xsl:variable name="Opacity" select="substring-after(@style, ';opacity:')" />
1035 <xsl:choose>
1036 <xsl:when test="contains($Opacity, ';')">
1037 <xsl:value-of select="substring-before($Opacity, ';')" />
1038 </xsl:when>
1039 <xsl:otherwise>
1040 <xsl:value-of select="$Opacity" />
1041 </xsl:otherwise>
1042 </xsl:choose>
1043 </xsl:when>
1044 <xsl:when test="@style and starts-with(@style, 'opacity:')">
1045 <xsl:variable name="Opacity" select="substring-after(@style, 'opacity:')" />
1046 <xsl:choose>
1047 <xsl:when test="contains($Opacity, ';')">
1048 <xsl:value-of select="substring-before($Opacity, ';')" />
1049 </xsl:when>
1050 <xsl:otherwise>
1051 <xsl:value-of select="$Opacity" />
1052 </xsl:otherwise>
1053 </xsl:choose>
1054 </xsl:when>
1055 <xsl:when test="name(..) = 'g' or name(..) = 'svg'">
1056 <xsl:apply-templates mode="object_opacity" select="parent::*" />
1057 </xsl:when>
1058 <xsl:otherwise>1</xsl:otherwise>
1059 </xsl:choose>
1060 </xsl:variable>
1061 <xsl:attribute name="alpha">
1062 <xsl:choose>
1063 <xsl:when test="$value < 0">0</xsl:when>
1064 <xsl:when test="$value > 1">1</xsl:when>
1065 <xsl:otherwise>
1066 <xsl:value-of select="$value" />
1067 </xsl:otherwise>
1068 </xsl:choose>
1069 </xsl:attribute>
1070 </xsl:if>
1071 </xsl:template>
1073 <!--
1074 // Fill //
1075 -->
1076 <xsl:template mode="fill" match="*">
1077 <xsl:variable name="value">
1078 <xsl:choose>
1079 <xsl:when test="@fill">
1080 <xsl:value-of select="@fill" />
1081 </xsl:when>
1082 <xsl:when test="@style and contains(@style, 'fill:')">
1083 <xsl:variable name="Fill" select="normalize-space(substring-after(@style, 'fill:'))" />
1084 <xsl:choose>
1085 <xsl:when test="contains($Fill, ';')">
1086 <xsl:value-of select="substring-before($Fill, ';')" />
1087 </xsl:when>
1088 <xsl:otherwise>
1089 <xsl:value-of select="$Fill" />
1090 </xsl:otherwise>
1091 </xsl:choose>
1092 </xsl:when>
1093 <xsl:when test="name(..) = 'g' or name(..) = 'svg'">
1094 <xsl:apply-templates mode="fill" select="parent::*"/>
1095 </xsl:when>
1096 </xsl:choose>
1097 </xsl:variable>
1098 <xsl:if test="$value">
1099 <!-- Removes unwanted characters in the color link (TODO: export to a specific template)-->
1100 <xsl:value-of select="normalize-space(translate($value, '"', ''))" />
1101 </xsl:if>
1102 </xsl:template>
1104 <!--
1105 // Fill opacity //
1106 -->
1107 <xsl:template mode="fill_opacity" match="*">
1108 <xsl:variable name="value">
1109 <xsl:choose>
1110 <xsl:when test="@fill-opacity">
1111 <xsl:value-of select="@fill-opacity" />
1112 </xsl:when>
1113 <xsl:when test="@style and contains(@style, 'fill-opacity:')">
1114 <xsl:variable name="Opacity" select="substring-after(@style, 'fill-opacity:')" />
1115 <xsl:choose>
1116 <xsl:when test="contains($Opacity, ';')">
1117 <xsl:value-of select="substring-before($Opacity, ';')" />
1118 </xsl:when>
1119 <xsl:otherwise>
1120 <xsl:value-of select="$Opacity" />
1121 </xsl:otherwise>
1122 </xsl:choose>
1123 </xsl:when>
1124 <xsl:when test="name(..) = 'g' or name(..) = 'svg'">
1125 <xsl:apply-templates mode="fill_opacity" select="parent::*" />
1126 </xsl:when>
1127 <xsl:otherwise>1</xsl:otherwise>
1128 </xsl:choose>
1129 </xsl:variable>
1130 <xsl:choose>
1131 <xsl:when test="$value < 0">0</xsl:when>
1132 <xsl:when test="$value > 1">1</xsl:when>
1133 <xsl:otherwise>
1134 <xsl:value-of select="$value" />
1135 </xsl:otherwise>
1136 </xsl:choose>
1137 </xsl:template>
1139 <!--
1140 // Fill rule //
1141 -->
1142 <xsl:template mode="fill_rule" match="*">
1143 <xsl:choose>
1144 <xsl:when test="@fill-rule and (@fill-rule = 'nonzero' or @fill-rule = 'evenodd')">
1145 <xsl:if test="@fill-rule = 'nonzero'">
1146 <xsl:attribute name="winding">nonZero</xsl:attribute>
1147 </xsl:if>
1148 <xsl:if test="@fill-rule = 'evenodd'">
1149 <xsl:attribute name="winding">evenOdd</xsl:attribute>
1150 </xsl:if>
1151 </xsl:when>
1152 <xsl:when test="@style and contains(@style, 'fill-rule:')">
1153 <xsl:variable name="FillRule" select="normalize-space(substring-after(@style, 'fill-rule:'))" />
1154 <xsl:choose>
1155 <xsl:when test="contains($FillRule, ';')">
1156 <xsl:if test="substring-before($FillRule, ';') = 'nonzero'">
1157 <xsl:attribute name="winding">nonZero</xsl:attribute>
1158 </xsl:if>
1159 <xsl:if test="substring-before($FillRule, ';') = 'evenodd'">
1160 <xsl:attribute name="winding">evenOdd</xsl:attribute>
1161 </xsl:if>
1162 </xsl:when>
1163 <xsl:when test="$FillRule = 'nonzero'">
1164 <xsl:attribute name="winding">nonZero</xsl:attribute>
1165 </xsl:when>
1166 <xsl:when test=" $FillRule = 'evenodd'">
1167 <xsl:attribute name="winding">evenOdd</xsl:attribute>
1168 </xsl:when>
1169 </xsl:choose>
1170 </xsl:when>
1171 <xsl:when test="name(..) = 'g' or name(..) = 'svg'">
1172 <xsl:apply-templates mode="fill_rule" select="parent::*"/>
1173 </xsl:when>
1174 <xsl:otherwise>
1175 <xsl:attribute name="winding">nonZero</xsl:attribute>
1176 </xsl:otherwise>
1177 </xsl:choose>
1178 </xsl:template>
1180 <!--
1181 // Generic fill template //
1182 -->
1183 <xsl:template mode="template_fill" match="*">
1184 <xsl:variable name="fill"><xsl:apply-templates mode="fill" select="." /></xsl:variable>
1185 <xsl:variable name="fill_opacity"><xsl:apply-templates mode="fill_opacity" select="." /></xsl:variable>
1187 <xsl:choose>
1188 <xsl:when test="$fill != '' and $fill != 'none' and not(starts-with($fill, 'url(#'))">
1189 <!-- Solid color -->
1190 <fill>
1191 <SolidColor>
1192 <xsl:attribute name="color">
1193 <xsl:call-template name="template_color">
1194 <xsl:with-param name="colorspec">
1195 <xsl:value-of select="$fill" />
1196 </xsl:with-param>
1197 </xsl:call-template>
1198 </xsl:attribute>
1199 <xsl:attribute name="alpha">
1200 <xsl:value-of select="$fill_opacity" />
1201 </xsl:attribute>
1202 </SolidColor>
1203 </fill>
1204 </xsl:when>
1205 <!-- Gradients -->
1206 <xsl:when test="starts-with($fill, 'url(#')">
1207 <xsl:for-each select="//*[@id=substring-before(substring-after($fill, 'url(#'), ')')]">
1208 <xsl:if test="name(.) = 'linearGradient'">
1209 <fill>
1210 <LinearGradient>
1211 <xsl:call-template name="linearGradient" >
1212 <xsl:with-param name="id">
1213 <xsl:value-of select="substring-before(substring-after($fill, 'url(#'), ')')" />
1214 </xsl:with-param>
1215 </xsl:call-template>
1216 </LinearGradient>
1217 </fill>
1218 </xsl:if>
1219 <xsl:if test="name(.) = 'radialGradient'">
1220 <fill>
1221 <RadialGradient>
1222 <xsl:call-template name="radialGradient" >
1223 <xsl:with-param name="id">
1224 <xsl:value-of select="substring-before(substring-after($fill, 'url(#'), ')')" />
1225 </xsl:with-param>
1226 </xsl:call-template>
1227 </RadialGradient>
1228 </fill>
1229 </xsl:if>
1230 </xsl:for-each>
1231 </xsl:when>
1232 <xsl:when test="$fill = 'none'">
1233 </xsl:when>
1234 <xsl:otherwise>
1235 <fill>
1236 <SolidColor color="#ffffff" alpha="1"/>
1237 </fill>
1238 </xsl:otherwise>
1239 </xsl:choose>
1240 </xsl:template>
1242 <!--
1243 // Stroke //
1244 -->
1245 <xsl:template mode="stroke" match="*">
1246 <xsl:choose>
1247 <xsl:when test="@stroke">
1248 <xsl:value-of select="@stroke" />
1249 </xsl:when>
1250 <xsl:when test="@style and contains(@style, 'stroke:')">
1251 <xsl:variable name="Stroke" select="normalize-space(substring-after(@style, 'stroke:'))" />
1252 <xsl:choose>
1253 <xsl:when test="contains($Stroke, ';')">
1254 <xsl:value-of select="substring-before($Stroke, ';')" />
1255 </xsl:when>
1256 <xsl:when test="$Stroke">
1257 <xsl:value-of select="$Stroke" />
1258 </xsl:when>
1259 </xsl:choose>
1260 </xsl:when>
1261 <xsl:when test="name(..) = 'g' or name(..) = 'svg'">
1262 <xsl:apply-templates mode="stroke" select="parent::*"/>
1263 </xsl:when>
1264 </xsl:choose>
1265 </xsl:template>
1267 <!--
1268 // Stroke opacity //
1269 -->
1270 <xsl:template mode="stroke_opacity" match="*">
1271 <xsl:variable name="value">
1272 <xsl:choose>
1273 <xsl:when test="@stroke-opacity"><xsl:value-of select="@stroke-opacity" /></xsl:when>
1274 <xsl:when test="@style and contains(@style, 'stroke-opacity:')">
1275 <xsl:variable name="Opacity" select="substring-after(@style, 'stroke-opacity:')" />
1276 <xsl:choose>
1277 <xsl:when test="contains($Opacity, ';')">
1278 <xsl:value-of select="substring-before($Opacity, ';')" />
1279 </xsl:when>
1280 <xsl:otherwise>
1281 <xsl:value-of select="$Opacity" />
1282 </xsl:otherwise>
1283 </xsl:choose>
1284 </xsl:when>
1285 <xsl:when test="name(..) = 'g' or name(..) = 'svg'">
1286 <xsl:apply-templates mode="stroke_opacity" select="parent::*" />
1287 </xsl:when>
1288 <xsl:otherwise>1</xsl:otherwise>
1289 </xsl:choose>
1290 </xsl:variable>
1291 <xsl:choose>
1292 <xsl:when test="$value < 0">0</xsl:when>
1293 <xsl:when test="$value > 1">1</xsl:when>
1294 <xsl:otherwise>
1295 <xsl:value-of select="$value" />
1296 </xsl:otherwise>
1297 </xsl:choose>
1298 </xsl:template>
1300 <!--
1301 // Generic stroke template //
1303 Not supported in FXG:
1304 * stroke-dasharray
1305 * stroke-dashoffset
1307 -->
1308 <xsl:template mode="template_stroke" match="*">
1309 <xsl:variable name="stroke"><xsl:apply-templates mode="stroke" select="." /></xsl:variable>
1310 <xsl:variable name="stroke_opacity"><xsl:apply-templates mode="stroke_opacity" select="." /></xsl:variable>
1311 <xsl:variable name="stroke_width"><xsl:apply-templates mode="stroke_width" select="." /></xsl:variable>
1312 <xsl:variable name="stroke_miterlimit"><xsl:apply-templates mode="stroke_miterlimit" select="." /></xsl:variable>
1313 <xsl:variable name="stroke_linejoin"><xsl:apply-templates mode="stroke_linejoin" select="." /></xsl:variable>
1314 <xsl:variable name="stroke_linecap"><xsl:apply-templates mode="stroke_linecap" select="." /></xsl:variable>
1316 <!-- Solid color -->
1317 <xsl:if test="$stroke != '' and $stroke != 'none' and not(starts-with($stroke, 'url(#'))">
1318 <stroke>
1319 <SolidColorStroke>
1320 <xsl:attribute name="color">
1321 <xsl:call-template name="template_color">
1322 <xsl:with-param name="colorspec">
1323 <xsl:value-of select="$stroke" />
1324 </xsl:with-param>
1325 </xsl:call-template>
1326 </xsl:attribute>
1327 <xsl:attribute name="alpha">
1328 <xsl:value-of select="$stroke_opacity" />
1329 </xsl:attribute>
1330 <xsl:attribute name="weight">
1331 <xsl:value-of select="$stroke_width" />
1332 </xsl:attribute>
1333 <xsl:if test="$stroke_miterlimit != ''">
1334 <xsl:attribute name="miterLimit">
1335 <xsl:value-of select="$stroke_miterlimit" />
1336 </xsl:attribute>
1337 </xsl:if>
1338 <xsl:attribute name="joints">
1339 <xsl:value-of select="$stroke_linejoin" />
1340 </xsl:attribute>
1341 <xsl:attribute name="caps">
1342 <xsl:value-of select="$stroke_linecap" />
1343 </xsl:attribute>
1344 </SolidColorStroke>
1345 </stroke>
1346 </xsl:if>
1348 <!-- Gradients -->
1349 <xsl:if test="starts-with($stroke, 'url(#')">
1350 <xsl:for-each select="//*[@id=substring-before(substring-after($stroke, 'url(#'), ')')]">
1351 <xsl:if test="name(.) = 'linearGradient'">
1352 <stroke>
1353 <LinearGradientStroke>
1354 <xsl:attribute name="weight">
1355 <xsl:value-of select="$stroke_width" />
1356 </xsl:attribute>
1357 <xsl:if test="$stroke_miterlimit != ''">
1358 <xsl:attribute name="miterLimit">
1359 <xsl:value-of select="$stroke_miterlimit" />
1360 </xsl:attribute>
1361 </xsl:if>
1362 <xsl:attribute name="joints">
1363 <xsl:value-of select="$stroke_linejoin" />
1364 </xsl:attribute>
1365 <xsl:attribute name="caps">
1366 <xsl:value-of select="$stroke_linecap" />
1367 </xsl:attribute>
1368 <xsl:call-template name="linearGradient" >
1369 <xsl:with-param name="id">
1370 <xsl:value-of select="substring-before(substring-after($stroke, 'url(#'), ')')" />
1371 </xsl:with-param>
1372 </xsl:call-template>
1373 </LinearGradientStroke>
1374 </stroke>
1375 </xsl:if>
1376 <xsl:if test="name(.) = 'radialGradient'">
1377 <stroke>
1378 <RadialGradientStroke>
1379 <xsl:attribute name="weight">
1380 <xsl:value-of select="$stroke_width" />
1381 </xsl:attribute>
1382 <xsl:if test="$stroke_miterlimit != ''">
1383 <xsl:attribute name="miterLimit">
1384 <xsl:value-of select="$stroke_miterlimit" />
1385 </xsl:attribute>
1386 </xsl:if>
1387 <xsl:attribute name="joints">
1388 <xsl:value-of select="$stroke_linejoin" />
1389 </xsl:attribute>
1390 <xsl:attribute name="caps">
1391 <xsl:value-of select="$stroke_linecap" />
1392 </xsl:attribute>
1393 <xsl:call-template name="radialGradient" >
1394 <xsl:with-param name="id">
1395 <xsl:value-of select="substring-before(substring-after($stroke, 'url(#'), ')')" />
1396 </xsl:with-param>
1397 </xsl:call-template>
1398 </RadialGradientStroke>
1399 </stroke>
1400 </xsl:if>
1401 </xsl:for-each>
1402 </xsl:if>
1403 </xsl:template>
1405 <!--
1406 // Stroke width //
1407 -->
1408 <xsl:template mode="stroke_width" match="*">
1409 <xsl:choose>
1410 <xsl:when test="@stroke-width">
1411 <xsl:call-template name="convert_unit">
1412 <xsl:with-param name="convert_value">
1413 <xsl:value-of select="@stroke-width" />
1414 </xsl:with-param>
1415 </xsl:call-template>
1416 </xsl:when>
1417 <xsl:when test="@style and contains(@style, 'stroke-width:')">
1418 <xsl:call-template name="convert_unit">
1419 <xsl:with-param name="convert_value">
1420 <xsl:choose>
1421 <xsl:when test="contains(substring-after(@style, 'stroke-width:'), ';')">
1422 <xsl:value-of select="substring-before(substring-after(@style, 'stroke-width:'), ';')" />
1423 </xsl:when>
1424 <xsl:otherwise>
1425 <xsl:value-of select="substring-after(@style, 'stroke-width:')" />
1426 </xsl:otherwise>
1427 </xsl:choose>
1428 </xsl:with-param>
1429 </xsl:call-template>
1430 </xsl:when>
1431 <xsl:when test="name(..) = 'g' or name(..) = 'svg'">
1432 <xsl:apply-templates mode="stroke_width" select="parent::*"/>
1433 </xsl:when>
1434 <xsl:otherwise>1</xsl:otherwise>
1435 </xsl:choose>
1436 </xsl:template>
1438 <!--
1439 // Stroke miterlimit //
1441 Probably not calculated the same way in SVG and FXG (same value but different result)
1442 -->
1443 <xsl:template mode="stroke_miterlimit" match="*">
1444 <xsl:choose>
1445 <xsl:when test="@stroke-miterlimit">
1446 <xsl:value-of select="@stroke-miterlimit" />
1447 </xsl:when>
1448 <xsl:when test="@style and contains(@style, 'stroke-miterlimit:')">
1449 <xsl:variable name="miterLimit" select="substring-after(@style, 'stroke-miterlimit:')" />
1450 <xsl:choose>
1451 <xsl:when test="contains($miterLimit, ';')">
1452 <xsl:value-of select="substring-before($miterLimit, ';')" />
1453 </xsl:when>
1454 <xsl:otherwise>
1455 <xsl:value-of select="$miterLimit" />
1456 </xsl:otherwise>
1457 </xsl:choose>
1458 </xsl:when>
1459 <xsl:when test="name(..) = 'g' or name(..) = 'svg'">
1460 <xsl:apply-templates mode="stroke_miterlimit" select="parent::*"/>
1461 </xsl:when>
1462 </xsl:choose>
1463 </xsl:template>
1465 <!--
1466 // Stroke dasharray //
1467 !! Not supported !!
1468 -->
1469 <xsl:template mode="stroke_dasharray" match="*">
1470 <xsl:comment>FXG does not support dasharrays</xsl:comment>
1471 </xsl:template>
1473 <!--
1474 // Stroke dashoffset //
1475 !! Not supported !!
1476 -->
1477 <xsl:template mode="stroke_dashoffset" match="*">
1478 <xsl:comment>FXG does not support dashoffsets</xsl:comment>
1479 </xsl:template>
1481 <!--
1482 // Linejoin SVG to FXG converter //
1483 -->
1484 <xsl:template name="linejoin_svg_to_fxg">
1485 <xsl:param name="linejoin" />
1486 <xsl:choose>
1487 <xsl:when test="$linejoin = 'bevel'">bevel</xsl:when>
1488 <xsl:when test="$linejoin = 'round'">round</xsl:when>
1489 <xsl:otherwise>miter</xsl:otherwise>
1490 </xsl:choose>
1491 </xsl:template>
1493 <!--
1494 // Stroke linejoin //
1495 -->
1496 <xsl:template mode="stroke_linejoin" match="*">
1497 <xsl:choose>
1498 <xsl:when test="@stroke-linejoin">
1499 <xsl:call-template name="linejoin_svg_to_fxg">
1500 <xsl:with-param name="linejoin">
1501 <xsl:value-of select="@stroke-linejoin" />
1502 </xsl:with-param>
1503 </xsl:call-template>
1504 </xsl:when>
1505 <xsl:when test="@style and contains(@style, 'stroke-linejoin:')">
1506 <xsl:variable name="joints" select="substring-after(@style, 'stroke-linejoin:')" />
1507 <xsl:choose>
1508 <xsl:when test="contains($joints, ';')">
1509 <xsl:call-template name="linejoin_svg_to_fxg">
1510 <xsl:with-param name="linejoin">
1511 <xsl:value-of select="substring-before($joints, ';')" />
1512 </xsl:with-param>
1513 </xsl:call-template>
1514 </xsl:when>
1515 <xsl:otherwise>
1516 <xsl:call-template name="linejoin_svg_to_fxg">
1517 <xsl:with-param name="linejoin">
1518 <xsl:value-of select="$joints" />
1519 </xsl:with-param>
1520 </xsl:call-template>
1521 </xsl:otherwise>
1522 </xsl:choose>
1523 </xsl:when>
1524 <xsl:when test="name(..) = 'g' or name(..) = 'svg'">
1525 <xsl:apply-templates mode="stroke_linejoin" select="parent::*"/>
1526 </xsl:when>
1527 <xsl:otherwise>miter</xsl:otherwise>
1528 </xsl:choose>
1529 </xsl:template>
1531 <!--
1532 // Linecap SVG to FXG converter //
1534 Not supported in FXG:
1535 * butt linecap
1536 -->
1537 <xsl:template name="linecap_svg_to_fxg">
1538 <xsl:param name="linecap" />
1539 <xsl:choose>
1540 <xsl:when test="$linecap = 'round'">round</xsl:when>
1541 <xsl:when test="$linecap = 'square'">square</xsl:when>
1542 <xsl:when test="$linecap = 'butt'">round</xsl:when>
1543 <xsl:otherwise>none</xsl:otherwise>
1544 </xsl:choose>
1545 </xsl:template>
1547 <!--
1548 // Stroke linecap //
1549 -->
1550 <xsl:template mode="stroke_linecap" match="*">
1551 <xsl:choose>
1552 <xsl:when test="@stroke-linecap">
1553 <xsl:call-template name="linecap_svg_to_fxg">
1554 <xsl:with-param name="linecap">
1555 <xsl:value-of select="@stroke-linecap" />
1556 </xsl:with-param>
1557 </xsl:call-template>
1558 </xsl:when>
1559 <xsl:when test="@style and contains(@style, 'stroke-linecap:')">
1560 <xsl:variable name="caps" select="substring-after(@style, 'stroke-linecap:')" />
1561 <xsl:choose>
1562 <xsl:when test="contains($caps, ';')">
1563 <xsl:call-template name="linecap_svg_to_fxg">
1564 <xsl:with-param name="linecap">
1565 <xsl:value-of select="substring-before($caps, ';')" />
1566 </xsl:with-param>
1567 </xsl:call-template>
1568 </xsl:when>
1569 <xsl:otherwise>
1570 <xsl:call-template name="linecap_svg_to_fxg">
1571 <xsl:with-param name="linecap">
1572 <xsl:value-of select="$caps" />
1573 </xsl:with-param>
1574 </xsl:call-template>
1575 </xsl:otherwise>
1576 </xsl:choose>
1577 </xsl:when>
1578 <xsl:when test="name(..) = 'g' or name(..) = 'svg'">
1579 <xsl:apply-templates mode="stroke_linecap" select="parent::*"/>
1580 </xsl:when>
1581 <xsl:otherwise>none</xsl:otherwise>
1582 </xsl:choose>
1583 </xsl:template>
1585 <!--
1586 // Gradient stops //
1587 -->
1588 <xsl:template mode="stop_color" match="*">
1589 <xsl:variable name="Opacity">
1590 <xsl:choose>
1591 <xsl:when test="@stop-opacity">
1592 <xsl:value-of select="@stop-opacity" />
1593 </xsl:when>
1594 <xsl:when test="@style and contains(@style, 'stop-opacity:')">
1595 <xsl:variable name="temp_opacity" select="substring-after(@style, 'stop-opacity:')" />
1596 <xsl:choose>
1597 <xsl:when test="contains($temp_opacity, ';')">
1598 <xsl:value-of select="substring-before($temp_opacity, ';')" />
1599 </xsl:when>
1600 <xsl:otherwise>
1601 <xsl:value-of select="$temp_opacity" />
1602 </xsl:otherwise>
1603 </xsl:choose>
1604 </xsl:when>
1605 <xsl:otherwise><xsl:value-of select="''" /></xsl:otherwise>
1606 </xsl:choose>
1607 </xsl:variable>
1608 <xsl:variable name="hex_opacity">
1609 <xsl:choose>
1610 <xsl:when test="$Opacity != ''">
1611 <xsl:call-template name="to_hex">
1612 <xsl:with-param name="convert">
1613 <xsl:value-of select="number($Opacity) * 255" />
1614 </xsl:with-param>
1615 </xsl:call-template>
1616 </xsl:when>
1617 <xsl:otherwise>
1618 <xsl:value-of select="$Opacity" />
1619 </xsl:otherwise>
1620 </xsl:choose>
1621 </xsl:variable>
1622 <xsl:variable name="stopcolor">
1623 <xsl:choose>
1624 <xsl:when test="@stop-color">
1625 <xsl:call-template name="template_color">
1626 <xsl:with-param name="colorspec">
1627 <xsl:value-of select="@stop-color" />
1628 </xsl:with-param>
1629 </xsl:call-template>
1630 </xsl:when>
1631 <xsl:when test="@style and contains(@style, 'stop-color:')">
1632 <xsl:variable name="Color" select="normalize-space(substring-after(@style, 'stop-color:'))" />
1633 <xsl:choose>
1634 <xsl:when test="contains($Color, ';')">
1635 <xsl:call-template name="template_color">
1636 <xsl:with-param name="colorspec">
1637 <xsl:value-of select="substring-before($Color, ';')" />
1638 </xsl:with-param>
1639 </xsl:call-template>
1640 </xsl:when>
1641 <xsl:otherwise>
1642 <xsl:call-template name="template_color">
1643 <xsl:with-param name="colorspec">
1644 <xsl:value-of select="$Color" />
1645 </xsl:with-param>
1646 </xsl:call-template>
1647 </xsl:otherwise>
1648 </xsl:choose>
1649 </xsl:when>
1650 <xsl:when test="name(..) = 'g' or name(..) = 'svg'">
1651 <xsl:apply-templates mode="stop_color" select="parent::*"/>
1652 </xsl:when>
1653 <xsl:otherwise>#000</xsl:otherwise>
1654 </xsl:choose>
1655 </xsl:variable>
1656 <xsl:attribute name="color">
1657 <xsl:value-of select="$stopcolor" />
1658 </xsl:attribute>
1659 <xsl:if test="$Opacity != ''">
1660 <xsl:attribute name="alpha">
1661 <xsl:value-of select="$Opacity" />
1662 </xsl:attribute>
1663 </xsl:if>
1664 </xsl:template>
1666 <!--
1667 // Gradient stop opacity //
1668 -->
1669 <xsl:template mode="stop_opacity" match="*">
1670 <xsl:choose>
1671 <xsl:when test="@stop-opacity">
1672 <xsl:attribute name="Opacity">
1673 <xsl:value-of select="@stop-opacity" />
1674 </xsl:attribute>
1675 </xsl:when>
1676 <xsl:when test="@style and contains(@style, 'stop-opacity:')">
1677 <xsl:variable name="Opacity" select="substring-after(@style, 'stop-opacity:')" />
1678 <xsl:attribute name="opacity">
1679 <xsl:choose>
1680 <xsl:when test="contains($Opacity, ';')">
1681 <xsl:value-of select="substring-before($Opacity, ';')" />
1682 </xsl:when>
1683 <xsl:otherwise>
1684 <xsl:value-of select="$Opacity" />
1685 </xsl:otherwise>
1686 </xsl:choose>
1687 </xsl:attribute>
1688 </xsl:when>
1689 <xsl:when test="name(..) = 'g' or name(..) = 'svg'">
1690 <xsl:apply-templates mode="stop_opacity" select="parent::*"/>
1691 </xsl:when>
1692 </xsl:choose>
1693 </xsl:template>
1695 <!--
1696 // Gradient stop offset //
1697 -->
1698 <xsl:template mode="offset" match="*">
1699 <xsl:choose>
1700 <xsl:when test="@offset">
1701 <xsl:attribute name="ratio">
1702 <xsl:choose>
1703 <xsl:when test="contains(@offset, '%')">
1704 <xsl:value-of select="number(substring-before(@offset, '%')) div 100" />
1705 </xsl:when>
1706 <xsl:otherwise>
1707 <xsl:value-of select="@offset" />
1708 </xsl:otherwise>
1709 </xsl:choose>
1710 </xsl:attribute>
1711 </xsl:when>
1712 <xsl:when test="@style and contains(@style, 'offset:')">
1713 <xsl:variable name="Offset" select="substring-after(@style, 'offset:')" />
1714 <xsl:attribute name="ratio">
1715 <xsl:choose>
1716 <xsl:when test="contains($Offset, '%')">
1717 <xsl:value-of select="number(substring-before($Offset, '%')) div 100" />
1718 </xsl:when>
1719 <xsl:when test="contains($Offset, ';')">
1720 <xsl:value-of select="substring-before($Offset, ';')" />
1721 </xsl:when>
1722 <xsl:otherwise>
1723 <xsl:value-of select="$Offset" />
1724 </xsl:otherwise>
1725 </xsl:choose>
1726 </xsl:attribute>
1727 </xsl:when>
1728 <xsl:when test="name(..) = 'g' or name(..) = 'svg'">
1729 <xsl:apply-templates mode="stop_offset" select="parent::*"/>
1730 </xsl:when>
1731 </xsl:choose>
1732 </xsl:template>
1734 <!--
1735 // Text specific templates //
1737 * Text tspan
1738 * Text flowPara
1739 * Text flowRegion (text frame)
1740 * Font size
1741 * Font weight
1742 * Font family
1743 * Font style
1744 * Baseline shift
1745 * Line height
1746 * Writing mode
1747 * Text decoration
1748 * Text fill
1749 * Text direction
1750 * Text size
1751 * Text position
1752 * Text object
1753 * FlowRoot object
1754 -->
1756 <!--
1757 // Text span //
1758 SVG: tspan, flowSpan, FXG: span
1760 Not supported in FXG:
1761 * span position
1762 -->
1763 <xsl:template mode="forward" match="*[name(.) = 'tspan' or name(.) = 'flowSpan']">
1764 <span>
1765 <xsl:if test="../@xml:space='preserve'">
1766 <xsl:attribute name="whiteSpaceCollapse">preserve</xsl:attribute>
1767 </xsl:if>
1768 <xsl:variable name="fill">
1769 <xsl:apply-templates mode="fill" select="." />
1770 </xsl:variable>
1771 <xsl:variable name="fill_opacity">
1772 <xsl:apply-templates mode="fill_opacity" select="." />
1773 </xsl:variable>
1774 <xsl:if test="starts-with($fill, '#') or (not(starts-with($fill, 'url')) and $fill != '' and $fill != 'none')">
1775 <xsl:attribute name="color">
1776 <xsl:call-template name="template_color">
1777 <xsl:with-param name="colorspec">
1778 <xsl:value-of select="$fill" />
1779 </xsl:with-param>
1780 </xsl:call-template>
1781 </xsl:attribute>
1782 <xsl:attribute name="textAlpha">
1783 <xsl:value-of select="$fill_opacity" />
1784 </xsl:attribute>
1785 </xsl:if>
1786 <xsl:apply-templates mode="font_size" select="." />
1787 <xsl:apply-templates mode="font_weight" select="." />
1788 <xsl:apply-templates mode="font_family" select="." />
1789 <xsl:apply-templates mode="font_style" select="." />
1790 <xsl:apply-templates mode="text_fill" select="." />
1791 <xsl:apply-templates mode="text_decoration" select="." />
1792 <xsl:apply-templates mode="line_height" select="." />
1793 <xsl:apply-templates mode="baseline_shift" select="." />
1795 <xsl:if test="text()">
1796 <xsl:value-of select="text()" />
1797 </xsl:if>
1798 </span>
1799 </xsl:template>
1801 <!--
1802 // Text flowPara //
1803 SVG: flowPara, flowDiv FXG: p
1805 Not supported in FXG:
1806 * paragraph position
1807 -->
1808 <xsl:template mode="forward" match="*[name(.) = 'flowPara' or name(.) = 'flowDiv']">
1809 <p>
1810 <xsl:if test="../@xml:space='preserve'">
1811 <xsl:attribute name="whiteSpaceCollapse">preserve</xsl:attribute>
1812 </xsl:if>
1813 <xsl:variable name="fill">
1814 <xsl:apply-templates mode="fill" select="." />
1815 </xsl:variable>
1816 <xsl:variable name="fill_opacity">
1817 <xsl:apply-templates mode="fill_opacity" select="." />
1818 </xsl:variable>
1819 <xsl:if test="starts-with($fill, '#') or (not(starts-with($fill, 'url')) and $fill != '' and $fill != 'none')">
1820 <xsl:attribute name="color">
1821 <xsl:call-template name="template_color">
1822 <xsl:with-param name="colorspec">
1823 <xsl:value-of select="$fill" />
1824 </xsl:with-param>
1825 </xsl:call-template>
1826 </xsl:attribute>
1827 <xsl:attribute name="textAlpha">
1828 <xsl:value-of select="$fill_opacity" />
1829 </xsl:attribute>
1830 </xsl:if>
1831 <xsl:apply-templates mode="font_size" select="." />
1832 <xsl:apply-templates mode="font_weight" select="." />
1833 <xsl:apply-templates mode="font_family" select="." />
1834 <xsl:apply-templates mode="font_style" select="." />
1835 <xsl:apply-templates mode="text_fill" select="." />
1836 <xsl:apply-templates mode="text_decoration" select="." />
1837 <xsl:apply-templates mode="line_height" select="." />
1838 <xsl:apply-templates mode="baseline_shift" select="." />
1840 <xsl:choose>
1841 <xsl:when test="*[name(.) = 'flowSpan']/text()">
1842 <xsl:apply-templates mode="forward" />
1843 </xsl:when>
1844 <xsl:otherwise>
1845 <xsl:choose>
1846 <xsl:when test="@xml:space='preserve'">
1847 <xsl:copy-of select="translate(text(), '	

', ' ')" />
1848 </xsl:when>
1849 <xsl:otherwise>
1850 <xsl:copy-of select="normalize-space(translate(text(), '	

', ' '))" />
1851 </xsl:otherwise>
1852 </xsl:choose>
1853 </xsl:otherwise>
1854 </xsl:choose>
1855 </p>
1856 </xsl:template>
1859 <!--
1860 // Text flowRegion //
1861 -->
1862 <xsl:template mode="flow_region" match="*">
1863 <xsl:apply-templates mode="text_size" select="." />
1864 <xsl:apply-templates mode="text_position" select="." />
1865 </xsl:template>
1867 <!--
1868 // Text font size //
1869 SVG: font-size, FXG: fontSize
1870 -->
1871 <xsl:template mode="font_size" match="*">
1872 <xsl:variable name="value">
1873 <xsl:if test="@font-size">
1874 <xsl:value-of select="@font-size" />
1875 </xsl:if>
1876 <xsl:if test="@style and contains(@style, 'font-size:')">
1877 <xsl:variable name="font_size" select="normalize-space(substring-after(@style, 'font-size:'))" />
1878 <xsl:choose>
1879 <xsl:when test="contains($font_size, ';')">
1880 <xsl:value-of select="substring-before($font_size, ';')" />
1881 </xsl:when>
1882 <xsl:otherwise>
1883 <xsl:value-of select="$font_size" />
1884 </xsl:otherwise>
1885 </xsl:choose>
1886 </xsl:if>
1887 </xsl:variable>
1888 <xsl:if test="$value != ''">
1889 <xsl:attribute name="fontSize">
1890 <xsl:call-template name="convert_unit">
1891 <xsl:with-param name="convert_value" select="$value" />
1892 </xsl:call-template>
1893 </xsl:attribute>
1894 </xsl:if>
1895 </xsl:template>
1897 <!--
1898 // Text font weight //
1899 SVG: font-weight, FXG: fontWeight
1900 -->
1901 <xsl:template mode="font_weight" match="*">
1902 <xsl:variable name="value">
1903 <xsl:if test="@font-weight">
1904 <xsl:value-of select="@font-weight" />
1905 </xsl:if>
1906 <xsl:if test="@style and contains(@style, 'font-weight:')">
1907 <xsl:variable name="font_weight" select="normalize-space(substring-after(@style, 'font-weight:'))" />
1908 <xsl:choose>
1909 <xsl:when test="contains($font_weight, ';')">
1910 <xsl:value-of select="substring-before($font_weight, ';')" />
1911 </xsl:when>
1912 <xsl:otherwise>
1913 <xsl:value-of select="$font_weight" />
1914 </xsl:otherwise>
1915 </xsl:choose>
1916 </xsl:if>
1917 </xsl:variable>
1918 <xsl:if test="$value != ''">
1919 <xsl:attribute name="fontWeight">
1920 <xsl:choose>
1921 <xsl:when test="$value='normal' or $value='bold'">
1922 <xsl:value-of select="$value" />
1923 </xsl:when>
1924 <xsl:when test="$value < 500 or $value = 'lighter'">normal</xsl:when>
1925 <xsl:when test="$value > 499 or $value = 'bolder'">bold</xsl:when>
1926 <xsl:otherwise>normal</xsl:otherwise>
1927 </xsl:choose>
1928 </xsl:attribute>
1929 </xsl:if>
1930 </xsl:template>
1932 <!--
1933 // Text font family //
1934 SVG: font-family, FXG: fontFamily
1935 -->
1936 <xsl:template mode="font_family" match="*">
1937 <xsl:variable name="value">
1938 <xsl:if test="@font-family">
1939 <xsl:value-of select="translate(@font-family, "'", '')" />
1940 </xsl:if>
1941 <xsl:if test="@style and contains(@style, 'font-family:')">
1942 <xsl:variable name="font_family" select="normalize-space(substring-after(@style, 'font-family:'))" />
1943 <xsl:choose>
1944 <xsl:when test="contains($font_family, ';')">
1945 <xsl:value-of select="translate(substring-before($font_family, ';'), "'", '')" />
1946 </xsl:when>
1947 <xsl:otherwise>
1948 <xsl:value-of select="translate($font_family, "'", '')" />
1949 </xsl:otherwise>
1950 </xsl:choose>
1951 </xsl:if>
1952 </xsl:variable>
1953 <xsl:if test="$value != ''">
1954 <xsl:attribute name="fontFamily">
1955 <xsl:choose>
1956 <xsl:when test="$value='Sans'">Arial</xsl:when>
1957 <xsl:otherwise>
1958 <xsl:value-of select="$value" />
1959 </xsl:otherwise>
1960 </xsl:choose>
1961 </xsl:attribute>
1962 </xsl:if>
1963 </xsl:template>
1965 <!--
1966 // Text font style //
1967 SVG: font-style, FXG: fontStyle
1968 -->
1969 <xsl:template mode="font_style" match="*">
1970 <xsl:variable name="value">
1971 <xsl:if test="@font-style">
1972 <xsl:value-of select="@font-style" />
1973 </xsl:if>
1974 <xsl:if test="@style and contains(@style, 'font-style:')">
1975 <xsl:variable name="font_style" select="normalize-space(substring-after(@style, 'font-style:'))" />
1976 <xsl:choose>
1977 <xsl:when test="contains($font_style, ';')">
1978 <xsl:value-of select="substring-before($font_style, ';')" />
1979 </xsl:when>
1980 <xsl:otherwise>
1981 <xsl:value-of select="$font_style" />
1982 </xsl:otherwise>
1983 </xsl:choose>
1984 </xsl:if>
1985 </xsl:variable>
1986 <xsl:if test="$value != ''">
1987 <xsl:attribute name="fontStyle">
1988 <xsl:value-of select="$value" />
1989 </xsl:attribute>
1990 </xsl:if>
1991 </xsl:template>
1993 <!--
1994 // Text baseline shift //
1995 SVG: baseline-shift, FXG: baselineShift
1996 -->
1997 <xsl:template mode="baseline_shift" match="*">
1998 <xsl:variable name="value">
1999 <xsl:if test="@baseline-shift">
2000 <xsl:value-of select="@baseline-shift" />
2001 </xsl:if>
2002 <xsl:if test="@style and contains(@style, 'baseline-shift:') and not(contains(substring-after(@style, 'baseline-shift:'), ';'))">
2003 <xsl:value-of select="substring-after(@style, 'baseline-shift:')" />
2004 </xsl:if>
2005 <xsl:if test="@style and contains(@style, 'baseline-shift:') and contains(substring-after(@style, 'baseline-shift:'), ';')">
2006 <xsl:value-of select="substring-before(substring-after(@style, 'baseline-shift:'), ';')" />
2007 </xsl:if>
2008 </xsl:variable>
2009 <xsl:if test="$value != ''">
2010 <xsl:attribute name="baselineShift">
2011 <xsl:choose>
2012 <xsl:when test="$value='baseline'">0</xsl:when>
2013 <xsl:when test="$value='super'">superscript</xsl:when>
2014 <xsl:when test="$value='sub'">subscript</xsl:when>
2015 <xsl:when test="translate($value, '%', '') < -1000">-1000</xsl:when>
2016 <xsl:when test="translate($value, '%', '') > 1000">1000</xsl:when>
2017 <xsl:otherwise>
2018 <xsl:value-of select="translate($value, '%', '')" />
2019 </xsl:otherwise>
2020 </xsl:choose>
2021 <xsl:if test="contains($value, '%')">%</xsl:if>
2022 </xsl:attribute>
2023 </xsl:if>
2024 </xsl:template>
2026 <!--
2027 // Text line height //
2028 SVG: line-height, FXG: lineHeight
2029 -->
2030 <xsl:template mode="line_height" match="*">
2031 <xsl:variable name="value">
2032 <xsl:if test="@line-height">
2033 <xsl:value-of select="@line-height" />
2034 </xsl:if>
2035 <xsl:if test="@style and contains(@style, 'line-height:')">
2036 <xsl:variable name="line_height" select="normalize-space(substring-after(@style, 'line-height:'))" />
2037 <xsl:choose>
2038 <xsl:when test="contains($line_height, ';')">
2039 <xsl:value-of select="substring-before($line_height, ';')" />
2040 </xsl:when>
2041 <xsl:otherwise>
2042 <xsl:value-of select="$line_height" />
2043 </xsl:otherwise>
2044 </xsl:choose>
2045 </xsl:if>
2046 </xsl:variable>
2047 <xsl:if test="$value != ''">
2048 <xsl:attribute name="lineHeight">
2049 <xsl:call-template name="convert_unit">
2050 <xsl:with-param name="convert_value" select="$value" />
2051 </xsl:call-template>
2052 </xsl:attribute>
2053 </xsl:if>
2054 </xsl:template>
2056 <!--
2057 // Text writing mode //
2058 SVG: writing-mode, FXG: blockProgression
2060 Values inverted in FXG...
2061 -->
2062 <xsl:template mode="writing_mode" match="*">
2063 <xsl:variable name="value">
2064 <xsl:if test="@writing-mode">
2065 <xsl:value-of select="@writing-mode" />
2066 </xsl:if>
2067 <xsl:if test="@style and contains(@style, 'writing-mode:') and not(contains(substring-after(@style, 'writing-mode:'), ';'))">
2068 <xsl:value-of select="substring-after(@style, 'writing-mode:')" />
2069 </xsl:if>
2070 <xsl:if test="@style and contains(@style, 'writing-mode:') and contains(substring-after(@style, 'writing-mode:'), ';')">
2071 <xsl:value-of select="substring-before(substring-after(@style, 'writing-mode:'), ';')" />
2072 </xsl:if>
2073 </xsl:variable>
2074 <xsl:if test="$value != ''">
2075 <xsl:attribute name="blockProgression">
2076 <xsl:choose>
2077 <xsl:when test="$value='tb'">rl</xsl:when>
2078 <xsl:otherwise>tb</xsl:otherwise>
2079 </xsl:choose>
2080 </xsl:attribute>
2081 <xsl:if test="$value='tb'">
2082 <xsl:attribute name="textRotation">rotate270</xsl:attribute>
2083 </xsl:if>
2084 </xsl:if>
2085 </xsl:template>
2087 <!--
2088 // Text decoration //
2089 SVG: text-decoration, FXG: textDecoration, lineThrough
2090 -->
2091 <xsl:template mode="text_decoration" match="*">
2092 <xsl:variable name="value">
2093 <xsl:if test="@text-decoration">
2094 <xsl:value-of select="@text-decoration" />
2095 </xsl:if>
2096 <xsl:if test="@style and contains(@style, 'text-decoration:') and not(contains(substring-after(@style, 'text-decoration:'), ';'))">
2097 <xsl:value-of select="substring-after(@style, 'text-decoration:')" />
2098 </xsl:if>
2099 <xsl:if test="@style and contains(@style, 'text-decoration:') and contains(substring-after(@style, 'text-decoration:'), ';')">
2100 <xsl:value-of select="substring-before(substring-after(@style, 'text-decoration:'), ';')" />
2101 </xsl:if>
2102 </xsl:variable>
2103 <xsl:if test="$value != ''">
2104 <xsl:choose>
2105 <xsl:when test="$value='underline'">
2106 <xsl:attribute name="textDecoration">underline</xsl:attribute>
2107 </xsl:when>
2108 <xsl:when test="$value='line-through'">
2109 <xsl:attribute name="lineThrough">true</xsl:attribute>
2110 </xsl:when>
2111 </xsl:choose>
2112 </xsl:if>
2113 </xsl:template>
2115 <!--
2116 // Text fill //
2117 SVG: fill, fill-opacity, FXG: color, textAlpha
2118 -->
2119 <xsl:template mode="text_fill" match="*">
2120 <xsl:variable name="fill">
2121 <xsl:apply-templates mode="fill" select="." />
2122 </xsl:variable>
2123 <xsl:variable name="fill_opacity">
2124 <xsl:apply-templates mode="fill_opacity" select="." />
2125 </xsl:variable>
2126 <xsl:if test="starts-with($fill, '#') or (not(starts-with($fill, 'url')) and $fill != '' and $fill != 'none')">
2127 <xsl:attribute name="color">
2128 <xsl:call-template name="template_color">
2129 <xsl:with-param name="colorspec">
2130 <xsl:value-of select="$fill" />
2131 </xsl:with-param>
2132 </xsl:call-template>
2133 </xsl:attribute>
2134 <xsl:attribute name="textAlpha">
2135 <xsl:value-of select="$fill_opacity" />
2136 </xsl:attribute>
2137 </xsl:if>
2138 </xsl:template>
2140 <!--
2141 // Text direction //
2142 SVG: direction, unicode-bidi, FXG: direction
2143 -->
2144 <xsl:template mode="direction" match="*">
2145 <xsl:variable name="value">
2146 <xsl:if test="@direction">
2147 <xsl:value-of select="@direction" />
2148 </xsl:if>
2149 <xsl:if test="@style and contains(@style, 'direction:') and not(contains(substring-after(@style, 'direction:'), ';'))">
2150 <xsl:value-of select="substring-after(@style, 'direction:')" />
2151 </xsl:if>
2152 <xsl:if test="@style and contains(@style, 'direction:') and contains(substring-after(@style, 'direction:'), ';')">
2153 <xsl:value-of select="substring-before(substring-after(@style, 'direction:'), ';')" />
2154 </xsl:if>
2155 </xsl:variable>
2156 <xsl:variable name="bidi">
2157 <xsl:if test="@unicode-bidi">
2158 <xsl:value-of select="@unicode-bidi" />
2159 </xsl:if>
2160 <xsl:if test="@style and contains(@style, 'unicode-bidi:') and not(contains(substring-after(@style, 'unicode-bidi:'), ';'))">
2161 <xsl:value-of select="substring-after(@style, 'unicode-bidi:')" />
2162 </xsl:if>
2163 <xsl:if test="@style and contains(@style, 'unicode-bidi:') and contains(substring-after(@style, 'unicode-bidi:'), ';')">
2164 <xsl:value-of select="substring-before(substring-after(@style, 'unicode-bidi:'), ';')" />
2165 </xsl:if>
2166 </xsl:variable>
2168 <xsl:if test="$value != '' and ($bidi='embed' or $bidi='bidi-override')">
2169 <xsl:attribute name="direction">
2170 <xsl:choose>
2171 <xsl:when test="$value='ltr'">ltr</xsl:when>
2172 <xsl:when test="$value='rtl'">rtl</xsl:when>
2173 </xsl:choose>
2174 </xsl:attribute>
2175 </xsl:if>
2176 </xsl:template>
2178 <!--
2179 // Text size //
2180 -->
2181 <xsl:template mode="text_size" match="*">
2182 <xsl:if test="@width">
2183 <xsl:attribute name="width">
2184 <xsl:call-template name="convert_unit">
2185 <xsl:with-param name="convert_value" select="@width" />
2186 </xsl:call-template>
2187 </xsl:attribute>
2188 </xsl:if>
2189 <xsl:if test="@height">
2190 <xsl:attribute name="height">
2191 <xsl:call-template name="convert_unit">
2192 <xsl:with-param name="convert_value" select="@height" />
2193 </xsl:call-template>
2194 </xsl:attribute>
2195 </xsl:if>
2196 </xsl:template>
2198 <!--
2199 // Text position //
2200 -->
2201 <xsl:template mode="text_position" match="*">
2202 <!-- Keep the first x value only -->
2203 <xsl:if test="@x">
2204 <xsl:attribute name="x">
2205 <xsl:choose>
2206 <xsl:when test="contains(@x, ' ')">
2207 <xsl:call-template name="convert_unit">
2208 <xsl:with-param name="convert_value" select="substring-before(@x, ' ')" />
2209 </xsl:call-template>
2210 </xsl:when>
2211 <xsl:otherwise>
2212 <xsl:call-template name="convert_unit">
2213 <xsl:with-param name="convert_value" select="@x" />
2214 </xsl:call-template>
2215 </xsl:otherwise>
2216 </xsl:choose>
2217 </xsl:attribute>
2218 </xsl:if>
2219 <!-- Keep the first y value only -->
2220 <xsl:if test="@y">
2221 <xsl:attribute name="y">
2222 <xsl:choose>
2223 <xsl:when test="contains(@y, ' ')">
2224 <xsl:call-template name="convert_unit">
2225 <xsl:with-param name="convert_value" select="substring-before(@y, ' ')" />
2226 </xsl:call-template>
2227 </xsl:when>
2228 <xsl:otherwise>
2229 <xsl:call-template name="convert_unit">
2230 <xsl:with-param name="convert_value" select="@y" />
2231 </xsl:call-template>
2232 </xsl:otherwise>
2233 </xsl:choose>
2234 </xsl:attribute>
2235 </xsl:if>
2236 </xsl:template>
2239 <!--
2240 // Text objects //
2241 SVG: text, FXG: RichText
2243 Not supported by FXG:
2244 * Generic fonts.
2245 * Embedded fonts (in defs).
2246 * Character rotation.
2247 * Character positionning (x and y).
2248 * Text-anchor.
2249 * Text stroke.
2251 Partial support:
2252 * Text rotation (0, 90, 180 and 270 degrees only) -> not implemented.
2253 * Font weight (normal and bold only) -> values under 500 are considered normal, the others bold.
2254 * Whitespace handling, issues with xml:whitespace='preserve'.
2255 -->
2256 <xsl:template mode="forward" match="*[name(.) = 'text']">
2257 <xsl:variable name="object">
2258 <RichText>
2259 <!-- Force default baseline to "ascent" -->
2260 <xsl:attribute name="alignmentBaseline">ascent</xsl:attribute>
2262 <xsl:apply-templates mode="font_size" select="." />
2263 <xsl:apply-templates mode="font_weight" select="." />
2264 <xsl:apply-templates mode="font_family" select="." />
2265 <xsl:apply-templates mode="font_style" select="." />
2266 <xsl:apply-templates mode="text_fill" select="." />
2267 <xsl:apply-templates mode="text_decoration" select="." />
2268 <xsl:apply-templates mode="line_height" select="." />
2269 <xsl:apply-templates mode="text_size" select="." />
2270 <xsl:apply-templates mode="text_position" select="." />
2271 <xsl:apply-templates mode="direction" select="." />
2272 <xsl:apply-templates mode="writing_mode" select="." />
2273 <xsl:apply-templates mode="id" select="." />
2275 <xsl:if test="not(*[name(.) = 'tspan']/text())">
2276 <xsl:attribute name="whiteSpaceCollapse">preserve</xsl:attribute>
2277 </xsl:if>
2279 <xsl:apply-templates mode="filter_effect" select="." />
2280 <xsl:apply-templates mode="desc" select="." />
2282 <!--xsl:apply-templates mode="forward" /-->
2283 <content>
2284 <xsl:choose>
2285 <xsl:when test="*[name(.) = 'tspan']/text()">
2286 <xsl:apply-templates mode="forward" />
2287 </xsl:when>
2288 <xsl:otherwise>
2289 <xsl:choose>
2290 <xsl:when test="@xml:space='preserve'">
2291 <xsl:copy-of select="translate(text(), '	

', ' ')" />
2292 </xsl:when>
2293 <xsl:otherwise>
2294 <xsl:copy-of select="normalize-space(translate(text(), '	

', ' '))" />
2295 </xsl:otherwise>
2296 </xsl:choose>
2297 </xsl:otherwise>
2298 </xsl:choose>
2299 </content>
2300 </RichText>
2301 </xsl:variable>
2303 <xsl:variable name="clipped_object">
2304 <xsl:apply-templates mode="clip" select="." >
2305 <xsl:with-param name="object" select="$object" />
2306 <xsl:with-param name="clip_type" select="'clip'" />
2307 </xsl:apply-templates>
2308 </xsl:variable>
2310 <xsl:variable name="masked_object">
2311 <xsl:apply-templates mode="clip" select="." >
2312 <xsl:with-param name="object" select="$clipped_object" />
2313 <xsl:with-param name="clip_type" select="'mask'" />
2314 </xsl:apply-templates>
2315 </xsl:variable>
2317 <xsl:choose>
2318 <xsl:when test="@transform">
2319 <Group>
2320 <xsl:call-template name="object_transform">
2321 <xsl:with-param name="object" select="$masked_object" />
2322 <xsl:with-param name="transform" select="@transform" />
2323 </xsl:call-template>
2324 </Group>
2325 </xsl:when>
2326 <xsl:otherwise>
2327 <xsl:copy-of select="$masked_object" />
2328 </xsl:otherwise>
2329 </xsl:choose>
2330 </xsl:template>
2332 <!--
2333 // FlowRoot objects //
2334 SVG: flowRoot, FXG: RichText
2336 Not supported by FXG:
2337 * See text objects
2338 -->
2339 <xsl:template mode="forward" match="*[name(.) = 'flowRoot']">
2340 <xsl:variable name="object">
2341 <RichText>
2342 <!-- Force default baseline to "ascent" -->
2343 <xsl:attribute name="alignmentBaseline">ascent</xsl:attribute>
2345 <xsl:apply-templates mode="font_size" select="." />
2346 <xsl:apply-templates mode="font_weight" select="." />
2347 <xsl:apply-templates mode="font_family" select="." />
2348 <xsl:apply-templates mode="font_style" select="." />
2349 <xsl:apply-templates mode="text_fill" select="." />
2350 <xsl:apply-templates mode="text_decoration" select="." />
2351 <xsl:apply-templates mode="line_height" select="." />
2352 <xsl:apply-templates mode="direction" select="." />
2353 <xsl:apply-templates mode="writing_mode" select="." />
2354 <xsl:apply-templates mode="id" select="." />
2355 <xsl:apply-templates mode="flow_region" select="*[name(.) = 'flowRegion']/child::node()" />
2357 <xsl:apply-templates mode="filter_effect" select="." />
2358 <xsl:apply-templates mode="desc" select="." />
2360 <content>
2361 <xsl:choose>
2362 <xsl:when test="*[name(.) = 'flowPara' or name(.) = 'flowDiv']/text()">
2363 <xsl:apply-templates mode="forward" />
2364 </xsl:when>
2365 <xsl:otherwise>
2366 <xsl:choose>
2367 <xsl:when test="@xml:space='preserve'">
2368 <xsl:copy-of select="translate(text(), '	

', ' ')" />
2369 </xsl:when>
2370 <xsl:otherwise>
2371 <xsl:copy-of select="normalize-space(translate(text(), '	

', ' '))" />
2372 </xsl:otherwise>
2373 </xsl:choose>
2374 </xsl:otherwise>
2375 </xsl:choose>
2376 </content>
2377 </RichText>
2378 </xsl:variable>
2380 <xsl:variable name="clipped_object">
2381 <xsl:apply-templates mode="clip" select="." >
2382 <xsl:with-param name="object" select="$object" />
2383 <xsl:with-param name="clip_type" select="'clip'" />
2384 </xsl:apply-templates>
2385 </xsl:variable>
2387 <xsl:variable name="masked_object">
2388 <xsl:apply-templates mode="clip" select="." >
2389 <xsl:with-param name="object" select="$clipped_object" />
2390 <xsl:with-param name="clip_type" select="'mask'" />
2391 </xsl:apply-templates>
2392 </xsl:variable>
2394 <xsl:choose>
2395 <xsl:when test="@transform">
2396 <Group>
2397 <xsl:call-template name="object_transform">
2398 <xsl:with-param name="object" select="$masked_object" />
2399 <xsl:with-param name="transform" select="@transform" />
2400 </xsl:call-template>
2401 </Group>
2402 </xsl:when>
2403 <xsl:otherwise>
2404 <xsl:copy-of select="$masked_object" />
2405 </xsl:otherwise>
2406 </xsl:choose>
2407 </xsl:template>
2409 <!--
2410 // Shapes //
2412 * Lines
2413 * Rectangle
2414 * Path
2415 * Ellipse
2416 * Circle
2417 * Image
2418 * Polygon (not supported)
2419 * Polyline (not supported)
2420 -->
2422 <!--
2423 // Line object //
2424 SVG: line, FXG: Line
2425 -->
2426 <xsl:template mode="forward" match="*[name(.) = 'line']">
2427 <xsl:variable name="object">
2428 <Line>
2429 <xsl:if test="@x1">
2430 <xsl:attribute name="xFrom">
2431 <xsl:call-template name="convert_unit">
2432 <xsl:with-param name="convert_value" select="@x1" />
2433 </xsl:call-template>
2434 </xsl:attribute>
2435 </xsl:if>
2436 <xsl:if test="@y1">
2437 <xsl:attribute name="yFrom">
2438 <xsl:call-template name="convert_unit">
2439 <xsl:with-param name="convert_value" select="@y1" />
2440 </xsl:call-template>
2441 </xsl:attribute>
2442 </xsl:if>
2443 <xsl:if test="@x2">
2444 <xsl:attribute name="xTo">
2445 <xsl:call-template name="convert_unit">
2446 <xsl:with-param name="convert_value" select="@x2" />
2447 </xsl:call-template>
2448 </xsl:attribute>
2449 </xsl:if>
2450 <xsl:if test="@y2">
2451 <xsl:attribute name="yTo">
2452 <xsl:call-template name="convert_unit">
2453 <xsl:with-param name="convert_value" select="@y2" />
2454 </xsl:call-template>
2455 </xsl:attribute>
2456 </xsl:if>
2457 <xsl:apply-templates mode="object_opacity" select="." />
2458 <xsl:apply-templates mode="id" select="." />
2460 <xsl:apply-templates mode="template_fill" select="." />
2461 <xsl:apply-templates mode="template_stroke" select="." />
2462 <xsl:apply-templates mode="filter_effect" select="." />
2463 <xsl:apply-templates mode="desc" select="." />
2465 <xsl:apply-templates mode="forward" />
2466 </Line>
2467 </xsl:variable>
2469 <xsl:variable name="clipped_object">
2470 <xsl:apply-templates mode="clip" select="." >
2471 <xsl:with-param name="object" select="$object" />
2472 <xsl:with-param name="clip_type" select="'clip'" />
2473 </xsl:apply-templates>
2474 </xsl:variable>
2476 <xsl:variable name="masked_object">
2477 <xsl:apply-templates mode="clip" select="." >
2478 <xsl:with-param name="object" select="$clipped_object" />
2479 <xsl:with-param name="clip_type" select="'mask'" />
2480 </xsl:apply-templates>
2481 </xsl:variable>
2483 <xsl:choose>
2484 <xsl:when test="@transform">
2485 <Group>
2486 <xsl:call-template name="object_transform">
2487 <xsl:with-param name="object" select="$masked_object" />
2488 <xsl:with-param name="transform" select="@transform" />
2489 </xsl:call-template>
2490 </Group>
2491 </xsl:when>
2492 <xsl:otherwise>
2493 <xsl:copy-of select="$masked_object" />
2494 </xsl:otherwise>
2495 </xsl:choose>
2496 </xsl:template>
2498 <!--
2499 // Rectangle object //
2500 SVG: rect, FXG: Rect
2501 -->
2502 <xsl:template mode="forward" match="*[name(.) = 'rect']">
2503 <xsl:variable name="object">
2504 <Rect>
2505 <xsl:if test="@x">
2506 <xsl:attribute name="x">
2507 <xsl:call-template name="convert_unit">
2508 <xsl:with-param name="convert_value" select="@x" />
2509 </xsl:call-template>
2510 </xsl:attribute>
2511 </xsl:if>
2512 <xsl:if test="@y">
2513 <xsl:attribute name="y">
2514 <xsl:call-template name="convert_unit">
2515 <xsl:with-param name="convert_value" select="@y" />
2516 </xsl:call-template>
2517 </xsl:attribute>
2518 </xsl:if>
2519 <xsl:if test="@width">
2520 <xsl:attribute name="width">
2521 <xsl:call-template name="convert_unit">
2522 <xsl:with-param name="convert_value" select="@width" />
2523 </xsl:call-template>
2524 </xsl:attribute>
2525 </xsl:if>
2526 <xsl:if test="@height">
2527 <xsl:attribute name="height">
2528 <xsl:call-template name="convert_unit">
2529 <xsl:with-param name="convert_value" select="@height" />
2530 </xsl:call-template>
2531 </xsl:attribute>
2532 </xsl:if>
2533 <xsl:if test="@rx">
2534 <xsl:attribute name="radiusX">
2535 <xsl:value-of select="@rx" />
2536 </xsl:attribute>
2537 </xsl:if>
2538 <xsl:if test="@ry">
2539 <xsl:attribute name="radiusY">
2540 <xsl:value-of select="@ry" />
2541 </xsl:attribute>
2542 </xsl:if>
2543 <xsl:if test="@rx and not(@ry)">
2544 <xsl:attribute name="radiusX">
2545 <xsl:value-of select="@rx" />
2546 </xsl:attribute>
2547 <xsl:attribute name="radiusY">
2548 <xsl:value-of select="@rx" />
2549 </xsl:attribute>
2550 </xsl:if>
2551 <xsl:if test="@ry and not(@rx)">
2552 <xsl:attribute name="radiusX">
2553 <xsl:value-of select="@ry" />
2554 </xsl:attribute>
2555 <xsl:attribute name="radiusY">
2556 <xsl:value-of select="@ry" />
2557 </xsl:attribute>
2558 </xsl:if>
2559 <xsl:apply-templates mode="object_opacity" select="." />
2560 <xsl:apply-templates mode="id" select="." />
2562 <xsl:apply-templates mode="template_fill" select="." />
2563 <xsl:apply-templates mode="template_stroke" select="." />
2564 <xsl:apply-templates mode="filter_effect" select="." />
2565 <!-- <xsl:apply-templates mode="resources" select="." /> -->
2566 <xsl:apply-templates mode="desc" select="." />
2568 <xsl:apply-templates mode="forward" />
2569 </Rect>
2570 </xsl:variable>
2572 <xsl:variable name="clipped_object">
2573 <xsl:apply-templates mode="clip" select="." >
2574 <xsl:with-param name="object" select="$object" />
2575 <xsl:with-param name="clip_type" select="'clip'" />
2576 </xsl:apply-templates>
2577 </xsl:variable>
2579 <xsl:variable name="masked_object">
2580 <xsl:apply-templates mode="clip" select="." >
2581 <xsl:with-param name="object" select="$clipped_object" />
2582 <xsl:with-param name="clip_type" select="'mask'" />
2583 </xsl:apply-templates>
2584 </xsl:variable>
2586 <xsl:choose>
2587 <xsl:when test="@transform">
2588 <Group>
2589 <xsl:call-template name="object_transform">
2590 <xsl:with-param name="object" select="$masked_object" />
2591 <xsl:with-param name="transform" select="@transform" />
2592 </xsl:call-template>
2593 </Group>
2594 </xsl:when>
2595 <xsl:otherwise>
2596 <xsl:copy-of select="$masked_object" />
2597 </xsl:otherwise>
2598 </xsl:choose>
2599 </xsl:template>
2601 <!--
2602 // Path //
2603 SVG: path, FXG: Path
2605 Not supported by FXG:
2606 * elliptical arc curve commands (workaround: convert to path first)
2607 TODO:
2608 * Implement an arc to curve convertor
2609 -->
2610 <xsl:template mode="forward" match="*[name(.) = 'path']">
2611 <xsl:variable name="object">
2612 <Path>
2613 <!-- Path element -->
2614 <!-- Exclude arcs in order to prevent the mxml compiler from failing -->
2615 <xsl:if test="@d and not(contains(@d, 'a') or contains(@d, 'A'))">
2616 <xsl:attribute name="data">
2617 <xsl:value-of select="normalize-space(translate(@d , ',', ' '))" />
2618 </xsl:attribute>
2619 </xsl:if>
2620 <xsl:apply-templates mode="fill_rule" select="." />
2621 <xsl:apply-templates mode="object_opacity" select="." />
2622 <xsl:apply-templates mode="id" select="." />
2624 <!-- Child elements -->
2625 <xsl:apply-templates mode="template_fill" select="." />
2626 <xsl:apply-templates mode="template_stroke" select="." />
2627 <xsl:apply-templates mode="filter_effect" select="." />
2628 <xsl:apply-templates mode="desc" select="." />
2630 <xsl:apply-templates mode="forward" />
2631 </Path>
2632 </xsl:variable>
2634 <xsl:variable name="clipped_object">
2635 <xsl:apply-templates mode="clip" select="." >
2636 <xsl:with-param name="object" select="$object" />
2637 <xsl:with-param name="clip_type" select="'clip'" />
2638 </xsl:apply-templates>
2639 </xsl:variable>
2641 <xsl:variable name="masked_object">
2642 <xsl:apply-templates mode="clip" select="." >
2643 <xsl:with-param name="object" select="$clipped_object" />
2644 <xsl:with-param name="clip_type" select="'mask'" />
2645 </xsl:apply-templates>
2646 </xsl:variable>
2648 <xsl:choose>
2649 <xsl:when test="@transform">
2650 <Group>
2651 <xsl:call-template name="object_transform">
2652 <xsl:with-param name="object" select="$masked_object" />
2653 <xsl:with-param name="transform" select="@transform" />
2654 </xsl:call-template>
2655 </Group>
2656 </xsl:when>
2657 <xsl:otherwise>
2658 <xsl:copy-of select="$masked_object" />
2659 </xsl:otherwise>
2660 </xsl:choose>
2661 <xsl:if test="contains(@d, 'a') or contains(@d, 'A')">
2662 <xsl:comment><xsl:value-of select="'Elliptic arc command in path data not supported, please convert to path (arcs are thus converted to curves) before exporting.'" /></xsl:comment>
2663 </xsl:if>
2664 </xsl:template>
2666 <!--
2667 // Ellipse object //
2668 SVG: ellipse, FXG: Ellipse
2669 -->
2670 <xsl:template mode="forward" match="*[name(.) = 'ellipse']">
2671 <xsl:variable name="object">
2672 <Ellipse>
2673 <xsl:variable name="cx">
2674 <xsl:choose>
2675 <xsl:when test="@cx">
2676 <xsl:call-template name="convert_unit">
2677 <xsl:with-param name="convert_value" select="@cx" />
2678 </xsl:call-template>
2679 </xsl:when>
2680 <xsl:otherwise>0</xsl:otherwise>
2681 </xsl:choose>
2682 </xsl:variable>
2683 <xsl:variable name="cy">
2684 <xsl:choose>
2685 <xsl:when test="@cy">
2686 <xsl:call-template name="convert_unit">
2687 <xsl:with-param name="convert_value" select="@cy" />
2688 </xsl:call-template>
2689 </xsl:when>
2690 <xsl:otherwise>0</xsl:otherwise>
2691 </xsl:choose>
2692 </xsl:variable>
2693 <xsl:variable name="rx">
2694 <xsl:choose>
2695 <xsl:when test="@rx">
2696 <xsl:call-template name="convert_unit">
2697 <xsl:with-param name="convert_value" select="@rx" />
2698 </xsl:call-template>
2699 </xsl:when>
2700 <xsl:otherwise>0</xsl:otherwise>
2701 </xsl:choose>
2702 </xsl:variable>
2703 <xsl:variable name="ry">
2704 <xsl:choose>
2705 <xsl:when test="@ry">
2706 <xsl:call-template name="convert_unit">
2707 <xsl:with-param name="convert_value" select="@ry" />
2708 </xsl:call-template>
2709 </xsl:when>
2710 <xsl:otherwise>0</xsl:otherwise>
2711 </xsl:choose>
2712 </xsl:variable>
2714 <xsl:choose>
2715 <xsl:when test="$rx != 0">
2716 <xsl:attribute name="x">
2717 <xsl:value-of select='format-number($cx - $rx, "#.#")' />
2718 </xsl:attribute>
2719 <xsl:attribute name="width">
2720 <xsl:value-of select='format-number(2 * $rx, "#.#")' />
2721 </xsl:attribute>
2722 </xsl:when>
2723 <xsl:otherwise>
2724 <xsl:attribute name="x">
2725 <xsl:value-of select='format-number($cx, "#.#")' />
2726 </xsl:attribute>
2727 <xsl:attribute name="width">0</xsl:attribute>
2728 </xsl:otherwise>
2729 </xsl:choose>
2730 <xsl:choose>
2731 <xsl:when test="$ry != 0">
2732 <xsl:attribute name="y">
2733 <xsl:value-of select='format-number($cy - $ry, "#.#")' />
2734 </xsl:attribute>
2735 <xsl:attribute name="height">
2736 <xsl:value-of select='format-number(2 * $ry, "#.#")' />
2737 </xsl:attribute>
2738 </xsl:when>
2739 <xsl:otherwise>
2740 <xsl:attribute name="y">
2741 <xsl:value-of select='format-number($cy, "#.#")' />
2742 </xsl:attribute>
2743 <xsl:attribute name="height">0</xsl:attribute>
2744 </xsl:otherwise>
2745 </xsl:choose>
2746 <xsl:apply-templates mode="object_opacity" select="." />
2747 <xsl:apply-templates mode="id" select="." />
2749 <!-- Child elements -->
2750 <xsl:apply-templates mode="template_fill" select="." />
2751 <xsl:apply-templates mode="template_stroke" select="." />
2752 <xsl:apply-templates mode="filter_effect" select="." />
2753 <xsl:apply-templates mode="desc" select="." />
2755 <xsl:apply-templates mode="forward" />
2756 </Ellipse>
2757 </xsl:variable>
2759 <xsl:variable name="clipped_object">
2760 <xsl:apply-templates mode="clip" select="." >
2761 <xsl:with-param name="object" select="$object" />
2762 <xsl:with-param name="clip_type" select="'clip'" />
2763 </xsl:apply-templates>
2764 </xsl:variable>
2766 <xsl:variable name="masked_object">
2767 <xsl:apply-templates mode="clip" select="." >
2768 <xsl:with-param name="object" select="$clipped_object" />
2769 <xsl:with-param name="clip_type" select="'mask'" />
2770 </xsl:apply-templates>
2771 </xsl:variable>
2773 <xsl:choose>
2774 <xsl:when test="@transform">
2775 <Group>
2776 <xsl:call-template name="object_transform">
2777 <xsl:with-param name="object" select="$masked_object" />
2778 <xsl:with-param name="transform" select="@transform" />
2779 </xsl:call-template>
2780 </Group>
2781 </xsl:when>
2782 <xsl:otherwise>
2783 <xsl:copy-of select="$masked_object" />
2784 </xsl:otherwise>
2785 </xsl:choose>
2786 </xsl:template>
2788 <!--
2789 // Circle object //
2790 SVG: circle, FXG: Ellipse
2791 -->
2792 <xsl:template mode="forward" match="*[name(.) = 'circle']">
2793 <xsl:variable name="object">
2794 <Ellipse>
2795 <xsl:variable name="cx">
2796 <xsl:choose>
2797 <xsl:when test="@cx">
2798 <xsl:call-template name="convert_unit">
2799 <xsl:with-param name="convert_value" select="@cx" />
2800 </xsl:call-template>
2801 </xsl:when>
2802 <xsl:otherwise>0</xsl:otherwise>
2803 </xsl:choose>
2804 </xsl:variable>
2805 <xsl:variable name="cy">
2806 <xsl:choose>
2807 <xsl:when test="@cy">
2808 <xsl:call-template name="convert_unit">
2809 <xsl:with-param name="convert_value" select="@cy" />
2810 </xsl:call-template>
2811 </xsl:when>
2812 <xsl:otherwise>0</xsl:otherwise>
2813 </xsl:choose>
2814 </xsl:variable>
2815 <xsl:variable name="r">
2816 <xsl:choose>
2817 <xsl:when test="@r">
2818 <xsl:call-template name="convert_unit">
2819 <xsl:with-param name="convert_value" select="@r" />
2820 </xsl:call-template>
2821 </xsl:when>
2822 <xsl:otherwise>0</xsl:otherwise>
2823 </xsl:choose>
2824 </xsl:variable>
2826 <xsl:choose>
2827 <xsl:when test="$r != 0">
2828 <xsl:attribute name="x">
2829 <xsl:value-of select='format-number($cx - $r, "#.#")' />
2830 </xsl:attribute>
2831 <xsl:attribute name="y">
2832 <xsl:value-of select='format-number($cy - $r, "#.#")' />
2833 </xsl:attribute>
2834 <xsl:attribute name="width">
2835 <xsl:value-of select='format-number(2 * $r, "#.#")' />
2836 </xsl:attribute>
2837 <xsl:attribute name="height">
2838 <xsl:value-of select='format-number(2 * $r, "#.#")' />
2839 </xsl:attribute>
2840 </xsl:when>
2841 <xsl:otherwise>
2842 <xsl:attribute name="x">
2843 <xsl:value-of select='format-number($cx, "#.#")' />
2844 </xsl:attribute>
2845 <xsl:attribute name="y">
2846 <xsl:value-of select='format-number($cy, "#.#")' />
2847 </xsl:attribute>
2848 <xsl:attribute name="width">0</xsl:attribute>
2849 <xsl:attribute name="height">0</xsl:attribute>
2850 </xsl:otherwise>
2851 </xsl:choose>
2852 <xsl:apply-templates mode="object_opacity" select="." />
2853 <xsl:apply-templates mode="id" select="." />
2855 <!-- Child elements -->
2856 <xsl:apply-templates mode="template_fill" select="." />
2857 <xsl:apply-templates mode="template_stroke" select="." />
2858 <xsl:apply-templates mode="filter_effect" select="." />
2859 <xsl:apply-templates mode="desc" select="." />
2861 <xsl:apply-templates mode="forward" />
2862 </Ellipse>
2863 </xsl:variable>
2865 <xsl:variable name="clipped_object">
2866 <xsl:apply-templates mode="clip" select="." >
2867 <xsl:with-param name="object" select="$object" />
2868 <xsl:with-param name="clip_type" select="'clip'" />
2869 </xsl:apply-templates>
2870 </xsl:variable>
2872 <xsl:variable name="masked_object">
2873 <xsl:apply-templates mode="clip" select="." >
2874 <xsl:with-param name="object" select="$clipped_object" />
2875 <xsl:with-param name="clip_type" select="'mask'" />
2876 </xsl:apply-templates>
2877 </xsl:variable>
2879 <xsl:choose>
2880 <xsl:when test="@transform">
2881 <Group>
2882 <xsl:call-template name="object_transform">
2883 <xsl:with-param name="object" select="$masked_object" />
2884 <xsl:with-param name="transform" select="@transform" />
2885 </xsl:call-template>
2886 </Group>
2887 </xsl:when>
2888 <xsl:otherwise>
2889 <xsl:copy-of select="$masked_object" />
2890 </xsl:otherwise>
2891 </xsl:choose>
2892 </xsl:template>
2894 <!--
2895 // Image objects //
2896 SVG: image, FXG: Rect+BitmapFill
2898 Not supported by FXG:
2899 * Embedded images (base64).
2900 * Preserve ratio.
2901 -->
2902 <xsl:template mode="forward" match="*[name(.) = 'image']">
2903 <xsl:variable name="object">
2904 <Rect>
2905 <xsl:if test="@x">
2906 <xsl:attribute name="x">
2907 <xsl:call-template name="convert_unit">
2908 <xsl:with-param name="convert_value" select="@x" />
2909 </xsl:call-template>
2910 </xsl:attribute>
2911 </xsl:if>
2912 <xsl:if test="@y">
2913 <xsl:attribute name="y">
2914 <xsl:call-template name="convert_unit">
2915 <xsl:with-param name="convert_value" select="@y" />
2916 </xsl:call-template>
2917 </xsl:attribute>
2918 </xsl:if>
2919 <xsl:if test="@width">
2920 <xsl:attribute name="width">
2921 <xsl:call-template name="convert_unit">
2922 <xsl:with-param name="convert_value" select="@width" />
2923 </xsl:call-template>
2924 </xsl:attribute>
2925 </xsl:if>
2926 <xsl:if test="@height">
2927 <xsl:attribute name="height">
2928 <xsl:call-template name="convert_unit">
2929 <xsl:with-param name="convert_value" select="@height" />
2930 </xsl:call-template>
2931 </xsl:attribute>
2932 </xsl:if>
2933 <xsl:apply-templates mode="object_opacity" select="." />
2934 <xsl:apply-templates mode="id" select="." />
2936 <xsl:apply-templates mode="desc" select="." />
2938 <xsl:if test="@xlink:href">
2939 <fill>
2940 <BitmapFill>
2941 <xsl:attribute name="source">@Embed('<xsl:value-of select="@xlink:href"/>')</xsl:attribute>
2942 </BitmapFill>
2943 </fill>
2944 </xsl:if>
2946 <xsl:apply-templates mode="forward" />
2947 </Rect>
2948 </xsl:variable>
2950 <xsl:variable name="clipped_object">
2951 <xsl:apply-templates mode="clip" select="." >
2952 <xsl:with-param name="object" select="$object" />
2953 <xsl:with-param name="clip_type" select="'clip'" />
2954 </xsl:apply-templates>
2955 </xsl:variable>
2957 <xsl:variable name="masked_object">
2958 <xsl:apply-templates mode="clip" select="." >
2959 <xsl:with-param name="object" select="$clipped_object" />
2960 <xsl:with-param name="clip_type" select="'mask'" />
2961 </xsl:apply-templates>
2962 </xsl:variable>
2964 <xsl:choose>
2965 <xsl:when test="@transform">
2966 <Group>
2967 <xsl:call-template name="object_transform">
2968 <xsl:with-param name="object" select="$masked_object" />
2969 <xsl:with-param name="transform" select="@transform" />
2970 </xsl:call-template>
2971 </Group>
2972 </xsl:when>
2973 <xsl:otherwise>
2974 <xsl:copy-of select="$masked_object" />
2975 </xsl:otherwise>
2976 </xsl:choose>
2977 </xsl:template>
2979 <!--
2980 // Polygon object //
2981 !! Not supported !!
2982 -->
2983 <xsl:template mode="forward" match="*[name(.) = 'polygon']">
2984 <xsl:comment>FXG does not support polygons</xsl:comment>
2985 </xsl:template>
2987 <!--
2988 // Polyline object //
2989 !! Not supported !!
2990 -->
2991 <xsl:template mode="forward" match="*[name(.) = 'polyline']">
2992 <xsl:comment>FXG does not support polylines</xsl:comment>
2993 </xsl:template>
2995 </xsl:stylesheet>