Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 19 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,25 @@ follow semantic versioning; release dates are ISO 8601.
byte-identical decks across runs by pinning the OPC created/modified
properties and normalizing every zip entry timestamp (zone-independent).

- Provably no-op clips stay editable in the fixed PPTX backend: when every
child of a clip region sits safely inside the clip outline (the common
defensive-clip case — a rounded card whose padded content never reaches the
corners), the raster fallback is skipped and the region renders as native,
editable shapes. Nested clip regions are judged by their confining clip box
and re-dispatch at their own granularity, so an unprovable icon inside a
card no longer rasterizes the whole card — only the icon. The proof is
conservative — unprovable outline kinds (polygons, free paths), transforms
inside the region, stroked polygons and paths (mitred joins), path segments
outside the unit box, table rows, broken nested pairings, and ink whose
stroke or side-border bleed nears the boundary all keep the pixel-exact
raster path.
- PPTX gradients pin their first and last stop offsets to the domain ends,
matching what the PDF shading functions actually paint — a partial-offset
ramp now shades identically in both formats.
- `PptxFixedLayoutBackend.Builder.addHandler` rejects a duplicate custom
handler for the same payload type, matching the PDF builder's contract, and
documents that custom handlers do not apply inside rasterized clip
composites.
- `DocumentSession.toPptxBytes()` / `writePptx(OutputStream)` /
`buildPptx()` / `buildPptx(Path)` — the PPTX counterparts of the PDF
convenience trio. The backend resolves through the format-keyed provider
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,10 @@ public static DocumentColor rgb(int red, int green, int blue) {
* rectangles/panels/bars, chart value-label halos, ellipses (chart point
* markers), polygons, and inline shapes — via a graphics-state alpha
* constant. Text, lines, and the DOCX backend currently render the colour
* fully opaque.</p>
* fully opaque. The PPTX backend carries the alpha natively on every
* surface — fills, strokes, text runs, and table paint — so a translucent
* colour on text or table cells shows through in the deck where the PDF
* still paints it opaque.</p>
*
* @param red red channel from 0 to 255
* @param green green channel from 0 to 255
Expand Down
5 changes: 3 additions & 2 deletions docs/architecture/backend-capability-matrix.md
Original file line number Diff line number Diff line change
Expand Up @@ -56,11 +56,12 @@ Payload records live in `core` under
| Image — STRETCH / CONTAIN / COVER fit (`ImageFragmentPayload`) | ✅ `PdfImageFragmentRenderHandler` | ✅ `PptxImageFragmentRenderHandler` (COVER via the picture source crop) | ✅ semantic images (`DocxSemanticBackend`) |
| Barcode / QR (`BarcodeFragmentPayload`) | ✅ `PdfBarcodeFragmentRenderHandler` (ZXing raster) | ✅ `PptxBarcodeFragmentRenderHandler` (identical ZXing raster) | ❌ |
| Table rows — resolved cells, row/col spans, two-pass fill/border paint (`TableRowFragmentPayload`) | ✅ `PdfTableRowFragmentRenderHandler` + row grouping in `PdfFixedLayoutBackend` | ✅ `PptxTableRowFragmentRenderHandler` + row grouping in `PptxFixedLayoutBackend` (positioned rectangles, edge lines, and text frames — never native PPTX tables, which re-lay-out content) | ✅ semantic tables (`DocxSemanticBackend`) |
| Clip region open/close (`ShapeClipBegin/EndPayload`) | ✅ `PdfShapeClipBegin/EndRenderHandler` (CLIP_BOUNDS + CLIP_PATH) | ✅ raster fallback in `PptxFixedLayoutBackend` — the clip region renders through the PDF backend into one transparent picture on the clip bounds (pixel-exact, not editable as shapes; `Builder.clipRasterFallback(false)` restores unclipped vectors + warning; a true vector clip is tracked in [#413](https://github.com/DemchaAV/GraphCompose/issues/413)) | ⚠️ inline fallback + one-time capability warning |
| Clip region open/close (`ShapeClipBegin/EndPayload`) | ✅ `PdfShapeClipBegin/EndRenderHandler` (CLIP_BOUNDS + CLIP_PATH) | ✅ `PptxClipSafety` + raster fallback in `PptxFixedLayoutBackend` — a provably no-op clip (padded content that cannot be cut) skips the fallback entirely and stays native, editable shapes; a clip that can cut ink renders through the PDF backend into one transparent picture on the clip bounds (pixel-exact, not editable as shapes; run-level link hotspots are not emitted and custom fragment handlers do not apply inside the picture; `Builder.clipRasterFallback(false)` restores unclipped vectors + warning; a true vector clip is tracked in [#413](https://github.com/DemchaAV/GraphCompose/issues/413)) | ⚠️ inline fallback + one-time capability warning |
| Transform open/close — rotate/scale about fragment centre (`TransformBegin/EndPayload`) | ✅ `PdfTransformBegin/EndRenderHandler` | ✅ `PptxTransformBegin/EndRenderHandler` (group shape; rotation and centre-pivot scaling via the exterior/interior frame ratio) | ⚠️ inline fallback + one-time capability warning |
| Anchor markers (`AnchorMarkerPayload`) | ✅ `PdfAnchorMarkerRenderHandler` + `PdfInternalLinkWriter` | ✅ `PptxAnchorMarkerRenderHandler` + `PptxNavigationWriter` (slide-jump hyperlinks resolved after all fragments, so forward references work) | ❌ |
| Bookmark markers (`BookmarkMarkerPayload`) | ✅ `PdfBookmarkMarkerRenderHandler` + `PdfBookmarkOutlineWriter` | ⚠️ `PptxBookmarkMarkerRenderHandler` + `PptxNavigationWriter` (PPTX has no outline tree — the first bookmark on a page names its slide, further bookmarks on the same page are dropped with a debug note) | ❌ |
| Alpha / opacity | ✅ `PdfAlphaSupport` (`PDExtendedGraphicsState`) | 🚧 (native fill alpha) | ❌ |
| Alpha / opacity | ⚠️ `PdfAlphaSupport` (`PDExtendedGraphicsState` on shape fills and strokes; text, lines, and table paint render opaque) | ✅ native `<a:alpha>` via POI on every surface — fills, strokes, text runs, table paint | ❌ |
| Text decorations — underline / strikethrough (`DocumentTextDecoration`) | ❌ (the decoration flags resolve to font faces, but no decoration lines are drawn) | ✅ `PptxTextFrames.applyStyle` | ❌ |

## Navigation and interactivity

Expand Down
Loading
Loading