Skip to content

feat(render-pptx): chrome, navigation, multi-section, and deterministic output#414

Merged
DemchaAV merged 2 commits into
developfrom
feature/pptx-chrome-nav
Jul 18, 2026
Merged

feat(render-pptx): chrome, navigation, multi-section, and deterministic output#414
DemchaAV merged 2 commits into
developfrom
feature/pptx-chrome-nav

Conversation

@DemchaAV

Copy link
Copy Markdown
Owner

Why

The fixed PPTX backend rendered every fragment payload but stopped at the document level: chrome (metadata, watermark, headers/footers) configured on a session was silently dropped, recorded links and bookmarks were never emitted, multi-section documents threw, and every render produced different bytes because POI stamps wall-clock times into the OPC properties and every zip entry.

What

  • Chrome. PptxChromeRenderer renders the canonical chrome with the PDF backend's math: metadata lands in the OPC core properties plus the extended application property (OPC has no producer field); text watermarks measure with Helvetica-Bold, orbit the frame centre around the PDF's baseline-start rotation pivot, and carry opacity as colour alpha; image watermarks use native alphaModFix; tiling matches the PDF grid (invisible off-slide tiles are skipped); headers/footers resolve {page}/{pages}/{date} with the full numbering-window rules and draw separators as connectors. Behind-content watermarks apply before fragment rendering, so document order reproduces the PDF's layering without z-order surgery. Protection, viewer preferences, and debug overlays have no PPTX counterpart and are skipped with a one-time warning.
  • Navigation. All link rectangles — fragment-, line-, and span-level, external and internal — are recorded during the fragment pass and emitted by PptxNavigationWriter afterwards as transparent hotspots above all content: external targets as URL hyperlinks, internal targets as slide-jump hyperlinks resolved against the anchor map (forward references work; a dangling anchor warns and skips). Inline-graphic spans get baseline-aligned hotspot boxes, mirroring the PDF's span rectangles. The first bookmark on a page names its slide.
  • Multi-section. renderSections/writeSections concatenate sections into one deck: per-section chrome with section-local page numbering, cross-section navigation against the combined deck, first-declaring-section metadata, and fonts embedded once from the union. A deck carries one slide size, so differing page canvases are rejected. A raster-slide section still resolves incoming links and bookmarks; its own outgoing navigation is baked into the pixels.
  • Determinism. Builder.deterministic(boolean | Instant) pins the OPC created/modified properties and rewrites the finished archive with zone-independent zip entry times, making render-twice byte-identical.
  • renderToImages stays unsupported with a pointer to the PDF backend; capability matrix and CHANGELOG updated (the clip row now links the vector-clip follow-up pptx: replace the clip raster fallback with true vector clipping #413).

Verification

  • 17 new tests: OPC properties, watermark layer order and a hand-derived pin of the rotated frame centre (191.315, 96.724 for 45°/CENTER — a sign flip in the orbit math moves it by tens of points), token windows with roman styles and show-on-first-page, resolved URL and slide-jump hotspots, dangling-anchor degradation, section-local footer restarts, a cross-section jump into a raster section, differing-page-size rejection, and render-twice byte equality (single doc and sections) with pinned zip entry times.
  • Reviewable pair under render-pptx/target/visual-tests/pptx-parity/chrome-nav/ (PDF + PPTX + per-page PNGs at matching scale).
  • Full reactor gate green: clean verify across core, render-pdf, render-docx, render-pptx, templates, testing, root, bundle, qa, coverage.

@DemchaAV
DemchaAV merged commit 85543d0 into develop Jul 18, 2026
12 checks passed
@DemchaAV
DemchaAV deleted the feature/pptx-chrome-nav branch July 18, 2026 00:46
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant