From 0e1c69e316c9d4da49f75a941e74a8b31dd79ae9 Mon Sep 17 00:00:00 2001 From: Karim Date: Fri, 3 Jul 2026 18:47:40 +0200 Subject: [PATCH] PlanView: Haarlinien-Modus auch im GPU-Pfad zoom-konstant (Audit-Fund #1) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit paperScaleForGl nutzt im hairline-Modus den live aus dem Ausschnitt abgeleiteten scaleFromView(v) statt des stabilen paperScale. Der GL-Term mm_to_device_px = N/1000·PX_PER_M·meet wuchs bisher über meet mit dem Zoom, obwohl Display/Haarlinie konstante Strichbreiten verspricht. scaleFromView ist der exakte Kehrwert von meet → N·meet kürzt sich, die Breite in Geräte-px bleibt zoom-unabhängig (dieselbe Wirkung wie non-scaling-stroke im SVG-Pfad). Print-Modus unverändert. Restlücke (separat, bräuchte Shader-Änderung): noch nicht wörtlich uniform 1px wie der SVG-Haarlinienpfad — Breiten bleiben gewichts-proportional, aber zoom-konstant. --- src/plan/PlanView.tsx | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/src/plan/PlanView.tsx b/src/plan/PlanView.tsx index e168b93..9bfb89b 100644 --- a/src/plan/PlanView.tsx +++ b/src/plan/PlanView.tsx @@ -472,8 +472,18 @@ export const PlanView = forwardRef( // Papier-Massstab-Nenner (1:N) für die GL-Strichbreiten — ECHTE mm im Massstab // (0.35 mm bei 1:100). Bevorzugt der stabile `paperScale` (wie beim SVG-Print); // solange der noch nicht gemessen ist, der live aus dem Ausschnitt abgeleitete N. + // Im Haarlinien-Modus (Display, wie `textScaleForGl` daneben) NICHT den + // stabilen `paperScale`: der bliebe beim Rad-Zoom konstant, während die GPU- + // Strichbreite (`mm_to_device_px` = N/1000·PX_PER_M·meet) über `meet` trotzdem + // mit dem Zoom wächst — genau der Haarlinien-Bug (Finding 1). Der LIVE aus dem + // Ausschnitt abgeleitete `scaleFromView` ist hingegen exakt der reziproke Wert + // von `meet` (siehe dessen Formel), sodass N·meet — und damit die GL-Strich- + // breite in Geräte-px — unabhängig vom Zoom konstant bleibt: dieselbe Wirkung + // wie `non-scaling-stroke` im SVG-Pfad, nur über den Massstab-Nenner erzielt. const paperScaleForGl = (v: ViewBox): number => - paperScaleRef.current ?? scaleFromView(v, svgRef.current) ?? 100; + hairline + ? scaleFromView(v, svgRef.current) ?? 100 + : paperScaleRef.current ?? scaleFromView(v, svgRef.current) ?? 100; // Referenz-Nenner (1:N) NUR für die Text-Schriftgröße der Engine — spiegelt // EXAKT die SVG-Formel (case "text" unten, gleiche `print`-Bedingung): im