From a7d86dea76e381d50bddf9d7d1b59a3ebb132a68 Mon Sep 17 00:00:00 2001
From: Eric Kaden <608341+EricKaden@users.noreply.github.com>
Date: Fri, 23 Oct 2026 22:05:46 -0400
Subject: [PATCH] M12: a flowed subform's last part keeps its bottom margin
inside the content area
---
crates/xfa/src/layout.rs | 5 ++++-
crates/xfa/src/tests.rs | 7 +++++++
2 files changed, 11 insertions(+), 1 deletion(-)
diff --git a/crates/xfa/src/layout.rs b/crates/xfa/src/layout.rs
index 39841c469..a5dd72a79 100644
--- a/crates/xfa/src/layout.rs
+++ b/crates/xfa/src/layout.rs
@@ -691,7 +691,10 @@ impl Layouter<'_> {
if b.fill().is_none() && b.visible_edges() == [false; 4] {
return Ok(());
}
- let (_, end, _) = self.cursor();
+ let (area, end, _) = self.cursor();
+ // The bottom margin stays in the content area, as at a break; content that itself runs
+ // past it keeps the border round it.
+ let end = end.min(area.bottom()).max(end - f.margin.bottom);
let page = self.pages.len().saturating_sub(1);
if !self.on_area(&f.part) {
f.lost = true;
diff --git a/crates/xfa/src/tests.rs b/crates/xfa/src/tests.rs
index aabfe175d..f20bb94ee 100644
--- a/crates/xfa/src/tests.rs
+++ b/crates/xfa/src/tests.rs
@@ -2096,6 +2096,13 @@ fn a_flowed_subform_is_drawn_with_its_border_under_its_content() {
let f19 = form.pages[1].items.iter().find_map(|i| if let Item::Widget(w) = i { (w.name == "f19").then_some(w.rect) } else { None }).unwrap();
assert!((f19.y - 43.2).abs() < 0.01, "the second part starts after the top margin: {}", f19.y);
assert!(form.warnings.is_empty(), "{:?}", form.warnings);
+ // A bottom margin that would run past the content area stops at its edge: 39 quarter-inch
+ // fields end at 738, and 0.4in more would reach 766.8, past 756.
+ let quarter: String = (0..39).map(|i| format!(r#""#)).collect();
+ let low = format!(r#"{quarter}"#);
+ let form = lay(&low);
+ let edge = form.pages[0].items.iter().find_map(|i| if let Item::Fill { rect, .. } = i { Some(rect.bottom()) } else { None }).unwrap();
+ assert!((edge - 756.0).abs() < 0.01, "the box ends at the content area's bottom: {edge}");
// The margins come back without a border too.
let bare = format!(r#"{many}"#);
let form = lay(&bare);