7f809655bf5a0ce313dfb15ccedc0bbb51e1345f
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 * Baseline shift
1742 * Writing mode
1743 * Text decoration
1744 * Text direction
1745 * Text size
1746 * Text position
1747 -->
1749 <!--
1750 // Text span //
1751 SVG: tspan, flowSpan, FXG: span
1753 Not supported in FXG:
1754 * span position
1755 -->
1756 <xsl:template mode="forward" match="*[name(.) = 'tspan' or name(.) = 'flowSpan']">
1757 <span>
1758 <xsl:variable name="fill">
1759 <xsl:apply-templates mode="fill" select="." />
1760 </xsl:variable>
1761 <xsl:variable name="fill_opacity">
1762 <xsl:apply-templates mode="fill_opacity" select="." />
1763 </xsl:variable>
1764 <xsl:if test="starts-with($fill, '#') or (not(starts-with($fill, 'url')) and $fill != '' and $fill != 'none')">
1765 <xsl:attribute name="color">
1766 <xsl:call-template name="template_color">
1767 <xsl:with-param name="colorspec">
1768 <xsl:value-of select="$fill" />
1769 </xsl:with-param>
1770 </xsl:call-template>
1771 </xsl:attribute>
1772 <xsl:attribute name="textAlpha">
1773 <xsl:value-of select="$fill_opacity" />
1774 </xsl:attribute>
1775 </xsl:if>
1776 <xsl:apply-templates mode="font_size" select="." />
1777 <xsl:apply-templates mode="baseline_shift" select="." />
1778 <xsl:apply-templates mode="text_decoration" select="." />
1780 <xsl:if test="text()">
1781 <xsl:value-of select="text()" />
1782 </xsl:if>
1783 </span>
1784 </xsl:template>
1786 <!--
1787 // Text flowPara //
1788 SVG: flowPara, flowDiv FXG: p
1790 Not supported in FXG:
1791 * paragraph position
1792 -->
1793 <xsl:template mode="forward" match="*[name(.) = 'flowPara' or name(.) = 'flowDiv']">
1794 <p>
1795 <xsl:variable name="fill">
1796 <xsl:apply-templates mode="fill" select="." />
1797 </xsl:variable>
1798 <xsl:variable name="fill_opacity">
1799 <xsl:apply-templates mode="fill_opacity" select="." />
1800 </xsl:variable>
1801 <xsl:if test="starts-with($fill, '#') or (not(starts-with($fill, 'url')) and $fill != '' and $fill != 'none')">
1802 <xsl:attribute name="color">
1803 <xsl:call-template name="template_color">
1804 <xsl:with-param name="colorspec">
1805 <xsl:value-of select="$fill" />
1806 </xsl:with-param>
1807 </xsl:call-template>
1808 </xsl:attribute>
1809 <xsl:attribute name="textAlpha">
1810 <xsl:value-of select="$fill_opacity" />
1811 </xsl:attribute>
1812 </xsl:if>
1813 <xsl:apply-templates mode="font_size" select="." />
1814 <xsl:apply-templates mode="baseline_shift" select="." />
1815 <xsl:apply-templates mode="text_decoration" select="." />
1817 <xsl:choose>
1818 <xsl:when test="*[name(.) = 'flowSpan']/text()">
1819 <xsl:apply-templates mode="forward" />
1820 </xsl:when>
1821 <xsl:otherwise>
1822 <xsl:choose>
1823 <xsl:when test="@xml:space='preserve'">
1824 <xsl:copy-of select="translate(text(), '	

', ' ')" />
1825 </xsl:when>
1826 <xsl:otherwise>
1827 <xsl:copy-of select="normalize-space(translate(text(), '	

