From 55285f3f519baa84622b24fb95a3f2e5c672ef33 Mon Sep 17 00:00:00 2001 From: Florian Ostermaier Date: Thu, 24 Nov 2022 21:45:49 +0100 Subject: [PATCH 1/5] fix wrong bar width in ImageWriter --- barcode/writer.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/barcode/writer.py b/barcode/writer.py index f304703..d89a70a 100755 --- a/barcode/writer.py +++ b/barcode/writer.py @@ -428,7 +428,7 @@ def _paint_module(self, xpos, ypos, width, color): size = [ (mm2px(xpos, self.dpi), mm2px(ypos, self.dpi)), ( - mm2px(xpos + width, self.dpi), + mm2px(xpos + width, self.dpi) - 1, mm2px(ypos + self.module_height, self.dpi), ), ] From cb678b80fda899476123cc3930d54787cf75c06d Mon Sep 17 00:00:00 2001 From: Florian Ostermaier Date: Thu, 24 Nov 2022 23:11:46 +0100 Subject: [PATCH 2/5] replace hard-coded margin with parameters pass 'quiet_zone': 0, 'margin_top': 0, 'margin_bottom': 0, for borderless codes --- barcode/writer.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/barcode/writer.py b/barcode/writer.py index d89a70a..6a748e9 100755 --- a/barcode/writer.py +++ b/barcode/writer.py @@ -101,6 +101,8 @@ def __init__( self.text_line_distance = 1 self.center_text = True self.guard_height_factor = 1.1 + self.margin_top = 1 + self.margin_bottom = 1 def calculate_size(self, modules_per_line, number_of_lines): """Calculates the size of the barcode in pixel. @@ -115,7 +117,7 @@ def calculate_size(self, modules_per_line, number_of_lines): :rtype: Tuple """ width = 2 * self.quiet_zone + modules_per_line * self.module_width - height = 2.0 + self.module_height * number_of_lines + height = self.margin_bottom + self.margin_top + self.module_height * number_of_lines number_of_text_lines = len(self.text.splitlines()) if self.font_size and self.text: height += ( @@ -204,7 +206,7 @@ def render(self, code): """ if self._callbacks["initialize"] is not None: self._callbacks["initialize"](code) - ypos = 1.0 + ypos = self.margin_top base_height = self.module_height for cc, line in enumerate(code): # Left quiet zone is x startposition From 6073331ddb9623fea080f2c59cf79b5ef412ad45 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Thu, 24 Nov 2022 22:14:04 +0000 Subject: [PATCH 3/5] [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --- barcode/writer.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/barcode/writer.py b/barcode/writer.py index 6a748e9..3a3dcd0 100755 --- a/barcode/writer.py +++ b/barcode/writer.py @@ -117,7 +117,9 @@ def calculate_size(self, modules_per_line, number_of_lines): :rtype: Tuple """ width = 2 * self.quiet_zone + modules_per_line * self.module_width - height = self.margin_bottom + self.margin_top + self.module_height * number_of_lines + height = ( + self.margin_bottom + self.margin_top + self.module_height * number_of_lines + ) number_of_text_lines = len(self.text.splitlines()) if self.font_size and self.text: height += ( From ae1ef4bddd3352f8612d9b9692781a942d96e362 Mon Sep 17 00:00:00 2001 From: Florian Ostermaier Date: Sat, 26 Nov 2022 00:11:12 +0100 Subject: [PATCH 4/5] enable pzn8 --- barcode/__init__.py | 1 + barcode/codex.py | 13 +++++++++++-- 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/barcode/__init__.py b/barcode/__init__.py index d0d15cd..9661706 100755 --- a/barcode/__init__.py +++ b/barcode/__init__.py @@ -10,6 +10,7 @@ from barcode.codabar import CODABAR from barcode.codex import PZN +from barcode.codex import PZN8 from barcode.codex import Code39 from barcode.codex import Code128 from barcode.codex import Gs1_128 diff --git a/barcode/codex.py b/barcode/codex.py index 74665be..2113f0c 100755 --- a/barcode/codex.py +++ b/barcode/codex.py @@ -98,7 +98,7 @@ def __init__(self, pzn, writer=None): ) self.pzn = pzn self.pzn = f"{pzn}{self.calculate_checksum()}" - super().__init__(f"PZN-{self.pzn}", writer, add_checksum=False) + super().__init__(f"-{self.pzn}", writer, add_checksum=False) def get_fullcode(self): return f"PZN-{self.pzn}" @@ -113,7 +113,16 @@ def calculate_checksum(self): class PZN8(PZN7): - """Will be fully added in v0.9.""" + """Represents an PZN8 barcode. See PZN7's __init__ for details. + + :parameters: + pzn : String + Code to render. + writer : barcode.writer Instance + The writer to render the barcode (default: SVGWriter). + """ + + name = "Pharmazentralnummer-8" digits = 7 From d8775b0a17658487c1c35225b46bd43df2a8637a Mon Sep 17 00:00:00 2001 From: Florian Ostermaier Date: Wed, 30 Nov 2022 23:36:48 +0100 Subject: [PATCH 5/5] Implement PZN8 Code * verify or append checksum based on code length for PZN7 and PZN8 * explicit error messages for both classes respectively * different checksum calculation for PZN8 --- barcode/codex.py | 35 +++++++++++++++++++++++++++-------- 1 file changed, 27 insertions(+), 8 deletions(-) diff --git a/barcode/codex.py b/barcode/codex.py index 2113f0c..f621996 100755 --- a/barcode/codex.py +++ b/barcode/codex.py @@ -87,29 +87,45 @@ class PZN7(Code39): name = "Pharmazentralnummer" digits = 6 + checksum_length = 1 def __init__(self, pzn, writer=None): - pzn = pzn[: self.digits] + if not pzn.isdigit(): raise IllegalCharacterError("PZN can only contain numbers.") - if len(pzn) != self.digits: + + # calculate and append checksum if not included in supplied code, verify last digit otherwise + if len(pzn) == self.digits: + self.pzn_core = pzn + self.pzn = pzn + self.calculate_checksum() + + elif len(pzn) == self.digits + self.checksum_length: + self.pzn_core = pzn[:-1] + checksum_ok = pzn[-1] == self.calculate_checksum() + if checksum_ok: + self.pzn = pzn + else: + raise BarcodeError( + f"Checksum (last digit) is not valid for the supplied {self.__class__.__name__} code.") + + else: raise NumberOfDigitsError( - f"PZN must have {self.digits} digits, not {len(pzn)}." + f"{self.__class__.__name__} must have {self.digits} digits (excluding checksum) " + f"or {self.digits + self.checksum_length} digits (including checksum), not {len(pzn)}." ) - self.pzn = pzn - self.pzn = f"{pzn}{self.calculate_checksum()}" + super().__init__(f"-{self.pzn}", writer, add_checksum=False) def get_fullcode(self): return f"PZN-{self.pzn}" - def calculate_checksum(self): - sum_ = sum(int(x) * int(y) for x, y in enumerate(self.pzn, start=2)) + def calculate_checksum(self, start=2): + sum_ = sum(int(x) * int(y) for x, y in enumerate(self.pzn_core, start)) checksum = sum_ % 11 if checksum == 10: raise BarcodeError("Checksum can not be 10 for PZN.") else: - return checksum + return str(checksum) class PZN8(PZN7): @@ -126,6 +142,9 @@ class PZN8(PZN7): digits = 7 + def calculate_checksum(self, start=1): + return super().calculate_checksum(start=start) + class Code128(Barcode): """Initializes a new Code128 instance. The checksum is added automatically