Skip to content

GraphCompose v2.0.0

Latest

Choose a tag to compare

@github-actions github-actions released this 13 Jul 06:41

v2.0.0 — 2026-07-13

The 2.0 development line. Binary-breaking by design — japicmp runs report-only
for this cycle.

Removed

  • The classic (pre-layered) CV and cover-letter template presets have been removed.
    The layered template stack — templates.cv.*, templates.coverletter.*,
    templates.invoice.*, and templates.proposal.*, all on BrandTheme — is now the
    single template surface.
  • The standalone BusinessTheme design-token bundle (and its DocumentPalette /
    SpacingScale / TextScale / TablePreset companions) is no longer part of the
    library. It lives on only as a styling helper inside the examples module; author
    documents with explicit DocumentColor / DocumentTextStyle values or a template
    BrandTheme.
  • The DSL name-aliases DocumentSession.builder() and DocumentDsl.text() have been
    removed. Use DocumentSession.dsl() and DocumentDsl.paragraph().
  • The PDF-typed document-chrome overloads on DocumentSession
    metadata(PdfMetadataOptions), watermark(PdfWatermarkOptions),
    protect(PdfProtectionOptions), header(PdfHeaderFooterOptions) and
    footer(PdfHeaderFooterOptions) — have been removed in favour of the canonical,
    backend-neutral overloads (metadata(DocumentMetadata), watermark(DocumentWatermark),
    protect(DocumentProtection), header(DocumentHeaderFooter),
    footer(DocumentHeaderFooter)). The PDF option types remain available on
    PdfFixedLayoutBackend.builder() for advanced backend-level configuration.
  • The linkOptions() accessor on the document nodes and inline runs (paragraph, table,
    image, shape, ellipse, line, barcode, and the inline image / shape / text runs) has
    been removed. Use linkTarget() and read the external URI from
    ExternalLinkTarget.options().
  • The unused engine-internal Font.adjustFontSizeToFit(...) (and its PdfFont /
    WordFont implementations) has been removed; text auto-sizing is resolved by the
    layout compiler.
  • The dormant Entity-Component-System engine internals have been removed: the
    EntityManager / SystemECS runtime, the Entity component model with its
    geometry / coordinator / renderable companions, the ECS render pipeline
    (engine.render.* and the guide renderers under engine.render.guides), and
    LayoutSnapshotExtractor. None were reachable from the live render path —
    DocumentSession → layout compiler → fixed-layout backend — so document layout,
    PDF output, and the public guideLines(...) overlay are unchanged.

Public API

  • Reproducible PDF output (@Beta). PdfFixedLayoutBackend.builder().deterministic(true)
    (or .deterministic(Instant) for an explicit timestamp) pins the document
    CreationDate / ModDate and derives the PDF /ID from the document metadata instead
    of PDFBox's time-seeded default, so the same document renders to byte-identical PDF
    bytes across runs — for reproducible builds and byte-level output tests. Off by
    default (output keeps the live timestamp and /ID). PDF encryption via protect(...)
    can reintroduce randomness (AES-256 uses random salts), so an encrypted document is
    not byte-reproducible even with this enabled. Multi-section documents opt in through
    the new MultiSectionDocument.toPdfBytes(FixedLayoutRenderer) /
    writePdf(FixedLayoutRenderer, OutputStream) overloads — the multi-section
    counterpart of DocumentSession.render(backend).
  • The layered template packages dropped their .v2 suffix:
    com.demcha.compose.document.templates.<family>.v2.*
    com.demcha.compose.document.templates.<family>.* for cv, coverletter,
    invoice, and proposal. Update imports accordingly — behaviour and rendering are
    unchanged; this is a package rename only.

