From e41821c97a7e982d022962e8da6b38899e114da5 Mon Sep 17 00:00:00 2001 From: Karim Date: Wed, 22 Jul 2026 00:30:57 +0200 Subject: [PATCH] =?UTF-8?q?2D-Massstab:=20dpi-Berechnung=20f=C3=A4lschlich?= =?UTF-8?q?=20mit=20devicePixelRatio=20multipliziert?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit CSS-Pixel sind laut Spezifikation physisch konstant 1/96 Zoll, unabhängig von devicePixelRatio (der beschreibt nur die Geräte-Pixel-Dichte hinter einem CSS-Pixel, relevant für Rasterungs-Schärfe, nicht für die physische Grösse). Die Papier-Massstab-Umrechnung in PlanView.tsx nahm bisher 96 * devicePixelRatio an und verfälschte dadurch den angezeigten wie gemessenen Massstab auf jedem Retina-/HiDPI-Bildschirm um genau den Faktor devicePixelRatio (per Lineal am Bildschirm nachgemessen). Betrifft nur die Bildschirmanzeige, nicht den PDF/DXF-Export (eigene Berechnung). --- src/plan/PlanView.tsx | 18 ++++++++++++------ src/plan/generatePlan.ts | 4 ++-- 2 files changed, 14 insertions(+), 8 deletions(-) diff --git a/src/plan/PlanView.tsx b/src/plan/PlanView.tsx index 0869455..ae61d51 100644 --- a/src/plan/PlanView.tsx +++ b/src/plan/PlanView.tsx @@ -78,13 +78,19 @@ function visibleEdgeRuns(scr: Vec2[], noStroke: number[]): Vec2[][] { /** * Papier-Massstab (docs/design/plans-output.md §3): Der Plan IST Papier-Space. - * dpi = 96·devicePixelRatio (CSS definiert 1px = 1/96 inch). Strichstärken sind - * in mm Papier definiert und werden über diese dpi in konstante Bildschirm-Pixel - * umgerechnet (zusammen mit vector-effect:non-scaling-stroke bleiben sie beim - * Zoomen papierkonstant). Live wird zusätzlich gelesen, falls sich der Monitor - * (devicePixelRatio) ändert. + * dpi = 96 (CSS definiert 1 CSS-px = 1/96 inch, UNABHÄNGIG von devicePixelRatio — + * das gilt genauso auf Retina/HiDPI-Displays und bei OS-Skalierung, da der + * Browser CSS-px genau dafür physisch konstant hält, egal wie viele Geräte-px + * dahinterstecken). Strichstärken sind in mm Papier definiert und werden über + * diese dpi in konstante Bildschirm-Pixel umgerechnet (zusammen mit + * vector-effect:non-scaling-stroke bleiben sie beim Zoomen papierkonstant). + * BUGFIX: früher fälschlich `96 · devicePixelRatio` — das verwechselte die + * Geräte-px-Dichte (für Tessellierung/Rasterung relevant, siehe + * `pxPerMeterForView` weiter unten) mit der physischen CSS-px-Grösse und + * verdoppelte/halbierte den gemessenen Massstab auf jedem Retina-Bildschirm + * (per Lineal am Bildschirm nachgemessen falsch). */ -const dpi = (): number => 96 * (window.devicePixelRatio || 1); +const dpi = (): number => 96; /** mm Papier → Bildschirm-Pixel (für non-scaling-stroke / dasharray). */ const mmToPx = (mm: number): number => (mm / 25.4) * dpi(); diff --git a/src/plan/generatePlan.ts b/src/plan/generatePlan.ts index 1be80c2..378d593 100644 --- a/src/plan/generatePlan.ts +++ b/src/plan/generatePlan.ts @@ -108,8 +108,8 @@ const MONO_INK = "#111111"; // ── Linienstärken in PAPIER-Millimeter (vgl. docs/design/plans-output.md §3.2) ── // Alle Stricharten sind in mm Papier definiert; die PlanView rechnet sie über -// dpi = 96·devicePixelRatio in konstante Bildschirm-Pixel um (non-scaling-stroke), -// damit Linien beim Zoomen ihre Papiergröße behalten und der Massstab stimmt. +// dpi = 96 in konstante Bildschirm-Pixel um (non-scaling-stroke), damit Linien +// beim Zoomen ihre Papiergröße behalten und der Massstab stimmt. /** Default-Schichtfuge zwischen den Materialschichten in mm — Haarlinie (0.02), * gleiche Stärke wie die Schraffur-Tinte. Pro Fuge im Wandstil überschreibbar