2
Copyright (C) 2007 Martin Owens
4
Thanks to Lineaire Chez of Inkbar ( www.inkbar.lineaire.net )
6
This program is free software; you can redistribute it and/or modify
7
it under the terms of the GNU General Public License as published by
8
the Free Software Foundation; either version 2 of the License, or
9
(at your option) any later version.
11
This program is distributed in the hope that it will be useful,
12
but WITHOUT ANY WARRANTY; without even the implied warranty of
13
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14
GNU General Public License for more details.
16
You should have received a copy of the GNU General Public License
17
along with this program; if not, write to the Free Software
18
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
22
from EAN13 import mapLeftFaimly, guardBar, centerBar
2
# Copyright (C) 2010 Martin Owens
4
# This program is free software; you can redistribute it and/or modify
5
# it under the terms of the GNU General Public License as published by
6
# the Free Software Foundation; either version 2 of the License, or
7
# (at your option) any later version.
9
# This program is distributed in the hope that it will be useful,
10
# but WITHOUT ANY WARRANTY; without even the implied warranty of
11
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12
# GNU General Public License for more details.
14
# You should have received a copy of the GNU General Public License
15
# along with this program; if not, write to the Free Software
16
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19
Python barcode renderer for UPCE barcodes. Designed for use with Inkscape.
22
from BaseEan import EanBarcode
25
mapFamily = [ '000111','001011','001101','001110','010011','011001','011100','010101','010110','011010' ]
27
class Object(EAN13.Object):
28
def encode(self, number):
33
if (l != 6 and l != 7 and l != 11 and l != 12) or not number.isdigit():
34
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")
41
sys.stderr.write("CHECKSUM FOUND!")
45
number = self.ConvertEtoA(number)
48
echeck = self.getChecksum(number)
50
if not self.verifyChecksum(number + echeck):
51
sys.stderr.write("UPC-E Checksum not correct for this barcode, omit last character to generate new checksum.\n")
54
number = self.ConvertAtoE(number)
56
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")
61
result = result + guardBar
62
# The check digit isn't stored as bars but as a mirroring system. :-(
63
family = mapFamily[int(echeck)]
67
result += mapLeftFaimly[int(family[i])-1][int(number[i])]
69
result = result + centerBar + '2';
71
self.label = '0 ' + number[:6] + ' ' + echeck
72
self.inclabel = self.label
78
def ConvertAtoE(self, number):
79
# Converting UPC-A to UPC-E
81
# All UPC-E Numbers use number system 0
82
if number[0] != '0' or len(number)!=11:
83
# If not then the code is invalid
86
# Most of the conversions deal
87
# with the specific code parts
88
manufacturer = number[1:6]
89
product = number[6:11]
91
# There are 4 cases to convert:
92
if manufacturer[2:] == '000' or manufacturer[2:] == '100' or manufacturer[2:] == '200':
93
# Maxium number product code digits can be encoded
95
return manufacturer[:2] + product[2:] + manufacturer[2]
96
elif manufacturer[3:5] == '00':
97
# Now only 2 product code digits can be used
98
if product[:3]=='000':
99
return manufacturer[:3] + product[3:] + '3'
100
elif manufacturer[4] == '0':
101
# With even more manufacturer code we have less room for product code
102
if product[:4]=='0000':
103
return manufacturer[0:4] + product[4] + '4'
104
elif product[:4]=='0000' and int(product[4]) > 4:
105
# The last recorse is to try and squeeze it in the last 5 numbers
106
# so long as the product is 00005-00009 so as not to conflict with
107
# the 0-4 used above.
108
return manufacturer + product[4]
110
# Invalid UPC-A Numbe
113
def ConvertEtoA(self, number):
114
# Convert UPC-E to UPC-A
116
# It's more likly to convert this without fault
117
# But we still must be mindful of the 4 conversions
121
if number[5]=='0' or number[5]=='1' or number[5]=='2':
122
return '0' + number[:2] + number[5] + '0000' + number[2:5]
124
return '0' + number[:3] + '00000' + number[3:5]
126
return '0' + number[:4] + '00000' + number[4]
128
return '0' + number[:5] + '0000' + number[5]
25
# This is almost exactly the same as the standard FAMILIES
26
# But flipped around and with the first 111000 instead of 000000.
27
FAMS = [ '111000', '110100', '110010', '110001', '101100',
28
'100110', '100011', '101010', '101001', '100101' ]
30
class Object(EanBarcode):
31
"""Generate EAN6/UPC-E barcode generator"""
37
"""Generate a UPC-E Barcode"""
38
self.label = self.space(['0'], 2, n[:6], 2, n[-1])
39
code = self.encode_interleaved(n[-1], n[:6], FAMS)
40
# 202(guard) + code + 020(center) + 202(guard)
41
return self.enclose(code, center='020')
43
def appendChecksum(self, number):
44
"""Generate a UPCE Checksum"""
46
number = self.ConvertEtoA(number)
47
result = self.getChecksum(number)
48
return self.ConvertAtoE(number) + result
51
"""We need a font size of 10"""
54
def ConvertAtoE(self, number):
55
"""Converting UPC-A to UPC-E, may cause errors."""
56
# All UPC-E Numbers use number system 0
57
if number[0] != '0' or len(number)!=11:
58
# If not then the code is invalid
61
# Most of the conversions deal
62
# with the specific code parts
63
manufacturer = number[1:6]
64
product = number[6:11]
66
# There are 4 cases to convert:
67
if manufacturer[2:] == '000' or manufacturer[2:] == '100' or manufacturer[2:] == '200':
68
# Maxium number product code digits can be encoded
70
return manufacturer[:2] + product[2:] + manufacturer[2]
71
elif manufacturer[3:5] == '00':
72
# Now only 2 product code digits can be used
73
if product[:3]=='000':
74
return manufacturer[:3] + product[3:] + '3'
75
elif manufacturer[4] == '0':
76
# With even more manufacturer code we have less room for product code
77
if product[:4]=='0000':
78
return manufacturer[0:4] + product[4] + '4'
79
elif product[:4]=='0000' and int(product[4]) > 4:
80
# The last recorse is to try and squeeze it in the last 5 numbers
81
# so long as the product is 00005-00009 so as not to conflict with
83
return manufacturer + product[4]
88
def ConvertEtoA(self, number):
89
"""Convert UPC-E to UPC-A by padding with zeros"""
90
# It's more likly to convert this without fault
91
# But we still must be mindful of the 4 conversions
95
if number[5] in ['0', '1', '2']:
96
return '0' + number[:2] + number[5] + '0000' + number[2:5]
97
elif number[5] == '3':
98
return '0' + number[:3] + '00000' + number[3:5]
99
elif number[5] == '4':
100
return '0' + number[:4] + '00000' + number[4]
102
return '0' + number[:5] + '0000' + number[5]