From fcbae0b39975c20aebecc2c638f413b82356bc53 Mon Sep 17 00:00:00 2001 From: DemchaAV Date: Mon, 24 Aug 2026 09:44:09 +0100 Subject: [PATCH] chore(api): graduate the SVG surface from beta to stable --- CHANGELOG.md | 19 +++++++++++++++++++ .../document/dsl/AbstractFlowBuilder.java | 2 -- .../compose/document/dsl/PathBuilder.java | 2 -- .../document/dsl/ShapeContainerBuilder.java | 1 - .../compose/document/style/DocumentPaint.java | 9 --------- .../demcha/compose/document/svg/SvgIcon.java | 5 ----- .../demcha/compose/document/svg/SvgPath.java | 6 ------ .../compose/document/svg/package-info.java | 3 --- .../compose/document/svg/SvgPathTest.java | 2 +- 9 files changed, 20 insertions(+), 29 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 24ffab2be..0b33d552e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,25 @@ follow semantic versioning; release dates are ISO 8601. ## v2.2.1 — Planned +### Public API + +- **The SVG surface graduates from `@Beta` to Stable.** `SvgPath`, `SvgIcon`, + `PathBuilder.svg(svgPath)`, both `addSvgIcon(...)` flow adders, + `ShapeContainerBuilder.path(w, h, svgPath)`, and the gradient paints the + reader emits (`DocumentPaint.LinearAxis` / `RadialCircle`) drop the + annotation and join the Stable tier — additive-only changes in minors from + here on. The surface shipped in 1.8.0 marked `@Beta` "while it hardens + against real-world exporter output"; that hardening is done — the stroke, + colour and unit work, per-element error context, the clip-path support + added in 1.9.0, and the opacity-family + warning pass in this release — + and the API shape itself has not moved since 1.9.0, four minors of real + use. The annotation drop also closes an inconsistency: `inlineSvgIcon` / + `RichText.svgIcon` and the emoji pipeline were built on `@Beta` `SvgIcon` + without carrying the marker themselves; now no SVG entry point does. No + binary or source change for callers — the remaining `@Beta` carriers are + the `NodeDefinition` Extension SPI seam and the PPTX backend, exactly as + [docs/api-stability.md](docs/api-stability.md) lists them. + ### Fixed - **The SVG reader honours the opacity family.** `opacity`, `fill-opacity` and diff --git a/core/src/main/java/com/demcha/compose/document/dsl/AbstractFlowBuilder.java b/core/src/main/java/com/demcha/compose/document/dsl/AbstractFlowBuilder.java index e5aa793db..d0c4911c7 100644 --- a/core/src/main/java/com/demcha/compose/document/dsl/AbstractFlowBuilder.java +++ b/core/src/main/java/com/demcha/compose/document/dsl/AbstractFlowBuilder.java @@ -626,7 +626,6 @@ public T addPath(Consumer spec) { * @return this builder * @since 1.8.0 */ - @com.demcha.compose.document.api.Beta public T addSvgIcon(com.demcha.compose.document.svg.SvgIcon icon, double width) { Objects.requireNonNull(icon, "icon"); return add(icon.node(width)); @@ -643,7 +642,6 @@ public T addSvgIcon(com.demcha.compose.document.svg.SvgIcon icon, double width) * @return this builder * @since 1.8.0 */ - @com.demcha.compose.document.api.Beta public T addSvgIcon(com.demcha.compose.document.svg.SvgIcon icon, double width, com.demcha.compose.document.node.HorizontalAlign align) { Objects.requireNonNull(icon, "icon"); diff --git a/core/src/main/java/com/demcha/compose/document/dsl/PathBuilder.java b/core/src/main/java/com/demcha/compose/document/dsl/PathBuilder.java index 5140620b7..2847c2c9b 100644 --- a/core/src/main/java/com/demcha/compose/document/dsl/PathBuilder.java +++ b/core/src/main/java/com/demcha/compose/document/dsl/PathBuilder.java @@ -1,6 +1,5 @@ package com.demcha.compose.document.dsl; -import com.demcha.compose.document.api.Beta; import com.demcha.compose.document.node.PathNode; import com.demcha.compose.document.style.DocumentColor; import com.demcha.compose.document.style.DocumentDashPattern; @@ -171,7 +170,6 @@ public PathBuilder closePath() { * @return this builder * @since 1.8.0 */ - @Beta public PathBuilder svg(SvgPath svgPath) { Objects.requireNonNull(svgPath, "svgPath"); segments.addAll(svgPath.segments()); diff --git a/core/src/main/java/com/demcha/compose/document/dsl/ShapeContainerBuilder.java b/core/src/main/java/com/demcha/compose/document/dsl/ShapeContainerBuilder.java index f071b551c..619a2e12a 100644 --- a/core/src/main/java/com/demcha/compose/document/dsl/ShapeContainerBuilder.java +++ b/core/src/main/java/com/demcha/compose/document/dsl/ShapeContainerBuilder.java @@ -225,7 +225,6 @@ public ShapeContainerBuilder path(double width, double height, * @return this builder * @since 1.8.0 */ - @com.demcha.compose.document.api.Beta public ShapeContainerBuilder path(double width, double height, com.demcha.compose.document.svg.SvgPath svgPath) { Objects.requireNonNull(svgPath, "svgPath"); diff --git a/core/src/main/java/com/demcha/compose/document/style/DocumentPaint.java b/core/src/main/java/com/demcha/compose/document/style/DocumentPaint.java index 0d8b1863e..0d35fb669 100644 --- a/core/src/main/java/com/demcha/compose/document/style/DocumentPaint.java +++ b/core/src/main/java/com/demcha/compose/document/style/DocumentPaint.java @@ -1,6 +1,5 @@ package com.demcha.compose.document.style; -import com.demcha.compose.document.api.Beta; import java.util.List; import java.util.Objects; @@ -134,9 +133,6 @@ public DocumentColor primaryColor() { * exact: colour runs from the first stop at {@code (x0, y0)} to the last * stop at {@code (x1, y1)} and clamps beyond (pad spread). * - *