', ' '))" />
1828 </xsl:otherwise>
1829 </xsl:choose>
1830 </xsl:otherwise>
1831 </xsl:choose>
1832 </p>
1833 </xsl:template>
1836 <!--
1837 // Text flowRegion //
1838 -->
1839 <xsl:template mode="flow_region" match="*">
1840 <xsl:apply-templates mode="text_size" select="." />
1841 <xsl:apply-templates mode="text_position" select="." />
1842 </xsl:template>
1844 <!--
1845 // Text font size //
1846 SVG: font-size, FXG: fontSize
1847 -->
1848 <xsl:template mode="font_size" match="*">
1849 <xsl:variable name="value">
1850 <xsl:if test="@font-size">
1851 <xsl:value-of select="@font-size" />
1852 </xsl:if>
1853 <xsl:if test="@style and contains(@style, 'font-size:')">
1854 <xsl:variable name="font_size" select="normalize-space(substring-after(@style, 'font-size:'))" />
1855 <xsl:choose>
1856 <xsl:when test="contains($font_size, ';')">
1857 <xsl:value-of select="substring-before($font_size, ';')" />
1858 </xsl:when>
1859 <xsl:otherwise>
1860 <xsl:value-of select="$font_size" />
1861 </xsl:otherwise>
1862 </xsl:choose>
1863 </xsl:if>
1864 </xsl:variable>
1865 <xsl:if test="$value != ''">
1866 <xsl:attribute name="fontSize">
1867 <xsl:call-template name="convert_unit">
1868 <xsl:with-param name="convert_value" select="$value" />
1869 </xsl:call-template>
1870 </xsl:attribute>
1871 </xsl:if>
1872 </xsl:template>
1874 <!--
1875 // Text baseline shift //
1876 SVG: baseline-shift, FXG: baselineShift
1877 -->
1878 <xsl:template mode="baseline_shift" match="*">
1879 <xsl:variable name="value">
1880 <xsl:if test="@baseline-shift">
1881 <xsl:value-of select="@baseline-shift" />
1882 </xsl:if>
1883 <xsl:if test="@style and contains(@style, 'baseline-shift:') and not(contains(substring-after(@style, 'baseline-shift:'), ';'))">
1884 <xsl:value-of select="substring-after(@style, 'baseline-shift:')" />
1885 </xsl:if>
1886 <xsl:if test="@style and contains(@style, 'baseline-shift:') and contains(substring-after(@style, 'baseline-shift:'), ';')">
1887 <xsl:value-of select="substring-before(substring-after(@style, 'baseline-shift:'), ';')" />
1888 </xsl:if>
1889 </xsl:variable>
1890 <xsl:if test="$value != ''">
1891 <xsl:attribute name="baselineShift">
1892 <xsl:choose>
1893 <xsl:when test="$value='baseline'">0</xsl:when>
1894 <xsl:when test="$value='super'">superscript</xsl:when>
1895 <xsl:when test="$value='sub'">subscript</xsl:when>
1896 <xsl:when test="translate($value, '%', '') < -1000">-1000</xsl:when>
1897 <xsl:when test="translate($value, '%', '') > 1000">1000</xsl:when>
1898 <xsl:otherwise>
1899 <xsl:value-of select="translate($value, '%', '')" />
1900 </xsl:otherwise>
1901 </xsl:choose>
1902 <xsl:if test="contains($value, '%')">%</xsl:if>
1903 </xsl:attribute>
1904 </xsl:if>
1905 </xsl:template>
1907 <!--
1908 // Text writing mode //
1909 SVG: writing-mode, FXG: blockProgression
1911 Values inverted in FXG...
1912 -->
1913 <xsl:template mode="writing_mode" match="*">
1914 <xsl:variable name="value">
1915 <xsl:if test="@writing-mode">
1916 <xsl:value-of select="@writing-mode" />
1917 </xsl:if>
1918 <xsl:if test="@style and contains(@style, 'writing-mode:') and not(contains(substring-after(@style, 'writing-mode:'), ';'))">
1919 <xsl:value-of select="substring-after(@style, 'writing-mode:')" />
1920 </xsl:if>
1921 <xsl:if test="@style and contains(@style, 'writing-mode:') and contains(substring-after(@style, 'writing-mode:'), ';')">
1922 <xsl:value-of select="substring-before(substring-after(@style, 'writing-mode:'), ';')" />
1923 </xsl:if>
1924 </xsl:variable>
1925 <xsl:if test="$value != ''">
1926 <xsl:attribute name="blockProgression">
1927 <xsl:choose>
1928 <xsl:when test="$value='tb'">rl</xsl:when>
1929 <xsl:otherwise>tb</xsl:otherwise>
1930 </xsl:choose>
1931 </xsl:attribute>
1932 <xsl:if test="$value='tb'">
1933 <xsl:attribute name="textRotation">rotate270</xsl:attribute>
1934 </xsl:if>
1935 </xsl:if>
1936 </xsl:template>
1938 <!--
1939 // Text decoration //
1940 SVG: text-decoration, FXG: textDecoration, lineThrough
1941 -->
1942 <xsl:template mode="text_decoration" match="*">
1943 <xsl:variable name="value">
1944 <xsl:if test="@text-decoration">
1945 <xsl:value-of select="@text-decoration" />
1946 </xsl:if>
1947 <xsl:if test="@style and contains(@style, 'text-decoration:') and not(contains(substring-after(@style, 'text-decoration:'), ';'))">
1948 <xsl:value-of select="substring-after(@style, 'text-decoration:')" />
1949 </xsl:if>
1950 <xsl:if test="@style and contains(@style, 'text-decoration:') and contains(substring-after(@style, 'text-decoration:'), ';')">
1951 <xsl:value-of select="substring-before(substring-after(@style, 'text-decoration:'), ';')" />
1952 </xsl:if>
1953 </xsl:variable>
1954 <xsl:if test="$value != ''">
1955 <xsl:choose>
1956 <xsl:when test="$value='underline'">
1957 <xsl:attribute name="textDecoration">underline</xsl:attribute>
1958 </xsl:when>
1959 <xsl:when test="$value='line-through'">
1960 <xsl:attribute name="lineThrough">true</xsl:attribute>
1961 </xsl:when>
1962 </xsl:choose>
1963 </xsl:if>
1964 </xsl:template>
1966 <!--
1967 // Text direction //
1968 SVG: direction, unicode-bidi, FXG: direction
1969 -->
1970 <xsl:template mode="direction" match="*">
1971 <xsl:variable name="value">
1972 <xsl:if test="@direction">
1973 <xsl:value-of select="@direction" />
1974 </xsl:if>
1975 <xsl:if test="@style and contains(@style, 'direction:') and not(contains(substring-after(@style, 'direction:'), ';'))">
1976 <xsl:value-of select="substring-after(@style, 'direction:')" />
1977 </xsl:if>
1978 <xsl:if test="@style and contains(@style, 'direction:') and contains(substring-after(@style, 'direction:'), ';')">
1979 <xsl:value-of select="substring-before(substring-after(@style, 'direction:'), ';')" />
1980 </xsl:if>
1981 </xsl:variable>
1982 <xsl:variable name="bidi">
1983 <xsl:if test="@unicode-bidi">
1984 <xsl:value-of select="@unicode-bidi" />
1985 </xsl:if>
1986 <xsl:if test="@style and contains(@style, 'unicode-bidi:') and not(contains(substring-after(@style, 'unicode-bidi:'), ';'))">
1987 <xsl:value-of select="substring-after(@style, 'unicode-bidi:')" />
1988 </xsl:if>
1989 <xsl:if test="@style and contains(@style, 'unicode-bidi:') and contains(substring-after(@style, 'unicode-bidi:'), ';')">
1990 <xsl:value-of select="substring-before(substring-after(@style, 'unicode-bidi:'), ';')" />
1991 </xsl:if>
1992 </xsl:variable>
1994 <xsl:if test="$value != '' and ($bidi='embed' or $bidi='bidi-override')">
1995 <xsl:attribute name="direction">
1996 <xsl:choose>
1997 <xsl:when test="$value='ltr'">ltr</xsl:when>
1998 <xsl:when test="$value='rtl'">rtl</xsl:when>
1999 </xsl:choose>
2000 </xsl:attribute>
2001 </xsl:if>
2002 </xsl:template>
2004 <!--
2005 // Text size //
2006 -->
2007 <xsl:template mode="text_size" match="*">
2008 <xsl:if test="@width">
2009 <xsl:attribute name="width">
2010 <xsl:call-template name="convert_unit">
2011 <xsl:with-param name="convert_value" select="@width" />
2012 </xsl:call-template>
2013 </xsl:attribute>
2014 </xsl:if>
2015 <xsl:if test="@height">
2016 <xsl:attribute name="height">
2017 <xsl:call-template name="convert_unit">
2018 <xsl:with-param name="convert_value" select="@height" />
2019 </xsl:call-template>
2020 </xsl:attribute>
2021 </xsl:if>
2022 </xsl:template>
2024 <!--
2025 // Text position //
2026 -->
2027 <xsl:template mode="text_position" match="*">
2028 <!-- Keep the first x value only -->
2029 <xsl:if test="@x">
2030 <xsl:attribute name="x">
2031 <xsl:choose>
2032 <xsl:when test="contains(@x, ' ')">
2033 <xsl:call-template name="convert_unit">
2034 <xsl:with-param name="convert_value" select="substring-before(@x, ' ')" />
2035 </xsl:call-template>
2036 </xsl:when>
2037 <xsl:otherwise>
2038 <xsl:call-template name="convert_unit">
2039 <xsl:with-param name="convert_value" select="@x" />
2040 </xsl:call-template>
2041 </xsl:otherwise>
2042 </xsl:choose>
2043 </xsl:attribute>
2044 </xsl:if>
2045 <!-- Keep the first y value only -->
2046 <xsl:if test="@y">
2047 <xsl:attribute name="y">
2048 <xsl:choose>
2049 <xsl:when test="contains(@y, ' ')">
2050 <xsl:call-template name="convert_unit">
2051 <xsl:with-param name="convert_value" select="substring-before(@y, ' ')" />
2052 </xsl:call-template>
2053 </xsl:when>
2054 <xsl:otherwise>
2055 <xsl:call-template name="convert_unit">
2056 <xsl:with-param name="convert_value" select="@y" />
2057 </xsl:call-template>
2058 </xsl:otherwise>
2059 </xsl:choose>
2060 </xsl:attribute>
2061 </xsl:if>
2062 </xsl:template>
2064 <!--
2065 // Objects //
2067 * Text
2068 * Lines
2069 * Rectangle
2070 * Path
2071 * Ellipse
2072 * Circle
2073 * Image
2074 * Polygon (not supported)
2075 * Polyline (not supported)
2076 -->
2078 <!--
2079 // Text objects //
2080 SVG: text, FXG: RichText
2082 Not supported by FXG:
2083 * Generic fonts.
2084 * Embedded fonts (in defs).
2085 * Character rotation.
2086 * Character positionning (x and y).
2087 * Text-anchor.
2088 * Text stroke.
2090 Partial support:
2091 * Text rotation (0, 90, 180 and 270 degrees only) -> not implemented.
2092 * Font weight (normal and bold only) -> values under 500 are considered normal, the others bold.
2093 * Whitespace handling, issues with xml:whitespace='preserve'.
2094 -->
2095 <xsl:template mode="forward" match="*[name(.) = 'text']">
2096 <xsl:variable name="object">
2097 <RichText>
2098 <xsl:apply-templates mode="font_size" select="." />
2100 <xsl:variable name="font_weight">
2101 <xsl:if test="@font-weight">
2102 <xsl:value-of select="@font-weight" />
2103 </xsl:if>
2104 <xsl:if test="@style and contains(@style, 'font-weight:') and not(contains(substring-after(@style, 'font-weight:'), ';'))">
2105 <xsl:value-of select="substring-after(@style, 'font-weight:')" />
2106 </xsl:if>
2107 <xsl:if test="@style and contains(@style, 'font-weight:') and contains(substring-after(@style, 'font-weight:'), ';')">
2108 <xsl:value-of select="substring-before(substring-after(@style, 'font-weight:'), ';')" />
2109 </xsl:if>
2110 </xsl:variable>
2111 <xsl:attribute name="fontWeight">
2112 <xsl:choose>
2113 <xsl:when test="$font_weight='normal' or $font_weight='bold'">
2114 <xsl:value-of select="$font_weight" />
2115 </xsl:when>
2116 <xsl:when test="$font_weight < 500 or $font_weight = 'lighter'">normal</xsl:when>
2117 <xsl:when test="$font_weight > 499 or $font_weight = 'bolder'">bold</xsl:when>
2118 <xsl:otherwise>normal</xsl:otherwise>
2119 </xsl:choose>
2120 </xsl:attribute>
2122 <xsl:if test="@font-family">
2123 <xsl:attribute name="fontFamily">
2124 <xsl:value-of select="translate(@font-family, "'", '')" />
2125 </xsl:attribute>
2126 </xsl:if>
2127 <xsl:if test="@style and contains(@style, 'font-family:')">
2128 <xsl:variable name="font_family" select="substring-after(@style, 'font-family:')" />
2129 <xsl:attribute name="fontFamily">
2130 <xsl:choose>
2131 <xsl:when test="contains($font_family, ';')">
2132 <xsl:value-of select="translate(substring-before($font_family, ';'), "'", '')" />
2133 </xsl:when>
2134 <xsl:otherwise>
2135 <xsl:value-of select="translate($font_family, "'", '')" />
2136 </xsl:otherwise>
2137 </xsl:choose>
2138 </xsl:attribute>
2139 </xsl:if>
2140 <xsl:if test="@font-style">
2141 <xsl:attribute name="fontStyle">
2142 <xsl:value-of select="@font-style" />
2143 </xsl:attribute>
2144 </xsl:if>
2145 <xsl:if test="@style and contains(@style, 'font-style:')">
2146 <xsl:variable name="font_style" select="substring-after(@style, 'font-style:')" />
2147 <xsl:attribute name="fontStyle">
2148 <xsl:choose>
2149 <xsl:when test="contains($font_style, ';')">
2150 <xsl:value-of select="substring-before($font_style, ';')" />
2151 </xsl:when>
2152 <xsl:otherwise>
2153 <xsl:value-of select="$font_style" />
2154 </xsl:otherwise>
2155 </xsl:choose>
2156 </xsl:attribute>
2157 </xsl:if>
2159 <xsl:variable name="fill">
2160 <xsl:apply-templates mode="fill" select="." />
2161 </xsl:variable>
2162 <xsl:variable name="fill_opacity">
2163 <xsl:apply-templates mode="fill_opacity" select="." />
2164 </xsl:variable>
2166 <xsl:if test="starts-with($fill, '#') or (not(starts-with($fill, 'url')) and $fill != '' and $fill != 'none')">
2167 <xsl:attribute name="color">
2168 <xsl:call-template name="template_color">
2169 <xsl:with-param name="colorspec">
2170 <xsl:value-of select="$fill" />
2171 </xsl:with-param>
2172 </xsl:call-template>
2173 </xsl:attribute>
2174 <xsl:attribute name="textAlpha">
2175 <xsl:value-of select="$fill_opacity" />
2176 </xsl:attribute>
2177 </xsl:if>
2179 <!-- Force default baseline to "ascent" -->
2180 <xsl:attribute name="alignmentBaseline">ascent</xsl:attribute>
2182 <xsl:if test="@xml:space='preserve'">
2183 <xsl:attribute name="whiteSpaceCollapse">preserve</xsl:attribute>
2184 </xsl:if>
2186 <xsl:apply-templates mode="text_size" select="." />
2187 <xsl:apply-templates mode="text_position" select="." />
2188 <xsl:apply-templates mode="text_decoration" select="." />
2189 <xsl:apply-templates mode="direction" select="." />
2190 <xsl:apply-templates mode="writing_mode" select="." />
2191 <xsl:apply-templates mode="id" select="." />
2193 <xsl:apply-templates mode="filter_effect" select="." />
2194 <xsl:apply-templates mode="desc" select="." />
2197 <!--xsl:apply-templates mode="forward" /-->
2198 <content>
2199 <xsl:choose>
2200 <xsl:when test="*[name(.) = 'tspan']/text()">
2201 <xsl:apply-templates mode="forward" />
2202 </xsl:when>
2203 <xsl:otherwise>
2204 <xsl:choose>
2205 <xsl:when test="@xml:space='preserve'">
2206 <xsl:copy-of select="translate(text(), '	

