diff --git a/CHANGELOG.md b/CHANGELOG.md index 495e2602e..6efbb6ad9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -90,7 +90,10 @@ Entries land here as they merge. mask under `ClipPolicy.CLIP_PATH`. The outline rides the existing vector-path fragment pipeline (one source of truth for native curves) and the clip handler emits the same `addPathSegments` geometry, so fill, clip, - and `addPath(...)` all agree. + and `addPath(...)` all agree. The new `Path` permit is additive and keeps + the artifact binary-compatible (the `japicmp` gate stays green); only + consumer code that exhaustively `switch`es over `ShapeOutline` would need a + new branch, and the canonical authoring surface exposes no such switch. - **SVG path import** (`@since 1.8.0`, **beta** — annotated `@Beta` while the surface hardens against real-world exporter output). `SvgPath.parse(d)` / `parse(d, viewBox...)` in the new `document.svg` package lowers the full @@ -271,6 +274,16 @@ Entries land here as they merge. ### Documentation +- **Contract-drift Javadoc fixes on the new 1.8 surface.** `LegendPosition` + no longer claims `RIGHT`/`TOP` are "reserved and rejected by validation" — + all four placements are laid out for every chart kind, as the resolver and + its tests already prove. `DocumentPaint` documents why the `Linear`/`Radial` + (angle/corner-reaching) and `LinearAxis`/`RadialCircle` (exact endpoint/radius) + forms coexist. `ShapeContainerBuilder`'s missing-outline error and class + Javadoc now name the full set of outline setters (including `path`). + `PathBuilder.dashed(double...)` documents the `IllegalArgumentException` it + throws eagerly, and `SvgIcon` documents that a gradient `href` inherits stops + only, not geometry attributes. - **Browsable feature-catalog PDF.** New flagship `FeatureCatalogExample` renders every shipped capability as a self-documenting block: the heading lands in the PDF outline (the bookmarks panel works as a clickable index), diff --git a/src/main/java/com/demcha/compose/document/chart/LegendPosition.java b/src/main/java/com/demcha/compose/document/chart/LegendPosition.java index f1d1e6f8f..dae0e0807 100644 --- a/src/main/java/com/demcha/compose/document/chart/LegendPosition.java +++ b/src/main/java/com/demcha/compose/document/chart/LegendPosition.java @@ -3,10 +3,10 @@ /** * Placement of the series legend relative to the plot area. * - *
v1 of the geometry resolver supports {@link #NONE} and {@link #BOTTOM}; the - * remaining placements are reserved and rejected by validation until the - * corresponding layout lands. Adding resolver support for a reserved constant is - * an additive, non-breaking change.
+ *All four placements are laid out by the geometry resolver for every chart + * kind, including pie: {@link #NONE}, {@link #BOTTOM} (a row below the plot), + * {@link #TOP} (a row above), and {@link #RIGHT} (a column beside it). The + * resolver reserves the corresponding gutter and packs the entries to fit.
* * @author Artem Demchyshyn * @since 1.8.0 @@ -21,11 +21,11 @@ public enum LegendPosition { */ BOTTOM, /** - * Reserved — legend column to the right of the plot area. + * Legend column to the right of the plot area. */ RIGHT, /** - * Reserved — single legend row above the plot area. + * Single legend row above the plot area. */ TOP } diff --git a/src/main/java/com/demcha/compose/document/dsl/PathBuilder.java b/src/main/java/com/demcha/compose/document/dsl/PathBuilder.java index 1183e85d7..5140620b7 100644 --- a/src/main/java/com/demcha/compose/document/dsl/PathBuilder.java +++ b/src/main/java/com/demcha/compose/document/dsl/PathBuilder.java @@ -241,10 +241,15 @@ public PathBuilder strokePaint(DocumentPaint strokePaint) { /** * Makes the stroke dashed using alternating on/off lengths in points * (the same contract as {@code LineBuilder.dashed}). Affects only the - * stroke; fills are unaffected. + * stroke; fills are unaffected. Validates eagerly: an empty or + * non-finite/non-positive pattern is rejected at this call, not at + * {@link #build()}. * * @param pattern alternating on/off lengths in points * @return this builder + * @throws IllegalArgumentException if no segments are supplied or any + * segment is not finite and strictly + * positive */ public PathBuilder dashed(double... pattern) { this.dashPattern = DocumentDashPattern.of(pattern); diff --git a/src/main/java/com/demcha/compose/document/dsl/ShapeContainerBuilder.java b/src/main/java/com/demcha/compose/document/dsl/ShapeContainerBuilder.java index 3d4b25b05..f071b551c 100644 --- a/src/main/java/com/demcha/compose/document/dsl/ShapeContainerBuilder.java +++ b/src/main/java/com/demcha/compose/document/dsl/ShapeContainerBuilder.java @@ -15,11 +15,13 @@ * Builder for {@link ShapeContainerNode}. * *Reads as: "container is a [shape], inside it I'm composing layers". - * The outline is mandatory — call {@link #rectangle(double, double)}, - * {@link #roundedRect(double, double, double)}, {@link #ellipse(double, double)}, - * or {@link #circle(double)} before {@link #build()}. Layers are appended in - * source order (first behind, last in front) and each layer carries one of the - * nine {@link LayerAlign} anchors plus optional on-screen offset.
+ * The outline is mandatory — call one of the outline setters + * ({@link #rectangle(double, double)}, {@link #roundedRect(double, double, double)}, + * {@link #ellipse(double, double)}, {@link #circle(double)}, a polygon factory, + * or {@link #path(double, double, java.util.List)}) before {@link #build()}. + * Layers are appended in source order (first behind, last in front) and each + * layer carries one of the nine {@link LayerAlign} anchors plus optional + * on-screen offset. * * @author Artem Demchyshyn * @since 1.0.0 @@ -541,8 +543,8 @@ public ShapeContainerBuilder bottomRight(DocumentNode node) { public ShapeContainerNode build() { if (outline == null) { throw new IllegalStateException( - "ShapeContainerBuilder '" + name + "' requires an outline; " - + "call rectangle/roundedRect/ellipse/circle before build()."); + "ShapeContainerBuilder '" + name + "' requires an outline; call an outline " + + "setter (rectangle/roundedRect/ellipse/circle/polygon/path/...) before build()."); } return new ShapeContainerNode(name, outline, layers, clipPolicy, fillColor, stroke, padding, margin, transform); } diff --git a/src/main/java/com/demcha/compose/document/style/DocumentPaint.java b/src/main/java/com/demcha/compose/document/style/DocumentPaint.java index 23a57a86d..1810f2eb0 100644 --- a/src/main/java/com/demcha/compose/document/style/DocumentPaint.java +++ b/src/main/java/com/demcha/compose/document/style/DocumentPaint.java @@ -9,10 +9,18 @@ * single paint vocabulary every fillable surface shares — chart palettes * today, shape and panel fills as they adopt the {@code fillPaint} component. * - *Backend contract: the PDF backend renders {@link Linear} and - * {@link Radial} as native axial / radial shadings; a backend (or surface) - * that cannot paint a gradient degrades to {@link #primaryColor()} — the - * first stop — so authoring code never branches per backend.
+ *Backend contract: the PDF backend renders all gradient forms as native + * axial / radial shadings; a backend (or surface) that cannot paint a gradient + * degrades to {@link #primaryColor()} — the first stop — so authoring code + * never branches per backend.
+ * + *Two ways to spell each gradient coexist by design, not by redundancy. + * {@link Linear} / {@link Radial} take an ergonomic angle / corner-reaching + * geometry and are the chart- and shape-authoring forms; {@link LinearAxis} / + * {@link RadialCircle} take exact endpoints / a radius in the unit box and are + * the forms the SVG reader emits to reproduce a source gradient verbatim. All + * four render through the same shading machinery and degrade to the same + * {@link #primaryColor()}.
* * @author Artem Demchyshyn * @since 1.8.0 diff --git a/src/main/java/com/demcha/compose/document/svg/SvgIcon.java b/src/main/java/com/demcha/compose/document/svg/SvgIcon.java index a124707e7..31c36d6cd 100644 --- a/src/main/java/com/demcha/compose/document/svg/SvgIcon.java +++ b/src/main/java/com/demcha/compose/document/svg/SvgIcon.java @@ -42,9 +42,13 @@ * {@code