This release includes breaking changes for platform teams planning a safe upgrade.
Published 1mo
Build & Package
✓ No known CVEs patched
✓ No known CVEs patched in this version
Topics
business-documents
cv-templates
declarative-api
document-generation
invoice-template
java
+12 more
java-17
layout-engine
maven
pagination
pdf
pdf-generator
pdf-lib
pdf-library
pdfbox3
report-generation
snapshot-testing
template-engine
Summary
AI summaryBroad release touches Public API, Build, sides, and multi-layer.
Full changelog
v1.7.0 — 2026-06-07
Canonical DSL primitives — additive only, zero breaking changes. Adding public
API turns the open cycle into a minor.
Public API
- Inline shape runs — geometry-based dots, diamonds, stars and bullets. New
com.demcha.compose.document.node.InlineShapeRun(@since 1.7.0) joins the
sealedInlineRunhierarchy alongside text and image runs. It draws any
ShapeOutlinefigure on the paragraph baseline directly from geometry — no
raster payload, no font glyph — so skill rating dots (Java ●●●●○), custom
bullets and inline status markers no longer depend on a font shipping
U+25CFand friends. Authored throughParagraphBuilder/RichText
dot(...),ellipse(...),diamond(...),triangle(...),star(...)and
the genericshape(ShapeOutline, ...); measured into line width and height
like inline images. Anullfill paints an outlined figure, anullstroke
a filled one; at least one must be present. - New polygon shape geometry, usable block-level and inline.
ShapeOutline
(com.demcha.compose.document.style) gains aPolygonkind plus a family of
factories built from normalizedShapePointvertices (@since 1.7.0):
diamond,triangle,star,polygon,arrow/arrowRight/arrowLeft
(4-wayDirection),chevron,checkmark,plusandregularPolygon(sides).
Arrows and chevrons read as directional list bullets or inline markers
between text ("Step 1 → Step 2", "Home › Docs").ParagraphBuilder/
RichTextaddarrow(size, Direction, fill)andchevron(...)shortcuts
(every other kind is reachable throughshape(ShapeOutline, ...));
ShapeContainerBuilderexposes matching block outlines. Rectangle,
rounded-rectangle and ellipse shape containers are unchanged. - Inline checkboxes + composite (multi-layer) inline figures. An inline
shape run is now a stack of paint layers
(com.demcha.compose.document.node.ShapeLayer,@since 1.7.0) drawn overlaid
and centred, so a figure can compose several outlines — each with its own
fill/stroke — and still measure and place as one unit on the baseline.
ParagraphBuilder/RichTextgaincheckbox(size, checked, color)/
checkbox(size, checked, boxColor, checkColor)(@since 1.7.0): a rounded
frame plus, in the checked state, a centred tick — the todo / checklist marker
for "some items done, some not". The single-outlineInlineShapeRun
convenience constructors are unchanged; every other kind still renders as one
layer. - Swappable tick and arrow designs (the "pick your figure" seam).
ShapeOutlineaddsCheckmarkStyle(CLASSIC,HEAVY) andArrowStyle
(BLOCK,TRIANGLE) enums plus the overloads
checkmark(w, h, CheckmarkStyle)andarrow(w, h, Direction, ArrowStyle)
(@since 1.7.0); the no-style factories delegate toCLASSIC/BLOCK, so
the default look is unchanged.checkbox(...),RichText.arrow(...)and
ParagraphBuilder.arrow(...)gain matching style overloads, andcheckbox
also accepts a rawShapeOutlinemark for fully custom ticks. Adding a new
design is one enum constant plus its vertex ring — the foundation for letting
a caller choose which tick or arrow to render. softPanel(...)gains stroke overloads — rounded fill + outline in one node.
AbstractFlowBuilder.softPanel(color, radius, padding, stroke)and
softPanel(color, cornerRadius, padding, stroke)(@since 1.7.0) apply a
border stroke alongside the panel fill on the same flow node (section, module,
page flow), so a rounded, padded background with a thin outline no longer needs
a separate wrapping node. Equivalent to the always-available
softPanel(...).stroke(...)chain — these overloads just make the one-node
form discoverable.- Per-corner radius on shape containers.
ShapeContainerBuilder.roundedRect(width, height, DocumentCornerRadius)plus the newShapeOutline.RoundedRectanglePerCorner
(@since 1.7.0) round a container's four corners independently — a card "rounded on
the left, square on the right" no longer needs a CLIP_PATH-parent workaround, since
both the outline fill/stroke and the child clip now follow the per-corner geometry.
DocumentCornerRadius.left/right/top/bottom(...)give the common asymmetric presets.
The single-radiusroundedRect(w, h, double)overload is unchanged, and uniform
rounded rectangles render byte-for-byte identically (the clip and fill now share one
per-corner path implementation, called with four equal radii). - Vertical text alignment for shape-container labels.
ParagraphBuilder.verticalAlign(TextVerticalAlign)(new enum
com.demcha.compose.document.node.TextVerticalAlign,@since 1.7.0) seats a
single line by its cap band within its line box —TOP(cap top to the box top),
CENTER(cap band centred) orBOTTOM(baseline to the box bottom). Combined
with a vertically-centred layer placement (.center(...)/.centerLeft(...)), a
label dropped into a tallerShapeContainer/LayerStack"pill" sits where you
ask instead of always on the font baseline — no compensating offset hacks.
TextVerticalAlign.DEFAULTkeeps the pre-1.7.0 baseline seating;
the correction is derived from font metrics (ascent, descent, leading, cap
height), not a magic number. Render-only and opt-in — existing layouts are
byte-for-byte unchanged. - Bundled font: JetBrains Mono. New
FontName.JETBRAINS_MONO(@since 1.7.0)
joins the built-inDefaultFontscatalog with its Regular / Bold / Italic /
Bold-Italic faces (bundled from the OFL-1.1 release), so monospaced code and
data blocks render without a system-font install. Usable through any
DocumentTextStyle.fontName(...)and listed in the font showcase. - Dashed and dotted lines.
LineBuilder.dashed(double... pattern)/
dashed()/dashed(DocumentDashPattern)plus the new value type
com.demcha.compose.document.style.DocumentDashPattern(@since 1.7.0) make a
line(...)paint an on/off dash instead of a solid stroke — section and résumé
dividers, timeline connectors, cut-here rules. The pattern alternates paint-on
and paint-off lengths in points (dashed(8, 5);dashed()is a balanced 3pt-on
/ 2pt-off;dashed(1, 4)reads as dotted). Carried on the line independently of
DocumentStroke, so the stroke value stays a stable two-component record; lines
are solid by default and the PDF backend honours the dash (other backends fall
back to a solid stroke). - Semantic timelines.
addTimeline(timeline -> ...)on every flow / section /
module, plusTimelineBuilder,TimelineMarkerandTimelineEntryBuilder
(com.demcha.compose.document.dsl,@since 1.7.0), lay out a vertical timeline
where eachentry(marker, e -> e.title(...).meta(...).body(...))pairs a marker
with its content along a continuous connector rail — work history, project
milestones, numbered process steps. Markers areTimelineMarker.dot,circle,
numberedorsquare; the rail colour/width, gutter, entry spacing and default
title / meta / body styles are all tunable. Declaring the marker-to-content
relationship replaces the hand-placed bullet-plus-margin pattern; the timeline
paginates between entries and a tall entry splits within itself, the rail
continuing across the page break. DocumentSession.availableHeight(). A one-call alias for
canvas().innerHeight()(@since 1.7.0) — the usable page content height
(page height minus top and bottom margins), the value a composition reads to
decide how much vertical room a section, sidebar or spacer may fill.
Previously reachable only through the layout-inspection facade.headingBar(text, bar -> ...)— one-call filled title band. Every flow,
section and module gainsheadingBar(String)andheadingBar(String, Consumer<HeadingBarStyle>)(@since 1.7.0) onAbstractFlowBuilder: a
filled, rounded heading band with a single label, added as a child above the
body.HeadingBarStyle(com.demcha.compose.document.dsl) tunes fill, corner
radius, padding, margin, label text style, alignment and an optional outline
stroke, each with a sensible default (a light-grey band with a centred bold
label), sobar -> bar.fill(brand).textStyle(white)is enough. Sugar over the
softPanel(...).addParagraph(...)recipe — no new node type, just discoverable.
Fixed
position(node, dx, dy, align)offsets are now honored for stacks nested
inside a fixed slot. ALayerStack/ShapeContainerplaced inside a row
column or another layer compiled through the fixed-slot stack path, which
silently dropped the per-layer offsets (anchoring on alignment only) — so a
positioned badge or cap could not be nudged from its anchor once nested, even
though the same call worked at the document root. The nested path now feeds
the samePreparedStackLayoutoffsets as the root path. Layout for documents
that did not useposition(...)inside a nested stack is unchanged.
Documentation
- New recipe pages for page composition and font coverage (closing the
docs/recipes/discoverability gaps G2 / G6):
page-backgrounds.md(PageBackgroundFill
columns / bands / point-based fills / layering),
layered-page-design.md(choosing
between page backgrounds, rows, layer stacks and canvases),
absolute-placement.md(addCanvas+
position(x, y)), andfont-coverage.md(WinAnsi
limits,●vs•, and the inline-shape / bundled-font alternatives). Linked
from the README recipes index,docs/README.md, anddocs/recipes.md.
Build
- Showcase website separated from documentation (
docs/→web/), now deployed
via GitHub Actions. The static GitHub Pages site (index.html,styles.css,
examples.js, the generatedexamples.json+showcase/gallery assets,
robots.txt,sitemap.xml, logo) moved out ofdocs/— which previously had to
host it because branch-based Pages can only serve repo-root or/docs— into a new
top-levelweb/folder, sodocs/now holds only documentation. A new
deploy-web.ymlpublishesweb/to Pages from
the "GitHub Actions" source; the old branch-/docsdeploy-site.ymlwas
removed.ShowcaseSyncnow writesweb/showcase+web/examples.json,
VersionConsistencyGuardTestreadsweb/index.html, andcut-release.ps1
bumps / commitsweb/. The unused Next.js rebuild undersite/(added in v1.6.8
but never deployed) was removed. Also renameddocs/SHOWCASE.md→web/README.md.
⚠️ Action required before the next release reachesmain: set
Settings → Pages → Source = "GitHub Actions" — once the move lands onmain,
/docsno longer holdsindex.html, so a branch-/docsPages source would 404.
The live site is unaffected until then.
Weekly OSS security release digest.
The CVE patches and breaking changes that affected production tools this week. One email, every Sunday.
No spam, unsubscribe anytime.
Share this release
About GraphCompose 2.0
All releases →Related context
Related tools
Earlier breaking changes
- v2.0.0 Package rename: layered template packages dropped `.v2` suffix; update imports.
- v2.0.0 Removed dormant ECS engine internals (EntityManager, SystemECS, Entity components, render pipeline).
- v2.0.0 Removed linkOptions() accessor; use linkTarget() and ExternalLinkTarget.options().
- v2.0.0 Removed PDF‑typed document‑chrome overloads on DocumentSession; use backend‑neutral metadata/watermark/protect/header/footer.
- v2.0.0 Removed DSL name-aliases DocumentSession.builder() and DocumentDsl.text(); use builder() and paragraph().
Beta — feedback welcome: [email protected]