Add PyInstaller packaging for Windows and Linux

- label_app.spec: one-file build bundling fonts, emoji data, ttkbootstrap
  themes and (on Windows) fribidi.dll so Pillow can shape emoji sequences
- build-windows.ps1 helper; assets/icon.ico app icon
- Fonts resolved from assets/fonts first, then system dirs, so the app
  runs from a bundle or a checkout on any OS
- Bump Pillow pin to 12.3
This commit is contained in:
Gracious
2026-09-21 08:38:00 +01:00
parent 41b4d4ce64
commit 42221341d5
17 changed files with 902 additions and 6 deletions
+28 -4
View File
@@ -6,6 +6,7 @@ select, drag to move, arrow keys to nudge, rotate/resize from the side panel.
import json
import re
import sys
import threading
import tkinter as tk
from dataclasses import asdict, dataclass, field
@@ -30,11 +31,34 @@ PX_PER_MM = 8
SETTINGS_PATH = Path.home() / ".config" / "niimprint-label" / "settings.json"
DEFAULT_ADDR = "94:11:02:66:16:4D" # your D101 — change in the app, it is remembered
def _asset_dir() -> Path:
"""Bundled assets: next to this file, or inside a PyInstaller bundle."""
base = Path(getattr(sys, "_MEIPASS", Path(__file__).resolve().parent))
return base / "assets" / "fonts"
def _find_font(name: str, *system_dirs: str) -> str:
for d in (_asset_dir(), *map(Path, system_dirs)):
if (d / name).is_file():
return str(d / name)
raise FileNotFoundError(
f"Font {name} not found (looked in assets/fonts and system dirs)"
)
_FONT_DIRS = (
"/usr/share/fonts/TTF",
"/usr/share/fonts/truetype/dejavu",
"/usr/share/fonts/noto",
"C:/Windows/Fonts",
"/Library/Fonts",
)
TEXT_FONTS = {
"bold": "/usr/share/fonts/TTF/DejaVuSans-Bold.ttf",
"regular": "/usr/share/fonts/TTF/DejaVuSans.ttf",
"bold": _find_font("DejaVuSans-Bold.ttf", *_FONT_DIRS),
"regular": _find_font("DejaVuSans.ttf", *_FONT_DIRS),
}
EMOJI_FONT = "/usr/share/fonts/noto/NotoColorEmoji.ttf"
EMOJI_FONT = _find_font("NotoColorEmoji.ttf", *_FONT_DIRS)
EMOJI_FONT_SIZE = 109 # Noto Color Emoji is a bitmap font; only this size loads
EMOJI_GAMMA = 3.0 # >1 darkens emoji so they survive 1-bit dithering
EMOJI_SCALE = 1.15 # emoji height relative to text size
@@ -612,7 +636,7 @@ class LabelApp(ttk.Window):
bar.grid(row=5, column=0, sticky="we", pady=(12, 0))
self.print_btn = ttk.Button(
bar,
text="🖨 Print",
text="Print",
command=self.print_label,
bootstyle="success",
width=12,