From dd7087cd6d4b52ac3355edf2667a317e43198421 Mon Sep 17 00:00:00 2001 From: Benjamin Admin Date: Wed, 11 Mar 2026 10:14:58 +0100 Subject: [PATCH] fix: Pixel-Analyse nicht mehr ueberspringen wenn Cluster < Gruppen MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Vorher: wenn Text mehr Wort-Gruppen hatte als Pixel-Cluster gefunden wurden (z.B. bei Box-Rahmen die Cluster zusammenmergen), wurde die Zelle komplett uebersprungen → Fallback bei x=0%. Jetzt: Fallback auf Single-Span Positionierung (first→last Cluster) statt Skip. Damit wird der Text immer korrekt horizontal platziert. Co-Authored-By: Claude Opus 4.6 --- .../ocr-overlay/usePixelWordPositions.ts | 31 ++++++++++--------- 1 file changed, 16 insertions(+), 15 deletions(-) diff --git a/admin-lehrer/components/ocr-overlay/usePixelWordPositions.ts b/admin-lehrer/components/ocr-overlay/usePixelWordPositions.ts index e3ff23b..1141181 100644 --- a/admin-lehrer/components/ocr-overlay/usePixelWordPositions.ts +++ b/admin-lehrer/components/ocr-overlay/usePixelWordPositions.ts @@ -126,20 +126,8 @@ export function usePixelWordPositions( const wordPos: WordPosition[] = [] - if (groups.length <= 1) { - const firstCl = clusters[0] - const lastCl = clusters[clusters.length - 1] - const clusterW = lastCl.end - firstCl.start + 1 - const measured = ctx.measureText(cell.text.trim()) - const autoFontPx = refFontSize * (clusterW / measured.width) - const fontRatio = Math.min(autoFontPx / ch, 1.0) - wordPos.push({ - xPct: cell.bbox_pct.x + (firstCl.start / cw) * cell.bbox_pct.w, - wPct: ((lastCl.end - firstCl.start + 1) / cw) * cell.bbox_pct.w, - text: cell.text.trim(), - fontRatio, - }) - } else if (clusters.length >= groups.length) { + if (groups.length > 1 && clusters.length >= groups.length) { + // Multiple text groups with enough clusters: map each group to a cluster for (let i = 0; i < groups.length; i++) { const cl = clusters[i] const clusterW = cl.end - cl.start + 1 @@ -154,7 +142,20 @@ export function usePixelWordPositions( }) } } else { - continue + // Single group OR clusters don't match groups: + // position entire text as one span from first to last cluster + const firstCl = clusters[0] + const lastCl = clusters[clusters.length - 1] + const clusterW = lastCl.end - firstCl.start + 1 + const measured = ctx.measureText(cell.text.trim()) + const autoFontPx = refFontSize * (clusterW / measured.width) + const fontRatio = Math.min(autoFontPx / ch, 1.0) + wordPos.push({ + xPct: cell.bbox_pct.x + (firstCl.start / cw) * cell.bbox_pct.w, + wPct: ((lastCl.end - firstCl.start + 1) / cw) * cell.bbox_pct.w, + text: cell.text.trim(), + fontRatio, + }) } positions.set(cell.cell_id, wordPos)