1
0
Fork 0
inkscape/share/extensions/barcode/Code93.py
Daniel Baumann 02d935e272
Adding upstream version 1.4.
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
2025-06-22 23:40:13 +02:00

187 lines
4.3 KiB
Python

# coding=utf-8
#
# 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA.
#
"""
Python barcode renderer for Code93 barcodes. Designed for use with Inkscape.
"""
from .Base import Barcode
PALLET = list("0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ-. $/+%")
PALLET.append("($)")
PALLET.append("(/)")
PALLET.append("(+)")
PALLET.append("(%)")
PALLET.append("MARKER")
MAP = dict((PALLET[i], i) for i in range(len(PALLET)))
def get_map(array):
"""Extended ENCODE maps for full ASCII Code93"""
result = {}
pos = 10
for char in array:
result[chr(char)] = PALLET[pos]
pos += 1
return result
# MapA is eclectic, but B, C, D are all ASCII ranges
MAP_A = get_map(
[
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,
]
) # %
MAP_B = get_map(range(1, 26)) # $
MAP_C = get_map(range(33, 58)) # /
MAP_D = get_map(range(97, 122)) # +
ENCODE = [
"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",
"",
]
class Code93(Barcode):
"""Encode Code93 Barcode"""
def encode(self, text):
# start marker
bits = ENCODE[MAP.get("MARKER", -1)]
# Extend to ASCII charset ( return Array )
text = Code93.encode_ascii(text)
# Calculate the checksums
text.append(Code93.checksum(text, 20)) # C
text.append(Code93.checksum(text, 15)) # K
# Now convert text into the ENCODE bits (black and white stripes)
for char in text:
bits = bits + ENCODE[MAP.get(char, -1)]
# end marker and termination bar
return bits + ENCODE[MAP.get("MARKER", -1)] + "1"
@staticmethod
def checksum(text, mod):
"""Generate a code 93 checksum"""
weight = len(text) % mod
check = 0
for char in text:
check = check + (MAP[char] * weight)
# Reset the weight is required
weight -= 1
if weight == 0:
weight = mod
return PALLET[check % 47]
@staticmethod
def encode_ascii(text):
"""Some characters need re-ENCODE into the code93 specification"""
result = []
for char in text:
if char in MAP:
result.append(char)
elif char in MAP_A:
result.append("(%)")
result.append(MAP_A[char])
elif char in MAP_B:
result.append("($)")
result.append(MAP_B[char])
elif char in MAP_C:
result.append("(/)")
result.append(MAP_C[char])
elif char in MAP_D:
result.append("(+)")
result.append(MAP_D[char])
return result