Skip to content

Commit 3e28724

Browse files
authored
docs(pptx): describe the shipped fixed-layout backend (#437)
* docs(capabilities): mark the PPTX fixed-layout backend beta, not in development The per-capability cells already list the PPTX fixed-layout backend as implemented (✅/⚠️), but the backend descriptor still read "(in development)" — which the legend defines as "not usable yet". That contradicts the README and docs/api-stability.md, where the backend ships as @beta (Experimental). Restate the descriptor as implemented and shipping @beta so the capability matrix agrees with the policy and the changelog. * docs(roadmap): retarget to the shipped 2.0 line and 2.1 development The roadmap still described 2.0 as in flight on the retired `2.0-dev` branch preparing GA, named v1.9.x the current stable, and listed real PPTX export under "Later" as a manifest skeleton — contradicting the code, README and changelog. Retarget it: "Now" is the 2.1 line (the fixed-layout PPTX @beta backend plus the keep-with-next pagination work), 2.0.0 is the current stable line, and PPTX moves from "manifest skeleton" to a beyond-beta graduation item. Drop the two post-2.0 items that have since shipped — the ArchUnit module-boundary guards and the cross-module coverage aggregator. * docs(pptx): describe the shipped fixed-layout backend The module landing page for graph-compose-render-pptx still told readers that `.pptx` emission "is not built out yet" and to depend on the artifact "not for production slide export" — against 37 shipped production classes, a registered SPI, and the headline feature of the release. docs/capabilities.md listed the PPTX methods as Stable while the code marks them `@Beta`, and CONTRIBUTING sent contributors to `2.0-dev`, a branch that no longer exists. Rewrite render-pptx/README.md around the fixed-layout backend: what it produces, a first deck, the limitations worth knowing before shipping (raster fallback for clipped regions, viewer-side glyph rendering, opt-in determinism, unimplemented `renderToImages`, PDF-only chrome options), and the fact that a PPTX consumer also resolves the PDF stack because the backend reuses its font measurement and raster pass. Quantify the capability picture rather than promising blanket native output: of the 38 tracked capabilities, 24 map to a native equivalent, 10 render natively with an approximated styling detail, and 4 are unsupported. Correct the stability tier in docs/capabilities.md to Experimental (`@Beta`) so it agrees with the annotations and with docs/api-stability.md, and add the two `document.backend.fixed.pptx` packages to the §4 tier lookup, which the page's own maintenance rule requires. Refresh the frozen "New in" table to 2.1.0. Give PPTX a path in the docs: an Output backends section in the index and a PowerPoint section in getting-started, whose snippet carries a `doc-example` marker so it is compiled against the live API. Soften the root README's geometry promise to the capability matrix's own wording — frames and positions match, glyphs are rasterised by the viewer. Retarget ROADMAP to the 2.1 line, drop the "manifest skeleton" entry, and replace every `2.0-dev` reference in CONTRIBUTING with the post-GA branch roles. Install snippets are left alone: cut-release.ps1 rewrites the per-module ones in the release commit and VersionConsistencyGuardTest requires them to name the latest published release until then. Verified: full reactor `clean verify` green (1508 tests, 0 failures); core guards 402/402 and the documentation snippet guard green against the final text.
1 parent f477511 commit 3e28724

10 files changed

Lines changed: 181 additions & 48 deletions

File tree

CONTRIBUTING.md

Lines changed: 14 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -35,24 +35,23 @@ When writing new code, avoid Java 21+ APIs and language constructs that don't ex
3535

3636
## How to propose changes
3737

38-
GraphCompose follows a fork → feature branch → pull request flow. **Target the branch that matches your change** — GraphCompose is mid-transition to the 2.0 module line, so pick the base branch from this table before you fork:
38+
GraphCompose follows a fork → feature branch → pull request flow. **Target the branch that matches your change** — pick the base branch from this table before you fork:
3939

4040
| Change type | Base branch |
4141
|---|---|
42-
| **2.0 feature / fix** (almost all current work) | `2.0-dev` |
43-
| **Critical 1.9.x fix** (bug / security backport) | `develop` |
42+
| **Feature / fix** (almost all work) | `develop` |
43+
| **Critical 1.9.x fix** (bug / security backport) | `1.x` |
4444
| Stable releases (tags) | `main` |
45-
| After 2.0 GA | `develop` |
4645

47-
Almost all current work is 2.0 and targets **`2.0-dev`**. `develop` and `main` carry the shipping **1.9.x** line and take only critical fixes; `main` is the public stable surface and accepts release merges only. See [Version lines](#version-lines-and-the-1x-maintenance-branch) below for the full transition.
46+
Almost all work targets **`develop`**, the ongoing 2.x line. The `1.x` branch takes critical fixes and security backports only — no features. `main` is the public stable surface and accepts release merges only. See [Version lines](#version-lines-and-the-1x-maintenance-branch) below.
4847

4948
### Contribution flow
5049

5150
1. **Fork** the repository on GitHub and clone your fork locally.
52-
2. **Create a feature branch** from your target base (`2.0-dev` for 2.0 work — substitute `develop` for a critical 1.9.x fix):
51+
2. **Create a feature branch** from your target base (`develop` for feature work — substitute `1.x` for a critical 1.9.x backport):
5352
```bash
54-
git checkout 2.0-dev
55-
git pull --ff-only origin 2.0-dev
53+
git checkout develop
54+
git pull --ff-only origin develop
5655
git checkout -b feature/short-description
5756
```
5857
Use `feature/...` for new functionality, `fix/...` for bug fixes, and `docs/...` for documentation-only changes. Issue-prefixed names (`42/fix/short-description`) are also welcome — convenient when the branch closes a specific issue.
@@ -62,7 +61,7 @@ Almost all current work is 2.0 and targets **`2.0-dev`**. `develop` and `main` c
6261
./mvnw -B -ntp clean verify
6362
```
6463
This runs the architecture-and-documentation guards plus the full test suite. The same gate runs in CI on every PR.
65-
5. **Push** your feature branch to your fork and open a pull request against the base branch you started from (`2.0-dev` for 2.0 work) on `DemchaAV/GraphCompose`. Reference any related issue and describe the user-visible change in the PR body.
64+
5. **Push** your feature branch to your fork and open a pull request against the base branch you started from (`develop` for feature work) on `DemchaAV/GraphCompose`. Reference any related issue and describe the user-visible change in the PR body.
6665
6. **CI runs automatically.** Active jobs:
6766
- `Architecture and Documentation Guards` — fast canonical / engine-boundary guard tests, fail-first gate (always runs)
6867
- `Build and run tests (JDK 17)`, `(JDK 21)`, `(JDK 25)` — full `mvnw verify` in parallel matrix across the supported JVMs
@@ -71,7 +70,7 @@ Almost all current work is 2.0 and targets **`2.0-dev`**. `develop` and `main` c
7170
- `Performance Smoke Check` — PR-only coarse benchmark to catch performance regressions
7271
- `CI Gate` — single aggregate status check that is green when every job that ran passed
7372

74-
**Selective on pull requests:** a `dorny/paths-filter` step skips the heavy jobs when a PR touches nothing that affects the build — a **docs-only PR runs the guards only**; `Binary Compatibility` runs only when the core module changed, and the `Performance Smoke Check` only when core / render-pdf / templates changed. Pushes to `2.0-dev` / `main` (and manual dispatch) always run the full gate. Point branch protection at **`CI Gate`** + **`Architecture and Documentation Guards`** rather than the individual matrix legs, so a docs-only PR is not left waiting on a skipped check.
73+
**Selective on pull requests:** a `dorny/paths-filter` step skips the heavy jobs when a PR touches nothing that affects the build — a **docs-only PR runs the guards only**; `Binary Compatibility` runs only when the core module changed, and the `Performance Smoke Check` only when core / render-pdf / templates changed. Pushes to `develop` / `main` (and manual dispatch) always run the full gate. Point branch protection at **`CI Gate`** + **`Architecture and Documentation Guards`** rather than the individual matrix legs, so a docs-only PR is not left waiting on a skipped check.
7574

7675
The PR cannot merge into a protected branch until all required checks are green.
7776
7. **Address review comments**, then squash any fixup commits before merge. The maintainer merges through GitHub once review is complete.
@@ -85,7 +84,7 @@ Almost all current work is 2.0 and targets **`2.0-dev`**. `develop` and `main` c
8584
- linear history is enforced (squash or rebase, no merge commits)
8685
- force pushes and branch deletion are disabled
8786

88-
`2.0-dev` (and, for 1.9.x fixes, `develop`) accepts feature-branch PRs from contributors. The maintainer may push directly for solo-driven release-prep work; external contributions still flow through PRs.
87+
`develop` (and, for 1.9.x backports, `1.x`) accepts feature-branch PRs from contributors. The maintainer may push directly for solo-driven release-prep work; external contributions still flow through PRs.
8988

9089
### Release flow
9190

@@ -98,16 +97,11 @@ See [docs/contributing/release-process.md](./docs/contributing/release-process.m
9897

9998
### Version lines and the 1.x maintenance branch
10099

101-
GraphCompose is mid-transition to the 2.0 module line. Until 2.0 ships:
100+
The 2.0 GA shipped, so the branches now hold their long-term roles:
102101

103-
- **`2.0-dev`** is the working branch for 2.0 — feature branches for 2.0 work target `2.0-dev`, not `develop`.
104-
- **`develop`** and **`main`** carry the shipping **1.9.x** line; `main` is its stable, tagged surface (latest `v1.9.x`).
105-
106-
At the **2.0 GA** merge the branches take their long-term roles:
107-
108-
- **`main`** fast-forwards to 2.0 and becomes the stable 2.0 line.
109-
- **`develop`** becomes the ongoing 2.x working branch (what `2.0-dev` was); `2.0-dev` retires.
110-
- A **`1.x`** maintenance branch is cut from the final 1.9.x commit on `main` at that moment. It receives **critical fixes and security / CVE backports only — no features** — released as `1.9.x` patches from `1.x` via the same `cut-release.ps1` + tag flow. New feature work always targets the 2.x line.
102+
- **`develop`** is the ongoing 2.x working branch — all feature branches target it.
103+
- **`main`** is the stable 2.x line, tagged at each release (latest `v2.x`).
104+
- **`1.x`** is the maintenance branch cut from the final 1.9.x commit. It receives **critical fixes and security / CVE backports only — no features** — released as `1.9.x` patches from `1.x` via the same `cut-release.ps1` + tag flow. New feature work always targets the 2.x line.
111105

112106
## Repository map
113107

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@
4444

4545
## One source → a PDF <i>and</i> an editable PowerPoint deck
4646

47-
The same `DocumentSession` emits both. The PDF backend prints the resolved layout; the PPTX backend (**beta**) rebuilds it as slides with identical geometry — text, panels, tables, and vectors arrive in PowerPoint as **native, editable shapes**, not screenshots (the page below lands as 69 native shapes; only its clip-masked logo art is a picture).
47+
The same `DocumentSession` emits both. The PDF backend prints the resolved layout; the PPTX backend (**beta**) rebuilds it as slides. Both consume the same resolved layout graph, so page and slide frames and every positioned element share the same geometry — text, panels, tables, and vectors arrive in PowerPoint as **native, editable shapes**, not screenshots (the page below lands as 69 native shapes; only its clip-masked logo art is a picture). Glyphs are rasterised by the viewer, so the exact text rendering depends on the fonts installed on the viewing machine; see the [backend capability matrix](docs/architecture/backend-capability-matrix.md) for per-feature fidelity.
4848

4949
```java
5050
Path deck = Path.of("twin-output.pptx");

ROADMAP.md

Lines changed: 14 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -2,41 +2,42 @@
22

33
GraphCompose is solo-maintained. This roadmap is a direction, not a contract. Dates are intentionally omitted. Concrete work is tracked in [issues](https://github.com/DemchaAV/GraphCompose/issues) and shipped work is recorded in [CHANGELOG.md](CHANGELOG.md). For v1.6 phase-level detail, see [docs/roadmaps/v1.6-roadmap.md](docs/roadmaps/v1.6-roadmap.md).
44

5-
## Now — 2.0 line
5+
## Now — 2.1 line
66

7-
In flight on `2.0-dev`, preparing the 2.0.0 GA. The 2.0 line is about **packaging and internal hygiene**, not new authoring API — binary-breaking by design, with `japicmp` report-only for the cycle.
7+
In development on `develop`, building toward the **2.1.0** minor. The headline is the **fixed-layout PPTX render backend**: the same `DocumentSession` that prints a PDF now also emits an editable PowerPoint deck — one page per slide, identical geometry by construction, native shapes. It ships as `@Beta` (Experimental) while its API shape settles; the geometry identity with the PDF backend is a design invariant, not subject to change. See the [API stability policy](docs/api-stability.md) and the [backend capability matrix](docs/architecture/backend-capability-matrix.md).
88

9-
**Scope frozen (2026-07).** 2.0.0 ships exactly the set below; no further internal engineering is pulled in before GA — that work is the post-2.0 line (next section).
9+
Alongside it, 2.1 hardens pagination: `keepWithNext()` for headings, orphaned-heading fixes ahead of paragraphs, tables and lists, and the layered CV presets wired to the keep-with-next policy.
10+
11+
Full detail lands in [CHANGELOG.md](CHANGELOG.md) under `v2.1.0`.
12+
13+
## Current stable — 2.0
14+
15+
The **2.0.0** GA is the current stable line. 2.0 was about **packaging and internal hygiene**, not new authoring API — binary-breaking by design.
1016

1117
- **Modular split** &mdash; the single jar is split into `graph-compose-core` plus `graph-compose-render-pdf` / `graph-compose-render-docx` / `graph-compose-render-pptx` / `graph-compose-templates` / `graph-compose-testing`, with render backends discovered through a `ServiceLoader` SPI. `graph-compose` stays a drop-in wrapper (core + render-pdf) so existing PDF callers upgrade unchanged. See the [2.0 modules migration guide](docs/migration/v2.0.0-modules.md) and [ADR 0016](docs/adr/0016-multi-module-packaging.md).
1218
- **Legacy removal** &mdash; the dead Entity-Component-System execution layer and the deprecated (`forRemoval`) public API are gone; the classic template presets are replaced by the layered `templates.*` stack on `BrandTheme`.
1319
- **Release &amp; publishing pipeline** &mdash; multi-module Maven Central publishing, the `core/`-layout reactor (`./mvnw clean verify` at the root builds everything), and the cut / tag / GA runbook.
1420
- **Compatibility tests** &mdash; the guard, snapshot, and visual-regression suites that prove the split left rendered output unchanged.
15-
- **Maintenance** &mdash; the **v1.9.x** line (current stable) receives critical fixes only.
16-
17-
Further internal engineering — more layout-class decomposition, abstraction cleanup, streaming, optional performance work — is **deferred to post-2.0** and does not gate GA.
1821

19-
Full detail in [CHANGELOG.md](CHANGELOG.md) under `v2.0.0 — Planned`.
22+
The **v1.9.x** line receives critical fixes only.
2023

2124
## Next — post-2.0 engineering
2225

23-
Committed direction for after the 2.0 GA: internal refactors, scale work, and tooling that do **not** change the public authoring API. Tracked in [docs/roadmaps/post-2.0-engineering.md](docs/roadmaps/post-2.0-engineering.md).
26+
Committed internal direction for the post-2.0 line: refactors, scale work, and tooling that do **not** change the public authoring API. Tracked in [docs/roadmaps/post-2.0-engineering.md](docs/roadmaps/post-2.0-engineering.md).
2427

2528
- **Decompose the layout hot files** &mdash; split `LayoutCompiler` and `TextFlowSupport` along their natural seams into individually-tested collaborators, with layout output unchanged.
26-
- **ArchUnit module-boundary guards** &mdash; enforce the canonical / engine / render layering structurally, replacing the path-based greps that can pass vacuously after a move.
27-
- **Cross-module coverage aggregation** &mdash; a dedicated non-published module that compile-depends on the tested modules so JaCoCo sees the `qa` suites; report-only first, thresholds after a baseline read.
28-
- **Per-module binary-compatibility baselines** &mdash; once the 2.0 GA artifacts are published, switch `japicmp` to per-module baselines in break-on-incompatible mode.
29+
- **Per-module binary-compatibility baselines** &mdash; now that the 2.0 GA artifacts are published, switch `japicmp` from the single-artifact baseline to per-module baselines in break-on-incompatible mode.
2930

3031
## Later (directional)
3132

3233
Not committed. Reflects current thinking; priorities may shift based on user feedback and adoption signals.
3334

35+
- **PPTX beyond beta.** Graduate the fixed-layout PPTX backend from `@Beta` to stable and close the remaining fidelity gaps &mdash; true vector clipping instead of the raster fallback ([#413](https://github.com/DemchaAV/GraphCompose/issues/413)), exact numeric dash arrays, and distinct per-corner radii.
3436
- **DOCX visibility for unsupported nodes.** Make currently-silent skips (`shape`, `line`, `ellipse`, `barcode`) loud &mdash; minimum a warn log, ideally a strict-mode flag that fails instead of dropping content silently.
3537
- **Block-level alignment for fixed-size flow children.** Paths, images, layer stacks, shape containers and barcodes currently left-align in a flow; centring one means wrapping it in a full-width `ShapeContainer` just to use its CENTER anchor. Add a per-node horizontal align (left / centre / right &mdash; the `margin: auto` / `align(center)` analogue) so a fixed box can place itself in the flow directly. Surfaced by the v1.8 SVG icon-gallery and feature-catalog work.
3638
- **Backend-neutral layout measurement.** Decouple measurement from PDFBox-specific resources so non-PDF backends do not pull PDFBox into the dependency graph.
3739
- **DOCX maturity.** Either expand DOCX coverage toward PDF parity, or move DOCX behind an explicitly experimental flag.
38-
- **Property-based testing.** Random table spans, pagination edge cases, deeply nested layouts.
39-
- **Real PPTX export.** Current state is a manifest skeleton. Will only be built out if there is concrete user demand.
40+
- **Property-based testing.** Expand the `@Property` layout-invariant seed to random table spans, pagination edge cases, and deeply nested layouts.
4041
- **Public Javadoc site.** Generated and hosted, kept in sync with releases.
4142

4243
## Not on the roadmap

docs/README.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,11 @@ back here.
3838
- **[templates/v2-layered/](templates/v2-layered/)** — the template surface (CV is the reference implementation): `data` / `theme` / `components` / `widgets` / `presets`.
3939
- **[templates/v1-classic/](templates/v1-classic/)** — 🗄️ archived: the classic spec/builder/presets surface removed in 2.0; kept for pre-2.0 callers.
4040

41+
### Output backends
42+
- **[architecture/backend-capability-matrix.md](architecture/backend-capability-matrix.md)** — what each render backend supports, per capability. The source of truth for PDF vs PPTX fidelity.
43+
- **[../render-pptx/README.md](../render-pptx/README.md)**`graph-compose-render-pptx`: editable PowerPoint decks from the same session that prints the PDF (`@Beta`, first shipped in 2.1.0).
44+
- **[api-stability.md](api-stability.md)** — stability tier per package, and what a tier promises.
45+
4146
### Architecture
4247
- **[architecture/overview.md](architecture/overview.md)** — high-level system architecture (engine + DSL + templates + backends).
4348
- **[architecture/lifecycle.md](architecture/lifecycle.md)** — the document lifecycle from `GraphCompose.document(...)` through `buildPdf()`.

docs/api-stability.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -241,6 +241,8 @@ Javadoc per element.
241241
| `com.demcha.compose.document.templates.invoice.*` | **Stable** | `graph-compose-templates` | Layered invoice family — `ModernInvoice` on `InvoiceDocumentSpec`. |
242242
| `com.demcha.compose.document.templates.proposal.*` | **Stable** | `graph-compose-templates` | Layered proposal family — `ModernProposal` on `ProposalDocumentSpec`. |
243243
| `com.demcha.compose.document.templates.data.*` | **Stable** | `graph-compose-templates` | Family-neutral document data records (invoice / proposal / schedule specs). |
244+
| `com.demcha.compose.document.backend.fixed.pptx` | **Experimental** | `graph-compose-render-pptx` | Marked `@Beta` at the package level — `PptxFixedLayoutBackend`, its builder, and `PptxFixedLayoutBackendProvider`. First shipped in 2.1.0. |
245+
| `com.demcha.compose.document.backend.fixed.pptx.handlers` | **Experimental** | `graph-compose-render-pptx` | Marked `@Beta` at the package level — the `PptxFragmentRenderHandler` seam and its built-in handlers. |
244246
| `com.demcha.compose.document.layout.*` | **Internal** | `graph-compose-core` | Marked `@Internal` at the package level. Engine surface. |
245247
| `com.demcha.compose.engine.*` | **Internal** | `graph-compose-core` | Engine surface; not part of the public contract regardless of `public` keyword. `engine.render.pdf.*` ships in `graph-compose-render-pdf`. |
246248

docs/architecture/backend-capability-matrix.md

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -22,9 +22,12 @@ Backends:
2222
`com.demcha.compose.document.backend.fixed.pdf`. Consumes the resolved
2323
`LayoutGraph`; the reference implementation.
2424
- **PPTX (fixed-layout)**`graph-compose-render-pptx`,
25-
`com.demcha.compose.document.backend.fixed.pptx` (in development).
26-
Consumes the same resolved `LayoutGraph`; geometry-identical to PDF by
27-
construction, since layout is compiled in core before any backend runs.
25+
`com.demcha.compose.document.backend.fixed.pptx`. Consumes the same
26+
resolved `LayoutGraph`; geometry-identical to PDF by construction, since
27+
layout is compiled in core before any backend runs. Ships as `@Beta`
28+
(Experimental) in its first release — usable, with the per-capability
29+
status in the tables below; the API shape may still change in a minor
30+
while feedback lands (see [../api-stability.md](../api-stability.md)).
2831
- **DOCX (semantic)**`graph-compose-render-docx`,
2932
`DocxSemanticBackend`. Walks the semantic node tree, deliberately
3033
ignores fixed-layout geometry; Word owns the flow. Geometry rows are

docs/architecture/canonical-legacy-parity.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -92,7 +92,7 @@ compatibility concerns. New authoring features should be added through
9292
| Guide lines | Done | `guideLines(true)` is available on document builder and session. |
9393
| Metadata/protection/watermark/header/footer | Done | Configure on `DocumentSession` (e.g. `metadata(...)`, `watermark(...)`, `protect(...)`, `header(...)`, `footer(...)`); convenience PDF entrypoints (`buildPdf`, `writePdf`, `toPdfBytes`) honour these options without an explicit backend builder. `PdfFixedLayoutBackend.builder()` remains for advanced cases. |
9494
| DOCX semantic export | Done | Use `session.export(new DocxSemanticBackend())` for paragraph/table/image-aware Word output. Requires `org.apache.poi:poi-ooxml` on the consumer classpath. |
95-
| PPTX semantic export | Planned for v1.6 (stretch) | Build out `PptxSemanticBackend` from the existing manifest skeleton to a working POI-based exporter — paragraphs as text boxes, tables as PowerPoint tables, sections as slides. See [v1.6 roadmap, Phase D](../roadmaps/v1.6-roadmap.md). |
95+
| PPTX export | Done (fixed-layout, `@Beta` since 2.1.0) | `session.buildPptx(path)` with `graph-compose-render-pptx` on the classpath emits an editable deck from the same resolved layout graph as the PDF — one page per slide, native shapes, matching geometry. See the [backend capability matrix](backend-capability-matrix.md). The older `PptxSemanticBackend` manifest remains in the module but is not what the convenience methods use. |
9696
| PDFBox types in session API | Rejected | Keep PDFBox behind the fixed PDF backend. |
9797

9898
## Diagnostics

0 commit comments

Comments
 (0)