diff --git a/src/labelle/cli/cli.py b/src/labelle/cli/cli.py index 0ab34132..5979eeb5 100755 --- a/src/labelle/cli/cli.py +++ b/src/labelle/cli/cli.py @@ -18,7 +18,6 @@ from labelle.lib.constants import ( DEFAULT_BARCODE_TYPE, DEFAULT_MARGIN_PX, - PIXELS_PER_MM, USE_QR, BarcodeType, Direction, @@ -54,12 +53,12 @@ LOG = logging.getLogger(__name__) -def mm_to_payload_px(mm: float, margin: float) -> float: +def mm_to_payload_px(labeler: DymoLabeler, mm: float, margin: float) -> float: """Convert a length in mm to a number of pixels of payload. - The print resolution is 7 pixels/mm, and margin is subtracted from each side. + Margin is subtracted from each side. """ - return max(0, (mm * PIXELS_PER_MM) - margin * 2) + return max(0, (mm * labeler.pixels_per_mm) - margin * 2) def version_callback(value: bool) -> None: @@ -503,13 +502,6 @@ def default( min_label_mm_len = fixed_length max_label_mm_len = fixed_length - min_payload_len_px = mm_to_payload_px(min_label_mm_len, margin_px) - max_payload_len_px = ( - mm_to_payload_px(max_label_mm_len, margin_px) - if max_label_mm_len is not None - else None - ) - if output == Output.PRINTER: device_manager = get_device_manager() device = device_manager.find_and_select_device(patterns=device_pattern) @@ -518,13 +510,21 @@ def default( device = None dymo_labeler = DymoLabeler(tape_size_mm=tape_size_mm, device=device) + + min_payload_len_px = mm_to_payload_px(dymo_labeler, min_label_mm_len, margin_px) + max_payload_len_px = ( + mm_to_payload_px(dymo_labeler, max_label_mm_len, margin_px) + if max_label_mm_len is not None + else None + ) + if not render_engines: raise typer.BadParameter("No elements to print") render_engine = HorizontallyCombinedRenderEngine(render_engines) render_context = RenderContext( background_color="white", foreground_color="black", - height_px=dymo_labeler.height_px, + height_px=dymo_labeler.label_height_px, preview_show_margins=False, ) @@ -544,6 +544,7 @@ def default( else: render = PrintPreviewRenderEngine( render_engine=render_engine, + dymo_labeler=dymo_labeler, justify=justify, visible_horizontal_margin_px=margin_px, labeler_margin_px=dymo_labeler.labeler_margin_px, diff --git a/src/labelle/gui/gui.py b/src/labelle/gui/gui.py index 3bcc679f..730ef1b5 100644 --- a/src/labelle/gui/gui.py +++ b/src/labelle/gui/gui.py @@ -63,7 +63,7 @@ def _init_elements(self) -> None: self._device_manager = DeviceManager() self._dymo_labeler = DymoLabeler() self._settings_toolbar.update_labeler_context( - supported_tape_sizes=self._dymo_labeler.SUPPORTED_TAPE_SIZES_MM, + supported_tape_sizes=self._dymo_labeler.device_config.supported_tape_sizes_mm, installed_tape_size=self._dymo_labeler.tape_size_mm, minimum_horizontal_margin_mm=self._dymo_labeler.minimum_horizontal_margin_mm, ) @@ -105,7 +105,7 @@ def _on_settings_changed(self, settings: Settings) -> None: self._render_context = RenderContext( foreground_color=settings.foreground_color, background_color=settings.background_color, - height_px=self._dymo_labeler.height_px, + height_px=self._dymo_labeler.label_height_px, preview_show_margins=settings.preview_show_margins, ) self._label_list.update_params( diff --git a/src/labelle/gui/q_labels_list.py b/src/labelle/gui/q_labels_list.py index 60cb5a85..bbaa133e 100644 --- a/src/labelle/gui/q_labels_list.py +++ b/src/labelle/gui/q_labels_list.py @@ -27,7 +27,6 @@ RenderEngine, RenderEngineException, ) -from labelle.lib.utils import mm_to_px LOG = logging.getLogger(__name__) @@ -159,11 +158,12 @@ def render_preview(self) -> None: assert self.render_context is not None render_engine = PrintPreviewRenderEngine( render_engine=self._payload_render_engine, + dymo_labeler=self.dymo_labeler, justify=self.justify, - visible_horizontal_margin_px=mm_to_px(self.h_margin_mm), + visible_horizontal_margin_px=self.dymo_labeler.mm_to_px(self.h_margin_mm), labeler_margin_px=self.dymo_labeler.labeler_margin_px, max_width_px=None, - min_width_px=mm_to_px(self.min_label_width_mm), + min_width_px=self.dymo_labeler.mm_to_px(self.min_label_width_mm), ) try: bitmap = render_engine.render(self.render_context) @@ -179,10 +179,10 @@ def render_print(self) -> None: render_engine = PrintPayloadRenderEngine( render_engine=self._payload_render_engine, justify=self.justify, - visible_horizontal_margin_px=mm_to_px(self.h_margin_mm), + visible_horizontal_margin_px=self.dymo_labeler.mm_to_px(self.h_margin_mm), labeler_margin_px=self.dymo_labeler.labeler_margin_px, max_width_px=None, - min_width_px=mm_to_px(self.min_label_width_mm), + min_width_px=self.dymo_labeler.mm_to_px(self.min_label_width_mm), ) try: bitmap, _ = render_engine.render_with_meta(self.render_context) diff --git a/src/labelle/gui/q_settings_toolbar.py b/src/labelle/gui/q_settings_toolbar.py index 57b45e6a..f633451a 100644 --- a/src/labelle/gui/q_settings_toolbar.py +++ b/src/labelle/gui/q_settings_toolbar.py @@ -57,7 +57,7 @@ def _init_elements(self) -> None: def update_labeler_context( self, - supported_tape_sizes: tuple[int, ...], + supported_tape_sizes: list[int], installed_tape_size: int, minimum_horizontal_margin_mm: float, ) -> None: diff --git a/src/labelle/lib/constants.py b/src/labelle/lib/constants.py index dc17da49..646a39f1 100755 --- a/src/labelle/lib/constants.py +++ b/src/labelle/lib/constants.py @@ -18,6 +18,7 @@ import labelle.resources.fonts import labelle.resources.icons +from labelle.lib.devices.device_config import DeviceConfig try: from pyqrcode import QRCode @@ -34,19 +35,92 @@ "WARNING: This device is not confirmed to work with this software. Please " "report your experiences in https://github.com/labelle-org/labelle/issues/4" ) -SUPPORTED_PRODUCTS = { - 0x0011: "DYMO LabelMANAGER PC", - 0x0015: "LabelPoint 350", - 0x1001: "LabelManager PnP (no mode switch)", - 0x1002: "LabelManager PnP (mode switch)", - 0x1003: f"LabelManager 420P (no mode switch) {UNCONFIRMED_MESSAGE}", - 0x1004: f"LabelManager 420P (mode switch) {UNCONFIRMED_MESSAGE}", - 0x1005: "LabelManager 280 (no mode switch)", - 0x1006: "LabelManager 280 (no mode switch)", - 0x1007: f"LabelManager Wireless PnP (no mode switch) {UNCONFIRMED_MESSAGE}", - 0x1008: f"LabelManager Wireless PnP (mode switch) {UNCONFIRMED_MESSAGE}", - 0x1009: f"MobileLabeler {UNCONFIRMED_MESSAGE}", -} + +# ---- Supported USB Devices configuration ---- +SUPPORTED_PRODUCTS = [ + DeviceConfig( + name="DYMO LabelMANAGER PC", + device_ids=[0x0011], + # ToDo: Validate config! + # Printhead 128 Pixels, distributed over 18mm of active area + print_head_px=128, + print_head_mm=18, + supported_tape_sizes_mm=[6, 9, 12, 19], + ), + DeviceConfig( + name="LabelPoint 350", + device_ids=[0x0015], + # ToDo: Validate config! + # Printhead 64 Pixels, distributed over 9mm of active area + print_head_px=64, + print_head_mm=9, + supported_tape_sizes_mm=[6, 9, 12], + ), + DeviceConfig( + name="DYMO LabelMANAGER PC II", + device_ids=[0x001C], + # Printhead 128 Pixels, distributed over 18mm of active area + print_head_px=128, + print_head_mm=18, + supported_tape_sizes_mm=[6, 9, 12, 19, 24], + ), + DeviceConfig( + name="LabelManager PnP", + device_ids=[0x1001, 0x1002], + # Printhead 64 Pixels, distributed over 9mm of active area + print_head_px=64, + print_head_mm=9, + supported_tape_sizes_mm=[6, 9, 12], + ), + DeviceConfig( + name=f"LabelManager 420P {UNCONFIRMED_MESSAGE}", + device_ids=[0x1003, 0x1004], + # ToDo: Validate config! + # Printhead 64 Pixels, distributed over 9mm of active area + print_head_px=64, + print_head_mm=9, + supported_tape_sizes_mm=[6, 9, 12], + ), + DeviceConfig( + name="LabelManager 280", + device_ids=[0x1006, 0x1005], + # ToDo: Validate config! + # Printhead 64 Pixels, distributed over 9mm of active area + print_head_px=64, + print_head_mm=9, + supported_tape_sizes_mm=[6, 9, 12], + ), + DeviceConfig( + name=f"LabelManager Wireless PnP {UNCONFIRMED_MESSAGE}", + device_ids=[0x1007, 0x1008], + # ToDo: Validate config! + # Printhead 64 Pixels, distributed over 9mm of active area + print_head_px=64, + print_head_mm=9, + supported_tape_sizes_mm=[6, 9, 12], + ), + DeviceConfig( + name=f"MobileLabeler {UNCONFIRMED_MESSAGE}", + device_ids=[0x1009], + # ToDo: Validate config! + # Printhead 64 Pixels, distributed over 9mm of active area + print_head_px=64, + print_head_mm=9, + supported_tape_sizes_mm=[6, 9, 12], + ), +] + +# Simulator configuration +SIMULATOR_CONFIG = DeviceConfig( + name="Simulator", + device_ids=[0], + # Fake printhead 128 Pixels, distributed over 18mm of active area + print_head_px=128, + print_head_mm=18, + supported_tape_sizes_mm=[6, 9, 12, 19, 24], +) + + DEV_VENDOR = 0x0922 PRINTER_INTERFACE_CLASS = 0x07 @@ -63,10 +137,6 @@ DEFAULT_MARGIN_PX = 56 VERTICAL_PREVIEW_MARGIN_PX = 13 -DPI = 180 -MM_PER_INCH = 25.4 -PIXELS_PER_MM = DPI / MM_PER_INCH - ICON_DIR = Path(labelle.resources.icons.__file__).parent diff --git a/src/labelle/lib/devices/device_config.py b/src/labelle/lib/devices/device_config.py new file mode 100644 index 00000000..4de9fc68 --- /dev/null +++ b/src/labelle/lib/devices/device_config.py @@ -0,0 +1,44 @@ +from __future__ import annotations + +import logging +from dataclasses import dataclass + +LOG = logging.getLogger(__name__) + + +@dataclass +class DeviceConfig: + """Configuration object for the capabilities of a label printer.""" + + name: str + """Name of this device""" + + device_ids: list[int] + """List of USB Device ID's this device can identify as""" + + print_head_px: int + """Size of the print head in pixels (use calibration routine to determine)""" + + print_head_mm: float + """Size of the active area of the print head in millimters + (use calibration routine to determine)""" + + supported_tape_sizes_mm: list[int] + """List of supported tape sizes in mm""" + + tape_alignment_inaccuracy_mm: float = 1.0 + """The inaccuracy of the tape position relative to the printhead + + Inaccuracy of the tape position is mostly caused by + the tape moving slightly from side to side in the cartridge. + Improper cartrigde placemement is also an factor, + but negligible due to a physical spring in the lid. + """ + + LABELER_DISTANCE_BETWEEN_PRINT_HEAD_AND_CUTTER_MM: float = 8.1 + """This is the distance between the printhead and the cutter (knife). + """ + + def matches_device_id(self, device_id: int) -> bool: + """Check if the a device ID matches this config.""" + return device_id in self.device_ids diff --git a/src/labelle/lib/devices/device_manager.py b/src/labelle/lib/devices/device_manager.py index 0cd9b508..1a66a2fd 100644 --- a/src/labelle/lib/devices/device_manager.py +++ b/src/labelle/lib/devices/device_manager.py @@ -8,6 +8,7 @@ SUPPORTED_PRODUCTS, UNCONFIRMED_MESSAGE, ) +from labelle.lib.devices.device_config import DeviceConfig from labelle.lib.devices.usb_device import UsbDevice LOG = logging.getLogger(__name__) @@ -80,8 +81,23 @@ def find_and_select_device(self, patterns: list[str] | None = None) -> UsbDevice LOG.debug(dev.device_info) dev = devices[0] if dev.is_supported: - msg = f"Recognized device as {SUPPORTED_PRODUCTS[dev.id_product]}" + msg = f"Recognized device as {get_device_config_by_id(dev.id_product).name}" else: msg = f"Unrecognized device: {hex(dev.id_product)}. {UNCONFIRMED_MESSAGE}" LOG.debug(msg) return dev + + +def get_device_config_by_id(product_id: int) -> DeviceConfig: + """Get a labeler device config with USB ID. + + :param idValue: USB ID value + :return: Device config, None if not found + """ + # + for device in SUPPORTED_PRODUCTS: + if device.matches_device_id(product_id): + return device + + # No device config found + raise ValueError(f"Unsupported device type product id: {hex(product_id)}") diff --git a/src/labelle/lib/devices/dymo_labeler.py b/src/labelle/lib/devices/dymo_labeler.py index 066309f6..f712a79d 100755 --- a/src/labelle/lib/devices/dymo_labeler.py +++ b/src/labelle/lib/devices/dymo_labeler.py @@ -10,14 +10,16 @@ import array import logging import math +from collections import namedtuple import usb from PIL import Image from usb.core import NoBackendError, USBError -from labelle.lib.constants import ESC, SYN +from labelle.lib.constants import ESC, SIMULATOR_CONFIG, SYN +from labelle.lib.devices.device_config import DeviceConfig +from labelle.lib.devices.device_manager import get_device_config_by_id from labelle.lib.devices.usb_device import UsbDevice, UsbDeviceError -from labelle.lib.utils import mm_to_px LOG = logging.getLogger(__name__) POSSIBLE_USB_ERRORS = (UsbDeviceError, NoBackendError, USBError) @@ -236,31 +238,43 @@ def _raw_print_label(self, lines: list[list[int]]): class DymoLabeler: _device: UsbDevice | None + _device_config: DeviceConfig tape_size_mm: int - LABELER_DISTANCE_BETWEEN_PRINT_HEAD_AND_CUTTER_MM = 8.1 - LABELER_PRINT_HEAD_HEIGHT_MM = 8.2 - SUPPORTED_TAPE_SIZES_MM = (19, 12, 9, 6) - DEFAULT_TAPE_SIZE_MM = 12 + TapePrintProperties = namedtuple( + "TapePrintProperties", + ["usable_tape_height_px", "top_margin_px", "bottom_margin_px"], + ) + """Tape print properties tuple type. + Contains margins and size in pixels for printing. + """ def __init__( self, tape_size_mm: int | None = None, device: UsbDevice | None = None, ): + self.device = device + + if self._device_config is None: + raise ValueError("No device config") + if tape_size_mm is None: - tape_size_mm = self.DEFAULT_TAPE_SIZE_MM - if tape_size_mm not in self.SUPPORTED_TAPE_SIZES_MM: + # Select highest supported tape size as default, if not set + tape_size_mm = max(self._device_config.supported_tape_sizes_mm) + + # Check if selected tape size is supported + if tape_size_mm not in self._device_config.supported_tape_sizes_mm: raise ValueError( f"Unsupported tape size {tape_size_mm}mm. " - f"Supported sizes: {self.SUPPORTED_TAPE_SIZES_MM}" + f"Supported sizes: {self._device_config.supported_tape_sizes_mm}mm" ) self.tape_size_mm = tape_size_mm - self._device = device @property - def height_px(self): - return DymoLabelerFunctions.height_px(self.tape_size_mm) + def label_height_px(self): + """Get the (usable) tape height in pixels.""" + return self.tape_print_properties.usable_tape_height_px @property def _functions(self) -> DymoLabelerFunctions: @@ -273,19 +287,76 @@ def _functions(self) -> DymoLabelerFunctions: @property def minimum_horizontal_margin_mm(self): - return self.LABELER_DISTANCE_BETWEEN_PRINT_HEAD_AND_CUTTER_MM + # Return distance between printhead and cutter + # as we don't want to cut though our printed label + return self.device_config.LABELER_DISTANCE_BETWEEN_PRINT_HEAD_AND_CUTTER_MM @property def labeler_margin_px(self) -> tuple[float, float]: - vertical_margin_mm = max( - 0, (self.tape_size_mm - self.LABELER_PRINT_HEAD_HEIGHT_MM) / 2 + return ( + self.mm_to_px(self.minimum_horizontal_margin_mm), + self.tape_print_properties.top_margin_px, ) - return ( - mm_to_px(self.minimum_horizontal_margin_mm), - mm_to_px(vertical_margin_mm), + @property + def tape_print_properties(self) -> TapePrintProperties: + # Check if selected tape size supported + if self.tape_size_mm not in self.device_config.supported_tape_sizes_mm: + raise ValueError( + f"Unsupported tape size {self.tape_size_mm}mm. " + f"Supported sizes: {self.device_config.supported_tape_sizes_mm}mm" + ) + + # Calculate usable tape height (*2 for top and bottom) + usable_tape_height_mm: float = self.tape_size_mm - ( + 2 * self.device_config.tape_alignment_inaccuracy_mm + ) + + # Calculate the numer of active pixels for the tape + usable_tape_height_pixels: float = 0 + if usable_tape_height_mm >= self.device_config.print_head_mm: + # Tape is larger than active area of printhead. Use all pixels + usable_tape_height_pixels = self.device_config.print_head_px + else: + # Calculate the amount of active pixels we are able to use + # (taking the placement inaccuracy into account) + usable_tape_height_pixels = self.pixels_per_mm * usable_tape_height_mm + + # Round down to nearest whole number as we can't use half a pixels ;) + usable_tape_height_pixels = math.floor(usable_tape_height_pixels) + + # To calculate the margins we need to know some hardware info: + # The printer has special "support studs" that allow 19 & 24mm tapes + # to sink to the bottom of the printer. + # 12mm based casettes are raised slightly so they are center to the printhead. + # Tapes smaller than 12mm are centered in the cartridge and to the printhead. + # This gives us the advantage that we can calculate the top and bottom margin + + # Calculate the top margin + margin_top = round( + ((self.device_config.print_head_px - usable_tape_height_pixels) / 2), 0 ) + # Bottom margin is equal due to centering of the tape + margin_bottom = margin_top + + # Make sure the total is the exact amount of pixels of the printhead + # Aka compensate for margin rounding/division errors + usable_tape_height_pixels = self.device_config.print_head_px - ( + margin_top + margin_bottom + ) + + # Return active pixels / margins set + return self.TapePrintProperties( + usable_tape_height_px=int(usable_tape_height_pixels), + top_margin_px=int(margin_top), + bottom_margin_px=int(margin_bottom), + ) + + @property + def device_config(self) -> DeviceConfig: + return self._device_config + @property def device(self) -> UsbDevice | None: return self._device @@ -295,6 +366,13 @@ def device(self, device: UsbDevice | None): try: if device: device.setup() + + # Retrieve device config based on product ID + self._device_config = get_device_config_by_id(device.id_product) + else: + # Use simulator config + self._device_config = SIMULATOR_CONFIG + except UsbDeviceError as e: device = None LOG.error(e) @@ -304,6 +382,23 @@ def device(self, device: UsbDevice | None): def is_ready(self) -> bool: return self.device is not None + @property + def pixels_per_mm(self) -> float: + # Calculate the pixels per mm for this printer + # Example: printhead of 128 Pixels, distributed over 18 mm of active area. + # Makes 7.11 pixels/mm + return self.device_config.print_head_px / self.device_config.print_head_mm + + def px_to_mm(self, px) -> float: + """Convert pixels to millimeters for the current printer.""" + mm = px / self.pixels_per_mm + # Round up to nearest 0.1mm + return math.ceil(mm * 10) / 10 + + def mm_to_px(self, mm) -> float: + """Convert millimeters to pixels for the current printer.""" + return mm * self.pixels_per_mm + def print( self, bitmap: Image.Image, diff --git a/src/labelle/lib/devices/usb_device.py b/src/labelle/lib/devices/usb_device.py index 2770091c..113d5a7d 100644 --- a/src/labelle/lib/devices/usb_device.py +++ b/src/labelle/lib/devices/usb_device.py @@ -87,10 +87,15 @@ def _is_supported_vendor(dev: usb.core.Device) -> bool: @property def is_supported(self) -> bool: - return ( - self._is_supported_vendor(self._dev) - and self.id_product in SUPPORTED_PRODUCTS - ) + # If vendor matches + if self._is_supported_vendor(self._dev) is True: + # if one item in our supported products matches the device id + for device in SUPPORTED_PRODUCTS: + if device.matches_device_id(self.id_product) is True: + return True + + # no matches found + return False @staticmethod def supported_devices() -> set[UsbDevice]: diff --git a/src/labelle/lib/render_engines/margins.py b/src/labelle/lib/render_engines/margins.py index 15cfe01e..a634920d 100644 --- a/src/labelle/lib/render_engines/margins.py +++ b/src/labelle/lib/render_engines/margins.py @@ -105,25 +105,22 @@ def render_with_meta( # There's also some vertical margin between printed area and the label # edge - vertical_offset_px: float = 0 if self.mode == "print": # print head is already in offset from label's edge under the cutter horizontal_offset_px -= self.labeler_horizontal_margin_px - # no need to add vertical margins to bitmap - bitmap_height = float(payload_bitmap.height) - elif self.mode == "preview": - # add vertical margins to bitmap - bitmap_height = ( - float(payload_bitmap.height) + self.labeler_vertical_margin_px * 2.0 - ) - vertical_offset_px = self.labeler_vertical_margin_px + + # add vertical margins to bitmap + bitmap_height = ( + float(payload_bitmap.height) + self.labeler_vertical_margin_px * 2.0 + ) bitmap = Image.new("1", (math.ceil(label_width_px), math.ceil(bitmap_height))) bitmap.paste( - payload_bitmap, box=(round(horizontal_offset_px), round(vertical_offset_px)) + payload_bitmap, + box=(round(horizontal_offset_px), round(self.labeler_vertical_margin_px)), ) meta = { "horizontal_offset_px": horizontal_offset_px, - "vertical_offset_px": vertical_offset_px, + "vertical_offset_px": self.labeler_vertical_margin_px, } return bitmap, meta diff --git a/src/labelle/lib/render_engines/print_preview.py b/src/labelle/lib/render_engines/print_preview.py index a7406517..4cbc32cc 100644 --- a/src/labelle/lib/render_engines/print_preview.py +++ b/src/labelle/lib/render_engines/print_preview.py @@ -4,10 +4,10 @@ from PIL import Image, ImageColor, ImageDraw, ImageOps from labelle.lib.constants import Direction +from labelle.lib.devices.dymo_labeler import DymoLabeler from labelle.lib.render_engines.margins import MarginsRenderEngine from labelle.lib.render_engines.render_context import RenderContext from labelle.lib.render_engines.render_engine import RenderEngine -from labelle.lib.utils import px_to_mm class PrintPreviewRenderEngine(RenderEngine): @@ -15,10 +15,12 @@ class PrintPreviewRenderEngine(RenderEngine): Y_MARGIN_PX = 30 DX = X_MARGIN_PX * 0.3 DY = Y_MARGIN_PX * 0.3 + dymo_labeler: DymoLabeler def __init__( self, render_engine: RenderEngine, + dymo_labeler: DymoLabeler, justify: Direction = Direction.CENTER, visible_horizontal_margin_px: float = 0, labeler_margin_px: tuple[float, float] = (0, 0), @@ -26,6 +28,7 @@ def __init__( min_width_px: float = 0, ): super().__init__() + self.dymo_labeler = dymo_labeler self.render_engine = MarginsRenderEngine( render_engine=render_engine, mode="preview", @@ -166,28 +169,28 @@ def _show_margins(self, label_bitmap, preview_bitmap, meta, context): # payload width { "xy": (self.X_MARGIN_PX + label_width / 2, preview_width_mark_y), - "text": f"{px_to_mm(label_width - x_margin * 2)} mm", + "text": f"{self.dymo_labeler.px_to_mm(label_width - x_margin * 2)} mm", "anchor": "mm", "align": "center", }, # label width { "xy": (self.X_MARGIN_PX + label_width / 2, label_width_mark_y), - "text": f"{px_to_mm(label_width)} mm", + "text": f"{self.dymo_labeler.px_to_mm(label_width)} mm", "anchor": "mm", "align": "center", }, # payload height { "xy": (preview_width_mark_x, self.DY + label_height / 2 - self.DY), - "text": f"{px_to_mm(label_height - y_margin * 2)} mm", + "text": f"{self.dymo_labeler.px_to_mm(label_height - y_margin * 2)} mm", "anchor": "mm", "align": "center", }, # label height { "xy": (label_width_mark_x, self.DY + label_height / 2 + self.DY), - "text": f"{px_to_mm(label_height)} mm", + "text": f"{self.dymo_labeler.px_to_mm(label_height)} mm", "anchor": "mm", "align": "center", }, diff --git a/src/labelle/lib/utils.py b/src/labelle/lib/utils.py index a465004f..56fb7281 100755 --- a/src/labelle/lib/utils.py +++ b/src/labelle/lib/utils.py @@ -7,13 +7,11 @@ # === END LICENSE STATEMENT === import contextlib import logging -import math import sys from typing import Generator, List, Tuple from PIL import ImageDraw -from labelle.lib.constants import PIXELS_PER_MM from labelle.lib.logger import print_exception LOG = logging.getLogger(__name__) @@ -34,16 +32,6 @@ def draw_image(bitmap) -> Generator[ImageDraw.ImageDraw, None, None]: del drawobj -def px_to_mm(px) -> float: - mm = px / PIXELS_PER_MM - # Round up to nearest 0.1mm - return math.ceil(mm * 10) / 10 - - -def mm_to_px(mm) -> float: - return mm * PIXELS_PER_MM - - @contextlib.contextmanager def system_run() -> Generator[None, None, None]: try: