From 7d2c9803d639393e928c29208dba78df3d9f4a5a Mon Sep 17 00:00:00 2001 From: Karim Date: Fri, 3 Jul 2026 18:54:39 +0200 Subject: [PATCH] Print-Vorschau: Strichbreiten auf die PEN_STEPS-Leiter quantisieren (Audit-Fund #2) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Die SVG-Print-Vorschau reichte rohe mm-Breiten in printStrokeVb, während der PDF-Export jede Breite via quantizePen() auf die Stiftleiter (0.13/0.18/0.25/…) rundete → Vorschau ≠ Druck. quantizePen ist jetzt aus sceneToPrintSvg.ts exportiert und wird in den zwei Print-Zweigen von PlanView (DrawingRunShape, renderPrimitive-weight) verwendet. Nur EINE Leiter, keine Kopie. Haarlinien-Pfad und Dash-Arrays unangetastet (das PDF quantisiert Dashes ebenfalls nicht). --- src/export/sceneToPrintSvg.ts | 2 +- src/plan/PlanView.tsx | 11 ++++++++--- 2 files changed, 9 insertions(+), 4 deletions(-) diff --git a/src/export/sceneToPrintSvg.ts b/src/export/sceneToPrintSvg.ts index 92bce64..7e5c381 100644 --- a/src/export/sceneToPrintSvg.ts +++ b/src/export/sceneToPrintSvg.ts @@ -47,7 +47,7 @@ const PEN_STEPS = [0.13, 0.18, 0.25, 0.35, 0.5, 0.7, 1.0] as const; const MIN_PEN_MM = 0.13; /** Quantelt eine mm-Strichstaerke auf die naechste Stift-Stufe (>= MIN_PEN_MM). */ -function quantizePen(mm: number): number { +export function quantizePen(mm: number): number { const w = Math.max(MIN_PEN_MM, mm); for (const step of PEN_STEPS) if (w <= step + 1e-6) return step; return PEN_STEPS[PEN_STEPS.length - 1]; diff --git a/src/plan/PlanView.tsx b/src/plan/PlanView.tsx index 9bfb89b..32feb34 100644 --- a/src/plan/PlanView.tsx +++ b/src/plan/PlanView.tsx @@ -19,6 +19,7 @@ import type { EdgeGrip, Vec2 } from "../model/types"; import type { DraftShape, SnapResult, ToolHandlers, ToolId, ToolMods } from "../tools/types"; import { useGlPlanRenderer } from "./useGlPlanRenderer"; import { useWasmPlanRenderer } from "./useWasmPlanRenderer"; +import { quantizePen } from "../export/sceneToPrintSvg"; const PX_PER_M = 90; // viewBox-Einheiten je Meter (Modell → SVG-Benutzerraum) const PAD = 60; // Rand in viewBox-Einheiten @@ -2533,7 +2534,7 @@ function DrawingRunShape({ const sw = hairline ? HAIRLINE_PX : print - ? printStrokeVb(run.weightMm, paperScale!) + ? printStrokeVb(quantizePen(run.weightMm), paperScale!) : mmToPx(run.weightMm); const vfx = print ? undefined : ("non-scaling-stroke" as const); const dashStr = @@ -2623,9 +2624,13 @@ function renderPrimitive( const print = !hairline && paperScale != null && paperScale > 0; // Strichstärke: // • Display → konstante Haarlinie (Bildschirm-px), papierunabhängig. - // • Print → echte Papier-mm in viewBox-Einheiten (skaliert mit dem Zoom). + // • Print → echte Papier-mm, VORHER auf die PEN_STEPS-Stiftstufe + // gequantelt (identisch zum PDF-Export, `quantizePen` aus + // `sceneToPrintSvg.ts`), dann in viewBox-Einheiten (skaliert mit dem + // Zoom) — so zeigt die Vorschau exakt die Strichbreite, die auch gedruckt + // wird. const weight = (mm: number): number => - hairline ? HAIRLINE_PX : print ? printStrokeVb(mm, paperScale!) : mmToPx(mm); + hairline ? HAIRLINE_PX : print ? printStrokeVb(quantizePen(mm), paperScale!) : mmToPx(mm); // vectorEffect: non-scaling NUR, wenn NICHT im Print-Modus (Print skaliert die // Linie bewusst mit der Geometrie). undefined ⇒ Attribut entfällt. const vfx = print ? undefined : ("non-scaling-stroke" as const);