Skip to content

feat(render-pptx): keep provably no-op clips editable, align gradient stops and handler contracts#417

Open
DemchaAV wants to merge 1 commit into
feature/pptx-guards-examplesfrom
fix/pptx-clip-noop-alignments
Open

feat(render-pptx): keep provably no-op clips editable, align gradient stops and handler contracts#417
DemchaAV wants to merge 1 commit into
feature/pptx-guards-examplesfrom
fix/pptx-clip-noop-alignments

Conversation

@DemchaAV

Copy link
Copy Markdown
Owner

Stacked on #416 — retarget to develop before merging the parent.

Why

Every clipped composite rendered as one raster picture, even when the clip could not visibly cut anything — the overwhelmingly common defensive-clip case (a rounded card whose padded content never reaches the corners). On the flagship deck that turned the bottom badges, the backend cards, and the engine grid into non-editable pictures, defeating the editable-deck promise for exactly the shapes a user reaches for first. Separately, a parity audit found PPTX gradients honouring partial stop offsets the PDF shading ignores, and addHandler silently accepting duplicates the PDF builder rejects.

What

  • PptxClipSafety proves a clip region cannot remove ink, in which case the raster fallback is skipped and the children render as native, editable shapes. The ink model is exact where it can be: smooth strokes and side borders bleed half their width past the fragment box; a projecting line cap bleeds ×√2; unstroked polygon fills stay inside (ShapePoint clamps); an unstroked path fill is provable only when every segment coordinate — Bézier control points as a conservative hull — stays in the unit box, because the segment contract does not clamp them. Text gets a font-size-aware overhang guard. Everything else is unprovable and keeps the pixel-exact raster: stroked polygons/paths (mitred joins spike), table rows, transforms inside the region, polygon/path clip outlines, unknown payloads, NaN stroke widths. Rounded-rect containment forbids only the corner squares (per-corner radii honoured in the y-up convention); ellipse containment is a Minkowski test against the true ellipse.
  • Flagship-deck effect: 14 raster composites → 8, native shapes 276 → 299 — the badges, backend cards, and grid tiles are now selectable, editable text and shapes; the remaining rasters genuinely cut ink (overflowing logo art, edge-flush stroked thumbnails, SVG fills whose control points leave the box).
  • Gradient boundary stops pin to the domain ends in PptxGradientFill, matching what the PDF shading functions actually paint — partial-offset ramps now shade identically in both formats.
  • Builder.addHandler rejects a duplicate custom handler for the same payload type (PDF contract parity) and documents that custom handlers do not apply inside rasterized clip composites.
  • Docs: the capability matrix's alpha row reflects reality (PPTX carries alpha natively on fills, strokes, text, and table paint; PDF renders text/lines/table paint opaque), a new text-decorations row records that the PDF backend draws no underline/strikethrough lines while PPTX does, the clip row describes the no-op path and the raster region's interactivity limits, and DocumentColor.rgba's Javadoc names the PPTX behaviour.

Verification

  • PptxClipSafetyTest (14 tests): exact-fit and padded safety, overflow/stroke-bleed/side-border/projecting-cap rejections, rounded and per-corner squares with a top-vs-bottom y-up discriminator, Minkowski ellipse, bounds-vs-path policy, miter and unclamped-path bail-outs, unknown-payload and transform bail-outs, nested-marker transparency.
  • PptxClipRasterFallbackTest gains the no-op case (padded rounded card renders two native shapes, no composite) while the genuinely-cutting fixtures still raster; PptxAlphaTest pins native alpha for fills, strokes (at the XML level — POI's getLineColor hides the alpha its writer emits), and text runs; gradient-stop pinning and the duplicate-handler rejection are CT-level pinned.
  • An adversarial soundness review of the proof ran before merge; every finding (unclamped path segments, side borders, miter joins, ellipse erosion) is closed with a discriminating test.
  • Full reactor gate green: clean verify across core, render-pdf, render-docx, render-pptx, templates, testing, root, bundle, qa, coverage.

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