From 1120f847062f17b8256010f73a083dc76a4a4fcb Mon Sep 17 00:00:00 2001 From: Martin Owens Date: Fri, 16 May 2014 09:51:26 -0400 Subject: Barcode extension: Code cleanup and merge in delta from last year. (bzr r13386) --- share/extensions/Barcode/Base.py | 34 +++++---- share/extensions/Barcode/Code128.py | 49 ++++++++---- share/extensions/Barcode/Code25i.py | 3 +- share/extensions/Barcode/Code39.py | 7 +- share/extensions/Barcode/Code39Ext.py | 6 +- share/extensions/Barcode/Code93.py | 2 +- share/extensions/Barcode/EAN13.py | 38 ---------- share/extensions/Barcode/EAN5.py | 39 ---------- share/extensions/Barcode/EAN8.py | 34 --------- share/extensions/Barcode/Ean13.py | 38 ++++++++++ share/extensions/Barcode/Ean5.py | 39 ++++++++++ share/extensions/Barcode/Ean8.py | 34 +++++++++ share/extensions/Barcode/RM4CC.py | 135 ---------------------------------- share/extensions/Barcode/Rm4scc.py | 135 ++++++++++++++++++++++++++++++++++ share/extensions/Barcode/UPCA.py | 37 ---------- share/extensions/Barcode/UPCE.py | 103 -------------------------- share/extensions/Barcode/Upca.py | 37 ++++++++++ share/extensions/Barcode/Upce.py | 103 ++++++++++++++++++++++++++ share/extensions/Barcode/__init__.py | 61 +++++---------- share/extensions/render_barcode.inx | 22 +++--- share/extensions/render_barcode.py | 79 +++++++++++--------- 21 files changed, 521 insertions(+), 514 deletions(-) delete mode 100644 share/extensions/Barcode/EAN13.py delete mode 100644 share/extensions/Barcode/EAN5.py delete mode 100644 share/extensions/Barcode/EAN8.py create mode 100644 share/extensions/Barcode/Ean13.py create mode 100644 share/extensions/Barcode/Ean5.py create mode 100644 share/extensions/Barcode/Ean8.py delete mode 100644 share/extensions/Barcode/RM4CC.py create mode 100644 share/extensions/Barcode/Rm4scc.py delete mode 100644 share/extensions/Barcode/UPCA.py delete mode 100644 share/extensions/Barcode/UPCE.py create mode 100644 share/extensions/Barcode/Upca.py create mode 100644 share/extensions/Barcode/Upce.py diff --git a/share/extensions/Barcode/Base.py b/share/extensions/Barcode/Base.py index b86185388..90a1837c4 100644 --- a/share/extensions/Barcode/Base.py +++ b/share/extensions/Barcode/Base.py @@ -34,12 +34,12 @@ class Barcode(object): """Cause an error to be reported""" sys.stderr.write( "Error encoding '%s' as %s barcode: %s\n" % (bar, self.name, msg)) + return "ERROR" def __init__(self, param={}): self.document = param.get('document', None) self.x = int(param.get('x', 0)) self.y = int(param.get('y', 0)) - self.scale = param.get('scale', 1) self.height = param.get('height', 30) self.label = param.get('text', None) self.string = self.encode( self.label ) @@ -50,35 +50,39 @@ class Barcode(object): 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 + def get_id(self): + """Get the next useful id""" if not self.document: - return self.error("No document defined") - - data = self.data - # Collect document ids + return "barcode" doc_ids = {} docIdNodes = self.document.xpath('//@id') for m in docIdNodes: doc_ids[m] = 1 - # We don't have svg documents so lets do something raw: name = 'barcode' - # Make sure that the id/name is inique index = 0 while (doc_ids.has_key(name)): - name = 'barcode' + str(index) - index = index + 1 + index += 1 + name = 'barcode%d' % index + return name + + def generate(self): + """Generate the actual svg from the coding""" + svg_uri = u'http://www.w3.org/2000/svg' + if self.string == 'ERROR': + return + if not self.string or not self.data: + raise ValueError("No string specified for barcode.") + + data = self.data + name = self.get_id() # use an svg group element to contain the barcode barcode = etree.Element('{%s}%s' % (svg_uri,'g')) barcode.set('id', name) barcode.set('style', 'fill: black;') - barcode.set('transform', 'translate(%d,%d) scale(%f)' % (self.x, self.y, self.scale)) + barcode.set('transform', 'translate(%d,%d)' % (self.x, self.y)) bar_offset = 0 bar_id = 1 diff --git a/share/extensions/Barcode/Code128.py b/share/extensions/Barcode/Code128.py index 8734fc330..618ce7817 100644 --- a/share/extensions/Barcode/Code128.py +++ b/share/extensions/Barcode/Code128.py @@ -27,7 +27,29 @@ from Base import Barcode import math 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' ] +codeMap = [ + '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) @@ -44,7 +66,8 @@ charAB = list(' !"#$%&\'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^ charA = mapExtra(charAB, range(0, 31)) # Offset 64 charB = mapExtra(charAB, range(96, 125)) # Offset -32 -class Object(Barcode): +class Code128(Barcode): + """Main barcode object, generates the encoding bits here""" def encode(self, text): result = '' blocks = [] @@ -65,7 +88,7 @@ class Object(Barcode): if block: blocks.append(self.bestBlock(block)) block = ''; - + self.inclabel = text return self.encodeBlocks(blocks) @@ -74,12 +97,12 @@ class Object(Barcode): 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] @@ -103,7 +126,7 @@ class Object(Barcode): i = 1 total = total + num * i - encode = encode + map[num] + encode = encode + codeMap[num] pos = pos + 1 if set == 'A' or set == 'B': @@ -113,18 +136,18 @@ class Object(Barcode): for char in datum: total = total + (chars.index(char) * pos) - encode = encode + map[chars.index(char)] + encode = encode + codeMap[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)] + encode = encode + codeMap[int(char)] pos = pos + 1 - + checksum = total % 103 - encode = encode + map[checksum] - encode = encode + map[106] - encode = encode + map[107] - + encode = encode + codeMap[checksum] + encode = encode + codeMap[106] + encode = encode + codeMap[107] + return encode diff --git a/share/extensions/Barcode/Code25i.py b/share/extensions/Barcode/Code25i.py index 518a306f2..51346be60 100644 --- a/share/extensions/Barcode/Code25i.py +++ b/share/extensions/Barcode/Code25i.py @@ -34,14 +34,13 @@ encoding = { '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): +class Code25i(Barcode): # Convert a text into string binary of black and white markers def encode(self, number): self.label = number diff --git a/share/extensions/Barcode/Code39.py b/share/extensions/Barcode/Code39.py index 64b22f352..ade397463 100644 --- a/share/extensions/Barcode/Code39.py +++ b/share/extensions/Barcode/Code39.py @@ -68,7 +68,7 @@ encoding = { ' ' : '011000100', } -class Object(Barcode): +class Code39(Barcode): # Convert a text into string binary of black and white markers def encode(self, text): text = text.upper() @@ -93,10 +93,7 @@ class Object(Barcode): encoded = encoded + colour + colour else: encoded = encoded + colour - if colour == '1': - colour = '0' - else: - colour = '1' + colour = colour == '1' and '0' or '1' self.inclabel = text return encoded; diff --git a/share/extensions/Barcode/Code39Ext.py b/share/extensions/Barcode/Code39Ext.py index 8f1e77826..b6df47de2 100644 --- a/share/extensions/Barcode/Code39Ext.py +++ b/share/extensions/Barcode/Code39Ext.py @@ -19,7 +19,7 @@ Python barcode renderer for Code39 Extended barcodes. Designed for Inkscape. """ -import Code39 +from Code39 import Code39 encode = list('ABCDEFGHIJKLMNOPQRSTUVWXYZ') @@ -46,7 +46,7 @@ mapB = getMap(range(1, 26)) # $ mapC = getMap(range(33, 58)) # / mapD = getMap(range(97, 122)) # + -class Object(Code39.Object): +class Code39Ext(Code39): def encode(self, text): # We are only going to extend the Code39 barcodes result = '' @@ -61,5 +61,5 @@ class Object(Code39.Object): char = '+' + mapD[char] result = result + char - return Code39.Object.encode(self, result); + return Code39.encode(self, result); diff --git a/share/extensions/Barcode/Code93.py b/share/extensions/Barcode/Code93.py index 76cbf683b..866ec6036 100644 --- a/share/extensions/Barcode/Code93.py +++ b/share/extensions/Barcode/Code93.py @@ -56,7 +56,7 @@ 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): +class Code93(Barcode): def encode(self, text): # start marker bits = self.encode93('MARKER') diff --git a/share/extensions/Barcode/EAN13.py b/share/extensions/Barcode/EAN13.py deleted file mode 100644 index 41681173b..000000000 --- a/share/extensions/Barcode/EAN13.py +++ /dev/null @@ -1,38 +0,0 @@ -# -# 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:]) ) - - diff --git a/share/extensions/Barcode/EAN5.py b/share/extensions/Barcode/EAN5.py deleted file mode 100644 index 68ff99738..000000000 --- a/share/extensions/Barcode/EAN5.py +++ /dev/null @@ -1,39 +0,0 @@ -# -# 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 - 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)) - diff --git a/share/extensions/Barcode/EAN8.py b/share/extensions/Barcode/EAN8.py deleted file mode 100644 index 05b4d7bb7..000000000 --- a/share/extensions/Barcode/EAN8.py +++ /dev/null @@ -1,34 +0,0 @@ -# -# 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/Ean13.py b/share/extensions/Barcode/Ean13.py new file mode 100644 index 000000000..3bad5d6e5 --- /dev/null +++ b/share/extensions/Barcode/Ean13.py @@ -0,0 +1,38 @@ +# +# 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 Ean13(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:]) ) + + diff --git a/share/extensions/Barcode/Ean5.py b/share/extensions/Barcode/Ean5.py new file mode 100644 index 000000000..f328ed536 --- /dev/null +++ b/share/extensions/Barcode/Ean5.py @@ -0,0 +1,39 @@ +# +# 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 Ean5(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 + 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)) + diff --git a/share/extensions/Barcode/Ean8.py b/share/extensions/Barcode/Ean8.py new file mode 100644 index 000000000..83e82814a --- /dev/null +++ b/share/extensions/Barcode/Ean8.py @@ -0,0 +1,34 @@ +# +# 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 Ean8(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/RM4CC.py b/share/extensions/Barcode/RM4CC.py deleted file mode 100644 index d980c6c86..000000000 --- a/share/extensions/Barcode/RM4CC.py +++ /dev/null @@ -1,135 +0,0 @@ -# -# 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', -} - -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 = '' - - self.height = 18 - text = text.upper() - text.replace('(', '') - text.replace(')', '') - - text = '(' + text + self.checksum(text) + ')' - - i = 0 - for char in text: - if map.has_key(char): - result = result + map[char] - - i = i + 1 - - 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 - - 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 - - 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/Rm4scc.py b/share/extensions/Barcode/Rm4scc.py new file mode 100644 index 000000000..0fb154280 --- /dev/null +++ b/share/extensions/Barcode/Rm4scc.py @@ -0,0 +1,135 @@ +# +# 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', +} + +check = ['ZUVWXY','501234','B6789A','HCDEFG','NIJKLM','TOPQRS'] +(BAR_TRACK, BAR_DOWN, BAR_UP, BAR_FULL, BAR_NONE, WHITE_SPACE) = range(6) + +class Rm4scc(Barcode): + def encode(self, text): + result = '' + + self.height = 18 + text = text.upper() + text.replace('(', '') + text.replace(')', '') + + text = '(' + text + self.checksum(text) + ')' + + i = 0 + for char in text: + if map.has_key(char): + result = result + map[char] + + i = i + 1 + + 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 + + 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 + + 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 deleted file mode 100644 index 6ac10943c..000000000 --- a/share/extensions/Barcode/UPCA.py +++ /dev/null @@ -1,37 +0,0 @@ -# -# 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 deleted file mode 100644 index dba5d48ea..000000000 --- a/share/extensions/Barcode/UPCE.py +++ /dev/null @@ -1,103 +0,0 @@ -# -# 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 - -# 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/Upca.py b/share/extensions/Barcode/Upca.py new file mode 100644 index 000000000..d69ed11e6 --- /dev/null +++ b/share/extensions/Barcode/Upca.py @@ -0,0 +1,37 @@ +# +# 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 Upca(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 new file mode 100644 index 000000000..eee2a739c --- /dev/null +++ b/share/extensions/Barcode/Upce.py @@ -0,0 +1,103 @@ +# +# 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 + +# 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 Upce(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 + raise ValueError("Invalid UPC Number") + + # 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 + raise ValueError("Invalid UPC Number") + + 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 370839f45..e4e328ae3 100644 --- a/share/extensions/Barcode/__init__.py +++ b/share/extensions/Barcode/__init__.py @@ -1,5 +1,5 @@ # -# Copyright (C) 2010 Martin Owens +# Copyright (C) 2014 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 @@ -16,10 +16,9 @@ # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA # """ -Renderer for barcodes, SVG extention for Inkscape. +Renderer for barcodes, SVG extention for Inkscape. For supported barcodes see Barcode module directory. - """ # This lists all known Barcodes missing from this package @@ -40,45 +39,19 @@ For supported barcodes see Barcode module directory. import sys -def getBarcode(format, 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 == '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") +def getBarcode(code, **kwargs): + """Gets a barcode from a list of available barcode formats""" + if not code: + return sys.stderr.write("No barcode format given!\n") + + + code = str(code).replace('-', '').strip() + try: + barcode = getattr(__import__('Barcode.'+code, fromlist=['Barcode']), code) + return barcode(kwargs) + except ImportError: + sys.stderr.write("Invalid type of barcode: %s\n" % code) + except AttributeError: + raise + sys.stderr.write("Barcode module is missing the barcode class: %s\n" % code) diff --git a/share/extensions/render_barcode.inx b/share/extensions/render_barcode.inx index 64d828a19..debefadad 100644 --- a/share/extensions/render_barcode.inx +++ b/share/extensions/render_barcode.inx @@ -5,17 +5,17 @@ inkex.py render_barcode.py - EAN5 - EAN8 - EAN13 - UPC-A - UPC-E - Code25 Interleaved 2 of 5 - Code39 - Code39 Extended - Code93 - Code128 - RM4CC / RM4SCC + EAN5 + EAN8 + EAN13 + UPC-A + UPC-E + Code25 Interleaved 2 of 5 + Code39 + Code39 Extended + Code93 + Code128 + RM4CC / RM4SCC 30 diff --git a/share/extensions/render_barcode.py b/share/extensions/render_barcode.py index c3b809c9e..694dcc8f3 100755 --- a/share/extensions/render_barcode.py +++ b/share/extensions/render_barcode.py @@ -26,41 +26,52 @@ import sys from Barcode import getBarcode class InsertBarcode(inkex.Effect): - def __init__(self): - inkex.Effect.__init__(self) - self.OptionParser.add_option("-l", "--height", - action="store", type="int", - dest="height", default=30, - help="Barcode Height") - self.OptionParser.add_option("-t", "--type", - action="store", type="string", - dest="type", default='', - help="Barcode Type") - self.OptionParser.add_option("-d", "--text", - action="store", type="string", - dest="text", default='', - help="Text to print on barcode") + def __init__(self): + inkex.Effect.__init__(self) + self.OptionParser.add_option("-l", "--height", + action="store", type="int", + dest="height", default=30, + help="Barcode Height") + self.OptionParser.add_option("-t", "--type", + action="store", type="string", + dest="type", default='', + help="Barcode Type") + self.OptionParser.add_option("-d", "--text", + action="store", type="string", + dest="text", default='', + help="Text to print on barcode") + + def effect(self): + x, y = self.view_center + bargen = getBarcode( self.options.type, + text=self.options.text, + height=self.options.height, + document=self.document, + x=x, y=y, + scale=self.unittouu('1px'), + ) + if bargen is not None: + barcode = bargen.generate() + if barcode is not None: + self.current_layer.append(barcode) + else: + sys.stderr.write("No barcode was generated\n") + else: + sys.stderr.write("Unable to make barcode with: " + str(self.options) + "\n") + +def test_barcode(): + bargen = getBarcode("Ean13", text="123456789101") + if bargen is not None: + barcode = bargen.generate() + if barcode: + print inkex.etree.tostring(barcode, pretty_print=True) - def effect(self): - x, y = self.view_center - bargen = getBarcode( self.options.type, { - 'text' : self.options.text, - 'height' : self.options.height, - 'document' : self.document, - 'x' : x, - 'y' : y, - 'scale' : self.unittouu('1px'), - } ) - if bargen is not None: - barcode = bargen.generate() - if barcode is not None: - self.current_layer.append(barcode) - else: - sys.stderr.write("No barcode was generated\n") - else: - sys.stderr.write("Unable to make barcode with: " + str(self.options) + "\n") if __name__ == '__main__': - e = InsertBarcode() - e.affect() + if len(sys.argv) == 1: + # Debug mode without inkex + test_barcode() + exit(0) + e = InsertBarcode() + e.affect() -- cgit v1.2.3