Skip to content

feat(style): gradient fills - Series A (DocumentPaint shadings)#157

Merged
DemchaAV merged 3 commits into
developfrom
feat/v1.8-gradients
Jun 11, 2026
Merged

feat(style): gradient fills - Series A (DocumentPaint shadings)#157
DemchaAV merged 3 commits into
developfrom
feat/v1.8-gradients

Conversation

@DemchaAV

Copy link
Copy Markdown
Owner

Summary

Series A of the design-engine roadmap: gradients become real, with the paint abstraction designed for reuse across every fillable surface.

The abstraction contract (the point of this series):

DocumentPaint (document.style — neutral, serializable, sealed Solid|Linear|Radial)
  → ShapeNode.fillPaint  (ShapeBuilder.fill(paint); wins over fillColor)
  → ShapeFragmentPayload (layout, @Internal — carries the paint untouched)
  → backend interprets   (PDF: native shadings · others: primaryColor() fallback)

No backend type leaks upward; weak backends degrade by the paint type's own documented contract. The same fillPaint component is ready for PolygonNode/EllipseNode/page backgrounds without new concepts.

Commits

  1. A1 — type graduation (de84e61b): DocumentPaint moves document.chartdocument.style (pre-release, no bridge). Zero behaviour change, suite green unchanged.
  2. A2+A3 — shadings (047e24aa): Linear → axial /ShadingType 2 along the paint angle (0°=left→right, 90°=bottom→top; 2 stops exponential, n stops stitched), Radial/ShadingType 3 to the farthest corner; gradient fill clips to the shape path (rounded corners included) in a nested graphics state so strokes are unaffected. Byte-identity is structural: solid paints normalise to the plain fill-colour path at emission — pinned by solidPaintEmitsNoShadingResources alongside axial/radial/multi-stop tests.
  3. A5 + hero (46327269): chart bars carry their full series paint (gradient palettes finally render as gradients); BusinessReportExample drops its last raster — the Graphics2D sunset becomes a native canvas scene (3-stop gradient-sky shape + two polygon ranges, far one translucent), zero AWT imports left.

Testing

Full suite green: 1190 tests, 0 failures. Angle semantics, multi-stop stitching, radial centring and rounded-corner clipping verified visually at render; demo panels and the regenerated flagship PDF included in the dev loop.

DemchaAV added 3 commits June 11, 2026 08:42
…ent.style

The paint vocabulary (sealed Solid | Linear | Radial with colour stops) is
not chart-specific - it is the shared fill type every fillable surface will
use. Pre-release move (the v1.8.0 cycle is unreleased), so no deprecation
bridge: chart classes, tests, examples re-import from document.style. The
javadoc drops the 'lives in the chart package for now' note and states the
backend contract instead: gradient-capable backends paint shadings, others
degrade to primaryColor(). Zero behaviour change - full suite green
unchanged.
…DF shadings

ShapeNode gains an optional fillPaint component (ShapeBuilder.fill(paint));
when set it wins over fillColor. The abstraction contract holds end to end:
the neutral DocumentPaint travels through ShapeFragmentPayload, and only
the PDF backend interprets it - Linear maps to an axial /ShadingType 2
whose axis crosses the box centre along the paint angle (0=left-to-right,
90=bottom-to-top), Radial to /ShadingType 3 reaching the farthest corner;
two stops become one exponential function, more stops a stitching function.
The gradient fill clips to the shape path (rounded corners included) inside
a nested graphics state so strokes are unaffected.

Byte-identity is structural: solid paints are normalised to a plain fill
colour at emission, so existing documents and DocumentPaint.solid(...)
produce the exact pre-gradient operator stream - pinned by the
solidPaintEmitsNoShadingResources test alongside axial/radial/multi-stop
coverage. Backends without shading support keep the documented
primaryColor() fallback.
…lly vector

Chart bars (vertical and horizontal, grouped and stacked) now carry the
complete DocumentPaint from the style cascade through ShapeNode.fillPaint
instead of degrading to primaryColor() - a gradient palette finally renders
as gradients. Markers and legend swatches intentionally keep the primary
colour (gradient ink at swatch size is noise).

BusinessReportExample drops its last raster: the Graphics2D sunset
(GradientPaint sky + two awt Polygons encoded to PNG) is replaced by a
native CanvasLayerNode scene - a gradient-sky ShapeNode (three-stop linear,
90 degrees) under two PolygonNode mountain ranges, the distant one
translucent via rgba - clipped to the same rounded gold-stroked frame. The
example now has zero AWT imports and renders crisp at any zoom.
@DemchaAV DemchaAV merged commit 0aa9a4a into develop Jun 11, 2026
11 checks passed
@DemchaAV DemchaAV deleted the feat/v1.8-gradients branch June 11, 2026 08:05
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant