Add interactive layout review editor with mobile UI and font controls

This commit is contained in:
Sean McElwain 2026-05-10 22:18:13 -05:00
parent 658240c031
commit b84b259f08
2 changed files with 1222 additions and 298 deletions

View File

@ -1820,6 +1820,8 @@ def _layout_review_group_words_into_lines(words, y_tol: float = 12.0):
"id": word.get("id"),
"text": (word.get("text") or "").strip(),
"bbox": [x1, y1, x2, y2],
"font_size_guess": float(word.get("font_size_guess") or max(6.0, (y2 - y1) * 0.75)),
"font_family_guess": (word.get("font_family_guess") or "Helvetica"),
})
normalized.sort(key=lambda w: (w["bbox"][1], w["bbox"][0]))
@ -1845,12 +1847,14 @@ def _layout_review_group_words_into_lines(words, y_tol: float = 12.0):
top = min(item["bbox"][1] for item in group)
right = max(item["bbox"][2] for item in group)
bottom = max(item["bbox"][3] for item in group)
line_font_sizes = [float(item.get("font_size_guess") or max(6.0, (item["bbox"][3] - item["bbox"][1]) * 0.75)) for item in group]
line_font_family = next((item.get("font_family_guess") for item in group if item.get("font_family_guess")), "Helvetica")
lines.append({
"text": line_text,
"bbox": [left, top, right, bottom],
"confidence": None,
"font_family_guess": "Helvetica",
"font_size_guess": max(6.0, (bottom - top) * 0.75),
"font_family_guess": line_font_family,
"font_size_guess": round(sum(line_font_sizes) / len(line_font_sizes), 2),
"text_color_guess": "#000000",
"words": group,
})
@ -1898,6 +1902,7 @@ async def save_layout_review(document_id: str, request: Request, db: Session = D
),
None,
)
source_version = reviewed_ocr or raw_ocr or current_text_version
if source_version is None:
return RedirectResponse(
@ -1933,13 +1938,27 @@ async def save_layout_review(document_id: str, request: Request, db: Session = D
except Exception:
continue
x_left = min(x1, x2)
x_right = max(x1, x2)
y_top = min(y1, y2)
y_bottom = max(y1, y2)
if abs(x_right - x_left) < 1.0 or abs(y_bottom - y_top) < 1.0:
continue
font_size_guess = float(word.get("font_size_guess") or max(6.0, (y_bottom - y_top) * 0.75))
font_family_guess = (word.get("font_family_guess") or "Helvetica")
words.append({
"id": int(word.get("id") or word_idx),
"text": (word.get("text") or "").strip(),
"bbox": [x1, y1, x2, y2],
"bbox": [x_left, y_top, x_right, y_bottom],
"confidence": None,
"font_size_guess": font_size_guess,
"font_family_guess": font_family_guess,
})
words.sort(key=lambda w: (w["bbox"][1], w["bbox"][0]))
lines = _layout_review_group_words_into_lines(words)
rebuilt_text_lines.extend((line.get("text") or "") for line in lines)
@ -2001,6 +2020,8 @@ async def save_layout_review(document_id: str, request: Request, db: Session = D
url=f"/documents/{document_id}?tab=layout-review&success=saved_layout_review",
status_code=303,
)
# --- layout review save helpers end ---
@router.get("/{document_id}", response_class=HTMLResponse)
@ -2078,6 +2099,8 @@ def document_detail(document_id: str, request: Request, queue: str | None = None
"id": idx,
"text": (word.get("text") or "").strip(),
"bbox": [float(bbox[0]), float(bbox[1]), float(bbox[2]), float(bbox[3])],
"font_size_guess": float(word.get("font_size_guess") or max(6.0, (float(bbox[3]) - float(bbox[1])) * 0.75)),
"font_family_guess": (word.get("font_family_guess") or "Helvetica"),
}
words.append(word_row)

File diff suppressed because it is too large Load Diff