""" Print a measuring label to determine the printer's actual scale factors. The problem: we render a correct 61 x 18 mm label, but it prints around 25 x 17 mm. Two candidate causes predict different numbers, and both look similar at that size: (a) Resolution mismatch - the driver reports LOGPIXELSX=360 but the device is 180 dpi, so content is compressed 2x along the tape. Predicts marks 10 mm apart appearing ~5 mm apart in X only. (b) Driver shrink-to-fit across the 24 mm media width. Predicts an equal shrink in X and Y: scale 24/65.05 = 0.37 -> marks 10 mm apart appear 3.7 mm. This label makes the answer unambiguous: it draws ruler ticks at known spacings in both axes, so reading one number off the tape identifies the cause. Reading the print: * X ticks (along the tape) are laid out every 10 mm from 0 to 60. * Y ticks (across the tape) are laid out every 2 mm from 0 to 18. * A 10 x 10 mm reference square sits at a known position. Measure the distance between tick "0" and tick "60" (intended 60 mm): ~60 mm -> geometry correct; the problem lies elsewhere ~30 mm -> case (a), 2x compression along the tape ~22 mm -> case (b), shrink-to-fit on width other -> report the measured value """ from __future__ import annotations import os import sys sys.path.insert(0, os.path.dirname(os.path.abspath(__file__))) os.chdir(os.path.dirname(os.path.abspath(__file__))) from reportlab.lib.units import mm from reportlab.pdfgen import canvas from label_config import load_config from print_area import query_print_area from ptouch_label import LabelConfig PRINTER = "Brother PT-E560BT" def build_measure_pdf(cfg: LabelConfig, path: str) -> str: """Draw the measuring label at the configured content size.""" page_w, page_h = cfg.page_size_mm ox, oy = cfg.origin_mm content_w, content_h = cfg.page_width_mm, cfg.page_height_mm c = canvas.Canvas(path, pagesize=(page_w * mm, page_h * mm)) c.setTitle("PT-E560BT scale measurement") def X(v: float) -> float: return (ox + v) * mm def Y(v: float) -> float: return (oy + v) * mm # Outer frame exactly at the content bounds. c.setStrokeColorRGB(0, 0, 0) c.setLineWidth(0.4) c.rect(X(0), Y(0), content_w * mm, content_h * mm) # X ruler: a tick every 10 mm along the bottom, labelled. c.setFont("Helvetica", 5) for i in range(0, int(content_w) + 1, 10): tall = i % 20 == 0 c.setLineWidth(0.6 if tall else 0.3) c.line(X(i), Y(0), X(i), Y(3.5 if tall else 1.8)) if tall: c.drawString(X(i + 0.4), Y(3.8), str(i)) # Y ruler: a tick every 2 mm up the left edge, labelled every 6 mm. for j in range(0, int(content_h) + 1, 2): tall = j % 6 == 0 c.setLineWidth(0.6 if tall else 0.3) c.line(X(0), Y(j), X(2.5 if tall else 1.4), Y(j)) if tall: c.drawString(X(2.8), Y(j + 0.3), str(j)) # 10 x 10 mm reference square, for an independent scale check. c.setLineWidth(0.6) c.rect(X(30), Y(4), 10 * mm, 10 * mm) c.setFont("Helvetica-Bold", 4) c.drawString(X(30.6), Y(8.4), "10x10") c.drawString(X(30.6), Y(6.0), "mm") # Explanation printed on the label itself. c.setFont("Helvetica-Bold", 5) c.drawString(X(44), Y(15.4), "MEASURE:") c.setFont("Helvetica", 4) c.drawString(X(44), Y(13.4), "tick 0 to 60") c.drawString(X(44), Y(11.6), "should be 60 mm") c.drawString(X(44), Y(9.8), "square = 10 mm") c.drawString(X(44), Y(8.0), "frame =") c.drawString(X(44), Y(6.4), f"{content_w:.0f} x {content_h:.0f} mm") c.drawString(X(44), Y(4.8), "tape = 24 mm") c.showPage() c.save() return path def main() -> int: cfg = load_config() # Use the printer's real printable area for this measurement. area = query_print_area(PRINTER) if area: print(f"Printable area: {area.printable_width_mm:.2f} x " f"{area.printable_height_mm:.2f} mm") cfg.media_width_mm = round(area.media_width_mm, 2) cfg.media_height_mm = round(area.media_height_mm, 2) cfg.page_width_mm = round(area.printable_width_mm - 0.1, 2) cfg.page_height_mm = round(area.printable_height_mm - 0.1, 2) os.makedirs("pdf_backup", exist_ok=True) out = os.path.join("pdf_backup", "measure_scale.pdf") build_measure_pdf(cfg, out) print(f"Content bounds : {cfg.page_width_mm:.2f} x {cfg.page_height_mm:.2f} mm") print(f"PDF page : {cfg.page_size_mm[0]:.2f} x {cfg.page_size_mm[1]:.2f} mm") print(f"Origin : {cfg.origin_mm}") print(f"Written : {out}") if "--no-print" in sys.argv: print("(--no-print: not sending to printer)") return 0 from print_label import print_to_printer settings = "noscale,paperkind=261" print(f"\nPrinting with -print-settings '{settings}' ...") ok = print_to_printer(PRINTER, out, settings=settings) print(f"Result: {'SENT' if ok else 'FAILED'}") return 0 if ok else 1 if __name__ == "__main__": raise SystemExit(main())