77 lines
3.7 KiB
Markdown
77 lines
3.7 KiB
Markdown
---
|
|
phase: 6
|
|
plan: 06-01
|
|
type: execute
|
|
wave: 1
|
|
depends_on: []
|
|
files_modified:
|
|
- Sources/RDReaderView/EPUBTextRendering/RDEPUBTextLayoutFrame.swift
|
|
- Sources/RDReaderView/EPUBTextRendering/RDEPUBTextLayouter.swift
|
|
- Sources/RDReaderView/EPUBTextRendering/RDEPUBTextPaginationSupport.swift
|
|
- Sources/RDReaderView/EPUBTextRendering/RDEPUBTextBookBuilder.swift
|
|
- Sources/RDReaderView/EPUBCore/RDEPUBReadingModels.swift
|
|
autonomous: true
|
|
requirements:
|
|
- LAYOUT-01
|
|
- LAYOUT-03
|
|
---
|
|
|
|
# Phase 6-01: Page Geometry Model
|
|
|
|
<objective>
|
|
Add a reusable page geometry layer on top of native text pagination so callers can query page-relative rectangles and map rectangles back to text ranges without breaking offset continuity.
|
|
</objective>
|
|
|
|
<must_haves>
|
|
- `RDEPUBTextLayoutFrame` can expose page geometry derived from CoreText, not guessed from offsets.
|
|
- `pageStartOffset`, `pageEndOffset`, `fragmentOffsets`, and `RDEPUBTextOffsetRangeInfo` semantics remain stable.
|
|
- The geometry API is reusable by selection, search, highlight, and tap-locate work in later plans.
|
|
</must_haves>
|
|
|
|
<tasks>
|
|
<task id="06-01-01">
|
|
<type>execute</type>
|
|
<action>Extend `RDEPUBTextLayoutFrame` and the page model with explicit geometry value types, including a page-level geometry container and line or fragment geometry records. Populate them from `RDEPUBTextLayouter` using CoreText line data so the page can answer range-to-rect and rect-to-range queries without changing pagination break rules.</action>
|
|
<read_first>
|
|
- Sources/RDReaderView/EPUBTextRendering/RDEPUBTextLayoutFrame.swift
|
|
- Sources/RDReaderView/EPUBTextRendering/RDEPUBTextLayouter.swift
|
|
- Sources/RDReaderView/EPUBTextRendering/RDEPUBTextPaginationSupport.swift
|
|
- Sources/RDReaderView/EPUBCore/RDEPUBReadingModels.swift
|
|
</read_first>
|
|
<acceptance_criteria>
|
|
- `RDEPUBTextLayoutFrame` or its companion geometry type exposes a query path for at least string-range rectangles and reverse lookup from rects to `NSRange`.
|
|
- Existing metadata fields (`contentRange`, `breakReason`, `blockRange`, `attachmentRanges`, `attachmentKinds`, `trailingFragmentID`, `diagnostics`) remain present and unchanged in meaning.
|
|
- `RDEPUBTextLayouter` still emits the same page boundaries for the sample books after the geometry data is added.
|
|
</acceptance_criteria>
|
|
</task>
|
|
|
|
<task id="06-01-02">
|
|
<type>execute</type>
|
|
<action>Thread the new geometry data through `RDEPUBTextBookBuilder` and `RDEPUBTextBook` so each page retains its geometry alongside `pageStartOffset`, `pageEndOffset`, and `fragmentOffsets`. Keep `pageNumber(for:)` and `location(forPageNumber:)` compatible with the existing absolute-offset contract.</action>
|
|
<read_first>
|
|
- Sources/RDReaderView/EPUBTextRendering/RDEPUBTextBookBuilder.swift
|
|
- Sources/RDReaderView/EPUBCore/RDEPUBReadingModels.swift
|
|
- Sources/RDReaderView/EPUBTextRendering/RDEPUBTextLayouter.swift
|
|
- Sources/RDReaderView/LegacyRDReaderController/RDEPUBTextPaging.swift
|
|
</read_first>
|
|
<acceptance_criteria>
|
|
- `RDEPUBTextBook` pages still map absolute offsets to pages through `pageStartOffset` / `pageEndOffset`.
|
|
- `RDEPUBTextBook.location(forPageNumber:)` still returns a stable `RDEPUBLocation` for native text pages.
|
|
- The sample text book builds successfully with the new geometry fields attached to each page.
|
|
</acceptance_criteria>
|
|
</task>
|
|
</tasks>
|
|
|
|
<verification>
|
|
- Build the `ReadViewDemo` workspace with the `ReadViewDemo` scheme.
|
|
- Confirm the new page geometry API compiles and the sample book still paginates.
|
|
- Confirm no existing offset-based selection or restore code needs to change to keep building.
|
|
</verification>
|
|
|
|
<success_criteria>
|
|
- Native text pages expose reusable geometry data.
|
|
- The offset-based page contract remains intact.
|
|
- Later selection overlay work can consume the geometry layer without re-deriving page boundaries.
|
|
</success_criteria>
|
|
|