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 * Get font size
1741 * Font size
1742 * Font weight
1743 * Font family
1744 * Font style
1745 * Baseline shift
1746 * Line height
1747 * Writing mode
1748 * Text decoration
1749 * Text fill
1750 * Text direction
1751 * Text size
1752 * Text position
1753 * Text object
1754 * FlowRoot object
1755 -->
1757 <!--
1758 // Text span //
1759 SVG: tspan, flowSpan, FXG: span
1761 Not supported in FXG:
1762 * span position
1763 -->
1764 <xsl:template mode="forward" match="*[name(.) = 'tspan' or name(.) = 'flowSpan']">
1765 <span>
1766 <xsl:if test="../@xml:space='preserve'">
1767 <xsl:attribute name="whiteSpaceCollapse">preserve</xsl:attribute>
1768 </xsl:if>
1769 <xsl:variable name="fill">
1770 <xsl:apply-templates mode="fill" select="." />
1771 </xsl:variable>
1772 <xsl:variable name="fill_opacity">
1773 <xsl:apply-templates mode="fill_opacity" select="." />
1774 </xsl:variable>
1775 <xsl:if test="starts-with($fill, '#') or (not(starts-with($fill, 'url')) and $fill != '' and $fill != 'none')">
1776 <xsl:attribute name="color">
1777 <xsl:call-template name="template_color">
1778 <xsl:with-param name="colorspec">
1779 <xsl:value-of select="$fill" />
1780 </xsl:with-param>
1781 </xsl:call-template>
1782 </xsl:attribute>
1783 <xsl:attribute name="textAlpha">
1784 <xsl:value-of select="$fill_opacity" />
1785 </xsl:attribute>
1786 </xsl:if>
1787 <xsl:apply-templates mode="font_size" select="." />
1788 <xsl:apply-templates mode="font_weight" select="." />
1789 <xsl:apply-templates mode="font_family" select="." />
1790 <xsl:apply-templates mode="font_style" select="." />
1791 <xsl:apply-templates mode="text_fill" select="." />
1792 <xsl:apply-templates mode="text_decoration" select="." />
1793 <xsl:apply-templates mode="line_height" select="." />
1794 <xsl:apply-templates mode="baseline_shift" select="." />
1796 <xsl:if test="text()">
1797 <xsl:value-of select="text()" />
1798 </xsl:if>
1799 </span>
1800 </xsl:template>
1802 <!--
1803 // Text flowPara //
1804 SVG: flowPara, flowDiv FXG: p
1806 Not supported in FXG:
1807 * paragraph position
1808 -->
1809 <xsl:template mode="forward" match="*[name(.) = 'flowPara' or name(.) = 'flowDiv']">
1810 <p>
1811 <xsl:if test="../@xml:space='preserve'">
1812 <xsl:attribute name="whiteSpaceCollapse">preserve</xsl:attribute>
1813 </xsl:if>
1814 <xsl:variable name="fill">
1815 <xsl:apply-templates mode="fill" select="." />
1816 </xsl:variable>
1817 <xsl:variable name="fill_opacity">
1818 <xsl:apply-templates mode="fill_opacity" select="." />
1819 </xsl:variable>
1820 <xsl:if test="starts-with($fill, '#') or (not(starts-with($fill, 'url')) and $fill != '' and $fill != 'none')">
1821 <xsl:attribute name="color">
1822 <xsl:call-template name="template_color">
1823 <xsl:with-param name="colorspec">
1824 <xsl:value-of select="$fill" />
1825 </xsl:with-param>
1826 </xsl:call-template>
1827 </xsl:attribute>
1828 <xsl:attribute name="textAlpha">
1829 <xsl:value-of select="$fill_opacity" />
1830 </xsl:attribute>
1831 </xsl:if>
1832 <xsl:apply-templates mode="font_size" select="." />
1833 <xsl:apply-templates mode="font_weight" select="." />
1834 <xsl:apply-templates mode="font_family" select="." />
1835 <xsl:apply-templates mode="font_style" select="." />
1836 <xsl:apply-templates mode="text_fill" select="." />
1837 <xsl:apply-templates mode="text_decoration" select="." />
1838 <xsl:apply-templates mode="line_height" select="." />
1839 <xsl:apply-templates mode="baseline_shift" select="." />
1841 <xsl:choose>
1842 <xsl:when test="*[name(.) = 'flowSpan']/text()">
1843 <xsl:apply-templates mode="forward" />
1844 </xsl:when>
1845 <xsl:otherwise>
1846 <xsl:choose>
1847 <xsl:when test="@xml:space='preserve'">
1848 <xsl:copy-of select="translate(text(), '	

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

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

', ' ')" />
2305 </xsl:when>
2306 <xsl:otherwise>
2307 <xsl:copy-of select="normalize-space(translate(text(), '	

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

', ' ')" />
2382 </xsl:when>
2383 <xsl:otherwise>
2384 <xsl:copy-of select="normalize-space(translate(text(), '	

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