diff options
Diffstat (limited to 'share/extensions')
49 files changed, 7683 insertions, 1857 deletions
diff --git a/share/extensions/Barcode/Base.py b/share/extensions/Barcode/Base.py index 398e877e9..8fee6a996 100644 --- a/share/extensions/Barcode/Base.py +++ b/share/extensions/Barcode/Base.py @@ -1,67 +1,63 @@ -#!/usr/bin/env python -''' -Copyright (C) 2007 Martin Owens - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -''' +# +# Copyright (C) 2010 Martin Owens +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +# +""" +Base module for rendering barcodes for Inkscape. +""" import itertools import sys from lxml import etree -class Barcode: +(WHITE_BAR, BLACK_BAR, TALL_BAR) = range(3) +TEXT_TEMPLATE = 'font-size:%dpx;text-align:center;text-anchor:middle;' + +class Barcode(object): + """Provide a base class for all barcode renderers""" + name = None + + def error(self, bar, msg): + """Cause an error to be reported""" + sys.stderr.write( + "Error encoding '%s' as %s barcode: %s\n" % (bar, self.name, msg)) + def __init__(self, param={}): - self.document = None - self.x = 0 - self.y = 0 - - if param.has_key('document'): - self.document = param['document'] - if param.has_key('x'): - self.x = param['x'] - if param.has_key('y'): - self.y = param['y'] - - if param.has_key('height'): - self.height = param['height'] - else: - self.height = 30 - - self.text = param['text'] - self.label = self.text - self.string = self.encode( self.text ) + self.document = param.get('document', None) + self.x = int(param.get('x', 0)) + self.y = int(param.get('y', 0)) + self.height = param.get('height', 30) + self.label = param.get('text', None) + self.string = self.encode( self.label ) + if not self.string: return + self.width = len(self.string) self.data = self.graphicalArray(self.string) def generate(self): + """Generate the actual svg from the coding""" svg_uri = u'http://www.w3.org/2000/svg' if not self.string or not self.data: return - - data = self.data; - - # create an SVG document if required - # if not self.document: - # self.document = UNKNOWN - if not self.document: - sys.stderr.write("No document defined to add barcode to\n") - return + return self.error("No document defined") + data = self.data # Collect document ids doc_ids = {} docIdNodes = self.document.xpath('//@id') @@ -81,10 +77,10 @@ class Barcode: barcode = etree.Element('{%s}%s' % (svg_uri,'g')) barcode.set('id', name) barcode.set('style', 'fill: black;') + barcode.set('transform', 'translate(%d,%d)' % (self.x, self.y)) - draw = 1 - wOffset = int(self.x) - id = 1 + bar_offset = 0 + bar_id = 1 for datum in data: # Datum 0 tells us what style of bar is to come next @@ -94,41 +90,41 @@ class Barcode: width = int(datum[1]) * int(style['width']) if style['write']: - # Add height for styles such as EA8 where - # the barcode goes into the text - rect = etree.SubElement(barcode,'{%s}%s' % (svg_uri,'rect')) - rect.set('x', str(wOffset)) + rect.set('x', str(bar_offset)) rect.set('y', str(style['top'])) rect.set('width', str(width)) rect.set('height', str(style['height'])) - rect.set('id', name + '_bar' + str(id)) - wOffset = int(wOffset) + int(width) - id = id + 1 + rect.set('id', "%s_bar%d" % (name, bar_id)) + bar_offset += width + bar_id += 1 - barwidth = wOffset - int(self.x) + bar_width = bar_offset # Add text at the bottom of the barcode text = etree.SubElement(barcode,'{%s}%s' % (svg_uri,'text')) - text.set( 'x', str(int(self.x) + int(barwidth / 2)) ) - text.set( 'y', str(int(self.height) + 10 + int(self.y)) ) - text.set( 'style', 'font-size:' + self.fontSize() + 'px;text-align:center;text-anchor:middle;' ) + text.set( 'x', str(int(bar_width / 2))) + text.set( 'y', str(self.height + self.fontSize() )) + text.set( 'style', TEXT_TEMPLATE % self.fontSize() ) text.set( '{http://www.w3.org/XML/1998/namespace}space', 'preserve' ) - text.set( 'id', name + '_bottomtext' ) - + text.set( 'id', '%s_text' % name ) text.text = str(self.label) - return barcode - # Converts black and white markers into a space array def graphicalArray(self, code): + """Converts black and white markets into a space array""" return [(x,len(list(y))) for x, y in itertools.groupby(code)] def getStyle(self, index): - result = { 'width' : 1, 'top' : int(self.y), 'write' : False } - if index==1: # Black Bar + """Returns the styles that should be applied to each bar""" + result = { 'width' : 1, 'top' : 0, 'write' : True } + if index == BLACK_BAR: result['height'] = int(self.height) - result['write'] = True + if index == TALL_BAR: + result['height'] = int(self.height) + int(self.fontSize() / 2) + if index == WHITE_BAR: + result['write'] = False return result def fontSize(self): - return '9' + """Return the ideal font size, defaults to 9px""" + return 9 diff --git a/share/extensions/Barcode/BaseEan.py b/share/extensions/Barcode/BaseEan.py new file mode 100644 index 000000000..05c9b1c39 --- /dev/null +++ b/share/extensions/Barcode/BaseEan.py @@ -0,0 +1,145 @@ +# +# Copyright (C) 2010 Martin Owens +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +# +""" +Some basic common code shared between EAN and UCP generators. +""" + +from Base import Barcode +import sys + +MAPPING = [ + # Left side of barcode Family '0' + [ "0001101", "0011001", "0010011", "0111101", "0100011", + "0110001", "0101111", "0111011", "0110111", "0001011" ], + # Left side of barcode Family '1' and flipped to right side. + [ "0100111", "0110011", "0011011", "0100001", "0011101", + "0111001", "0000101", "0010001", "0001001", "0010111" ], +] +# This chooses which of the two encodings above to use. +FAMILIES = [ '000000', '001011', '001101', '001110', '010011', + '011001', '011100', '010101', '010110', '011010' ] + +GUARD_BAR = '202' +CENTER_BAR = '02020' + +class EanBarcode(Barcode): + """Simple base class for all EAN type barcodes""" + length = None + lengths = None + checks = [] + + def intarray(self, number): + """Convert a string of digits into an array of ints""" + return [ int(i) for i in number ] + + + def encode_interleaved(self, family, number, fams=FAMILIES): + """Encode any side of the barcode, interleaved""" + result = [] + encset = self.intarray(fams[family]) + for i in range(len(number)): + thismap = MAPPING[encset[i]] + result.append( thismap[number[i]] ) + return result + + + def encode_right(self, number): + """Encode the right side of the barcode, non-interleaved""" + result = [] + for n in number: + # The right side is always the reverse of the left's family '1' + result.append( MAPPING[1][n][::-1] ) + return result + + + def encode_left(self, number): + """Encode the left side of the barcode, non-interleaved""" + result = [] + for n in number: + result.append( MAPPING[0][n] ) + return result + + + def space(self, *spacing): + """Space out an array of numbers""" + result = '' + for space in spacing: + if isinstance(space, list): + for i in space: + result += str(i) + elif isinstance(space, int): + result += ' ' * space + return result + + + def getLengths(self): + """Return a list of acceptable lengths""" + if self.length: + return [ self.length ] + return self.lengths[:] + + + def encode(self, code): + """Encode any EAN barcode""" + if not code.isdigit(): + return self.error(code, 'Not a Number, must be digits 0-9 only') + lengths = self.getLengths() + self.checks + + if len(code) not in lengths: + return self.error(code, 'Wrong size, must be %s digits' % + (', '.join(self.space(lengths)))) + + if self.checks: + if len(code) not in self.checks: + code = self.appendChecksum(code) + elif not self.verifyChecksum(code): + return self.error(code, 'Checksum failed, omit for new sum') + return self._encode(self.intarray(code)) + + + def _encode(self, n): + raise NotImplementedError("_encode should be provided by parent EAN") + + def enclose(self, left, right=[], guard=GUARD_BAR, center=CENTER_BAR): + """Standard Enclosure""" + parts = [ guard ] + left + [ center ] + right + [ guard ] + return ''.join( parts ) + + def getChecksum(self, number, magic=10): + """Generate a UPCA/EAN13/EAN8 Checksum""" + weight = [3,1] * len(number) + result = 0 + # We need to work from left to right so reverse + number = number[::-1] + # checksum based on first digits. + for i in range(len(number)): + result += int(number[i]) * weight[i] + # Modulous result to a single digit checksum + checksum = magic - (result % magic) + if checksum < 0 or checksum >= magic: + return '0' + return str(checksum) + + def appendChecksum(self, number): + """Apply the checksum to a short number""" + return number + self.getChecksum(number) + + def verifyChecksum(self, number): + """Verify any checksum""" + return self.getChecksum(number[:-1]) == number[-1] + diff --git a/share/extensions/Barcode/Code128.py b/share/extensions/Barcode/Code128.py index 3cb79b487..3036b5f98 100644 --- a/share/extensions/Barcode/Code128.py +++ b/share/extensions/Barcode/Code128.py @@ -1,27 +1,27 @@ -#!/usr/bin/env python -''' -Copyright (C) 2007 Martin Owens - -Debugged by Ralf Heinecke & Martin Siepmann 09/07/2007 -Debugged by Horst Schottky Feb. 27. 2010 - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - - - -''' +# +# Authored by Martin Owens <doctormo@ubuntu.com> +# Debugged by Ralf Heinecke & Martin Siepmann 2007-09-07 +# Horst Schottky 2010-02-27 +# +# Copyright (C) 2007 Martin Owens +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +# +""" +Python barcode renderer for Code128/EAN128 barcodes. Designed for use with Inkscape. +""" from Base import Barcode import math @@ -30,13 +30,13 @@ import re map = [ '11011001100','11001101100','11001100110','10010011000','10010001100','10001001100','10011001000','10011000100','10001100100','11001001000','11001000100','11000100100','10110011100','10011011100','10011001110','10111001100','10011101100','10011100110','11001110010','11001011100','11001001110','11011100100','11001110100','11101101110','11101001100','11100101100','11100100110','11101100100','11100110100','11100110010','11011011000','11011000110','11000110110','10100011000','10001011000','10001000110','10110001000','10001101000','10001100010','11010001000','11000101000','11000100010','10110111000','10110001110','10001101110','10111011000','10111000110','10001110110','11101110110','11010001110','11000101110','11011101000','11011100010','11011101110','11101011000','11101000110','11100010110','11101101000','11101100010','11100011010','11101111010','11001000010','11110001010','10100110000','10100001100','10010110000','10010000110','10000101100','10000100110','10110010000','10110000100','10011010000','10011000010','10000110100','10000110010','11000010010','11001010000','11110111010','11000010100','10001111010','10100111100','10010111100','10010011110','10111100100','10011110100','10011110010','11110100100','11110010100','11110010010','11011011110','11011110110','11110110110','10101111000','10100011110','10001011110','10111101000','10111100010','11110101000','11110100010','10111011110','10111101110','11101011110','11110101110','11010000100','11010010000','11010011100','11000111010','11' ] def mapExtra(sd, chars): - result = list(sd) - for char in chars: - result.append(chr(char)) - result.append('FNC3') - result.append('FNC2') - result.append('SHIFT') - return result + result = list(sd) + for char in chars: + result.append(chr(char)) + result.append('FNC3') + result.append('FNC2') + result.append('SHIFT') + return result # The mapExtra method is used to slim down the amount # of pre code and instead we generate the lists @@ -45,86 +45,86 @@ charA = mapExtra(charAB, range(0, 31)) # Offset 64 charB = mapExtra(charAB, range(96, 125)) # Offset -32 class Object(Barcode): - def encode(self, text): - result = '' - blocks = [] - block = '' - - # Split up into sections of numbers, or charicters - # This makes sure that all the charicters are encoded - # In the best way posible for Code128 - for datum in re.findall(r'(?:(?:\d\d){2,})|(?:^\d\d)|.', text): - if len(datum) == 1: - block = block + datum - else: - if block: - blocks.append(self.bestBlock(block)) - block = '' - blocks.append( [ 'C', datum ] ) - - if block: - blocks.append(self.bestBlock(block)) - block = ''; - - self.inclabel = text - return self.encodeBlocks(blocks) - - def bestBlock(self, block): - # If this has lower case then select B over A - if block.upper() == block: - return [ 'A', block ] - return [ 'B', block ] - - def encodeBlocks(self, blocks): - total = 0 - pos = 0 - encode = ''; - - for block in blocks: - set = block[0] - datum = block[1] - - # POS : 0, 1 - # A : 101, 103 - # B : 100, 104 - # C : 99, 105 - num = 0; - if set == 'A': - num = 103 - elif set == 'B': - num = 104 - elif set == 'C': - num = 105 - - i = pos - if pos: - num = 204 - num - else: - i = 1 - - total = total + num * i - encode = encode + map[num] - pos = pos + 1 - - if set == 'A' or set == 'B': - chars = charB - if set == 'A': - chars = charA - - for char in datum: - total = total + (chars.index(char) * pos) - encode = encode + map[chars.index(char)] - pos = pos + 1 - else: - for char in (datum[i:i+2] for i in range(0, len(datum), 2)): - total = total + (int(char) * pos) - encode = encode + map[int(char)] - pos = pos + 1 - - checksum = total % 103 - encode = encode + map[checksum] - encode = encode + map[106] - encode = encode + map[107] - - return encode + def encode(self, text): + result = '' + blocks = [] + block = '' + + # Split up into sections of numbers, or charicters + # This makes sure that all the charicters are encoded + # In the best way posible for Code128 + for datum in re.findall(r'(?:(?:\d\d){2,})|(?:^\d\d)|.', text): + if len(datum) == 1: + block = block + datum + else: + if block: + blocks.append(self.bestBlock(block)) + block = '' + blocks.append( [ 'C', datum ] ) + + if block: + blocks.append(self.bestBlock(block)) + block = ''; + + self.inclabel = text + return self.encodeBlocks(blocks) + + def bestBlock(self, block): + # If this has lower case then select B over A + if block.upper() == block: + return [ 'A', block ] + return [ 'B', block ] + + def encodeBlocks(self, blocks): + total = 0 + pos = 0 + encode = ''; + + for block in blocks: + set = block[0] + datum = block[1] + + # POS : 0, 1 + # A : 101, 103 + # B : 100, 104 + # C : 99, 105 + num = 0; + if set == 'A': + num = 103 + elif set == 'B': + num = 104 + elif set == 'C': + num = 105 + + i = pos + if pos: + num = 204 - num + else: + i = 1 + + total = total + num * i + encode = encode + map[num] + pos = pos + 1 + + if set == 'A' or set == 'B': + chars = charB + if set == 'A': + chars = charA + + for char in datum: + total = total + (chars.index(char) * pos) + encode = encode + map[chars.index(char)] + pos = pos + 1 + else: + for char in (datum[i:i+2] for i in range(0, len(datum), 2)): + total = total + (int(char) * pos) + encode = encode + map[int(char)] + pos = pos + 1 + + checksum = total % 103 + encode = encode + map[checksum] + encode = encode + map[106] + encode = encode + map[107] + + return encode diff --git a/share/extensions/Barcode/Code25i.py b/share/extensions/Barcode/Code25i.py new file mode 100644 index 000000000..518a306f2 --- /dev/null +++ b/share/extensions/Barcode/Code25i.py @@ -0,0 +1,78 @@ +# +# Copyright (C) 2010 Geoffrey Mosini +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +# +""" +Generate barcodes for Code25-interleaved 2 of 5, for Inkscape. +""" + +from Base import Barcode +import sys + +# 1 means thick, 0 means thin +encoding = { + '0' : '00110', + '1' : '10001', + '2' : '01001', + '3' : '11000', + '4' : '00101', + '5' : '10100', + '6' : '01100', + '7' : '00011', + '8' : '10010', + '9' : '01010', + +} + +# Start and stop code are already encoded into white (0) and black(1) bars +start_code = '1010' +stop_code = '1101' + +class Object(Barcode): + # Convert a text into string binary of black and white markers + def encode(self, number): + self.label = number + + if not number.isdigit(): + sys.stderr.write("CODE25 can only encode numbers.\n") + return + + # Number of figures to encode must be even, a 0 is added to the left in case it's odd. + if len(number) % 2 > 0 : + number = '0' + number + + # Number is encoded by pairs of 2 figures + size = len(number) / 2; + encoded = start_code; + for i in range(size): + # First in the pair is encoded in black (1), second in white (0) + black = encoding[number[i*2]] + white = encoding[number[i*2+1]] + for j in range(5): + if black[j] == '1': + encoded += '11' + else: + encoded += '1' + if white[j] == '1': + encoded += '00' + else: + encoded += '0' + + encoded += stop_code + + self.inclabel = number + return encoded; + diff --git a/share/extensions/Barcode/Code39.py b/share/extensions/Barcode/Code39.py index 78c8521f1..64b22f352 100644 --- a/share/extensions/Barcode/Code39.py +++ b/share/extensions/Barcode/Code39.py @@ -1,101 +1,103 @@ -#!/usr/bin/env python -''' -Copyright (C) 2007 Martin Owens - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -''' +# +# Copyright (C) 2007 Martin Owens +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +# +""" +Python barcode renderer for Code39 barcodes. Designed for use with Inkscape. +""" from Base import Barcode encoding = { - '0' : '000110100', - '1' : '100100001', - '2' : '001100001', - '3' : '101100000', - '4' : '000110001', - '5' : '100110000', - '6' : '001110000', - '7' : '000100101', - '8' : '100100100', - '9' : '001100100', - 'A' : '100001001', - 'B' : '001001001', - 'C' : '101001000', - 'D' : '000011001', - 'E' : '100011000', - 'F' : '001011000', - 'G' : '000001101', - 'H' : '100001100', - 'I' : '001001100', - 'J' : '000011100', - 'K' : '100000011', - 'L' : '001000011', - 'M' : '101000010', - 'N' : '000010011', - 'O' : '100010010', - 'P' : '001010010', - 'Q' : '000000111', - 'R' : '100000110', - 'S' : '001000110', - 'T' : '000010110', - 'U' : '110000001', - 'V' : '011000001', - 'W' : '111000000', - 'X' : '010010001', - 'Y' : '110010000', - 'Z' : '011010000', - '-' : '010000101', - '*' : '010010100', - '+' : '010001010', - '$' : '010101000', - '%' : '000101010', - '/' : '010100010', - '.' : '110000100', - ' ' : '011000100', + '0' : '000110100', + '1' : '100100001', + '2' : '001100001', + '3' : '101100000', + '4' : '000110001', + '5' : '100110000', + '6' : '001110000', + '7' : '000100101', + '8' : '100100100', + '9' : '001100100', + 'A' : '100001001', + 'B' : '001001001', + 'C' : '101001000', + 'D' : '000011001', + 'E' : '100011000', + 'F' : '001011000', + 'G' : '000001101', + 'H' : '100001100', + 'I' : '001001100', + 'J' : '000011100', + 'K' : '100000011', + 'L' : '001000011', + 'M' : '101000010', + 'N' : '000010011', + 'O' : '100010010', + 'P' : '001010010', + 'Q' : '000000111', + 'R' : '100000110', + 'S' : '001000110', + 'T' : '000010110', + 'U' : '110000001', + 'V' : '011000001', + 'W' : '111000000', + 'X' : '010010001', + 'Y' : '110010000', + 'Z' : '011010000', + '-' : '010000101', + '*' : '010010100', + '+' : '010001010', + '$' : '010101000', + '%' : '000101010', + '/' : '010100010', + '.' : '110000100', + ' ' : '011000100', } class Object(Barcode): - # Convert a text into string binary of black and white markers - def encode(self, text): - text = text.upper() - self.label = text - text = '*' + text + '*' - result = '' - # It isposible for us to encode code39 - # into full ascii, but this feature is - # not enabled here - for char in text: - if not encoding.has_key(char): - char = '-'; + # Convert a text into string binary of black and white markers + def encode(self, text): + text = text.upper() + self.label = text + text = '*' + text + '*' + result = '' + # It isposible for us to encode code39 + # into full ascii, but this feature is + # not enabled here + for char in text: + if not encoding.has_key(char): + char = '-'; - result = result + encoding[char] + '0'; + result = result + encoding[char] + '0'; - # Now we need to encode the code39, best read - # the code to understand what it's up to: - encoded = ''; - colour = '1'; # 1 = Black, 0 = White - for data in result: - if data == '1': - encoded = encoded + colour + colour - else: - encoded = encoded + colour - if colour == '1': - colour = '0' - else: - colour = '1' + # Now we need to encode the code39, best read + # the code to understand what it's up to: + encoded = ''; + colour = '1'; # 1 = Black, 0 = White + for data in result: + if data == '1': + encoded = encoded + colour + colour + else: + encoded = encoded + colour + if colour == '1': + colour = '0' + else: + colour = '1' - self.inclabel = text - return encoded; + self.inclabel = text + return encoded; diff --git a/share/extensions/Barcode/Code39Ext.py b/share/extensions/Barcode/Code39Ext.py index 23c0d6a46..8f1e77826 100644 --- a/share/extensions/Barcode/Code39Ext.py +++ b/share/extensions/Barcode/Code39Ext.py @@ -1,21 +1,23 @@ -#!/usr/bin/env python -''' -Copyright (C) 2007 Martin Owens - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -''' +# +# Copyright (C) 2007 Martin Owens +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +# +""" +Python barcode renderer for Code39 Extended barcodes. Designed for Inkscape. +""" import Code39 @@ -25,18 +27,18 @@ map = {} i = 0 for char in encode: - map[char] = i - i = i + 1 + map[char] = i + i = i + 1 # Extended encoding maps for full ASCII Code93 def getMap(array): - result = {} - y = 0 - for x in array: - result[chr(x)] = encode[y] - y = y + 1 + result = {} + y = 0 + for x in array: + result[chr(x)] = encode[y] + y = y + 1 - return result; + return result; # MapA is eclectic, but B, C, D are all ASCII ranges mapA = getMap([27,28,29,30,31,59,60,61,62,63,91,92,93,94,95,123,124,125,126,127,0,64,96,127,127,127]) # % @@ -45,19 +47,19 @@ mapC = getMap(range(33, 58)) # / mapD = getMap(range(97, 122)) # + class Object(Code39.Object): - def encode(self, text): - # We are only going to extend the Code39 barcodes - result = '' - for char in text: - if mapA.has_key(char): - char = '%' + mapA[char] - elif mapB.has_key(char): - char = '$' + mapB[char] - elif mapC.has_key(char): - char = '/' + mapC[char] - elif mapD.has_key(char): - char = '+' + mapD[char] - result = result + char - - return Code39.Object.encode(self, result); + def encode(self, text): + # We are only going to extend the Code39 barcodes + result = '' + for char in text: + if mapA.has_key(char): + char = '%' + mapA[char] + elif mapB.has_key(char): + char = '$' + mapB[char] + elif mapC.has_key(char): + char = '/' + mapC[char] + elif mapD.has_key(char): + char = '+' + mapD[char] + result = result + char + + return Code39.Object.encode(self, result); diff --git a/share/extensions/Barcode/Code93.py b/share/extensions/Barcode/Code93.py index 03c31adf1..76cbf683b 100644 --- a/share/extensions/Barcode/Code93.py +++ b/share/extensions/Barcode/Code93.py @@ -1,21 +1,23 @@ -#!/usr/bin/env python -''' -Copyright (C) 2007 Martin Owens - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -''' +# +# Copyright (C) 2007 Martin Owens +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +# +""" +Python barcode renderer for Code93 barcodes. Designed for use with Inkscape. +""" from Base import Barcode @@ -31,20 +33,20 @@ map = {} i = 0 for char in encode: - map[char] = i - i = i + 1 + map[char] = i + i = i + 1 # Extended encoding maps for full ASCII Code93 def getMap(array): - result = {} - y = 10 + result = {} + y = 10 - for x in array: - result[chr(x)] = encode[y] - y = y + 1 + for x in array: + result[chr(x)] = encode[y] + y = y + 1 - return result; + return result; # MapA is eclectic, but B, C, D are all ASCII ranges mapA = getMap([27,28,29,30,31,59,60,61,62,63,91,92,93,94,95,123,124,125,126,127,0,64,96,127,127,127]) # % @@ -55,65 +57,65 @@ mapD = getMap(range(97, 122)) # + encoding = '100010100 101001000 101000100 101000010 100101000 100100100 100100010 101010000 100010010 100001010 110101000 110100100 110100010 110010100 110010010 110001010 101101000 101100100 101100010 100110100 100011010 101011000 101001100 101000110 100101100 100010110 110110100 110110010 110101100 110100110 110010110 110011010 101101100 101100110 100110110 100111010 100101110 111010100 111010010 111001010 101101110 101110110 110101110 100100110 111011010 111010110 100110010 101011110'.split() class Object(Barcode): - def encode(self, text): - # start marker - bits = self.encode93('MARKER') + def encode(self, text): + # start marker + bits = self.encode93('MARKER') - # Extend to ASCII charset ( return Array ) - text = self.encodeAscii(text) + # Extend to ASCII charset ( return Array ) + text = self.encodeAscii(text) - # Calculate the checksums - text.append(self.checksum(text, 20)) # C - text.append(self.checksum(text, 15)) # K + # Calculate the checksums + text.append(self.checksum(text, 20)) # C + text.append(self.checksum(text, 15)) # K - # Now convert text into the encoding bits (black and white stripes) - for char in text: - bits = bits + self.encode93(char) + # Now convert text into the encoding bits (black and white stripes) + for char in text: + bits = bits + self.encode93(char) - # end marker - bits = bits + self.encode93('MARKER') + # end marker + bits = bits + self.encode93('MARKER') - # termination bar - bits = bits + '1' + # termination bar + bits = bits + '1' - self.inclabel = text - return bits - - def checksum(self, text, mod): - weight = len(text) % mod - check = 0 - for char in text: - check = check + (map[char] * weight) - # Reset the weight is required - weight = weight - 1 - if weight == 0: - weight = mod - - return encode[check % 47] - - # Some charicters need re-encoding into the code93 specification - def encodeAscii(self, text): - result = [] - for char in text: - if map.has_key(char): - result.append(char) - elif mapA.has_key(char): - result.append('(%)') - result.append(mapA[char]) - elif mapB.has_key(char): - result.append('($)') - result.append(mapB[char]) - elif mapC.has_key(char): - result.append('(/)') - result.append(mapC[char]) - elif mapD.has_key(char): - result.append('(+)') - result.append(mapD[char]) - - return result - - def encode93(self, char): - if map.has_key(char): - return encoding[map[char]] - return '' + self.inclabel = text + return bits + + def checksum(self, text, mod): + weight = len(text) % mod + check = 0 + for char in text: + check = check + (map[char] * weight) + # Reset the weight is required + weight = weight - 1 + if weight == 0: + weight = mod + + return encode[check % 47] + + # Some charicters need re-encoding into the code93 specification + def encodeAscii(self, text): + result = [] + for char in text: + if map.has_key(char): + result.append(char) + elif mapA.has_key(char): + result.append('(%)') + result.append(mapA[char]) + elif mapB.has_key(char): + result.append('($)') + result.append(mapB[char]) + elif mapC.has_key(char): + result.append('(/)') + result.append(mapC[char]) + elif mapD.has_key(char): + result.append('(+)') + result.append(mapD[char]) + + return result + + def encode93(self, char): + if map.has_key(char): + return encoding[map[char]] + return '' diff --git a/share/extensions/Barcode/EAN13.py b/share/extensions/Barcode/EAN13.py index a7029d982..41681173b 100644 --- a/share/extensions/Barcode/EAN13.py +++ b/share/extensions/Barcode/EAN13.py @@ -1,101 +1,38 @@ -#!/usr/bin/env python -''' -Copyright (C) 2007 Martin Owens +# +# Copyright (C) 2010 Martin Owens +# +# Thanks to Lineaire Chez of Inkbar ( www.inkbar.lineaire.net ) +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +# +""" +Python barcode renderer for EAN13 barcodes. Designed for use with Inkscape. +""" + +from BaseEan import EanBarcode + +class Object(EanBarcode): + """Provide an Ean13 barcode generator""" + name = 'ean13' + lengths = [ 12 ] + checks = [ 13 ] + + def _encode(self, n): + """Encode an ean13 barcode""" + self.label = self.space(n[0:1], 4, n[1:7], 5, n[7:], 7) + return self.enclose( + self.encode_interleaved(n[0], n[1:7]), self.encode_right(n[7:]) ) -Thanks to Lineaire Chez of Inkbar ( www.inkbar.lineaire.net ) - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -''' - -from Base import Barcode -import sys - -mapLeftFaimly = [ - [ "0001101","0011001","0010011","0111101","0100011","0110001","0101111","0111011","0110111","0001011" ], - [ "0100111","0110011","0011011","0100001","0011101","0111001","0000101","0010001","0001001","0010111" ], -] -mapRight = [ "1110010","1100110","1101100","1000010","1011100","1001110","1010000","1000100","1001000","1110100" ] -mapFaimly = [ '000000','001011','001101','001110','010011','011001','011100','010101','010110','011010' ] - -guardBar = '202'; -centerBar = '02020'; - -class Object(Barcode): - def encode(self, number): - result = '' - - if len(number) < 12 or len(number) > 13 or not number.isdigit(): - sys.stderr.write("Can not encode '" + number + "' into EAN13 Barcode, Size must be 12 numbers only\n") - return - - if len(number) == 12: - number = number + self.getChecksum(number) - else: - if not self.verifyChecksum(number): - sys.stderr.write("EAN13 Checksum not correct for this barcode, omit last character to generate new checksum.\n") - return - - result = result + guardBar - family = mapFaimly[int(number[0])] - - i = 0 - for i in range(0,6): - mapLeft = mapLeftFaimly[int(family[i])] - result += mapLeft[int(number[i+1])] - - result += centerBar - - for i in range (7,13): - result += mapRight[int(number[i])] - - result = result + guardBar; - - self.label = number[0] + ' ' + number[1:7] + ' ' + number[7:] + ' ' - self.inclabel = self.label - return result; - - def getChecksum(self, number): - # UPCA/EAN13 - weight=[3,1]*6 - magic=10 - sum = 0 - # We need to work from left to right so reverse - number = number[::-1] - # checksum based on first 12 digits. - for i in range(len(number)): - sum = sum + int(number[i]) * weight[i] - - # Mod it down to a single digit - z = ( magic - (sum % magic) ) % magic - if z < 0 or z >= magic: - return 0 - - return str(z) - - def verifyChecksum(self, number): - new = self.getChecksum(number[:-1]) - existing = number[-1] - return new == existing - - def getStyle(self, index): - result = { 'width' : '1', 'top' : int(self.y), 'write' : True } - if index==0: # White Space - result['write'] = False - elif index==1: # Black Bar - result['height'] = int(self.height) - elif index==2: # Guide Bar - result['height'] = int(self.height) + 5 - return result diff --git a/share/extensions/Barcode/EAN5.py b/share/extensions/Barcode/EAN5.py index 8a93b497b..68ff99738 100644 --- a/share/extensions/Barcode/EAN5.py +++ b/share/extensions/Barcode/EAN5.py @@ -1,68 +1,39 @@ -#!/usr/bin/env python -''' -Copyright (C) 2007 Martin Owens -Copyright (C) 2009 Aaron C Spike - -Thanks to Lineaire Chez of Inkbar ( www.inkbar.lineaire.net ) - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -''' - -from Base import Barcode -import sys - -mapLeftFamily = [ - [ "0001101","0011001","0010011","0111101","0100011","0110001","0101111","0111011","0110111","0001011" ], #L - [ "0100111","0110011","0011011","0100001","0011101","0111001","0000101","0010001","0001001","0010111" ], #G -] -mapFamily = [ '11000','10100','10010','10001','01100','00110','00011','01010','01001','00101' ] - -startBar = '01011'; -sepBar = '01'; - -class Object(Barcode): - def encode(self, number): - result = [] - self.x += 110.0 # horizontal offset so it does not overlap EAN13 +# +# Copyright (C) 2009 Aaron C Spike +# 2010 Martin Owens +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +# +""" +Python barcode renderer for EAN5 barcodes. Designed for use with Inkscape. +""" + +from BaseEan import EanBarcode + +FAMS = [ '11000','10100','10010','10001','01100','00110','00011','01010','01001','00101' ] +START = '01011' + +class Object(EanBarcode): + """Provide an Ean5 barcode generator""" + name = 'ean5' + length = 5 + + def _encode(self, number): + self.x += 110.0 # horiz offset so it does not overlap EAN13 self.y -= self.height + 5 # move the text to the top - if len(number) != 5 or not number.isdigit(): - sys.stderr.write("Can not encode '" + number + "' into EAN5 Barcode, Size must be 5 numbers only\n") - return - - check = self.getChecksum(number) - family = mapFamily[check] - - for i in range(5): - mapLeft = mapLeftFamily[int(family[i])] - result.append(mapLeft[int(number[i])]) - - self.label = number[0] - for i in range(1,5): - self.label += ' ' + number[i] - self.inclabel = self.label - return startBar + '01'.join(result) - - def getChecksum(self, number): - return sum([int(n)*int(m) for n,m in zip(number, '39393')]) % 10 + self.label = ' '.join(self.space(number)) + family = sum([int(n)*int(m) for n,m in zip(number, '39393')]) % 10 + return START + '01'.join(self.encode_interleaved(family, number, FAMS)) - def getStyle(self, index): - result = { 'width' : '1', 'top' : int(self.y) + self.height + 5 + int(self.fontSize()), 'write' : True } - if index==0: # White Space - result['write'] = False - elif index==1: # Black Bar - result['height'] = int(self.height) - elif index==2: # Guide Bar - result['height'] = int(self.height) + 5 - return result diff --git a/share/extensions/Barcode/EAN8.py b/share/extensions/Barcode/EAN8.py index e51cfa93a..05b4d7bb7 100644 --- a/share/extensions/Barcode/EAN8.py +++ b/share/extensions/Barcode/EAN8.py @@ -1,84 +1,34 @@ -#!/usr/bin/env python -''' -Copyright (C) 2007 Martin Owens - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -''' - -from Base import Barcode -import sys - -leftMap = [ '0001101', '0011001', '0010011', '0111101', '0100011', '0110001', '0101111', '0111011', '0110111', '0001011' ] -rightMap = [ '1110010', '1100110', '1101100', '1000010', '1011100', '1001110', '1010000', '1000100', '1001000', '1110100' ] -weightMap = [ 3, 1, 3, 1, 3, 1, 3 ] - -guardBar = '202'; -centerBar = '02020'; - -class Object(Barcode): - def encode(self, number): - result = '' - - # Rejig the label for use - self.label = number[:4] + ' ' + number[4:] - - if len(number) < 7 or len(number) > 8 or not number.isdigit(): - sys.stderr.write("Can not encode '" + number + "' into EAN8 Barcode, Size must be 7 or 8 Numbers only\n") - - if len(number) == 7: - number = number + self.calculateChecksum(number) - - result = result + guardBar - - i = 0 - for num in number: - if i >= 4: - result = result + rightMap[int(num)] - else: - result = result + leftMap[int(num)] - - i = i + 1 - if i == 4: - result = result + centerBar; - - result = result + guardBar; - - self.inclabel = ' ' + number[:4] + ' ' + number[4:] - return result; - - - def calculateChecksum(self, number): - weight = 0; - i = 0; - - for num in number: - weight = weight + (int(num) * weightMap[i]) - i = i + 1 - - weight = 10 - (weight % 10) - if weight == 10: - weight = 0 - return str(weight); - - def getStyle(self, index): - result = { 'width' : '1', 'top' : int(self.y), 'write' : True } - if index==0: # White Space - result['write'] = False - elif index==1: # Black Bar - result['height'] = int(self.height) - elif index==2: # Guide Bar - result['height'] = int(self.height) + 8 - return result +# +# Copyright (C) 2010 Martin Owens +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +# +""" +Python barcode renderer for EAN8 barcodes. Designed for use with Inkscape. +""" + +from BaseEan import EanBarcode + +class Object(EanBarcode): + """Provide an EAN8 barcode generator""" + name = 'ean8' + lengths = [ 7 ] + checks = [ 8 ] + + def _encode(self, n): + """Encode an ean8 barcode""" + self.label = self.space(n[:4], 3, n[4:]) + return self.enclose( self.encode_left(n[:4]), self.encode_right(n[4:]) ) diff --git a/share/extensions/Barcode/Makefile.am b/share/extensions/Barcode/Makefile.am index fd5f1663b..9ec7f166c 100644 --- a/share/extensions/Barcode/Makefile.am +++ b/share/extensions/Barcode/Makefile.am @@ -3,9 +3,11 @@ barcodedir = $(datadir)/inkscape/extensions/Barcode barcode_SCRIPTS = \ Base.py \ + BaseEan.py \ Code128.py \ Code39Ext.py \ Code39.py \ + Code25i.py \ Code93.py \ EAN13.py \ EAN8.py \ diff --git a/share/extensions/Barcode/RM4CC.py b/share/extensions/Barcode/RM4CC.py index 22902f2e4..d980c6c86 100644 --- a/share/extensions/Barcode/RM4CC.py +++ b/share/extensions/Barcode/RM4CC.py @@ -1,131 +1,135 @@ -#!/usr/bin/env python -''' -Copyright (C) 2007 Martin Owens - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -''' +# +# Copyright (C) 2007 Martin Owens +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +# +""" +Python barcode renderer for RM4CC barcodes. Designed for use with Inkscape. +""" from Base import Barcode map = { - '(' : '25', - ')' : '3', - '0' : '05053535', - '1' : '05152535', - '2' : '05153525', - '3' : '15052535', - '4' : '15053525', - '5' : '15152525', - '6' : '05251535', - '7' : '05350535', - '8' : '05351525', - '9' : '15250535', - 'A' : '15251525', - 'B' : '15350525', - 'C' : '05253515', - 'D' : '05352515', - 'E' : '05353505', - 'F' : '15252515', - 'G' : '15253505', - 'H' : '15352505', - 'I' : '25051535', - 'J' : '25150535', - 'K' : '25151525', - 'L' : '35050535', - 'M' : '35051525', - 'N' : '35150525', - 'O' : '25053525', - 'P' : '25152515', - 'Q' : '25153505', - 'R' : '35052515', - 'S' : '35053505', - 'T' : '35152505', - 'U' : '25251515', - 'V' : '25350515', - 'W' : '25351505', - 'X' : '35250515', - 'Y' : '35251505', - 'Z' : '35350505', + '(' : '25', + ')' : '3', + '0' : '05053535', + '1' : '05152535', + '2' : '05153525', + '3' : '15052535', + '4' : '15053525', + '5' : '15152525', + '6' : '05251535', + '7' : '05350535', + '8' : '05351525', + '9' : '15250535', + 'A' : '15251525', + 'B' : '15350525', + 'C' : '05253515', + 'D' : '05352515', + 'E' : '05353505', + 'F' : '15252515', + 'G' : '15253505', + 'H' : '15352505', + 'I' : '25051535', + 'J' : '25150535', + 'K' : '25151525', + 'L' : '35050535', + 'M' : '35051525', + 'N' : '35150525', + 'O' : '25053525', + 'P' : '25152515', + 'Q' : '25153505', + 'R' : '35052515', + 'S' : '35053505', + 'T' : '35152505', + 'U' : '25251515', + 'V' : '25350515', + 'W' : '25351505', + 'X' : '35250515', + 'Y' : '35251505', + 'Z' : '35350505', } check = ['ZUVWXY','501234','B6789A','HCDEFG','NIJKLM','TOPQRS'] +(BAR_TRACK, BAR_DOWN, BAR_UP, BAR_FULL, BAR_NONE, WHITE_SPACE) = range(6) class Object(Barcode): - def encode(self, text): - result = '' + def encode(self, text): + result = '' - self.height = 18 - text = text.upper() - text.replace('(', '') - text.replace(')', '') + self.height = 18 + text = text.upper() + text.replace('(', '') + text.replace(')', '') - text = '(' + text + self.checksum(text) + ')' + text = '(' + text + self.checksum(text) + ')' - i = 0 - for char in text: - if map.has_key(char): - result = result + map[char] - - i = i + 1 + i = 0 + for char in text: + if map.has_key(char): + result = result + map[char] + + i = i + 1 - self.inclabel = text - return result; + self.inclabel = text + return result; - # given a string of data, return the check character - def checksum(self, text): - total_lower = 0 - total_upper = 0 - for char in text: - if map.has_key(char): - bars = map[char][0:8:2] - lower = 0 - upper = 0 + # given a string of data, return the check character + def checksum(self, text): + total_lower = 0 + total_upper = 0 + for char in text: + if map.has_key(char): + bars = map[char][0:8:2] + lower = 0 + upper = 0 - if int(bars[0]) & 1: - lower = lower + 4 - if int(bars[1]) & 1: - lower = lower + 2 - if int(bars[2]) & 1: - lower = lower + 1 - if int(bars[0]) & 2: - upper = upper + 4 - if int(bars[1]) & 2: - upper = upper + 2 - if int(bars[2]) & 2: - upper = upper + 1 - total_lower = total_lower + (lower % 6) - total_upper = total_upper + (upper % 6) + if int(bars[0]) & 1: + lower = lower + 4 + if int(bars[1]) & 1: + lower = lower + 2 + if int(bars[2]) & 1: + lower = lower + 1 + if int(bars[0]) & 2: + upper = upper + 4 + if int(bars[1]) & 2: + upper = upper + 2 + if int(bars[2]) & 2: + upper = upper + 1 + total_lower = total_lower + (lower % 6) + total_upper = total_upper + (upper % 6) - total_lower = total_upper % 6 - total_upper = total_upper % 6 - - checkchar = check[total_upper][total_lower] - return checkchar + total_lower = total_upper % 6 + total_upper = total_upper % 6 + + checkchar = check[total_upper][total_lower] + return checkchar - def getStyle(self, index): - result = { 'width' : 2, 'write' : True, 'top' : int(self.y) } - if index==0: # Track Bar - result['top'] = result['top'] + 6 - result['height'] = 5 - elif index==1: # Decender Bar - result['top'] = result['top'] + 6 - result['height'] = 11 - elif index==2: # Accender Bar - result['height'] = 11 - elif index==3: # Full Bar - result['height'] = 17 - elif index==5: # White Space - result['write'] = False - return result + def getStyle(self, index): + """Royal Mail Barcodes use a completely different style""" + result = { 'width' : 2, 'write' : True, 'top' : 0 } + if index == BAR_TRACK: # Track Bar + result['top'] = 6 + result['height'] = 5 + elif index == BAR_DOWN: # Decender Bar + result['top'] = 6 + result['height'] = 11 + elif index == BAR_UP: # Accender Bar + result['height'] = 11 + elif index == BAR_FULL: # Full Bar + result['height'] = 17 + elif index == WHITE_SPACE: # White Space + result['write'] = False + return result diff --git a/share/extensions/Barcode/UPCA.py b/share/extensions/Barcode/UPCA.py index 15d189daa..6ac10943c 100644 --- a/share/extensions/Barcode/UPCA.py +++ b/share/extensions/Barcode/UPCA.py @@ -1,59 +1,37 @@ -#!/usr/bin/env python -''' -Copyright (C) 2007 Martin Owens - -Thanks to Lineaire Chez of Inkbar ( www.inkbar.lineaire.net ) - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -''' - -import EAN13 -from EAN13 import mapLeftFaimly, guardBar, centerBar, mapRight -import sys - -class Object(EAN13.Object): - def encode(self, number): - result = '' - - if len(number) < 11 or len(number) > 12 or not number.isdigit(): - sys.stderr.write("Can not encode '" + number + "' into UPC-A Barcode, Size must be 11 numbers only, and 1 check digit (optional).\n") - return - - if len(number) == 11: - number = number + self.getChecksum(number) - else: - if not self.verifyChecksum(number): - sys.stderr.write("UPC-A Checksum not correct for this barcode, omit last character to generate new checksum.\n") - return - - result = result + guardBar - - i = 0 - for i in range(0,6): - result += mapLeftFaimly[0][int(number[i])] - - result += centerBar - - for i in range (6,12): - result += mapRight[int(number[i])] - - result = result + guardBar; - - self.label = number[0] + ' ' + number[1:6] + ' ' + number[6:11] + ' ' + number[11] - self.inclabel = self.label - return result; - - def fontSize(self): - return '10' +# +# Copyright (C) 2007 Martin Owens +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +# +""" +Python barcode renderer for UPCA barcodes. Designed for use with Inkscape. +""" + +from BaseEan import EanBarcode + +class Object(EanBarcode): + """Provides a renderer for EAN12 aka UPC-A Barcodes""" + name = 'upca' + lengths = [ 11 ] + checks = [ 12 ] + + def _encode(self, n): + """Encode for a UPC-A Barcode""" + self.label = self.space(n[0:1], 3, n[1:6], 4, n[6:11], 3, n[11:]) + return self.enclose(self.encode_left(n[0:6]), self.encode_right(n[6:12])) + + def fontSize(self): + """We need a bigger barcode""" + return 10 diff --git a/share/extensions/Barcode/UPCE.py b/share/extensions/Barcode/UPCE.py index 2065cfae9..dba5d48ea 100644 --- a/share/extensions/Barcode/UPCE.py +++ b/share/extensions/Barcode/UPCE.py @@ -1,130 +1,103 @@ -#!/usr/bin/env python -''' -Copyright (C) 2007 Martin Owens - -Thanks to Lineaire Chez of Inkbar ( www.inkbar.lineaire.net ) - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -''' - -import EAN13 -from EAN13 import mapLeftFaimly, guardBar, centerBar +# +# Copyright (C) 2010 Martin Owens +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +# +""" +Python barcode renderer for UPCE barcodes. Designed for use with Inkscape. +""" + +from BaseEan import EanBarcode import sys -mapFamily = [ '000111','001011','001101','001110','010011','011001','011100','010101','010110','011010' ] - -class Object(EAN13.Object): - def encode(self, number): - result = '' - - l = len(number) - - if (l != 6 and l != 7 and l != 11 and l != 12) or not number.isdigit(): - sys.stderr.write("Can not encode '" + number + "' into UPC-E Barcode, Size must be 6 numbers only, and 1 check digit (optional)\nOr a convertable 11 digit UPC-A number with 1 check digit (also optional).\n") - return - - echeck = None - if l==7 or l==12: - echeck = number[-1] - number = number[:-1] - sys.stderr.write("CHECKSUM FOUND!") - l -= 1 - - if l==6: - number = self.ConvertEtoA(number) - - if not echeck: - echeck = self.getChecksum(number) - else: - if not self.verifyChecksum(number + echeck): - sys.stderr.write("UPC-E Checksum not correct for this barcode, omit last character to generate new checksum.\n") - return - - number = self.ConvertAtoE(number) - if not number: - sys.stderr.write("UPC-A code could not be converted into a UPC-E barcode, please follow the UPC guide or enter a 6 digit UPC-E number..\n") - return - - number = number - - result = result + guardBar - # The check digit isn't stored as bars but as a mirroring system. :-( - family = mapFamily[int(echeck)] - - i = 0 - for i in range(0,6): - result += mapLeftFaimly[int(family[i])-1][int(number[i])] - - result = result + centerBar + '2'; - - self.label = '0 ' + number[:6] + ' ' + echeck - self.inclabel = self.label - return result; - - def fontSize(self): - return '10' - - def ConvertAtoE(self, number): - # Converting UPC-A to UPC-E - - # All UPC-E Numbers use number system 0 - if number[0] != '0' or len(number)!=11: - # If not then the code is invalid - return None - - # Most of the conversions deal - # with the specific code parts - manufacturer = number[1:6] - product = number[6:11] - - # There are 4 cases to convert: - if manufacturer[2:] == '000' or manufacturer[2:] == '100' or manufacturer[2:] == '200': - # Maxium number product code digits can be encoded - if product[:2]=='00': - return manufacturer[:2] + product[2:] + manufacturer[2] - elif manufacturer[3:5] == '00': - # Now only 2 product code digits can be used - if product[:3]=='000': - return manufacturer[:3] + product[3:] + '3' - elif manufacturer[4] == '0': - # With even more manufacturer code we have less room for product code - if product[:4]=='0000': - return manufacturer[0:4] + product[4] + '4' - elif product[:4]=='0000' and int(product[4]) > 4: - # The last recorse is to try and squeeze it in the last 5 numbers - # so long as the product is 00005-00009 so as not to conflict with - # the 0-4 used above. - return manufacturer + product[4] - else: - # Invalid UPC-A Numbe - return None - - def ConvertEtoA(self, number): - # Convert UPC-E to UPC-A - - # It's more likly to convert this without fault - # But we still must be mindful of the 4 conversions - if len(number)!=6: - return None - - if number[5]=='0' or number[5]=='1' or number[5]=='2': - return '0' + number[:2] + number[5] + '0000' + number[2:5] - elif number[5]=='3': - return '0' + number[:3] + '00000' + number[3:5] - elif number[5]=='4': - return '0' + number[:4] + '00000' + number[4] - else: - return '0' + number[:5] + '0000' + number[5] +# This is almost exactly the same as the standard FAMILIES +# But flipped around and with the first 111000 instead of 000000. +FAMS = [ '111000', '110100', '110010', '110001', '101100', + '100110', '100011', '101010', '101001', '100101' ] + +class Object(EanBarcode): + """Generate EAN6/UPC-E barcode generator""" + name = 'upce' + lengths = [ 6, 11 ] + checks = [ 7, 12 ] + + def _encode(self, n): + """Generate a UPC-E Barcode""" + self.label = self.space(['0'], 2, n[:6], 2, n[-1]) + code = self.encode_interleaved(n[-1], n[:6], FAMS) + # 202(guard) + code + 020(center) + 202(guard) + return self.enclose(code, center='020') + + def appendChecksum(self, number): + """Generate a UPCE Checksum""" + if len(number) == 6: + number = self.ConvertEtoA(number) + result = self.getChecksum(number) + return self.ConvertAtoE(number) + result + + def fontSize(self): + """We need a font size of 10""" + return 10 + + def ConvertAtoE(self, number): + """Converting UPC-A to UPC-E, may cause errors.""" + # All UPC-E Numbers use number system 0 + if number[0] != '0' or len(number)!=11: + # If not then the code is invalid + return None + + # Most of the conversions deal + # with the specific code parts + manufacturer = number[1:6] + product = number[6:11] + + # There are 4 cases to convert: + if manufacturer[2:] == '000' or manufacturer[2:] == '100' or manufacturer[2:] == '200': + # Maxium number product code digits can be encoded + if product[:2]=='00': + return manufacturer[:2] + product[2:] + manufacturer[2] + elif manufacturer[3:5] == '00': + # Now only 2 product code digits can be used + if product[:3]=='000': + return manufacturer[:3] + product[3:] + '3' + elif manufacturer[4] == '0': + # With even more manufacturer code we have less room for product code + if product[:4]=='0000': + return manufacturer[0:4] + product[4] + '4' + elif product[:4]=='0000' and int(product[4]) > 4: + # The last recorse is to try and squeeze it in the last 5 numbers + # so long as the product is 00005-00009 so as not to conflict with + # the 0-4 used above. + return manufacturer + product[4] + else: + # Invalid UPC-A Numbe + return None + + def ConvertEtoA(self, number): + """Convert UPC-E to UPC-A by padding with zeros""" + # It's more likly to convert this without fault + # But we still must be mindful of the 4 conversions + if len(number) != 6: + return None + + if number[5] in ['0', '1', '2']: + return '0' + number[:2] + number[5] + '0000' + number[2:5] + elif number[5] == '3': + return '0' + number[:3] + '00000' + number[3:5] + elif number[5] == '4': + return '0' + number[:4] + '00000' + number[4] + else: + return '0' + number[:5] + '0000' + number[5] diff --git a/share/extensions/Barcode/__init__.py b/share/extensions/Barcode/__init__.py index 281702c1e..370839f45 100644 --- a/share/extensions/Barcode/__init__.py +++ b/share/extensions/Barcode/__init__.py @@ -1,39 +1,36 @@ -#!/usr/bin/env python -''' -Barcodes SVG Extention +# +# Copyright (C) 2010 Martin Owens +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +# +""" +Renderer for barcodes, SVG extention for Inkscape. -Supported Barcodes: EAN8, EAN13, Code39, Code39 Extended, Code93, Code128, RM4CC(RM4SCC) +For supported barcodes see Barcode module directory. -Copyright (C) 2007 Martin Owens - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -''' +""" # This lists all known Barcodes missing from this package -# =========== UPC-Based =========== # -# ISBN (EAN13) # ===== UPC-Based Extensions ====== # # Code11 # ========= Code25-Based ========== # -# Code25 # Codabar # Postnet # ITF25 # ========= Alpha-numeric ========= # # Code39Mod -# EAN128 (Code128) # USPS128 # =========== 2D Based ============ # # PDF417 @@ -44,41 +41,44 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA import sys def getBarcode(format, param={}): - if format: - format = str(format).lower() - format = format.replace('-', '') - format = format.replace(' ', '') - if format=='code39': - import Code39 - return Code39.Object(param) - elif format=='code39ext': - import Code39Ext - return Code39Ext.Object(param) - elif format=='code93': - import Code93 - return Code93.Object(param) - elif format=='code128': - import Code128 - return Code128.Object(param) + if format: + format = str(format).lower() + format = format.replace('-', '') + format = format.replace(' ', '') + if format=='code25i': + import Code25i + return Code25i.Object(param) + elif format=='code39': + import Code39 + return Code39.Object(param) + elif format=='code39ext': + import Code39Ext + return Code39Ext.Object(param) + elif format=='code93': + import Code93 + return Code93.Object(param) + elif format=='code128': + import Code128 + return Code128.Object(param) - elif format in ['rm4cc', 'rm4scc']: - import RM4CC - return RM4CC.Object(param) + elif format in ['rm4cc', 'rm4scc']: + import RM4CC + return RM4CC.Object(param) - elif format == 'upca': - import UPCA - return UPCA.Object(param) - elif format == 'upce': - import UPCE - return UPCE.Object(param) - elif format in ['ean13', 'ucc13','jan']: - import EAN13 - return EAN13.Object(param) - elif format == 'ean5': - import EAN5 - return EAN5.Object(param) - elif format in ['ean8', 'ucc8']: - import EAN8 - return EAN8.Object(param) - sys.stderr.write("Invalid format for barcode: " + str(format) + "\n") + elif format == 'upca': + import UPCA + return UPCA.Object(param) + elif format == 'upce': + import UPCE + return UPCE.Object(param) + elif format == 'ean5': + import EAN5 + return EAN5.Object(param) + elif format in ['ean8', 'ucc8']: + import EAN8 + return EAN8.Object(param) + elif format in ['ean13', 'ucc13','jan']: + import EAN13 + return EAN13.Object(param) + sys.stderr.write("Invalid format for barcode: " + str(format) + "\n") diff --git a/share/extensions/Makefile.am b/share/extensions/Makefile.am index f735f2ff2..01ecdb1f0 100644 --- a/share/extensions/Makefile.am +++ b/share/extensions/Makefile.am @@ -66,6 +66,7 @@ extensions = \ generate_voronoi.py \ gimp_xcf.py \ grid_cartesian.py \ + grid_isometric.py \ grid_polar.py \ guides_creator.py \ guillotine.py \ @@ -168,6 +169,7 @@ otherstuff = \ aisvg.xslt \ colors.xml \ jessyInk_video.svg \ + svg2fxg.xsl \ svg2xaml.xsl \ xaml2svg.xsl @@ -232,6 +234,7 @@ modules = \ generate_voronoi.inx \ gimp_xcf.inx \ grid_cartesian.inx \ + grid_isometric.inx \ grid_polar.inx \ guides_creator.inx \ guillotine.inx \ @@ -293,6 +296,7 @@ modules = \ split.inx \ straightseg.inx \ summersnight.inx \ + svg2fxg.inx \ svg2xaml.inx \ svg_and_media_zip_output.inx \ svgcalendar.inx \ diff --git a/share/extensions/cspsubdiv.py b/share/extensions/cspsubdiv.py index f05068df9..c34236afe 100644 --- a/share/extensions/cspsubdiv.py +++ b/share/extensions/cspsubdiv.py @@ -17,25 +17,21 @@ def cspsubdiv(csp,flat): subdiv(sp,flat) def subdiv(sp,flat,i=1): - p0 = sp[i-1][1] - p1 = sp[i-1][2] - p2 = sp[i][0] - p3 = sp[i][1] - - b = (p0,p1,p2,p3) - m = maxdist(b) - if m <= flat: - try: - subdiv(sp,flat,i+1) - except IndexError: - pass - else: - one, two = beziersplitatt(b,0.5) - sp[i-1][2] = one[1] - sp[i][0] = two[2] - p = [one[2],one[3],two[1]] - sp[i:1] = [p] - subdiv(sp,flat,i) - + while i < len(sp): + p0 = sp[i-1][1] + p1 = sp[i-1][2] + p2 = sp[i][0] + p3 = sp[i][1] + + b = (p0,p1,p2,p3) + m = maxdist(b) + if m <= flat: + i += 1 + else: + one, two = beziersplitatt(b,0.5) + sp[i-1][2] = one[1] + sp[i][0] = two[2] + p = [one[2],one[3],two[1]] + sp[i:1] = [p] # vim: expandtab shiftwidth=4 tabstop=8 softtabstop=4 fileencoding=utf-8 textwidth=99 diff --git a/share/extensions/dxf_input.py b/share/extensions/dxf_input.py index b46477de1..d3bd15ee0 100644 --- a/share/extensions/dxf_input.py +++ b/share/extensions/dxf_input.py @@ -88,6 +88,10 @@ def export_SPLINE(): path = 'M %f,%f Q %f,%f %f,%f' % (vals[groups['10']][0], vals[groups['20']][0], vals[groups['10']][1], vals[groups['20']][1], vals[groups['10']][2], vals[groups['20']][2]) attribs = {'d': path, 'style': style} inkex.etree.SubElement(layer, 'path', attribs) + if not (vals[groups['70']][0] & 3) and len(vals[groups['10']]) == 5 and len(vals[groups['20']]) == 5: + path = 'M %f,%f Q %f,%f %f,%f Q %f,%f %f,%f' % (vals[groups['10']][0], vals[groups['20']][0], vals[groups['10']][1], vals[groups['20']][1], vals[groups['10']][2], vals[groups['20']][2], vals[groups['10']][3], vals[groups['20']][3], vals[groups['10']][4], vals[groups['20']][4]) + attribs = {'d': path, 'style': style} + inkex.etree.SubElement(layer, 'path', attribs) def export_CIRCLE(): # mandatory group codes : (10, 20, 40) (x, y, radius) @@ -307,7 +311,7 @@ def get_group(group): # define DXF Entities and specify which Group Codes to monitor -entities = {'MTEXT': export_MTEXT, 'TEXT': export_MTEXT, 'POINT': export_POINT, 'LINE': export_LINE, 'SPLINE': export_SPLINE, 'CIRCLE': export_CIRCLE, 'ARC': export_ARC, 'ELLIPSE': export_ELLIPSE, 'LEADER': export_LEADER, 'LWPOLYLINE': export_LWPOLYLINE, 'HATCH': export_HATCH, 'DIMENSION': export_DIMENSION, 'INSERT': export_INSERT, 'BLOCK': export_BLOCK, 'ENDBLK': export_ENDBLK, 'ATTDEF': export_ATTDEF, 'VIEWPORT': False, 'DICTIONARY': False} +entities = {'MTEXT': export_MTEXT, 'TEXT': export_MTEXT, 'POINT': export_POINT, 'LINE': export_LINE, 'SPLINE': export_SPLINE, 'CIRCLE': export_CIRCLE, 'ARC': export_ARC, 'ELLIPSE': export_ELLIPSE, 'LEADER': export_LEADER, 'LWPOLYLINE': export_LWPOLYLINE, 'HATCH': export_HATCH, 'DIMENSION': export_DIMENSION, 'INSERT': export_INSERT, 'BLOCK': export_BLOCK, 'ENDBLK': export_ENDBLK, 'ATTDEF': export_ATTDEF, 'VIEWPORT': False, 'EOF': False} groups = {'1': 0, '2': 1, '3': 2, '6': 3, '8': 4, '10': 5, '11': 6, '13': 7, '14': 8, '20': 9, '21': 10, '23': 11, '24': 12, '40': 13, '41': 14, '42': 15, '50': 16, '51': 17, '62': 18, '70': 19, '72': 20, '73': 21, '92': 22, '93': 23, '370': 24} colors = { 1: '#FF0000', 2: '#FFFF00', 3: '#00FF00', 4: '#00FFFF', 5: '#0000FF', 6: '#FF00FF', 8: '#414141', 9: '#808080', 12: '#BD0000', 30: '#FF7F00', @@ -322,7 +326,7 @@ parser.add_option("--font", action="store", type="string", dest="font", default= parser.add_option("--tab", action="store", type="string", dest="tab", default="Options") parser.add_option("--inputhelp", action="store", type="string", dest="inputhelp", default="") (options, args) = parser.parse_args(inkex.sys.argv[1:]) -doc = inkex.etree.parse(StringIO('<svg xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"></svg>')) +doc = inkex.etree.parse(StringIO('<svg xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" width="%s" height="%s"></svg>' % (210*90/25.4, 297*90/25.4))) desc = inkex.etree.SubElement(doc.getroot(), 'desc', {}) defs = inkex.etree.SubElement(doc.getroot(), 'defs', {}) marker = inkex.etree.SubElement(defs, 'marker', {'id': 'DistanceX', 'orient': 'auto', 'refX': '0.0', 'refY': '0.0', 'style': 'overflow:visible'}) @@ -401,7 +405,7 @@ for linename in linetypes.keys(): # scale the dashed lines entity = '' block = defs # initiallize with dummy -while line[0] and line[1] != 'DICTIONARY': +while line[0] and line[1] != 'EOF': line = get_line() if entity and groups.has_key(line[0]): seqs.append(line[0]) # list of group codes diff --git a/share/extensions/dxf_outlines.inx b/share/extensions/dxf_outlines.inx index fe8048a8e..8e8c54c6c 100644 --- a/share/extensions/dxf_outlines.inx +++ b/share/extensions/dxf_outlines.inx @@ -9,11 +9,20 @@ <page name="options" _gui-text="Options"> <param name="ROBO" type="boolean" _gui-text="use ROBO-Master type of spline output">false</param> <param name="POLY" type="boolean" _gui-text="use LWPOLYLINE type of line output">true</param> + <param name="units" type="enum" _gui-text="Units"> + <_item value="72./90">pt</_item> + <_item value="1./15">pc</_item> + <_item value="1.">px</_item> + <_item value="25.4/90">mm</_item> + <_item value="2.54/90">cm</_item> + <_item value=".0254/90">m</_item> + <_item value="1./90">in</_item> + <_item value="1./1080">ft</_item> + </param> </page> <page name="help" _gui-text="Help"> <_param name="inputhelp" type="description" xml:space="preserve">- AutoCAD Release 13 format. - assume svg drawing is in pixels, at 90 dpi. -- assume dxf drawing is in mm. - only line and spline elements are supported. - ROBO-Master spline output is a specialized spline readable only by ROBO-Master and AutoDesk viewers, not Inkscape. - LWPOLYLINE output is a multiply-connected polyline, disable it to use a legacy version of the LINE output.</_param> diff --git a/share/extensions/dxf_outlines.py b/share/extensions/dxf_outlines.py index b2f777ae6..6dd0de477 100755 --- a/share/extensions/dxf_outlines.py +++ b/share/extensions/dxf_outlines.py @@ -10,6 +10,7 @@ Copyright (C) 2008,2010 Alvin Penner, penner@vaxxine.com - toggle between LINE/LWPOLYLINE added Jan 2010 - support for transform elements added July 2010 - support for layers added July 2010 +- support for rectangle added Dec 2010 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -57,6 +58,7 @@ class MyEffect(inkex.Effect): inkex.Effect.__init__(self) self.OptionParser.add_option("-R", "--ROBO", action="store", type="string", dest="ROBO") self.OptionParser.add_option("-P", "--POLY", action="store", type="string", dest="POLY") + self.OptionParser.add_option("--units", action="store", type="string", dest="units") self.OptionParser.add_option("--tab", action="store", type="string", dest="tab") self.OptionParser.add_option("--inputhelp", action="store", type="string", dest="inputhelp") self.dxf = [] @@ -165,26 +167,41 @@ class MyEffect(inkex.Effect): self.color = 7 # default is black if hsl[2]: self.color = 1 + (int(6*hsl[0] + 0.5) % 6) # use 6 hues - d = node.get('d') - if d: + if node.tag == inkex.addNS('path','svg'): + d = node.get('d') + if not d: + return p = cubicsuperpath.parsePath(d) - trans = node.get('transform') - if trans: - mat = simpletransform.composeTransform(mat, simpletransform.parseTransform(trans)) - simpletransform.applyTransformToPath(mat, p) - for sub in p: - for i in range(len(sub)-1): - s = sub[i] - e = sub[i+1] - if s[1] == s[2] and e[0] == e[1]: - if (self.options.POLY == 'true'): - self.LWPOLY_line([s[1],e[1]]) - else: - self.dxf_line([s[1],e[1]]) - elif (self.options.ROBO == 'true'): - self.ROBO_spline([s[1],s[2],e[0],e[1]]) + elif node.tag == inkex.addNS('rect','svg'): + x = float(node.get('x')) + y = float(node.get('y')) + width = float(node.get('width')) + height = float(node.get('height')) + p = [[[x, y],[x, y],[x, y]]] + p.append([[x + width, y],[x + width, y],[x + width, y]]) + p.append([[x + width, y + height],[x + width, y + height],[x + width, y + height]]) + p.append([[x, y + height],[x, y + height],[x, y + height]]) + p.append([[x, y],[x, y],[x, y]]) + p = [p] + else: + return + trans = node.get('transform') + if trans: + mat = simpletransform.composeTransform(mat, simpletransform.parseTransform(trans)) + simpletransform.applyTransformToPath(mat, p) + for sub in p: + for i in range(len(sub)-1): + s = sub[i] + e = sub[i+1] + if s[1] == s[2] and e[0] == e[1]: + if (self.options.POLY == 'true'): + self.LWPOLY_line([s[1],e[1]]) else: - self.dxf_spline([s[1],s[2],e[0],e[1]]) + self.dxf_line([s[1],e[1]]) + elif (self.options.ROBO == 'true'): + self.ROBO_spline([s[1],s[2],e[0],e[1]]) + else: + self.dxf_spline([s[1],s[2],e[0],e[1]]) def process_group(self, group): if group.get(inkex.addNS('groupmode', 'inkscape')) == 'layer': @@ -196,10 +213,10 @@ class MyEffect(inkex.Effect): if trans: self.groupmat.append(simpletransform.composeTransform(self.groupmat[-1], simpletransform.parseTransform(trans))) for node in group: - if node.tag == inkex.addNS('path','svg'): - self.process_path(node, self.groupmat[-1]) if node.tag == inkex.addNS('g','svg'): self.process_group(node) + else: + self.process_path(node, self.groupmat[-1]) if trans: self.groupmat.pop() @@ -220,7 +237,9 @@ class MyEffect(inkex.Effect): self.dxf_add(" 0\nLAYER\n 5\n%x\n100\nAcDbSymbolTableRecord\n100\nAcDbLayerTableRecord\n 2\n%s\n 70\n0\n 6\nCONTINUOUS\n" % (i + 80, self.layers[i])) self.dxf_add(dxf_templates.r14_style) - scale = 25.4/90.0 + scale = eval(self.options.units) + if not scale: + scale = 25.4/90 h = inkex.unittouu(self.document.getroot().xpath('@height', namespaces=inkex.NSS)[0]) self.groupmat = [[[scale, 0.0, 0.0], [0.0, -scale, h*scale]]] doc = self.document.getroot() diff --git a/share/extensions/gcodetools.py b/share/extensions/gcodetools.py index 37e89b318..f99c050bd 100644 --- a/share/extensions/gcodetools.py +++ b/share/extensions/gcodetools.py @@ -3638,7 +3638,7 @@ class Gcodetools(inkex.Effect): ################################################################################ def dxfpoints(self): if self.selected_paths == {}: - self.error(_("Noting is selected. Please select something to convert to drill point (dxfpoint) or clear point sign."),"warning") + self.error(_("Nothing is selected. Please select something to convert to drill point (dxfpoint) or clear point sign."),"warning") for layer in self.layers : if layer in self.selected_paths : for path in self.selected_paths[layer]: diff --git a/share/extensions/gcodetools_all_in_one.inx b/share/extensions/gcodetools_all_in_one.inx index 0f566fc7b..85d7cfbee 100644 --- a/share/extensions/gcodetools_all_in_one.inx +++ b/share/extensions/gcodetools_all_in_one.inx @@ -15,7 +15,7 @@ The segment will be split into two segments if the distance between path's segme </_param> </page> - <page name='area' _gui-text='Area'> + <page name='area' msgctxt="gcodetools extension" _gui-text='Area'> <param name="max-area-curves" type="int" min="0" max="1000" _gui-text="Maximum area cutting curves:">100</param> <param name="area-inkscape-radius" type="float" min="-1000" max="1000" _gui-text="Area width:">-10</param> diff --git a/share/extensions/gcodetools_area.inx b/share/extensions/gcodetools_area.inx index 718ae0d9f..53ceeafaa 100644 --- a/share/extensions/gcodetools_area.inx +++ b/share/extensions/gcodetools_area.inx @@ -6,7 +6,7 @@ <dependency type="executable" location="extensions">inkex.py</dependency> <param name='active-tab' type="notebook"> - <page name='area' _gui-text='Area'> + <page name='area' msgctxt="gcodetools extension" _gui-text='Area'> <param name="max-area-curves" type="int" min="0" max="1000" _gui-text="Maximum area cutting curves:">100</param> <param name="area-inkscape-radius" type="float" min="-1000" max="1000" _gui-text="Area width:">-10</param> diff --git a/share/extensions/gears.inx b/share/extensions/gears.inx index 8360a3745..ec733fb6b 100644 --- a/share/extensions/gears.inx +++ b/share/extensions/gears.inx @@ -5,8 +5,15 @@ <dependency type="executable" location="extensions">gears.py</dependency> <dependency type="executable" location="extensions">inkex.py</dependency> <param name="teeth" type="int" min="6" max="360" _gui-text="Number of teeth:">24</param> - <param name="pitch" type="float" min="0.0" max="1000.0" _gui-text="Circular pitch (px):">20.0</param> - <param name="angle" type="float" min="10.0" max="30.0" _gui-text="Pressure angle:">20.0</param> + <param name="pitch" type="float" min="0.0" max="1000.0" _gui-text="Circular pitch (tooth size):">20.0</param> + <param name="angle" type="float" min="10.0" max="30.0" _gui-text="Pressure angle (degrees):">20.0</param> + <param name="centerdiameter" type="float" min="0.0" max="1000.0" _gui-text="Diameter of center hole (0 for none):">20.0</param> + <param name="unit" _gui-text="Units:" type="optiongroup" appearance="minimal"> + <_option value="px">px</_option> + <_option value="in">in</_option> + <_option value="mm">mm</_option> + </param> + <param name="unit_text" type="description">Unit of measure for both circular pitch and center diameter.</param> <effect> <object-type>all</object-type> <effects-menu> diff --git a/share/extensions/gears.py b/share/extensions/gears.py index 8f4745423..a1b3ee666 100644 --- a/share/extensions/gears.py +++ b/share/extensions/gears.py @@ -21,6 +21,7 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA import inkex import simplestyle, sys from math import * +import string def involute_intersect_angle(Rb, R): Rb, R = float(Rb), float(R) @@ -55,11 +56,20 @@ class Gears(inkex.Effect): action="store", type="float", dest="angle", default=20.0, help="Pressure Angle (common values: 14.5, 20, 25 degrees)") + self.OptionParser.add_option("-c", "--centerdiameter", + action="store", type="float", + dest="centerdiameter", default=10.0, + help="Diameter of central hole - 0.0 for no hole") + self.OptionParser.add_option("-u", "--unit", + action="store", type="string", + dest="unit", default="px", + help="unit of measure for circular pitch and center diameter") def effect(self): teeth = self.options.teeth - pitch = self.options.pitch + pitch = inkex.unittouu( str(self.options.pitch) + self.options.unit) angle = self.options.angle # Angle of tangent to tooth at circular pitch wrt radial line. + centerdiameter = inkex.unittouu( str(self.options.centerdiameter) + self.options.unit) # print >>sys.stderr, "Teeth: %s\n" % teeth @@ -157,6 +167,15 @@ class Gears(inkex.Effect): style = { 'stroke': '#000000', 'fill': 'none' } gear_attribs = {'style':simplestyle.formatStyle(style), 'd':path} gear = inkex.etree.SubElement(g, inkex.addNS('path','svg'), gear_attribs ) + if(centerdiameter > 0.0): + center_attribs = {'style':simplestyle.formatStyle(style), + inkex.addNS('cx','sodipodi') :'0.0', + inkex.addNS('cy','sodipodi') :'0.0', + inkex.addNS('rx','sodipodi') :str(centerdiameter/2), + inkex.addNS('ry','sodipodi') :str(centerdiameter/2), + inkex.addNS('type','sodipodi') :'arc' + } + center = inkex.etree.SubElement(g, inkex.addNS('path','svg'), center_attribs ) if __name__ == '__main__': e = Gears() diff --git a/share/extensions/grid_cartesian.inx b/share/extensions/grid_cartesian.inx index 445f50904..494aabf76 100644 --- a/share/extensions/grid_cartesian.inx +++ b/share/extensions/grid_cartesian.inx @@ -1,38 +1,40 @@ <?xml version="1.0" encoding="UTF-8"?> <inkscape-extension xmlns="http://www.inkscape.org/namespace/inkscape/extension"> - <_name>Cartesian Grid</_name> - <id>grid.cartesian</id> - <dependency type="executable" location="extensions">grid_cartesian.py</dependency> - <dependency type="executable" location="extensions">inkex.py</dependency> - <param name="border_th" type="float" min="0" max="1000" _gui-text="Border Thickness (px):">3</param> - <_param name="x_axis" type="groupheader">X Axis</_param> - <param name="x_divs" type="int" min="1" max="1000" _gui-text="Major X Divisions:">6</param> - <param name="dx" type="float" min="1" max="1000" _gui-text="Major X Division Spacing (px):">100.0</param> - <param name="x_subdivs" type="int" min="1" max="1000" _gui-text="Subdivisions per Major X Division:">2</param> - <param name="x_log" type="boolean" _gui-text="Logarithmic X Subdiv. (Base given by entry above)">false</param> - <param name="x_subsubdivs" type="int" min="1" max="1000" _gui-text="Subsubdivs. per X Subdivision:">5</param> - <param name="x_half_freq" type="int" min="1" max="1000" _gui-text="Halve X Subsubdiv. Frequency after 'n' Subdivs. (log only):">4</param> - <param name="x_divs_th" type="float" min="0" max="1000" _gui-text="Major X Division Thickness (px):">2</param> - <param name="x_subdivs_th" type="float" min="0" max="1000" _gui-text="Minor X Division Thickness (px):">1</param> - <param name="x_subsubdivs_th" type="float" min="0" max="1000" _gui-text="Subminor X Division Thickness (px):">0.3</param> - <_param name="y_axis" type="groupheader">Y Axis</_param> - <param name="y_divs" type="int" min="1" max="1000" _gui-text="Major Y Divisions:">5</param> - <param name="dy" type="float" min="1" max="1000" _gui-text="Major Y Division Spacing (px):">100.0</param> - <param name="y_subdivs" type="int" min="1" max="1000" _gui-text="Subdivisions per Major Y Division:">1</param> - <param name="y_log" type="boolean" _gui-text="Logarithmic Y Subdiv. (Base given by entry above)">false</param> - <param name="y_subsubdivs" type="int" min="1" max="1000" _gui-text="Subsubdivs. per Y Subdivision:">5</param> - <param name="y_half_freq" type="int" min="1" max="1000" _gui-text="Halve Y Subsubdiv. Frequency after 'n' Subdivs. (log only):">4</param> - <param name="y_divs_th" type="float" min="0" max="1000" _gui-text="Major Y Division Thickness (px):">2</param> - <param name="y_subdivs_th" type="float" min="0" max="1000" _gui-text="Minor Y Division Thickness (px):">1</param> - <param name="y_subsubdivs_th" type="float" min="0" max="1000" _gui-text="Subminor Y Division Thickness (px):">0.3</param> + <_name>Cartesian Grid</_name> + <id>grid.cartesian</id> + <dependency type="executable" location="extensions">grid_cartesian.py</dependency> + <dependency type="executable" location="extensions">inkex.py</dependency> + <param name="border_th" type="float" min="0" max="1000" _gui-text="Border Thickness (px):">3</param> + <_param name="x_axis" type="description" appearance="header">X Axis</_param> + <param name="x_divs" type="int" min="1" max="1000" _gui-text="Major X Divisions:">6</param> + <param name="dx" type="float" min="1" max="1000" _gui-text="Major X Division Spacing (px):">100.0</param> + <param name="x_subdivs" type="int" min="1" max="1000" _gui-text="Subdivisions per Major X Division:">2</param> + <param name="x_log" type="boolean" _gui-text="Logarithmic X Subdiv. (Base given by entry above)">false</param> + <param name="x_subsubdivs" type="int" min="1" max="1000" _gui-text="Subsubdivs. per X Subdivision:">5</param> + <param name="x_half_freq" type="int" min="1" max="1000" _gui-text="Halve X Subsubdiv. Frequency after 'n' Subdivs. (log only):">4</param> + <param name="x_divs_th" type="float" min="0" max="1000" _gui-text="Major X Division Thickness (px):">2</param> + <param name="x_subdivs_th" type="float" min="0" max="1000" _gui-text="Minor X Division Thickness (px):">1</param> + <param name="x_subsubdivs_th" type="float" min="0" max="1000" _gui-text="Subminor X Division Thickness (px):">0.3</param> + <_param name="y_axis" type="description" appearance="header">Y Axis</_param> + <param name="y_divs" type="int" min="1" max="1000" _gui-text="Major Y Divisions:">5</param> + <param name="dy" type="float" min="1" max="1000" _gui-text="Major Y Division Spacing (px):">100.0</param> + <param name="y_subdivs" type="int" min="1" max="1000" _gui-text="Subdivisions per Major Y Division:">1</param> + <param name="y_log" type="boolean" _gui-text="Logarithmic Y Subdiv. (Base given by entry above)">false</param> + <param name="y_subsubdivs" type="int" min="1" max="1000" _gui-text="Subsubdivs. per Y Subdivision:">5</param> + <param name="y_half_freq" type="int" min="1" max="1000" _gui-text="Halve Y Subsubdiv. Frequency after 'n' Subdivs. (log only):">4</param> + <param name="y_divs_th" type="float" min="0" max="1000" _gui-text="Major Y Division Thickness (px):">2</param> + <param name="y_subdivs_th" type="float" min="0" max="1000" _gui-text="Minor Y Division Thickness (px):">1</param> + <param name="y_subsubdivs_th" type="float" min="0" max="1000" _gui-text="Subminor Y Division Thickness (px):">0.3</param> - <effect> - <object-type>all</object-type> - <effects-menu> - <submenu _name="Render"/> - </effects-menu> - </effect> - <script> - <command reldir="extensions" interpreter="python">grid_cartesian.py</command> - </script> + <effect> + <object-type>all</object-type> + <effects-menu> + <submenu _name="Render"> + <submenu name="Grids"/> + </submenu> + </effects-menu> + </effect> + <script> + <command reldir="extensions" interpreter="python">grid_cartesian.py</command> + </script> </inkscape-extension> diff --git a/share/extensions/grid_isometric.inx b/share/extensions/grid_isometric.inx new file mode 100644 index 000000000..bda671f18 --- /dev/null +++ b/share/extensions/grid_isometric.inx @@ -0,0 +1,27 @@ +<?xml version="1.0" encoding="UTF-8"?> +<inkscape-extension xmlns="http://www.inkscape.org/namespace/inkscape/extension"> + <_name>Isometric Grid</_name> + <id>grid.iso_grid</id> + <dependency type="executable" location="extensions">grid_isometric.py</dependency> + <dependency type="executable" location="extensions">inkex.py</dependency> + <param name="x_divs" type="int" min="1" max="1000" _gui-text="X Divisions [x2]:">5</param> + <param name="y_divs" type="int" min="1" max="1000" _gui-text="Y Divisions [x2] [> 1/2 X Div]:">5</param> + <param name="dx" type="float" min="1" max="1000" _gui-text="Division Spacing (px):">50.0</param> + <param name="subdivs" type="int" min="1" max="1000" _gui-text="Subdivisions per Major Division:">2</param> + <param name="subsubdivs" type="int" min="1" max="1000" _gui-text="Subsubdivs per Subdivision:">5</param> + <param name="divs_th" type="float" min="0" max="1000" _gui-text="Major Division Thickness (px):">2</param> + <param name="subdivs_th" type="float" min="0" max="1000" _gui-text="Minor Division Thickness (px):">0.5</param> + <param name="subsubdivs_th" type="float" min="0" max="1000" _gui-text="Subminor Division Thickness (px):">0.1</param> + <param name="border_th" type="float" min="0" max="1000" _gui-text="Border Thickness (px):">3</param> + <effect> + <object-type>all</object-type> + <effects-menu> + <submenu _name="Render"> + <submenu name="Grids"/> + </submenu> + </effects-menu> + </effect> + <script> + <command reldir="extensions" interpreter="python">grid_isometric.py</command> + </script> +</inkscape-extension> diff --git a/share/extensions/grid_isometric.py b/share/extensions/grid_isometric.py new file mode 100644 index 000000000..27951a0a8 --- /dev/null +++ b/share/extensions/grid_isometric.py @@ -0,0 +1,381 @@ +#!/usr/bin/env python + +#Copyright (C) 2010 Jean-Luc JOULIN "JeanJouX" jean-luc.joulin@laposte.net + +#This extension allow you to draw a isometric grid with inkscape +#There is some options including subdivision, subsubdivions and custom line width +#All elements are grouped with similar elements +#These grid are used for isometric view in mechanical drawing or piping schematic +#!!! Y Divisions can't be smaller than half the X Divions + +#This program is free software; you can redistribute it and/or modify +#it under the terms of the GNU General Public License as published by +#the Free Software Foundation; either version 2 of the License, or +#(at your option) any later version. + +#This program is distributed in the hope that it will be useful, +#but WITHOUT ANY WARRANTY; without even the implied warranty of +#MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +#GNU General Public License for more details. + +#You should have received a copy of the GNU General Public License +#along with this program; if not, write to the Free Software +#Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + + +import inkex +import simplestyle, sys +from math import * + + +def draw_SVG_line(x1, y1, x2, y2, width, name, parent): + style = { 'stroke': '#000000', 'stroke-width':str(width), 'fill': 'none' } + line_attribs = {'style':simplestyle.formatStyle(style), + inkex.addNS('label','inkscape'):name, + 'd':'M '+str(x1)+','+str(y1)+' L '+str(x2)+','+str(y2)} + inkex.etree.SubElement(parent, inkex.addNS('path','svg'), line_attribs ) + +def draw_SVG_rect(x,y,w,h, width, fill, name, parent): + style = { 'stroke': '#000000', 'stroke-width':str(width), 'fill':fill} + rect_attribs = {'style':simplestyle.formatStyle(style), + inkex.addNS('label','inkscape'):name, + 'x':str(x), 'y':str(y), 'width':str(w), 'height':str(h)} + inkex.etree.SubElement(parent, inkex.addNS('rect','svg'), rect_attribs ) + +class Grid_Polar(inkex.Effect): + def __init__(self): + inkex.Effect.__init__(self) + self.OptionParser.add_option("--x_divs", + action="store", type="int", + dest="x_divs", default=5, + help="Major X Divisions") + self.OptionParser.add_option("--y_divs", + action="store", type="int", + dest="y_divs", default=5, + help="Major X Divisions") + self.OptionParser.add_option("--dx", + action="store", type="float", + dest="dx", default=10.0, + help="Major X divison Spacing") + self.OptionParser.add_option("--subdivs", + action="store", type="int", + dest="subdivs", default=2, + help="Subdivisions per Major X division") + self.OptionParser.add_option("--subsubdivs", + action="store", type="int", + dest="subsubdivs", default=5, + help="Subsubdivisions per Minor X division") + self.OptionParser.add_option("--divs_th", + action="store", type="float", + dest="divs_th", default=2, + help="Major X Division Line thickness") + self.OptionParser.add_option("--subdivs_th", + action="store", type="float", + dest="subdivs_th", default=1, + help="Minor X Division Line thickness") + self.OptionParser.add_option("--subsubdivs_th", + action="store", type="float", + dest="subsubdivs_th", default=0.3, + help="Subminor X Division Line thickness") + self.OptionParser.add_option("--border_th", + action="store", type="float", + dest="border_th", default=3, + help="Border Line thickness") + + def effect(self): + + #Can't generate a grid too flat + #If the Y dimension is smallest than half the X dimension, fix it. + if self.options.y_divs<((self.options.x_divs+1)/2): + self.options.y_divs=int((self.options.x_divs+1)/2) + + #Find the pixel dimensions of the overall grid + xmax = self.options.dx * (2*self.options.x_divs) + ymax = self.options.dx * (2*self.options.y_divs) / 0.866025 + + #Embed grid in group + #Put in in the centre of the current view + t = 'translate(' + str( self.view_center[0]- xmax/2.0) + ',' + \ + str( self.view_center[1]- ymax/2.0) + ')' + g_attribs = {inkex.addNS('label','inkscape'):'Grid_Polar:X' + \ + str( self.options.x_divs )+':Y'+str( self.options.y_divs ), + 'transform':t } + grid = inkex.etree.SubElement(self.current_layer, 'g', g_attribs) + + #Group for major x gridlines + g_attribs = {inkex.addNS('label','inkscape'):'MajorXGridlines'} + majglx = inkex.etree.SubElement(grid, 'g', g_attribs) + #Group for major y gridlines + g_attribs = {inkex.addNS('label','inkscape'):'MajorYGridlines'} + majgly = inkex.etree.SubElement(grid, 'g', g_attribs) + #Group for major z gridlines + g_attribs = {inkex.addNS('label','inkscape'):'MajorZGridlines'} + majglz = inkex.etree.SubElement(grid, 'g', g_attribs) + #Group for minor x gridlines + if self.options.subdivs > 1:#if there are any minor x gridlines + g_attribs = {inkex.addNS('label','inkscape'):'MinorXGridlines'} + minglx = inkex.etree.SubElement(grid, 'g', g_attribs) + #Group for subminor x gridlines + if self.options.subsubdivs > 1:#if there are any minor minor x gridlines + g_attribs = {inkex.addNS('label','inkscape'):'SubMinorXGridlines'} + mminglx = inkex.etree.SubElement(grid, 'g', g_attribs) + #Group for minor y gridlines + if self.options.subdivs > 1:#if there are any minor y gridlines + g_attribs = {inkex.addNS('label','inkscape'):'MinorYGridlines'} + mingly = inkex.etree.SubElement(grid, 'g', g_attribs) + #Group for subminor y gridlines + if self.options.subsubdivs > 1:#if there are any minor minor x gridlines + g_attribs = {inkex.addNS('label','inkscape'):'SubMinorYGridlines'} + mmingly = inkex.etree.SubElement(grid, 'g', g_attribs) + #Group for minor z gridlines + if self.options.subdivs > 1:#if there are any minor y gridlines + g_attribs = {inkex.addNS('label','inkscape'):'MinorZGridlines'} + minglz = inkex.etree.SubElement(grid, 'g', g_attribs) + #Group for subminor z gridlines + if self.options.subsubdivs > 1:#if there are any minor minor x gridlines + g_attribs = {inkex.addNS('label','inkscape'):'SubMinorZGridlines'} + mminglz = inkex.etree.SubElement(grid, 'g', g_attribs) + + + draw_SVG_rect(0, 0, xmax, ymax, self.options.border_th, + 'none', 'Border', grid) #Border of grid + + #X DIVISION + #Shortcuts for divisions + sd = self.options.subdivs + ssd = self.options.subsubdivs + + #Initializing variable + cpt_div=0 + cpt_subdiv=0 + cpt_subsubdiv=0 + com_div=0 + com_subdiv=0 + com_subsubdiv=0 + + for i in range(1, (2*self.options.x_divs*sd*ssd)): + cpt_subsubdiv=cpt_subsubdiv+1 + com_subsubdiv=1 + if cpt_subsubdiv==self.options.subsubdivs: + cpt_subsubdiv=0 + cpt_subdiv=cpt_subdiv+1 + com_subsubdiv=0 + com_subdiv=1 + com_div=0 + + if cpt_subdiv==self.options.subdivs: + cpt_subdiv=0 + com_subsubdiv=0 + com_subdiv=0 + com_div=1 + + if com_subsubdiv==1: + draw_SVG_line(self.options.dx*i/sd/ssd, 0, + self.options.dx*i/sd/ssd,ymax, + self.options.subsubdivs_th, + 'MajorXDiv'+str(i), mminglx) + if com_subdiv==1: + com_subdiv=0 + draw_SVG_line(self.options.dx*i/sd/ssd, 0, + self.options.dx*i/sd/ssd,ymax, + self.options.subdivs_th, + 'MajorXDiv'+str(i), minglx) + if com_div==1: + com_div=0 + draw_SVG_line(self.options.dx*i/sd/ssd, 0, + self.options.dx*i/sd/ssd,ymax, + self.options.divs_th, + 'MajorXDiv'+str(i), majglx) + + + #Y DIVISONS + #Shortcuts for divisions + sd = self.options.subdivs + ssd = self.options.subsubdivs + + taille=self.options.dx/sd/ssd #Size of unity + nb_ligne=(self.options.x_divs+self.options.y_divs)*self.options.subdivs*self.options.subsubdivs #Global number of lines + nb_ligne_x=self.options.x_divs*self.options.subdivs*self.options.subsubdivs #Number of lines X + nb_ligne_y=self.options.y_divs*self.options.subdivs*self.options.subsubdivs #Number of lines Y + + #Initializing variable + cpt_div=0 + cpt_subdiv=0 + cpt_subsubdiv=0 + com_div=0 + com_subdiv=0 + com_subsubdiv=0 + + + for l in range(1, int(nb_ligne*4)): + cpt_subsubdiv=cpt_subsubdiv+1 + com_subsubdiv=1 + if cpt_subsubdiv==self.options.subsubdivs: + cpt_subsubdiv=0 + cpt_subdiv=cpt_subdiv+1 + com_subsubdiv=0 + com_subdiv=1 + com_div=0 + + if cpt_subdiv==self.options.subdivs: + cpt_subdiv=0 + com_subsubdiv=0 + com_subdiv=0 + com_div=1 + + if ((2*l)-1)< (2*nb_ligne_x): + txa=taille*((2*l)-1) + tya=ymax + txb=0 + tyb=ymax-(taille)/(2*0.866025)-(taille*((l-1))/(0.866025)) + + if com_subsubdiv==1: + draw_SVG_line(txa, tya, + txb,tyb, + self.options.subsubdivs_th, + 'MajorYDiv'+str(i), mmingly) + draw_SVG_line(xmax-txa, tya, + xmax-txb,tyb, + self.options.subsubdivs_th, + 'MajorZDiv'+str(l), mminglz) + if com_subdiv==1: + com_subdiv=0 + draw_SVG_line(txa, tya, + txb,tyb, + self.options.subdivs_th, + 'MajorYDiv'+str(i), mingly) + draw_SVG_line(xmax-txa, tya, + xmax-txb,tyb, + self.options.subdivs_th, + 'MajorZDiv'+str(l), minglz) + if com_div==1: + com_div=0 + draw_SVG_line(txa, tya, + txb,tyb, + self.options.divs_th, + 'MajorYDiv'+str(i), majgly) + draw_SVG_line(xmax-txa, tya, + xmax-txb,tyb, + self.options.divs_th, + 'MajorZDiv'+str(l), majglz) + + if ((2*l)-1)==(2*nb_ligne_x): + txa=taille*((2*l)-1) + tya=ymax + txb=0 + tyb=ymax-(taille)/(2*0.866025)-(taille*((l-1))/(0.866025)) + + if com_subsubdiv==1: + draw_SVG_line(txa, tya, + txb,tyb, + self.options.subsubdivs_th, + 'MajorYDiv'+str(i), mmingly) + draw_SVG_line(xmax-txa, tya, + xmax-txb,tyb, + self.options.subsubdivs_th, + 'MajorZDiv'+str(l), mminglz) + if com_subdiv==1: + com_subdiv=0 + draw_SVG_line(txa, tya, + txb,tyb, + self.options.subdivs_th, + 'MajorYDiv'+str(i), mingly) + draw_SVG_line(xmax-txa, tya, + xmax-txb,tyb, + self.options.subdivs_th, + 'MajorZDiv'+str(l), minglz) + if com_div==1: + com_div=0 + draw_SVG_line(txa, tya, + txb,tyb, + self.options.divs_th, + 'MajorYDiv'+str(i), majgly) + draw_SVG_line(xmax-txa, tya, + xmax-txb,tyb, + self.options.divs_th, + 'MajorZDiv'+str(l), majglz) + + if ((2*l)-1)> (2*nb_ligne_x): + txa=xmax + tya=ymax-(taille)/(2*0.866025)-(taille*((l-1-((2*nb_ligne_x)/2)))/(0.866025)) + txb=0 + tyb=ymax-(taille)/(2*0.866025)-(taille*((l-1))/(0.866025)) + + if tyb<=0: + txa=xmax + tya=ymax-(taille)/(2*0.866025)-(taille*((l-1-((2*nb_ligne_x)/2)))/(0.866025)) + txb=taille*((2*(l-(2*nb_ligne_y))-1)) + tyb=0 + + if txb<xmax: + if com_subsubdiv==1: + draw_SVG_line(txa, tya, + txb,tyb, + self.options.subsubdivs_th, + 'MajorYDiv'+str(i), mmingly) + draw_SVG_line(xmax-txa, tya, + xmax-txb,tyb, + self.options.subsubdivs_th, + 'MajorZDiv'+str(l), mminglz) + if com_subdiv==1: + com_subdiv=0 + draw_SVG_line(txa, tya, + txb,tyb, + self.options.subdivs_th, + 'MajorYDiv'+str(i), mingly) + draw_SVG_line(xmax-txa, tya, + xmax-txb,tyb, + self.options.subdivs_th, + 'MajorZDiv'+str(l), minglz) + if com_div==1: + com_div=0 + draw_SVG_line(txa, tya, + txb,tyb, + self.options.divs_th, + 'MajorYDiv'+str(i), majgly) + draw_SVG_line(xmax-txa, tya, + xmax-txb,tyb, + self.options.divs_th, + 'MajorZDiv'+str(l), majglz) + + else: + if txb<xmax: + if com_subsubdiv==1: + draw_SVG_line(txa, tya, + txb,tyb, + self.options.subsubdivs_th, + 'MajorYDiv'+str(i), mmingly) + draw_SVG_line(xmax-txa, tya, + xmax-txb,tyb, + self.options.subsubdivs_th, + 'MajorZDiv'+str(l), mminglz) + if com_subdiv==1: + com_subdiv=0 + draw_SVG_line(txa, tya, + txb,tyb, + self.options.subdivs_th, + 'MajorYDiv'+str(i), mingly) + draw_SVG_line(xmax-txa, tya, + xmax-txb,tyb, + self.options.subdivs_th, + 'MajorZDiv'+str(l), minglz) + if com_div==1: + com_div=0 + draw_SVG_line(txa, tya, + txb,tyb, + self.options.divs_th, + 'MajorYDiv'+str(i), majgly) + draw_SVG_line(xmax-txa, tya, + xmax-txb,tyb, + self.options.divs_th, + 'MajorZDiv'+str(l), majglz) + + + +if __name__ == '__main__': + e = Grid_Polar() + e.affect() + +#End of file + + diff --git a/share/extensions/grid_polar.inx b/share/extensions/grid_polar.inx index 7eb0efe52..ee468fa34 100644 --- a/share/extensions/grid_polar.inx +++ b/share/extensions/grid_polar.inx @@ -1,39 +1,40 @@ <?xml version="1.0" encoding="UTF-8"?> <inkscape-extension xmlns="http://www.inkscape.org/namespace/inkscape/extension"> - <_name>Polar Grid</_name> - <id>grids.polar</id> - <dependency type="executable" location="extensions">grid_polar.py</dependency> - <dependency type="executable" location="extensions">inkex.py</dependency> - <param name="c_dot_dia" type="float" min="1" max="1000" _gui-text="Centre Dot Diameter (px):">5.0</param> - <param name="a_labels" type="enum" _gui-text="Circumferential Labels:"> - <_item value="none">None</_item> - <_item value="deg">Degrees</_item> - </param> - <param name="a_label_size" type="int" min="1" max="1000" _gui-text="Circumferential Label Size (px):">18</param> - <param name="a_label_outset" type="float" min="0" max="1000" _gui-text="Circumferential Label Outset (px):">24</param> - <_param name="circ_divs_label" type="groupheader">Circular Divisions</_param> - <param name="r_divs" type="int" min="1" max="1000" _gui-text="Major Circular Divisions:">5</param> - <param name="dr" type="float" min="1" max="1000" _gui-text="Major Circular Division Spacing (px):">50.0</param> - <param name="r_subdivs" type="int" min="1" max="1000" _gui-text="Subdivisions per Major Circular Division:">3</param> - <param name="r_log" type="boolean" _gui-text="Logarithmic Subdiv. (Base given by entry above)">false</param> - <param name="r_divs_th" type="float" min="0" max="1000" _gui-text="Major Circular Division Thickness (px):">2</param> - <param name="r_subdivs_th" type="float" min="0" max="1000" _gui-text="Minor Circular Division Thickness (px):">1</param> - <_param name="ang_divs_label" type="groupheader">Angular Divisions</_param> - <param name="a_divs" type="int" min="1" max="1000" _gui-text="Angle Divisions:">24</param> - <param name="a_divs_cent" type="int" min="1" max="1000" _gui-text="Angle Divisions at Centre:">4</param> - <param name="a_subdivs" type="int" min="1" max="1000" _gui-text="Subdivisions per Major Angular Division:">1</param> - <param name="a_subdivs_cent" type="int" min="0" max="1000" _gui-text="Minor Angle Division End 'n' Divs. Before Centre:">2</param> - <param name="a_divs_th" type="float" min="0" max="1000" _gui-text="Major Angular Division Thickness (px):">2</param> - <param name="a_subdivs_th" type="float" min="0" max="1000" _gui-text="Minor Angular Division Thickness (px):">1</param> - + <_name>Polar Grid</_name> + <id>grids.polar</id> + <dependency type="executable" location="extensions">grid_polar.py</dependency> + <dependency type="executable" location="extensions">inkex.py</dependency> + <param name="c_dot_dia" type="float" min="1" max="1000" _gui-text="Centre Dot Diameter (px):">5.0</param> + <param name="a_labels" type="enum" _gui-text="Circumferential Labels:"> + <_item value="none">None</_item> + <_item value="deg">Degrees</_item> + </param> + <param name="a_label_size" type="int" min="1" max="1000" _gui-text="Circumferential Label Size (px):">18</param> + <param name="a_label_outset" type="float" min="0" max="1000" _gui-text="Circumferential Label Outset (px):">24</param> + <_param name="circ_divs_label" type="description" appearance="header">Circular Divisions</_param> + <param name="r_divs" type="int" min="1" max="1000" _gui-text="Major Circular Divisions:">5</param> + <param name="dr" type="float" min="1" max="1000" _gui-text="Major Circular Division Spacing (px):">50.0</param> + <param name="r_subdivs" type="int" min="1" max="1000" _gui-text="Subdivisions per Major Circular Division:">3</param> + <param name="r_log" type="boolean" _gui-text="Logarithmic Subdiv. (Base given by entry above)">false</param> + <param name="r_divs_th" type="float" min="0" max="1000" _gui-text="Major Circular Division Thickness (px):">2</param> + <param name="r_subdivs_th" type="float" min="0" max="1000" _gui-text="Minor Circular Division Thickness (px):">1</param> + <_param name="ang_divs_label" type="description" appearance="header">Angular Divisions</_param> + <param name="a_divs" type="int" min="1" max="1000" _gui-text="Angle Divisions:">24</param> + <param name="a_divs_cent" type="int" min="1" max="1000" _gui-text="Angle Divisions at Centre:">4</param> + <param name="a_subdivs" type="int" min="1" max="1000" _gui-text="Subdivisions per Major Angular Division:">1</param> + <param name="a_subdivs_cent" type="int" min="0" max="1000" _gui-text="Minor Angle Division End 'n' Divs. Before Centre:">2</param> + <param name="a_divs_th" type="float" min="0" max="1000" _gui-text="Major Angular Division Thickness (px):">2</param> + <param name="a_subdivs_th" type="float" min="0" max="1000" _gui-text="Minor Angular Division Thickness (px):">1</param> - <effect> - <object-type>all</object-type> - <effects-menu> - <submenu _name="Render"/> - </effects-menu> - </effect> - <script> - <command reldir="extensions" interpreter="python">grid_polar.py</command> - </script> + <effect> + <object-type>all</object-type> + <effects-menu> + <submenu _name="Render"> + <submenu name="Grids"/> + </submenu> + </effects-menu> + </effect> + <script> + <command reldir="extensions" interpreter="python">grid_polar.py</command> + </script> </inkscape-extension> diff --git a/share/extensions/inkscape_help_relnotes.inx b/share/extensions/inkscape_help_relnotes.inx index 881eada0c..7b034da8d 100644 --- a/share/extensions/inkscape_help_relnotes.inx +++ b/share/extensions/inkscape_help_relnotes.inx @@ -3,7 +3,7 @@ <_name>New in This Version</_name> <id>org.inkscape.help.relnotes</id> <dependency type="executable" location="extensions">launch_webbrowser.py</dependency> - <param name="url" gui-hidden="true" type="string">http://wiki.inkscape.org/wiki/index.php/Release_notes/0.48</param> + <param name="url" gui-hidden="true" type="string">http://wiki.inkscape.org/wiki/index.php/Release_notes/0.49</param> <effect needs-document="false"> <object-type>all</object-type> <effects-menu hidden="true"/> diff --git a/share/extensions/jessyInk_effects.inx b/share/extensions/jessyInk_effects.inx index 3a8a03df8..ce55b3859 100644 --- a/share/extensions/jessyInk_effects.inx +++ b/share/extensions/jessyInk_effects.inx @@ -12,7 +12,7 @@ <param name="effectIn" type="optiongroup" _gui-text="Type:"> <_option value="none">None (default)</_option> <_option value="appear">Appear</_option> - <_option value="fade">Fade</_option> + <_option value="fade">Fade in</_option> <_option value="pop">Pop</_option> </param> <_param name="effectOutLabel" type="description">Build-out effect</_param> @@ -21,7 +21,7 @@ <param name="effectOut" type="optiongroup" _gui-text="Type:"> <_option value="none">None (default)</_option> <_option value="appear">Appear</_option> - <_option value="fade">Fade</_option> + <_option value="fade">Fade out</_option> <_option value="pop">Pop</_option> </param> </page> diff --git a/share/extensions/markers_strokepaint.inx b/share/extensions/markers_strokepaint.inx index 50c1a1d7e..2422482a7 100644 --- a/share/extensions/markers_strokepaint.inx +++ b/share/extensions/markers_strokepaint.inx @@ -1,16 +1,40 @@ <?xml version="1.0" encoding="UTF-8"?> <inkscape-extension xmlns="http://www.inkscape.org/namespace/inkscape/extension"> - <_name>Color Markers to Match Stroke</_name> - <id>org.ekips.filter.markers.strokepaint</id> - <dependency type="executable" location="extensions">markers_strokepaint.py</dependency> - <dependency type="executable" location="extensions">inkex.py</dependency> - <effect> - <object-type>all</object-type> - <effects-menu> - <submenu _name="Modify Path"/> - </effects-menu> - </effect> - <script> - <command reldir="extensions" interpreter="python">markers_strokepaint.py</command> - </script> + <_name>Color Markers</_name> + <id>org.ekips.filter.markers.strokepaint</id> + <dependency type="executable" location="extensions">markers_strokepaint.py</dependency> + <dependency type="executable" location="extensions">inkex.py</dependency> + + <param name='tab' type="notebook"> + <page name='object' _gui-text="From object"> + <param name="type" type="enum" _gui-text="Marker type:"> + <_item value="solid">solid</_item> + <_item value="filled">filled</_item> + </param> + <param name="invert" type="boolean" _gui-text="Invert fill and stroke colors">false</param> + <param name="alpha" type="boolean" _gui-text="Assign alpha">true</param> + </page> + <page name='custom' _gui-text="Custom"> + <param name="colortab" type="notebook"> + <page name="fill_page" _gui-text="Fill"> + <param name="assign_fill" type="boolean" _gui-text="Assign fill color">true</param> + <param name="fill_color" gui-text="Fill color" type="color">-1</param> + </page> + <page name="stroke_page" _gui-text="Stroke"> + <param name="assign_stroke" type="boolean" _gui-text="Assign stroke color">true</param> + <param name="stroke_color" gui-text="Stroke color" type="color">255</param> + </page> + </param> + </page> + </param> + + <effect> + <object-type>all</object-type> + <effects-menu> + <submenu _name="Modify Path"/> + </effects-menu> + </effect> + <script> + <command reldir="extensions" interpreter="python">markers_strokepaint.py</command> + </script> </inkscape-extension> diff --git a/share/extensions/markers_strokepaint.py b/share/extensions/markers_strokepaint.py index 5f85d69db..d357d1988 100644 --- a/share/extensions/markers_strokepaint.py +++ b/share/extensions/markers_strokepaint.py @@ -1,6 +1,7 @@ #!/usr/bin/env python ''' Copyright (C) 2006 Aaron Spike, aaron@ekips.org +Copyright (C) 2010 Nicolas Dufour, nicoduf@yahoo.fr (color options) This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -26,8 +27,44 @@ class MyEffect(inkex.Effect): self.OptionParser.add_option("-m", "--modify", action="store", type="inkbool", dest="modify", default=False, - help="do not create a copy, modify the markers") - + help="Do not create a copy, modify the markers") + self.OptionParser.add_option("-t", "--type", + action="store", type="string", + dest="fill_type", default="stroke", + help="Replace the markers' fill with the object stroke or fill color") + self.OptionParser.add_option("-a", "--alpha", + action="store", type="inkbool", + dest="assign_alpha", default=True, + help="Assign the object fill and stroke alpha to the markers") + self.OptionParser.add_option("-i", "--invert", + action="store", type="inkbool", + dest="invert", default=False, + help="Invert fill and stroke colors") + self.OptionParser.add_option("--assign_fill", + action="store", type="inkbool", + dest="assign_fill", default=True, + help="Assign a fill color to the markers") + self.OptionParser.add_option("-f", "--fill_color", + action="store", type="int", + dest="fill_color", default=1364325887, + help="Choose a custom fill color") + self.OptionParser.add_option("--assign_stroke", + action="store", type="inkbool", + dest="assign_stroke", default=True, + help="Assign a stroke color to the markers") + self.OptionParser.add_option("-s", "--stroke_color", + action="store", type="int", + dest="stroke_color", default=1364325887, + help="Choose a custom fill color") + self.OptionParser.add_option("--tab", + action="store", type="string", + dest="tab", + help="The selected UI-tab when OK was pressed") + self.OptionParser.add_option("--colortab", + action="store", type="string", + dest="colortab", + help="The selected cutom color tab when OK was pressed") + def effect(self): defs = self.xpathSingle('/svg:svg//svg:defs') if defs == None: @@ -40,12 +77,51 @@ class MyEffect(inkex.Effect): except: inkex.errormsg(_("No style attribute found for id: %s") % id) continue - - stroke = style.get('stroke', '#000000') - + + # Use object colors + if self.options.tab == '"object"': + temp_stroke = style.get('stroke', '#000000') + temp_fill = style.get('fill', '#000000') + if (self.options.invert): + fill = temp_stroke + stroke = temp_fill + else: + fill = temp_fill + stroke = temp_stroke + if (self.options.assign_alpha): + temp_stroke_opacity = style.get('stroke-opacity', '1') + temp_fill_opacity = style.get('fill-opacity', '1') + if (self.options.invert): + fill_opacity = temp_stroke_opacity + stroke_opacity = temp_fill_opacity + else: + fill_opacity = temp_fill_opacity + stroke_opacity = temp_stroke_opacity + if (self.options.fill_type == "solid"): + fill = stroke + if (self.options.assign_alpha): + fill_opacity = stroke_opacity + # Choose custom colors + elif self.options.tab == '"custom"': + fill_red = ((self.options.fill_color >> 24) & 255) + fill_green = ((self.options.fill_color >> 16) & 255) + fill_blue = ((self.options.fill_color >> 8) & 255) + fill = "rgb(%s,%s,%s)" % (fill_red, fill_green, fill_blue) + fill_opacity = (((self.options.fill_color) & 255) / 255.) + stroke_red = ((self.options.stroke_color >> 24) & 255) + stroke_green = ((self.options.stroke_color >> 16) & 255) + stroke_blue = ((self.options.stroke_color >> 8) & 255) + stroke = "rgb(%s,%s,%s)" % (stroke_red, stroke_green, stroke_blue) + stroke_opacity = (((self.options.stroke_color) & 255) / 255.) + if (not(self.options.assign_fill)): + fill = "none"; + if (not(self.options.assign_stroke)): + stroke = "none"; + for mprop in mprops: if style.has_key(mprop) and style[mprop] != 'none'and style[mprop][:5] == 'url(#': marker_id = style[mprop][5:-1] + try: old_mnode = self.xpathSingle('/svg:svg//svg:marker[@id="%s"]' % marker_id) if not self.options.modify: @@ -66,10 +142,14 @@ class MyEffect(inkex.Effect): children = mnode.xpath('.//*[@style]', namespaces=inkex.NSS) for child in children: cstyle = simplestyle.parseStyle(child.get('style')) - if ('stroke' in cstyle and cstyle['stroke'] != 'none') or 'stroke' not in cstyle: + if (not('stroke' in cstyle and self.options.tab == '"object"' and cstyle['stroke'] == 'none' and self.options.fill_type == "filled")): cstyle['stroke'] = stroke - if ('fill' in cstyle and cstyle['fill'] != 'none') or 'fill' not in cstyle: - cstyle['fill'] = stroke + if 'stroke_opacity' in locals(): + cstyle['stroke-opacity'] = stroke_opacity + if (not('fill' in cstyle and self.options.tab == '"object"' and cstyle['fill'] == 'none' and self.options.fill_type == "solid")): + cstyle['fill'] = fill + if 'fill_opacity' in locals(): + cstyle['fill-opacity'] = fill_opacity child.set('style',simplestyle.formatStyle(cstyle)) node.set('style',simplestyle.formatStyle(style)) diff --git a/share/extensions/measure.inx b/share/extensions/measure.inx index 264e33ab6..63a919806 100644 --- a/share/extensions/measure.inx +++ b/share/extensions/measure.inx @@ -8,7 +8,7 @@ <page name="measure" _gui-text="Measure"> <param name="type" type="enum" _gui-text="Measurement Type: "> <_item value="length">Length</_item> - <_item value="area">Area</_item> + <_item msgctxt="measure extension" value="area">Area</_item> </param> <param name="fontsize" type="int" min="1" max="1000" _gui-text="Font size (px):">12</param> <param name="offset" type="float" min="-10000" max="10000" _gui-text="Offset (px):">-6</param> diff --git a/share/extensions/perfectboundcover.inx b/share/extensions/perfectboundcover.inx index 4cbe27a7f..f36ad64a6 100644 --- a/share/extensions/perfectboundcover.inx +++ b/share/extensions/perfectboundcover.inx @@ -4,12 +4,12 @@ <id>org.coswellproductions.inkscape.effects.perfectboundcover</id> <dependency type="executable" location="extensions">perfectboundcover.py</dependency> <dependency type="executable" location="extensions">inkex.py</dependency> - <_param name="book" type="groupheader">Book Properties</_param> + <_param name="book" type="description" appearance="header">Book Properties</_param> <param name="width" precision="3" type="float" min="0.0" max="100.000" _gui-text="Book Width (inches):">6</param> <param name="height" precision="3" type="float" min="0.0" max="100.000" _gui-text="Book Height (inches):">9</param> <param name="pages" type="int" min="4" max="6000" _gui-text="Number of Pages:">64</param> <param name="removeguides" type="boolean" _gui-text="Remove existing guides">true</param> - <_param name="paper" type="groupheader">Interior Pages</_param> + <_param name="paper" type="description" appearance="header">Interior Pages</_param> <param name="paperthicknessmeasurement" _gui-text="Paper Thickness Measurement:" type="enum"> <_item value="ppi">Pages Per Inch (PPI)</_item> <_item value="caliper">Caliper (inches)</_item> @@ -18,7 +18,7 @@ <_item value="width">Specify Width</_item> </param> <param precision="4" name="paperthickness" type="float" min="0.000" max="1000.000" _gui-text="Value:">0</param> - <_param name="cover" type="groupheader">Cover</_param> + <_param name="cover" type="description" appearance="header">Cover</_param> <param name="coverthicknessmeasurement" _gui-text="Cover Thickness Measurement:" type="enum"> <_item value="ppi">Pages Per Inch (PPI)</_item> <_item value="caliper">Caliper (inches)</_item> diff --git a/share/extensions/printing-marks.inx b/share/extensions/printing-marks.inx index 612ae84f5..e5e072c34 100644 --- a/share/extensions/printing-marks.inx +++ b/share/extensions/printing-marks.inx @@ -27,7 +27,7 @@ <item value="mm">mm</item> </param> <param name="crop_offset" type="float" min="0.0" max="9999.0" _gui-text="Offset:">5</param> - <_param name="bleed_settings" type="groupheader">Bleed Margin</_param> + <_param name="bleed_settings" type="description" appearance="header">Bleed Margin</_param> <param name="bleed_top" type="float" min="0.0" max="9999.0" _gui-text="Top:">5</param> <param name="bleed_bottom" type="float" min="0.0" max="9999.0" _gui-text="Bottom:">5</param> <param name="bleed_left" type="float" min="0.0" max="9999.0" _gui-text="Left:">5</param> diff --git a/share/extensions/render_barcode.inx b/share/extensions/render_barcode.inx index 91dd1bbe4..b511c7557 100644 --- a/share/extensions/render_barcode.inx +++ b/share/extensions/render_barcode.inx @@ -5,13 +5,14 @@ <dependency type="executable" location="extensions">inkex.py</dependency> <dependency type="executable" location="extensions">render_barcode.py</dependency> <param name="type" type="enum" _gui-text="Barcode Type:"> + <item value="ean5">EAN5</item> <item value="ean8">EAN8</item> <item value="ean13">EAN13</item> - <item value="ean5">EAN5</item> <item value="upca">UPC-A</item> <item value="upce">UPC-E</item> + <item value="code25i">Code25 Interleaved 2 of 5</item> <item value="code39">Code39</item> - <item value="code39ext">Code39Ext</item> + <item value="code39ext">Code39 Extended</item> <item value="code93">Code93</item> <item value="code128">Code128</item> <item value="rm4scc">RM4CC / RM4SCC</item> diff --git a/share/extensions/render_barcode.py b/share/extensions/render_barcode.py index 3de1a07da..ecfe215aa 100644 --- a/share/extensions/render_barcode.py +++ b/share/extensions/render_barcode.py @@ -39,15 +39,15 @@ class InsertBarcode(inkex.Effect): def effect(self): x, y = self.view_center - object = getBarcode( self.options.type, { + bargen = getBarcode( self.options.type, { 'text' : self.options.text, 'height' : self.options.height, 'document' : self.document, 'x' : x, 'y' : y, } ) - if object is not None: - barcode = object.generate() + if bargen is not None: + barcode = bargen.generate() if barcode is not None: self.current_layer.append(barcode) else: diff --git a/share/extensions/render_barcode_datamatrix.inx b/share/extensions/render_barcode_datamatrix.inx index 58699e4a9..ede179e24 100644 --- a/share/extensions/render_barcode_datamatrix.inx +++ b/share/extensions/render_barcode_datamatrix.inx @@ -5,8 +5,38 @@ <dependency type="executable" location="extensions">render_barcode_datamatrix.py</dependency> <dependency type="executable" location="extensions">inkex.py</dependency> <param name="text" type="string" _gui-text="Text:">Inkscape</param> - <param name="rows" type="int" min="8" max="144" _gui-text="Rows:">10</param> - <param name="cols" type="int" min="10" max="144" _gui-text="Cols:">10</param> + <param name="symbol" _gui-text="Size, in unit squares:" type="enum"> + <item value="sq10">10x10</item> + <item value="sq12">12x12</item> + <item value="sq14">14x14</item> + <item value="sq16">16x16</item> + <item value="sq18">18x18</item> + <item value="sq20">20x20</item> + <item value="sq22">22x22</item> + <item value="sq24">24x24</item> + <item value="sq26">26x26</item> + <item value="sq32">32x32</item> + <item value="sq36">36x36</item> + <item value="sq40">40x40</item> + <item value="sq44">44x44</item> + <item value="sq48">48x48</item> + <item value="sq52">52x52</item> + <item value="sq64">64x64</item> + <item value="sq72">72x72</item> + <item value="sq80">80x80</item> + <item value="sq88">88x88</item> + <item value="sq96">96x96</item> + <item value="sq104">104x104</item> + <item value="sq120">120x120</item> + <item value="sq132">132x132</item> + <item value="sq144">144x144</item> + <item value="rect8x18">8x18</item> + <item value="rect8x32">8x32</item> + <item value="rect12x26">12x26</item> + <item value="rect12x36">12x36</item> + <item value="rect16x36">16x36</item> + <item value="rect16x48">16x48</item> + </param> <param name="size" type="int" min="1" max="1000" _gui-text="Square Size (px):">4</param> <effect> <object-type>all</object-type> diff --git a/share/extensions/render_barcode_datamatrix.py b/share/extensions/render_barcode_datamatrix.py index 785d7de56..20bcf94dc 100644 --- a/share/extensions/render_barcode_datamatrix.py +++ b/share/extensions/render_barcode_datamatrix.py @@ -57,6 +57,39 @@ import inkex, simplestyle import gettext _ = gettext.gettext +symbols = { + 'sq10': (10, 10), + 'sq12': (12, 12), + 'sq14': (14, 14), + 'sq16': (16, 16), + 'sq18': (18, 18), + 'sq20': (20, 20), + 'sq22': (22, 22), + 'sq24': (24, 24), + 'sq26': (26, 26), + 'sq32': (32, 32), + 'sq36': (36, 36), + 'sq40': (40, 40), + 'sq44': (44, 44), + 'sq48': (48, 48), + 'sq52': (52, 52), + 'sq64': (64, 64), + 'sq72': (72, 72), + 'sq80': (80, 80), + 'sq88': (88, 88), + 'sq96': (96, 96), + 'sq104': (104, 104), + 'sq120': (120, 120), + 'sq132': (132, 132), + 'sq144': (144, 144), + 'rect8x18': (8, 18), + 'rect8x32': (8, 32), + 'rect12x26': (12, 26), + 'rect12x36': (12, 36), + 'rect16x36': (16, 36), + 'rect16x48': (16, 48), +} + #ENCODING ROUTINES =================================================== # Take an input string and convert it to a sequence (or sequences) # of codewords as specified in ISO/IEC 16022:2006 (section 5.2.3) @@ -167,6 +200,7 @@ def get_parameters(nrow, ncol): #RETURN ERROR else: inkex.errormsg(_('Unrecognised DataMatrix size')) + exit(0) return None @@ -616,6 +650,9 @@ class DataMatrix(inkex.Effect): self.OptionParser.add_option("--text", action="store", type="string", dest="TEXT", default='Inkscape') + self.OptionParser.add_option("--symbol", + action="store", type="string", + dest="SYMBOL", default='') self.OptionParser.add_option("--rows", action="store", type="int", dest="ROWS", default=10) @@ -630,6 +667,12 @@ class DataMatrix(inkex.Effect): so = self.options + rows = so.ROWS + cols = so.COLS + if (so.SYMBOL != '' and (so.SYMBOL in symbols)): + rows = symbols[so.SYMBOL][0] + cols = symbols[so.SYMBOL][1] + if so.TEXT == '': #abort if converting blank text inkex.errormsg(_('Please enter an input string')) else: @@ -644,8 +687,8 @@ class DataMatrix(inkex.Effect): grp = inkex.etree.SubElement(self.current_layer, 'g', grp_attribs)#the group to put everything in #GENERATE THE DATAMATRIX - encoded = encode( so.TEXT, (so.ROWS, so.COLS) ) #get the pattern of squares - render_data_matrix( encoded, so.SIZE, so.COLS*so.SIZE*1.5, grp ) # generate the SVG elements + encoded = encode( so.TEXT, (rows, cols) ) #get the pattern of squares + render_data_matrix( encoded, so.SIZE, cols*so.SIZE*1.5, grp ) # generate the SVG elements if __name__ == '__main__': e = DataMatrix() diff --git a/share/extensions/restack.py b/share/extensions/restack.py index 518c1b10e..615b41527 100644 --- a/share/extensions/restack.py +++ b/share/extensions/restack.py @@ -1,6 +1,6 @@ #!/usr/bin/env python """ -Copyright (C) 2007,2008 Rob Antonishen; rob.antonishen@gmail.com +Copyright (C) 2007-2011 Rob Antonishen; rob.antonishen@gmail.com Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal @@ -52,26 +52,34 @@ class Restack(inkex.Effect): if len( self.selected ) > 0: objlist = [] svg = self.document.getroot() - + parentnode = self.current_layer file = self.args[ -1 ] - #get all bounding boxes in file by calling inkscape again with the --querry-all command line option + + #get all bounding boxes in file by calling inkscape again with the --query-all command line option #it returns a comma seperated list structured id,x,y,w,h if bsubprocess: p = Popen('inkscape --query-all "%s"' % (file), shell=True, stdout=PIPE, stderr=PIPE) - rc = p.wait() - f = p.stdout err = p.stderr + f = p.communicate()[0] + try: + reader=csv.CSVParser().parse_string(f) #there was a module cvs.py in earlier inkscape that behaved differently + except: + reader=csv.reader(f.split( os.linesep )) + err.close() else: - _,f,err = os.popen3( "inkscape --query-all %s" % ( file ) ) - reader=csv.reader( f.readlines() ) - f.close() - err.close() - + _,f,err = os.popen3('inkscape --query-all "%s"' % ( file ) ) + reader=csv.reader( f ) + err.close() + #build a dictionary with id as the key dimen = dict() for line in reader: - dimen[line[0]] = map( float, line[1:]) + if len(line) > 0: + dimen[line[0]] = map( float, line[1:]) + if not bsubprocess: #close file if opened using os.popen3 + f.close + #find the center of all selected objects **Not the average! x,y,w,h = dimen[self.selected.keys()[0]] minx = x @@ -113,15 +121,15 @@ class Restack(inkex.Effect): cy = y + h else: # middle cy = y + h / 2 - + #direction chosen - if self.options.direction == "tb" or self.options.angle == 270: + if self.options.direction == "tb" or (self.options.direction == "aa" and self.options.angle == 270): objlist.append([cy,id]) - elif self.options.direction == "bt" or self.options.angle == 90: + elif self.options.direction == "bt" or (self.options.direction == "aa" and self.options.angle == 90): objlist.append([-cy,id]) - elif self.options.direction == "lr" or self.options.angle == 0 or self.options.angle == 360: + elif self.options.direction == "lr" or (self.options.direction == "aa" and (self.options.angle == 0 or self.options.angle == 360)): objlist.append([cx,id]) - elif self.options.direction == "rl" or self.options.angle == 180: + elif self.options.direction == "rl" or (self.options.direction == "aa" and self.options.angle == 180): objlist.append([-cx,id]) elif self.options.direction == "aa": distance = math.hypot(cx,cy)*(math.cos(math.radians(-self.options.angle)-math.atan2(cy, cx))) @@ -136,11 +144,11 @@ class Restack(inkex.Effect): objlist.sort() #move them to the top of the object stack in this order. for item in objlist: - svg.append( self.selected[item[1]]) + parentnode.append( self.selected[item[1]]) if __name__ == '__main__': e = Restack() e.affect() -# vim: expandtab shiftwidth=4 tabstop=8 softtabstop=4 fileencoding=utf-8 textwidth=99 +# vim: expandtab shiftwidth=4 tabstop=8 softtabstop=4 encoding=utf-8 textwidth=99 diff --git a/share/extensions/svg2fxg.inx b/share/extensions/svg2fxg.inx new file mode 100755 index 000000000..e2f9761fc --- /dev/null +++ b/share/extensions/svg2fxg.inx @@ -0,0 +1,14 @@ +<?xml version="1.0" encoding="UTF-8"?> +<inkscape-extension xmlns="http://www.inkscape.org/namespace/inkscape/extension"> + <_name>FXG Output</_name> + <id>org.inkscape.output.fxg</id> + <output> + <extension>.fxg</extension> + <mimetype>text/xml+fxg</mimetype> + <_filetypename>Flash XML Graphics (*.fxg)</_filetypename> + <_filetypetooltip>Adobe's XML Graphics file format</_filetypetooltip> + </output> + <xslt> + <file reldir="extensions">svg2fxg.xsl</file> + </xslt> +</inkscape-extension> diff --git a/share/extensions/svg2fxg.xsl b/share/extensions/svg2fxg.xsl new file mode 100755 index 000000000..4ccd62f27 --- /dev/null +++ b/share/extensions/svg2fxg.xsl @@ -0,0 +1,3008 @@ +<?xml version="1.0" encoding="UTF-8"?> + +<!-- +Authors: + Nicolas Dufour <nicoduf@yahoo.fr> + +Copyright (c) 2010 authors + +Released under GNU GPL, read the file 'COPYING' for more information +--> + +<xsl:stylesheet version="1.0" +xmlns:xsl="http://www.w3.org/1999/XSL/Transform" +xmlns:xlink="http://www.w3.org/1999/xlink" +xmlns:xs="http://www.w3.org/2001/XMLSchema" +xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" +xmlns="http://ns.adobe.com/fxg/2008" +xmlns:fxg="http://ns.adobe.com/fxg/2008" +xmlns:d="http://ns.adobe.com/fxg/2008/dt" +xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" +xmlns:exsl="http://exslt.org/common" +xmlns:math="http://exslt.org/math" +xmlns:libxslt="http://xmlsoft.org/XSLT/namespace" +xmlns:svg="http://www.w3.org/Graphics/SVG/1.1/DTD/svg11-tiny.dtd" +exclude-result-prefixes="rdf xlink xs exsl libxslt" +extension-element-prefixes="math"> + +<xsl:strip-space elements="*" /> +<xsl:output method="xml" encoding="UTF-8" indent="yes"/> + +<!-- + // Containers // + + * Root templace + * Graphic attributes + * Groups +--> + +<!-- + // Root template // +--> +<xsl:template match="/"> + <xsl:apply-templates mode="forward" /> +</xsl:template> +<!-- + // Graphic // + First SVG element is converted to Graphic +--> +<xsl:template mode="forward" match="/*[name(.) = 'svg']" priority="1"> + <Graphic> + <xsl:attribute name="version">2.0</xsl:attribute> + <xsl:if test="@width and not(contains(@width, '%'))"> + <xsl:attribute name="viewWidth"> + <xsl:call-template name="convert_unit"> + <xsl:with-param name="convert_value" select="@width" /> + </xsl:call-template> + </xsl:attribute> + </xsl:if> + <xsl:if test="@height and not(contains(@height, '%'))"> + <xsl:attribute name="viewHeight"> + <xsl:call-template name="convert_unit"> + <xsl:with-param name="convert_value" select="@height" /> + </xsl:call-template> + </xsl:attribute> + </xsl:if> + <xsl:if test="@width and not(contains(@width, '%')) and @height and not(contains(@height, '%'))"> + <mask> + <Group> + <Rect> + <xsl:attribute name="width"> + <xsl:call-template name="convert_unit"> + <xsl:with-param name="convert_value" select="@width" /> + </xsl:call-template> + </xsl:attribute> + <xsl:attribute name="height"> + <xsl:call-template name="convert_unit"> + <xsl:with-param name="convert_value" select="@height" /> + </xsl:call-template> + </xsl:attribute> + <fill> + <SolidColor color="#ffffff" alpha="1"/> + </fill> + </Rect> + </Group> + </mask> + </xsl:if> + <xsl:apply-templates mode="forward" /> + </Graphic> +</xsl:template> + +<!-- + // inner SVG elements // + Converted to groups +--> +<xsl:template mode="forward" match="*[name(.) = 'svg']"> + <Group> + <xsl:if test="@x"> + <xsl:attribute name="x"> + <xsl:call-template name="convert_unit"> + <xsl:with-param name="convert_value" select="@x" /> + </xsl:call-template> + </xsl:attribute> + </xsl:if> + <xsl:if test="@y"> + <xsl:attribute name="y"> + <xsl:call-template name="convert_unit"> + <xsl:with-param name="convert_value" select="@y" /> + </xsl:call-template> + </xsl:attribute> + </xsl:if> + <xsl:if test="@width and not(contains(@width, '%')) and @height and not(contains(@height, '%'))"> + <xsl:attribute name="maskType"><xsl:value-of select="'clip'"/></xsl:attribute> + <mask> + <Group> + <Rect> + <xsl:attribute name="width"> + <xsl:call-template name="convert_unit"> + <xsl:with-param name="convert_value" select="@width" /> + </xsl:call-template> + </xsl:attribute> + <xsl:attribute name="height"> + <xsl:call-template name="convert_unit"> + <xsl:with-param name="convert_value" select="@height" /> + </xsl:call-template> + </xsl:attribute> + <fill> + <SolidColor color="#ffffff" alpha="1"/> + </fill> + </Rect> + </Group> + </mask> + </xsl:if> + <xsl:apply-templates mode="forward" /> + </Group> +</xsl:template> + +<!-- + // Groups // + (including layers) + + FXG's Group doesn't support other elements attributes (such as font-size, etc.) +--> +<xsl:template mode="forward" match="*[name(.) = 'g']"> + <xsl:variable name="object"> + <Group> + <xsl:if test="@style and contains(@style, 'display:none')"> + <xsl:attribute name="Visibility">Collapsed</xsl:attribute> + </xsl:if> + <xsl:if test="@width and not(contains(@width, '%'))"> + <xsl:attribute name="width"> + <xsl:call-template name="convert_unit"> + <xsl:with-param name="convert_value" select="@width" /> + </xsl:call-template> + </xsl:attribute> + </xsl:if> + <xsl:if test="@height and not(contains(@height, '%'))"> + <xsl:attribute name="height"> + <xsl:call-template name="convert_unit"> + <xsl:with-param name="convert_value" select="@height" /> + </xsl:call-template> + </xsl:attribute> + </xsl:if> + <xsl:if test="@x"> + <xsl:attribute name="x"> + <xsl:call-template name="convert_unit"> + <xsl:with-param name="convert_value" select="@x" /> + </xsl:call-template> + </xsl:attribute> + </xsl:if> + <xsl:if test="@y"> + <xsl:attribute name="y"> + <xsl:call-template name="convert_unit"> + <xsl:with-param name="convert_value" select="@y" /> + </xsl:call-template> + </xsl:attribute> + </xsl:if> + <xsl:apply-templates mode="object_opacity" select="." /> + <xsl:apply-templates mode="id" select="." /> + + <xsl:apply-templates mode="layer_blend" select="." /> + <xsl:apply-templates mode="filter_effect" select="." /> + <xsl:apply-templates mode="forward" select="*" /> + </Group> + </xsl:variable> + + <xsl:variable name="clipped_object"> + <xsl:apply-templates mode="clip" select="." > + <xsl:with-param name="object" select="$object" /> + <xsl:with-param name="clip_type" select="'clip'" /> + </xsl:apply-templates> + </xsl:variable> + + <xsl:variable name="masked_object"> + <xsl:apply-templates mode="clip" select="." > + <xsl:with-param name="object" select="$clipped_object" /> + <xsl:with-param name="clip_type" select="'mask'" /> + </xsl:apply-templates> + </xsl:variable> + + <xsl:choose> + <xsl:when test="@transform"> + <Group> + <xsl:call-template name="object_transform"> + <xsl:with-param name="object" select="$masked_object" /> + <xsl:with-param name="transform" select="@transform" /> + </xsl:call-template> + </Group> + </xsl:when> + <xsl:otherwise> + <xsl:copy-of select="$masked_object" /> + </xsl:otherwise> + </xsl:choose> +</xsl:template> + +<!-- + // Transforms // + All the matrix, translate, rotate... stuff. + * Parse objects transform + * Object transform + * Parse gradient transform + * Gradient transform + + Not supported by FXG: + * Skew transform. + * Multiple values rotation. +--> + +<!-- + // Parse object transform // +--> +<xsl:template name="parse_object_transform"> + <xsl:param name="input" /> + <xsl:choose> + <!-- Matrix transform --> + <xsl:when test="starts-with($input, 'matrix(')"> + <transform> + <Transform> + <matrix> + <Matrix> + <xsl:variable name="matrix" select="normalize-space(translate(substring-before(substring-after($input, 'matrix('), ')'), ',', ' '))" /> + <xsl:variable name="a" select="substring-before($matrix, ' ')"/> + <xsl:variable name="ra" select="substring-after($matrix, ' ')"/> + <xsl:variable name="b" select="substring-before($ra, ' ')"/> + <xsl:variable name="rb" select="substring-after($ra, ' ')"/> + <xsl:variable name="c" select="substring-before($rb, ' ')"/> + <xsl:variable name="rc" select="substring-after($rb, ' ')"/> + <xsl:variable name="d" select="substring-before($rc, ' ')"/> + <xsl:variable name="rd" select="substring-after($rc, ' ')"/> + <xsl:variable name="tx" select="substring-before($rd, ' ')"/> + <xsl:variable name="ty" select="substring-after($rd, ' ')"/> + <xsl:attribute name="a"><xsl:value-of select="$a" /></xsl:attribute> + <xsl:attribute name="b"><xsl:value-of select="$b" /></xsl:attribute> + <xsl:attribute name="c"><xsl:value-of select="$c" /></xsl:attribute> + <xsl:attribute name="d"><xsl:value-of select="$d" /></xsl:attribute> + <xsl:attribute name="tx"><xsl:value-of select='format-number($tx, "#.##")' /></xsl:attribute> + <xsl:attribute name="ty"><xsl:value-of select='format-number($ty, "#.##")' /></xsl:attribute> + </Matrix> + </matrix> + </Transform> + </transform> + </xsl:when> + + <!-- Scale transform --> + <xsl:when test="starts-with($input, 'scale(')"> + <xsl:variable name="scale" select="normalize-space(translate(substring-before(substring-after($input, 'scale('), ')'), ',', ' '))" /> + <xsl:choose> + <xsl:when test="contains($scale, ' ')"> + <xsl:attribute name="scaleX"> + <xsl:value-of select="substring-before($scale, ' ')" /> + </xsl:attribute> + <xsl:attribute name="scaleY"> + <xsl:value-of select="substring-after($scale, ' ')" /> + </xsl:attribute> + </xsl:when> + <xsl:otherwise> + <xsl:attribute name="scaleX"> + <xsl:value-of select="$scale" /> + </xsl:attribute> + <xsl:attribute name="scaleY"> + <xsl:value-of select="$scale" /> + </xsl:attribute> + </xsl:otherwise> + </xsl:choose> + </xsl:when> + + <!-- Rotate transform --> + <xsl:when test="starts-with($input, 'rotate(')"> + <xsl:variable name="rotate" select="normalize-space(translate(substring-before(substring-after($input, 'rotate('), ')'), ',', ' '))" /> + <xsl:attribute name="rotation"> + <xsl:choose> + <xsl:when test="contains($rotate, ' ')"> + <xsl:value-of select="substring-before($rotate, ' ')" /> + </xsl:when> + <xsl:otherwise> + <xsl:value-of select="$rotate" /> + </xsl:otherwise> + </xsl:choose> + </xsl:attribute> + <xsl:if test="@rx"> + <xsl:attribute name="CenterX"> + <xsl:value-of select="@rx" /> + </xsl:attribute> + </xsl:if> + <xsl:if test="@ry"> + <xsl:attribute name="CenterY"> + <xsl:value-of select="@ry" /> + </xsl:attribute> + </xsl:if> + </xsl:when> + + <!-- Translate transform --> + <xsl:when test="starts-with($input, 'translate(')"> + <xsl:variable name="translate" select="normalize-space(translate(substring-before(substring-after($input, 'translate('), ')'), ',', ' '))" /> + <xsl:choose> + <xsl:when test="contains($translate, ' ')"> + <xsl:attribute name="x"> + <xsl:value-of select="substring-before($translate, ' ')" /> + </xsl:attribute> + <xsl:attribute name="y"> + <xsl:value-of select="substring-after($translate, ' ')" /> + </xsl:attribute> + </xsl:when> + <xsl:otherwise> + <xsl:attribute name="x"> + <xsl:value-of select="$translate" /> + </xsl:attribute> + </xsl:otherwise> + </xsl:choose> + </xsl:when> + </xsl:choose> +</xsl:template> + +<!-- + // Object transform // + FXG needs a separate group for each transform type in the transform attribute (scale+translate != translate+scale) +--> +<xsl:template name="object_transform"> + <xsl:param name="object" /> + <xsl:param name="transform" /> + + <xsl:variable name="values" select="normalize-space(translate($transform, ',', ' '))" /> + <xsl:choose> + <xsl:when test="contains($values, ') ')"> + <xsl:call-template name="parse_object_transform"> + <xsl:with-param name="input" select="concat(substring-before($values, ') '), ')')" /> + </xsl:call-template> + <xsl:variable name="values2" select="substring-after($values, ') ')" /> + <Group> + <xsl:choose> + <xsl:when test="contains($values2, ') ')"> + <xsl:call-template name="parse_object_transform"> + <xsl:with-param name="input" select="concat(substring-before($values2, ') '), ')')" /> + </xsl:call-template> + <xsl:variable name="values3" select="substring-after($values2, ') ')" /> + <Group> + <xsl:call-template name="parse_object_transform"> + <xsl:with-param name="input" select="concat($values3, ')')" /> + </xsl:call-template> + <xsl:copy-of select="$object" /> + </Group> + </xsl:when> + <xsl:otherwise> + <xsl:call-template name="parse_object_transform"> + <xsl:with-param name="input" select="$values2" /> + </xsl:call-template> + <xsl:copy-of select="$object" /> + </xsl:otherwise> + </xsl:choose> + </Group> + </xsl:when> + <xsl:otherwise> + <xsl:call-template name="parse_object_transform"> + <xsl:with-param name="input" select="$values" /> + </xsl:call-template> + <xsl:copy-of select="$object" /> + </xsl:otherwise> + </xsl:choose> +</xsl:template> + +<!-- + // Parse gradient transform // +--> +<xsl:template name="parse_gradient_transform"> + <xsl:param name="input" /> + <xsl:param name="type" /> + <xsl:choose> + <!-- Scale transform --> + <xsl:when test="starts-with($input, 'scale(')"> + <xsl:variable name="scale" select="normalize-space(translate(substring-before(substring-after($input, 'scale('), ')'), ',', ' '))" /> + <xsl:choose> + <xsl:when test="$type='radial'"> + <xsl:choose> + <xsl:when test="contains($scale, ' ')"> + <xsl:attribute name="scaleX"> + <xsl:value-of select="substring-before($scale, ' ')" /> + </xsl:attribute> + <xsl:attribute name="scaleY"> + <xsl:value-of select="substring-after($scale, ' ')" /> + </xsl:attribute> + </xsl:when> + <xsl:otherwise> + <xsl:attribute name="scaleX"> + <xsl:value-of select="$scale" /> + </xsl:attribute> + <xsl:attribute name="scaleY"> + <xsl:value-of select="$scale" /> + </xsl:attribute> + </xsl:otherwise> + </xsl:choose> + </xsl:when> + <xsl:otherwise> + <xsl:attribute name="scaleX"> + <xsl:value-of select="$scale" /> + </xsl:attribute> + </xsl:otherwise> + </xsl:choose> + </xsl:when> + + <!-- Rotate transform --> + <xsl:when test="starts-with($input, 'rotate(')"> + <xsl:variable name="rotate" select="normalize-space(translate(substring-before(substring-after($input, 'rotate('), ')'), ',', ' '))" /> + <xsl:attribute name="rotation"> + <xsl:choose> + <xsl:when test="contains($rotate, ' ')"> + <xsl:value-of select="substring-before($rotate, ' ')" /> + </xsl:when> + <xsl:otherwise> + <xsl:value-of select="$rotate" /> + </xsl:otherwise> + </xsl:choose> + </xsl:attribute> + </xsl:when> + + <!-- Translate transform --> + <xsl:when test="starts-with($input, 'translate(')"> + <xsl:variable name="translate" select="normalize-space(translate(substring-before(substring-after($input, 'translate('), ')'), ',', ' '))" /> + <xsl:choose> + <xsl:when test="contains($translate, ' ')"> + <xsl:attribute name="x"> + <xsl:value-of select="substring-before($translate, ' ')" /> + </xsl:attribute> + <xsl:attribute name="y"> + <xsl:value-of select="substring-after($translate, ' ')" /> + </xsl:attribute> + </xsl:when> + <xsl:otherwise> + <xsl:attribute name="x"> + <xsl:value-of select="$translate" /> + </xsl:attribute> + </xsl:otherwise> + </xsl:choose> + </xsl:when> + </xsl:choose> +</xsl:template> + +<!-- + // Gradient transform // + Not implemented yet + Gradient positioning and tranformation are very different in FXG +--> +<xsl:template name="gradient_transform"> + <xsl:param name="transform" /> + <xsl:param name="type" /> + + <xsl:if test="contains($transform, 'translate')"> + <xsl:call-template name="parse_gradient_transform"> + <xsl:with-param name="input" select="concat('translate(', substring-before(substring-after($transform, 'translate('), ')'), ')')" /> + <xsl:with-param name="type" select="$type" /> + </xsl:call-template> + </xsl:if> +</xsl:template> + +<!-- + // Resources (defs) // + + * Resources ids + * Generic defs template + * Defs gradients + * Layers blend mode + * Generic filters template + * Filter effects + * Linked filter effects + * Linear gradients + * Radial gradients + * Gradient stops list + * Gradient stop + * Clipping +--> + +<!-- + // Resources ids // +--> +<xsl:template mode="resources" match="*"> + <!-- should be in-depth --> + <xsl:if test="ancestor::*[name(.) = 'defs']"><xsl:attribute name="id"><xsl:value-of select="@id" /></xsl:attribute></xsl:if> +</xsl:template> + +<!-- + // Generic defs template // +--> +<xsl:template mode="forward" match="defs"> +<!-- Ignoring defs, do nothing + <xsl:apply-templates mode="forward" /> +--> +</xsl:template> + +<!-- + // Defs gradients // + ignored +--> +<xsl:template mode="forward" match="*[name(.) = 'linearGradient' or name(.) = 'radialGradient']"> + +</xsl:template> + +<!-- + // Layers blend mode // + + Partial support + Looks good with normal, multiply, and darken +--> +<xsl:template mode="layer_blend" match="*"> + <xsl:if test="@inkscape:groupmode='layer' and @style and contains(@style, 'filter:url(#')"> + <xsl:variable name="id" select="substring-before(substring-after(@style, 'filter:url(#'), ')')" /> + <xsl:for-each select="//*[@id=$id]"> + <xsl:if test="name(child::node()) = 'feBlend'"> + <xsl:attribute name="blendMode"> + <xsl:value-of select="child::node()/@mode"/> + </xsl:attribute> + </xsl:if> + </xsl:for-each> + </xsl:if> +</xsl:template> + +<!-- + // Generic filters template // + Limited to one filter (can be improved) +--> +<xsl:template mode="forward" match="*[name(.) = 'filter']"> + <xsl:if test="count(*) = 1"> + <xsl:apply-templates mode="forward" /> + </xsl:if> +</xsl:template> + +<!-- + // GaussianBlur filter effects // + Blur values approximated with d = floor(s * 3*sqrt(2*pi)/4 + 0.5) from: + http://www.w3.org/TR/SVG/filters.html#feGaussianBlurElement + Blur quality=2 recommended by the FXG specifications: + http://opensource.adobe.com/wiki/display/flexsdk/FXG+2.0+Specification#FXG2.0Specification-FilterEffects +--> +<xsl:template mode="forward" match="*[name(.) = 'feGaussianBlur']"> + <xsl:if test="name(.)='feGaussianBlur'"> + <filters> + <BlurFilter> + <xsl:attribute name="quality">2</xsl:attribute> + <xsl:if test="@stdDeviation"> + <xsl:variable name="blur" select="normalize-space(translate(@stdDeviation, ',', ' '))" /> + <xsl:choose> + <xsl:when test="not(contains($blur, ' '))"> + <xsl:attribute name="blurX"> + <xsl:value-of select="floor($blur * 1.88 + 0.5)" /> + </xsl:attribute> + <xsl:attribute name="blurY"> + <xsl:value-of select="floor($blur * 1.88 + 0.5)" /> + </xsl:attribute> + </xsl:when> + <xsl:otherwise> + <xsl:attribute name="blurX"> + <xsl:value-of select="floor(substring-before($blur, ' ') * 1.88 + 0.5)" /> + </xsl:attribute> + <xsl:attribute name="blurY"> + <xsl:value-of select="floor(substring-after($blur, ' ') * 1.88 + 0.5)" /> + </xsl:attribute> + </xsl:otherwise> + </xsl:choose> + </xsl:if> + </BlurFilter> + </filters> + </xsl:if> +</xsl:template> + +<!-- + // Linked filter effect // + Only supports blurs +--> +<xsl:template mode="filter_effect" match="*"> + <xsl:variable name="id"> + <xsl:choose> + <xsl:when test="@filter and starts-with(@filter, 'url(#')"> + <xsl:value-of select="substring-before(substring-after(@filter, 'url(#'), ')')" /> + </xsl:when> + <xsl:when test="@style and contains(@style, 'filter:url(#')"> + <xsl:value-of select="substring-before(substring-after(@style, 'filter:url(#'), ')')" /> + </xsl:when> + </xsl:choose> + </xsl:variable> + + <xsl:for-each select="//*[@id=$id]"> + <xsl:apply-templates mode="forward" /> + </xsl:for-each> +</xsl:template> + +<!-- + // Linear gradient // + Full convertion to FXG would require some math. +--> +<xsl:template name="linearGradient"> + <xsl:param name="id" /> + <xsl:for-each select="//*[@id=$id]"> + <xsl:if test="@id"> + <xsl:attribute name="id"> + <xsl:value-of select="@id" /> + </xsl:attribute> + </xsl:if> + <xsl:if test="@spreadMethod"> + <xsl:attribute name="spreadMethod"> + <xsl:choose> + <xsl:when test="@spreadMethod = 'pad'">pad</xsl:when> + <xsl:when test="@spreadMethod = 'reflect'">reflect</xsl:when> + <xsl:when test="@spreadMethod = 'repeat'">repeat</xsl:when> + </xsl:choose> + </xsl:attribute> + </xsl:if> + <xsl:if test="@color-interpolation"> + <xsl:attribute name="interpolationMethod"> + <xsl:choose> + <xsl:when test="@color-interpolation = 'linearRGB'">linearRGB</xsl:when> + <xsl:otherwise>rgb</xsl:otherwise> + </xsl:choose> + </xsl:attribute> + </xsl:if> + <xsl:if test="@x1 and @x2 and @y1 and @y2 and function-available('math:atan')"> + <xsl:attribute name="rotation"> + <xsl:value-of select="57.3 * math:atan((@y2 - @y1) div (@x2 - @x1))" /> + </xsl:attribute> + </xsl:if> + <xsl:if test="@gradientTransform"> + <xsl:call-template name="gradient_transform"> + <xsl:with-param name="transform" select="@gradientTransform" /> + <xsl:with-param name="type" select="linear" /> + </xsl:call-template> + </xsl:if> + <xsl:choose> + <xsl:when test="@xlink:href"> + <xsl:variable name="reference_id" select="@xlink:href" /> + <xsl:call-template name="gradientStops" > + <xsl:with-param name="id"> + <xsl:value-of select="substring-after($reference_id, '#')" /> + </xsl:with-param> + </xsl:call-template> + </xsl:when> + <xsl:otherwise><xsl:apply-templates mode="forward" /></xsl:otherwise> + </xsl:choose> + </xsl:for-each> +</xsl:template> + +<!-- + // Radial gradient // + + Full convertion to FXG would require some math. +--> +<xsl:template name="radialGradient"> + <xsl:param name="id" /> + <xsl:for-each select="//*[@id=$id]"> + <xsl:if test="@id"> + <xsl:attribute name="id"> + <xsl:value-of select="@id" /> + </xsl:attribute> + </xsl:if> + <xsl:if test="@spreadMethod"> + <xsl:attribute name="spreadMethod"> + <xsl:choose> + <xsl:when test="@spreadMethod = 'pad'">pad</xsl:when> + <xsl:when test="@spreadMethod = 'reflect'">reflect</xsl:when> + <xsl:when test="@spreadMethod = 'repeat'">repeat</xsl:when> + </xsl:choose> + </xsl:attribute> + </xsl:if> + <xsl:if test="@color-interpolation"> + <xsl:attribute name="interpolationMethod"> + <xsl:choose> + <xsl:when test="@color-interpolation = 'linearRGB'">linearRGB</xsl:when> + <xsl:otherwise>rgb</xsl:otherwise> + </xsl:choose> + </xsl:attribute> + </xsl:if> + <xsl:if test="@gradientTransform"> + <xsl:call-template name="gradient_transform"> + <xsl:with-param name="transform" select="@gradientTransform" /> + <xsl:with-param name="type" select="radial" /> + </xsl:call-template> + </xsl:if> + <xsl:choose> + <xsl:when test="@xlink:href"> + <xsl:variable name="reference_id" select="@xlink:href" /> + <xsl:call-template name="gradientStops" > + <xsl:with-param name="id"> + <xsl:value-of select="substring-after($reference_id, '#')" /> + </xsl:with-param> + </xsl:call-template> + </xsl:when> + <xsl:otherwise><xsl:apply-templates mode="forward" /></xsl:otherwise> + </xsl:choose> + </xsl:for-each> +</xsl:template> + +<!-- + // Gradient stops list // + + TODO: Find a way to test the existence of the node-set +--> +<xsl:template name="gradientStops"> + <xsl:param name="id" /> + <xsl:variable name="stops"> + <xsl:for-each select="//*[@id=$id]"> + <xsl:apply-templates mode="forward" /> + </xsl:for-each> + </xsl:variable> + <xsl:choose> + <xsl:when test="not($stops)"> + <GradientEntry> + <xsl:attribute name="alpha">0</xsl:attribute> + </GradientEntry> + </xsl:when> + <xsl:otherwise><xsl:copy-of select="$stops" /></xsl:otherwise> + </xsl:choose> +</xsl:template> + +<!-- + // Gradient stop // +--> +<xsl:template mode="forward" match="*[name(.) = 'stop']"> + <GradientEntry> + <!--xsl:apply-templates mode="stop_opacity" select="." /--> + <xsl:apply-templates mode="stop_color" select="." /> + <xsl:apply-templates mode="offset" select="." /> + <xsl:apply-templates mode="forward" /> + </GradientEntry> +</xsl:template> + +<!-- + // Clipping and masking// +--> +<xsl:template mode="clip" match="*"> + <xsl:param name="object" /> + <xsl:param name="clip_type" /> + + <xsl:choose> + <xsl:when test="$clip_type='clip' and @clip-path and contains(@clip-path, 'url')"> + <Group> + <xsl:attribute name="maskType"><xsl:value-of select="'clip'"/></xsl:attribute> + <mask> + <Group> + <xsl:variable name="clip_id" select="substring-before(substring-after(@clip-path, 'url(#'), ')')"/> + <xsl:for-each select="//*[@id=$clip_id]"> + <xsl:if test="not(@clipPathUnits) or @clipPathUnits != 'objectBoundingBox'"> + <xsl:apply-templates mode="forward" /> + </xsl:if> + </xsl:for-each> + </Group> + </mask> + <xsl:copy-of select="$object"/> + </Group> + </xsl:when> + <xsl:when test="$clip_type='mask' and @mask and contains(@mask, 'url')"> + <Group> + <xsl:attribute name="maskType"><xsl:value-of select="'alpha'"/></xsl:attribute> + <mask> + <Group> + <xsl:variable name="mask_id" select="substring-before(substring-after(@mask, 'url(#'), ')')"/> + <xsl:for-each select="//*[@id=$mask_id]"> + <xsl:if test="not(@maskUnits) or @maskUnits != 'objectBoundingBox'"> + <xsl:apply-templates mode="forward" /> + </xsl:if> + </xsl:for-each> + </Group> + </mask> + <xsl:copy-of select="$object"/> + </Group> + </xsl:when> + <xsl:otherwise> + <xsl:copy-of select="$object" /> + </xsl:otherwise> + </xsl:choose> +</xsl:template> + +<!-- + // Misc templates // + + * Id converter + * Decimal to hexadecimal converter + * Unit to pixel converter + * Switch + * Unknows tags + * Object description (not supported) + * Title and description (not supported) + * Symbols (not supported) + * Use (not supported) + * RDF and foreign objects (not supported) + * Misc ignored stuff (markers, patterns, styles) +--> + +<!-- + // Id converter // + Removes "-" from the original id + (Not sure FXG really needs it) +--> +<xsl:template mode="id" match="*"> + <xsl:if test="@id"> + <xsl:attribute name="id"><xsl:value-of select="translate(@id, '- ', '')" /></xsl:attribute> + </xsl:if> +</xsl:template> + +<!-- + // Decimal to hexadecimal converter // +--> +<xsl:template name="to_hex"> + <xsl:param name="convert" /> + <xsl:value-of select="concat(substring('0123456789ABCDEF', 1 + floor(round($convert) div 16), 1), substring('0123456789ABCDEF', 1 + round($convert) mod 16, 1))" /> +</xsl:template> + +<!-- + // Unit to pixel converter // + Values with units (except %) are converted to pixels and rounded. + Unknown units are kept. + em, ex and % not implemented +--> +<xsl:template name="convert_unit"> + <xsl:param name="convert_value" /> + <xsl:choose> + <xsl:when test="contains($convert_value, 'px')"> + <xsl:value-of select="round(translate($convert_value, 'px', ''))" /> + </xsl:when> + <xsl:when test="contains($convert_value, 'pt')"> + <xsl:value-of select="round(translate($convert_value, 'pt', '') * 1.25)" /> + </xsl:when> + <xsl:when test="contains($convert_value, 'pc')"> + <xsl:value-of select="round(translate($convert_value, 'pc', '') * 15)" /> + </xsl:when> + <xsl:when test="contains($convert_value, 'mm')"> + <xsl:value-of select="round(translate($convert_value, 'mm', '') * 3.543307)" /> + </xsl:when> + <xsl:when test="contains($convert_value, 'cm')"> + <xsl:value-of select="round(translate($convert_value, 'cm', '') * 35.43307)" /> + </xsl:when> + <xsl:when test="contains($convert_value, 'in')"> + <xsl:value-of select="round(translate($convert_value, 'in', '') * 90)" /> + </xsl:when> + <xsl:when test="contains($convert_value, 'ft')"> + <xsl:value-of select="round(translate($convert_value, 'ft', '') * 1080)" /> + </xsl:when> + <xsl:when test="not(string(number($convert_value))='NaN')"> + <xsl:value-of select="round($convert_value)" /> + </xsl:when> + <xsl:otherwise> + <xsl:value-of select="$convert_value" /> + </xsl:otherwise> + </xsl:choose> +</xsl:template> + +<!-- + // Switch // +--> +<xsl:template mode="forward" match="*[name(.) = 'switch']"> + <xsl:apply-templates mode="forward" /> +</xsl:template> + +<!-- + // Unknown tags // + With generic and mode="forward" templates +--> +<xsl:template match="*"> + <xsl:comment><xsl:value-of select="concat('Unknown tag: ', name(.))" /></xsl:comment> +</xsl:template> + +<xsl:template mode="forward" match="*"> + <xsl:comment><xsl:value-of select="concat('Unknown tag: ', name(.))" /></xsl:comment> +</xsl:template> + +<!-- + // Object description // +--> +<xsl:template mode="desc" match="*"> + +</xsl:template> + +<!-- + // Title and description // + Title is ignored and desc is converted to Tag in the mode="desc" template +--> +<xsl:template mode="forward" match="*[name(.) = 'title' or name(.) = 'desc']"> + +</xsl:template> + +<!-- + // Symbols // +--> +<xsl:template mode="forward" match="*[name(.) = 'symbol']"> + +</xsl:template> + +<!-- + // Use // + Could be implemented via librairies + (but since it is not supported by Inkscape, not implemented yet) +--> +<xsl:template mode="forward" match="*[name(.) = 'use']"> + +</xsl:template> + +<!-- + // RDF and foreign objects // +--> +<xsl:template mode="forward" match="rdf:RDF | *[name(.) = 'foreignObject']"> + +</xsl:template> + +<!-- + // Misc ignored stuff (markers, patterns, styles) // +--> +<xsl:template mode="forward" match="*[name(.) = 'marker' or name(.) = 'pattern' or name(.) = 'style']"> + +</xsl:template> + +<!-- + // Colors and patterns // + + * Generic color template + * Object opacity + * Fill + * Fill opacity + * Fill rule + * Generic fill template + * Stroke + * Stroke opacity + * Generic stroke template + * Stroke width + * Stroke mitterlimit + * Stroke dasharray (not supported in FXG) + * Stroke dashoffset (not supported in FXG) + * Linejoin SVG to FxG converter + * Stroke linejoin + * Linecap SVG to FXG converter + * Stroke linecap + * Gradient stop + * Gradient stop opacity + * Gradient stop offset +--> + +<!-- + // Generic color template // +--> +<xsl:template name="template_color"> + <xsl:param name="colorspec" /> + <xsl:choose> + <xsl:when test="starts-with($colorspec, 'rgb(') and not(contains($colorspec , '%'))"> + <xsl:value-of select="'#'" /> + <xsl:call-template name="to_hex"> + <xsl:with-param name="convert"> + <xsl:value-of select="substring-before(substring-after($colorspec, 'rgb('), ',')" /> + </xsl:with-param> + </xsl:call-template> + <xsl:call-template name="to_hex"> + <xsl:with-param name="convert"> + <xsl:value-of select="substring-before(substring-after(substring-after($colorspec, 'rgb('), ','), ',')" /> + </xsl:with-param> + </xsl:call-template> + <xsl:call-template name="to_hex"> + <xsl:with-param name="convert"> + <xsl:value-of select="substring-before(substring-after(substring-after(substring-after($colorspec, 'rgb('), ','), ','), ')')" /> + </xsl:with-param> + </xsl:call-template> + </xsl:when> + <xsl:when test="starts-with($colorspec, 'rgb(') and contains($colorspec , '%')"> + <xsl:value-of select="'#'" /> + <xsl:call-template name="to_hex"> + <xsl:with-param name="convert"> + <xsl:value-of select="number(substring-before(substring-after($colorspec, 'rgb('), '%,')) * 255 div 100" /> + </xsl:with-param> + </xsl:call-template> + <xsl:call-template name="to_hex"> + <xsl:with-param name="convert"> + <xsl:value-of select="number(substring-before(substring-after(substring-after($colorspec, 'rgb('), ','), '%,')) * 255 div 100" /> + </xsl:with-param> + </xsl:call-template> + <xsl:call-template name="to_hex"> + <xsl:with-param name="convert"> + <xsl:value-of select="number(substring-before(substring-after(substring-after(substring-after($colorspec, 'rgb('), ','), ','), '%)')) * 255 div 100" /> + </xsl:with-param> + </xsl:call-template> + </xsl:when> + <xsl:when test="starts-with($colorspec, '#')"> + <xsl:value-of select="'#'" /> + <xsl:choose> + <xsl:when test="string-length(substring-after($colorspec, '#')) = 3"> + <xsl:variable name="colorspec3"> + <xsl:value-of select="translate(substring-after($colorspec, '#'), 'abcdefgh', 'ABCDEFGH')" /> + </xsl:variable> + <xsl:value-of select="concat(substring($colorspec3, 1, 1), substring($colorspec3, 1, 1))" /> + <xsl:value-of select="concat(substring($colorspec3, 2, 1), substring($colorspec3, 2, 1))" /> + <xsl:value-of select="concat(substring($colorspec3, 3, 1), substring($colorspec3, 3, 1))" /> + </xsl:when> + <xsl:otherwise> + <xsl:value-of select="translate(substring-after($colorspec, '#'), 'abcdefgh', 'ABCDEFGH')" /> + </xsl:otherwise> + </xsl:choose> + </xsl:when> + <xsl:otherwise> + <xsl:variable name="named_color_hex" select="document('colors.xml')/colors/color[@name = translate($colorspec, 'ABCDEFGHIJKLMNOPQRSTUVWXYZ', 'abcdefghijklmnopqrstuvwxyz')]/@hex" /> + <xsl:choose> + <xsl:when test="$named_color_hex and $named_color_hex != ''"> + <xsl:value-of select="'#'" /> + <xsl:value-of select="substring-after($named_color_hex, '#')" /> + </xsl:when> + <xsl:otherwise> + <xsl:value-of select="$colorspec" /> + </xsl:otherwise> + </xsl:choose> + </xsl:otherwise> + </xsl:choose> +</xsl:template> + +<!-- + // Object opacity // +--> +<xsl:template mode="object_opacity" match="*"> + <xsl:if test="@opacity or (@style and (contains(@style, ';opacity:') or starts-with(@style, 'opacity:')))"> + <xsl:variable name="value"> + <xsl:choose> + <xsl:when test="@opacity"> + <xsl:value-of select="@opacity" /> + </xsl:when> + <xsl:when test="@style and contains(@style, ';opacity:')"> + <xsl:variable name="Opacity" select="substring-after(@style, ';opacity:')" /> + <xsl:choose> + <xsl:when test="contains($Opacity, ';')"> + <xsl:value-of select="substring-before($Opacity, ';')" /> + </xsl:when> + <xsl:otherwise> + <xsl:value-of select="$Opacity" /> + </xsl:otherwise> + </xsl:choose> + </xsl:when> + <xsl:when test="@style and starts-with(@style, 'opacity:')"> + <xsl:variable name="Opacity" select="substring-after(@style, 'opacity:')" /> + <xsl:choose> + <xsl:when test="contains($Opacity, ';')"> + <xsl:value-of select="substring-before($Opacity, ';')" /> + </xsl:when> + <xsl:otherwise> + <xsl:value-of select="$Opacity" /> + </xsl:otherwise> + </xsl:choose> + </xsl:when> + <xsl:when test="name(..) = 'g' or name(..) = 'svg'"> + <xsl:apply-templates mode="object_opacity" select="parent::*" /> + </xsl:when> + <xsl:otherwise>1</xsl:otherwise> + </xsl:choose> + </xsl:variable> + <xsl:attribute name="alpha"> + <xsl:choose> + <xsl:when test="$value < 0">0</xsl:when> + <xsl:when test="$value > 1">1</xsl:when> + <xsl:otherwise> + <xsl:value-of select="$value" /> + </xsl:otherwise> + </xsl:choose> + </xsl:attribute> + </xsl:if> +</xsl:template> + +<!-- + // Fill // +--> +<xsl:template mode="fill" match="*"> + <xsl:variable name="value"> + <xsl:choose> + <xsl:when test="@fill"> + <xsl:value-of select="@fill" /> + </xsl:when> + <xsl:when test="@style and contains(@style, 'fill:')"> + <xsl:variable name="Fill" select="normalize-space(substring-after(@style, 'fill:'))" /> + <xsl:choose> + <xsl:when test="contains($Fill, ';')"> + <xsl:value-of select="substring-before($Fill, ';')" /> + </xsl:when> + <xsl:otherwise> + <xsl:value-of select="$Fill" /> + </xsl:otherwise> + </xsl:choose> + </xsl:when> + <xsl:when test="name(..) = 'g' or name(..) = 'svg'"> + <xsl:apply-templates mode="fill" select="parent::*"/> + </xsl:when> + </xsl:choose> + </xsl:variable> + <xsl:if test="$value"> + <!-- Removes unwanted characters in the color link (TODO: export to a specific template)--> + <xsl:value-of select="normalize-space(translate($value, '"', ''))" /> + </xsl:if> +</xsl:template> + +<!-- + // Fill opacity // +--> +<xsl:template mode="fill_opacity" match="*"> + <xsl:variable name="value"> + <xsl:choose> + <xsl:when test="@fill-opacity"> + <xsl:value-of select="@fill-opacity" /> + </xsl:when> + <xsl:when test="@style and contains(@style, 'fill-opacity:')"> + <xsl:variable name="Opacity" select="substring-after(@style, 'fill-opacity:')" /> + <xsl:choose> + <xsl:when test="contains($Opacity, ';')"> + <xsl:value-of select="substring-before($Opacity, ';')" /> + </xsl:when> + <xsl:otherwise> + <xsl:value-of select="$Opacity" /> + </xsl:otherwise> + </xsl:choose> + </xsl:when> + <xsl:when test="name(..) = 'g' or name(..) = 'svg'"> + <xsl:apply-templates mode="fill_opacity" select="parent::*" /> + </xsl:when> + <xsl:otherwise>1</xsl:otherwise> + </xsl:choose> + </xsl:variable> + <xsl:choose> + <xsl:when test="$value < 0">0</xsl:when> + <xsl:when test="$value > 1">1</xsl:when> + <xsl:otherwise> + <xsl:value-of select="$value" /> + </xsl:otherwise> + </xsl:choose> +</xsl:template> + +<!-- + // Fill rule // +--> +<xsl:template mode="fill_rule" match="*"> + <xsl:choose> + <xsl:when test="@fill-rule and (@fill-rule = 'nonzero' or @fill-rule = 'evenodd')"> + <xsl:if test="@fill-rule = 'nonzero'"> + <xsl:attribute name="winding">nonZero</xsl:attribute> + </xsl:if> + <xsl:if test="@fill-rule = 'evenodd'"> + <xsl:attribute name="winding">evenOdd</xsl:attribute> + </xsl:if> + </xsl:when> + <xsl:when test="@style and contains(@style, 'fill-rule:')"> + <xsl:variable name="FillRule" select="normalize-space(substring-after(@style, 'fill-rule:'))" /> + <xsl:choose> + <xsl:when test="contains($FillRule, ';')"> + <xsl:if test="substring-before($FillRule, ';') = 'nonzero'"> + <xsl:attribute name="winding">nonZero</xsl:attribute> + </xsl:if> + <xsl:if test="substring-before($FillRule, ';') = 'evenodd'"> + <xsl:attribute name="winding">evenOdd</xsl:attribute> + </xsl:if> + </xsl:when> + <xsl:when test="$FillRule = 'nonzero'"> + <xsl:attribute name="winding">nonZero</xsl:attribute> + </xsl:when> + <xsl:when test=" $FillRule = 'evenodd'"> + <xsl:attribute name="winding">evenOdd</xsl:attribute> + </xsl:when> + </xsl:choose> + </xsl:when> + <xsl:when test="name(..) = 'g' or name(..) = 'svg'"> + <xsl:apply-templates mode="fill_rule" select="parent::*"/> + </xsl:when> + <xsl:otherwise> + <xsl:attribute name="winding">nonZero</xsl:attribute> + </xsl:otherwise> + </xsl:choose> +</xsl:template> + +<!-- + // Generic fill template // +--> +<xsl:template mode="template_fill" match="*"> + <xsl:variable name="fill"><xsl:apply-templates mode="fill" select="." /></xsl:variable> + <xsl:variable name="fill_opacity"><xsl:apply-templates mode="fill_opacity" select="." /></xsl:variable> + + <xsl:choose> + <xsl:when test="$fill != '' and $fill != 'none' and not(starts-with($fill, 'url(#'))"> + <!-- Solid color --> + <fill> + <SolidColor> + <xsl:attribute name="color"> + <xsl:call-template name="template_color"> + <xsl:with-param name="colorspec"> + <xsl:value-of select="$fill" /> + </xsl:with-param> + </xsl:call-template> + </xsl:attribute> + <xsl:attribute name="alpha"> + <xsl:value-of select="$fill_opacity" /> + </xsl:attribute> + </SolidColor> + </fill> + </xsl:when> + <!-- Gradients --> + <xsl:when test="starts-with($fill, 'url(#')"> + <xsl:for-each select="//*[@id=substring-before(substring-after($fill, 'url(#'), ')')]"> + <xsl:if test="name(.) = 'linearGradient'"> + <fill> + <LinearGradient> + <xsl:call-template name="linearGradient" > + <xsl:with-param name="id"> + <xsl:value-of select="substring-before(substring-after($fill, 'url(#'), ')')" /> + </xsl:with-param> + </xsl:call-template> + </LinearGradient> + </fill> + </xsl:if> + <xsl:if test="name(.) = 'radialGradient'"> + <fill> + <RadialGradient> + <xsl:call-template name="radialGradient" > + <xsl:with-param name="id"> + <xsl:value-of select="substring-before(substring-after($fill, 'url(#'), ')')" /> + </xsl:with-param> + </xsl:call-template> + </RadialGradient> + </fill> + </xsl:if> + </xsl:for-each> + </xsl:when> + <xsl:when test="$fill = 'none'"> + </xsl:when> + <xsl:otherwise> + <fill> + <SolidColor color="#ffffff" alpha="1"/> + </fill> + </xsl:otherwise> + </xsl:choose> +</xsl:template> + +<!-- + // Stroke // +--> +<xsl:template mode="stroke" match="*"> + <xsl:choose> + <xsl:when test="@stroke"> + <xsl:value-of select="@stroke" /> + </xsl:when> + <xsl:when test="@style and contains(@style, 'stroke:')"> + <xsl:variable name="Stroke" select="normalize-space(substring-after(@style, 'stroke:'))" /> + <xsl:choose> + <xsl:when test="contains($Stroke, ';')"> + <xsl:value-of select="substring-before($Stroke, ';')" /> + </xsl:when> + <xsl:when test="$Stroke"> + <xsl:value-of select="$Stroke" /> + </xsl:when> + </xsl:choose> + </xsl:when> + <xsl:when test="name(..) = 'g' or name(..) = 'svg'"> + <xsl:apply-templates mode="stroke" select="parent::*"/> + </xsl:when> + </xsl:choose> +</xsl:template> + +<!-- + // Stroke opacity // +--> +<xsl:template mode="stroke_opacity" match="*"> + <xsl:variable name="value"> + <xsl:choose> + <xsl:when test="@stroke-opacity"><xsl:value-of select="@stroke-opacity" /></xsl:when> + <xsl:when test="@style and contains(@style, 'stroke-opacity:')"> + <xsl:variable name="Opacity" select="substring-after(@style, 'stroke-opacity:')" /> + <xsl:choose> + <xsl:when test="contains($Opacity, ';')"> + <xsl:value-of select="substring-before($Opacity, ';')" /> + </xsl:when> + <xsl:otherwise> + <xsl:value-of select="$Opacity" /> + </xsl:otherwise> + </xsl:choose> + </xsl:when> + <xsl:when test="name(..) = 'g' or name(..) = 'svg'"> + <xsl:apply-templates mode="stroke_opacity" select="parent::*" /> + </xsl:when> + <xsl:otherwise>1</xsl:otherwise> + </xsl:choose> + </xsl:variable> + <xsl:choose> + <xsl:when test="$value < 0">0</xsl:when> + <xsl:when test="$value > 1">1</xsl:when> + <xsl:otherwise> + <xsl:value-of select="$value" /> + </xsl:otherwise> + </xsl:choose> +</xsl:template> + +<!-- + // Generic stroke template // + + Not supported in FXG: + * stroke-dasharray + * stroke-dashoffset + + --> +<xsl:template mode="template_stroke" match="*"> + <xsl:variable name="stroke"><xsl:apply-templates mode="stroke" select="." /></xsl:variable> + <xsl:variable name="stroke_opacity"><xsl:apply-templates mode="stroke_opacity" select="." /></xsl:variable> + <xsl:variable name="stroke_width"><xsl:apply-templates mode="stroke_width" select="." /></xsl:variable> + <xsl:variable name="stroke_miterlimit"><xsl:apply-templates mode="stroke_miterlimit" select="." /></xsl:variable> + <xsl:variable name="stroke_linejoin"><xsl:apply-templates mode="stroke_linejoin" select="." /></xsl:variable> + <xsl:variable name="stroke_linecap"><xsl:apply-templates mode="stroke_linecap" select="." /></xsl:variable> + + <!-- Solid color --> + <xsl:if test="$stroke != '' and $stroke != 'none' and not(starts-with($stroke, 'url(#'))"> + <stroke> + <SolidColorStroke> + <xsl:attribute name="color"> + <xsl:call-template name="template_color"> + <xsl:with-param name="colorspec"> + <xsl:value-of select="$stroke" /> + </xsl:with-param> + </xsl:call-template> + </xsl:attribute> + <xsl:attribute name="alpha"> + <xsl:value-of select="$stroke_opacity" /> + </xsl:attribute> + <xsl:attribute name="weight"> + <xsl:value-of select="$stroke_width" /> + </xsl:attribute> + <xsl:if test="$stroke_miterlimit != ''"> + <xsl:attribute name="miterLimit"> + <xsl:value-of select="$stroke_miterlimit" /> + </xsl:attribute> + </xsl:if> + <xsl:attribute name="joints"> + <xsl:value-of select="$stroke_linejoin" /> + </xsl:attribute> + <xsl:attribute name="caps"> + <xsl:value-of select="$stroke_linecap" /> + </xsl:attribute> + </SolidColorStroke> + </stroke> + </xsl:if> + + <!-- Gradients --> + <xsl:if test="starts-with($stroke, 'url(#')"> + <xsl:for-each select="//*[@id=substring-before(substring-after($stroke, 'url(#'), ')')]"> + <xsl:if test="name(.) = 'linearGradient'"> + <stroke> + <LinearGradientStroke> + <xsl:attribute name="weight"> + <xsl:value-of select="$stroke_width" /> + </xsl:attribute> + <xsl:if test="$stroke_miterlimit != ''"> + <xsl:attribute name="miterLimit"> + <xsl:value-of select="$stroke_miterlimit" /> + </xsl:attribute> + </xsl:if> + <xsl:attribute name="joints"> + <xsl:value-of select="$stroke_linejoin" /> + </xsl:attribute> + <xsl:attribute name="caps"> + <xsl:value-of select="$stroke_linecap" /> + </xsl:attribute> + <xsl:call-template name="linearGradient" > + <xsl:with-param name="id"> + <xsl:value-of select="substring-before(substring-after($stroke, 'url(#'), ')')" /> + </xsl:with-param> + </xsl:call-template> + </LinearGradientStroke> + </stroke> + </xsl:if> + <xsl:if test="name(.) = 'radialGradient'"> + <stroke> + <RadialGradientStroke> + <xsl:attribute name="weight"> + <xsl:value-of select="$stroke_width" /> + </xsl:attribute> + <xsl:if test="$stroke_miterlimit != ''"> + <xsl:attribute name="miterLimit"> + <xsl:value-of select="$stroke_miterlimit" /> + </xsl:attribute> + </xsl:if> + <xsl:attribute name="joints"> + <xsl:value-of select="$stroke_linejoin" /> + </xsl:attribute> + <xsl:attribute name="caps"> + <xsl:value-of select="$stroke_linecap" /> + </xsl:attribute> + <xsl:call-template name="radialGradient" > + <xsl:with-param name="id"> + <xsl:value-of select="substring-before(substring-after($stroke, 'url(#'), ')')" /> + </xsl:with-param> + </xsl:call-template> + </RadialGradientStroke> + </stroke> + </xsl:if> + </xsl:for-each> + </xsl:if> +</xsl:template> + +<!-- + // Stroke width // +--> +<xsl:template mode="stroke_width" match="*"> + <xsl:choose> + <xsl:when test="@stroke-width"> + <xsl:call-template name="convert_unit"> + <xsl:with-param name="convert_value"> + <xsl:value-of select="@stroke-width" /> + </xsl:with-param> + </xsl:call-template> + </xsl:when> + <xsl:when test="@style and contains(@style, 'stroke-width:')"> + <xsl:call-template name="convert_unit"> + <xsl:with-param name="convert_value"> + <xsl:choose> + <xsl:when test="contains(substring-after(@style, 'stroke-width:'), ';')"> + <xsl:value-of select="substring-before(substring-after(@style, 'stroke-width:'), ';')" /> + </xsl:when> + <xsl:otherwise> + <xsl:value-of select="substring-after(@style, 'stroke-width:')" /> + </xsl:otherwise> + </xsl:choose> + </xsl:with-param> + </xsl:call-template> + </xsl:when> + <xsl:when test="name(..) = 'g' or name(..) = 'svg'"> + <xsl:apply-templates mode="stroke_width" select="parent::*"/> + </xsl:when> + <xsl:otherwise>1</xsl:otherwise> + </xsl:choose> +</xsl:template> + +<!-- + // Stroke miterlimit // + + Probably not calculated the same way in SVG and FXG (same value but different result) +--> +<xsl:template mode="stroke_miterlimit" match="*"> + <xsl:choose> + <xsl:when test="@stroke-miterlimit"> + <xsl:value-of select="@stroke-miterlimit" /> + </xsl:when> + <xsl:when test="@style and contains(@style, 'stroke-miterlimit:')"> + <xsl:variable name="miterLimit" select="substring-after(@style, 'stroke-miterlimit:')" /> + <xsl:choose> + <xsl:when test="contains($miterLimit, ';')"> + <xsl:value-of select="substring-before($miterLimit, ';')" /> + </xsl:when> + <xsl:otherwise> + <xsl:value-of select="$miterLimit" /> + </xsl:otherwise> + </xsl:choose> + </xsl:when> + <xsl:when test="name(..) = 'g' or name(..) = 'svg'"> + <xsl:apply-templates mode="stroke_miterlimit" select="parent::*"/> + </xsl:when> + </xsl:choose> +</xsl:template> + +<!-- + // Stroke dasharray // + !! Not supported !! +--> +<xsl:template mode="stroke_dasharray" match="*"> + <xsl:comment>FXG does not support dasharrays</xsl:comment> +</xsl:template> + +<!-- + // Stroke dashoffset // + !! Not supported !! +--> +<xsl:template mode="stroke_dashoffset" match="*"> + <xsl:comment>FXG does not support dashoffsets</xsl:comment> +</xsl:template> + +<!-- + // Linejoin SVG to FXG converter // +--> +<xsl:template name="linejoin_svg_to_fxg"> + <xsl:param name="linejoin" /> + <xsl:choose> + <xsl:when test="$linejoin = 'bevel'">bevel</xsl:when> + <xsl:when test="$linejoin = 'round'">round</xsl:when> + <xsl:otherwise>miter</xsl:otherwise> + </xsl:choose> +</xsl:template> + +<!-- + // Stroke linejoin // +--> +<xsl:template mode="stroke_linejoin" match="*"> + <xsl:choose> + <xsl:when test="@stroke-linejoin"> + <xsl:call-template name="linejoin_svg_to_fxg"> + <xsl:with-param name="linejoin"> + <xsl:value-of select="@stroke-linejoin" /> + </xsl:with-param> + </xsl:call-template> + </xsl:when> + <xsl:when test="@style and contains(@style, 'stroke-linejoin:')"> + <xsl:variable name="joints" select="substring-after(@style, 'stroke-linejoin:')" /> + <xsl:choose> + <xsl:when test="contains($joints, ';')"> + <xsl:call-template name="linejoin_svg_to_fxg"> + <xsl:with-param name="linejoin"> + <xsl:value-of select="substring-before($joints, ';')" /> + </xsl:with-param> + </xsl:call-template> + </xsl:when> + <xsl:otherwise> + <xsl:call-template name="linejoin_svg_to_fxg"> + <xsl:with-param name="linejoin"> + <xsl:value-of select="$joints" /> + </xsl:with-param> + </xsl:call-template> + </xsl:otherwise> + </xsl:choose> + </xsl:when> + <xsl:when test="name(..) = 'g' or name(..) = 'svg'"> + <xsl:apply-templates mode="stroke_linejoin" select="parent::*"/> + </xsl:when> + <xsl:otherwise>miter</xsl:otherwise> + </xsl:choose> +</xsl:template> + +<!-- + // Linecap SVG to FXG converter // + + Not supported in FXG: + * butt linecap +--> +<xsl:template name="linecap_svg_to_fxg"> + <xsl:param name="linecap" /> + <xsl:choose> + <xsl:when test="$linecap = 'round'">round</xsl:when> + <xsl:when test="$linecap = 'square'">square</xsl:when> + <xsl:when test="$linecap = 'butt'">round</xsl:when> + <xsl:otherwise>none</xsl:otherwise> + </xsl:choose> +</xsl:template> + +<!-- + // Stroke linecap // +--> +<xsl:template mode="stroke_linecap" match="*"> + <xsl:choose> + <xsl:when test="@stroke-linecap"> + <xsl:call-template name="linecap_svg_to_fxg"> + <xsl:with-param name="linecap"> + <xsl:value-of select="@stroke-linecap" /> + </xsl:with-param> + </xsl:call-template> + </xsl:when> + <xsl:when test="@style and contains(@style, 'stroke-linecap:')"> + <xsl:variable name="caps" select="substring-after(@style, 'stroke-linecap:')" /> + <xsl:choose> + <xsl:when test="contains($caps, ';')"> + <xsl:call-template name="linecap_svg_to_fxg"> + <xsl:with-param name="linecap"> + <xsl:value-of select="substring-before($caps, ';')" /> + </xsl:with-param> + </xsl:call-template> + </xsl:when> + <xsl:otherwise> + <xsl:call-template name="linecap_svg_to_fxg"> + <xsl:with-param name="linecap"> + <xsl:value-of select="$caps" /> + </xsl:with-param> + </xsl:call-template> + </xsl:otherwise> + </xsl:choose> + </xsl:when> + <xsl:when test="name(..) = 'g' or name(..) = 'svg'"> + <xsl:apply-templates mode="stroke_linecap" select="parent::*"/> + </xsl:when> + <xsl:otherwise>none</xsl:otherwise> + </xsl:choose> +</xsl:template> + +<!-- + // Gradient stops // +--> +<xsl:template mode="stop_color" match="*"> + <xsl:variable name="Opacity"> + <xsl:choose> + <xsl:when test="@stop-opacity"> + <xsl:value-of select="@stop-opacity" /> + </xsl:when> + <xsl:when test="@style and contains(@style, 'stop-opacity:')"> + <xsl:variable name="temp_opacity" select="substring-after(@style, 'stop-opacity:')" /> + <xsl:choose> + <xsl:when test="contains($temp_opacity, ';')"> + <xsl:value-of select="substring-before($temp_opacity, ';')" /> + </xsl:when> + <xsl:otherwise> + <xsl:value-of select="$temp_opacity" /> + </xsl:otherwise> + </xsl:choose> + </xsl:when> + <xsl:otherwise><xsl:value-of select="''" /></xsl:otherwise> + </xsl:choose> + </xsl:variable> + <xsl:variable name="hex_opacity"> + <xsl:choose> + <xsl:when test="$Opacity != ''"> + <xsl:call-template name="to_hex"> + <xsl:with-param name="convert"> + <xsl:value-of select="number($Opacity) * 255" /> + </xsl:with-param> + </xsl:call-template> + </xsl:when> + <xsl:otherwise> + <xsl:value-of select="$Opacity" /> + </xsl:otherwise> + </xsl:choose> + </xsl:variable> + <xsl:variable name="stopcolor"> + <xsl:choose> + <xsl:when test="@stop-color"> + <xsl:call-template name="template_color"> + <xsl:with-param name="colorspec"> + <xsl:value-of select="@stop-color" /> + </xsl:with-param> + </xsl:call-template> + </xsl:when> + <xsl:when test="@style and contains(@style, 'stop-color:')"> + <xsl:variable name="Color" select="normalize-space(substring-after(@style, 'stop-color:'))" /> + <xsl:choose> + <xsl:when test="contains($Color, ';')"> + <xsl:call-template name="template_color"> + <xsl:with-param name="colorspec"> + <xsl:value-of select="substring-before($Color, ';')" /> + </xsl:with-param> + </xsl:call-template> + </xsl:when> + <xsl:otherwise> + <xsl:call-template name="template_color"> + <xsl:with-param name="colorspec"> + <xsl:value-of select="$Color" /> + </xsl:with-param> + </xsl:call-template> + </xsl:otherwise> + </xsl:choose> + </xsl:when> + <xsl:when test="name(..) = 'g' or name(..) = 'svg'"> + <xsl:apply-templates mode="stop_color" select="parent::*"/> + </xsl:when> + <xsl:otherwise>#000</xsl:otherwise> + </xsl:choose> + </xsl:variable> + <xsl:attribute name="color"> + <xsl:value-of select="$stopcolor" /> + </xsl:attribute> + <xsl:if test="$Opacity != ''"> + <xsl:attribute name="alpha"> + <xsl:value-of select="$Opacity" /> + </xsl:attribute> + </xsl:if> +</xsl:template> + +<!-- + // Gradient stop opacity // +--> +<xsl:template mode="stop_opacity" match="*"> + <xsl:choose> + <xsl:when test="@stop-opacity"> + <xsl:attribute name="Opacity"> + <xsl:value-of select="@stop-opacity" /> + </xsl:attribute> + </xsl:when> + <xsl:when test="@style and contains(@style, 'stop-opacity:')"> + <xsl:variable name="Opacity" select="substring-after(@style, 'stop-opacity:')" /> + <xsl:attribute name="opacity"> + <xsl:choose> + <xsl:when test="contains($Opacity, ';')"> + <xsl:value-of select="substring-before($Opacity, ';')" /> + </xsl:when> + <xsl:otherwise> + <xsl:value-of select="$Opacity" /> + </xsl:otherwise> + </xsl:choose> + </xsl:attribute> + </xsl:when> + <xsl:when test="name(..) = 'g' or name(..) = 'svg'"> + <xsl:apply-templates mode="stop_opacity" select="parent::*"/> + </xsl:when> + </xsl:choose> +</xsl:template> + +<!-- + // Gradient stop offset // +--> +<xsl:template mode="offset" match="*"> + <xsl:choose> + <xsl:when test="@offset"> + <xsl:attribute name="ratio"> + <xsl:choose> + <xsl:when test="contains(@offset, '%')"> + <xsl:value-of select="number(substring-before(@offset, '%')) div 100" /> + </xsl:when> + <xsl:otherwise> + <xsl:value-of select="@offset" /> + </xsl:otherwise> + </xsl:choose> + </xsl:attribute> + </xsl:when> + <xsl:when test="@style and contains(@style, 'offset:')"> + <xsl:variable name="Offset" select="substring-after(@style, 'offset:')" /> + <xsl:attribute name="ratio"> + <xsl:choose> + <xsl:when test="contains($Offset, '%')"> + <xsl:value-of select="number(substring-before($Offset, '%')) div 100" /> + </xsl:when> + <xsl:when test="contains($Offset, ';')"> + <xsl:value-of select="substring-before($Offset, ';')" /> + </xsl:when> + <xsl:otherwise> + <xsl:value-of select="$Offset" /> + </xsl:otherwise> + </xsl:choose> + </xsl:attribute> + </xsl:when> + <xsl:when test="name(..) = 'g' or name(..) = 'svg'"> + <xsl:apply-templates mode="stop_offset" select="parent::*"/> + </xsl:when> + </xsl:choose> +</xsl:template> + +<!-- + // Text specific templates // + + * Text tspan + * Text flowPara + * Text flowRegion (text frame) + * Get font size + * Font size + * Font weight + * Font family + * Font style + * Baseline shift + * Line height + * Writing mode + * Text decoration + * Text fill + * Text direction + * Text size + * Text position + * Text object + * FlowRoot object +--> + + <!-- + // Text span // + SVG: tspan, flowSpan, FXG: span + + Not supported in FXG: + * span position +--> +<xsl:template mode="forward" match="*[name(.) = 'tspan' or name(.) = 'flowSpan']"> + <span> + <xsl:if test="../@xml:space='preserve'"> + <xsl:attribute name="whiteSpaceCollapse">preserve</xsl:attribute> + </xsl:if> + <xsl:variable name="fill"> + <xsl:apply-templates mode="fill" select="." /> + </xsl:variable> + <xsl:variable name="fill_opacity"> + <xsl:apply-templates mode="fill_opacity" select="." /> + </xsl:variable> + <xsl:if test="starts-with($fill, '#') or (not(starts-with($fill, 'url')) and $fill != '' and $fill != 'none')"> + <xsl:attribute name="color"> + <xsl:call-template name="template_color"> + <xsl:with-param name="colorspec"> + <xsl:value-of select="$fill" /> + </xsl:with-param> + </xsl:call-template> + </xsl:attribute> + <xsl:attribute name="textAlpha"> + <xsl:value-of select="$fill_opacity" /> + </xsl:attribute> + </xsl:if> + <xsl:apply-templates mode="font_size" select="." /> + <xsl:apply-templates mode="font_weight" select="." /> + <xsl:apply-templates mode="font_family" select="." /> + <xsl:apply-templates mode="font_style" select="." /> + <xsl:apply-templates mode="text_fill" select="." /> + <xsl:apply-templates mode="text_decoration" select="." /> + <xsl:apply-templates mode="line_height" select="." /> + <xsl:apply-templates mode="baseline_shift" select="." /> + + <xsl:if test="text()"> + <xsl:value-of select="text()" /> + </xsl:if> + </span> +</xsl:template> + + <!-- + // Text flowPara // + SVG: flowPara, flowDiv FXG: p + + Not supported in FXG: + * paragraph position +--> +<xsl:template mode="forward" match="*[name(.) = 'flowPara' or name(.) = 'flowDiv']"> + <p> + <xsl:if test="../@xml:space='preserve'"> + <xsl:attribute name="whiteSpaceCollapse">preserve</xsl:attribute> + </xsl:if> + <xsl:variable name="fill"> + <xsl:apply-templates mode="fill" select="." /> + </xsl:variable> + <xsl:variable name="fill_opacity"> + <xsl:apply-templates mode="fill_opacity" select="." /> + </xsl:variable> + <xsl:if test="starts-with($fill, '#') or (not(starts-with($fill, 'url')) and $fill != '' and $fill != 'none')"> + <xsl:attribute name="color"> + <xsl:call-template name="template_color"> + <xsl:with-param name="colorspec"> + <xsl:value-of select="$fill" /> + </xsl:with-param> + </xsl:call-template> + </xsl:attribute> + <xsl:attribute name="textAlpha"> + <xsl:value-of select="$fill_opacity" /> + </xsl:attribute> + </xsl:if> + <xsl:apply-templates mode="font_size" select="." /> + <xsl:apply-templates mode="font_weight" select="." /> + <xsl:apply-templates mode="font_family" select="." /> + <xsl:apply-templates mode="font_style" select="." /> + <xsl:apply-templates mode="text_fill" select="." /> + <xsl:apply-templates mode="text_decoration" select="." /> + <xsl:apply-templates mode="line_height" select="." /> + <xsl:apply-templates mode="baseline_shift" select="." /> + + <xsl:choose> + <xsl:when test="*[name(.) = 'flowSpan']/text()"> + <xsl:apply-templates mode="forward" /> + </xsl:when> + <xsl:otherwise> + <xsl:choose> + <xsl:when test="@xml:space='preserve'"> + <xsl:copy-of select="translate(text(), '	

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

', ' '))" /> + </xsl:otherwise> + </xsl:choose> + </xsl:otherwise> + </xsl:choose> + </p> +</xsl:template> + + + <!-- + // Text flowRegion // +--> +<xsl:template mode="flow_region" match="*"> + <xsl:apply-templates mode="text_size" select="." /> + <xsl:apply-templates mode="text_position" select="." /> +</xsl:template> + +<!-- + // Get text font size // +--> +<xsl:template mode="get_font_size" match="*"> + <xsl:choose> + <xsl:when test="@font-size"> + <xsl:value-of select="@font-size" /> + </xsl:when> + <xsl:when test="@style and contains(@style, 'font-size:')"> + <xsl:variable name="font_size" select="normalize-space(substring-after(@style, 'font-size:'))" /> + <xsl:choose> + <xsl:when test="contains($font_size, ';')"> + <xsl:value-of select="substring-before($font_size, ';')" /> + </xsl:when> + <xsl:otherwise> + <xsl:value-of select="$font_size" /> + </xsl:otherwise> + </xsl:choose> + </xsl:when> + <xsl:when test="name(..) = 'g' or name(..) = 'svg'"> + <xsl:apply-templates mode="get_font_size" select="parent::*"/> + </xsl:when> + </xsl:choose> +</xsl:template> + +<!-- + // Text font size // + SVG: font-size, FXG: fontSize +--> +<xsl:template mode="font_size" match="*"> + <xsl:variable name="value"> + <xsl:apply-templates mode="get_font_size" select="." /> + </xsl:variable> + <xsl:if test="$value != ''"> + <xsl:attribute name="fontSize"> + <xsl:call-template name="convert_unit"> + <xsl:with-param name="convert_value" select="$value" /> + </xsl:call-template> + </xsl:attribute> + </xsl:if> +</xsl:template> + +<!-- + // Text font weight // + SVG: font-weight, FXG: fontWeight +--> +<xsl:template mode="font_weight" match="*"> + <xsl:variable name="value"> + <xsl:if test="@font-weight"> + <xsl:value-of select="@font-weight" /> + </xsl:if> + <xsl:if test="@style and contains(@style, 'font-weight:')"> + <xsl:variable name="font_weight" select="normalize-space(substring-after(@style, 'font-weight:'))" /> + <xsl:choose> + <xsl:when test="contains($font_weight, ';')"> + <xsl:value-of select="substring-before($font_weight, ';')" /> + </xsl:when> + <xsl:otherwise> + <xsl:value-of select="$font_weight" /> + </xsl:otherwise> + </xsl:choose> + </xsl:if> + </xsl:variable> + <xsl:if test="$value != ''"> + <xsl:attribute name="fontWeight"> + <xsl:choose> + <xsl:when test="$value='normal' or $value='bold'"> + <xsl:value-of select="$value" /> + </xsl:when> + <xsl:when test="$value < 500 or $value = 'lighter'">normal</xsl:when> + <xsl:when test="$value > 499 or $value = 'bolder'">bold</xsl:when> + <xsl:otherwise>normal</xsl:otherwise> + </xsl:choose> + </xsl:attribute> + </xsl:if> +</xsl:template> + +<!-- + // Text font family // + SVG: font-family, FXG: fontFamily +--> +<xsl:template mode="font_family" match="*"> + <xsl:variable name="value"> + <xsl:if test="@font-family"> + <xsl:value-of select="translate(@font-family, "'", '')" /> + </xsl:if> + <xsl:if test="@style and contains(@style, 'font-family:')"> + <xsl:variable name="font_family" select="normalize-space(substring-after(@style, 'font-family:'))" /> + <xsl:choose> + <xsl:when test="contains($font_family, ';')"> + <xsl:value-of select="translate(substring-before($font_family, ';'), "'", '')" /> + </xsl:when> + <xsl:otherwise> + <xsl:value-of select="translate($font_family, "'", '')" /> + </xsl:otherwise> + </xsl:choose> + </xsl:if> + </xsl:variable> + <xsl:if test="$value != ''"> + <xsl:attribute name="fontFamily"> + <xsl:choose> + <xsl:when test="$value='Sans'">Arial</xsl:when> + <xsl:otherwise> + <xsl:value-of select="$value" /> + </xsl:otherwise> + </xsl:choose> + </xsl:attribute> + </xsl:if> +</xsl:template> + +<!-- + // Text font style // + SVG: font-style, FXG: fontStyle +--> +<xsl:template mode="font_style" match="*"> + <xsl:variable name="value"> + <xsl:if test="@font-style"> + <xsl:value-of select="@font-style" /> + </xsl:if> + <xsl:if test="@style and contains(@style, 'font-style:')"> + <xsl:variable name="font_style" select="normalize-space(substring-after(@style, 'font-style:'))" /> + <xsl:choose> + <xsl:when test="contains($font_style, ';')"> + <xsl:value-of select="substring-before($font_style, ';')" /> + </xsl:when> + <xsl:otherwise> + <xsl:value-of select="$font_style" /> + </xsl:otherwise> + </xsl:choose> + </xsl:if> + </xsl:variable> + <xsl:if test="$value != ''"> + <xsl:attribute name="fontStyle"> + <xsl:value-of select="$value" /> + </xsl:attribute> + </xsl:if> +</xsl:template> + +<!-- + // Text baseline shift // + SVG: baseline-shift, FXG: baselineShift +--> +<xsl:template mode="baseline_shift" match="*"> + <xsl:variable name="value"> + <xsl:if test="@baseline-shift"> + <xsl:value-of select="@baseline-shift" /> + </xsl:if> + <xsl:if test="@style and contains(@style, 'baseline-shift:') and not(contains(substring-after(@style, 'baseline-shift:'), ';'))"> + <xsl:value-of select="substring-after(@style, 'baseline-shift:')" /> + </xsl:if> + <xsl:if test="@style and contains(@style, 'baseline-shift:') and contains(substring-after(@style, 'baseline-shift:'), ';')"> + <xsl:value-of select="substring-before(substring-after(@style, 'baseline-shift:'), ';')" /> + </xsl:if> + </xsl:variable> + <xsl:if test="$value != ''"> + <xsl:attribute name="baselineShift"> + <xsl:choose> + <xsl:when test="$value='baseline'">0</xsl:when> + <xsl:when test="$value='super'">superscript</xsl:when> + <xsl:when test="$value='sub'">subscript</xsl:when> + <xsl:when test="translate($value, '%', '') < -1000">-1000</xsl:when> + <xsl:when test="translate($value, '%', '') > 1000">1000</xsl:when> + <xsl:otherwise> + <xsl:value-of select="translate($value, '%', '')" /> + </xsl:otherwise> + </xsl:choose> + <xsl:if test="contains($value, '%')">%</xsl:if> + </xsl:attribute> + </xsl:if> +</xsl:template> + +<!-- + // Text line height // + SVG: line-height, FXG: lineHeight +--> +<xsl:template mode="line_height" match="*"> + <xsl:variable name="value"> + <xsl:if test="@line-height"> + <xsl:value-of select="@line-height" /> + </xsl:if> + <xsl:if test="@style and contains(@style, 'line-height:')"> + <xsl:variable name="line_height" select="normalize-space(substring-after(@style, 'line-height:'))" /> + <xsl:choose> + <xsl:when test="contains($line_height, ';')"> + <xsl:value-of select="substring-before($line_height, ';')" /> + </xsl:when> + <xsl:otherwise> + <xsl:value-of select="$line_height" /> + </xsl:otherwise> + </xsl:choose> + </xsl:if> + </xsl:variable> + <xsl:if test="$value != ''"> + <xsl:attribute name="lineHeight"> + <xsl:call-template name="convert_unit"> + <xsl:with-param name="convert_value" select="$value" /> + </xsl:call-template> + </xsl:attribute> + </xsl:if> +</xsl:template> + +<!-- + // Text writing mode // + SVG: writing-mode, FXG: blockProgression + + Values inverted in FXG... +--> +<xsl:template mode="writing_mode" match="*"> + <xsl:variable name="value"> + <xsl:if test="@writing-mode"> + <xsl:value-of select="@writing-mode" /> + </xsl:if> + <xsl:if test="@style and contains(@style, 'writing-mode:') and not(contains(substring-after(@style, 'writing-mode:'), ';'))"> + <xsl:value-of select="substring-after(@style, 'writing-mode:')" /> + </xsl:if> + <xsl:if test="@style and contains(@style, 'writing-mode:') and contains(substring-after(@style, 'writing-mode:'), ';')"> + <xsl:value-of select="substring-before(substring-after(@style, 'writing-mode:'), ';')" /> + </xsl:if> + </xsl:variable> + <xsl:if test="$value != ''"> + <xsl:attribute name="blockProgression"> + <xsl:choose> + <xsl:when test="$value='tb'">rl</xsl:when> + <xsl:otherwise>tb</xsl:otherwise> + </xsl:choose> + </xsl:attribute> + <xsl:if test="$value='tb'"> + <xsl:attribute name="textRotation">rotate270</xsl:attribute> + </xsl:if> + </xsl:if> +</xsl:template> + +<!-- + // Text decoration // + SVG: text-decoration, FXG: textDecoration, lineThrough +--> +<xsl:template mode="text_decoration" match="*"> + <xsl:variable name="value"> + <xsl:if test="@text-decoration"> + <xsl:value-of select="@text-decoration" /> + </xsl:if> + <xsl:if test="@style and contains(@style, 'text-decoration:') and not(contains(substring-after(@style, 'text-decoration:'), ';'))"> + <xsl:value-of select="substring-after(@style, 'text-decoration:')" /> + </xsl:if> + <xsl:if test="@style and contains(@style, 'text-decoration:') and contains(substring-after(@style, 'text-decoration:'), ';')"> + <xsl:value-of select="substring-before(substring-after(@style, 'text-decoration:'), ';')" /> + </xsl:if> + </xsl:variable> + <xsl:if test="$value != ''"> + <xsl:choose> + <xsl:when test="$value='underline'"> + <xsl:attribute name="textDecoration">underline</xsl:attribute> + </xsl:when> + <xsl:when test="$value='line-through'"> + <xsl:attribute name="lineThrough">true</xsl:attribute> + </xsl:when> + </xsl:choose> + </xsl:if> +</xsl:template> + +<!-- + // Text fill // + SVG: fill, fill-opacity, FXG: color, textAlpha +--> +<xsl:template mode="text_fill" match="*"> + <xsl:variable name="fill"> + <xsl:apply-templates mode="fill" select="." /> + </xsl:variable> + <xsl:variable name="fill_opacity"> + <xsl:apply-templates mode="fill_opacity" select="." /> + </xsl:variable> + <xsl:if test="starts-with($fill, '#') or (not(starts-with($fill, 'url')) and $fill != '' and $fill != 'none')"> + <xsl:attribute name="color"> + <xsl:call-template name="template_color"> + <xsl:with-param name="colorspec"> + <xsl:value-of select="$fill" /> + </xsl:with-param> + </xsl:call-template> + </xsl:attribute> + <xsl:attribute name="textAlpha"> + <xsl:value-of select="$fill_opacity" /> + </xsl:attribute> + </xsl:if> +</xsl:template> + +<!-- + // Text direction // + SVG: direction, unicode-bidi, FXG: direction +--> +<xsl:template mode="direction" match="*"> + <xsl:variable name="value"> + <xsl:if test="@direction"> + <xsl:value-of select="@direction" /> + </xsl:if> + <xsl:if test="@style and contains(@style, 'direction:') and not(contains(substring-after(@style, 'direction:'), ';'))"> + <xsl:value-of select="substring-after(@style, 'direction:')" /> + </xsl:if> + <xsl:if test="@style and contains(@style, 'direction:') and contains(substring-after(@style, 'direction:'), ';')"> + <xsl:value-of select="substring-before(substring-after(@style, 'direction:'), ';')" /> + </xsl:if> + </xsl:variable> + <xsl:variable name="bidi"> + <xsl:if test="@unicode-bidi"> + <xsl:value-of select="@unicode-bidi" /> + </xsl:if> + <xsl:if test="@style and contains(@style, 'unicode-bidi:') and not(contains(substring-after(@style, 'unicode-bidi:'), ';'))"> + <xsl:value-of select="substring-after(@style, 'unicode-bidi:')" /> + </xsl:if> + <xsl:if test="@style and contains(@style, 'unicode-bidi:') and contains(substring-after(@style, 'unicode-bidi:'), ';')"> + <xsl:value-of select="substring-before(substring-after(@style, 'unicode-bidi:'), ';')" /> + </xsl:if> + </xsl:variable> + + <xsl:if test="$value != '' and ($bidi='embed' or $bidi='bidi-override')"> + <xsl:attribute name="direction"> + <xsl:choose> + <xsl:when test="$value='ltr'">ltr</xsl:when> + <xsl:when test="$value='rtl'">rtl</xsl:when> + </xsl:choose> + </xsl:attribute> + </xsl:if> +</xsl:template> + + <!-- + // Text size // +--> +<xsl:template mode="text_size" match="*"> + <xsl:if test="@width"> + <xsl:attribute name="width"> + <xsl:call-template name="convert_unit"> + <xsl:with-param name="convert_value" select="@width" /> + </xsl:call-template> + </xsl:attribute> + </xsl:if> + <xsl:if test="@height"> + <xsl:attribute name="height"> + <xsl:call-template name="convert_unit"> + <xsl:with-param name="convert_value" select="@height" /> + </xsl:call-template> + </xsl:attribute> + </xsl:if> +</xsl:template> + + <!-- + // Text position // +--> +<xsl:template mode="text_position" match="*"> + <!-- Keep the first x value only --> + <xsl:if test="@x"> + <xsl:attribute name="x"> + <xsl:choose> + <xsl:when test="contains(@x, ' ')"> + <xsl:call-template name="convert_unit"> + <xsl:with-param name="convert_value" select="substring-before(@x, ' ')" /> + </xsl:call-template> + </xsl:when> + <xsl:otherwise> + <xsl:call-template name="convert_unit"> + <xsl:with-param name="convert_value" select="@x" /> + </xsl:call-template> + </xsl:otherwise> + </xsl:choose> + </xsl:attribute> + </xsl:if> + <!-- Keep the first y value only --> + <xsl:if test="@y"> + <xsl:attribute name="y"> + <xsl:choose> + <xsl:when test="contains(@y, ' ')"> + <xsl:call-template name="convert_unit"> + <xsl:with-param name="convert_value" select="substring-before(@y, ' ')" /> + </xsl:call-template> + </xsl:when> + <xsl:otherwise> + <xsl:call-template name="convert_unit"> + <xsl:with-param name="convert_value" select="@y" /> + </xsl:call-template> + </xsl:otherwise> + </xsl:choose> + </xsl:attribute> + </xsl:if> +</xsl:template> + + +<!-- + // Text objects // + SVG: text, FXG: RichText + + Not supported by FXG: + * Generic fonts. + * Embedded fonts (in defs). + * Character rotation. + * Character positionning (x and y). + * Text-anchor. + * Text stroke. + + Partial support: + * Text rotation (0, 90, 180 and 270 degrees only) -> not implemented. + * Font weight (normal and bold only) -> values under 500 are considered normal, the others bold. + * Whitespace handling, issues with xml:whitespace='preserve'. +--> +<xsl:template mode="forward" match="*[name(.) = 'text']"> + <xsl:variable name="object"> + <RichText> + <!-- Force default baseline to "ascent" --> + <xsl:attribute name="alignmentBaseline">ascent</xsl:attribute> + + <xsl:apply-templates mode="font_size" select="." /> + <xsl:apply-templates mode="font_weight" select="." /> + <xsl:apply-templates mode="font_family" select="." /> + <xsl:apply-templates mode="font_style" select="." /> + <xsl:apply-templates mode="text_fill" select="." /> + <xsl:apply-templates mode="text_decoration" select="." /> + <xsl:apply-templates mode="line_height" select="." /> + <xsl:apply-templates mode="text_size" select="." /> + <xsl:apply-templates mode="text_position" select="." /> + <xsl:apply-templates mode="direction" select="." /> + <xsl:apply-templates mode="writing_mode" select="." /> + <xsl:apply-templates mode="id" select="." /> + + <xsl:if test="not(*[name(.) = 'tspan']/text())"> + <xsl:attribute name="whiteSpaceCollapse">preserve</xsl:attribute> + </xsl:if> + + <xsl:apply-templates mode="filter_effect" select="." /> + <xsl:apply-templates mode="desc" select="." /> + + <!--xsl:apply-templates mode="forward" /--> + <content> + <xsl:choose> + <xsl:when test="*[name(.) = 'tspan']/text()"> + <xsl:apply-templates mode="forward" /> + </xsl:when> + <xsl:otherwise> + <xsl:choose> + <xsl:when test="@xml:space='preserve'"> + <xsl:copy-of select="translate(text(), '	

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

', ' '))" /> + </xsl:otherwise> + </xsl:choose> + </xsl:otherwise> + </xsl:choose> + </content> + </RichText> + </xsl:variable> + + <xsl:variable name="clipped_object"> + <xsl:apply-templates mode="clip" select="." > + <xsl:with-param name="object" select="$object" /> + <xsl:with-param name="clip_type" select="'clip'" /> + </xsl:apply-templates> + </xsl:variable> + + <xsl:variable name="masked_object"> + <xsl:apply-templates mode="clip" select="." > + <xsl:with-param name="object" select="$clipped_object" /> + <xsl:with-param name="clip_type" select="'mask'" /> + </xsl:apply-templates> + </xsl:variable> + + <xsl:choose> + <xsl:when test="@transform"> + <Group> + <xsl:call-template name="object_transform"> + <xsl:with-param name="object" select="$masked_object" /> + <xsl:with-param name="transform" select="@transform" /> + </xsl:call-template> + </Group> + </xsl:when> + <xsl:otherwise> + <xsl:copy-of select="$masked_object" /> + </xsl:otherwise> + </xsl:choose> +</xsl:template> + + <!-- + // FlowRoot objects // + SVG: flowRoot, FXG: RichText + + Not supported by FXG: + * See text objects +--> +<xsl:template mode="forward" match="*[name(.) = 'flowRoot']"> + <xsl:variable name="object"> + <RichText> + <!-- Force default baseline to "ascent" --> + <xsl:attribute name="alignmentBaseline">ascent</xsl:attribute> + + <xsl:apply-templates mode="font_size" select="." /> + <xsl:apply-templates mode="font_weight" select="." /> + <xsl:apply-templates mode="font_family" select="." /> + <xsl:apply-templates mode="font_style" select="." /> + <xsl:apply-templates mode="text_fill" select="." /> + <xsl:apply-templates mode="text_decoration" select="." /> + <xsl:apply-templates mode="line_height" select="." /> + <xsl:apply-templates mode="direction" select="." /> + <xsl:apply-templates mode="writing_mode" select="." /> + <xsl:apply-templates mode="id" select="." /> + <xsl:apply-templates mode="flow_region" select="*[name(.) = 'flowRegion']/child::node()" /> + + <xsl:apply-templates mode="filter_effect" select="." /> + <xsl:apply-templates mode="desc" select="." /> + + <content> + <xsl:choose> + <xsl:when test="*[name(.) = 'flowPara' or name(.) = 'flowDiv']/text()"> + <xsl:apply-templates mode="forward" /> + </xsl:when> + <xsl:otherwise> + <xsl:choose> + <xsl:when test="@xml:space='preserve'"> + <xsl:copy-of select="translate(text(), '	

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

', ' '))" /> + </xsl:otherwise> + </xsl:choose> + </xsl:otherwise> + </xsl:choose> + </content> + </RichText> + </xsl:variable> + + <xsl:variable name="clipped_object"> + <xsl:apply-templates mode="clip" select="." > + <xsl:with-param name="object" select="$object" /> + <xsl:with-param name="clip_type" select="'clip'" /> + </xsl:apply-templates> + </xsl:variable> + + <xsl:variable name="masked_object"> + <xsl:apply-templates mode="clip" select="." > + <xsl:with-param name="object" select="$clipped_object" /> + <xsl:with-param name="clip_type" select="'mask'" /> + </xsl:apply-templates> + </xsl:variable> + + <xsl:choose> + <xsl:when test="@transform"> + <Group> + <xsl:call-template name="object_transform"> + <xsl:with-param name="object" select="$masked_object" /> + <xsl:with-param name="transform" select="@transform" /> + </xsl:call-template> + </Group> + </xsl:when> + <xsl:otherwise> + <xsl:copy-of select="$masked_object" /> + </xsl:otherwise> + </xsl:choose> +</xsl:template> + +<!-- + // Shapes // + + * Lines + * Rectangle + * Path + * Ellipse + * Circle + * Image + * Polygon (not supported) + * Polyline (not supported) +--> + +<!-- + // Line object // + SVG: line, FXG: Line +--> +<xsl:template mode="forward" match="*[name(.) = 'line']"> + <xsl:variable name="object"> + <Line> + <xsl:if test="@x1"> + <xsl:attribute name="xFrom"> + <xsl:call-template name="convert_unit"> + <xsl:with-param name="convert_value" select="@x1" /> + </xsl:call-template> + </xsl:attribute> + </xsl:if> + <xsl:if test="@y1"> + <xsl:attribute name="yFrom"> + <xsl:call-template name="convert_unit"> + <xsl:with-param name="convert_value" select="@y1" /> + </xsl:call-template> + </xsl:attribute> + </xsl:if> + <xsl:if test="@x2"> + <xsl:attribute name="xTo"> + <xsl:call-template name="convert_unit"> + <xsl:with-param name="convert_value" select="@x2" /> + </xsl:call-template> + </xsl:attribute> + </xsl:if> + <xsl:if test="@y2"> + <xsl:attribute name="yTo"> + <xsl:call-template name="convert_unit"> + <xsl:with-param name="convert_value" select="@y2" /> + </xsl:call-template> + </xsl:attribute> + </xsl:if> + <xsl:apply-templates mode="object_opacity" select="." /> + <xsl:apply-templates mode="id" select="." /> + + <xsl:apply-templates mode="template_fill" select="." /> + <xsl:apply-templates mode="template_stroke" select="." /> + <xsl:apply-templates mode="filter_effect" select="." /> + <xsl:apply-templates mode="desc" select="." /> + + <xsl:apply-templates mode="forward" /> + </Line> + </xsl:variable> + + <xsl:variable name="clipped_object"> + <xsl:apply-templates mode="clip" select="." > + <xsl:with-param name="object" select="$object" /> + <xsl:with-param name="clip_type" select="'clip'" /> + </xsl:apply-templates> + </xsl:variable> + + <xsl:variable name="masked_object"> + <xsl:apply-templates mode="clip" select="." > + <xsl:with-param name="object" select="$clipped_object" /> + <xsl:with-param name="clip_type" select="'mask'" /> + </xsl:apply-templates> + </xsl:variable> + + <xsl:choose> + <xsl:when test="@transform"> + <Group> + <xsl:call-template name="object_transform"> + <xsl:with-param name="object" select="$masked_object" /> + <xsl:with-param name="transform" select="@transform" /> + </xsl:call-template> + </Group> + </xsl:when> + <xsl:otherwise> + <xsl:copy-of select="$masked_object" /> + </xsl:otherwise> + </xsl:choose> +</xsl:template> + +<!-- + // Rectangle object // + SVG: rect, FXG: Rect +--> +<xsl:template mode="forward" match="*[name(.) = 'rect']"> + <xsl:variable name="object"> + <Rect> + <xsl:if test="@x"> + <xsl:attribute name="x"> + <xsl:call-template name="convert_unit"> + <xsl:with-param name="convert_value" select="@x" /> + </xsl:call-template> + </xsl:attribute> + </xsl:if> + <xsl:if test="@y"> + <xsl:attribute name="y"> + <xsl:call-template name="convert_unit"> + <xsl:with-param name="convert_value" select="@y" /> + </xsl:call-template> + </xsl:attribute> + </xsl:if> + <xsl:if test="@width"> + <xsl:attribute name="width"> + <xsl:call-template name="convert_unit"> + <xsl:with-param name="convert_value" select="@width" /> + </xsl:call-template> + </xsl:attribute> + </xsl:if> + <xsl:if test="@height"> + <xsl:attribute name="height"> + <xsl:call-template name="convert_unit"> + <xsl:with-param name="convert_value" select="@height" /> + </xsl:call-template> + </xsl:attribute> + </xsl:if> + <xsl:if test="@rx"> + <xsl:attribute name="radiusX"> + <xsl:value-of select="@rx" /> + </xsl:attribute> + </xsl:if> + <xsl:if test="@ry"> + <xsl:attribute name="radiusY"> + <xsl:value-of select="@ry" /> + </xsl:attribute> + </xsl:if> + <xsl:if test="@rx and not(@ry)"> + <xsl:attribute name="radiusX"> + <xsl:value-of select="@rx" /> + </xsl:attribute> + <xsl:attribute name="radiusY"> + <xsl:value-of select="@rx" /> + </xsl:attribute> + </xsl:if> + <xsl:if test="@ry and not(@rx)"> + <xsl:attribute name="radiusX"> + <xsl:value-of select="@ry" /> + </xsl:attribute> + <xsl:attribute name="radiusY"> + <xsl:value-of select="@ry" /> + </xsl:attribute> + </xsl:if> + <xsl:apply-templates mode="object_opacity" select="." /> + <xsl:apply-templates mode="id" select="." /> + + <xsl:apply-templates mode="template_fill" select="." /> + <xsl:apply-templates mode="template_stroke" select="." /> + <xsl:apply-templates mode="filter_effect" select="." /> + <!-- <xsl:apply-templates mode="resources" select="." /> --> + <xsl:apply-templates mode="desc" select="." /> + + <xsl:apply-templates mode="forward" /> + </Rect> + </xsl:variable> + + <xsl:variable name="clipped_object"> + <xsl:apply-templates mode="clip" select="." > + <xsl:with-param name="object" select="$object" /> + <xsl:with-param name="clip_type" select="'clip'" /> + </xsl:apply-templates> + </xsl:variable> + + <xsl:variable name="masked_object"> + <xsl:apply-templates mode="clip" select="." > + <xsl:with-param name="object" select="$clipped_object" /> + <xsl:with-param name="clip_type" select="'mask'" /> + </xsl:apply-templates> + </xsl:variable> + + <xsl:choose> + <xsl:when test="@transform"> + <Group> + <xsl:call-template name="object_transform"> + <xsl:with-param name="object" select="$masked_object" /> + <xsl:with-param name="transform" select="@transform" /> + </xsl:call-template> + </Group> + </xsl:when> + <xsl:otherwise> + <xsl:copy-of select="$masked_object" /> + </xsl:otherwise> + </xsl:choose> +</xsl:template> + +<!-- + // Path // + SVG: path, FXG: Path + + Not supported by FXG: + * elliptical arc curve commands (workaround: convert to path first) + TODO: + * Implement an arc to curve convertor +--> +<xsl:template mode="forward" match="*[name(.) = 'path']"> + <xsl:variable name="object"> + <Path> + <!-- Path element --> + <!-- Exclude arcs in order to prevent the mxml compiler from failing --> + <xsl:if test="@d and not(contains(@d, 'a') or contains(@d, 'A'))"> + <xsl:attribute name="data"> + <xsl:value-of select="normalize-space(translate(@d , ',', ' '))" /> + </xsl:attribute> + </xsl:if> + <xsl:apply-templates mode="fill_rule" select="." /> + <xsl:apply-templates mode="object_opacity" select="." /> + <xsl:apply-templates mode="id" select="." /> + + <!-- Child elements --> + <xsl:apply-templates mode="template_fill" select="." /> + <xsl:apply-templates mode="template_stroke" select="." /> + <xsl:apply-templates mode="filter_effect" select="." /> + <xsl:apply-templates mode="desc" select="." /> + + <xsl:apply-templates mode="forward" /> + </Path> + </xsl:variable> + + <xsl:variable name="clipped_object"> + <xsl:apply-templates mode="clip" select="." > + <xsl:with-param name="object" select="$object" /> + <xsl:with-param name="clip_type" select="'clip'" /> + </xsl:apply-templates> + </xsl:variable> + + <xsl:variable name="masked_object"> + <xsl:apply-templates mode="clip" select="." > + <xsl:with-param name="object" select="$clipped_object" /> + <xsl:with-param name="clip_type" select="'mask'" /> + </xsl:apply-templates> + </xsl:variable> + + <xsl:choose> + <xsl:when test="@transform"> + <Group> + <xsl:call-template name="object_transform"> + <xsl:with-param name="object" select="$masked_object" /> + <xsl:with-param name="transform" select="@transform" /> + </xsl:call-template> + </Group> + </xsl:when> + <xsl:otherwise> + <xsl:copy-of select="$masked_object" /> + </xsl:otherwise> + </xsl:choose> + <xsl:if test="contains(@d, 'a') or contains(@d, 'A')"> + <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> + </xsl:if> +</xsl:template> + +<!-- + // Ellipse object // + SVG: ellipse, FXG: Ellipse +--> +<xsl:template mode="forward" match="*[name(.) = 'ellipse']"> + <xsl:variable name="object"> + <Ellipse> + <xsl:variable name="cx"> + <xsl:choose> + <xsl:when test="@cx"> + <xsl:call-template name="convert_unit"> + <xsl:with-param name="convert_value" select="@cx" /> + </xsl:call-template> + </xsl:when> + <xsl:otherwise>0</xsl:otherwise> + </xsl:choose> + </xsl:variable> + <xsl:variable name="cy"> + <xsl:choose> + <xsl:when test="@cy"> + <xsl:call-template name="convert_unit"> + <xsl:with-param name="convert_value" select="@cy" /> + </xsl:call-template> + </xsl:when> + <xsl:otherwise>0</xsl:otherwise> + </xsl:choose> + </xsl:variable> + <xsl:variable name="rx"> + <xsl:choose> + <xsl:when test="@rx"> + <xsl:call-template name="convert_unit"> + <xsl:with-param name="convert_value" select="@rx" /> + </xsl:call-template> + </xsl:when> + <xsl:otherwise>0</xsl:otherwise> + </xsl:choose> + </xsl:variable> + <xsl:variable name="ry"> + <xsl:choose> + <xsl:when test="@ry"> + <xsl:call-template name="convert_unit"> + <xsl:with-param name="convert_value" select="@ry" /> + </xsl:call-template> + </xsl:when> + <xsl:otherwise>0</xsl:otherwise> + </xsl:choose> + </xsl:variable> + + <xsl:choose> + <xsl:when test="$rx != 0"> + <xsl:attribute name="x"> + <xsl:value-of select='format-number($cx - $rx, "#.#")' /> + </xsl:attribute> + <xsl:attribute name="width"> + <xsl:value-of select='format-number(2 * $rx, "#.#")' /> + </xsl:attribute> + </xsl:when> + <xsl:otherwise> + <xsl:attribute name="x"> + <xsl:value-of select='format-number($cx, "#.#")' /> + </xsl:attribute> + <xsl:attribute name="width">0</xsl:attribute> + </xsl:otherwise> + </xsl:choose> + <xsl:choose> + <xsl:when test="$ry != 0"> + <xsl:attribute name="y"> + <xsl:value-of select='format-number($cy - $ry, "#.#")' /> + </xsl:attribute> + <xsl:attribute name="height"> + <xsl:value-of select='format-number(2 * $ry, "#.#")' /> + </xsl:attribute> + </xsl:when> + <xsl:otherwise> + <xsl:attribute name="y"> + <xsl:value-of select='format-number($cy, "#.#")' /> + </xsl:attribute> + <xsl:attribute name="height">0</xsl:attribute> + </xsl:otherwise> + </xsl:choose> + <xsl:apply-templates mode="object_opacity" select="." /> + <xsl:apply-templates mode="id" select="." /> + + <!-- Child elements --> + <xsl:apply-templates mode="template_fill" select="." /> + <xsl:apply-templates mode="template_stroke" select="." /> + <xsl:apply-templates mode="filter_effect" select="." /> + <xsl:apply-templates mode="desc" select="." /> + + <xsl:apply-templates mode="forward" /> + </Ellipse> + </xsl:variable> + + <xsl:variable name="clipped_object"> + <xsl:apply-templates mode="clip" select="." > + <xsl:with-param name="object" select="$object" /> + <xsl:with-param name="clip_type" select="'clip'" /> + </xsl:apply-templates> + </xsl:variable> + + <xsl:variable name="masked_object"> + <xsl:apply-templates mode="clip" select="." > + <xsl:with-param name="object" select="$clipped_object" /> + <xsl:with-param name="clip_type" select="'mask'" /> + </xsl:apply-templates> + </xsl:variable> + + <xsl:choose> + <xsl:when test="@transform"> + <Group> + <xsl:call-template name="object_transform"> + <xsl:with-param name="object" select="$masked_object" /> + <xsl:with-param name="transform" select="@transform" /> + </xsl:call-template> + </Group> + </xsl:when> + <xsl:otherwise> + <xsl:copy-of select="$masked_object" /> + </xsl:otherwise> + </xsl:choose> +</xsl:template> + +<!-- + // Circle object // + SVG: circle, FXG: Ellipse +--> +<xsl:template mode="forward" match="*[name(.) = 'circle']"> + <xsl:variable name="object"> + <Ellipse> + <xsl:variable name="cx"> + <xsl:choose> + <xsl:when test="@cx"> + <xsl:call-template name="convert_unit"> + <xsl:with-param name="convert_value" select="@cx" /> + </xsl:call-template> + </xsl:when> + <xsl:otherwise>0</xsl:otherwise> + </xsl:choose> + </xsl:variable> + <xsl:variable name="cy"> + <xsl:choose> + <xsl:when test="@cy"> + <xsl:call-template name="convert_unit"> + <xsl:with-param name="convert_value" select="@cy" /> + </xsl:call-template> + </xsl:when> + <xsl:otherwise>0</xsl:otherwise> + </xsl:choose> + </xsl:variable> + <xsl:variable name="r"> + <xsl:choose> + <xsl:when test="@r"> + <xsl:call-template name="convert_unit"> + <xsl:with-param name="convert_value" select="@r" /> + </xsl:call-template> + </xsl:when> + <xsl:otherwise>0</xsl:otherwise> + </xsl:choose> + </xsl:variable> + + <xsl:choose> + <xsl:when test="$r != 0"> + <xsl:attribute name="x"> + <xsl:value-of select='format-number($cx - $r, "#.#")' /> + </xsl:attribute> + <xsl:attribute name="y"> + <xsl:value-of select='format-number($cy - $r, "#.#")' /> + </xsl:attribute> + <xsl:attribute name="width"> + <xsl:value-of select='format-number(2 * $r, "#.#")' /> + </xsl:attribute> + <xsl:attribute name="height"> + <xsl:value-of select='format-number(2 * $r, "#.#")' /> + </xsl:attribute> + </xsl:when> + <xsl:otherwise> + <xsl:attribute name="x"> + <xsl:value-of select='format-number($cx, "#.#")' /> + </xsl:attribute> + <xsl:attribute name="y"> + <xsl:value-of select='format-number($cy, "#.#")' /> + </xsl:attribute> + <xsl:attribute name="width">0</xsl:attribute> + <xsl:attribute name="height">0</xsl:attribute> + </xsl:otherwise> + </xsl:choose> + <xsl:apply-templates mode="object_opacity" select="." /> + <xsl:apply-templates mode="id" select="." /> + + <!-- Child elements --> + <xsl:apply-templates mode="template_fill" select="." /> + <xsl:apply-templates mode="template_stroke" select="." /> + <xsl:apply-templates mode="filter_effect" select="." /> + <xsl:apply-templates mode="desc" select="." /> + + <xsl:apply-templates mode="forward" /> + </Ellipse> + </xsl:variable> + + <xsl:variable name="clipped_object"> + <xsl:apply-templates mode="clip" select="." > + <xsl:with-param name="object" select="$object" /> + <xsl:with-param name="clip_type" select="'clip'" /> + </xsl:apply-templates> + </xsl:variable> + + <xsl:variable name="masked_object"> + <xsl:apply-templates mode="clip" select="." > + <xsl:with-param name="object" select="$clipped_object" /> + <xsl:with-param name="clip_type" select="'mask'" /> + </xsl:apply-templates> + </xsl:variable> + + <xsl:choose> + <xsl:when test="@transform"> + <Group> + <xsl:call-template name="object_transform"> + <xsl:with-param name="object" select="$masked_object" /> + <xsl:with-param name="transform" select="@transform" /> + </xsl:call-template> + </Group> + </xsl:when> + <xsl:otherwise> + <xsl:copy-of select="$masked_object" /> + </xsl:otherwise> + </xsl:choose> +</xsl:template> + +<!-- + // Image objects // + SVG: image, FXG: Rect+BitmapFill + + Not supported by FXG: + * Embedded images (base64). + * Preserve ratio. +--> +<xsl:template mode="forward" match="*[name(.) = 'image']"> + <xsl:variable name="object"> + <Rect> + <xsl:if test="@x"> + <xsl:attribute name="x"> + <xsl:call-template name="convert_unit"> + <xsl:with-param name="convert_value" select="@x" /> + </xsl:call-template> + </xsl:attribute> + </xsl:if> + <xsl:if test="@y"> + <xsl:attribute name="y"> + <xsl:call-template name="convert_unit"> + <xsl:with-param name="convert_value" select="@y" /> + </xsl:call-template> + </xsl:attribute> + </xsl:if> + <xsl:if test="@width"> + <xsl:attribute name="width"> + <xsl:call-template name="convert_unit"> + <xsl:with-param name="convert_value" select="@width" /> + </xsl:call-template> + </xsl:attribute> + </xsl:if> + <xsl:if test="@height"> + <xsl:attribute name="height"> + <xsl:call-template name="convert_unit"> + <xsl:with-param name="convert_value" select="@height" /> + </xsl:call-template> + </xsl:attribute> + </xsl:if> + <xsl:apply-templates mode="object_opacity" select="." /> + <xsl:apply-templates mode="id" select="." /> + + <xsl:apply-templates mode="desc" select="." /> + + <xsl:if test="@xlink:href"> + <fill> + <BitmapFill> + <xsl:attribute name="source">@Embed('<xsl:value-of select="@xlink:href"/>')</xsl:attribute> + </BitmapFill> + </fill> + </xsl:if> + + <xsl:apply-templates mode="forward" /> + </Rect> + </xsl:variable> + + <xsl:variable name="clipped_object"> + <xsl:apply-templates mode="clip" select="." > + <xsl:with-param name="object" select="$object" /> + <xsl:with-param name="clip_type" select="'clip'" /> + </xsl:apply-templates> + </xsl:variable> + + <xsl:variable name="masked_object"> + <xsl:apply-templates mode="clip" select="." > + <xsl:with-param name="object" select="$clipped_object" /> + <xsl:with-param name="clip_type" select="'mask'" /> + </xsl:apply-templates> + </xsl:variable> + + <xsl:choose> + <xsl:when test="@transform"> + <Group> + <xsl:call-template name="object_transform"> + <xsl:with-param name="object" select="$masked_object" /> + <xsl:with-param name="transform" select="@transform" /> + </xsl:call-template> + </Group> + </xsl:when> + <xsl:otherwise> + <xsl:copy-of select="$masked_object" /> + </xsl:otherwise> + </xsl:choose> +</xsl:template> + +<!-- + // Polygon object // + !! Not supported !! +--> +<xsl:template mode="forward" match="*[name(.) = 'polygon']"> + <xsl:comment>FXG does not support polygons</xsl:comment> +</xsl:template> + +<!-- + // Polyline object // + !! Not supported !! +--> +<xsl:template mode="forward" match="*[name(.) = 'polyline']"> + <xsl:comment>FXG does not support polylines</xsl:comment> +</xsl:template> + +</xsl:stylesheet> diff --git a/share/extensions/svg2xaml.xsl b/share/extensions/svg2xaml.xsl index 1c663c11c..32f869da1 100755 --- a/share/extensions/svg2xaml.xsl +++ b/share/extensions/svg2xaml.xsl @@ -3,7 +3,7 @@ <!-- Copyright (c) 2005-2007 authors: Original version: Toine de Greef (a.degreef@chello.nl) -Modified (2010) by Nicolas Dufour (nicoduf@yahoo.fr) (blur support, units +Modified (2010-2011) by Nicolas Dufour (nicoduf@yahoo.fr) (blur support, units convertion, comments, and some other fixes) Permission is hereby granted, free of charge, to any person obtaining a copy @@ -37,12 +37,20 @@ xmlns:libxslt="http://xmlsoft.org/XSLT/namespace" exclude-result-prefixes="rdf xlink xs exsl libxslt"> <xsl:strip-space elements="*" /> -<xsl:output method="xml" encoding="UTF-8"/> +<xsl:output method="xml" encoding="UTF-8" indent="yes"/> -<xsl:param name="silverlight_compatible" select="1" /> +<xsl:param name="silverlight_compatible" select="2" /> -<!-- Root template. -Everything starts here! --> +<!-- + // Containers // + + * Root templace + * Groups +--> + +<!-- + // Root template // +--> <xsl:template match="/"> <xsl:choose> <xsl:when test="$silverlight_compatible = 1"> @@ -56,68 +64,90 @@ Everything starts here! --> </xsl:choose> </xsl:template> -<!-- SVG and groups -(including layers) --> +<!-- + // SVG and groups // + (including layers) +--> <xsl:template mode="forward" match="*[name(.) = 'svg' or name(.) = 'g']"> <xsl:choose> - <xsl:when test="name(.) = 'svg' or @transform or @viewBox or @id or @clip-path or (@style and contains(@style, 'clip-path:url(#')) or (@width and not(contains(@width, '%'))) or @x or @y or (@height and not(contains(@height, '%'))) or *[name(.) = 'linearGradient' or name(.) = 'radialGradient' or name(.) = 'defs' or name(.) = 'clipPath']"> + <xsl:when test="name(.) = 'svg' or @transform or @viewBox or @id or @clip-path or @filter or (@style and contains(@style, 'clip-path:url(#')) or (@width and not(contains(@width, '%'))) or @x or @y or (@height and not(contains(@height, '%'))) or *[name(.) = 'linearGradient' or name(.) = 'radialGradient' or name(.) = 'defs' or name(.) = 'clipPath']"> <Canvas> <xsl:apply-templates mode="id" select="." /> + <xsl:apply-templates mode="filter_effect" select="." /> <!-- <xsl:apply-templates mode="clip" select="." /> --> - <xsl:if test="@style and contains(@style, 'display:none')"><xsl:attribute name="Visibility">Collapsed</xsl:attribute></xsl:if> + <xsl:if test="@style and contains(@style, 'display:none')"> + <xsl:attribute name="Visibility">Collapsed</xsl:attribute> + </xsl:if> <xsl:if test="@style and contains(@style, 'opacity:')"> - <xsl:attribute name="Opacity"> + <xsl:attribute name="Opacity"> <xsl:choose> - <xsl:when test="contains(substring-after(@style, 'opacity:'), ';')"><xsl:value-of select="substring-before(substring-after(@style, 'opacity:'), ';')" /></xsl:when> - <xsl:otherwise><xsl:value-of select="substring-after(@style, 'opacity:')" /></xsl:otherwise> + <xsl:when test="contains(substring-after(@style, 'opacity:'), ';')"> + <xsl:value-of select="substring-before(substring-after(@style, 'opacity:'), ';')" /> + </xsl:when> + <xsl:otherwise> + <xsl:value-of select="substring-after(@style, 'opacity:')" /> + </xsl:otherwise> </xsl:choose> - </xsl:attribute> + </xsl:attribute> </xsl:if> <xsl:if test="@width and not(contains(@width, '%'))"> - <xsl:attribute name="Width"> + <xsl:attribute name="Width"> <xsl:call-template name="convert_unit"> - <xsl:with-param name="convert_value" select="@width" /> + <xsl:with-param name="convert_value" select="@width" /> </xsl:call-template> - </xsl:attribute></xsl:if> - <xsl:if test="@height and not(contains(@height, '%'))"> - <xsl:attribute name="Height"> + </xsl:attribute> + </xsl:if> + <xsl:if test="@height and not(contains(@height, '%'))"> + <xsl:attribute name="Height"> <xsl:call-template name="convert_unit"> - <xsl:with-param name="convert_value" select="@height" /> + <xsl:with-param name="convert_value" select="@height" /> </xsl:call-template> - </xsl:attribute></xsl:if> + </xsl:attribute> + </xsl:if> <xsl:if test="@x"> - <xsl:attribute name="Canvas.Left"> + <xsl:attribute name="Canvas.Left"> <xsl:call-template name="convert_unit"> - <xsl:with-param name="convert_value" select="@x" /> + <xsl:with-param name="convert_value" select="@x" /> </xsl:call-template> - </xsl:attribute></xsl:if> + </xsl:attribute></xsl:if> <xsl:if test="@y"> - <xsl:attribute name="Canvas.Top"> + <xsl:attribute name="Canvas.Top"> <xsl:call-template name="convert_unit"> - <xsl:with-param name="convert_value" select="@y" /> + <xsl:with-param name="convert_value" select="@y" /> </xsl:call-template> - </xsl:attribute></xsl:if> + </xsl:attribute> + </xsl:if> + <xsl:apply-templates mode="resources" select="." /> + <xsl:if test="@viewBox"> - <xsl:variable name="viewBox"><xsl:value-of select="normalize-space(translate(@viewBox, ',', ' '))" /></xsl:variable> - <xsl:attribute name="Width"><xsl:value-of select="substring-before(substring-after(substring-after($viewBox, ' '), ' '), ' ')" /></xsl:attribute> - <xsl:attribute name="Height"><xsl:value-of select="substring-after(substring-after(substring-after($viewBox, ' '), ' '), ' ')" /></xsl:attribute> + <xsl:variable name="viewBox"> + <xsl:value-of select="normalize-space(translate(@viewBox, ',', ' '))" /> + </xsl:variable> + <xsl:attribute name="Width"> + <xsl:value-of select="substring-before(substring-after(substring-after($viewBox, ' '), ' '), ' ')" /> + </xsl:attribute> + <xsl:attribute name="Height"> + <xsl:value-of select="substring-after(substring-after(substring-after($viewBox, ' '), ' '), ' ')" /> + </xsl:attribute> <Canvas.RenderTransform> <TranslateTransform> - <xsl:attribute name="X"><xsl:value-of select="-number(substring-before($viewBox, ' '))" /></xsl:attribute> - <xsl:attribute name="Y"><xsl:value-of select="-number(substring-before(substring-after($viewBox, ' '), ' '))" /></xsl:attribute> + <xsl:attribute name="X"> + <xsl:value-of select="-number(substring-before($viewBox, ' '))" /> + </xsl:attribute> + <xsl:attribute name="Y"> + <xsl:value-of select="-number(substring-before(substring-after($viewBox, ' '), ' '))" /> + </xsl:attribute> </TranslateTransform> </Canvas.RenderTransform> </xsl:if> - <xsl:if test="@transform"> - <Canvas> - <Canvas.RenderTransform> - <TransformGroup><xsl:apply-templates mode="transform" select="." /></TransformGroup> - </Canvas.RenderTransform> - <xsl:apply-templates mode="forward" select="*" /> - </Canvas> - </xsl:if> + <xsl:if test="@transform"> + <xsl:apply-templates mode="transform" select="."> + <xsl:with-param name="mapped_type" select="'Canvas'" /> + </xsl:apply-templates> + <xsl:apply-templates mode="forward" select="*" /> + </xsl:if> <xsl:if test="*[name(.) = 'linearGradient' or name(.) = 'radialGradient' or name(.) = 'defs' or name(.) = 'clipPath']"> <Canvas.Resources> @@ -135,67 +165,383 @@ Everything starts here! --> </xsl:choose> </xsl:template> -<!-- -// Resources (defs) // +<!-- + // Transforms // + All the matrix, translate, rotate... stuff. + Fixme: XAML transforms don't show the same result as SVG ones with the same values. + + * Parse transform + * Apply transform +--> + +<!-- + // Parse transform // +--> +<xsl:template name="parse_transform"> + <xsl:param name="input" /> + <xsl:choose> + + <!-- Matrix transform --> + <xsl:when test="starts-with($input, 'matrix(')"> + <MatrixTransform> + <xsl:attribute name="Matrix"> + <xsl:value-of select="normalize-space(translate(substring-before(substring-after($input, 'matrix('), ')'), ',', ' '))" /> + </xsl:attribute> + </MatrixTransform> + <xsl:call-template name="parse_transform"> + <xsl:with-param name="input" select="substring-after($input, ') ')" /> + </xsl:call-template> + </xsl:when> + + <!-- Scale transform --> + <xsl:when test="starts-with($input, 'scale(')"> + <ScaleTransform> + <xsl:variable name="scale" select="normalize-space(translate(substring-before(substring-after($input, 'scale('), ')'), ',', ' '))" /> + <xsl:choose> + <xsl:when test="contains($scale, ' ')"> + <xsl:attribute name="ScaleX"> + <xsl:value-of select="substring-before($scale, ' ')" /> + </xsl:attribute> + <xsl:attribute name="ScaleY"> + <xsl:value-of select="substring-after($scale, ' ')" /> + </xsl:attribute> + </xsl:when> + <xsl:otherwise> + <xsl:attribute name="ScaleX"> + <xsl:value-of select="$scale" /> + </xsl:attribute> + <xsl:attribute name="ScaleY"> + <xsl:value-of select="$scale" /> + </xsl:attribute> + </xsl:otherwise> + </xsl:choose> + </ScaleTransform> + <xsl:call-template name="parse_transform"> + <xsl:with-param name="input" select="substring-after($input, ') ')" /> + </xsl:call-template> + </xsl:when> + + <!-- Rotate transform --> + <xsl:when test="starts-with($input, 'rotate(')"> + <RotateTransform> + <xsl:attribute name="Angle"> + <xsl:value-of select="normalize-space(translate(substring-before(substring-after($input, 'rotate('), ')'), ',', ' '))" /> + </xsl:attribute> + <xsl:if test="@rx"> + <xsl:attribute name="CenterX"> + <xsl:value-of select="@rx" /> + </xsl:attribute> + </xsl:if> + <xsl:if test="@ry"> + <xsl:attribute name="CenterY"> + <xsl:value-of select="@ry" /> + </xsl:attribute> + </xsl:if> + </RotateTransform> + <xsl:call-template name="parse_transform"> + <xsl:with-param name="input" select="substring-after($input, ') ')" /> + </xsl:call-template> + </xsl:when> + + <!-- Skew transform --> + <xsl:when test="starts-with($input, 'skewX(')"> + <SkewTransform> + <xsl:attribute name="AngleX"> + <xsl:value-of select="normalize-space(translate(substring-before(substring-after($input, 'skewX('), ')'), ',', ' '))" /> + </xsl:attribute> + <xsl:call-template name="parse_transform"> + <xsl:with-param name="input" select="substring-after($input, ') ')" /> + </xsl:call-template> + </SkewTransform> + </xsl:when> + <xsl:when test="starts-with($input, 'skewY(')"> + <SkewTransform> + <xsl:attribute name="AngleY"> + <xsl:value-of select="normalize-space(translate(substring-before(substring-after($input, 'skewY('), ')'), ',', ' '))" /> + </xsl:attribute> + <xsl:call-template name="parse_transform"> + <xsl:with-param name="input" select="substring-after($input, ') ')" /> + </xsl:call-template> + </SkewTransform> + </xsl:when> + + <!-- Translate transform --> + <xsl:when test="starts-with($input, 'translate(')"> + <TranslateTransform> + <xsl:variable name="translate" select="normalize-space(translate(substring-before(substring-after($input, 'translate('), ')'), ',', ' '))" /> + <xsl:choose> + <xsl:when test="contains($translate, ' ')"> + <xsl:attribute name="X"> + <xsl:value-of select="substring-before($translate, ' ')" /> + </xsl:attribute> + <xsl:attribute name="Y"> + <xsl:value-of select="substring-after($translate, ' ')" /> + </xsl:attribute> + </xsl:when> + <xsl:otherwise> + <xsl:attribute name="X"> + <xsl:value-of select="$translate" /> + </xsl:attribute> + </xsl:otherwise> + </xsl:choose> + </TranslateTransform> + <xsl:call-template name="parse_transform"> + <xsl:with-param name="input" select="substring-after($input, ') ')" /> + </xsl:call-template> + </xsl:when> + </xsl:choose> +</xsl:template> + +<!-- + // Apply transform // +--> +<xsl:template mode="transform" match="*"> + <xsl:param name="mapped_type" /> + + <xsl:if test="@transform or @gradientTransform"> + <xsl:variable name="transform"> + <xsl:choose> + <xsl:when test="@transform"> + <xsl:value-of select="@transform" /> + </xsl:when> + <xsl:otherwise> + <xsl:value-of select="@gradientTransform" /> + </xsl:otherwise> + </xsl:choose> + </xsl:variable> + + <xsl:variable name="values" select="normalize-space(translate($transform, ',', ' '))" /> + <xsl:variable name="value1"> + <xsl:choose> + <xsl:when test="contains($values, ') ')"> + <xsl:value-of select="concat(substring-before($values, ') '), ')')" /> + </xsl:when> + <xsl:otherwise> + <xsl:value-of select="$values" /> + </xsl:otherwise> + </xsl:choose> + </xsl:variable> + <xsl:variable name="value2"> + <xsl:if test="substring-after($values, $value1) != ''"> + <xsl:choose> + <xsl:when test="contains(substring-after($values, $value1), ') ')"> + <xsl:value-of select="normalize-space(concat(substring-before(substring-after($values, $value1), ') '), ')'))" /> + </xsl:when> + <xsl:otherwise> + <xsl:value-of select="normalize-space(substring-after($values, $value1))" /> + </xsl:otherwise> + </xsl:choose> + </xsl:if> + </xsl:variable> + <xsl:variable name="value3"> + <xsl:if test="$value2 != '' and substring-after($values, $value2) != ''"> + <xsl:choose> + <xsl:when test="contains(substring-after($values, $value2), ') ')"> + <xsl:value-of select="normalize-space(concat(substring-before(substring-after($values, $value2), ') '), ')'))" /> + </xsl:when> + <xsl:otherwise> + <xsl:value-of select="normalize-space(substring-after($values, $value2))" /> + </xsl:otherwise> + </xsl:choose> + </xsl:if> + </xsl:variable> + + <xsl:variable name="transform_nodes"> + <xsl:if test="$value3 !=''"> + <xsl:call-template name="parse_transform"> + <xsl:with-param name="input" select="$value3" /> + </xsl:call-template> + </xsl:if> + <xsl:if test="$value2 !=''"> + <xsl:call-template name="parse_transform"> + <xsl:with-param name="input" select="$value2" /> + </xsl:call-template> + </xsl:if> + <xsl:if test="$value1 !=''"> + <xsl:call-template name="parse_transform"> + <xsl:with-param name="input" select="$value1" /> + </xsl:call-template> + </xsl:if> + </xsl:variable> + + <xsl:choose> + <xsl:when test="$mapped_type and $mapped_type != '' and not(contains($mapped_type, 'Geometry'))"> + <xsl:element name="{$mapped_type}.RenderTransform"> + <xsl:choose> + <xsl:when test="count(libxslt:node-set($transform_nodes)/*) = 1"> + <xsl:copy-of select="libxslt:node-set($transform_nodes)" /> + </xsl:when> + <xsl:when test="count(libxslt:node-set($transform_nodes)/*) > 1"> + <TransformGroup> + <xsl:copy-of select="libxslt:node-set($transform_nodes)" /> + </TransformGroup> + </xsl:when> + </xsl:choose> + </xsl:element> + </xsl:when> + <xsl:when test="$mapped_type and $mapped_type != '' and contains($mapped_type, 'Geometry')"> + <xsl:element name="{$mapped_type}.Transform"> + <xsl:choose> + <xsl:when test="count(libxslt:node-set($transform_nodes)/*) = 1"> + <xsl:copy-of select="libxslt:node-set($transform_nodes)" /> + </xsl:when> + <xsl:when test="count(libxslt:node-set($transform_nodes)/*) > 1"> + <TransformGroup> + <xsl:copy-of select="libxslt:node-set($transform_nodes)" /> + </TransformGroup> + </xsl:when> + </xsl:choose> + </xsl:element> + </xsl:when> + <xsl:otherwise> + <!-- For instance LinearGradient.Transform --> + <xsl:choose> + <xsl:when test="count(libxslt:node-set($transform_nodes)/*) = 1"> + <xsl:copy-of select="libxslt:node-set($transform_nodes)" /> + </xsl:when> + <xsl:when test="count(libxslt:node-set($transform_nodes)/*) > 1"> + <TransformGroup> + <xsl:copy-of select="libxslt:node-set($transform_nodes)" /> + </TransformGroup> + </xsl:when> + </xsl:choose> + </xsl:otherwise> + </xsl:choose> + </xsl:if> +</xsl:template> -* Resources ids -* Generic defs template -* Generic filters template -* Filter effects -* Linked filter effects -* Linear gradients -* Radial gradients -* Generic gradient stops -* Clipping +<!-- + // Resources (defs) // + + * Resources ids + * Generic defs template + * Generic filters template + * Filter effects + * Linked filter effects + * Absolute gradients + * Linear gradients + * Radial gradients + * Generic gradient stops + * Clipping --> -<!-- Resources ids --> +<!-- + // Resources ids // +--> <xsl:template mode="resources" match="*"> <!-- should be in-depth --> - <xsl:if test="ancestor::*[name(.) = 'defs']"><xsl:attribute name="x:Key"><xsl:value-of select="@id" /></xsl:attribute></xsl:if> + <xsl:if test="parent::*[name(.) = 'defs']"><xsl:attribute name="x:Key"><xsl:value-of select="@id" /></xsl:attribute></xsl:if> </xsl:template> -<!-- Generic defs template --> -<xsl:template mode="forward" match="defs"> +<!-- + // Generic defs template // +--> +<xsl:template mode="forward" match="*[name(.) = 'defs']"> <xsl:apply-templates mode="forward" /> </xsl:template> -<!-- Generic filters template -Limited to one filter (can be improved) --> +<!-- + // Generic filters template // + Limited to one filter (can be improved) +--> <xsl:template mode="forward" match="*[name(.) = 'filter']"> <xsl:if test="count(*) = 1"> <xsl:apply-templates mode="forward" /> </xsl:if> </xsl:template> -<!-- Filter effects --> +<!-- + // GaussianBlur filter effects // + Blur values approximated with d = floor(s * 3*sqrt(2*pi)/4 + 0.5) from: + http://www.w3.org/TR/SVG/filters.html#feGaussianBlurElement + + Not supported by XAML: + * Horizontal and vertical blur. +--> <xsl:template mode="forward" match="*[name(.) = 'feGaussianBlur']"> - <BlurEffect> - <xsl:if test="../@id"><xsl:attribute name="x:Key"><xsl:value-of select="../@id" /></xsl:attribute></xsl:if> - <xsl:if test="@stdDeviation"><xsl:attribute name="Radius"><xsl:value-of select="round(@stdDeviation * 3)" /></xsl:attribute></xsl:if> - </BlurEffect> + <BlurEffect> + <xsl:if test="../@id"><xsl:attribute name="x:Key"><xsl:value-of select="../@id" /></xsl:attribute></xsl:if> + <xsl:if test="@stdDeviation"> + <xsl:variable name="blur" select="normalize-space(translate(@stdDeviation, ',', ' '))" /> + <xsl:choose> + <xsl:when test="not(contains($blur, ' '))"> + <xsl:attribute name="Radius"> + <xsl:value-of select="floor($blur * 1.88 + 0.5)" /> + </xsl:attribute> + </xsl:when> + <xsl:otherwise> + <xsl:attribute name="Radius"> + <xsl:value-of select="floor(substring-before($blur, ' ') * 1.88 + 0.5)" /> + </xsl:attribute> + </xsl:otherwise> + </xsl:choose> + </xsl:if> + </BlurEffect> </xsl:template> -<!-- Linked filter effect --> +<!-- + // Linked filter effect // + Only supports blurs +--> <xsl:template mode="filter_effect" match="*"> -<xsl:choose> + <xsl:choose> <xsl:when test="@filter and starts-with(@filter, 'url(#')"> - <xsl:attribute name="Effect"> - <xsl:value-of select="concat('{StaticResource ', substring-before(substring-after(@filter, 'url(#'), ')'), '}')" /> - </xsl:attribute> + <xsl:attribute name="Effect"> + <xsl:value-of select="concat('{StaticResource ', substring-before(substring-after(@filter, 'url(#'), ')'), '}')" /> + </xsl:attribute> </xsl:when> - <xsl:when test="@style and contains(@style, 'filter:url(#')"> - <xsl:attribute name="Effect"> - <xsl:value-of select="concat('{StaticResource ', substring-before(substring-after(@style, 'filter:url(#'), ')'), '}')" /> - </xsl:attribute> + <xsl:when test="@style and contains(normalize-space(substring-after(translate(@style, '"', ''), 'filter:')), 'url(#')"> + <xsl:attribute name="Effect"> + <xsl:value-of select="concat('{StaticResource ', substring-before(normalize-space(substring-after(substring-after(translate(@style, '"', ''), 'filter:'), 'url(#')), ')'), '}')" /> + </xsl:attribute> </xsl:when> -</xsl:choose> + </xsl:choose> +</xsl:template> + +<!-- + // Absolute gradients // + Get the calling object position in order to substract it from the absolute gradient position. + (XAML absolute gradients values are absolute in the gradient's space). +--> +<xsl:template mode="absolute_gradient" match="*"> + <xsl:param name="position" /> + <xsl:if test="@id"> + <xsl:variable name="id" select="concat('#', @id)"/> + <xsl:variable name="value"> + <xsl:for-each select="//*[contains(@style,$id) or contains(@fill,$id) or contains(@stroke,$id)]"> + <xsl:choose> + <xsl:when test="$position = 'y' and @y"> + <xsl:call-template name="convert_unit"> + <xsl:with-param name="convert_value" select="@y" /> + </xsl:call-template> + </xsl:when> + <xsl:when test="$position = 'x' and @x"> + <xsl:call-template name="convert_unit"> + <xsl:with-param name="convert_value" select="@x" /> + </xsl:call-template> + </xsl:when> + </xsl:choose> + </xsl:for-each> + </xsl:variable> + <xsl:choose> + <xsl:when test="$value != ''"> + <xsl:value-of select="$value"/> + </xsl:when> + <xsl:otherwise>0</xsl:otherwise> + </xsl:choose> + </xsl:if> </xsl:template> -<!-- Linear gradient --> +<!-- + // Linear gradient // +--> <xsl:template mode="forward" match="*[name(.) = 'linearGradient']"> <LinearGradientBrush> - <xsl:if test="@id"><xsl:attribute name="x:Key"><xsl:value-of select="@id" /></xsl:attribute></xsl:if> + <xsl:if test="@id"> + <xsl:attribute name="x:Key"> + <xsl:value-of select="@id" /> + </xsl:attribute> + </xsl:if> <xsl:attribute name="MappingMode"> <xsl:choose> <xsl:when test="@gradientUnits = 'userSpaceOnUse' ">Absolute</xsl:when> @@ -211,28 +557,60 @@ Limited to one filter (can be improved) --> </xsl:choose> </xsl:attribute> </xsl:if> + <xsl:variable name="left"> + <xsl:choose> + <xsl:when test="@gradientUnits = 'userSpaceOnUse' "> + <xsl:apply-templates mode="absolute_gradient" select="."> + <xsl:with-param name="position" select="'x'" /> + </xsl:apply-templates> + </xsl:when> + <xsl:otherwise>0</xsl:otherwise> + </xsl:choose> + </xsl:variable> + <xsl:variable name="top"> + <xsl:choose> + <xsl:when test="@gradientUnits = 'userSpaceOnUse' "> + <xsl:apply-templates mode="absolute_gradient" select="."> + <xsl:with-param name="position" select="'y'" /> + </xsl:apply-templates> + </xsl:when> + <xsl:otherwise>0</xsl:otherwise> + </xsl:choose> + </xsl:variable> <xsl:choose> <xsl:when test="@x1 and @y1 and @x2 and @y2"> <xsl:choose> <xsl:when test="contains(@x1, '%') and contains(@y1, '%')"> - <xsl:attribute name="StartPoint"><xsl:value-of select="concat(substring-before(@x1, '%') div 100, ',', substring-before(@y1,'%') div 100)" /></xsl:attribute> + <xsl:attribute name="StartPoint"> + <xsl:value-of select="concat(substring-before(@x1, '%') div 100, ',', substring-before(@y1,'%') div 100)" /> + </xsl:attribute> </xsl:when> <xsl:otherwise> - <xsl:attribute name="StartPoint"><xsl:value-of select="concat(@x1, ',', @y1)" /></xsl:attribute> + <xsl:attribute name="StartPoint"> + <xsl:value-of select="concat(round((@x1 - $left)), ',', round((@y1 - $top)))" /> + </xsl:attribute> </xsl:otherwise> </xsl:choose> <xsl:choose> <xsl:when test="contains(@x2, '%') and contains(@y2, '%')"> - <xsl:attribute name="EndPoint"><xsl:value-of select="concat(substring-before(@x2, '%') div 100, ',', substring-before(@y2,'%') div 100)" /></xsl:attribute> + <xsl:attribute name="EndPoint"> + <xsl:value-of select="concat(substring-before(@x2, '%') div 100, ',', substring-before(@y2,'%') div 100)" /> + </xsl:attribute> </xsl:when> <xsl:otherwise> - <xsl:attribute name="EndPoint"><xsl:value-of select="concat(@x2, ',', @y2)" /></xsl:attribute> + <xsl:attribute name="EndPoint"> + <xsl:value-of select="concat(round((@x2 - $left)), ',', round((@y2 - $top)))" /> + </xsl:attribute> </xsl:otherwise> </xsl:choose> </xsl:when> <xsl:otherwise> - <xsl:attribute name="StartPoint"><xsl:value-of select="'0,0'" /></xsl:attribute> - <xsl:attribute name="EndPoint"><xsl:value-of select="'1,1'" /></xsl:attribute> + <xsl:attribute name="StartPoint"> + <xsl:value-of select="'0,0'" /> + </xsl:attribute> + <xsl:attribute name="EndPoint"> + <xsl:value-of select="'1,1'" /> + </xsl:attribute> </xsl:otherwise> </xsl:choose> <LinearGradientBrush.GradientStops> @@ -242,22 +620,30 @@ Limited to one filter (can be improved) --> <xsl:variable name="reference_id" select="@xlink:href" /> <xsl:apply-templates mode="forward" select="//*[name(.) = 'linearGradient' and $reference_id = concat('#', @id)]/*" /> </xsl:when> - <xsl:otherwise><xsl:apply-templates mode="forward" /></xsl:otherwise> + <xsl:otherwise> + <xsl:apply-templates mode="forward" /> + </xsl:otherwise> </xsl:choose> </GradientStopCollection> </LinearGradientBrush.GradientStops> <xsl:if test="@gradientTransform"> - <LinearGradientBrush.Transform> - <xsl:apply-templates mode="transform" select="." /> - </LinearGradientBrush.Transform> - </xsl:if> + <LinearGradientBrush.Transform> + <xsl:apply-templates mode="transform" select="." /> + </LinearGradientBrush.Transform> + </xsl:if> </LinearGradientBrush> </xsl:template> -<!-- Radial gradient --> +<!-- + // Radial gradient // +--> <xsl:template mode="forward" match="*[name(.) = 'radialGradient']"> <RadialGradientBrush> - <xsl:if test="@id"><xsl:attribute name="x:Key"><xsl:value-of select="@id" /></xsl:attribute></xsl:if> + <xsl:if test="@id"> + <xsl:attribute name="x:Key"> + <xsl:value-of select="@id" /> + </xsl:attribute> + </xsl:if> <xsl:attribute name="MappingMode"> <xsl:choose> <xsl:when test="@gradientUnits = 'userSpaceOnUse' ">Absolute</xsl:when> @@ -273,6 +659,26 @@ Limited to one filter (can be improved) --> </xsl:choose> </xsl:attribute> </xsl:if> + <xsl:variable name="left"> + <xsl:choose> + <xsl:when test="@gradientUnits = 'userSpaceOnUse' "> + <xsl:apply-templates mode="absolute_gradient" select="."> + <xsl:with-param name="position" select="'x'" /> + </xsl:apply-templates> + </xsl:when> + <xsl:otherwise>0</xsl:otherwise> + </xsl:choose> + </xsl:variable> + <xsl:variable name="top"> + <xsl:choose> + <xsl:when test="@gradientUnits = 'userSpaceOnUse' "> + <xsl:apply-templates mode="absolute_gradient" select="."> + <xsl:with-param name="position" select="'y'" /> + </xsl:apply-templates> + </xsl:when> + <xsl:otherwise>0</xsl:otherwise> + </xsl:choose> + </xsl:variable> <xsl:if test="@cx and @cy"> <xsl:attribute name="Center"> <xsl:choose> @@ -280,7 +686,7 @@ Limited to one filter (can be improved) --> <xsl:value-of select="concat(number(substring-before(@cx, '%')) div 100, ',', number(substring-before(@cy, '%')) div 100)" /> </xsl:when> <xsl:otherwise> - <xsl:value-of select="concat(@cx, ',', @cy)" /> + <xsl:value-of select="concat((@cx - $left), ',', (@cy - $top))" /> </xsl:otherwise> </xsl:choose> </xsl:attribute> @@ -292,7 +698,7 @@ Limited to one filter (can be improved) --> <xsl:value-of select="concat(number(substring-before(@fx, '%')) div 100, ',', number(substring-before(@fy, '%')) div 100)" /> </xsl:when> <xsl:otherwise> - <xsl:value-of select="concat(@fx, ',', @fy)" /> + <xsl:value-of select="concat((@fx - $left), ',', (@fy - $top))" /> </xsl:otherwise> </xsl:choose> </xsl:attribute> @@ -300,12 +706,20 @@ Limited to one filter (can be improved) --> <xsl:if test="@r"> <xsl:choose> <xsl:when test="contains(@r, '%')"> - <xsl:attribute name="RadiusX"><xsl:value-of select="number(substring-before(@r, '%')) div 100" /></xsl:attribute> - <xsl:attribute name="RadiusY"><xsl:value-of select="number(substring-before(@r, '%')) div 100" /></xsl:attribute> + <xsl:attribute name="RadiusX"> + <xsl:value-of select="number(substring-before(@r, '%')) div 100" /> + </xsl:attribute> + <xsl:attribute name="RadiusY"> + <xsl:value-of select="number(substring-before(@r, '%')) div 100" /> + </xsl:attribute> </xsl:when> <xsl:otherwise> - <xsl:attribute name="RadiusX"><xsl:value-of select="@r" /></xsl:attribute> - <xsl:attribute name="RadiusY"><xsl:value-of select="@r" /></xsl:attribute> + <xsl:attribute name="RadiusX"> + <xsl:value-of select="@r" /> + </xsl:attribute> + <xsl:attribute name="RadiusY"> + <xsl:value-of select="@r" /> + </xsl:attribute> </xsl:otherwise> </xsl:choose> </xsl:if> @@ -314,21 +728,25 @@ Limited to one filter (can be improved) --> <xsl:choose> <xsl:when test="@xlink:href"> <xsl:variable name="reference_id" select="@xlink:href" /> - <xsl:apply-templates mode="forward" select="//*[name(.) = 'linearGradient' and $reference_id = concat('#', @id)]/*" /> + <xsl:apply-templates mode="forward" select="//*[name(.) = 'radialGradient' and $reference_id = concat('#', @id)]/*" /> </xsl:when> - <xsl:otherwise><xsl:apply-templates mode="forward" /></xsl:otherwise> + <xsl:otherwise> + <xsl:apply-templates mode="forward" /> + </xsl:otherwise> </xsl:choose> </GradientStopCollection> </RadialGradientBrush.GradientStops> <xsl:if test="@gradientTransform"> - <RadialGradientBrush.Transform> - <xsl:apply-templates mode="transform" select="." /> - </RadialGradientBrush.Transform> + <RadialGradientBrush.Transform> + <xsl:apply-templates mode="transform" select="." /> + </RadialGradientBrush.Transform> </xsl:if> </RadialGradientBrush> </xsl:template> -<!-- Generic gradient stops --> +<!-- + // Gradient stop // +--> <xsl:template mode="forward" match="*[name(.) = 'stop']"> <GradientStop> <!--xsl:apply-templates mode="stop_opacity" select="." /--> @@ -338,37 +756,52 @@ Limited to one filter (can be improved) --> </GradientStop> </xsl:template> -<!-- Clipping --> +<!-- + // Clipping // +--> <xsl:template mode="clip" match="*"> <xsl:choose> - <xsl:when test="@clip-path and defs/clipPath/path/@d"><xsl:attribute name="Clip"><xsl:value-of select="defs/clipPath/path/@d" /></xsl:attribute></xsl:when> - <xsl:when test="@clip-path and starts-with(@clip-path, 'url(#')"><xsl:attribute name="Clip"><xsl:value-of select="concat('{StaticResource ', substring-before(substring-after(@clip-path, 'url(#'), ')'), '}')" /></xsl:attribute></xsl:when> - <xsl:when test="@style and contains(@style, 'clip-path:url(#')"><xsl:attribute name="Clip"><xsl:value-of select="concat('{StaticResource ', substring-before(substring-after(@style, 'url(#'), ')'), '}')" /></xsl:attribute></xsl:when> - <xsl:when test="clipPath"><xsl:apply-templates mode="forward" /></xsl:when> + <xsl:when test="@clip-path and defs/clipPath/path/@d"> + <xsl:attribute name="Clip"> + <xsl:value-of select="defs/clipPath/path/@d" /> + </xsl:attribute> + </xsl:when> + <xsl:when test="@clip-path and starts-with(@clip-path, 'url(#')"> + <xsl:attribute name="Clip"> + <xsl:value-of select="concat('{StaticResource ', substring-before(substring-after(@clip-path, 'url(#'), ')'), '}')" /> + </xsl:attribute> + </xsl:when> + <xsl:when test="@style and contains(@style, 'clip-path:url(#')"> + <xsl:attribute name="Clip"> + <xsl:value-of select="concat('{StaticResource ', substring-before(substring-after(@style, 'url(#'), ')'), '}')" /> + </xsl:attribute> + </xsl:when> + <xsl:when test="clipPath"> + <xsl:apply-templates mode="forward" /> + </xsl:when> </xsl:choose> </xsl:template> <!-- // Misc templates // -* Object description -* Id converter -* Decimal to hexadecimal converter -* Unit to pixel converter -* Title and description -* Misc ignored stuff (markers, patterns, styles) -* Symbols -* Use -* RDF and foreign objects -* Unknows tags + * Id converter + * Decimal to hexadecimal converter + * Unit to pixel converter + * Object description + * Title and description + * Switch + * Symbols + * Use + * RDF and foreign objects + * Misc ignored stuff (markers, patterns, styles) + * Unknows tags --> -<!-- Object description --> -<xsl:template mode="desc" match="*"> - <xsl:if test="*[name(.) = 'desc']/text()"><xsl:attribute name="Tag"><xsl:value-of select="*[name(.) = 'desc']/text()" /></xsl:attribute></xsl:if> -</xsl:template> - -<!-- Id converter. Removes "-" from the original id. --> +<!-- + // Id converter // + Removes "-" from the original id +--> <xsl:template mode="id" match="*"> <xsl:if test="@id"> <xsl:attribute name="Name"><xsl:value-of select="translate(@id, '- ', '')" /></xsl:attribute> @@ -378,94 +811,177 @@ Limited to one filter (can be improved) --> </xsl:if> </xsl:template> -<!-- Decimal to hexadecimal converter --> +<!-- + // Decimal to hexadecimal converter // +--> <xsl:template name="to_hex"> <xsl:param name="convert" /> <xsl:value-of select="concat(substring('0123456789ABCDEF', 1 + floor(round($convert) div 16), 1), substring('0123456789ABCDEF', 1 + round($convert) mod 16, 1))" /> </xsl:template> -<!-- Unit to pixel converter -Values with units (except %) are converted to pixels and rounded. -Unknown units are kept. --> +<!-- + // Unit to pixel converter // + Values with units (except %) are converted to pixels and rounded. + Unknown units are kept. + em, ex and % not implemented +--> <xsl:template name="convert_unit"> <xsl:param name="convert_value" /> - <xsl:choose> - <xsl:when test="contains($convert_value, 'px')"> - <xsl:value-of select="round(translate($convert_value, 'px', ''))" /> - </xsl:when> - <xsl:when test="contains($convert_value, 'pt')"> - <xsl:value-of select="round(translate($convert_value, 'pt', '') * 1.25)" /> - </xsl:when> - <xsl:when test="contains($convert_value, 'pc')"> - <xsl:value-of select="round(translate($convert_value, 'pc', '') * 15)" /> - </xsl:when> - <xsl:when test="contains($convert_value, 'mm')"> - <xsl:value-of select="round(translate($convert_value, 'mm', '') * 3.543307)" /> - </xsl:when> - <xsl:when test="contains($convert_value, 'cm')"> - <xsl:value-of select="round(translate($convert_value, 'cm', '') * 35.43307)" /> - </xsl:when> - <xsl:when test="contains($convert_value, 'in')"> - <xsl:value-of select="round(translate($convert_value, 'in', '') * 90)" /> - </xsl:when> - <xsl:when test="contains($convert_value, 'ft')"> - <xsl:value-of select="round(translate($convert_value, 'ft', '') * 1080)" /> - </xsl:when> - <xsl:when test="not(string(number($convert_value))='NaN')"> - <xsl:value-of select="round($convert_value)" /> - </xsl:when> - <xsl:otherwise> - <xsl:value-of select="$convert_value" /> - </xsl:otherwise> - </xsl:choose> + <xsl:choose> + <xsl:when test="contains($convert_value, 'px')"> + <xsl:value-of select="round(translate($convert_value, 'px', ''))" /> + </xsl:when> + <xsl:when test="contains($convert_value, 'pt')"> + <xsl:value-of select="round(translate($convert_value, 'pt', '') * 1.25)" /> + </xsl:when> + <xsl:when test="contains($convert_value, 'pc')"> + <xsl:value-of select="round(translate($convert_value, 'pc', '') * 15)" /> + </xsl:when> + <xsl:when test="contains($convert_value, 'mm')"> + <xsl:value-of select="round(translate($convert_value, 'mm', '') * 3.543307)" /> + </xsl:when> + <xsl:when test="contains($convert_value, 'cm')"> + <xsl:value-of select="round(translate($convert_value, 'cm', '') * 35.43307)" /> + </xsl:when> + <xsl:when test="contains($convert_value, 'in')"> + <xsl:value-of select="round(translate($convert_value, 'in', '') * 90)" /> + </xsl:when> + <xsl:when test="contains($convert_value, 'ft')"> + <xsl:value-of select="round(translate($convert_value, 'ft', '') * 1080)" /> + </xsl:when> + <xsl:when test="not(string(number($convert_value))='NaN')"> + <xsl:value-of select="round($convert_value)" /> + </xsl:when> + <xsl:otherwise> + <xsl:value-of select="$convert_value" /> + </xsl:otherwise> + </xsl:choose> </xsl:template> -<!-- Title and description -Blank template. Title is ignored and desc is converted to Tag in the mode="desc" template +<!-- + // Object description // +--> +<xsl:template mode="desc" match="*"> + <xsl:if test="*[name(.) = 'desc']/text()"> + <xsl:attribute name="Tag"> + <xsl:value-of select="*[name(.) = 'desc']/text()" /> + </xsl:attribute> + </xsl:if> +</xsl:template> + +<!-- + // Title and description // + Title is ignored and desc is converted to Tag in the mode="desc" template --> <xsl:template mode="forward" match="*[name(.) = 'title' or name(.) = 'desc']"> - <!-- --> + </xsl:template> -<!-- Misc ignored stuff (markers, patterns, styles) --> -<xsl:template mode="forward" match="*[name(.) = 'marker' or name(.) = 'pattern' or name(.) = 'style']"> - <!-- --> +<!-- + // Switch // +--> +<xsl:template mode="forward" match="*[name(.) = 'switch']"> + <xsl:apply-templates mode="forward" /> </xsl:template> -<!-- Symbols --> +<!-- + // Symbols // +--> <xsl:template mode="forward" match="*[name(.) = 'symbol']"> <Style> - <xsl:if test="@id"><xsl:attribute name="x:Key"><xsl:value-of select="@id" /></xsl:attribute></xsl:if> + <xsl:if test="@id"> + <xsl:attribute name="x:Key"> + <xsl:value-of select="@id" /> + </xsl:attribute> + </xsl:if> <Canvas> <xsl:apply-templates mode="forward" /> </Canvas> </Style> </xsl:template> -<!-- Use --> +<!-- + // Use // + (since it is not supported by Inkscape, not implemented yet) +--> <xsl:template mode="forward" match="*[name(.) = 'use']"> +<!-- Errors when more than one use element share the same reference <Canvas> - <xsl:if test="@xlink:href"><xsl:attribute name="Style"><xsl:value-of select="@xlink:href" /></xsl:attribute></xsl:if> - <!--xsl:apply-templates mode="transform" select="." /--> - <xsl:apply-templates mode="forward" /> + <xsl:if test="@width and not(contains(@width, '%'))"> + <xsl:attribute name="Width"> + <xsl:call-template name="convert_unit"> + <xsl:with-param name="convert_value" select="@width" /> + </xsl:call-template> + </xsl:attribute> + </xsl:if> + <xsl:if test="@height and not(contains(@height, '%'))"> + <xsl:attribute name="Height"> + <xsl:call-template name="convert_unit"> + <xsl:with-param name="convert_value" select="@height" /> + </xsl:call-template> + </xsl:attribute> + </xsl:if> + <xsl:if test="@x"> + <xsl:attribute name="Canvas.Left"> + <xsl:call-template name="convert_unit"> + <xsl:with-param name="convert_value" select="@x" /> + </xsl:call-template> + </xsl:attribute></xsl:if> + <xsl:if test="@y"> + <xsl:attribute name="Canvas.Top"> + <xsl:call-template name="convert_unit"> + <xsl:with-param name="convert_value" select="@y" /> + </xsl:call-template> + </xsl:attribute> + </xsl:if> + + <StaticResource> + <xsl:if test="@xlink:href"> + <xsl:attribute name="ResourceKey"> + <xsl:value-of select="substring-after(@xlink:href, '#')" /> + </xsl:attribute> + </xsl:if> + <xsl:apply-templates mode="forward" /> + </StaticResource> </Canvas> + --> </xsl:template> -<!-- RDF and foreign objects --> +<!-- + // RDF and foreign objects // +--> <xsl:template mode="forward" match="rdf:RDF | *[name(.) = 'foreignObject']"> - <!-- --> + +</xsl:template> + +<!-- + // Misc ignored stuff (markers, patterns, styles) // +--> +<xsl:template mode="forward" match="*[name(.) = 'marker' or name(.) = 'pattern' or name(.) = 'style']"> + </xsl:template> -<!-- Unknown tags --> +<!-- + // Unknown tags // + With generic and mode="forward" templates +--> <xsl:template match="*"> -<xsl:comment><xsl:value-of select="concat('Unknown tag: ', name(.))" /></xsl:comment> + <xsl:comment> + <xsl:value-of select="concat('Unknown tag: ', name(.))" /> + </xsl:comment> </xsl:template> +<xsl:template mode="forward" match="*"> + <xsl:comment> + <xsl:value-of select="concat('Unknown tag: ', name(.))" /> + </xsl:comment> +</xsl:template> <!-- // Colors and patterns // * Generic color template +* Object opacity * Fill * Fill opacity * Fill rule @@ -484,38 +1000,87 @@ Blank template. Title is ignored and desc is converted to Tag in the mode="desc" * Gradient stop * Gradient stop opacity * Gradient stop offset +* Image stretch --> -<!-- Generic color template --> +<!-- + // Generic color template // +--> <xsl:template name="template_color"> <xsl:param name="colorspec" /> <xsl:param name="opacityspec" /> <xsl:choose> <xsl:when test="starts-with($colorspec, 'rgb(') and not(contains($colorspec , '%'))"> <xsl:value-of select="'#'" /> - <xsl:if test="$opacityspec != '' and number($opacityspec) != 1"><xsl:call-template name="to_hex"><xsl:with-param name="convert"><xsl:value-of select="round(number($opacityspec) * 255)" /></xsl:with-param></xsl:call-template></xsl:if> - <xsl:call-template name="to_hex"><xsl:with-param name="convert"><xsl:value-of select="substring-before(substring-after($colorspec, 'rgb('), ',')" /></xsl:with-param></xsl:call-template> - <xsl:call-template name="to_hex"><xsl:with-param name="convert"><xsl:value-of select="substring-before(substring-after(substring-after($colorspec, 'rgb('), ','), ',')" /></xsl:with-param></xsl:call-template> - <xsl:call-template name="to_hex"><xsl:with-param name="convert"><xsl:value-of select="substring-before(substring-after(substring-after(substring-after($colorspec, 'rgb('), ','), ','), ')')" /></xsl:with-param></xsl:call-template> + <xsl:if test="$opacityspec != '' and number($opacityspec) != 1"> + <xsl:call-template name="to_hex"> + <xsl:with-param name="convert"> + <xsl:value-of select="round(number($opacityspec) * 255)" /> + </xsl:with-param> + </xsl:call-template> + </xsl:if> + <xsl:call-template name="to_hex"> + <xsl:with-param name="convert"> + <xsl:value-of select="substring-before(substring-after($colorspec, 'rgb('), ',')" /> + </xsl:with-param> + </xsl:call-template> + <xsl:call-template name="to_hex"> + <xsl:with-param name="convert"> + <xsl:value-of select="substring-before(substring-after(substring-after($colorspec, 'rgb('), ','), ',')" /> + </xsl:with-param> + </xsl:call-template> + <xsl:call-template name="to_hex"> + <xsl:with-param name="convert"> + <xsl:value-of select="substring-before(substring-after(substring-after(substring-after($colorspec, 'rgb('), ','), ','), ')')" /> + </xsl:with-param> + </xsl:call-template> </xsl:when> <xsl:when test="starts-with($colorspec, 'rgb(') and contains($colorspec , '%')"> <xsl:value-of select="'#'" /> - <xsl:if test="$opacityspec != '' and number($opacityspec) != 1"><xsl:call-template name="to_hex"><xsl:with-param name="convert"><xsl:value-of select="round(number($opacityspec) * 255)" /></xsl:with-param></xsl:call-template></xsl:if> - <xsl:call-template name="to_hex"><xsl:with-param name="convert"><xsl:value-of select="number(substring-before(substring-after($colorspec, 'rgb('), '%,')) * 255 div 100" /></xsl:with-param></xsl:call-template> - <xsl:call-template name="to_hex"><xsl:with-param name="convert"><xsl:value-of select="number(substring-before(substring-after(substring-after($colorspec, 'rgb('), ','), '%,')) * 255 div 100" /></xsl:with-param></xsl:call-template> - <xsl:call-template name="to_hex"><xsl:with-param name="convert"><xsl:value-of select="number(substring-before(substring-after(substring-after(substring-after($colorspec, 'rgb('), ','), ','), '%)')) * 255 div 100" /></xsl:with-param></xsl:call-template> + <xsl:if test="$opacityspec != '' and number($opacityspec) != 1"> + <xsl:call-template name="to_hex"> + <xsl:with-param name="convert"> + <xsl:value-of select="round(number($opacityspec) * 255)" /> + </xsl:with-param> + </xsl:call-template> + </xsl:if> + <xsl:call-template name="to_hex"> + <xsl:with-param name="convert"> + <xsl:value-of select="number(substring-before(substring-after($colorspec, 'rgb('), '%,')) * 255 div 100" /> + </xsl:with-param> + </xsl:call-template> + <xsl:call-template name="to_hex"> + <xsl:with-param name="convert"> + <xsl:value-of select="number(substring-before(substring-after(substring-after($colorspec, 'rgb('), ','), '%,')) * 255 div 100" /> + </xsl:with-param> + </xsl:call-template> + <xsl:call-template name="to_hex"> + <xsl:with-param name="convert"> + <xsl:value-of select="number(substring-before(substring-after(substring-after(substring-after($colorspec, 'rgb('), ','), ','), '%)')) * 255 div 100" /> + </xsl:with-param> + </xsl:call-template> </xsl:when> <xsl:when test="starts-with($colorspec, '#')"> <xsl:value-of select="'#'" /> - <xsl:if test="$opacityspec != ''"><xsl:call-template name="to_hex"><xsl:with-param name="convert"><xsl:value-of select="round(number($opacityspec) * 255)" /></xsl:with-param></xsl:call-template></xsl:if> + <xsl:if test="$opacityspec != ''"> + <xsl:call-template name="to_hex"> + <xsl:with-param name="convert"> + <xsl:value-of select="round(number($opacityspec) * 255)" /> + </xsl:with-param> + </xsl:call-template> + </xsl:if> <xsl:choose> <xsl:when test="string-length(substring-after($colorspec, '#')) = 3"> - <xsl:variable name="colorspec3"><xsl:value-of select="translate(substring-after($colorspec, '#'), 'abcdefgh', 'ABCDEFGH')" /></xsl:variable> + <xsl:variable name="colorspec3"> + <xsl:value-of select="translate(substring-after($colorspec, '#'), 'abcdefgh', 'ABCDEFGH')" /> + </xsl:variable> <xsl:value-of select="concat(substring($colorspec3, 1, 1), substring($colorspec3, 1, 1))" /> <xsl:value-of select="concat(substring($colorspec3, 2, 1), substring($colorspec3, 2, 1))" /> <xsl:value-of select="concat(substring($colorspec3, 3, 1), substring($colorspec3, 3, 1))" /> </xsl:when> - <xsl:otherwise><xsl:value-of select="translate(substring-after($colorspec, '#'), 'abcdefgh', 'ABCDEFGH')" /></xsl:otherwise> + <xsl:otherwise> + <xsl:value-of select="translate(substring-after($colorspec, '#'), 'abcdefgh', 'ABCDEFGH')" /> + </xsl:otherwise> </xsl:choose> </xsl:when> <xsl:otherwise> @@ -523,68 +1088,184 @@ Blank template. Title is ignored and desc is converted to Tag in the mode="desc" <xsl:choose> <xsl:when test="$named_color_hex and $named_color_hex != ''"> <xsl:value-of select="'#'" /> - <xsl:if test="$opacityspec != '' and number($opacityspec) != 1"><xsl:call-template name="to_hex"><xsl:with-param name="convert"><xsl:value-of select="number($opacityspec) * 255" /></xsl:with-param></xsl:call-template></xsl:if> + <xsl:if test="$opacityspec != '' and number($opacityspec) != 1"> + <xsl:call-template name="to_hex"> + <xsl:with-param name="convert"> + <xsl:value-of select="number($opacityspec) * 255" /> + </xsl:with-param> + </xsl:call-template> + </xsl:if> <xsl:value-of select="substring-after($named_color_hex, '#')" /> </xsl:when> - <xsl:otherwise><xsl:value-of select="$colorspec" /></xsl:otherwise> + <xsl:otherwise> + <xsl:value-of select="$colorspec" /> + </xsl:otherwise> </xsl:choose> </xsl:otherwise> </xsl:choose> </xsl:template> -<!-- Fill --> +<!-- + // Object opacity // +--> +<xsl:template mode="object_opacity" match="*"> + <xsl:if test="@opacity or (@style and (contains(@style, ';opacity:') or starts-with(@style, 'opacity:')))"> + <xsl:variable name="value"> + <xsl:choose> + <xsl:when test="@opacity"> + <xsl:value-of select="@opacity" /> + </xsl:when> + <xsl:when test="@style and contains(@style, ';opacity:')"> + <xsl:variable name="Opacity" select="substring-after(@style, ';opacity:')" /> + <xsl:choose> + <xsl:when test="contains($Opacity, ';')"> + <xsl:value-of select="substring-before($Opacity, ';')" /> + </xsl:when> + <xsl:otherwise> + <xsl:value-of select="$Opacity" /> + </xsl:otherwise> + </xsl:choose> + </xsl:when> + <xsl:when test="@style and starts-with(@style, 'opacity:')"> + <xsl:variable name="Opacity" select="substring-after(@style, 'opacity:')" /> + <xsl:choose> + <xsl:when test="contains($Opacity, ';')"> + <xsl:value-of select="substring-before($Opacity, ';')" /> + </xsl:when> + <xsl:otherwise> + <xsl:value-of select="$Opacity" /> + </xsl:otherwise> + </xsl:choose> + </xsl:when> + <xsl:when test="name(..) = 'g' or name(..) = 'svg'"> + <xsl:apply-templates mode="object_opacity" select="parent::*" /> + </xsl:when> + <xsl:otherwise>1</xsl:otherwise> + </xsl:choose> + </xsl:variable> + <xsl:attribute name="Opacity"> + <xsl:choose> + <xsl:when test="$value < 0">0</xsl:when> + <xsl:when test="$value > 1">1</xsl:when> + <xsl:otherwise> + <xsl:value-of select="$value" /> + </xsl:otherwise> + </xsl:choose> + </xsl:attribute> + </xsl:if> +</xsl:template> + +<!-- + // Fill // +--> <xsl:template mode="fill" match="*"> - <xsl:choose> - <xsl:when test="@fill and starts-with(@fill, 'url(#')"><xsl:value-of select="concat('{StaticResource ', substring-before(substring-after(@fill, 'url(#'), ')'), '}')" /></xsl:when> - <xsl:when test="@fill"><xsl:value-of select="@fill" /></xsl:when> - <xsl:when test="@style and contains(@style, 'fill:') and starts-with(substring-after(@style, 'fill:'), 'url(#')"><xsl:value-of select="concat('{StaticResource ', substring-before(substring-after(@style, 'url(#'), ')'), '}')" /></xsl:when> - <xsl:when test="@style and contains(@style, 'fill:')"> - <xsl:variable name="Fill" select="substring-after(@style, 'fill:')" /> - <xsl:choose> - <xsl:when test="contains($Fill, ';')"> - <xsl:value-of select="substring-before($Fill, ';')" /> - </xsl:when> - <xsl:otherwise><xsl:value-of select="$Fill" /></xsl:otherwise> - </xsl:choose> - </xsl:when> - <xsl:when test="name(..) = 'g' or name(..) = 'svg'"><xsl:apply-templates mode="fill" select="parent::*"/></xsl:when> - </xsl:choose> + <xsl:variable name="value"> + <xsl:choose> + <xsl:when test="@fill and starts-with(normalize-space(translate(@fill, '"', '')), 'url(#')"> + <!-- Removes unwanted characters in the color link (TODO: export to a specific template)--> + <xsl:value-of select="concat('{StaticResource ', substring-before(substring-after(normalize-space(translate(@fill, '"', '')), 'url(#'), ')'), '}')" /> + </xsl:when> + <xsl:when test="@fill"> + <xsl:value-of select="normalize-space(@fill)" /> + </xsl:when> + <xsl:when test="@style and contains(@style, 'fill:') and starts-with(normalize-space(substring-after(translate(@style, '"', ''), 'fill:')), 'url(#')"> + <xsl:value-of select="concat('{StaticResource ', substring-before(normalize-space(substring-after(substring-after(translate(@style, '"', ''), 'fill:'), 'url(#')), ')'), '}')" /> + </xsl:when> + <xsl:when test="@style and contains(@style, 'fill:')"> + <xsl:variable name="Fill" select="normalize-space(substring-after(@style, 'fill:'))" /> + <xsl:choose> + <xsl:when test="contains($Fill, ';')"> + <xsl:value-of select="substring-before($Fill, ';')" /> + </xsl:when> + <xsl:otherwise> + <xsl:value-of select="$Fill" /> + </xsl:otherwise> + </xsl:choose> + </xsl:when> + <xsl:when test="name(..) = 'g' or name(..) = 'svg'"> + <xsl:apply-templates mode="fill" select="parent::*"/> + </xsl:when> + </xsl:choose> + </xsl:variable> + <xsl:if test="$value"> + <xsl:value-of select="$value" /> + </xsl:if> </xsl:template> -<!-- Fill opacity --> +<!-- + // Fill opacity // +--> <xsl:template mode="fill_opacity" match="*"> + <xsl:variable name="value"> <xsl:choose> - <xsl:when test="@fill-opacity"><xsl:value-of select="@fill-opacity" /></xsl:when> + <xsl:when test="@fill-opacity"> + <xsl:value-of select="normalize-space(@fill-opacity)" /> + </xsl:when> <xsl:when test="@style and contains(@style, 'fill-opacity:')"> - <xsl:variable name="Opacity" select="substring-after(@style, 'fill-opacity:')" /> + <xsl:variable name="Opacity" select="normalize-space(substring-after(@style, 'fill-opacity:'))" /> <xsl:choose> - <xsl:when test="contains($Opacity, ';')"><xsl:value-of select="substring-before($Opacity, ';')" /></xsl:when> - <xsl:otherwise><xsl:value-of select="$Opacity" /></xsl:otherwise> + <xsl:when test="contains($Opacity, ';')"> + <xsl:value-of select="substring-before($Opacity, ';')" /> + </xsl:when> + <xsl:otherwise> + <xsl:value-of select="$Opacity" /> + </xsl:otherwise> </xsl:choose> </xsl:when> - <xsl:when test="name(..) = 'g' or name(..) = 'svg'"><xsl:apply-templates mode="fill_opacity" select="parent::*" /></xsl:when> + <xsl:when test="name(..) = 'g' or name(..) = 'svg'"> + <xsl:apply-templates mode="fill_opacity" select="parent::*" /> + </xsl:when> + <xsl:otherwise>1</xsl:otherwise> + </xsl:choose> + </xsl:variable> + <xsl:choose> + <xsl:when test="$value < 0">0</xsl:when> + <xsl:when test="$value > 1">1</xsl:when> + <xsl:otherwise> + <xsl:value-of select="$value" /> + </xsl:otherwise> </xsl:choose> </xsl:template> -<!-- Fill rule --> +<!-- + // Fill rule // +--> <xsl:template mode="fill_rule" match="*"> <xsl:choose> - <xsl:when test="@fill-rule and (@fill-rule = 'nonzero' or @fill-rule = 'evenodd')"><xsl:attribute name="FillRule"><xsl:value-of select="@fill-rule" /></xsl:attribute></xsl:when> + <xsl:when test="@fill-rule and (@fill-rule = 'nonzero' or @fill-rule = 'evenodd')"> + <xsl:attribute name="FillRule"> + <xsl:value-of select="normalize-space(@fill-rule)" /> + </xsl:attribute> + </xsl:when> <xsl:when test="@style and contains(@style, 'fill-rule:')"> - <xsl:variable name="FillRule" select="substring-after(@style, 'fill-rule:')" /> + <xsl:variable name="FillRule" select="normalize-space(substring-after(@style, 'fill-rule:'))" /> <xsl:choose> <xsl:when test="contains($FillRule, ';')"> - <xsl:if test="substring-before($FillRule, ';') = 'nonzero' or substring-before($FillRule, ';') = 'evenodd'"><xsl:attribute name="FillRule"><xsl:value-of select="substring-before($FillRule, ';')" /></xsl:attribute></xsl:if> + <xsl:if test="substring-before($FillRule, ';') = 'nonzero' or substring-before($FillRule, ';') = 'evenodd'"> + <xsl:attribute name="FillRule"> + <xsl:value-of select="substring-before($FillRule, ';')" /> + </xsl:attribute> + </xsl:if> + </xsl:when> + <xsl:when test="$FillRule = 'nonzero' or $FillRule = 'evenodd'"> + <xsl:attribute name="FillRule"> + <xsl:value-of select="$FillRule" /> + </xsl:attribute> </xsl:when> - <xsl:when test="$FillRule = 'nonzero' or $FillRule = 'evenodd'"><xsl:attribute name="FillRule"><xsl:value-of select="$FillRule" /></xsl:attribute></xsl:when> </xsl:choose> </xsl:when> - <xsl:when test="name(..) = 'g' or name(..) = 'svg'"><xsl:apply-templates mode="fill_rule" select="parent::*"/></xsl:when> - <xsl:otherwise><xsl:attribute name="FillRule">NonZero</xsl:attribute></xsl:otherwise> + <xsl:when test="name(..) = 'g' or name(..) = 'svg'"> + <xsl:apply-templates mode="fill_rule" select="parent::*"/> + </xsl:when> + <xsl:otherwise> + <xsl:attribute name="FillRule">NonZero</xsl:attribute> + </xsl:otherwise> </xsl:choose> </xsl:template> -<!-- Generic fill template --> +<!-- + // Generic fill template // +--> <xsl:template mode="template_fill" match="*"> <xsl:variable name="fill"><xsl:apply-templates mode="fill" select="." /></xsl:variable> <xsl:variable name="fill_opacity"><xsl:apply-templates mode="fill_opacity" select="." /></xsl:variable> @@ -594,9 +1275,13 @@ Blank template. Title is ignored and desc is converted to Tag in the mode="desc" <xsl:when test="$fill != ''"> <xsl:call-template name="template_color"> <xsl:with-param name="colorspec"> - <xsl:if test="$fill != 'none'"><xsl:value-of select="$fill" /></xsl:if> + <xsl:if test="$fill != 'none'"> + <xsl:value-of select="$fill" /> + </xsl:if> + </xsl:with-param> + <xsl:with-param name="opacityspec"> + <xsl:value-of select="$fill_opacity" /> </xsl:with-param> - <xsl:with-param name="opacityspec"><xsl:value-of select="$fill_opacity" /></xsl:with-param> </xsl:call-template> </xsl:when> <xsl:otherwise>#000000</xsl:otherwise> @@ -605,129 +1290,250 @@ Blank template. Title is ignored and desc is converted to Tag in the mode="desc" </xsl:if> </xsl:template> -<!-- Stroke --> +<!-- + // Stroke // +--> <xsl:template mode="stroke" match="*"> <xsl:choose> - <xsl:when test="@stroke and starts-with(@stroke, 'url(#')"><xsl:value-of select="concat('{StaticResource ', substring-before(substring-after(@stroke, 'url(#'), ')'), '}')" /></xsl:when> - <xsl:when test="@stroke and @stroke != 'none'"><xsl:value-of select="@stroke" /></xsl:when> - <xsl:when test="@style and contains(@style, 'stroke:') and starts-with(substring-after(@style, 'stroke:'), 'url(#')"><xsl:value-of select="concat('{StaticResource ', substring-before(substring-after(@style, 'url(#'), ')'), '}')" /></xsl:when> + <xsl:when test="@stroke and starts-with(@stroke, 'url(#')"> + <!-- Removes unwanted characters in the color link (TODO: export to a specific template)--> + <xsl:value-of select="concat('{StaticResource ', substring-before(substring-after(normalize-space(translate(@stroke, '"', '')), 'url(#'), ')'), '}')" /> + </xsl:when> + <xsl:when test="@stroke and normalize-space(@stroke) != 'none'"> + <xsl:value-of select="@stroke" /> + </xsl:when> + <xsl:when test="@style and contains(@style, 'stroke:') and starts-with(normalize-space(substring-after(translate(@style, '"', ''), 'stroke:')), 'url(#')"> + <xsl:value-of select="concat('{StaticResource ', substring-before(normalize-space(substring-after(substring-after(translate(@style, '"', ''), 'stroke:'), 'url(#')), ')'), '}')" /> + </xsl:when> <xsl:when test="@style and contains(@style, 'stroke:')"> - <xsl:variable name="Stroke" select="substring-after(@style, 'stroke:')" /> + <xsl:variable name="Stroke" select="normalize-space(substring-after(@style, 'stroke:'))" /> <xsl:choose> <xsl:when test="contains($Stroke, ';')"> - <xsl:if test="substring-before($Stroke, ';') != 'none'"><xsl:value-of select="substring-before($Stroke, ';')" /></xsl:if> + <xsl:if test="substring-before($Stroke, ';') != 'none'"> + <xsl:value-of select="substring-before($Stroke, ';')" /> + </xsl:if> + </xsl:when> + <xsl:when test="$Stroke != 'none'"> + <xsl:value-of select="$Stroke" /> </xsl:when> - <xsl:when test="$Stroke != 'none'"><xsl:value-of select="$Stroke" /></xsl:when> </xsl:choose> </xsl:when> - <xsl:when test="name(..) = 'g' or name(..) = 'svg'"><xsl:apply-templates mode="stroke" select="parent::*"/></xsl:when> + <xsl:when test="name(..) = 'g' or name(..) = 'svg'"> + <xsl:apply-templates mode="stroke" select="parent::*"/> + </xsl:when> </xsl:choose> </xsl:template> -<!-- Stroke opacity --> +<!-- + // Stroke opacity // +--> <xsl:template mode="stroke_opacity" match="*"> + <xsl:variable name="value"> <xsl:choose> - <xsl:when test="@stroke-opacity"><xsl:value-of select="@stroke-opacity" /></xsl:when> + <xsl:when test="@stroke-opacity"> + <xsl:value-of select="@stroke-opacity" /> + </xsl:when> <xsl:when test="@style and contains(@style, 'stroke-opacity:')"> <xsl:variable name="Opacity" select="substring-after(@style, 'stroke-opacity:')" /> <xsl:choose> - <xsl:when test="contains($Opacity, ';')"><xsl:value-of select="substring-before($Opacity, ';')" /></xsl:when> - <xsl:otherwise><xsl:value-of select="$Opacity" /></xsl:otherwise> + <xsl:when test="contains($Opacity, ';')"> + <xsl:value-of select="substring-before($Opacity, ';')" /> + </xsl:when> + <xsl:otherwise> + <xsl:value-of select="$Opacity" /> + </xsl:otherwise> </xsl:choose> </xsl:when> - <xsl:when test="name(..) = 'g' or name(..) = 'svg'"><xsl:apply-templates mode="stroke_opacity" select="parent::*" /></xsl:when> + <xsl:when test="name(..) = 'g' or name(..) = 'svg'"> + <xsl:apply-templates mode="stroke_opacity" select="parent::*" /> + </xsl:when> + <xsl:otherwise>1</xsl:otherwise> + </xsl:choose> + </xsl:variable> + <xsl:choose> + <xsl:when test="$value < 0">0</xsl:when> + <xsl:when test="$value > 1">1</xsl:when> + <xsl:otherwise> + <xsl:value-of select="$value" /> + </xsl:otherwise> </xsl:choose> </xsl:template> -<!-- Generic stroke template --> +<!-- + // Generic stroke template // + --> <xsl:template mode="template_stroke" match="*"> - <xsl:variable name="stroke"><xsl:apply-templates mode="stroke" select="." /></xsl:variable> - <xsl:variable name="stroke_opacity"><xsl:apply-templates mode="stroke_opacity" select="." /></xsl:variable> + <xsl:variable name="stroke"> + <xsl:apply-templates mode="stroke" select="." /> + </xsl:variable> + <xsl:variable name="stroke_opacity"> + <xsl:apply-templates mode="stroke_opacity" select="." /> + </xsl:variable> + <xsl:variable name="stroke_width"> + <xsl:apply-templates mode="stroke_width" select="." /> + </xsl:variable> + + <xsl:if test="$stroke_width != ''"> + <xsl:attribute name="StrokeThickness"> + <xsl:value-of select="$stroke_width" /> + </xsl:attribute> + </xsl:if> <xsl:if test="$stroke != ''"> <xsl:attribute name="Stroke"> <xsl:call-template name="template_color"> - <xsl:with-param name="colorspec"><xsl:value-of select="$stroke" /></xsl:with-param> - <xsl:with-param name="opacityspec"><xsl:value-of select="$stroke_opacity" /></xsl:with-param> + <xsl:with-param name="colorspec"> + <xsl:value-of select="$stroke" /> + </xsl:with-param> + <xsl:with-param name="opacityspec"> + <xsl:value-of select="$stroke_opacity" /> + </xsl:with-param> </xsl:call-template> </xsl:attribute> </xsl:if> </xsl:template> -<!-- Stroke width --> +<!-- + // Stroke width // +--> <xsl:template mode="stroke_width" match="*"> <xsl:choose> <xsl:when test="@stroke-width"> - <xsl:attribute name="StrokeThickness"><xsl:value-of select="@stroke-width" /></xsl:attribute> + <xsl:call-template name="convert_unit"> + <xsl:with-param name="convert_value"> + <xsl:value-of select="@stroke-width" /> + </xsl:with-param> + </xsl:call-template> </xsl:when> <xsl:when test="@style and contains(@style, 'stroke-width:')"> - <xsl:attribute name="StrokeThickness"> - <xsl:call-template name="convert_unit"> - <xsl:with-param name="convert_value"> - <xsl:choose> - <xsl:when test="contains(substring-after(@style, 'stroke-width:'), ';')"><xsl:value-of select="substring-before(substring-after(@style, 'stroke-width:'), ';')" /></xsl:when> - <xsl:otherwise><xsl:value-of select="substring-after(@style, 'stroke-width:')" /></xsl:otherwise> - </xsl:choose> - </xsl:with-param> - </xsl:call-template> - </xsl:attribute> + <xsl:call-template name="convert_unit"> + <xsl:with-param name="convert_value"> + <xsl:choose> + <xsl:when test="contains(substring-after(@style, 'stroke-width:'), ';')"> + <xsl:value-of select="substring-before(substring-after(@style, 'stroke-width:'), ';')" /> + </xsl:when> + <xsl:otherwise> + <xsl:value-of select="substring-after(@style, 'stroke-width:')" /> + </xsl:otherwise> + </xsl:choose> + </xsl:with-param> + </xsl:call-template> + </xsl:when> + <xsl:when test="name(..) = 'g' or name(..) = 'svg'"> + <xsl:apply-templates mode="stroke_width" select="parent::*"/> </xsl:when> - <xsl:when test="name(..) = 'g' or name(..) = 'svg'"><xsl:apply-templates mode="stroke_width" select="parent::*"/></xsl:when> </xsl:choose> </xsl:template> -<!-- Stroke miterlimit --> +<!-- + // Stroke miterlimit // +--> <xsl:template mode="stroke_miterlimit" match="*"> <xsl:choose> - <xsl:when test="@stroke-miterlimit"><xsl:attribute name="StrokeMiterLimit"><xsl:value-of select="@stroke-miterlimit" /></xsl:attribute></xsl:when> + <xsl:when test="@stroke-miterlimit"> + <xsl:attribute name="StrokeMiterLimit"> + <xsl:value-of select="normalize-space(@stroke-miterlimit)" /> + </xsl:attribute> + </xsl:when> <xsl:when test="@style and contains(@style, 'stroke-miterlimit:')"> - <xsl:variable name="StrokeMiterLimit" select="substring-after(@style, 'stroke-miterlimit:')" /> + <xsl:variable name="StrokeMiterLimit" select="normalize-space(substring-after(@style, 'stroke-miterlimit:'))" /> <xsl:attribute name="StrokeMiterLimit"> <xsl:choose> - <xsl:when test="contains($StrokeMiterLimit, ';')"><xsl:value-of select="substring-before($StrokeMiterLimit, ';')" /></xsl:when> - <xsl:otherwise><xsl:value-of select="$StrokeMiterLimit" /></xsl:otherwise> + <xsl:when test="contains($StrokeMiterLimit, ';')"> + <xsl:value-of select="substring-before($StrokeMiterLimit, ';')" /> + </xsl:when> + <xsl:otherwise> + <xsl:value-of select="$StrokeMiterLimit" /> + </xsl:otherwise> </xsl:choose> </xsl:attribute> </xsl:when> - <xsl:when test="name(..) = 'g' or name(..) = 'svg'"><xsl:apply-templates mode="stroke_miterlimit" select="parent::*"/></xsl:when> + <xsl:when test="name(..) = 'g' or name(..) = 'svg'"> + <xsl:apply-templates mode="stroke_miterlimit" select="parent::*"/> + </xsl:when> </xsl:choose> </xsl:template> -<!-- Stroke dasharray --> +<!-- + // Stroke dasharray // +--> <xsl:template mode="stroke_dasharray" match="*"> <!-- stroke-dasharray="10,30,20,30" becomes StrokeDashArray="1 3 2 3" ?? --> <xsl:choose> - <xsl:when test="@stroke-dasharray and @stroke-dasharray != 'none'"><xsl:attribute name="StrokeDashArray"><xsl:value-of select="@stroke-dasharray" /></xsl:attribute></xsl:when> + <xsl:when test="@stroke-dasharray and normalize-space(@stroke-dasharray) != 'none'"> + <xsl:attribute name="StrokeDashArray"> + <xsl:value-of select="@stroke-dasharray" /> + </xsl:attribute> + </xsl:when> <xsl:when test="@style and contains(@style, 'stroke-dasharray:')"> <xsl:variable name="StrokeDashArray" select="substring-after(@style, 'stroke-dasharray:')" /> <xsl:choose> <xsl:when test="contains($StrokeDashArray, ';')"> - <xsl:if test="substring-before($StrokeDashArray, ';') != 'none'"><xsl:attribute name="StrokeDashArray"><xsl:value-of select="substring-before($StrokeDashArray, ';')" /></xsl:attribute></xsl:if> + <xsl:if test="normalize-space(substring-before($StrokeDashArray, ';')) != 'none'"> + <xsl:attribute name="StrokeDashArray"> + <xsl:value-of select="substring-before($StrokeDashArray, ';')" /> + </xsl:attribute> + </xsl:if> + </xsl:when> + <xsl:when test="normalize-space($StrokeDashArray) != 'none'"> + <xsl:attribute name="StrokeDashArray"> + <xsl:value-of select="$StrokeDashArray" /> + </xsl:attribute> </xsl:when> - <xsl:when test="$StrokeDashArray != 'none'"><xsl:attribute name="StrokeDashArray"><xsl:value-of select="$StrokeDashArray" /></xsl:attribute></xsl:when> </xsl:choose> </xsl:when> - <xsl:when test="name(..) = 'g' or name(..) = 'svg'"><xsl:apply-templates mode="stroke_dasharray" select="parent::*"/></xsl:when> + <xsl:when test="name(..) = 'g' or name(..) = 'svg'"> + <xsl:apply-templates mode="stroke_dasharray" select="parent::*"/> + </xsl:when> </xsl:choose> </xsl:template> -<!-- Stroke dashoffset --> +<!-- + // Stroke dashoffset // +--> <xsl:template mode="stroke_dashoffset" match="*"> <xsl:choose> - <xsl:when test="@stroke-dashoffset"><xsl:attribute name="StrokeDashOffset"><xsl:value-of select="@stroke-dashoffset" /></xsl:attribute></xsl:when> - <xsl:when test="@style and contains(@style, 'stroke-dashoffset:')"> - <xsl:variable name="StrokeDashOffset" select="substring-after(@style, 'stroke-dashoffset:')" /> - <xsl:attribute name="StrokeDashOffset"> + <xsl:when test="@stroke-dashoffset or (@style and contains(@style, 'stroke-dashoffset:'))"> + <xsl:variable name="value"> <xsl:choose> - <xsl:when test="contains($StrokeDashOffset, ';')"><xsl:value-of select="substring-before($StrokeDashOffset, ';')" /></xsl:when> - <xsl:otherwise><xsl:value-of select="$StrokeDashOffset" /></xsl:otherwise> + <xsl:when test="@stroke-dashoffset"> + <xsl:call-template name="convert_unit"> + <xsl:with-param name="convert_value" select="normalize-space(@stroke-dashoffset)" /> + </xsl:call-template> + </xsl:when> + <xsl:when test="@style and contains(@style, 'stroke-dashoffset:')"> + <xsl:variable name="StrokeDashOffset" select="normalize-space(substring-after(@style, 'stroke-dashoffset:'))" /> + <xsl:attribute name="StrokeDashOffset"> + <xsl:choose> + <xsl:when test="contains($StrokeDashOffset, ';')"> + <xsl:call-template name="convert_unit"> + <xsl:with-param name="convert_value" select="substring-before($StrokeDashOffset, ';')" /> + </xsl:call-template> + </xsl:when> + <xsl:otherwise> + <xsl:call-template name="convert_unit"> + <xsl:with-param name="convert_value" select="$StrokeDashOffset" /> + </xsl:call-template> + </xsl:otherwise> + </xsl:choose> + </xsl:attribute> + </xsl:when> </xsl:choose> - </xsl:attribute> + </xsl:variable> + <xsl:if test="value != ''"> + <xsl:attribute name="StrokeDashOffset"> + <xsl:value-of select="$value" /> + </xsl:attribute> + </xsl:if> + </xsl:when> + <xsl:when test="name(..) = 'g' or name(..) = 'svg'"> + <xsl:apply-templates mode="stroke_dashoffset" select="parent::*"/> </xsl:when> - <xsl:when test="name(..) = 'g' or name(..) = 'svg'"><xsl:apply-templates mode="stroke_dashoffset" select="parent::*"/></xsl:when> </xsl:choose> </xsl:template> -<!-- Linejoin SVG to XAML converter --> +<!-- + // Linejoin SVG to XAML converter // +--> <xsl:template name="linejoin_svg_to_xaml"> <xsl:param name="linejoin" /> <xsl:choose> @@ -737,31 +1543,50 @@ Blank template. Title is ignored and desc is converted to Tag in the mode="desc" </xsl:choose> </xsl:template> -<!-- Stroke linejoin --> +<!-- + // Stroke linejoin // +--> <xsl:template mode="stroke_linejoin" match="*"> <xsl:choose> - <xsl:when test="@stroke-miterlimit"> + <xsl:when test="@stroke-linejoin"> <xsl:attribute name="StrokeLineJoin"> - <xsl:call-template name="linejoin_svg_to_xaml"><xsl:with-param name="linejoin"><xsl:value-of select="@stroke-linejoin" /></xsl:with-param></xsl:call-template> - </xsl:attribute></xsl:when> + <xsl:call-template name="linejoin_svg_to_xaml"> + <xsl:with-param name="linejoin"> + <xsl:value-of select="@stroke-linejoin" /> + </xsl:with-param> + </xsl:call-template> + </xsl:attribute> + </xsl:when> <xsl:when test="@style and contains(@style, 'stroke-linejoin:')"> <xsl:variable name="StrokeLineJoin" select="substring-after(@style, 'stroke-linejoin:')" /> <xsl:attribute name="StrokeLineJoin"> <xsl:choose> <xsl:when test="contains($StrokeLineJoin, ';')"> - <xsl:call-template name="linejoin_svg_to_xaml"><xsl:with-param name="linejoin"><xsl:value-of select="substring-before($StrokeLineJoin, ';')" /></xsl:with-param></xsl:call-template> + <xsl:call-template name="linejoin_svg_to_xaml"> + <xsl:with-param name="linejoin"> + <xsl:value-of select="substring-before($StrokeLineJoin, ';')" /> + </xsl:with-param> + </xsl:call-template> </xsl:when> <xsl:otherwise> - <xsl:call-template name="linejoin_svg_to_xaml"><xsl:with-param name="linejoin"><xsl:value-of select="$StrokeLineJoin" /></xsl:with-param></xsl:call-template> + <xsl:call-template name="linejoin_svg_to_xaml"> + <xsl:with-param name="linejoin"> + <xsl:value-of select="$StrokeLineJoin" /> + </xsl:with-param> + </xsl:call-template> </xsl:otherwise> </xsl:choose> </xsl:attribute> </xsl:when> - <xsl:when test="name(..) = 'g' or name(..) = 'svg'"><xsl:apply-templates mode="stroke_linejoin" select="parent::*"/></xsl:when> + <xsl:when test="name(..) = 'g' or name(..) = 'svg'"> + <xsl:apply-templates mode="stroke_linejoin" select="parent::*"/> + </xsl:when> </xsl:choose> </xsl:template> -<!-- Linecap SVG to XAML converter --> +<!-- + // Linecap SVG to XAML converter // +--> <xsl:template name="linecap_svg_to_xaml"> <xsl:param name="linecap" /> <xsl:choose> @@ -771,118 +1596,201 @@ Blank template. Title is ignored and desc is converted to Tag in the mode="desc" </xsl:choose> </xsl:template> -<!-- Stroke linecap --> +<!-- + // Stroke linecap // +--> <xsl:template mode="stroke_linecap" match="*"> <xsl:choose> <xsl:when test="@stroke-linecap"> <xsl:attribute name="StrokeStartLineCap"> - <xsl:call-template name="linecap_svg_to_xaml"><xsl:with-param name="linecap"><xsl:value-of select="@stroke-linecap" /></xsl:with-param></xsl:call-template> + <xsl:call-template name="linecap_svg_to_xaml"> + <xsl:with-param name="linecap"> + <xsl:value-of select="@stroke-linecap" /> + </xsl:with-param> + </xsl:call-template> </xsl:attribute> <xsl:attribute name="StrokeEndLineCap"> - <xsl:call-template name="linecap_svg_to_xaml"><xsl:with-param name="linecap"><xsl:value-of select="@stroke-linecap" /></xsl:with-param></xsl:call-template> - </xsl:attribute></xsl:when> + <xsl:call-template name="linecap_svg_to_xaml"> + <xsl:with-param name="linecap"> + <xsl:value-of select="@stroke-linecap" /> + </xsl:with-param> + </xsl:call-template> + </xsl:attribute> + </xsl:when> <xsl:when test="@style and contains(@style, 'stroke-linecap:')"> <xsl:variable name="StrokeStartLineCap" select="substring-after(@style, 'stroke-linecap:')" /> <xsl:variable name="StrokeEndLineCap" select="substring-after(@style, 'stroke-linecap:')" /> <xsl:attribute name="StrokeStartLineCap"> <xsl:choose> <xsl:when test="contains($StrokeStartLineCap, ';')"> - <xsl:call-template name="linecap_svg_to_xaml"><xsl:with-param name="linecap"><xsl:value-of select="substring-before($StrokeStartLineCap, ';')" /></xsl:with-param></xsl:call-template> + <xsl:call-template name="linecap_svg_to_xaml"> + <xsl:with-param name="linecap"> + <xsl:value-of select="substring-before($StrokeStartLineCap, ';')" /> + </xsl:with-param> + </xsl:call-template> </xsl:when> <xsl:otherwise> - <xsl:call-template name="linecap_svg_to_xaml"><xsl:with-param name="linecap"><xsl:value-of select="$StrokeStartLineCap" /></xsl:with-param></xsl:call-template> + <xsl:call-template name="linecap_svg_to_xaml"> + <xsl:with-param name="linecap"> + <xsl:value-of select="$StrokeStartLineCap" /> + </xsl:with-param> + </xsl:call-template> </xsl:otherwise> </xsl:choose> </xsl:attribute> <xsl:attribute name="StrokeEndLineCap"> <xsl:choose> <xsl:when test="contains($StrokeEndLineCap, ';')"> - <xsl:call-template name="linecap_svg_to_xaml"><xsl:with-param name="linecap"><xsl:value-of select="substring-before($StrokeEndLineCap, ';')" /></xsl:with-param></xsl:call-template> + <xsl:call-template name="linecap_svg_to_xaml"> + <xsl:with-param name="linecap"> + <xsl:value-of select="substring-before($StrokeEndLineCap, ';')" /> + </xsl:with-param> + </xsl:call-template> </xsl:when> <xsl:otherwise> - <xsl:call-template name="linecap_svg_to_xaml"><xsl:with-param name="linecap"><xsl:value-of select="$StrokeEndLineCap" /></xsl:with-param></xsl:call-template> + <xsl:call-template name="linecap_svg_to_xaml"> + <xsl:with-param name="linecap"> + <xsl:value-of select="$StrokeEndLineCap" /> + </xsl:with-param> + </xsl:call-template> </xsl:otherwise> </xsl:choose> </xsl:attribute> </xsl:when> - <xsl:when test="name(..) = 'g' or name(..) = 'svg'"><xsl:apply-templates mode="stroke_linecap" select="parent::*"/></xsl:when> + <xsl:when test="name(..) = 'g' or name(..) = 'svg'"> + <xsl:apply-templates mode="stroke_linecap" select="parent::*"/> + </xsl:when> </xsl:choose> </xsl:template> -<!-- Gradient stops --> +<!-- + // Gradient stops // +--> <xsl:template mode="stop_color" match="*"> <xsl:variable name="Opacity"> <xsl:choose> - <xsl:when test="@stop-opacity"><xsl:value-of select="@stop-opacity" /></xsl:when> + <xsl:when test="@stop-opacity"> + <xsl:value-of select="normalize-space(@stop-opacity)" /> + </xsl:when> <xsl:when test="@style and contains(@style, 'stop-opacity:')"> - <xsl:variable name="temp_opacity" select="substring-after(@style, 'stop-opacity:')" /> + <xsl:variable name="temp_opacity" select="normalize-space(substring-after(@style, 'stop-opacity:'))" /> <xsl:choose> - <xsl:when test="contains($temp_opacity, ';')"><xsl:value-of select="substring-before($temp_opacity, ';')" /></xsl:when> - <xsl:otherwise><xsl:value-of select="$temp_opacity" /></xsl:otherwise> + <xsl:when test="contains($temp_opacity, ';')"> + <xsl:value-of select="substring-before($temp_opacity, ';')" /> + </xsl:when> + <xsl:otherwise> + <xsl:value-of select="$temp_opacity" /> + </xsl:otherwise> </xsl:choose> </xsl:when> - <xsl:otherwise><xsl:value-of select="''" /></xsl:otherwise> + <xsl:otherwise> + <xsl:value-of select="''" /> + </xsl:otherwise> </xsl:choose> </xsl:variable> <xsl:variable name="hex_opacity"> <xsl:choose> - <xsl:when test="$Opacity != ''"><xsl:call-template name="to_hex"><xsl:with-param name="convert"><xsl:value-of select="number($Opacity) * 255" /></xsl:with-param></xsl:call-template> </xsl:when> - <xsl:otherwise><xsl:value-of select="$Opacity" /></xsl:otherwise> + <xsl:when test="$Opacity != ''"> + <xsl:call-template name="to_hex"> + <xsl:with-param name="convert"> + <xsl:value-of select="number($Opacity) * 255" /> + </xsl:with-param> + </xsl:call-template> + </xsl:when> + <xsl:otherwise> + <xsl:value-of select="$Opacity" /> + </xsl:otherwise> </xsl:choose> </xsl:variable> <xsl:variable name="stopcolor"> <xsl:choose> <xsl:when test="@stop-color"> - <xsl:call-template name="template_color"><xsl:with-param name="colorspec"><xsl:value-of select="@stop-color" /></xsl:with-param></xsl:call-template> + <xsl:call-template name="template_color"> + <xsl:with-param name="colorspec"> + <xsl:value-of select="normalize-space(@stop-color)" /> + </xsl:with-param> + </xsl:call-template> </xsl:when> <xsl:when test="@style and contains(@style, 'stop-color:')"> - <xsl:variable name="Color" select="substring-after(@style, 'stop-color:')" /> + <xsl:variable name="Color" select="normalize-space(substring-after(@style, 'stop-color:'))" /> <xsl:choose> <xsl:when test="contains($Color, ';')"> - <xsl:call-template name="template_color"><xsl:with-param name="colorspec"><xsl:value-of select="substring-before($Color, ';')" /></xsl:with-param></xsl:call-template> + <xsl:call-template name="template_color"> + <xsl:with-param name="colorspec"> + <xsl:value-of select="substring-before($Color, ';')" /> + </xsl:with-param> + </xsl:call-template> </xsl:when> <xsl:otherwise> - <xsl:call-template name="template_color"><xsl:with-param name="colorspec"><xsl:value-of select="$Color" /></xsl:with-param></xsl:call-template> + <xsl:call-template name="template_color"> + <xsl:with-param name="colorspec"> + <xsl:value-of select="$Color" /> + </xsl:with-param> + </xsl:call-template> </xsl:otherwise> </xsl:choose> </xsl:when> - <xsl:when test="name(..) = 'g' or name(..) = 'svg'"><xsl:apply-templates mode="stop_color" select="parent::*"/></xsl:when> - <xsl:otherwise>#000</xsl:otherwise> + <xsl:when test="name(..) = 'g' or name(..) = 'svg'"> + <xsl:apply-templates mode="stop_color" select="parent::*"/> + </xsl:when> + <xsl:otherwise>#000000</xsl:otherwise> </xsl:choose> </xsl:variable> <xsl:attribute name="Color"> <xsl:choose> - <xsl:when test="$hex_opacity != '' and starts-with($stopcolor, '#')"><xsl:value-of select="concat('#', $hex_opacity, substring-after($stopcolor, '#'))" /></xsl:when> - <xsl:otherwise><xsl:value-of select="$stopcolor" /></xsl:otherwise> + <xsl:when test="$hex_opacity != '' and starts-with($stopcolor, '#')"> + <xsl:value-of select="concat('#', $hex_opacity, substring-after($stopcolor, '#'))" /> + </xsl:when> + <xsl:otherwise> + <xsl:value-of select="$stopcolor" /> + </xsl:otherwise> </xsl:choose> </xsl:attribute> </xsl:template> -<!-- Gradient stop opacity --> +<!-- + // Gradient stop opacity // +--> <xsl:template mode="stop_opacity" match="*"> <xsl:choose> - <xsl:when test="@stop-opacity"><xsl:attribute name="Opacity"><xsl:value-of select="@stop-opacity" /></xsl:attribute></xsl:when> + <xsl:when test="@stop-opacity"> + <xsl:attribute name="Opacity"> + <xsl:value-of select="@stop-opacity" /> + </xsl:attribute> + </xsl:when> <xsl:when test="@style and contains(@style, 'stop-opacity:')"> <xsl:variable name="Opacity" select="substring-after(@style, 'stop-opacity:')" /> <xsl:attribute name="Opacity"> <xsl:choose> - <xsl:when test="contains($Opacity, ';')"><xsl:value-of select="substring-before($Opacity, ';')" /></xsl:when> - <xsl:otherwise><xsl:value-of select="$Opacity" /></xsl:otherwise> + <xsl:when test="contains($Opacity, ';')"> + <xsl:value-of select="substring-before($Opacity, ';')" /> + </xsl:when> + <xsl:otherwise> + <xsl:value-of select="$Opacity" /> + </xsl:otherwise> </xsl:choose> </xsl:attribute> </xsl:when> - <xsl:when test="name(..) = 'g' or name(..) = 'svg'"><xsl:apply-templates mode="stop_opacity" select="parent::*"/></xsl:when> + <xsl:when test="name(..) = 'g' or name(..) = 'svg'"> + <xsl:apply-templates mode="stop_opacity" select="parent::*"/> + </xsl:when> </xsl:choose> </xsl:template> -<!-- Gradient stop offset --> +<!-- + // Gradient stop offset // +--> <xsl:template mode="offset" match="*"> <xsl:choose> <xsl:when test="@offset"> <xsl:attribute name="Offset"> <xsl:choose> - <xsl:when test="contains(@offset, '%')"><xsl:value-of select="number(substring-before(@offset, '%')) div 100" /></xsl:when> - <xsl:otherwise><xsl:value-of select="@offset" /></xsl:otherwise> + <xsl:when test="contains(@offset, '%')"> + <xsl:value-of select="number(substring-before(@offset, '%')) div 100" /> + </xsl:when> + <xsl:otherwise> + <xsl:value-of select="@offset" /> + </xsl:otherwise> </xsl:choose> </xsl:attribute> </xsl:when> @@ -890,260 +1798,597 @@ Blank template. Title is ignored and desc is converted to Tag in the mode="desc" <xsl:variable name="Offset" select="substring-after(@style, 'offset:')" /> <xsl:attribute name="Offset"> <xsl:choose> - <xsl:when test="contains($Offset, '%')"><xsl:value-of select="number(substring-before($Offset, '%')) div 100" /></xsl:when> - <xsl:when test="contains($Offset, ';')"><xsl:value-of select="substring-before($Offset, ';')" /></xsl:when> - <xsl:otherwise><xsl:value-of select="$Offset" /></xsl:otherwise> + <xsl:when test="contains($Offset, '%')"> + <xsl:value-of select="number(substring-before($Offset, '%')) div 100" /> + </xsl:when> + <xsl:when test="contains($Offset, ';')"> + <xsl:value-of select="substring-before($Offset, ';')" /> + </xsl:when> + <xsl:otherwise> + <xsl:value-of select="$Offset" /> + </xsl:otherwise> </xsl:choose> </xsl:attribute> </xsl:when> - <xsl:when test="name(..) = 'g' or name(..) = 'svg'"><xsl:apply-templates mode="stop_offset" select="parent::*"/></xsl:when> + <xsl:when test="name(..) = 'g' or name(..) = 'svg'"> + <xsl:apply-templates mode="stop_offset" select="parent::*"/> + </xsl:when> </xsl:choose> </xsl:template> <!-- -// Transforms // -All the matrix, translate, rotate... stuff. -Fixme: XAML transforms don't show the same result as SVG ones with the same values. - -* Parse transform -* Apply transform -* Apply transform v2 + // Image stretch // + SVG: preserveAspectRatio, XAML: Stretch --> - -<!-- Parse transform --> -<xsl:template name="parse_transform"> - <xsl:param name="input" /> - <xsl:choose> - <xsl:when test="starts-with($input, 'matrix(')"> - <MatrixTransform><xsl:attribute name="Matrix"><xsl:value-of select="substring-before(substring-after($input, 'matrix('), ')')" /></xsl:attribute></MatrixTransform> - <xsl:call-template name="parse_transform"><xsl:with-param name="input" select="substring-after($input, ') ')" /></xsl:call-template> - </xsl:when> - <xsl:when test="starts-with($input, 'scale(')"> - <ScaleTransform> - <xsl:variable name="scale" select="substring-before(substring-after($input, 'scale('), ')')" /> +<xsl:template mode="image_stretch" match="*"> + <xsl:variable name="value"> + <xsl:choose> + <xsl:when test="@preserveAspectRatio"> + <xsl:value-of select="@preserveAspectRatio" /> + </xsl:when> + <xsl:when test="@style and contains(@style, 'preserveAspectRatio:')"> + <xsl:variable name="ratio" select="normalize-space(substring-after(@style, 'preserveAspectRatio:'))" /> <xsl:choose> - <xsl:when test="contains($scale, ',')"> - <xsl:attribute name="ScaleX"><xsl:value-of select="substring-before($scale, ',')" /></xsl:attribute> - <xsl:attribute name="ScaleY"><xsl:value-of select="substring-after($scale, ',')" /></xsl:attribute> + <xsl:when test="contains($ratio, ';')"> + <xsl:value-of select="substring-before($ratio, ';')" /> </xsl:when> <xsl:otherwise> - <xsl:attribute name="ScaleX"><xsl:value-of select="$scale" /></xsl:attribute> - <xsl:attribute name="ScaleY"><xsl:value-of select="$scale" /></xsl:attribute> + <xsl:value-of select="$ratio" /> </xsl:otherwise> </xsl:choose> - </ScaleTransform> - <xsl:call-template name="parse_transform"><xsl:with-param name="input" select="substring-after($input, ') ')" /></xsl:call-template> - </xsl:when> - <xsl:when test="starts-with($input, 'rotate(')"> - <RotateTransform> - <xsl:attribute name="Angle"><xsl:value-of select="substring-before(substring-after($input, 'rotate('), ')')" /></xsl:attribute> - <xsl:if test="@rx"><xsl:attribute name="CenterX"><xsl:value-of select="@rx" /></xsl:attribute></xsl:if> - <xsl:if test="@ry"><xsl:attribute name="CenterY"><xsl:value-of select="@ry" /></xsl:attribute></xsl:if> - </RotateTransform> - <xsl:call-template name="parse_transform"><xsl:with-param name="input" select="substring-after($input, ') ')" /></xsl:call-template> - </xsl:when> - <xsl:when test="starts-with($input, 'skewX(')"> - <SkewTransform> - <xsl:attribute name="AngleX"><xsl:value-of select="substring-before(substring-after($input, 'skewX('), ')')" /></xsl:attribute> - <xsl:call-template name="parse_transform"><xsl:with-param name="input" select="substring-after($input, ') ')" /></xsl:call-template> - </SkewTransform> - </xsl:when> - <xsl:when test="starts-with($input, 'skewY(')"> - <SkewTransform> - <xsl:attribute name="AngleY"><xsl:value-of select="substring-before(substring-after($input, 'skewY('), ')')" /></xsl:attribute> - <xsl:call-template name="parse_transform"><xsl:with-param name="input" select="substring-after($input, ') ')" /></xsl:call-template> - </SkewTransform> - </xsl:when> - <xsl:when test="starts-with($input, 'translate(')"> - <TranslateTransform> - <xsl:variable name="translate" select="substring-before(substring-after($input, 'translate('), ')')" /> - <xsl:choose> - <xsl:when test="contains($translate, ',')"> - <xsl:attribute name="X"><xsl:value-of select="substring-before($translate, ',')" /></xsl:attribute> - <xsl:attribute name="Y"><xsl:value-of select="substring-after($translate, ',')" /></xsl:attribute> - </xsl:when> - <xsl:when test="contains($translate, ' ')"> - <xsl:attribute name="X"><xsl:value-of select="substring-before($translate, ' ')" /></xsl:attribute> - <xsl:attribute name="Y"><xsl:value-of select="substring-after($translate, ' ')" /></xsl:attribute> - </xsl:when> - <xsl:otherwise><xsl:attribute name="X"><xsl:value-of select="$translate" /></xsl:attribute></xsl:otherwise> - </xsl:choose> - </TranslateTransform> - <xsl:call-template name="parse_transform"><xsl:with-param name="input" select="substring-after($input, ') ')" /></xsl:call-template> - </xsl:when> - </xsl:choose> -</xsl:template> - -<!-- Apply transform --> -<xsl:template mode="transform" match="*"> - <xsl:param name="mapped_type" /> - <xsl:if test="@transform or @gradientTransform"> - <xsl:variable name="transform"> - <xsl:choose> - <xsl:when test="@transform"><xsl:value-of select="@transform" /></xsl:when> - <xsl:otherwise><xsl:value-of select="@gradientTransform" /></xsl:otherwise> + </xsl:when> </xsl:choose> </xsl:variable> - <xsl:variable name="transform_nodes"> - <xsl:call-template name="parse_transform"> - <xsl:with-param name="input" select="$transform" /> - </xsl:call-template> - </xsl:variable> + <xsl:if test="$value = 'none'"> + <xsl:attribute name="Stretch">Fill</xsl:attribute> + </xsl:if> +</xsl:template> - <xsl:comment> - <xsl:value-of select="name(.)" /> - </xsl:comment> +<!-- + // Text specific templates // + + * Text tspan + * Text flowPara + * Text flowRegion (text frame) + * Get font size + * Font size + * Font weight + * Font family + * Font style + * Baseline shift + * Line height + * Writing mode + * Text decoration + * Text fill + * Text direction + * Text size + * Text position + * Text object + * FlowRoot object +--> + <!-- + // Text span // + SVG: tspan, flowSpan, XAML: Span + + Not supported in XAML: + * span position +--> +<xsl:template mode="forward" match="*[name(.) = 'tspan' or name(.) = 'flowSpan']"> + <Span> + <xsl:if test="../@xml:space='preserve'"> + <xsl:attribute name="whiteSpaceCollapse">preserve</xsl:attribute> + </xsl:if> + <xsl:variable name="fill"> + <xsl:apply-templates mode="fill" select="." /> + </xsl:variable> + <xsl:if test="starts-with($fill, '#') or (not(starts-with($fill, 'url')) and $fill != '' and $fill != 'none')"> + <xsl:attribute name="Foreground"> + <xsl:call-template name="template_color"> + <xsl:with-param name="colorspec"> + <xsl:value-of select="$fill" /> + </xsl:with-param> + </xsl:call-template> + </xsl:attribute> + </xsl:if> + <xsl:apply-templates mode="font_size" select="." /> + <xsl:apply-templates mode="font_weight" select="." /> + <xsl:apply-templates mode="font_family" select="." /> + <xsl:apply-templates mode="font_style" select="." /> + <xsl:apply-templates mode="text_fill" select="." /> + <xsl:apply-templates mode="text_decoration" select="." /> + <xsl:apply-templates mode="line_height" select="." /> + <xsl:apply-templates mode="baseline_shift" select="." /> + + <xsl:if test="text()"> + <xsl:value-of select="text()" /> + </xsl:if> + </Span> +</xsl:template> + + <!-- + // Text flowPara // + SVG: flowPara, flowDiv XAML: ? + +--> +<xsl:template mode="forward" match="*[name(.) = 'flowPara' or name(.) = 'flowDiv']"> <xsl:choose> - <xsl:when test="$mapped_type and $mapped_type != ''"> - <xsl:element name="{$mapped_type}.RenderTransform"> - <xsl:choose> - <xsl:when test="count(libxslt:node-set($transform_nodes)/*) = 1"><xsl:copy-of select="libxslt:node-set($transform_nodes)" /></xsl:when> - <xsl:when test="count(libxslt:node-set($transform_nodes)/*) > 1"><TransformGroup><xsl:copy-of select="libxslt:node-set($transform_nodes)" /></TransformGroup></xsl:when> - </xsl:choose> - </xsl:element> + <xsl:when test="*[name(.) = 'flowSpan']/text()"> + <xsl:apply-templates mode="forward" /> </xsl:when> <xsl:otherwise> - <!-- For instance LinearGradient.Transform --> <xsl:choose> - <xsl:when test="count(libxslt:node-set($transform_nodes)/*) = 1"><xsl:copy-of select="libxslt:node-set($transform_nodes)" /></xsl:when> - <xsl:when test="count(libxslt:node-set($transform_nodes)/*) > 1"><TransformGroup><xsl:copy-of select="libxslt:node-set($transform_nodes)" /></TransformGroup></xsl:when> - </xsl:choose> + <xsl:when test="@xml:space='preserve'"> + <xsl:copy-of select="translate(text(), '	

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

', ' '))" /> + </xsl:otherwise> + </xsl:choose> </xsl:otherwise> </xsl:choose> - </xsl:if> </xsl:template> -<!-- Apply transform v2 -Fixme: is this template still in use? --> -<xsl:template mode="transform2" match="*"> + + <!-- + // Text flowRegion // +--> +<xsl:template mode="flow_region" match="*"> + <xsl:apply-templates mode="text_size" select="." /> + <xsl:apply-templates mode="text_position" select="." /> +</xsl:template> + +<!-- + // Get text font size // +--> +<xsl:template mode="get_font_size" match="*"> <xsl:choose> - <xsl:when test="@transform"> - <Canvas> - <Canvas.RenderTransform> - <TransformGroup><xsl:apply-templates mode="transform" select="." /></TransformGroup> - </Canvas.RenderTransform> - <xsl:apply-templates mode="forward" select="." /> - </Canvas> + <xsl:when test="@font-size"> + <xsl:value-of select="@font-size" /> + </xsl:when> + <xsl:when test="@style and contains(@style, 'font-size:')"> + <xsl:variable name="font_size" select="normalize-space(substring-after(@style, 'font-size:'))" /> + <xsl:choose> + <xsl:when test="contains($font_size, ';')"> + <xsl:value-of select="substring-before($font_size, ';')" /> + </xsl:when> + <xsl:otherwise> + <xsl:value-of select="$font_size" /> + </xsl:otherwise> + </xsl:choose> + </xsl:when> + <xsl:when test="name(..) = 'g' or name(..) = 'svg' or name(..) = 'text' or name(..) = 'flowPara' or name(..) = 'flowRoot'"> + <xsl:apply-templates mode="get_font_size" select="parent::*"/> </xsl:when> - <xsl:otherwise> - <xsl:apply-templates mode="forward" select="." /> - </xsl:otherwise> </xsl:choose> </xsl:template> <!-- -// Objects // - -* Image -* Text -* Lines -* Rectangle -* Polygon -* Polyline -* Path -* Ellipse -* Circle + // Text font size // + SVG: font-size, XAML: FontSize --> - -<!-- Image --> -<xsl:template mode="forward" match="*[name(.) = 'image']"> - <Image> - <xsl:apply-templates mode="id" select="." /> - <xsl:if test="@x"><xsl:attribute name="Canvas.Left"> - <xsl:call-template name="convert_unit"> - <xsl:with-param name="convert_value" select="@x" /> - </xsl:call-template> - </xsl:attribute></xsl:if> - <xsl:if test="@y"><xsl:attribute name="Canvas.Top"> - <xsl:call-template name="convert_unit"> - <xsl:with-param name="convert_value" select="@y" /> - </xsl:call-template> - </xsl:attribute></xsl:if> - <xsl:apply-templates mode="desc" select="." /> - <xsl:apply-templates mode="clip" select="." /> - <xsl:if test="@xlink:href"><xsl:attribute name="Source"><xsl:value-of select="@xlink:href" /></xsl:attribute></xsl:if> - <xsl:if test="@width"><xsl:attribute name="Width"> - <xsl:call-template name="convert_unit"> - <xsl:with-param name="convert_value" select="@width" /> - </xsl:call-template> - </xsl:attribute></xsl:if> - <xsl:if test="@height"><xsl:attribute name="Height"> +<xsl:template mode="font_size" match="*"> + <xsl:variable name="value"> + <xsl:apply-templates mode="get_font_size" select="." /> + </xsl:variable> + <xsl:if test="$value != ''"> + <xsl:attribute name="FontSize"> + <xsl:call-template name="convert_unit"> + <xsl:with-param name="convert_value" select="$value" /> + </xsl:call-template> + </xsl:attribute> + </xsl:if> + <xsl:attribute name="FontSize"> + <xsl:choose> + <xsl:when test="$value != ''"> <xsl:call-template name="convert_unit"> - <xsl:with-param name="convert_value" select="@height" /> + <xsl:with-param name="convert_value" select="$value" /> </xsl:call-template> - </xsl:attribute></xsl:if> - <xsl:apply-templates mode="transform" select="."> - <xsl:with-param name="mapped_type" select="'Image'" /> - </xsl:apply-templates> - <!--xsl:apply-templates mode="transform" /--> - <xsl:apply-templates mode="forward" /> - </Image> + </xsl:when> + <xsl:otherwise>12</xsl:otherwise> + </xsl:choose> + </xsl:attribute> </xsl:template> -<!-- Text --> -<xsl:template mode="forward" match="*[name(.) = 'text']"> - <TextBlock> - <xsl:if test="@font-size"><xsl:attribute name="FontSize"><xsl:value-of select="@font-size" /></xsl:attribute></xsl:if> - <xsl:if test="@style and contains(@style, 'font-size:')"> - <xsl:variable name="font_size" select="substring-after(@style, 'font-size:')" /> - <xsl:attribute name="FontSize"> - <xsl:choose> - <xsl:when test="contains($font_size, ';')"> - <xsl:value-of select="substring-before($font_size, ';')" /> - </xsl:when> - <xsl:otherwise><xsl:value-of select="$font_size" /></xsl:otherwise> - </xsl:choose> - </xsl:attribute> +<!-- + // Text font weight // + SVG: font-weight, XAML: FontWeight +--> +<xsl:template mode="font_weight" match="*"> + <xsl:variable name="value"> + <xsl:if test="@font-weight"> + <xsl:value-of select="@font-weight" /> </xsl:if> - <xsl:if test="@font-weight"><xsl:attribute name="FontWeight"><xsl:value-of select="@font-weight" /></xsl:attribute></xsl:if> <xsl:if test="@style and contains(@style, 'font-weight:')"> - <xsl:variable name="font_weight" select="substring-after(@style, 'font-weight:')" /> - <xsl:attribute name="FontWeight"> - <xsl:choose> - <xsl:when test="contains($font_weight, ';')"> - <xsl:value-of select="substring-before($font_weight, ';')" /> - </xsl:when> - <xsl:otherwise><xsl:value-of select="$font_weight" /></xsl:otherwise> - </xsl:choose> - </xsl:attribute> + <xsl:variable name="font_weight" select="normalize-space(substring-after(@style, 'font-weight:'))" /> + <xsl:choose> + <xsl:when test="contains($font_weight, ';')"> + <xsl:value-of select="substring-before($font_weight, ';')" /> + </xsl:when> + <xsl:otherwise> + <xsl:value-of select="$font_weight" /> + </xsl:otherwise> + </xsl:choose> + </xsl:if> + </xsl:variable> + <xsl:if test="$value != ''"> + <xsl:attribute name="FontWeight"> + <xsl:choose> + <xsl:when test="$value <= 100 or $value = 'lighter'">Thin</xsl:when> + <xsl:when test="$value > 100 and $value <= 200">ExtraLight</xsl:when> + <xsl:when test="$value > 200 and $value <= 300">Light</xsl:when> + <xsl:when test="($value > 300 and $value <= 400) or $value ='normal'">Normal</xsl:when> + <xsl:when test="$value > 400 and $value <= 500">Medium</xsl:when> + <xsl:when test="$value > 500 and $value <= 600">SemiBold</xsl:when> + <xsl:when test="($value > 600 and $value <= 700) or $value ='bold'">Bold</xsl:when> + <xsl:when test="$value > 700 and $value <= 800">ExtraBold</xsl:when> + <xsl:when test="$value > 800 and $value <= 900">Black</xsl:when> + <xsl:when test="$value > 900 or $value = 'bolder'">ExtraBlack</xsl:when> + <xsl:otherwise>normal</xsl:otherwise> + </xsl:choose> + </xsl:attribute> + </xsl:if> +</xsl:template> + +<!-- + // Text font family // + SVG: font-family, XAML: FontFamily +--> +<xsl:template mode="font_family" match="*"> + <xsl:variable name="value"> + <xsl:if test="@font-family"> + <xsl:value-of select="translate(@font-family, "'", '')" /> </xsl:if> - <xsl:if test="@font-family"><xsl:attribute name="FontFamily"><xsl:value-of select="@font-family" /></xsl:attribute></xsl:if> <xsl:if test="@style and contains(@style, 'font-family:')"> - <xsl:variable name="font_family" select="substring-after(@style, 'font-family:')" /> - <xsl:attribute name="FontFamily"> - <xsl:choose> - <xsl:when test="contains($font_family, ';')"> - <xsl:value-of select="substring-before($font_family, ';')" /> - </xsl:when> - <xsl:otherwise><xsl:value-of select="$font_family" /></xsl:otherwise> - </xsl:choose> - </xsl:attribute> + <xsl:variable name="font_family" select="normalize-space(substring-after(@style, 'font-family:'))" /> + <xsl:choose> + <xsl:when test="contains($font_family, ';')"> + <xsl:value-of select="translate(substring-before($font_family, ';'), "'", '')" /> + </xsl:when> + <xsl:otherwise> + <xsl:value-of select="translate($font_family, "'", '')" /> + </xsl:otherwise> + </xsl:choose> + </xsl:if> + </xsl:variable> + <xsl:if test="$value != ''"> + <xsl:attribute name="FontFamily"> + <xsl:choose> + <xsl:when test="$value='Sans'">Arial</xsl:when> + <xsl:otherwise> + <xsl:value-of select="$value" /> + </xsl:otherwise> + </xsl:choose> + </xsl:attribute> + </xsl:if> +</xsl:template> + +<!-- + // Text font style // + SVG: font-style, XAML: FontStyle +--> +<xsl:template mode="font_style" match="*"> + <xsl:variable name="value"> + <xsl:if test="@font-style"> + <xsl:value-of select="@font-style" /> </xsl:if> - <xsl:if test="@font-style"><xsl:attribute name="FontStyle"><xsl:value-of select="@font-style" /></xsl:attribute></xsl:if> <xsl:if test="@style and contains(@style, 'font-style:')"> - <xsl:variable name="font_style" select="substring-after(@style, 'font-style:')" /> - <xsl:attribute name="FontStyle"> - <xsl:choose> - <xsl:when test="contains($font_style, ';')"> - <xsl:value-of select="substring-before($font_style, ';')" /> + <xsl:variable name="font_style" select="normalize-space(substring-after(@style, 'font-style:'))" /> + <xsl:choose> + <xsl:when test="contains($font_style, ';')"> + <xsl:value-of select="substring-before($font_style, ';')" /> + </xsl:when> + <xsl:otherwise> + <xsl:value-of select="$font_style" /> + </xsl:otherwise> + </xsl:choose> + </xsl:if> + </xsl:variable> + <xsl:if test="$value != ''"> + <xsl:attribute name="FontStyle"> + <xsl:value-of select="$value" /> + </xsl:attribute> + </xsl:if> +</xsl:template> + +<!-- + // Text baseline shift // + SVG: baseline-shift, XAML: BaselineAlignment +--> +<xsl:template mode="baseline_shift" match="*"> + <xsl:variable name="value"> + <xsl:if test="@baseline-shift"> + <xsl:value-of select="@baseline-shift" /> + </xsl:if> + <xsl:if test="@style and contains(@style, 'baseline-shift:') and not(contains(substring-after(@style, 'baseline-shift:'), ';'))"> + <xsl:value-of select="substring-after(@style, 'baseline-shift:')" /> + </xsl:if> + <xsl:if test="@style and contains(@style, 'baseline-shift:') and contains(substring-after(@style, 'baseline-shift:'), ';')"> + <xsl:value-of select="substring-before(substring-after(@style, 'baseline-shift:'), ';')" /> + </xsl:if> + </xsl:variable> + <xsl:if test="$value = 'baseline' or $value='super' or $value='sub'"> + <xsl:attribute name="BaselineAlignment"> + <xsl:choose> + <xsl:when test="$value='baseline'">Normal</xsl:when> + <xsl:when test="$value='super'">Superscript</xsl:when> + <xsl:when test="$value='sub'">Subscript</xsl:when> + </xsl:choose> + <xsl:if test="contains($value, '%')">%</xsl:if> + </xsl:attribute> + </xsl:if> +</xsl:template> + +<!-- + // Text line height // + SVG: line-height, FXG: lineHeight +--> +<xsl:template mode="line_height" match="*"> + <xsl:variable name="value"> + <xsl:if test="@line-height"> + <xsl:value-of select="@line-height" /> + </xsl:if> + <xsl:if test="@style and contains(@style, 'line-height:')"> + <xsl:variable name="line_height" select="normalize-space(substring-after(@style, 'line-height:'))" /> + <xsl:choose> + <xsl:when test="contains($line_height, ';')"> + <xsl:value-of select="substring-before($line_height, ';')" /> + </xsl:when> + <xsl:otherwise> + <xsl:value-of select="$line_height" /> + </xsl:otherwise> + </xsl:choose> + </xsl:if> + </xsl:variable> + <xsl:if test="$value != ''"> + <xsl:attribute name="lineHeight"> + <xsl:call-template name="convert_unit"> + <xsl:with-param name="convert_value" select="$value" /> + </xsl:call-template> + </xsl:attribute> + </xsl:if> +</xsl:template> + +<!-- + // Text writing mode // + SVG: writing-mode, FXG: blockProgression + + Values inverted in FXG... +--> +<xsl:template mode="writing_mode" match="*"> + <xsl:variable name="value"> + <xsl:if test="@writing-mode"> + <xsl:value-of select="@writing-mode" /> + </xsl:if> + <xsl:if test="@style and contains(@style, 'writing-mode:') and not(contains(substring-after(@style, 'writing-mode:'), ';'))"> + <xsl:value-of select="substring-after(@style, 'writing-mode:')" /> + </xsl:if> + <xsl:if test="@style and contains(@style, 'writing-mode:') and contains(substring-after(@style, 'writing-mode:'), ';')"> + <xsl:value-of select="substring-before(substring-after(@style, 'writing-mode:'), ';')" /> + </xsl:if> + </xsl:variable> + <xsl:if test="$value != ''"> + <xsl:attribute name="blockProgression"> + <xsl:choose> + <xsl:when test="$value='tb'">rl</xsl:when> + <xsl:otherwise>tb</xsl:otherwise> + </xsl:choose> + </xsl:attribute> + <xsl:if test="$value='tb'"> + <xsl:attribute name="textRotation">rotate270</xsl:attribute> + </xsl:if> + </xsl:if> +</xsl:template> + +<!-- + // Text decoration // + SVG: text-decoration, XAML: TextDecorations +--> +<xsl:template mode="text_decoration" match="*"> + <xsl:variable name="value"> + <xsl:if test="@text-decoration"> + <xsl:value-of select="@text-decoration" /> + </xsl:if> + <xsl:if test="@style and contains(@style, 'text-decoration:') and not(contains(substring-after(@style, 'text-decoration:'), ';'))"> + <xsl:value-of select="substring-after(@style, 'text-decoration:')" /> + </xsl:if> + <xsl:if test="@style and contains(@style, 'text-decoration:') and contains(substring-after(@style, 'text-decoration:'), ';')"> + <xsl:value-of select="substring-before(substring-after(@style, 'text-decoration:'), ';')" /> + </xsl:if> + </xsl:variable> + <xsl:if test="$value != ''"> + <xsl:attribute name="TextDecorations"> + <xsl:choose> + <xsl:when test="$value='underline'">Underline</xsl:when> + <xsl:when test="$value='line-through'">Strikethrough</xsl:when> + <xsl:when test="$value='overline'">Overline</xsl:when> + <xsl:otherwise>None</xsl:otherwise> + </xsl:choose> + </xsl:attribute> + </xsl:if> +</xsl:template> + +<!-- + // Text fill // + SVG: fill, fill-opacity, XAML: Foreground +--> +<xsl:template mode="text_fill" match="*"> + <xsl:variable name="fill"> + <xsl:apply-templates mode="fill" select="." /> + </xsl:variable> + <xsl:variable name="fill_opacity"> + <xsl:apply-templates mode="fill_opacity" select="." /> + </xsl:variable> + <xsl:if test="starts-with($fill, '#') or (not(starts-with($fill, 'url')) and $fill != '' and $fill != 'none')"> + <xsl:attribute name="Foreground"> + <xsl:call-template name="template_color"> + <xsl:with-param name="colorspec"> + <xsl:value-of select="$fill" /> + </xsl:with-param> + <xsl:with-param name="opacityspec"> + <xsl:choose> + <xsl:when test="$fill_opacity"> + <xsl:value-of select="$fill_opacity" /> </xsl:when> - <xsl:otherwise><xsl:value-of select="$font_style" /></xsl:otherwise> - </xsl:choose> - </xsl:attribute> + <xsl:otherwise>1</xsl:otherwise> + </xsl:choose> + </xsl:with-param> + </xsl:call-template> + </xsl:attribute> + </xsl:if> +</xsl:template> + +<!-- + // Text direction // + SVG: direction, unicode-bidi, XAML: FlowDirection +--> +<xsl:template mode="direction" match="*"> + <xsl:variable name="value"> + <xsl:if test="@direction"> + <xsl:value-of select="@direction" /> </xsl:if> - <xsl:if test="@fill"><xsl:attribute name="Foreground"><xsl:value-of select="@fill" /></xsl:attribute></xsl:if> - <xsl:if test="@style and contains(@style, 'fill')"> - <xsl:variable name="fill" select="substring-after(@style, 'fill:')" /> - <xsl:attribute name="Foreground"> + <xsl:if test="@style and contains(@style, 'direction:') and not(contains(substring-after(@style, 'direction:'), ';'))"> + <xsl:value-of select="substring-after(@style, 'direction:')" /> + </xsl:if> + <xsl:if test="@style and contains(@style, 'direction:') and contains(substring-after(@style, 'direction:'), ';')"> + <xsl:value-of select="substring-before(substring-after(@style, 'direction:'), ';')" /> + </xsl:if> + </xsl:variable> + <xsl:variable name="bidi"> + <xsl:if test="@unicode-bidi"> + <xsl:value-of select="@unicode-bidi" /> + </xsl:if> + <xsl:if test="@style and contains(@style, 'unicode-bidi:') and not(contains(substring-after(@style, 'unicode-bidi:'), ';'))"> + <xsl:value-of select="substring-after(@style, 'unicode-bidi:')" /> + </xsl:if> + <xsl:if test="@style and contains(@style, 'unicode-bidi:') and contains(substring-after(@style, 'unicode-bidi:'), ';')"> + <xsl:value-of select="substring-before(substring-after(@style, 'unicode-bidi:'), ';')" /> + </xsl:if> + </xsl:variable> + + <xsl:if test="$value != '' and ($bidi='embed' or $bidi='bidi-override')"> + <xsl:attribute name="FlowDirection"> + <xsl:choose> + <xsl:when test="$value='ltr'">LeftToRight</xsl:when> + <xsl:when test="$value='rtl'">RightToLeft</xsl:when> + </xsl:choose> + </xsl:attribute> + </xsl:if> +</xsl:template> + + <!-- + // Text size // +--> +<xsl:template mode="text_size" match="*"> + <xsl:if test="@width"> + <xsl:attribute name="Width"> + <xsl:call-template name="convert_unit"> + <xsl:with-param name="convert_value" select="@width" /> + </xsl:call-template> + </xsl:attribute> + </xsl:if> + <xsl:if test="@height"> + <xsl:attribute name="Height"> + <xsl:call-template name="convert_unit"> + <xsl:with-param name="convert_value" select="@height" /> + </xsl:call-template> + </xsl:attribute> + </xsl:if> +</xsl:template> + + <!-- + // Text position // +--> +<xsl:template mode="text_position" match="*"> + <!-- Keep the first x value only --> + <xsl:if test="@x"> + <xsl:attribute name="Canvas.Left"> + <xsl:choose> + <xsl:when test="contains(@x, ' ')"> + <xsl:call-template name="convert_unit"> + <xsl:with-param name="convert_value" select="substring-before(@x, ' ')" /> + </xsl:call-template> + </xsl:when> + <xsl:otherwise> + <xsl:call-template name="convert_unit"> + <xsl:with-param name="convert_value" select="@x" /> + </xsl:call-template> + </xsl:otherwise> + </xsl:choose> + </xsl:attribute> + </xsl:if> + <!-- Keep the first y value only --> + <xsl:if test="@y"> + <xsl:attribute name="Canvas.Top"> + <xsl:variable name="top_val"> + <xsl:choose> + <xsl:when test="contains(@y, ' ')"> + <xsl:call-template name="convert_unit"> + <xsl:with-param name="convert_value" select="substring-before(@y, ' ')" /> + </xsl:call-template> + </xsl:when> + <xsl:otherwise> + <xsl:call-template name="convert_unit"> + <xsl:with-param name="convert_value" select="@y" /> + </xsl:call-template> + </xsl:otherwise> + </xsl:choose> + </xsl:variable> + <xsl:variable name="size_val"> + <xsl:variable name="value"> + <xsl:apply-templates mode="get_font_size" select="." /> + </xsl:variable> <xsl:choose> - <xsl:when test="contains($fill, ';')"> - <xsl:value-of select="substring-before($fill, ';')" /> + <xsl:when test="$value != ''"> + <xsl:call-template name="convert_unit"> + <xsl:with-param name="convert_value" select="$value" /> + </xsl:call-template> </xsl:when> - <xsl:otherwise><xsl:value-of select="$fill" /></xsl:otherwise> + <xsl:otherwise>12</xsl:otherwise> </xsl:choose> + </xsl:variable> + <xsl:if test="$top_val != '' and $size_val != ''"> + <xsl:value-of select="$top_val - $size_val" /> + </xsl:if> + </xsl:attribute> + </xsl:if> +</xsl:template> + +<!-- + // Objects // + + * Text + * Lines + * Rectangle + * Polygon + * Polyline + * Path + * Ellipse + * Circle + * Image +--> + +<!-- + // Text objects // + SVG: text, XAML: TextBlock +--> +<xsl:template mode="forward" match="*[name(.) = 'text' or name(.) = 'flowRoot']"> + <TextBlock> + <xsl:apply-templates mode="font_size" select="." /> + <xsl:apply-templates mode="font_weight" select="." /> + <xsl:apply-templates mode="font_family" select="." /> + <xsl:apply-templates mode="font_style" select="." /> + <xsl:apply-templates mode="text_fill" select="." /> + <xsl:apply-templates mode="text_size" select="." /> + <xsl:apply-templates mode="text_decoration" select="." /> + <xsl:apply-templates mode="direction" select="." /> + <xsl:apply-templates mode="text_position" select="." /> + <xsl:if test="name(.) = 'flowRoot'"> + <xsl:attribute name="TextWrapping"> + <xsl:value-of select="'Wrap'" /> </xsl:attribute> </xsl:if> + <xsl:if test="@text-anchor"> <xsl:attribute name="HorizontalAlignment"> <xsl:choose> @@ -1153,55 +2398,78 @@ Fixme: is this template still in use? --> </xsl:choose> </xsl:attribute> </xsl:if> - <xsl:if test="@width"><xsl:attribute name="Width"> - <xsl:call-template name="convert_unit"> - <xsl:with-param name="convert_value" select="@width" /> - </xsl:call-template> - </xsl:attribute></xsl:if> - <xsl:if test="@height"><xsl:attribute name="Height"> - <xsl:call-template name="convert_unit"> - <xsl:with-param name="convert_value" select="@height" /> - </xsl:call-template> - </xsl:attribute></xsl:if> - <xsl:if test="@x"><xsl:attribute name="Canvas.Left"> - <xsl:call-template name="convert_unit"> - <xsl:with-param name="convert_value" select="@x" /> - </xsl:call-template> - </xsl:attribute></xsl:if> - <xsl:if test="@y"><xsl:attribute name="Canvas.Top"> - <xsl:call-template name="convert_unit"> - <xsl:with-param name="convert_value" select="@y" /> - </xsl:call-template> - </xsl:attribute></xsl:if> + + <xsl:apply-templates mode="object_opacity" select="." /> + <xsl:apply-templates mode="id" select="." /> + <xsl:if test="name(.) = 'flowRoot'"> + <xsl:apply-templates mode="flow_region" select="*[name(.) = 'flowRegion']/child::node()" /> + </xsl:if> <xsl:apply-templates mode="filter_effect" select="." /> <xsl:apply-templates mode="desc" select="." /> + <xsl:apply-templates mode="resources" select="." /> <xsl:apply-templates mode="clip" select="." /> <!--xsl:apply-templates mode="transform" select="." /--> <!--xsl:apply-templates mode="forward" /--> - <xsl:if test="text()"><xsl:value-of select="text()" /></xsl:if> - <xsl:if test="*[name(.) = 'tspan']/text()"><xsl:value-of select="*[name(.) = 'tspan']/text()" /></xsl:if> + + <xsl:choose> + <xsl:when test="*[name(.) = 'tspan' or name(.) = 'flowPara' or name(.) = 'flowDiv']/text()"> + <xsl:apply-templates mode="forward" /> + </xsl:when> + <xsl:otherwise> + <xsl:choose> + <xsl:when test="@xml:space='preserve'"> + <xsl:copy-of select="translate(text(), '	

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

', ' '))" /> + </xsl:otherwise> + </xsl:choose> + </xsl:otherwise> + </xsl:choose> + </TextBlock> </xsl:template> -<!-- Lines --> +<!-- + // Line object // + SVG: line, XAML: Line +--> <xsl:template mode="forward" match="*[name(.) = 'line']"> <Line> - <xsl:if test="@x1"><xsl:attribute name="X1"><xsl:value-of select="@x1" /></xsl:attribute></xsl:if> - <xsl:if test="@y1"><xsl:attribute name="Y1"><xsl:value-of select="@y1" /></xsl:attribute></xsl:if> - <xsl:if test="@x2"><xsl:attribute name="X2"><xsl:value-of select="@x2" /></xsl:attribute></xsl:if> - <xsl:if test="@y2"><xsl:attribute name="Y2"><xsl:value-of select="@y2" /></xsl:attribute></xsl:if> + <xsl:if test="@x1"> + <xsl:attribute name="X1"> + <xsl:value-of select="@x1" /> + </xsl:attribute> + </xsl:if> + <xsl:if test="@y1"> + <xsl:attribute name="Y1"> + <xsl:value-of select="@y1" /> + </xsl:attribute> + </xsl:if> + <xsl:if test="@x2"> + <xsl:attribute name="X2"> + <xsl:value-of select="@x2" /> + </xsl:attribute> + </xsl:if> + <xsl:if test="@y2"> + <xsl:attribute name="Y2"> + <xsl:value-of select="@y2" /> + </xsl:attribute> + </xsl:if> + <xsl:apply-templates mode="id" select="." /> <xsl:apply-templates mode="template_fill" select="." /> <xsl:apply-templates mode="template_stroke" select="." /> - <xsl:apply-templates mode="stroke_width" select="." /> <xsl:apply-templates mode="stroke_miterlimit" select="." /> <xsl:apply-templates mode="stroke_dasharray" select="." /> <xsl:apply-templates mode="stroke_dashoffset" select="." /> <xsl:apply-templates mode="stroke_linejoin" select="." /> <xsl:apply-templates mode="stroke_linecap" select="." /> <xsl:apply-templates mode="filter_effect" select="." /> + <xsl:apply-templates mode="object_opacity" select="." /> <xsl:apply-templates mode="desc" select="." /> + <xsl:apply-templates mode="resources" select="." /> <xsl:apply-templates mode="transform" select="."> <xsl:with-param name="mapped_type" select="'Line'" /> @@ -1211,38 +2479,63 @@ Fixme: is this template still in use? --> </Line> </xsl:template> -<!-- Rectangle --> +<!-- + // Rectangle object // + SVG: rect, XAML: Rectangle +--> <xsl:template mode="forward" match="*[name(.) = 'rect']"> <Rectangle> - <xsl:if test="@x"><xsl:attribute name="Canvas.Left"> - <xsl:call-template name="convert_unit"> - <xsl:with-param name="convert_value" select="@x" /> + <xsl:if test="@x"> + <xsl:attribute name="Canvas.Left"> + <xsl:call-template name="convert_unit"> + <xsl:with-param name="convert_value" select="@x" /> </xsl:call-template> - </xsl:attribute></xsl:if> - <xsl:if test="@y"><xsl:attribute name="Canvas.Top"> - <xsl:call-template name="convert_unit"> - <xsl:with-param name="convert_value" select="@y" /> - </xsl:call-template> - </xsl:attribute></xsl:if> - <xsl:if test="@width"><xsl:attribute name="Width"> + </xsl:attribute> + </xsl:if> + <xsl:if test="@y"> + <xsl:attribute name="Canvas.Top"> <xsl:call-template name="convert_unit"> - <xsl:with-param name="convert_value" select="@width" /> + <xsl:with-param name="convert_value" select="@y" /> </xsl:call-template> - </xsl:attribute></xsl:if> - <xsl:if test="@height"><xsl:attribute name="Height"> + </xsl:attribute> + </xsl:if> + <xsl:if test="@width"> + <xsl:attribute name="Width"> <xsl:call-template name="convert_unit"> - <xsl:with-param name="convert_value" select="@height" /> + <xsl:with-param name="convert_value" select="@width" /> </xsl:call-template> - </xsl:attribute></xsl:if> - <xsl:if test="@rx"><xsl:attribute name="RadiusX"><xsl:value-of select="@rx" /></xsl:attribute></xsl:if> - <xsl:if test="@ry"><xsl:attribute name="RadiusY"><xsl:value-of select="@ry" /></xsl:attribute></xsl:if> - <xsl:if test="@rx and not(@ry)"><xsl:attribute name="RadiusX"><xsl:value-of select="@rx" /></xsl:attribute><xsl:attribute name="RadiusY"><xsl:value-of select="@rx" /></xsl:attribute></xsl:if> + </xsl:attribute> + </xsl:if> + <xsl:if test="@height"> + <xsl:attribute name="Height"> + <xsl:call-template name="convert_unit"> + <xsl:with-param name="convert_value" select="@height" /> + </xsl:call-template> + </xsl:attribute> + </xsl:if> + <xsl:if test="@rx"> + <xsl:attribute name="RadiusX"> + <xsl:value-of select="@rx" /> + </xsl:attribute> + </xsl:if> + <xsl:if test="@ry"> + <xsl:attribute name="RadiusY"> + <xsl:value-of select="@ry" /> + </xsl:attribute> + </xsl:if> + <xsl:if test="@rx and not(@ry)"> + <xsl:attribute name="RadiusX"> + <xsl:value-of select="@rx" /> + </xsl:attribute> + <xsl:attribute name="RadiusY"> + <xsl:value-of select="@rx" /> + </xsl:attribute> + </xsl:if> <xsl:if test="@ry and not(@rx)"><xsl:attribute name="RadiusX"><xsl:value-of select="@ry" /></xsl:attribute><xsl:attribute name="RadiusY"><xsl:value-of select="@ry" /></xsl:attribute></xsl:if> <xsl:apply-templates mode="id" select="." /> <xsl:apply-templates mode="template_fill" select="." /> <xsl:apply-templates mode="template_stroke" select="." /> - <xsl:apply-templates mode="stroke_width" select="." /> <xsl:apply-templates mode="stroke_miterlimit" select="." /> <xsl:apply-templates mode="stroke_dasharray" select="." /> <xsl:apply-templates mode="stroke_dashoffset" select="." /> @@ -1250,6 +2543,7 @@ Fixme: is this template still in use? --> <xsl:apply-templates mode="stroke_linecap" select="." /> <xsl:apply-templates mode="filter_effect" select="." /> <xsl:apply-templates mode="resources" select="." /> + <xsl:apply-templates mode="object_opacity" select="." /> <xsl:apply-templates mode="desc" select="." /> <xsl:apply-templates mode="clip" select="." /> @@ -1261,7 +2555,10 @@ Fixme: is this template still in use? --> </Rectangle> </xsl:template> -<!-- Polygon --> +<!-- + // Polygon object // + SVG: polygon, XAML: Polygon +--> <xsl:template mode="forward" match="*[name(.) = 'polygon']"> <Polygon> <xsl:if test="@points"><xsl:attribute name="Points"><xsl:value-of select="@points" /></xsl:attribute></xsl:if> @@ -1269,14 +2566,15 @@ Fixme: is this template still in use? --> <xsl:apply-templates mode="fill_rule" select="." /> <xsl:apply-templates mode="template_fill" select="." /> <xsl:apply-templates mode="template_stroke" select="." /> - <xsl:apply-templates mode="stroke_width" select="." /> <xsl:apply-templates mode="stroke_miterlimit" select="." /> <xsl:apply-templates mode="stroke_dasharray" select="." /> <xsl:apply-templates mode="stroke_dashoffset" select="." /> <xsl:apply-templates mode="stroke_linejoin" select="." /> <xsl:apply-templates mode="stroke_linecap" select="." /> <xsl:apply-templates mode="filter_effect" select="." /> + <xsl:apply-templates mode="object_opacity" select="." /> <xsl:apply-templates mode="desc" select="." /> + <xsl:apply-templates mode="resources" select="." /> <xsl:apply-templates mode="transform" select="."> <xsl:with-param name="mapped_type" select="'Polygon'" /> @@ -1286,7 +2584,10 @@ Fixme: is this template still in use? --> </Polygon> </xsl:template> -<!-- Polyline --> +<!-- + // Polyline object // + SVG: polyline, XAML: Polyline +--> <xsl:template mode="forward" match="*[name(.) = 'polyline']"> <Polyline> <xsl:if test="@points"><xsl:attribute name="Points"><xsl:value-of select="@points" /></xsl:attribute></xsl:if> @@ -1294,13 +2595,13 @@ Fixme: is this template still in use? --> <xsl:apply-templates mode="fill_rule" select="." /> <xsl:apply-templates mode="template_fill" select="." /> <xsl:apply-templates mode="template_stroke" select="." /> - <xsl:apply-templates mode="stroke_width" select="." /> <xsl:apply-templates mode="stroke_miterlimit" select="." /> <xsl:apply-templates mode="stroke_dasharray" select="." /> <xsl:apply-templates mode="stroke_dashoffset" select="." /> <xsl:apply-templates mode="stroke_linejoin" select="." /> <xsl:apply-templates mode="stroke_linecap" select="." /> <xsl:apply-templates mode="filter_effect" select="." /> + <xsl:apply-templates mode="object_opacity" select="." /> <xsl:apply-templates mode="desc" select="." /> <xsl:apply-templates mode="transform" select="."> @@ -1311,26 +2612,31 @@ Fixme: is this template still in use? --> </Polyline> </xsl:template> -<!-- Path --> +<!-- + // Path // + SVG: path, XAML: Path +--> <xsl:template mode="forward" match="*[name(.) = 'path']"> <Path> <xsl:apply-templates mode="id" select="." /> <xsl:apply-templates mode="template_fill" select="." /> <xsl:apply-templates mode="template_stroke" select="." /> - <xsl:apply-templates mode="stroke_width" select="." /> <xsl:apply-templates mode="stroke_miterlimit" select="." /> <xsl:apply-templates mode="stroke_dasharray" select="." /> <xsl:apply-templates mode="stroke_dashoffset" select="." /> <xsl:apply-templates mode="stroke_linejoin" select="." /> <xsl:apply-templates mode="stroke_linecap" select="." /> <xsl:apply-templates mode="filter_effect" select="." /> + <xsl:apply-templates mode="object_opacity" select="." /> <xsl:apply-templates mode="desc" select="." /> - + <xsl:apply-templates mode="resources" select="." /> + <xsl:apply-templates mode="clip" select="." /> + <xsl:if test="@d"> <xsl:choose> <xsl:when test="$silverlight_compatible = 1"> <xsl:attribute name="Data"> - <xsl:value-of select="translate(@d , ',', ' ')" /> + <xsl:value-of select="translate(@d , ',', ' ')" /> </xsl:attribute> </xsl:when> <xsl:otherwise> @@ -1354,7 +2660,10 @@ Fixme: is this template still in use? --> </Path> </xsl:template> -<!-- Ellipse --> +<!-- + // Ellipse object // + SVG: ellipse, XAML: Ellipse +--> <xsl:template mode="forward" match="*[name(.) = 'ellipse']"> <Ellipse> <xsl:variable name="cx"> @@ -1380,14 +2689,15 @@ Fixme: is this template still in use? --> <xsl:apply-templates mode="id" select="." /> <xsl:apply-templates mode="template_fill" select="." /> <xsl:apply-templates mode="template_stroke" select="." /> - <xsl:apply-templates mode="stroke_width" select="." /> <xsl:apply-templates mode="stroke_miterlimit" select="." /> <xsl:apply-templates mode="stroke_dasharray" select="." /> <xsl:apply-templates mode="stroke_dashoffset" select="." /> <xsl:apply-templates mode="stroke_linejoin" select="." /> <xsl:apply-templates mode="stroke_linecap" select="." /> <xsl:apply-templates mode="filter_effect" select="." /> + <xsl:apply-templates mode="object_opacity" select="." /> <xsl:apply-templates mode="desc" select="." /> + <xsl:apply-templates mode="resources" select="." /> <xsl:apply-templates mode="clip" select="." /> <xsl:apply-templates mode="transform" select="."> @@ -1398,7 +2708,10 @@ Fixme: is this template still in use? --> </Ellipse> </xsl:template> -<!-- Circle --> +<!-- + // Circle object // + SVG: circle, XAML: Ellipse +--> <xsl:template mode="forward" match="*[name(.) = 'circle']"> <Ellipse> <xsl:variable name="cx"> @@ -1422,14 +2735,15 @@ Fixme: is this template still in use? --> <xsl:apply-templates mode="id" select="." /> <xsl:apply-templates mode="template_fill" select="." /> <xsl:apply-templates mode="template_stroke" select="." /> - <xsl:apply-templates mode="stroke_width" select="." /> <xsl:apply-templates mode="stroke_miterlimit" select="." /> <xsl:apply-templates mode="stroke_dasharray" select="." /> <xsl:apply-templates mode="stroke_dashoffset" select="." /> <xsl:apply-templates mode="stroke_linejoin" select="." /> <xsl:apply-templates mode="stroke_linecap" select="." /> <xsl:apply-templates mode="filter_effect" select="." /> + <xsl:apply-templates mode="object_opacity" select="." /> <xsl:apply-templates mode="desc" select="." /> + <xsl:apply-templates mode="resources" select="." /> <xsl:apply-templates mode="clip" select="." /> <xsl:apply-templates mode="transform" select="."> @@ -1440,43 +2754,195 @@ Fixme: is this template still in use? --> </Ellipse> </xsl:template> +<!-- + // Image object// + SVG: image, FXG: Image +--> +<xsl:template mode="forward" match="*[name(.) = 'image']"> + <Image> + <xsl:apply-templates mode="id" select="." /> + <xsl:if test="@x"> + <xsl:attribute name="Canvas.Left"> + <xsl:call-template name="convert_unit"> + <xsl:with-param name="convert_value" select="@x" /> + </xsl:call-template> + </xsl:attribute> + </xsl:if> + <xsl:if test="@y"> + <xsl:attribute name="Canvas.Top"> + <xsl:call-template name="convert_unit"> + <xsl:with-param name="convert_value" select="@y" /> + </xsl:call-template> + </xsl:attribute> + </xsl:if> + <xsl:apply-templates mode="desc" select="." /> + <xsl:apply-templates mode="clip" select="." /> + <xsl:if test="@xlink:href"> + <xsl:attribute name="Source"> + <xsl:value-of select="@xlink:href" /> + </xsl:attribute> + </xsl:if> + <xsl:if test="@width"> + <xsl:attribute name="Width"> + <xsl:call-template name="convert_unit"> + <xsl:with-param name="convert_value" select="@width" /> + </xsl:call-template> + </xsl:attribute> + </xsl:if> + <xsl:if test="@height"> + <xsl:attribute name="Height"> + <xsl:call-template name="convert_unit"> + <xsl:with-param name="convert_value" select="@height" /> + </xsl:call-template> + </xsl:attribute> + </xsl:if> + + <xsl:apply-templates mode="image_stretch" select="." /> + <xsl:apply-templates mode="object_opacity" select="." /> + <xsl:apply-templates mode="resources" select="." /> + + <xsl:apply-templates mode="transform" select="."> + <xsl:with-param name="mapped_type" select="'Image'" /> + </xsl:apply-templates> + <xsl:apply-templates mode="forward" /> + </Image> +</xsl:template> + <!-- // Geometry // * Generic clip path template +* Geometry for path * Geometry for circle * Geometry for rectangle --> -<!-- Generic clip path template --> +<!-- + // Generic clip path template // +--> <xsl:template mode="forward" match="*[name(.) = 'clipPath']"> <xsl:apply-templates mode="geometry" /> </xsl:template> -<!-- Geometry for circle --> -<xsl:template mode="geometry" match="*[name(.) = 'circle']"> +<!-- + // Clip Geometry for path // + TODO: PathGeometry is positionned in the object's space, and thus needs to be translated. +--> +<xsl:template mode="geometry" match="*[name(.) = 'path']"> + <PathGeometry> + <xsl:if test="../@id"> + <xsl:attribute name="x:Key"> + <xsl:value-of select="../@id" /> + </xsl:attribute> + </xsl:if> + <xsl:attribute name="Figures"> + <xsl:value-of select="translate(@d , ',', ' ')" /> + </xsl:attribute> + <xsl:apply-templates mode="fill_rule" select="." /> + <xsl:apply-templates mode="transform" select="."> + <xsl:with-param name="mapped_type" select="'PathGeometry'" /> + </xsl:apply-templates> + </PathGeometry> +</xsl:template> + +<!-- + // Clip Geometry for circle // +--> +<xsl:template mode="geometry" match="*[name(.) = 'circle' or name(.) = 'ellipse']"> <EllipseGeometry> - <xsl:if test="../@id"><xsl:attribute name="x:Key"><xsl:value-of select="../@id" /></xsl:attribute></xsl:if> - <xsl:if test="@cx and @cy"><xsl:attribute name="Center"><xsl:value-of select="concat(@cx, ',', @cy)" /></xsl:attribute></xsl:if> + <xsl:if test="../@id"> + <xsl:attribute name="x:Key"> + <xsl:value-of select="../@id" /> + </xsl:attribute> + </xsl:if> + <xsl:if test="@cx and @cy"> + <xsl:attribute name="Center"> + <xsl:value-of select="concat(@cx, ',', @cy)" /> + </xsl:attribute> + </xsl:if> <xsl:if test="@r"> - <xsl:attribute name="RadiusX"><xsl:value-of select="@r" /></xsl:attribute> - <xsl:attribute name="RadiusY"><xsl:value-of select="@r" /></xsl:attribute> + <xsl:attribute name="RadiusX"> + <xsl:value-of select="@r" /> + </xsl:attribute> + <xsl:attribute name="RadiusY"> + <xsl:value-of select="@r" /> + </xsl:attribute> </xsl:if> + <xsl:if test="@rx"> + <xsl:attribute name="RadiusX"> + <xsl:value-of select="@rx" /> + </xsl:attribute> + </xsl:if> + <xsl:if test="@ry"> + <xsl:attribute name="RadiusY"> + <xsl:value-of select="@ry" /> + </xsl:attribute> + </xsl:if> + <xsl:apply-templates mode="transform" select="."> + <xsl:with-param name="mapped_type" select="'EllipseGeometry'" /> + </xsl:apply-templates> </EllipseGeometry> </xsl:template> -<!-- Geometry for rectangle --> +<!-- + // Clip Geometry for rectangle // +--> <xsl:template mode="geometry" match="*[name(.) = 'rect']"> <RectangleGeometry> - <xsl:if test="../@id"><xsl:attribute name="x:Key"><xsl:value-of select="../@id" /></xsl:attribute></xsl:if> - <!-- - <xsl:if test="@x"><xsl:attribute name="Canvas.Left"><xsl:value-of select="@x" /></xsl:attribute></xsl:if> - <xsl:if test="@y"><xsl:attribute name="Canvas.Top"><xsl:value-of select="@y" /></xsl:attribute></xsl:if> - <xsl:if test="@width"><xsl:attribute name="Width"><xsl:value-of select="@width" /></xsl:attribute></xsl:if> - <xsl:if test="@height"><xsl:attribute name="Height"><xsl:value-of select="@height" /></xsl:attribute></xsl:if> - <xsl:if test="@rx"><xsl:attribute name="RadiusX"><xsl:value-of select="@rx" /></xsl:attribute></xsl:if> - <xsl:if test="@ry"><xsl:attribute name="RadiusY"><xsl:value-of select="@ry" /></xsl:attribute></xsl:if> - --> - <xsl:attribute name="Rect"><xsl:value-of select="concat('0, 0, ', @width, ', ', @height)" /></xsl:attribute> + <xsl:if test="../@id"> + <xsl:attribute name="x:Key"> + <xsl:value-of select="../@id" /> + </xsl:attribute> + </xsl:if> + <xsl:variable name="x"> + <xsl:call-template name="convert_unit"> + <xsl:with-param name="convert_value" select="@x" /> + </xsl:call-template> + </xsl:variable> + <xsl:variable name="y"> + <xsl:call-template name="convert_unit"> + <xsl:with-param name="convert_value" select="@y" /> + </xsl:call-template> + </xsl:variable> + <xsl:variable name="width"> + <xsl:call-template name="convert_unit"> + <xsl:with-param name="convert_value" select="@width" /> + </xsl:call-template> + </xsl:variable> + <xsl:variable name="height"> + <xsl:call-template name="convert_unit"> + <xsl:with-param name="convert_value" select="@height" /> + </xsl:call-template> + </xsl:variable> + <xsl:if test="@rx"> + <xsl:attribute name="RadiusX"> + <xsl:value-of select="@rx" /> + </xsl:attribute> + </xsl:if> + <xsl:if test="@ry"> + <xsl:attribute name="RadiusY"> + <xsl:value-of select="@ry" /> + </xsl:attribute> + </xsl:if> + <xsl:if test="@rx and not(@ry)"> + <xsl:attribute name="RadiusX"> + <xsl:value-of select="@rx" /> + </xsl:attribute> + <xsl:attribute name="RadiusY"> + <xsl:value-of select="@rx" /> + </xsl:attribute> + </xsl:if> + <xsl:if test="@ry and not(@rx)"> + <xsl:attribute name="RadiusX"> + <xsl:value-of select="@ry" /> + </xsl:attribute> + <xsl:attribute name="RadiusY"> + <xsl:value-of select="@ry" /> + </xsl:attribute> + </xsl:if> + <xsl:attribute name="Rect"><xsl:value-of select="concat($x, ', ', $y, ', ', $width, ', ', $height)" /></xsl:attribute> + <xsl:apply-templates mode="transform" select="."> + <xsl:with-param name="mapped_type" select="'RectangleGeometry'" /> + </xsl:apply-templates> </RectangleGeometry> </xsl:template> diff --git a/share/extensions/svg_and_media_zip_output.inx b/share/extensions/svg_and_media_zip_output.inx index c6597a03f..f8a4c02f4 100644 --- a/share/extensions/svg_and_media_zip_output.inx +++ b/share/extensions/svg_and_media_zip_output.inx @@ -1,19 +1,21 @@ <?xml version="1.0" encoding="UTF-8"?> <inkscape-extension xmlns="http://www.inkscape.org/namespace/inkscape/extension"> - <_name>ZIP Output</_name> - <id>org.inkscape.output.ZIP</id> - <dependency type="extension">org.inkscape.output.svg.inkscape</dependency> - <dependency type="executable" location="extensions">svg_and_media_zip_output.py</dependency> - <dependency type="executable" location="extensions">inkex.py</dependency> - <output> - <extension>.zip</extension> - <mimetype>application/x-zip</mimetype> - <_filetypename>Compressed Inkscape SVG with media (*.zip)</_filetypename> - <_filetypetooltip>Inkscape's native file format compressed with Zip and including all media files</_filetypetooltip> - <dataloss>false</dataloss> - </output> - <script> - <command reldir="extensions" interpreter="python">svg_and_media_zip_output.py</command> - <helper_extension>org.inkscape.output.svg.inkscape</helper_extension> - </script> + <_name>Compressed Inkscape SVG with media export</_name> + <id>org.inkscape.output.ZIP</id> + <dependency type="extension">org.inkscape.output.svg.inkscape</dependency> + <dependency type="executable" location="extensions">svg_and_media_zip_output.py</dependency> + <dependency type="executable" location="extensions">inkex.py</dependency> + <param name="image_dir" type="string" _gui-text="Image zip directory:">images</param> + <param name="font_list" type="boolean" _gui-text="Add font list">false</param> + <output> + <extension>.zip</extension> + <mimetype>application/x-zip</mimetype> + <_filetypename>Compressed Inkscape SVG with media (*.zip)</_filetypename> + <_filetypetooltip>Inkscape's native file format compressed with Zip and including all media files</_filetypetooltip> + <dataloss>false</dataloss> + </output> + <script> + <command reldir="extensions" interpreter="python">svg_and_media_zip_output.py</command> + <helper_extension>org.inkscape.output.svg.inkscape</helper_extension> + </script> </inkscape-extension> diff --git a/share/extensions/svg_and_media_zip_output.py b/share/extensions/svg_and_media_zip_output.py index 640c9ede4..62e2b2ef5 100644 --- a/share/extensions/svg_and_media_zip_output.py +++ b/share/extensions/svg_and_media_zip_output.py @@ -1,11 +1,16 @@ #!/usr/bin/env python -""" +''' svg_and_media_zip_output.py An extention which collects all images to the documents directory and creates a zip archive containing all images and the document Copyright (C) 2005 Pim Snel, pim@lingewoud.com Copyright (C) 2008 Aaron Spike, aaron@ekips.org +Copyright (C) 2011 Nicolas Dufour, nicoduf@yahoo.fr + * Fix for a bug related to special caracters in the path (LP #456248). + * Fix for Windows support (LP #391307 ). + * Font list and image directory features. + this is the first Python script ever created its based on embedimage.py @@ -23,17 +28,14 @@ You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -Version 0.5 (Nicolas Dufour, nicoduf@yahoo.fr) - Fix a bug related to special caracters in the path (LP #456248). - -TODO +TODOs - fix bug: not saving existing .zip after a Collect for Output is run this bug occurs because after running an effect extention the inkscape:output_extension is reset to svg.inkscape the file name is still xxx.zip. after saving again the file xxx.zip is written with a plain .svg which looks like a corrupt zip - maybe add better extention - consider switching to lzma in order to allow cross platform compression with no encoding problem... -""" +''' import inkex import urlparse @@ -44,18 +46,42 @@ import zipfile import shutil import sys import tempfile +import simplestyle import gettext +import locale +locale.setlocale(locale.LC_ALL, '') _ = gettext.gettext -class SVG_and_Media_ZIP_Output(inkex.Effect): +class CompressedMediaOutput(inkex.Effect): def __init__(self): inkex.Effect.__init__(self) if os.name == 'nt': self.encoding = "cp437" else: - self.encoding = "latin-1" + self.encoding = "latin-1" + self.text_tags = ['{http://www.w3.org/2000/svg}tspan', + '{http://www.w3.org/2000/svg}text', + '{http://www.w3.org/2000/svg}flowRoot', + '{http://www.w3.org/2000/svg}flowPara', + '{http://www.w3.org/2000/svg}flowSpan'] + self.OptionParser.add_option("--image_dir", + action="store", type="string", + dest="image_dir", default="", + help="Image directory") + self.OptionParser.add_option("--font_list", + action="store", type="inkbool", + dest="font_list", default=False, + help="Add font list") + self.OptionParser.add_option("--tab", + action="store", type="string", + dest="tab", + help="The selected UI-tab when OK was pressed") def output(self): + ''' + Writes the temporary compressed file to its destination + and removes the temporary directory. + ''' out = open(self.zip_file,'rb') if os.name == 'nt': try: @@ -65,74 +91,139 @@ class SVG_and_Media_ZIP_Output(inkex.Effect): pass sys.stdout.write(out.read()) out.close() - self.clear_tmp() - - def clear_tmp(self): shutil.rmtree(self.tmp_dir) - def effect(self): - ttmp_orig = self.document.getroot() - - docname = ttmp_orig.get(inkex.addNS('docname',u'sodipodi')) - if docname is None: docname = self.args[-1] - - #create os temp dir - self.tmp_dir = tempfile.mkdtemp() - - #fixme replace whatever extention - docstripped = docname.replace('.zip', '') - docstripped = docstripped.replace('.svg', '') - docstripped = docstripped.replace('.svgz', '') - - # create destination zip in same directory as the document - self.zip_file = os.path.join(self.tmp_dir, docstripped) + '.zip' - z = zipfile.ZipFile(self.zip_file, 'w') - - #read tmpdoc and copy all images to temp dir + def collect_images(self, docname, z): + ''' + Collects all images in the document + and copy them to the temporary directory. + ''' + if locale.getpreferredencoding(): + dir_locale = locale.getpreferredencoding() + else: + dir_locale = "UTF-8" + dir = unicode(self.options.image_dir, dir_locale) for node in self.document.xpath('//svg:image', namespaces=inkex.NSS): - self.collectAndZipImages(node, docname, z) - - ##copy tmpdoc to tempdir + xlink = node.get(inkex.addNS('href',u'xlink')) + if (xlink[:4] != 'data'): + absref = node.get(inkex.addNS('absref',u'sodipodi')) + url = urlparse.urlparse(xlink) + href = urllib.url2pathname(url.path) + + if (href != None): + absref = os.path.realpath(href) + + absref = unicode(absref, "utf-8") + image_path = os.path.join(dir, os.path.basename(absref)) + + if (os.path.isfile(absref)): + shutil.copy(absref, self.tmp_dir) + z.write(absref, image_path.encode(self.encoding)) + elif (os.path.isfile(os.path.join(self.tmp_dir, absref))): + # TODO: please explain why this clause is necessary + shutil.copy(os.path.join(self.tmp_dir, absref), self.tmp_dir) + z.write(os.path.join(self.tmp_dir, absref), image_path.encode(self.encoding)) + else: + inkex.errormsg(_('Could not locate file: %s') % absref) + + node.set(inkex.addNS('href',u'xlink'), image_path) + #node.set(inkex.addNS('absref',u'sodipodi'), image_path) + + def collect_SVG(self, docstripped, z): + ''' + Copy SVG document to the temporary directory + and add it to the temporary compressed file + ''' dst_file = os.path.join(self.tmp_dir, docstripped) stream = open(dst_file,'w') - self.document.write(stream) - stream.close() - z.write(dst_file,docstripped.encode(self.encoding)+'.svg') - z.close() - - def collectAndZipImages(self, node, docname, z): - xlink = node.get(inkex.addNS('href',u'xlink')) - if (xlink[:4]!='data'): - absref=node.get(inkex.addNS('absref',u'sodipodi')) - url=urlparse.urlparse(xlink) - href=urllib.url2pathname(url.path) + def is_text(self, node): + ''' + Returns true if the tag in question is an element that + can hold text. + ''' + return node.tag in self.text_tags + + def get_fonts(self, node): + ''' + Given a node, returns a list containing all the fonts that + the node is using. + ''' + fonts = [] + s = '' + if 'style' in node.attrib: + s = simplestyle.parseStyle(node.attrib['style']) + if not s: + return fonts - if (href != None): - absref=os.path.realpath(href) - - absref=unicode(absref, "utf-8") - - if (os.path.isfile(absref)): - shutil.copy(absref, self.tmp_dir) - z.write(absref, os.path.basename(absref).encode(self.encoding)) - elif (os.path.isfile(os.path.join(self.tmp_dir, absref))): - #TODO: please explain why this clause is necessary - shutil.copy(os.path.join(self.tmp_dir, absref), self.tmp_dir) - z.write(os.path.join(self.tmp_dir, absref), - os.path.basename(absref).encode(self.encoding)) + if s.has_key('font-family'): + if s.has_key('font-weight'): + fonts.append(s['font-family'] + ' ' + s['font-weight']) + else: + fonts.append(s['font-family']) + elif s.has_key('-inkscape-font-specification'): + fonts.append(s['-inkscape-font-specification']) + return fonts + + def list_fonts(self, z): + ''' + Walks through nodes, building a list of all fonts found, then + reports to the user with that list. + Based on Craig Marshall's replace_font.py + ''' + items = [] + nodes = [] + items = self.document.getroot().getiterator() + nodes.extend(filter(self.is_text, items)) + fonts_found = [] + for node in nodes: + for f in self.get_fonts(node): + if not f in fonts_found: + fonts_found.append(f) + findings = sorted(fonts_found) + # Write list to the temporary compressed file + filename = 'fontlist.txt' + dst_file = os.path.join(self.tmp_dir, filename) + stream = open(dst_file,'w') + if len(findings) == 0: + stream.write(_("Didn't find any fonts in this document/selection.")) + else: + if len(findings) == 1: + stream.write(_("Found the following font only: %s") % findings[0]) else: - inkex.errormsg(_('Could not locate file: %s') % absref) + stream.write(_("Found the following fonts:\n%s") % '\n'.join(findings)) + stream.close() + z.write(dst_file, filename) + - node.set(inkex.addNS('href',u'xlink'),os.path.basename(absref)) - node.set(inkex.addNS('absref',u'sodipodi'),os.path.basename(absref)) + def effect(self): + docroot = self.document.getroot() + docname = docroot.get(inkex.addNS('docname',u'sodipodi')) + #inkex.errormsg(_('Locale: %s') % locale.getpreferredencoding()) + if docname is None: + docname = self.args[-1] + # TODO: replace whatever extention + docstripped = os.path.basename(docname.replace('.zip', '')) + docstripped = docstripped.replace('.svg', '') + docstripped = docstripped.replace('.svgz', '') + # Create os temp dir + self.tmp_dir = tempfile.mkdtemp() + # Create destination zip in same directory as the document + self.zip_file = os.path.join(self.tmp_dir, docstripped) + '.zip' + z = zipfile.ZipFile(self.zip_file, 'w') + + self.collect_images(docname, z) + self.collect_SVG(docstripped, z) + if self.options.font_list == True: + self.list_fonts(z) + z.close() if __name__ == '__main__': #pragma: no cover - e = SVG_and_Media_ZIP_Output() + e = CompressedMediaOutput() e.affect() diff --git a/share/extensions/test/render_barcode.data b/share/extensions/test/render_barcode.data new file mode 100644 index 000000000..a5052faca --- /dev/null +++ b/share/extensions/test/render_barcode.data @@ -0,0 +1,500 @@ +ean8:9493712:2020001011010001100010110111101020201000100110011011011001100110202 +ean8:2811738:2020010011011011100110010011001020201000100100001010010001011100202 +ean8:2248057:2020010011001001101000110110111020201110010100111010001001010000202 +ean8:0995042:2020001101000101100010110110001020201110010101110011011001110100202 +ean8:0262682:2020001101001001101011110010011020201010000100100011011001010000202 +ean8:2006346:2020010011000110100011010101111020201000010101110010100001000100202 +ean8:9892307:2020001011011011100010110010011020201000010111001010001001010000202 +ean8:7033691:2020111011000110101111010111101020201010000111010011001101000100202 +ean8:6587381:2020101111011000101101110111011020201000010100100011001101010000202 +ean8:4491441:2020100011010001100010110011001020201011100101110011001101000100202 +ean8:0099044:2020001101000110100010110001011020201110010101110010111001001000202 +ean8:7565347:2020111011011000101011110110001020201000010101110010001001000100202 +ean8:0764195:2020001101011101101011110100011020201100110111010010011101011100202 +ean8:4882328:2020100011011011101101110010011020201000010110110010010001110100202 +ean8:4635078:2020100011010111101111010110001020201110010100010010010001000100202 +ean8:8992114:2020110111000101100010110010011020201100110110011010111001101100202 +ean8:6658162:2020101111010111101100010110111020201100110101000011011001001000202 +ean8:7880049:2020111011011011101101110001101020201110010101110011101001010000202 +ean8:7782648:2020111011011101101101110010011020201010000101110010010001110010202 +ean8:8249002:2020110111001001101000110001011020201110010111001011011001000100202 +ean8:8735885:2020110111011101101111010110001020201001000100100010011101001000202 +ean8:9818050:2020001011011011100110010110111020201110010100111011100101110100202 +ean8:3410390:2020111101010001100110010001101020201000010111010011100101010000202 +ean8:9699144:2020001011010111100010110001011020201100110101110010111001101100202 +ean8:7628790:2020111011010111100100110110111020201000100111010011100101110100202 +ean8:2020310:2020010011000110100100110001101020201000010110011011100101001000202 +ean8:0429248:2020001101010001100100110001011020201101100101110010010001000100202 +ean8:3135528:2020111101001100101111010110001020201001110110110010010001001110202 +ean8:3182301:2020111101001100101101110010011020201000010111001011001101101100202 +ean8:0320063:2020001101011110100100110001101020201110010101000010000101010000202 +ean8:0865925:2020001101011011101011110110001020201110100110110010011101001110202 +ean8:3413434:2020111101010001100110010111101020201011100100001010111001011100202 +ean8:6730313:2020101111011101101111010001101020201000010110011010000101000100202 +ean8:4091215:2020100011000110100010110011001020201101100110011010011101001000202 +ean8:6504268:2020101111011000100011010100011020201101100101000010010001000100202 +ean8:0127593:2020001101001100100100110111011020201001110111010010000101000010202 +ean8:9214184:2020001011001001100110010100011020201100110100100010111001100110202 +ean8:4457000:2020100011010001101100010111011020201110010111001011100101101100202 +ean8:2575579:2020010011011000101110110110001020201001110100010011101001011100202 +ean8:3501739:2020111101011000100011010011001020201000100100001011101001011100202 +ean8:0733658:2020001101011101101111010111101020201010000100111010010001011100202 +ean8:6162818:2020101111001100101011110010011020201001000110011010010001101100202 +ean8:2397509:2020010011011110100010110111011020201001110111001011101001001110202 +ean8:3813610:2020111101011011100110010111101020201010000110011011100101001000202 +ean8:9488712:2020001011010001101101110110111020201000100110011011011001110100202 +ean8:1754326:2020011001011101101100010100011020201000010110110010100001101100202 +ean8:5221351:2020110001001001100100110011001020201000010100111011001101110100202 +ean8:6047658:2020101111000110101000110111011020201010000100111010010001010000202 +ean8:0475473:2020001101010001101110110110001020201011100100010010000101101100202 +ean8:0775368:2020001101011101101110110110001020201000010101000010010001001000202 +ean8:5825189:2020110001011011100100110110001020201100110100100011101001001000202 +ean8:9934666:2020001011000101101111010100011020201010000101000010100001110100202 +ean8:4849196:2020100011011011101000110001011020201100110111010010100001110100202 +ean8:6672405:2020101111010111101110110010011020201011100111001010011101010000202 +ean8:6368942:2020101111011110101011110110111020201110100101110011011001010000202 +ean8:0356360:2020001101011110101100010101111020201000010101000011100101100110202 +ean8:1506024:2020011001011000100011010101111020201110010110110010111001101100202 +ean8:0218852:2020001101001001100110010110111020201001000100111011011001101100202 +ean8:4357801:2020100011011110101100010111011020201001000111001011001101010000202 +ean8:8268643:2020110111001001101011110110111020201010000101110010000101000100202 +ean8:0117677:2020001101001100100110010111011020201010000100010010001001000010202 +ean8:8066330:2020110111000110101011110101111020201000010100001011100101110010202 +ean8:3074324:2020111101000110101110110100011020201000010110110010111001000010202 +ean8:7241642:2020111011001001101000110011001020201010000101110011011001010000202 +ean8:3375910:2020111101011110101110110110001020201110100110011011100101011100202 +ean8:5797167:2020110001011101100010110111011020201100110101000010001001011100202 +ean8:4413827:2020100011010001100110010111101020201001000110110010001001100110202 +ean8:0008083:2020001101000110100011010110111020201110010100100010000101001110202 +ean8:3240693:2020111101001001101000110001101020201010000111010010000101100110202 +ean8:3358989:2020111101011110101100010110111020201110100100100011101001000010202 +ean8:2525297:2020010011011000100100110110001020201101100111010010001001101100202 +ean8:9429514:2020001011010001100100110001011020201001110110011010111001010000202 +ean8:7496160:2020111011010001100010110101111020201100110101000011100101000010202 +ean8:2549811:2020010011011000101000110001011020201001000110011011001101110010202 +ean8:0366059:2020001101011110101011110101111020201110010100111011101001100110202 +ean8:7565529:2020111011011000101011110110001020201001110110110011101001000100202 +ean8:0544331:2020001101011000101000110100011020201000010100001011001101011100202 +ean8:5278325:2020110001001001101110110110111020201000010110110010011101001000202 +ean8:9659719:2020001011010111101100010001011020201000100110011011101001011100202 +ean8:6060276:2020101111000110101011110001101020201101100100010010100001000010202 +ean8:9983234:2020001011000101101101110111101020201101100100001010111001010000202 +ean8:9912723:2020001011000101100110010010011020201000100110110010000101000100202 +ean8:3934993:2020111101000101101111010100011020201110100111010010000101011100202 +ean8:9878705:2020001011011011101110110110111020201000100111001010011101110010202 +ean8:6099896:2020101111000110100010110001011020201001000111010010100001001110202 +ean8:9344302:2020001011011110101000110100011020201000010111001011011001110100202 +ean8:5779196:2020110001011101101110110001011020201100110111010010100001001000202 +ean8:2670364:2020010011010111101110110001101020201000010101000010111001110010202 +ean8:4049157:2020100011000110101000110001011020201100110100111010001001001000202 +ean8:6303180:2020101111011110100011010111101020201100110100100011100101001110202 +ean8:4252404:2020100011001001101100010010011020201011100111001010111001001110202 +ean8:6442834:2020101111010001101000110010011020201001000100001010111001001110202 +ean8:7330702:2020111011011110101111010001101020201000100111001011011001110010202 +ean8:6650523:2020101111010111101100010001101020201001110110110010000101001110202 +ean8:3261954:2020111101001001101011110011001020201110100100111010111001010000202 +ean8:1149083:2020011001001100101000110001011020201110010100100010000101001000202 +ean8:1227062:2020011001001001100100110111011020201110010101000011011001110010202 +ean8:7770854:2020111011011101101110110001101020201001000100111010111001110010202 +ean8:4841093:2020100011011011101000110011001020201110010111010010000101110100202 +ean8:9642244:2020001011010111101000110010011020201101100101110010111001100110202 +ean13:082432472648:20201101110010011010001101111010010011010001102020100010011011001010000101110010010001110010202 +ean13:867963203104:20201011110010001000101100001010100001001001102020111001010000101100110111001010111001001110202 +ean13:509274672682:20200011010010111001101101110110100011000010102020100010011011001010000100100011011001110010202 +ean13:137969745319:20201111010111011001011101011110010111001000102020101110010011101000010110011011101001101100202 +ean13:167788639568:20201011110111011001000101101110001001000010102020100001011101001001110101000010010001101100202 +ean13:763909437639:20201011110100001000101101001110001011001110102020100001010001001010000100001011101001110010202 +ean13:552090940230:20201100010011011010011100010110001101001011102020101110011100101101100100001011100101110100202 +ean13:064430020090:20201011110100011010001101111010001101000110102020110110011100101110010111010011100101001000202 +ean13:932131660272:20201111010011011011001101111010110011010111102020101000011100101101100100010011011001001000202 +ean13:697948544222:20200010110010001001011100111010110111011000102020101110010111001101100110110011011001110010202 +ean13:156973387097:20201100010101111001011101110110100001010000102020100100010001001110010111010010001001100110202 +ean13:742353933447:20201000110011011011110101110010111101001011102020100001010000101011100101110010001001001000202 +ean13:165804313397:20201011110110001000100100011010011101010000102020110011010000101000010111010010001001101100202 +ean13:142542648187:20201000110010011011100101000110011011000010102020101110010010001100110100100010001001101100202 +ean13:293746185362:20200010110111101001000100111010101111011001102020100100010011101000010101000011011001011100202 +ean13:079018947306:20201110110001011000110100110010110111000101102020101110010001001000010111001010100001110010202 +ean13:114714603442:20200110010100011001000100110010011101000010102020111001010000101011100101110011011001000100202 +ean13:886864480655:20201101110000101011011100001010011101010001102020100100011100101010000100111010011101011100202 +ean13:087399049352:20201101110111011011110100010110001011000110102020101110011101001000010100111011011001000010202 +ean13:680731212600:20201101110100111001000101000010011001001001102020110011011011001010000111001011100101001000202 +ean13:839853108496:20201111010010111011011101110010100001001100102020111001010010001011100111010010100001001000202 +ean13:759662798861:20201100010010111010111100001010010011001000102020111010010010001001000101000011001101011100202 +ean13:522030126885:20200100110011011010011101111010001101011001102020110110010100001001000100100010011101011100202 +ean13:872252192093:20201110110011011001001101110010011011001100102020111010011011001110010111010010000101011100202 +ean13:978323527315:20201110110001001010000100100110100001011000102020110110010001001000010110011010011101110100202 +ean13:594820728295:20200010110011101000100100100110001101001000102020110110010010001101100111010010011101000100202 +ean13:817309047999:20200110010010001011110101001110010111000110102020101110010001001110100111010011101001011100202 +ean13:529552650589:20200100110010111011100101100010010011000010102020100111011100101001110100100011101001000010202 +ean13:301953031072:20200011010011001001011101110010100001000110102020100001011001101110010100010011011001101100202 +ean13:279759074172:20201110110001011001000101110010001011010011102020100010010111001100110100010011011001011100202 +ean13:966269952443:20201011110000101001101101011110010111000101102020100111011011001011100101110010000101000100202 +ean13:393886491651:20200010110111101000100100010010000101010001102020111010011001101010000100111011001101110100202 +ean13:592818880852:20200010110011011000100100110010110111000100102020100100011100101001000100111011011001110010202 +ean13:629415132010:20200100110010111001110101100110110001001100102020100001011011001110010110011011100101001000202 +ean13:649798154930:20201000110010111001000100101110110111001100102020100111010111001110100100001011100101110100202 +ean13:106475417609:20200011010101111001110101110110111001001110102020110011010001001010000111001011101001110010202 +ean13:853904645292:20201100010100001000101101001110011101010111102020101110010011101101100111010011011001100110202 +ean13:431977667645:20201111010110011000101101110110010001000010102020101000010001001010000101110010011101000010202 +ean13:814819509497:20200110010011101011011101100110010111011000102020111001011101001011100111010010001001000100202 +ean13:308817835364:20200011010110111000100101100110010001011011102020100001010011101000010101000010111001011100202 +ean13:618801393027:20200110010001001000100101001110011001011110102020111010010000101110010110110010001001110010202 +ean13:164480667538:20201011110100011001110101101110100111000010102020101000010001001001110100001010010001011100202 +ean13:081023710137:20201101110011001000110100100110111101011101102020110011011100101100110100001010001001000100202 +ean13:493359422890:20200010110100001011110101100010010111001110102020110110011011001001000111010011100101110010202 +ean13:275532814865:20201110110110001011100101000010010011000100102020110011010111001001000101000010011101001000202 +ean13:111345042302:20200110010011001010000101000110111001010011102020101110011011001000010111001011011001001000202 +ean13:513537464719:20200110010100001011100101111010111011001110102020101000010111001000100110011011101001001110202 +ean13:766449694282:20201011110000101010001100111010001011000010102020111010010111001101100100100011011001110100202 +ean13:961792988802:20201011110110011001000100010110011011000101102020100100010010001001000111001011011001001110202 +ean13:866540005468:20201011110000101011000100111010100111000110102020111001010011101011100101000010010001101100202 +ean13:888983089059:20201101110001001000101100010010100001000110102020100100011101001110010100111011101001100110202 +ean13:722513175727:20200100110011011011000101100110111101011001102020100010010011101000100110110010001001110100202 +ean13:843297735811:20201000110100001001001100101110010001011101102020100001010011101001000110011011001101101100202 +ean13:627233353075:20200100110010001001101101000010111101011110102020100111010000101110010100010010011101110010202 +ean13:203591705672:20200011010111101011100100101110011001001000102020111001010011101010000100010011011001001110202 +ean13:686779501514:20201101110000101001000100100010001011011000102020111001011001101001110110011010111001001110202 +ean13:379483955591:20201110110001011001110100010010100001000101102020100111010011101001110111010011001101101100202 +ean13:576363706332:20201110110000101010000101011110111101001000102020111001010100001000010100001011011001000010202 +ean13:295226681860:20200010110110001001101100110110101111000010102020100100011001101001000101000011100101110100202 +ean13:901443422086:20200011010110011001110101000110100001010001102020110110011011001110010100100010100001000100202 +ean13:093300442985:20200010110111101011110100011010001101010001102020101110011011001110100100100010011101000010202 +ean13:517520551545:20200110010010001011100100100110001101011100102020100111011001101001110101110010011101000010202 +ean13:370982564882:20201110110001101001011100010010011011011000102020101000010111001001000100100011011001110010202 +ean13:640884610730:20201000110100111000100100010010100011010111102020110011011100101000100100001011100101001110202 +ean13:601211133573:20200011010110011001101101100110011001001100102020100001010000101001110100010010000101110100202 +ean13:772390839786:20201110110011011011110100101110001101000100102020100001011101001000100100100010100001110100202 +ean13:037823325554:20201111010111011011011100100110111101011110102020110110010011101001110100111010111001000010202 +ean13:636746415900:20201111010000101001000100111010101111010001102020110011010011101110100111001011100101000100202 +ean13:378365729312:20201110110110111010000100001010111001011101102020110110011101001000010110011011011001110010202 +ean13:588008084415:20201101110001001010011100011010110111010011102020100100010111001011100110011010011101000010202 +ean13:493847586062:20200010110100001011011101000110010001011100102020100100010100001110010101000011011001110010202 +ean13:661725378018:20201011110110011001000100110110110001011110102020100010010010001110010110011010010001110010202 +ean13:785941917380:20201101110111001000101100111010011001001011102020110011010001001000010100100011100101011100202 +ean13:476858945743:20201110110000101011011101100010001001001011102020101110010011101000100101110010000101010000202 +ean13:621022451023:20200100110110011010011100110110010011010001102020100111011001101110010110110010000101001000202 +ean13:738611126276:20201111010001001010111101100110011001011001102020110110010100001101100100010010100001110010202 +ean13:610023637901:20200110010100111010011100110110111101010111102020100001010001001110100111001011001101001000202 +ean13:310432899227:20200110010001101001110101000010011011011011102020111010011101001101100110110010001001110010202 +ean13:079481718507:20201110110001011010001101101110011001011101102020110011010010001001110111001010001001000010202 +ean13:794525704564:20200010110011101011000100110110110001001000102020111001010111001001110101000010111001010000202 +ean13:367079205365:20201011110111011010011100100010010111001001102020111001010011101000010101000010011101100110202 +ean13:791478205064:20200010110110011010001100100010110111001101102020111001010011101110010101000010111001000100202 +ean13:622805103976:20200100110011011000100101001110110001001100102020111001010000101110100100010010100001100110202 +ean13:659692878482:20201100010010111000010100101110010011011011102020100010010010001011100100100011011001011100202 +ean13:312673979722:20200110010010011000010100100010100001000101102020100010011101001000100110110011011001110010202 +ean13:634789369262:20201111010011101001000100010010001011011110102020101000011101001101100101000011011001000100202 +ean13:508031061191:20200011010001001010011101111010011001010011102020101000011001101100110111010011001101000100202 +ean13:617546677352:20200110010010001011100100111010101111010111102020100010010001001000010100111011011001000010202 +ean13:386750842077:20201101110101111001000101110010100111011011102020101110011011001110010100010010001001100110202 +ean13:217930060540:20200110010111011001011101000010001101010011102020101000011100101001110101110011100101100110202 +ean13:529453929533:20200100110010111001110101100010111101001011102020110110011101001001110100001010000101000010202 +ean13:403667633768:20200011010100001010111101011110010001000010102020100001010000101000100101000010010001110100202 +ean13:788401327704:20201101110001001010001101001110011001010000102020110110010001001000100111001010111001000100202 +ean13:316882500762:20200110010101111000100100010010011011011000102020111001011100101000100101000011011001101100202 +ean13:413254666172:20200110010100001001001101100010011101000010102020101000010100001100110100010011011001100110202 +ean13:666719764771:20201011110000101001000101100110001011011101102020101000010111001000100100010011001101100110202 +ean13:502326102133:20200011010011011010000100100110101111011001102020111001011011001100110100001010000101010000202 +ean13:690549661049:20200010110100111011100100111010001011010111102020101000011001101110010101110011101001001110202 +ean13:055572466568:20201100010110001011000101110110010011010001102020101000010100001001110101000010010001110100202 +ean13:636596356068:20201111010000101011100100101110101111011110102020100111010100001110010101000010010001000010202 +upce:844677:202000100100111010011101010111101110110111011020202 +upce:610879:202000010101100110001101011011101110110010111020202 +upce:982526:202001011100010010011011011000100100110101111020202 +upce:846420:202000100100111010101111010001100110110001101020202 +upce:322140:202010000100110110010011001100100111010001101020202 +upce:625042:202000010100100110110001010011101000110011011020202 +upce:996072:202001011100101110101111000110101110110011011020202 +upce:539996:202011100101000010001011000101100010110000101020202 +upce:340168:202010000100111010001101001100100001010110111020202 +upce:841913:202000100101000110100111000101101100110011001020202 +upce:124122:202011001100110110100011001100100110110010011020202 +upce:401968:202001110100011010110011000101101011110001001020202 +upce:225085:202001101100100110111001010011101101110110001020202 +upce:368038:202010000101011110001001010011101111010110111020202 +upce:817155:202000100100110010111011011001101100010111001020202 +upce:554120:202011100101110010100011011001100100110001101020202 +upce:113080:202011001101100110111101000110101101110100111020202 +upce:755380:202001000101100010110001011110100010010100111020202 +upce:201858:202001101100011010110011000100101100010110111020202 +upce:226567:202001101100100110000101011100101011110111011020202 +upce:507089:202011100101001110111011000110101101110010111020202 +upce:442680:202001110101000110011011010111101101110100111020202 +upce:557738:202011100101100010111011001000101000010110111020202 +upce:928720:202001011100100110001001011101100100110100111020202 +upce:395240:202010000100101110110001001101101000110001101020202 +upce:931548:202001011101111010110011011000101000110001001020202 +upce:729228:202001000100100110001011001001100110110001001020202 +upce:116746:202011001100110010000101011101100111010101111020202 +upce:293469:202001101100101110111101010001101011110010111020202 +upce:555569:202011100101100010111001011000100001010001011020202 +upce:786474:202001000100010010000101010001101110110100011020202 +upce:761950:202001000101011110110011000101101100010100111020202 +upce:585584:202011100101101110111001011000100010010100011020202 +upce:929816:202001011100110110001011011011100110010000101020202 +upce:311259:202010000100110010011001001101101110010001011020202 +upce:694531:202000010100101110011101011000101111010011001020202 +upce:375808:202010000100100010110001011011101101110011101020202 +upce:240462:202001101100111010001101010001100001010010011020202 +upce:309270:202010000100011010010111001001100100010001101020202 +upce:531272:202011100101111010110011001001101110110011011020202 +upce:910577:202001011100110010001101011100100100010111011020202 +upce:816561:202000100100110010000101011000100001010011001020202 +upce:805838:202000100100011010110001011011101000010001001020202 +upce:533215:202011100101000010111101001101100110010110001020202 +upce:346122:202010000101000110000101001100100100110011011020202 +upce:625930:202000010100100110110001001011101000010001101020202 +upce:952717:202001011101110010010011001000100110010111011020202 +upce:402896:202001110101001110010011011011100010110000101020202 +upce:295983:202001101100101110110001000101101101110100001020202 +upce:024592:202010011100100110011101011000100010110011011020202 +upce:289724:202001101101101110010111011101100100110011101020202 +upce:252704:202001101101110010011011011101100011010100011020202 +upce:273290:202001101101110110111101001101100010110100111020202 +upce:385633:202010000100010010110001010111101111010100001020202 +upce:549951:202011100100111010001011001011101100010011001020202 +upce:568347:202011100101011110110111010000100111010111011020202 +upce:214740:202001101100110010011101001000101000110001101020202 +upce:969934:202001011101011110010111000101101111010011101020202 +upce:832367:202000100101111010010011010000100001010111011020202 +upce:359222:202010000101100010001011001101100110110010011020202 +upce:508230:202011100101001110001001001001101111010001101020202 +upce:308002:202010000101001110110111010011100011010010011020202 +upce:318751:202010000100110010001001011101101110010011001020202 +upce:174459:202011001100100010011101010001101100010001011020202 +upce:403448:202001110101001110111101010001101000110001001020202 +upce:429459:202001110100100110010111010001101110010001011020202 +upce:271338:202001101100100010110011011110101111010110111020202 +upce:515949:202011100100110010110001001011101000110010111020202 +upce:066186:202010011101011110000101001100100010010101111020202 +upce:609466:202000010100011010001011001110101011110000101020202 +upce:857406:202000100101110010010001010001101011110100011020202 +upce:237382:202001101101111010111011010000101101110011011020202 +upce:260304:202001101100001010001101010000100011010100011020202 +upce:899152:202000100100101110010111001100101100010010011020202 +upce:773424:202001000100100010111101001110100100110100011020202 +upce:367789:202010000101011110111011011101100010010010111020202 +upce:344078:202010000100111010011101000110101110110110111020202 +upce:627031:202000010100100110010001000110101000010011001020202 +upce:146732:202011001100111010101111001000101111010010011020202 +upce:608666:202000010100011010001001000010101011110101111020202 +upce:855228:202000100101110010111001001001100100110110111020202 +upce:439192:202001110101000010010111001100100010110010011020202 +upce:917451:202001011100110010010001010001101110010011001020202 +upce:072613:202010011101110110100111010111100110010011011020202 +upce:813590:202000100100110010100001011000100010110100111020202 +upce:176138:202011001100100010101111001100101000010110111020202 +upce:690945:202000010100101110001101001011101000110110001020202 +upce:849613:202000100100111010001011010111101100110111101020202 +upce:269053:202001101101011110001011000110101110010100001020202 +upce:701050:202001000100011010011001010011101110010001101020202 +upce:074527:202010011101110110011101011000100110110111011020202 +upce:218296:202001101100110010001001001101100010110101111020202 +upce:874938:202000100100100010100011000101101111010001001020202 +upce:023936:202010011100110110111101000101101111010000101020202 +upce:896764:202000100100101110000101011101101011110100011020202 +upce:979612:202001011100100010001011010111101100110010011020202 +upce:137449:202011001101000010010001010001101000110001011020202 +upce:687160:202000010100010010010001001100101011110001101020202 +upce:839620:202000100101111010010111000010100100110001101020202 +upce:921800:202001011100100110110011000100100011010001101020202 +ean5:72823:010110010001010011011010110111010010011010111101 +ean5:19075:010110110011010001011010001101010010001010110001 +ean5:16659:010110011001010000101010101111010111001010001011 +ean5:54239:010110111001010100011010011011010111101010001011 +ean5:70848:010110111011010001101010001001010011101010110111 +ean5:75795:010110010001010110001010111011010001011010111001 +ean5:15726:010110011001010110001010010001010011011010101111 +ean5:58560:010110110001010110111010110001010000101010100111 +ean5:24670:010110011011010100011010101111010111011010100111 +ean5:24946:010110011011010100011010001011010100011010000101 +ean5:69776:010110000101010001011010010001010111011010101111 +ean5:74692:010110010001010100011010101111010010111010010011 +ean5:10925:010110110011010001101010001011010010011010111001 +ean5:63372:010110000101010111101010111101010111011010011011 +ean5:62942:010110101111010010011010010111010011101010010011 +ean5:35265:010110111101010110001010011011010101111010111001 +ean5:38088:010110111101010001001010001101010001001010110111 +ean5:50203:010110111001010100111010010011010001101010111101 +ean5:57111:010110111001010111011010011001010011001010110011 +ean5:64593:010110101111010100011010111001010001011010100001 +ean5:52424:010110110001010010011010011101010011011010100011 +ean5:77259:010110010001010111011010010011010111001010001011 +ean5:07028:010110001101010111011010100111010011011010110111 +ean5:50627:010110111001010001101010101111010011011010111011 +ean5:60414:010110000101010001101010011101010011001010100011 +ean5:86940:010110001001010101111010010111010100011010001101 +ean5:36095:010110111101010101111010100111010001011010111001 +ean5:01124:010110100111010011001010011001010011011010100011 +ean5:57346:010110111001010111011010100001010100011010101111 +ean5:79607:010110010001010001011010000101010001101010111011 +ean5:31184:010110111101010011001010110011010001001010100011 +ean5:29583:010110011011010001011010110001010110111010100001 +ean5:75568:010110111011010110001010111001010101111010001001 +ean5:53258:010110110001010100001010010011010111001010110111 +ean5:78345:010110010001010110111010111101010100011010111001 +ean5:56838:010110110001010000101010001001010111101010110111 +ean5:61031:010110101111010110011010001101010100001010011001 +ean5:98054:010110001011010110111010001101010111001010011101 +ean5:28204:010110010011010110111010010011010100111010011101 +ean5:18738:010110011001010001001010111011010100001010110111 +ean5:17221:010110110011010111011010010011010010011010110011 +ean5:02270:010110001101010011011010010011010010001010001101 +ean5:02378:010110001101010011011010100001010111011010110111 +ean5:15957:010110110011010110001010010111010110001010111011 +ean5:13621:010110011001010111101010000101010010011010110011 +ean5:98891:010110001011010001001010110111010010111010011001 +ean5:50554:010110110001010100111010110001010111001010100011 +ean5:22677:010110010011010010011010101111010010001010010001 +ean5:49420:010110011101010001011010100011010010011010100111 +ean5:57712:010110110001010010001010010001010011001010010011 +ean5:13839:010110011001010100001010110111010111101010010111 +ean5:36422:010110111101010101111010011101010010011010011011 +ean5:10137:010110011001010100111010110011010111101010111011 +ean5:22734:010110010011010011011010010001010111101010100011 +ean5:25562:010110010011010110001010110001010000101010011011 +ean5:49015:010110100011010010111010001101010110011010110001 +ean5:34620:010110100001010100011010000101010010011010001101 +ean5:74909:010110010001010100011010010111010001101010001011 +ean5:57115:010110110001010111011010110011010110011010110001 +ean5:84963:010110001001010011101010001011010101111010111101 +ean5:95948:010110001011010110001010010111010100011010001001 +ean5:36006:010110100001010101111010100111010001101010101111 +ean5:05457:010110100111010110001010100011010110001010010001 +ean5:54806:010110111001010100011010110111010001101010000101 +ean5:32152:010110100001010010011010110011010110001010010011 +ean5:64913:010110101111010100011010010111010011001010100001 +ean5:53560:010110111001010111101010111001010101111010001101 +ean5:57373:010110110001010111011010100001010111011010100001 +ean5:54685:010110110001010100011010101111010001001010111001 +ean5:75408:010110010001010110001010100011010100111010110111 +ean5:56632:010110111001010000101010101111010111101010010011 +ean5:22639:010110010011010010011010101111010100001010010111 +ean5:92955:010110010111010010011010001011010111001010110001 +ean5:75465:010110111011010111001010100011010000101010110001 +ean5:56506:010110111001010101111010110001010100111010101111 +ean5:22627:010110011011010010011010000101010010011010111011 +ean5:98251:010110010111010110111010010011010110001010110011 +ean5:90220:010110010111010001101010011011010010011010001101 +ean5:93426:010110010111010111101010100011010011011010101111 +ean5:74169:010110010001010100011010110011010101111010001011 +ean5:36259:010110100001010101111010011011010110001010001011 +ean5:71855:010110111011010110011010001001010110001010110001 +ean5:04584:010110001101010100011010111001010001001010100011 +ean5:01152:010110100111010011001010011001010110001010011011 +ean5:72757:010110111011010010011010111011010111001010010001 +ean5:28673:010110010011010001001010101111010111011010100001 +ean5:75084:010110010001010111001010001101010110111010100011 +ean5:10562:010110011001010100111010110001010101111010011011 +ean5:63726:010110000101010111101010111011010011011010101111 +ean5:04292:010110001101010100011010011011010001011010011011 +ean5:77513:010110111011010010001010110001010110011010111101 +ean5:17826:010110011001010111011010110111010011011010000101 +ean5:44790:010110011101010011101010111011010001011010001101 +ean5:39572:010110111101010010111010111001010111011010010011 +ean5:55321:010110111001010111001010111101010010011010011001 +ean5:89717:010110110111010001011010111011010110011010010001 +ean5:02126:010110001101010011011010011001010011011010101111 +ean5:30106:010110100001010100111010011001010001101010101111 +ean5:57489:010110110001010111011010011101010110111010010111 +ean5:26505:010110011011010000101010110001010001101010110001 +upca:40710631975:20201000110001101011101100110010001101010111102020100001011001101110100100010010011101100110202 +upca:80176224795:20201101110001101001100101110110101111001001102020110110010111001000100111010010011101100110202 +upca:92748137722:20200010110010011011101101000110110111001100102020100001010001001000100110110011011001010000202 +upca:32450677259:20201111010010011010001101100010001101010111102020100010010001001101100100111011101001110010202 +upca:40851674702:20201000110001101011011101100010011001010111102020100010010111001000100111001011011001001000202 +upca:59115174167:20201100010001011001100100110010110001001100102020100010010111001100110101000010001001100110202 +upca:84003578078:20201101110100011000110100011010111101011000102020100010010010001110010100010010010001001000202 +upca:95062540829:20200010110110001000110101011110010011011000102020101110011100101001000110110011101001010000202 +upca:64901078016:20201011110100011000101100011010011001000110102020100010010010001110010110011010100001110010202 +upca:48432140125:20201000110110111010001101111010010011001100102020101110011100101100110110110010011101010000202 +upca:17430588576:20200110010111011010001101111010001101011000102020100100010010001001110100010010100001001000202 +upca:63153964133:20201011110111101001100101100010111101000101102020101000010111001100110100001010000101010000202 +upca:74093932950:20201110110100011000110100010110111101000101102020100001011011001110100100111011100101001110202 +upca:57541363089:20201100010111011011000101000110011001011110102020101000010000101110010100100011101001000100202 +upca:07377087198:20200011010111011011110101110110111011000110102020100100010001001100110111010010010001110100202 +upca:05635524594:20200011010110001010111101111010110001011000102020110110010111001001110111010010111001001000202 +upca:70318362910:20201110110001101011110100110010110111011110102020101000011011001110100110011011100101011100202 +upca:36925218506:20201111010101111000101100100110110001001001102020110011010010001001110111001010100001001110202 +upca:45343236277:20201000110110001011110101000110111101001001102020100001010100001101100100010010001001110010202 +upca:03926388241:20200011010111101000101100100110101111011110102020100100010010001101100101110011001101101100202 +upca:64192083538:20201011110100011001100100010110010011000110102020100100010000101001110100001010010001100110202 +upca:25525653142:20200100110110001011000100100110110001010111102020100111010000101100110101110011011001110010202 +upca:38104462945:20201111010110111001100100011010100011010001102020101000011011001110100101110010011101001000202 +upca:09225889378:20200011010001011001001100100110110001011011102020100100011101001000010100010010010001000100202 +upca:93748811785:20200010110111101011101101000110110111011011102020110011011001101000100100100010011101001110202 +upca:30467816622:20201111010001101010001101011110111011011011102020110011010100001010000110110011011001110100202 +upca:74931591622:20201110110100011000101101111010011001011000102020111010011001101010000110110011011001000010202 +upca:92475784788:20200010110010011010001101110110110001011101102020100100010111001000100100100010010001110100202 +upca:40454544331:20201000110001101010001101100010100011011000102020101110010111001000010100001011001101000010202 +upca:35237883084:20201111010110001001001101111010111011011011102020100100010000101110010100100010111001100110202 +upca:75646706855:20201110110110001010111101000110101111011101102020111001010100001001000100111010011101000100202 +upca:82889483314:20201101110010011011011101101110001011010001102020100100010000101000010110011010111001101100202 +upca:73893633416:20201110110111101011011100010110111101010111102020100001010000101011100110011010100001001110202 +upca:10454576813:20200110010001101010001101100010100011011000102020100010010100001001000110011010000101101100202 +upca:33334522835:20201111010111101011110101111010100011011000102020110110011011001001000100001010011101110100202 +upca:45793591164:20201000110110001011101100010110111101011000102020111010011001101100110101000010111001110010202 +upca:18057726450:20200110010110111000110101100010111011011101102020110110010100001011100100111011100101000100202 +upca:96083152912:20200010110101111000110101101110111101001100102020100111011011001110100110011011011001001000202 +upca:16563181689:20200110010101111011000101011110111101001100102020100100011001101010000100100011101001101100202 +upca:51276473461:20201100010011001001001101110110101111010001102020100010010000101011100101000011001101011100202 +upca:08128913293:20200011010110111001100100100110110111000101102020110011010000101101100111010010000101011100202 +upca:34146752391:20201111010100011001100101000110101111011101102020100111011011001000010111010011001101000100202 +upca:97515692692:20200010110111011011000100110010110001010111102020111010011011001010000111010011011001000100202 +upca:97669919853:20200010110111011010111101011110001011000101102020110011011101001001000100111010000101010000202 +upca:18678734797:20200110010110111010111101110110110111011101102020100001010111001000100111010010001001110100202 +upca:74076303825:20201110110100011000110101110110101111011110102020111001010000101001000110110010011101000010202 +upca:08662387020:20200011010110111010111101011110010011011110102020100100010001001110010110110011100101010000202 +upca:26133671442:20200100110101111001100101111010111101010111102020100010011001101011100101110011011001000010202 +upca:87138605931:20201101110111011001100101111010110111010111102020111001010011101110100100001011001101001110202 +upca:67189289819:20201011110111011001100101101110001011001001102020100100011101001001000110011011101001110010202 +upca:09759720707:20200011010001011011101101100010001011011101102020110110011100101000100111001010001001000010202 +upca:56485529906:20201100010101111010001101101110110001011000102020110110011101001110100111001010100001110100202 +upca:58154525395:20201100010110111001100101100010100011011000102020110110010011101000010111010010011101001000202 +upca:67888609275:20201011110111011011011101101110110111010111102020111001011101001101100100010010011101010000202 +upca:15168153237:20200110010110001001100101011110110111001100102020100111010000101101100100001010001001110010202 +upca:74424730673:20201110110100011010001100100110100011011101102020100001011100101010000100010010000101110100202 +upca:45168971187:20201000110110001001100101011110110111000101102020100010011001101100110100100010001001000100202 +upca:12149723784:20200110010010011001100101000110001011011101102020110110010000101000100100100010111001011100202 +upca:33804286457:20201111010111101011011100011010100011001001102020100100010100001011100100111010001001101100202 +upca:27558248562:20200100110111011011000101100010110111001001102020101110010010001001110101000011011001011100202 +upca:92390267160:20200010110010011011110100010110001101001001102020101000010001001100110101000011100101000100202 +upca:63742039163:20201011110111101011101101000110010011000110102020100001011101001100110101000010000101101100202 +upca:67117098326:20201011110111011001100100110010111011000110102020111010010010001000010110110010100001010000202 +upca:32901624258:20201111010010011000101100011010011001010111102020110110010111001101100100111010010001001000202 +upca:88848685777:20201101110110111011011101000110110111010111102020100100010011101000100100010010001001101100202 +upca:57070085601:20201100010111011000110101110110001101000110102020100100010011101010000111001011001101100110202 +upca:83043128438:20201101110111101000110101000110111101001100102020110110010010001011100100001010010001010000202 +upca:52432147628:20201100010010011010001101111010010011001100102020101110010001001010000110110010010001001000202 +upca:15067795584:20200110010110001000110101011110111011011101102020111010010011101001110100100010111001100110202 +upca:27777156430:20200100110111011011101101110110111011001100102020100111010100001011100100001011100101100110202 +upca:82471218344:20201101110010011010001101110110011001001001102020110011010010001000010101110010111001011100202 +upca:94175044091:20200010110100011001100101110110110001000110102020101110010111001110010111010011001101010000202 +upca:34936749963:20201111010100011000101101111010101111011101102020101110011101001110100101000010000101110100202 +upca:46502492658:20201000110101111011000100011010010011010001102020111010011011001010000100111010010001100110202 +upca:47153985860:20201000110111011001100101100010111101000101102020100100010011101001000101000011100101010000202 +upca:79601763982:20201110110001011010111100011010011001011101102020101000010000101110100100100011011001110010202 +upca:91685238225:20200010110011001010111101101110110001001001102020100001010010001101100110110010011101110100202 +upca:46916417994:20201000110101111000101100110010101111010001102020110011010001001110100111010010111001011100202 +upca:30878845484:20201111010001101011011101110110110111011011102020101110010011101011100100100010111001110100202 +upca:39321907655:20201111010001011011110100100110011001000101102020111001010001001010000100111010011101011100202 +upca:48232524842:20201000110110111001001101111010010011011000102020110110010111001001000101110011011001010000202 +upca:94750199914:20200010110100011011101101100010001101001100102020111010011101001110100110011010111001010000202 +upca:28310653784:20200100110110111011110100110010001101010111102020100111010000101000100100100010111001100110202 +upca:00814405096:20200011010001101011011100110010100011010001102020111001010011101110010111010010100001000100202 +upca:60974743279:20201011110001101000101101110110100011011101102020101110010000101101100100010011101001011100202 +upca:45141255670:20201000110110001001100101000110011001001001102020100111010011101010000100010011100101010000202 +upca:62241294735:20201011110010011001001101000110011001001001102020111010010111001000100100001010011101001110202 +upca:67241197048:20201011110111011001001101000110011001001100102020111010010001001110010101110010010001110100202 +upca:57709892169:20201100010111011011101100011010001011011011102020111010011011001100110101000011101001000100202 +upca:49234133045:20201000110001011001001101111010100011001100102020100001010000101110010101110010011101010000202 +upca:44106865868:20201000110100011001100100011010101111011011102020101000010011101001000101000010010001001000202 +upca:07033900539:20200011010111011000110101111010111101000101102020111001011100101001110100001011101001000100202 +upca:63922260360:20201011110111101000101100100110010011001001102020101000011100101000010101000011100101110100202 +upca:63544942112:20201011110111101011000101000110100011000101102020101110011011001100110110011011011001001110202 +upca:52602007800:20201100010010011010111100011010010011000110102020111001010001001001000111001011100101001000202 +upca:94048257810:20200010110100011000110101000110110111001001102020100111010001001001000110011011100101101100202 +upca:82699181094:20201101110010011010111100010110001011001100102020100100011001101110010111010010111001000010202 +upca:94628599972:20200010110100011010111100100110110111011000102020111010011101001110100100010011011001011100202 +upca:09938844603:20200011010001011000101101111010110111011011102020101110010111001010000111001010000101010000202 +upca:37128560103:20201111010111011001100100100110110111011000102020101000011100101100110111001010000101110010202 diff --git a/share/extensions/test/render_barcode.test.py b/share/extensions/test/render_barcode.test.py index 0762ccb99..79f4ff979 100755 --- a/share/extensions/test/render_barcode.test.py +++ b/share/extensions/test/render_barcode.test.py @@ -1,20 +1,39 @@ #!/usr/bin/env python - -# This is only the automatic generated test file for ../render_barcode.py -# This must be filled with real tests and this commentary -# must be cleared. -# If you want to help, read the python unittest documentation: -# http://docs.python.org/library/unittest.html +# +# Copyright (C) 2010 Martin Owens +# +# Written to test the coding of generating barcodes. +# import sys -sys.path.append('..') # this line allows to import the extension code - +import random import unittest + +# Allow import of the extension code and modules +sys.path.append('..') + from render_barcode import * -class InsertBarcodeBasicTest(unittest.TestCase): +import Barcode.EAN5 +import Barcode.EAN8 +import Barcode.EAN13 +import Barcode.UPCA +import Barcode.UPCE + +digits = [ '0', '1', '2', '3', '4', '5', '6', '7', '8', '9' ] - #def setUp(self): +class InsertBarcodeBasicTest(unittest.TestCase): + """Render Barcode""" + def setUp(self): + self.data = {} + fhl = open('render_barcode.data', 'r') + for line in fhl: + line = line.replace('\n', '').replace('\r', '') + (btype, text, code) = line.split(':') + if not self.data.has_key(btype): + self.data[btype] = [] + self.data[btype].append( [ text, code ] ) + fhl.close() def test_run_without_parameters(self): args = [ 'minimal-blank.svg' ] @@ -22,5 +41,36 @@ class InsertBarcodeBasicTest(unittest.TestCase): e.affect( args, False ) #self.assertEqual( e.something, 'some value', 'A commentary about that.' ) + def test_render_barcode_ian5(self): + """Barcode IAN5""" + self.barcode_test( 'ean5', Barcode.EAN5 ) + + def test_render_barcode_ian8(self): + """Barcode IAN5""" + self.barcode_test( 'ean8', Barcode.EAN8 ) + + def test_render_barcode_ian13(self): + """Barcode IAN5""" + self.barcode_test( 'ean13', Barcode.EAN13 ) + + def test_render_barcode_upca(self): + """Barcode IAN5""" + self.barcode_test( 'upca', Barcode.UPCA ) + + def test_render_barcode_upce(self): + """Barcode UPCE""" + self.barcode_test( 'upce', Barcode.UPCE ) + + def barcode_test(self, name, module): + """Base module for all barcode testing""" + for datum in self.data[name]: + (text, code) = datum + if not text or not code: + continue + code2 = module.Object( {'text': text} ).encode(text) + self.assertEqual(code, code2) + + if __name__ == '__main__': unittest.main() + diff --git a/share/extensions/webslicer_create_rect.inx b/share/extensions/webslicer_create_rect.inx index 8a56c7892..5b3b447e9 100644 --- a/share/extensions/webslicer_create_rect.inx +++ b/share/extensions/webslicer_create_rect.inx @@ -19,12 +19,12 @@ <param name="bg-color" type="string" _gui-text="Background color:"></param> <param name="tab" type="notebook"> <page name="tabJPG" gui-text="JPG"> - <_param name="help-jpg" type="groupheader">JPG specific options</_param> + <_param name="help-jpg" type="description" appearance="header">JPG specific options</_param> <param name="quality" type="int" min="0" max="100" _gui-text="Quality:">85</param> <_param name="help-quality" type="description">0 is the lowest image quality and highest compression, and 100 is the best quality but least effective compression</_param> </page> <page name="tabGIF" gui-text="GIF"> - <_param name="help-gif" type="groupheader">GIF specific options</_param> + <_param name="help-gif" type="description" appearance="header">GIF specific options</_param> <param name="gif-type" type="enum" _gui-text="Type:"> <_item value="grayscale">Grayscale</_item> <_item value="palette">Palette</_item> @@ -34,7 +34,7 @@ <page name="tabHTML" gui-text="HTML"> <param name="html-id" type="string" _gui-text="HTML id attribute:"></param> <param name="html-class" type="string" _gui-text="HTML class attribute:"></param> - <_param name="help-gif" type="groupheader">Options for HTML export</_param> + <_param name="help-gif" type="description" appearance="header">Options for HTML export</_param> <param name="layout-disposition" type="enum" _gui-text="Layout disposition:"> <_item value="bg-el-norepeat">Positioned html block element with the image as Background</_item> <_item value="bg-parent-repeat">Tiled Background (on parent group)</_item> |
