From cca66b9ec4e494c1d919bff0f71a820d8afab1fa Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Sun, 7 Apr 2024 20:24:48 +0200 Subject: Adding upstream version 1.2.2. Signed-off-by: Daniel Baumann --- share/extensions/barcode/Code128.py | 246 ++++++++++++++++++++++++++++++++++++ 1 file changed, 246 insertions(+) create mode 100644 share/extensions/barcode/Code128.py (limited to 'share/extensions/barcode/Code128.py') diff --git a/share/extensions/barcode/Code128.py b/share/extensions/barcode/Code128.py new file mode 100644 index 0000000..e5f8701 --- /dev/null +++ b/share/extensions/barcode/Code128.py @@ -0,0 +1,246 @@ +# coding=utf-8 +# +# Authored by Martin Owens +# 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA. +# +""" +Renderer for Code128/EAN128 codes. Designed for use with Inkscape. +""" + +import re + +from .Base import Barcode + +CODE_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 map_extra(data, chars): + """Maps the data into the chars""" + result = list(data) + for char in chars: + result.append(chr(char)) + result.append("FNC3") + result.append("FNC2") + result.append("SHIFT") + return result + + +# The map_extra method is used to slim down the amount +# of pre code and instead we generate the lists +CHAR_AB = list(" !\"#$%&'()*+,-./0123456789:;<=>?@" "ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_") +CHAR_A = map_extra(CHAR_AB, range(0, 31)) # Offset 64 +CHAR_B = map_extra(CHAR_AB, range(96, 127)) # Offset -32 + + +class Code128(Barcode): + """Main barcode object, generates the encoding bits here""" + + def encode(self, text): + blocks = [] + block = "" + + # Split up into sections of numbers, or characters + # This makes sure that all the characters are encoded + # In the best way possible 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.best_block(block)) + block = "" + blocks.append(["C", datum]) + + if block: + blocks.append(Code128.best_block(block)) + block = "" + + return Code128.encode_blocks(blocks) + + @staticmethod + def best_block(block): + """If this has characters above 63, select B over A""" + if any(ord(x) > 63 for x in block): + return ["B", block] + return ["A", block] + + @staticmethod + def encode_blocks(blocks): + """Encode the given blocks into A, B or C codes""" + encode = "" + total = 0 + pos = 0 + + for block in blocks: + b_set = block[0] + datum = block[1] + + # POS : 0, 1 + # A : 101, 103 + # B : 100, 104 + # C : 99, 105 + num = 0 + if b_set == "A": + num = 103 + elif b_set == "B": + num = 104 + elif b_set == "C": + num = 105 + + i = pos + if pos: + num = 204 - num + else: + i = 1 + + total = total + num * i + encode = encode + CODE_MAP[num] + pos += 1 + + if b_set in ("A", "B"): + chars = CHAR_B + if b_set == "A": + chars = CHAR_A + + for char in datum: + total = total + (chars.index(char) * pos) + encode = encode + CODE_MAP[chars.index(char)] + 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 + CODE_MAP[int(char)] + pos += 1 + + checksum = total % 103 + encode = encode + CODE_MAP[checksum] + encode = encode + CODE_MAP[106] + encode = encode + CODE_MAP[107] + + return encode -- cgit v1.2.3