summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--crates/typst/src/layout/container.rs6
-rw-r--r--crates/typst/src/layout/flow/collect.rs16
-rw-r--r--crates/typst/src/layout/flow/distribute.rs9
-rw-r--r--tests/ref/issue-5160-unbreakable-pad.pngbin0 -> 145 bytes
-rw-r--r--tests/suite/layout/pad.typ4
5 files changed, 24 insertions, 11 deletions
diff --git a/crates/typst/src/layout/container.rs b/crates/typst/src/layout/container.rs
index 9fdef0be..cc1559c6 100644
--- a/crates/typst/src/layout/container.rs
+++ b/crates/typst/src/layout/container.rs
@@ -487,7 +487,7 @@ impl Packed<BlockElem> {
engine: &mut Engine,
locator: Locator,
styles: StyleChain,
- base: Size,
+ region: Region,
) -> SourceResult<Frame> {
// Fetch sizing properties.
let width = self.width(styles);
@@ -495,7 +495,7 @@ impl Packed<BlockElem> {
let inset = self.inset(styles).unwrap_or_default();
// Build the pod regions.
- let pod = unbreakable_pod(&width.into(), &height, &inset, styles, base);
+ let pod = unbreakable_pod(&width.into(), &height, &inset, styles, region.size);
// Layout the body.
let body = self.body(styles);
@@ -518,6 +518,8 @@ impl Packed<BlockElem> {
// If we have a child that wants to layout with full region access,
// we layout it.
Some(BlockBody::MultiLayouter(callback)) => {
+ let expand = (pod.expand | region.expand) & pod.size.map(Abs::is_finite);
+ let pod = Region { expand, ..pod };
callback.call(engine, locator, styles, pod.into())?.into_frame()
}
};
diff --git a/crates/typst/src/layout/flow/collect.rs b/crates/typst/src/layout/flow/collect.rs
index a477c334..efb16427 100644
--- a/crates/typst/src/layout/flow/collect.rs
+++ b/crates/typst/src/layout/flow/collect.rs
@@ -173,6 +173,7 @@ impl<'a> Collector<'a, '_, '_> {
fn block(&mut self, elem: &'a Packed<BlockElem>, styles: StyleChain<'a>) {
let locator = self.locator.next(&elem.span());
let align = AlignElem::alignment_in(styles).resolve(styles);
+ let alone = self.children.len() == 1;
let sticky = elem.sticky(styles);
let breakable = elem.breakable(styles);
let fr = match elem.height(styles) {
@@ -193,6 +194,7 @@ impl<'a> Collector<'a, '_, '_> {
self.output.push(Child::Single(self.boxed(SingleChild {
align,
sticky,
+ alone,
fr,
elem,
styles,
@@ -200,7 +202,6 @@ impl<'a> Collector<'a, '_, '_> {
cell: CachedCell::new(),
})));
} else {
- let alone = self.children.len() == 1;
self.output.push(Child::Multi(self.boxed(MultiChild {
align,
sticky,
@@ -318,6 +319,7 @@ pub struct LineChild {
pub struct SingleChild<'a> {
pub align: Axes<FixedAlignment>,
pub sticky: bool,
+ pub alone: bool,
pub fr: Option<Fr>,
elem: &'a Packed<BlockElem>,
styles: StyleChain<'a>,
@@ -327,8 +329,10 @@ pub struct SingleChild<'a> {
impl SingleChild<'_> {
/// Build the child's frame given the region's base size.
- pub fn layout(&self, engine: &mut Engine, base: Size) -> SourceResult<Frame> {
- self.cell.get_or_init(base, |base| {
+ pub fn layout(&self, engine: &mut Engine, region: Region) -> SourceResult<Frame> {
+ self.cell.get_or_init(region, |mut region| {
+ // Vertical expansion is only kept if this block is the only child.
+ region.expand.y &= self.alone;
layout_single_impl(
engine.world,
engine.introspector,
@@ -338,7 +342,7 @@ impl SingleChild<'_> {
self.elem,
self.locator.track(),
self.styles,
- base,
+ region,
)
})
}
@@ -356,7 +360,7 @@ fn layout_single_impl(
elem: &Packed<BlockElem>,
locator: Tracked<Locator>,
styles: StyleChain,
- base: Size,
+ region: Region,
) -> SourceResult<Frame> {
let link = LocatorLink::new(locator);
let locator = Locator::link(&link);
@@ -368,7 +372,7 @@ fn layout_single_impl(
route: Route::extend(route),
};
- elem.layout_single(&mut engine, locator, styles, base)
+ elem.layout_single(&mut engine, locator, styles, region)
.map(|frame| frame.post_processed(styles))
}
diff --git a/crates/typst/src/layout/flow/distribute.rs b/crates/typst/src/layout/flow/distribute.rs
index a30b71ba..a738b3e6 100644
--- a/crates/typst/src/layout/flow/distribute.rs
+++ b/crates/typst/src/layout/flow/distribute.rs
@@ -226,7 +226,10 @@ impl<'a, 'b> Distributor<'a, 'b, '_, '_, '_> {
}
// Lay out the block.
- let frame = single.layout(self.composer.engine, self.regions.base())?;
+ let frame = single.layout(
+ self.composer.engine,
+ Region::new(self.regions.base(), self.regions.expand),
+ )?;
// If the block doesn't fit and a followup region may improve things,
// finish the region.
@@ -422,8 +425,8 @@ impl<'a, 'b> Distributor<'a, 'b, '_, '_, '_> {
for item in &self.items {
let Item::Fr(v, Some(single)) = item else { continue };
let length = v.share(frs, fr_space);
- let base = Size::new(region.size.x, length);
- let frame = single.layout(self.composer.engine, base)?;
+ let pod = Region::new(Size::new(region.size.x, length), region.expand);
+ let frame = single.layout(self.composer.engine, pod)?;
used.x.set_max(frame.width());
fr_frames.push(frame);
}
diff --git a/tests/ref/issue-5160-unbreakable-pad.png b/tests/ref/issue-5160-unbreakable-pad.png
new file mode 100644
index 00000000..f370870a
--- /dev/null
+++ b/tests/ref/issue-5160-unbreakable-pad.png
Binary files differ
diff --git a/tests/suite/layout/pad.typ b/tests/suite/layout/pad.typ
index 4ff9f8ec..e9830cf7 100644
--- a/tests/suite/layout/pad.typ
+++ b/tests/suite/layout/pad.typ
@@ -32,3 +32,7 @@ Hi #box(pad(left: 10pt)[A]) there
--- issue-5044-pad-100-percent ---
#set page(width: 30pt, height: 30pt)
#pad(100%, block(width: 1cm, height: 1cm, fill: red))
+
+--- issue-5160-unbreakable-pad ---
+#set block(breakable: false)
+#block(width: 100%, pad(x: 20pt, align(right)[A]))