Marked {@link Beta} — emitted by the beta SVG gradient reader; the - * endpoint normalization contract may shift while that reader hardens.

- * * @param stops ordered colour stops, offsets in [0,1]; at least two * @param x0 axis start x, normalized to the box width * @param y0 axis start y, normalized to the box height @@ -144,7 +140,6 @@ public DocumentColor primaryColor() { * @param y1 axis end y, normalized to the box height * @since 1.8.0 */ - @Beta record LinearAxis(List stops, double x0, double y0, double x1, double y1) implements DocumentPaint { /** @@ -179,16 +174,12 @@ public DocumentColor primaryColor() { * a circle when the box preserves the source's aspect ratio (the SVG * icon frame contract). Colour clamps beyond the last stop (pad spread). * - *

Marked {@link Beta} — emitted by the beta SVG gradient reader; the - * centre/radius normalization contract may shift while that reader hardens.

- * * @param stops ordered colour stops, offsets in [0,1]; at least two * @param cx centre x, normalized to the box width * @param cy centre y, normalized to the box height * @param r radius as a fraction of the box width; positive * @since 1.8.0 */ - @Beta record RadialCircle(List stops, double cx, double cy, double r) implements DocumentPaint { /** diff --git a/core/src/main/java/com/demcha/compose/document/svg/SvgIcon.java b/core/src/main/java/com/demcha/compose/document/svg/SvgIcon.java index 6d75bd948..f2afa5bae 100644 --- a/core/src/main/java/com/demcha/compose/document/svg/SvgIcon.java +++ b/core/src/main/java/com/demcha/compose/document/svg/SvgIcon.java @@ -1,6 +1,5 @@ package com.demcha.compose.document.svg; -import com.demcha.compose.document.api.Beta; import com.demcha.compose.document.node.LayerStackNode; import com.demcha.compose.document.node.PathNode; import com.demcha.compose.document.style.DocumentColor; @@ -69,13 +68,9 @@ * card.center(logo.node(48)); // node form for layer anchors * } * - *

Beta: the SVG surface is new in 1.8.0 and marked {@link Beta} - * while it hardens against real-world exporter output.

- * * @author Artem Demchyshyn * @since 1.8.0 */ -@Beta public final class SvgIcon { private final List layers; diff --git a/core/src/main/java/com/demcha/compose/document/svg/SvgPath.java b/core/src/main/java/com/demcha/compose/document/svg/SvgPath.java index 813362df2..45caa303f 100644 --- a/core/src/main/java/com/demcha/compose/document/svg/SvgPath.java +++ b/core/src/main/java/com/demcha/compose/document/svg/SvgPath.java @@ -1,6 +1,5 @@ package com.demcha.compose.document.svg; -import com.demcha.compose.document.api.Beta; import com.demcha.compose.document.style.DocumentPathSegment; import java.util.ArrayList; @@ -34,14 +33,9 @@ * .fillColor(crimson)); * } * - *

Beta: the SVG surface is new in 1.8.0 and marked {@link Beta} - * while it hardens against real-world files — the API may still adjust in a - * minor release based on feedback.

- * * @author Artem Demchyshyn * @since 1.8.0 */ -@Beta public final class SvgPath { private static final double EPS = 1e-9; diff --git a/core/src/main/java/com/demcha/compose/document/svg/package-info.java b/core/src/main/java/com/demcha/compose/document/svg/package-info.java index 955d7fd53..7dca20a1a 100644 --- a/core/src/main/java/com/demcha/compose/document/svg/package-info.java +++ b/core/src/main/java/com/demcha/compose/document/svg/package-info.java @@ -8,9 +8,6 @@ * {@code PathBuilder.svg(...)} / {@code PathNode}. Curves render as native * PDF operators; nothing is tessellated.

* - *

Beta: the whole package is marked beta for the 1.8 cycle while - * it hardens against real-world exporter output.

- * * @since 1.8.0 */ package com.demcha.compose.document.svg; diff --git a/core/src/test/java/com/demcha/compose/document/svg/SvgPathTest.java b/core/src/test/java/com/demcha/compose/document/svg/SvgPathTest.java index e90c820a7..17e12caf6 100644 --- a/core/src/test/java/com/demcha/compose/document/svg/SvgPathTest.java +++ b/core/src/test/java/com/demcha/compose/document/svg/SvgPathTest.java @@ -205,7 +205,7 @@ void strayTokenAfterCloseIsRejectedAndDoesNotHang() { // Regression: an operand-less Z/z followed by a non-command token used // to spin forever (the close op consumes no characters, so the scanner // never advanced), appending a close op per iteration until OOM. A - // single malformed/hostile 'd' string would DoS the @Beta reader. + // single malformed/hostile 'd' string would DoS the reader. // Each call must fail fast; the assertTimeout pins that it cannot hang. Assertions.assertTimeoutPreemptively( Duration.ofSeconds(2), () -> {