From c5733a171be6f0b216b97afba4515e0f4ea94ebc Mon Sep 17 00:00:00 2001 From: Benjamin Admin Date: Mon, 13 Apr 2026 23:24:27 +0200 Subject: [PATCH] StepAnsicht: fix font size and row spacing to match original - Font: use font_size_suggestion_px * scale directly (removed 0.85 factor) - Row height: calculate from row-to-row spacing (y_min of next row minus y_min of current row) instead of text height (y_max - y_min). This produces correct line spacing matching the original layout. - Multi-line cells: height multiplied by line count Content zone should now span from ~250 to ~2050 matching the original. Co-Authored-By: Claude Opus 4.6 (1M context) --- .../components/ocr-kombi/StepAnsicht.tsx | 29 ++++++++++++++----- 1 file changed, 21 insertions(+), 8 deletions(-) diff --git a/admin-lehrer/components/ocr-kombi/StepAnsicht.tsx b/admin-lehrer/components/ocr-kombi/StepAnsicht.tsx index 1f727de..f9a4036 100644 --- a/admin-lehrer/components/ocr-kombi/StepAnsicht.tsx +++ b/admin-lehrer/components/ocr-kombi/StepAnsicht.tsx @@ -71,7 +71,8 @@ export function StepAnsicht({ sessionId, onNext }: StepAnsichtProps) { const panelHeight = imgH * scale const baseFontPx = (grid as any).layout_metrics?.font_size_suggestion_px || 14 - const scaledFont = Math.max(7, baseFontPx * scale * 0.85) + const avgRowH = (grid as any).layout_metrics?.avg_row_height_px || 31 + const scaledFont = Math.max(7, baseFontPx * scale) // Collect all word boxes for OCR overlay const allWordBoxes = grid.zones.flatMap((z) => @@ -161,7 +162,7 @@ export function StepAnsicht({ sessionId, onNext }: StepAnsichtProps) { {/* Rendered zones */} {grid.zones.map((zone) => ( - + ))} {/* Coordinate grid */} @@ -208,8 +209,8 @@ function CoordinateGrid({ imgW, imgH, scale, spacing }: { // Zone renderer (reconstruction side) // --------------------------------------------------------------------------- -function ZoneRenderer({ zone, scale, fontSize }: { - zone: GridZone; scale: number; fontSize: number +function ZoneRenderer({ zone, scale, fontSize, avgRowH }: { + zone: GridZone; scale: number; fontSize: number; avgRowH: number }) { const isBox = zone.zone_type === 'box' const boxColor = (zone as any).box_bg_hex || '#6b7280' @@ -253,10 +254,22 @@ function ZoneRenderer({ zone, scale, fontSize }: { }} >
`${w.toFixed(1)}px`).join(' ') }}> - {zone.rows.map((row) => { + {zone.rows.map((row, rowIdx) => { const isSpanning = zone.cells.some((c) => c.row_index === row.index && c.col_type === 'spanning_header') - const measuredH = (row.y_max_px ?? 0) - (row.y_min_px ?? 0) - const rowH = Math.max(fontSize * 1.3, measuredH * scale) + + // Row height = distance to next row's start (not text height) + // This produces correct line spacing matching the original + const nextRow = rowIdx + 1 < zone.rows.length ? zone.rows[rowIdx + 1] : null + const rowStartY = row.y_min_px ?? row.y_min ?? 0 + const nextStartY = nextRow ? (nextRow.y_min_px ?? nextRow.y_min ?? 0) : rowStartY + avgRowH + const rowSpacing = nextStartY - rowStartY + const rowH = Math.max(fontSize * 1.3, rowSpacing * scale) + + // Multi-line cells need more height + const maxLines = Math.max(1, ...zone.cells + .filter((c) => c.row_index === row.index) + .map((c) => (c.text ?? '').split('\n').length)) + const effectiveRowH = rowH * Math.max(1, maxLines) return (
@@ -273,7 +286,7 @@ function ZoneRenderer({ zone, scale, fontSize }: { className={`px-0.5 overflow-hidden ${row.is_header ? 'font-bold' : ''}`} style={{ gridColumn: `${cell.col_index + 1} / ${cell.col_index + 1 + colspan}`, - minHeight: `${rowH}px`, + minHeight: `${effectiveRowH}px`, color: color || undefined, whiteSpace: 'pre-wrap', }}