Skip to content

Commit 0c072f1

Browse files
authored
feat(api): add PageBackgroundFill band factory helpers (#76)
Adds topBand, bottomBand, band, topBandPoints, and bandPoints factory methods for full-width horizontal background bands (top, bottom, or an arbitrary vertical offset; ratio- or point-based), complementing the existing column helpers and building on the v1.6.5 y-coordinate fix. Includes ratio-equality and render-placement tests plus a CHANGELOG entry.
1 parent 747b6c4 commit 0c072f1

3 files changed

Lines changed: 97 additions & 0 deletions

File tree

CHANGELOG.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,14 @@ follow semantic versioning; release dates are ISO 8601.
1212
regression baselines, and reusable `Subheadline` /
1313
`SectionHeader.flatSpacedCaps` widget support.
1414

15+
### Public API
16+
17+
- **`PageBackgroundFill` band helpers.** Added `topBand`, `bottomBand`,
18+
`band`, `topBandPoints`, and `bandPoints` factory methods for full-width
19+
horizontal background bands (top, bottom, or arbitrary vertical offset;
20+
ratio- or point-based), complementing the existing column helpers and
21+
building on the v1.6.5 y-coordinate fix below.
22+
1523
### Bug fixes
1624

1725
- **`PageBackgroundFill` y-coordinate.** A partial-height page-background

src/main/java/com/demcha/compose/document/api/PageBackgroundFill.java

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,13 @@
2121
* column aligned to the right edge.</li>
2222
* <li>{@link #column(double, double, DocumentColor)} — arbitrary
2323
* horizontal slice spanning the full page height.</li>
24+
* <li>{@link #topBand(double, DocumentColor)} /
25+
* {@link #bottomBand(double, DocumentColor)} /
26+
* {@link #band(double, double, DocumentColor)} — full-width
27+
* horizontal bands at the top, bottom, or an arbitrary vertical
28+
* offset (also available in absolute points via
29+
* {@link #topBandPoints(double, double, DocumentColor)} and
30+
* {@link #bandPoints(double, double, double, DocumentColor)}).</li>
2431
* </ul>
2532
*
2633
* <p>Fills supplied to a session are painted at z=0 (below every other
@@ -88,4 +95,41 @@ public static PageBackgroundFill column(double xRatio,
8895
DocumentColor color) {
8996
return new PageBackgroundFill(xRatio, 0.0, widthRatio, 1.0, color);
9097
}
98+
99+
/** Full-width band flush with the top of the page (height = ratio of page height). */
100+
public static PageBackgroundFill topBand(double heightRatio,
101+
DocumentColor color) {
102+
return new PageBackgroundFill(0.0, 0.0, 1.0, heightRatio, color);
103+
}
104+
105+
/** Full-width band flush with the bottom of the page (height = ratio of page height). */
106+
public static PageBackgroundFill bottomBand(double heightRatio,
107+
DocumentColor color) {
108+
return new PageBackgroundFill(0.0, 1.0 - heightRatio, 1.0,
109+
heightRatio, color);
110+
}
111+
112+
/** Full-width band whose top edge sits {@code yRatioFromTop} down the page (0.0 = page top). */
113+
public static PageBackgroundFill band(double yRatioFromTop,
114+
double heightRatio,
115+
DocumentColor color) {
116+
return new PageBackgroundFill(0.0, yRatioFromTop, 1.0,
117+
heightRatio, color);
118+
}
119+
120+
/** Top-aligned band sized in absolute points, converted against {@code pageHeight}. */
121+
public static PageBackgroundFill topBandPoints(double heightPoints,
122+
double pageHeight,
123+
DocumentColor color) {
124+
return topBand(heightPoints / pageHeight, color);
125+
}
126+
127+
/** Band positioned and sized in absolute points from the page top, converted against {@code pageHeight}. */
128+
public static PageBackgroundFill bandPoints(double yFromTopPoints,
129+
double heightPoints,
130+
double pageHeight,
131+
DocumentColor color) {
132+
return band(yFromTopPoints / pageHeight, heightPoints / pageHeight,
133+
color);
134+
}
91135
}

src/test/java/com/demcha/compose/document/api/PageBackgroundTest.java

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -341,6 +341,51 @@ void midPageBandLandsAtCorrectVerticalPosition() {
341341
}
342342
}
343343

344+
// -- Band factory helpers (build on the corrected coordinate model) --
345+
346+
@Test
347+
void bandFactoryHelpersComputeRatiosCorrectly() {
348+
DocumentColor c = DocumentColor.WHITE;
349+
assertThat(PageBackgroundFill.topBand(0.16, c))
350+
.isEqualTo(new PageBackgroundFill(0.0, 0.0, 1.0, 0.16, c));
351+
assertThat(PageBackgroundFill.bottomBand(0.16, c))
352+
.isEqualTo(new PageBackgroundFill(0.0, 0.84, 1.0, 0.16, c));
353+
assertThat(PageBackgroundFill.band(0.4, 0.2, c))
354+
.isEqualTo(new PageBackgroundFill(0.0, 0.4, 1.0, 0.2, c));
355+
assertThat(PageBackgroundFill.topBandPoints(48, 300, c))
356+
.isEqualTo(new PageBackgroundFill(0.0, 0.0, 1.0, 48.0 / 300.0, c));
357+
assertThat(PageBackgroundFill.bandPoints(120, 60, 300, c))
358+
.isEqualTo(new PageBackgroundFill(0.0, 120.0 / 300.0, 1.0, 60.0 / 300.0, c));
359+
}
360+
361+
@Test
362+
void topBandAndBottomBandHelpersRenderAtCorrectEdges() {
363+
DocumentColor fill = DocumentColor.of(Color.DARK_GRAY);
364+
try (DocumentSession session = GraphCompose.document()
365+
.pageSize(400, 300)
366+
.margin(DocumentInsets.zero())
367+
.pageBackgrounds(List.of(
368+
PageBackgroundFill.topBand(0.16, fill),
369+
PageBackgroundFill.bottomBand(0.16, fill)))
370+
.create()) {
371+
372+
session.add(new SpacerNode("Block", 200, 80,
373+
DocumentInsets.zero(), DocumentInsets.zero()));
374+
List<PlacedFragment> bg = session.layoutGraph().fragments().stream()
375+
.filter(this::isPageBackgroundFragment)
376+
.toList();
377+
378+
assertThat(bg).hasSize(2);
379+
// List order: topBand first, bottomBand second.
380+
assertThat(bg.get(0).y()).isCloseTo(252.0, within(EPS)); // top band
381+
assertThat(bg.get(0).height()).isCloseTo(48.0, within(EPS));
382+
assertThat(bg.get(1).y()).isCloseTo(0.0, within(EPS)); // bottom band
383+
assertThat(bg.get(1).height()).isCloseTo(48.0, within(EPS));
384+
} catch (Exception e) {
385+
throw new RuntimeException(e);
386+
}
387+
}
388+
344389
private boolean isPageBackgroundFragment(PlacedFragment fragment) {
345390
return fragment.payload() instanceof ShapeFragmentPayload payload
346391
&& payload.fillColor() != null

0 commit comments

Comments
 (0)