Print-Vorschau: Strichbreiten auf die PEN_STEPS-Leiter quantisieren (Audit-Fund #2)

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).
This commit is contained in:
2026-07-03 18:54:39 +02:00
parent 7cf867a1a0
commit 7d2c9803d6
2 changed files with 9 additions and 4 deletions
+1 -1
View File
@@ -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];
+8 -3
View File
@@ -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);