Initial Blockminers printer

This commit is contained in:
ajp_anton
2026-05-30 16:54:49 +00:00
commit 47748f3897
261 changed files with 3992 additions and 0 deletions
+65
View File
@@ -0,0 +1,65 @@
import math
from pathlib import Path
from .assets import load_json, load_rgb
from .settings import BOARD_DECK, DECKS_DIR, BuildConfig
def board_target_mm_for_mode(
board_path: Path,
board_mode: str,
board_custom_mm: tuple[float, float] | None = None,
) -> tuple[float, float]:
if board_custom_mm is not None:
return board_custom_mm
ratio = board_aspect_ratio(board_path)
if board_mode == "a4-fit":
max_w, max_h = 210.0, 297.0
if ratio > max_w / max_h:
return max_w, max_w / ratio
return max_h * ratio, max_h
if board_mode == "a5-fit":
max_w, max_h = 148.0, 210.0
if ratio > max_w / max_h:
return max_w, max_w / ratio
return max_h * ratio, max_h
# Default: preserve aspect ratio while using approximately A5 area,
# capped to fit inside A4.
a5_area = 148.0 * 210.0
width = math.sqrt(a5_area * ratio)
height = math.sqrt(a5_area / ratio)
if width > 210.0 or height > 297.0:
scale = min(210.0 / width, 297.0 / height)
width *= scale
height *= scale
return width, height
def board_aspect_ratio(board_path: Path) -> float:
deck_json = board_path.parent / "deck.json"
if deck_json.exists():
meta = load_json(deck_json)
if meta.get("cardWidth") and meta.get("cardHeight"):
return float(meta["cardWidth"]) / float(meta["cardHeight"])
with load_rgb(board_path) as img:
return img.width / img.height
def board_target_mm(board_path: Path, config: BuildConfig) -> tuple[float, float]:
return board_target_mm_for_mode(board_path, config.board_mode, config.board_custom_mm)
def board_mode_fits_paper(board_mode: str, paper_mm: tuple[float, float], margin_mm: float) -> bool:
usable_w = paper_mm[0] - 2 * margin_mm
usable_h = paper_mm[1] - 2 * margin_mm
board_paths = sorted((DECKS_DIR / BOARD_DECK).glob("*-jumbo-front.png"))
if not board_paths:
return True
for board_path in board_paths:
board_w, board_h = board_target_mm_for_mode(board_path, board_mode)
fits_upright = board_w <= usable_w and board_h <= usable_h
fits_rotated = board_h <= usable_w and board_w <= usable_h
if not (fits_upright or fits_rotated):
return False
return True