feat(wxread): align pagination, rendering, and docs

This commit is contained in:
shen
2026-05-24 15:36:01 +08:00
parent a318c0e3d0
commit 2a94921e88
103 changed files with 6124 additions and 4623 deletions
@@ -384,22 +384,22 @@ final class RDEPUBTextPerformanceSampler {
| A3 | Cache key schema version bump is sufficient for invalidation on code changes | Cache invalidation | Stale cache could persist if version is forgotten |
| A4 | CTFrame line origins can detect orphan/widow conditions | Pagination quality | Orphan/widow control would need different approach |
## Open Questions
## Open Questions (RESOLVED)
1. **Cache storage format: NSKeyedArchiver vs decomposed JSON?**
- What we know: `NSAttributedString` supports `NSCoding`. `RDEPUBTextBook` does NOT conform to `NSCoding` or `Codable`.
- What's unclear: Whether DTCoreText custom attributes survive `NSKeyedArchiver` round-trip.
- Recommendation: Test `NSKeyedArchiver` first. If custom attributes are lost, fall back to storing raw HTML + re-render parameters (slower cache load but more robust).
1. **Cache storage format: NSKeyedArchiver vs decomposed JSON?** ✅ RESOLVED
- Decision: Use `NSKeyedArchiver` first. Create private `NSCoding` wrapper classes for `RDEPUBTextBook`/`RDEPUBTextChapter`/`RDEPUBTextPage`/`RDEPUBTextPageMetadata`.
- Rationale: `NSAttributedString` and `NSRange` both support `NSCoding` natively. DTCoreText custom attributes are standard `NSAttributedString` attribute keys (string-typed) and survive archiver round-trip.
- Fallback: If runtime test reveals attribute loss, fall back to decomposed JSON (store HTML + render parameters, re-render on cache load).
2. **Should cache store full attributed content or just page ranges?**
- What we know: Full `RDEPUBTextBook` includes `NSAttributedString` per page (memory-heavy). Page ranges alone would require re-slicing on load.
- What's unclear: Memory impact of caching full attributed strings for large books.
- Recommendation: Cache full `RDEPUBTextBook` (matches D-03 decision). Add memory pressure monitoring.
2. **Should cache store full attributed content or just page ranges?** ✅ RESOLVED
- Decision: Cache full `RDEPUBTextBook` including `NSAttributedString` per page (matches D-01 decision in CONTEXT.md).
- Rationale: Re-slicing on load would negate the cache performance benefit. Memory pressure is manageable for typical EPUB books (< 500 pages).
- Mitigation: Cache eviction on memory warning (`didReceiveMemoryWarning` notification).
3. **Orphan/widow control: how aggressive?**
- What we know: WXRead has `avoidOrphans`/`avoidWidows` in `WRCoreTextLayoutConfig`. Current `RDEPUBTextLayouter` has no such config.
- What's unclear: Whether to add a configuration struct or hard-code reasonable defaults.
- Recommendation: Add `RDEPUBTextLayoutConfig` with `avoidOrphans: Bool = true` and `avoidWidows: Bool = true`. Default to enabled.
3. **Orphan/widow control: how aggressive?** ✅ RESOLVED
- Decision: Add `RDEPUBTextLayoutConfig` struct with configurable thresholds (`avoidOrphans: Bool = true`, `avoidWidows: Bool = true`), defaulting to enabled.
- Rationale: Follows the same pattern as `RDEPUBTextRenderStyle` (public struct + Equatable + explicit init). Hard-coding would prevent future tuning.
- WXRead reference: `WRCoreTextLayoutConfig` uses the same configurable approach.
## Environment Availability