Packaging

  • 2.0 splits the monolithic engine into modules. The engine now builds under a new
    graph-compose-core coordinate, and the original graph-compose coordinate
    becomes a thin drop-in aggregator
    that depends on graph-compose-core — so an
    existing graph-compose dependency keeps compiling and rendering PDF unchanged.
    Consumer-testing support (graph-compose-testing) and the semantic DOCX / PPTX
    backends (graph-compose-render-docx / graph-compose-render-pptx) are already
    separate artifacts; the PDF render backend now lives in
    graph-compose-render-pdf
    , which the graph-compose wrapper aggregates so a
    bare graph-compose still renders PDF, while graph-compose-core alone is lean
    (it throws MissingBackendException if asked to render without a backend). The
    built-in templates now ship in graph-compose-templates (opt-in; the
    graph-compose wrapper does not bundle them). The
    optional graph-compose-fonts / graph-compose-emoji artifacts are unchanged.
    Full install guidance ships with 2.0.0.
  • graph-compose-render-pdf is a separate artifact: the entire PDFBox backend —
    document.backend.fixed.pdf.** and the engine.render.pdf.** render tree — plus
    PDFBox, zxing (barcodes), and the commons-logging→SLF4J bridge leave
    graph-compose-core. The core keeps the DocumentSession API and the
    ServiceLoader seam (FixedLayoutBackendProvider / FontMetricsProvider); the
    PDF provider ships in render-pdf and is discovered at runtime. Depend on
    graph-compose (or graph-compose-render-pdf directly) for PDF; a bare
    graph-compose-core renders nothing until a backend is on the classpath.
  • graph-compose-templates is a separate artifact: the built-in CV, cover-letter,
    invoice, and proposal templates (document.templates.**) leave the engine. They
    are pure authoring code over the canonical DSL, so the module depends only on
    graph-compose-core. Add graph-compose-templates for the ready-made presets; a
    consumer that used them through graph-compose before must now add this artifact
    (the com.demcha.compose.document.templates.** packages are unchanged).
  • The semantic office backends are separate artifacts and Apache POI leaves the
    engine: DocxSemanticBackend ships in graph-compose-render-docx (which brings
    POI transitively — add it to export DOCX), and PptxSemanticBackend ships in its
    own graph-compose-render-pptx (a POI-free skeleton for now — add it for the
    slide-safe semantic manifest). Their packages —
    com.demcha.compose.document.backend.semantic.{docx,pptx} — are unchanged. The
    no-poi build profile is retired.
  • graph-compose-testing is now a separate artifact: the consumer testing
    support — LayoutSnapshotAssertions (deterministic layout snapshots) and
    PdfVisualRegression (pixel-diff of rendered pages) — leaves the
    graph-compose jar together with its Jackson and PDFBox dependencies. The
    com.demcha.compose.testing.layout / com.demcha.compose.testing.visual
    packages are unchanged, so imports stay the same; add graph-compose-testing
    at test scope to keep using them.
  • graph-compose-bundle is the batteries-included aggregate for the split layout:
    one dependency pulls the default PDF stack (graph-compose = core + render-pdf),
    the built-in templates (graph-compose-templates), the bundled Google fonts, and
    the colour-emoji set at compatible pinned versions. The office backends
    (graph-compose-render-docx / graph-compose-render-pptx) stay opt-in and are not
    bundled.

Internal

  • The process-wide image caches (decoded source bytes and image metadata) are now
    bounded with LRU eviction instead of growing without limit. A long-lived JVM that
    renders many distinct images — a rendering service, a batch job — no longer
    accumulates image data indefinitely. Single documents are unaffected: the caps sit
    far above any realistic distinct-image count, so a render never evicts or re-decodes.

Build

  • Added report-only cross-module code coverage. A new non-published
    graph-compose-coverage module runs JaCoCo report-aggregate over the engine, the
    PDF backend, and the built-in templates plus the graph-compose-qa cross-module
    suites, so each module's coverage counts the tests that actually exercise it (a
    single-module report undercounts, because much of the production code is driven from
    qa at test scope). CI publishes the HTML/XML report as an artifact; no coverage
    threshold is enforced yet.

Documentation

  • Documented that text is laid out left-to-right only: bidirectional (RTL) reordering
    and complex-script shaping (Arabic joining, Indic reordering) are not performed. Added
    to the README support matrix.
  • The 2.0 module migration guide now lists the API changes it previously delegated to the
    changelog — the .v2 package rename, the BusinessTheme removal, the retired classic
    presets, and Font.adjustFontSizeToFit — each with its migration action.