2.9 KiB
ADR-0001 — Render what you will save
- Status: Accepted
- Date: 2025-07-25
- Plan reference: §2.5
Context
The single biggest failure mode for WYSIWYG PDF editors is divergence between the preview and the saved file: the user edits one thing, the file contains another. Overlay-style editors avoid this by not really editing — they cover old text with a white rectangle and draw new text on top, producing files that look right and are broken for search, copy-paste, accessibility, and redaction. We chose full content editing (§1.1), so we own an interpreter and an emitter, and divergence is a structural risk.
The decision must be made before any rendering or editing code lands because it shapes the whole pipeline: every edit's effect on the saved bytes must be computable, and the rasterizer must render the saved bytes, not a model projection.
Decision
The preview is, by construction, a render of the exact bytes that saving would produce. Concretely:
- Every edit mutates the semantic model (L5).
- The dirty page's content stream is re-emitted immediately into an in-memory buffer (§4.4).
- The rasterizer renders that buffer, not the model.
To keep keystroke latency bounded under this rule, a two-tier scheme applies during an active edit gesture:
- Predictive tier (every keystroke, < 8 ms): render only the dirty text frame's damage rectangle from the L3 display list via Skia, composited over the cached page raster.
- Authoritative tier (on 120 ms idle, on gesture end, and always before save): re-emit and re-render through PDFium, then diff against the predictive tier. A mismatch above threshold repaints and logs a fidelity event.
Nothing is ever saved that has not been rendered from its own bytes.
Consequences
Positive. The preview and the saved file cannot diverge by construction. The predictive-vs-authoritative diff gives a continuous, free, in-production consistency check between our interpreter and PDFium's — exactly the divergence we are most exposed to (§11).
Negative. Re-emission must be fast (< 5 ms for a typical page) which drives the surgical (not full-rebuild) design of ADR-0002. The predictive tier requires a first-class Skia display-list renderer, which is real ongoing cost — it is a tracked metric with a budget, not a debugging toy.
Neutral. Fidelity events (§2.5, §4.3, §4.4) are recorded locally and visible in the fidelity panel; they are only transmitted if the user explicitly submits a diagnostic bundle.
Alternatives considered
- Overlay editing — rejected; produces files that are broken for search, copy-paste, accessibility, and redaction (§1.1).
- Model-driven rendering (render the L5 model directly, save separately) — rejected; reintroduces divergence as the model and the emitter can drift.
- Re-render through PDFium on every keystroke — rejected for latency on dense pages; kept as the authoritative tier only.