', ' ')" />
2207 </xsl:when>
2208 <xsl:otherwise>
2209 <xsl:copy-of select="normalize-space(translate(text(), '	

', ' '))" />
2210 </xsl:otherwise>
2211 </xsl:choose>
2212 </xsl:otherwise>
2213 </xsl:choose>
2214 </content>
2215 </RichText>
2216 </xsl:variable>
2218 <xsl:variable name="clipped_object">
2219 <xsl:apply-templates mode="clip" select="." >
2220 <xsl:with-param name="object" select="$object" />
2221 <xsl:with-param name="clip_type" select="'clip'" />
2222 </xsl:apply-templates>
2223 </xsl:variable>
2225 <xsl:variable name="masked_object">
2226 <xsl:apply-templates mode="clip" select="." >
2227 <xsl:with-param name="object" select="$clipped_object" />
2228 <xsl:with-param name="clip_type" select="'mask'" />
2229 </xsl:apply-templates>
2230 </xsl:variable>
2232 <xsl:choose>
2233 <xsl:when test="@transform">
2234 <Group>
2235 <xsl:call-template name="object_transform">
2236 <xsl:with-param name="object" select="$masked_object" />
2237 <xsl:with-param name="transform" select="@transform" />
2238 </xsl:call-template>
2239 </Group>
2240 </xsl:when>
2241 <xsl:otherwise>
2242 <xsl:copy-of select="$masked_object" />
2243 </xsl:otherwise>
2244 </xsl:choose>
2245 </xsl:template>
2247 <!--
2248 // FlowRoot objects //
2249 SVG: flowRoot, FXG: RichText
2251 Not supported by FXG:
2252 * See text objects
2253 -->
2254 <xsl:template mode="forward" match="*[name(.) = 'flowRoot']">
2255 <xsl:variable name="object">
2256 <RichText>
2257 <xsl:apply-templates mode="font_size" select="." />
2259 <xsl:variable name="font_weight">
2260 <xsl:if test="@font-weight">
2261 <xsl:value-of select="@font-weight" />
2262 </xsl:if>
2263 <xsl:if test="@style and contains(@style, 'font-weight:') and not(contains(substring-after(@style, 'font-weight:'), ';'))">
2264 <xsl:value-of select="substring-after(@style, 'font-weight:')" />
2265 </xsl:if>
2266 <xsl:if test="@style and contains(@style, 'font-weight:') and contains(substring-after(@style, 'font-weight:'), ';')">
2267 <xsl:value-of select="substring-before(substring-after(@style, 'font-weight:'), ';')" />
2268 </xsl:if>
2269 </xsl:variable>
2270 <xsl:attribute name="fontWeight">
2271 <xsl:choose>
2272 <xsl:when test="$font_weight='normal' or $font_weight='bold'">
2273 <xsl:value-of select="$font_weight" />
2274 </xsl:when>
2275 <xsl:when test="$font_weight < 500 or $font_weight = 'lighter'">normal</xsl:when>
2276 <xsl:when test="$font_weight > 499 or $font_weight = 'bolder'">bold</xsl:when>
2277 <xsl:otherwise>normal</xsl:otherwise>
2278 </xsl:choose>
2279 </xsl:attribute>
2281 <xsl:if test="@font-family">
2282 <xsl:attribute name="fontFamily">
2283 <xsl:value-of select="translate(@font-family, "'", '')" />
2284 </xsl:attribute>
2285 </xsl:if>
2286 <xsl:if test="@style and contains(@style, 'font-family:')">
2287 <xsl:variable name="font_family" select="substring-after(@style, 'font-family:')" />
2288 <xsl:attribute name="fontFamily">
2289 <xsl:choose>
2290 <xsl:when test="contains($font_family, ';')">
2291 <xsl:value-of select="translate(substring-before($font_family, ';'), "'", '')" />
2292 </xsl:when>
2293 <xsl:otherwise>
2294 <xsl:value-of select="translate($font_family, "'", '')" />
2295 </xsl:otherwise>
2296 </xsl:choose>
2297 </xsl:attribute>
2298 </xsl:if>
2299 <xsl:if test="@font-style">
2300 <xsl:attribute name="fontStyle">
2301 <xsl:value-of select="@font-style" />
2302 </xsl:attribute>
2303 </xsl:if>
2304 <xsl:if test="@style and contains(@style, 'font-style:')">
2305 <xsl:variable name="font_style" select="substring-after(@style, 'font-style:')" />
2306 <xsl:attribute name="fontStyle">
2307 <xsl:choose>
2308 <xsl:when test="contains($font_style, ';')">
2309 <xsl:value-of select="substring-before($font_style, ';')" />
2310 </xsl:when>
2311 <xsl:otherwise>
2312 <xsl:value-of select="$font_style" />
2313 </xsl:otherwise>
2314 </xsl:choose>
2315 </xsl:attribute>
2316 </xsl:if>
2318 <xsl:variable name="fill">
2319 <xsl:apply-templates mode="fill" select="." />
2320 </xsl:variable>
2321 <xsl:variable name="fill_opacity">
2322 <xsl:apply-templates mode="fill_opacity" select="." />
2323 </xsl:variable>
2325 <xsl:if test="starts-with($fill, '#') or (not(starts-with($fill, 'url')) and $fill != '' and $fill != 'none')">
2326 <xsl:attribute name="color">
2327 <xsl:call-template name="template_color">
2328 <xsl:with-param name="colorspec">
2329 <xsl:value-of select="$fill" />
2330 </xsl:with-param>
2331 </xsl:call-template>
2332 </xsl:attribute>
2333 <xsl:attribute name="textAlpha">
2334 <xsl:value-of select="$fill_opacity" />
2335 </xsl:attribute>
2336 </xsl:if>
2338 <!-- Force default baseline to "ascent" -->
2339 <xsl:attribute name="alignmentBaseline">ascent</xsl:attribute>
2341 <xsl:if test="@xml:space='preserve'">
2342 <xsl:attribute name="whiteSpaceCollapse">preserve</xsl:attribute>
2343 </xsl:if>
2345 <xsl:apply-templates mode="text_decoration" select="." />
2346 <xsl:apply-templates mode="direction" select="." />
2347 <xsl:apply-templates mode="writing_mode" select="." />
2348 <xsl:apply-templates mode="id" select="." />
2349 <xsl:apply-templates mode="flow_region" select="*[name(.) = 'flowRegion']/child::node()" />
2350 <xsl:apply-templates mode="filter_effect" select="." />
2351 <xsl:apply-templates mode="desc" select="." />
2353 <content>
2354 <xsl:choose>
2355 <xsl:when test="*[name(.) = 'flowPara' or name(.) = 'flowDiv']/text()">
2356 <xsl:apply-templates mode="forward" />
2357 </xsl:when>
2358 <xsl:otherwise>
2359 <xsl:choose>
2360 <xsl:when test="@xml:space='preserve'">
2361 <xsl:copy-of select="translate(text(), '	

', ' ')" />
2362 </xsl:when>
2363 <xsl:otherwise>
2364 <xsl:copy-of select="normalize-space(translate(text(), '	

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