# Tasks: Simple Text Positioning ## Phase 1: Core Implementation - [x] Create `TextRegionRenderer` class in `app/services/text_region_renderer.py` - [x] Implement `calculate_rotation()` from bbox quadrilateral - [x] Implement `estimate_font_size()` from bbox height - [x] Implement `render_text_region()` main method - [x] Handle coordinate system transformation (OCR → PDF) ## Phase 2: Integration - [x] Add `simple_text_positioning_enabled` config option - [x] Modify `PDFGeneratorService._generate_ocr_track_pdf()` to use `TextRegionRenderer` - [x] Ensure raw OCR regions are loaded correctly via `load_raw_ocr_regions()` ## Phase 3: Image/Chart/Formula Support - [x] Add image element type detection (`figure`, `image`, `chart`, `seal`, `formula`) - [x] Render image elements from UnifiedDocument to PDF - [x] Handle image path resolution (result_dir, imgs/ subdirectory) - [x] Coordinate transformation for image placement ## Phase 4: Text Straightening & Overlap Avoidance - [x] Add rotation straightening threshold (default 10°) - Small rotation angles (< 10°) are treated as 0° for clean output - Only significant rotations (e.g., 90°) are preserved - [x] Add IoA (Intersection over Area) overlap detection - IoA threshold default 0.3 (30% overlap triggers skip) - Text regions overlapping with images/charts are skipped - [x] Collect exclusion zones from image elements - [x] Pass exclusion zones to text renderer ## Phase 5: Chart Axis Label Deduplication - [x] Add `is_axis_label()` method to detect axis labels - Y-axis: Vertical text immediately left of chart - X-axis: Horizontal text immediately below chart - [x] Add `is_near_zone()` method for proximity checking - [x] Position-aware deduplication in `render_text_region()` - Collect texts inside zones + axis labels - Skip matching text only if near zone or is axis label - Preserve matching text far from zones (e.g., table values) - [x] Test results: - "Temperature, C" and "Syringe Thaw Time, Minutes" correctly skipped - Table values like "10" at top of page correctly rendered - Page 2: 128/148 text regions rendered (12 overlap + 8 dedupe) ## Phase 6: Testing - [x] Test with scan.pdf task (064e2d67-338c-4e54-b005-204c3b76fe63) - Page 2: Chart image rendered, axis labels deduplicated - PDF is searchable and selectable - Text is properly straightened (no skew artifacts) - [ ] Compare output quality vs original scan visually - [ ] Test with documents containing seals/formulas