Skip to content

feat(api): LineBuilder.lineCap — round/square caps and dotted lines#229

Merged
DemchaAV merged 1 commit into
developfrom
feat/line-cap
Jun 25, 2026
Merged

feat(api): LineBuilder.lineCap — round/square caps and dotted lines#229
DemchaAV merged 1 commit into
developfrom
feat/line-cap

Conversation

@DemchaAV

Copy link
Copy Markdown
Owner

Why

LineBuilder could draw dashed lines but not control the stroke end-cap, so a dotted line — round dots, the classic table-of-contents leader / separator — was impossible: a zero-length on-dash renders nothing without a round cap. PathBuilder already had lineCap(...); plain lines did not.

What changed

  • LineBuilder.lineCap(DocumentLineCap) — round / square / butt end-caps for lines, reusing the already-public DocumentLineCap enum (no new type).
  • A lineCap component is threaded through LineNode, LineFragmentPayload, LineDefinition.emitFragments, and PdfLineFragmentRenderHandler (one applyStrokeStyle call, inside the existing save/restore-graphics-state block so the cap never leaks to later strokes) — the same way dashPattern was added in 1.7.0. Back-compat constructors are preserved on both records.
  • The BUTT default emits no cap operator (applyStrokeStyle short-circuits on the PDF default), so existing line output is byte-identical.
  • No lineJoin — a single line segment has no corners, so a join setter would be dead API.

The dotted idiom: line.dashed(0.1, 4).lineCap(DocumentLineCap.ROUND) (a tiny on-dash, because DocumentDashPattern.of rejects a literal zero-length segment).

Lane: canonical public DSL (LineBuilder/LineNode) + shared-engine (payload / definition / render handler).

Verification

  • ./mvnw test -pl . — 1501 tests, 0 failures, 0 visual baselines changed.
  • PdfLineStrokeStyleTest (render-level): ROUND emits the J cap operator with value 1, SQUARE value 2, the BUTT default emits none (byte-identity), and dashed + ROUND emits J 1 (the dotted composition).
  • LineBuilderTest: cap defaults to BUTT, carries into the node, and lineCap(null) resets to BUTT.
  • Runnable LineCapExample (solid / dashed / dotted rules + a thick round-vs-butt comparison) with a committed preview and an examples README row.

@since 1.9.0 on the new public method.

LineBuilder gains lineCap(DocumentLineCap), bringing the round/square
end-caps PathBuilder already exposed to plain lines. Pairing ROUND with a
short dash draws a dotted line — line.dashed(0.1, 4).lineCap(ROUND) renders
round dots, the classic table-of-contents leader/separator.

A lineCap component is threaded through LineNode, LineFragmentPayload,
LineDefinition and PdfLineFragmentRenderHandler the same way dashPattern was;
the BUTT default emits no cap operator (applyStrokeStyle short-circuits), so
existing line output is byte-identical. No lineJoin is added — a single line
segment has no corners.

Verified: ./mvnw test -pl . — 1501 tests, 0 baselines changed.
PdfLineStrokeStyleTest asserts ROUND/SQUARE emit the J operator and BUTT emits
none; a runnable LineCapExample ships with a committed preview.
@DemchaAV DemchaAV merged commit c45623c into develop Jun 25, 2026
11 checks passed
@DemchaAV DemchaAV deleted the feat/line-cap branch June 25, 2026 07:09
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