Renderer-gaps quick wins: DOMVersion, ShowMasterItems, overset, GraphicLine, VerticalScale, Position, MasterPageTransform#1
Merged
Conversation
…set, GraphicLine, VerticalScale, Position, MasterPageTransform) Closes the small-scope items from thoughts/docs/paged/core/renderer-gaps.md after verifying each against the code; several documented "gaps" were already done and are noted in that doc separately. - DOMVersion: parse onto DesignMap, surface read-only in paged-inspect (human summary + JSON). No version branching yet. - ShowMasterItems: parse on <Page>; skip the whole master-stamp loop body for a page when false (suppresses master frames, lines, and page-number text at once). - Overset: surface the existing dropped_overflow_lines counter as a diagnostic (inspect line + JSON) instead of dropping lines silently. - GraphicLine: stroke the real multi-segment/open anchor path (reusing polygon_path_from_anchors_with_open + frame_outer_transform) instead of the bounds diagonal; contours default to open. Falls back to the diagonal only when anchorless. - VerticalScale: mirror HorizontalScale end to end — StyledRun.vertical_scale_pct -> PositionedGlyph.y_scale -> the glyph affine's y term (scales height about the baseline; advance/leading unchanged). Layout-cache hash updated. - Position (super/subscript): new position_metrics() applies InDesign's factory defaults (58.3% size, +/-33.3% baseline) via the existing point size + baseline-shift plumbing. Exact values await Preferences parsing. - MasterPageTransform: stamp master items under the full affine translate(target) o MPT o translate(-master origin) via compose_outer_matrix, not translation only. Identity MPT reduces to the prior (dx,dy) shift. - Strokes: consume custom <DottedStrokeStyle> patterns; make the Striped/Wavy -> solid fallback explicit (true multi-line/sine rendering needs a new rasterizer capability — deferred). New unit tests: DOMVersion parse, ShowMasterItems parse, position_metrics, compose_outer_matrix (identity + scale), vertical-scale affine, stroke_for custom styles. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
drietsch
pushed a commit
that referenced
this pull request
Jun 6, 2026
…index shifts The editor's E2E op suite caught two symptoms of one cache family (editor/docs/engine-findings.md #1 and #3, 2026-06-05): - undo/redo of a text op kept the stale post-edit text layout: the forward paths (apply_mutation's text arm, apply_operation) clear master_text_emit_cache + body_story_emit_cache before rebuild, but undo()/redo() did not — and the body-story signature matches on content-only edits, so the rebuild spliced the pre-undo emission. - insertPage in the MIDDLE of the page set panicked the renderer ('index out of bounds: the len is N but the index is N' at the body-story splice) once a pipeline existed: the signature ignored the chain's page INDICES, so cached per-page deltas survived page-set changes with stale absolute indices; the un-cleared undo path then spliced past pages.len() and mutate() never resolved. Three layers, defense in depth: - undo()/redo() clear both emit caches before rebuild_after_mutation, for both log arms (frame inverses replay structural ops under the same caches), mirroring the forward paths. - body_story_signature hashes the chain's page indices (plus a present/absent discriminant per wrap-rect lookup) — an index shift is a key change. Indices are stable across gestures, so the cache's hot path keeps its hit ratio. - the splice loop treats any out-of-range per_page index as a cache miss (fresh emission) instead of panicking inside the worker. tests/emit_cache_undo.rs asserts on built display lists (the scene- hash determinism tests cannot see these bugs — the scene round-trips while the rendered output goes stale): text undo/redo repaint, mid-set insertPage undo/redo round-trip (reproduces the exact panic pre-fix), story-stays-on-its-page after the shift, and the style-edit repaint cascade (engine side of finding #2 — the cascade works; the E2E symptom was fixture direct formatting). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Implements the small-scope ("quick win") items from the private
renderer-gaps.mdroadmap, after verifying each against the code at thepinned commit. Several documented "gaps" turned out to be already done
(NestedStyle splitting, Knuth–Plass, nested-in-group frames, Dotted strokes);
those are reconciled in the roadmap doc separately, not here.
Changes
DesignMap; surfaced read-only inpaged-inspect(human summary + JSON). No version branching yet.
<Page>; whenfalse, the whole master-stamploop body is skipped (suppresses master frames, lines, and page-number text
together).
dropped_overflow_linescounter is now surfaced asa diagnostic (inspect line + JSON) instead of dropping clipped lines silently.
polygon_path_from_anchors_with_open+frame_outer_transform) instead of thebounds diagonal; contours default to open. Falls back to the diagonal only when
anchorless.
HorizontalScaleend to end:StyledRun.vertical_scale_pct→PositionedGlyph.y_scale→ the glyph affine'sy term (scales height about the baseline; advance/leading unchanged). Layout
cache hash updated.
position_metrics()applies InDesign'sfactory defaults (58.3% size, ±33.3% baseline) via the existing point-size +
baseline-shift plumbing. Exact values await
Preferencesparsing (separate gap).translate(target) ∘ MPT ∘ translate(-master origin)viacompose_outer_matrix,not translation-only. Identity MPT reduces to the prior
(dx, dy)shift.<DottedStrokeStyle>patterns are now consumed; theStriped/Wavy → solid fallback is made explicit (true multi-line/sine rendering
needs a new rasterizer stroke capability — deferred, tracked in the roadmap).
Tests
New unit tests: DOMVersion parse (present/absent), ShowMasterItems parse,
position_metrics,compose_outer_matrix(identity + scale), vertical-scaleglyph affine,
stroke_forcustom styles. Fullcargo test --workspaceis green(the one pre-existing
paged-scriptstoryRange baseline failure is unrelated).No new clippy lints.
🤖 Generated with Claude Code