112 lines
3.9 KiB
Python
112 lines
3.9 KiB
Python
# coding=utf-8
|
|
#
|
|
# 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA.
|
|
#
|
|
"""
|
|
Python barcode renderer for UPCE barcodes. Designed for use with Inkscape.
|
|
"""
|
|
|
|
from .BaseEan import EanBarcode
|
|
from inkex.localization import inkex_gettext as _
|
|
|
|
# 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"
|
|
font_size = 10
|
|
lengths = [6, 11]
|
|
checks = [7, 12]
|
|
center_bar = "020"
|
|
|
|
def _encode(self, num, guide=False):
|
|
"""Generate a UPC-E Barcode"""
|
|
self.text = EanBarcode.space(["0"], 2, num[:6], 2, num[-1])
|
|
code = EanBarcode.encode_interleaved(num[-1], num[:6], FAMS)
|
|
return self.enclose(code)
|
|
|
|
def append_checksum(self, number):
|
|
"""Generate a UPCE Checksum"""
|
|
if len(number) == 6:
|
|
number = Upce.convert_e2a(number)
|
|
result = self.get_checksum(number)
|
|
return Upce.convert_a2e(number) + result
|
|
|
|
@staticmethod
|
|
def convert_a2e(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
|
|
maker = number[1:6]
|
|
product = number[6:11]
|
|
|
|
# There are 4 cases to convert:
|
|
if maker[2:] == "000" or maker[2:] == "100" or maker[2:] == "200":
|
|
# Maximum number product code digits can be encoded
|
|
if product[:2] == "00":
|
|
return maker[:2] + product[2:] + maker[2]
|
|
elif maker[3:5] == "00":
|
|
# Now only 2 product code digits can be used
|
|
if product[:3] == "000":
|
|
return maker[:3] + product[3:] + "3"
|
|
elif maker[4] == "0":
|
|
# With even more maker code we have less room for product code
|
|
if product[:4] == "0000":
|
|
return maker[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 maker + product[4]
|
|
# Invalid UPC-A Numbe
|
|
raise ValueError(_("Invalid UPC Number"))
|
|
|
|
@staticmethod
|
|
def convert_e2a(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]
|
|
if number[5] == "3":
|
|
return "0" + number[:3] + "00000" + number[3:5]
|
|
if number[5] == "4":
|
|
return "0" + number[:4] + "00000" + number[4]
|
|
return "0" + number[:5] + "0000" + number[5]
|