Vorher: split(/\s+/) zerlegte alles in Einzelwoerter, verlor die
Spaltenstruktur (3+ Spaces zwischen Gruppen). Woerter stauten sich links.
Jetzt: split(/\s{3,}/) erhält Gruppen wie im Cluster-Modus. Jede Gruppe
wird als Einheit von links nach rechts geschoben bis Tinte gefunden.
Breite = max(gemessene Textbreite, tatsaechliche Tintenbreite).
fontRatio=1.0, kein Wort geht verloren.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
fontRatio war 0.65 (35% kleiner als Fallback-Rendering). Jetzt 1.0
wie beim Fallback. Token-Breiten berechnet aus measureText skaliert
auf die tatsaechlich gerenderte Schriftgroesse (medianCh * 0.7).
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Schriftgroesse wird jetzt GLOBAL aus der medianen Zellhoehe berechnet
(65% der Zellhoehe als Ziel-Font). Alle Tokens bekommen dieselbe
konsistente Groesse. Die Slide-Logik bestimmt nur noch die x-Position.
Vorher: Scale pro Zelle aus Ink-Span/Textbreite -> inkonsistente Groessen.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
totalInk zaehlte nur dunkle Pixel-Spalten (Striche), ignorierte
Luecken zwischen Buchstaben. Scale war dadurch viel zu klein,
Schrift unlesbar. Jetzt wird der Ink-Span (erstes bis letztes
dunkles Pixel) als Referenz fuer die Textbreite verwendet.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Neuer Hook useSlideWordPositions: Schiebt alle erkannten Woerter von links
nach rechts ueber die Pixel-Projektion bis jedes Wort auf seiner Tinte
einrastet. Kein Wort geht verloren, keine Cluster-Matching-Regeln noetig.
Toggle-Button (Slide/Cluster) in der Overlay-Toolbar zum Umschalten.
Bestehender Cluster-Algorithmus bleibt als Alternative erhalten.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>