Allow unbreakable multi-layouters to expand (#5162)

This commit is contained in:
Laurenz 2024-10-08 17:55:44 +02:00 committed by GitHub
parent fc5858c982
commit b7725a7442
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
5 changed files with 24 additions and 11 deletions

View File

@ -487,7 +487,7 @@ impl Packed<BlockElem> {
engine: &mut Engine, engine: &mut Engine,
locator: Locator, locator: Locator,
styles: StyleChain, styles: StyleChain,
base: Size, region: Region,
) -> SourceResult<Frame> { ) -> SourceResult<Frame> {
// Fetch sizing properties. // Fetch sizing properties.
let width = self.width(styles); let width = self.width(styles);
@ -495,7 +495,7 @@ impl Packed<BlockElem> {
let inset = self.inset(styles).unwrap_or_default(); let inset = self.inset(styles).unwrap_or_default();
// Build the pod regions. // 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. // Layout the body.
let body = self.body(styles); 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, // If we have a child that wants to layout with full region access,
// we layout it. // we layout it.
Some(BlockBody::MultiLayouter(callback)) => { 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() callback.call(engine, locator, styles, pod.into())?.into_frame()
} }
}; };

View File

@ -173,6 +173,7 @@ impl<'a> Collector<'a, '_, '_> {
fn block(&mut self, elem: &'a Packed<BlockElem>, styles: StyleChain<'a>) { fn block(&mut self, elem: &'a Packed<BlockElem>, styles: StyleChain<'a>) {
let locator = self.locator.next(&elem.span()); let locator = self.locator.next(&elem.span());
let align = AlignElem::alignment_in(styles).resolve(styles); let align = AlignElem::alignment_in(styles).resolve(styles);
let alone = self.children.len() == 1;
let sticky = elem.sticky(styles); let sticky = elem.sticky(styles);
let breakable = elem.breakable(styles); let breakable = elem.breakable(styles);
let fr = match elem.height(styles) { let fr = match elem.height(styles) {
@ -193,6 +194,7 @@ impl<'a> Collector<'a, '_, '_> {
self.output.push(Child::Single(self.boxed(SingleChild { self.output.push(Child::Single(self.boxed(SingleChild {
align, align,
sticky, sticky,
alone,
fr, fr,
elem, elem,
styles, styles,
@ -200,7 +202,6 @@ impl<'a> Collector<'a, '_, '_> {
cell: CachedCell::new(), cell: CachedCell::new(),
}))); })));
} else { } else {
let alone = self.children.len() == 1;
self.output.push(Child::Multi(self.boxed(MultiChild { self.output.push(Child::Multi(self.boxed(MultiChild {
align, align,
sticky, sticky,
@ -318,6 +319,7 @@ pub struct LineChild {
pub struct SingleChild<'a> { pub struct SingleChild<'a> {
pub align: Axes<FixedAlignment>, pub align: Axes<FixedAlignment>,
pub sticky: bool, pub sticky: bool,
pub alone: bool,
pub fr: Option<Fr>, pub fr: Option<Fr>,
elem: &'a Packed<BlockElem>, elem: &'a Packed<BlockElem>,
styles: StyleChain<'a>, styles: StyleChain<'a>,
@ -327,8 +329,10 @@ pub struct SingleChild<'a> {
impl SingleChild<'_> { impl SingleChild<'_> {
/// Build the child's frame given the region's base size. /// Build the child's frame given the region's base size.
pub fn layout(&self, engine: &mut Engine, base: Size) -> SourceResult<Frame> { pub fn layout(&self, engine: &mut Engine, region: Region) -> SourceResult<Frame> {
self.cell.get_or_init(base, |base| { 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( layout_single_impl(
engine.world, engine.world,
engine.introspector, engine.introspector,
@ -338,7 +342,7 @@ impl SingleChild<'_> {
self.elem, self.elem,
self.locator.track(), self.locator.track(),
self.styles, self.styles,
base, region,
) )
}) })
} }
@ -356,7 +360,7 @@ fn layout_single_impl(
elem: &Packed<BlockElem>, elem: &Packed<BlockElem>,
locator: Tracked<Locator>, locator: Tracked<Locator>,
styles: StyleChain, styles: StyleChain,
base: Size, region: Region,
) -> SourceResult<Frame> { ) -> SourceResult<Frame> {
let link = LocatorLink::new(locator); let link = LocatorLink::new(locator);
let locator = Locator::link(&link); let locator = Locator::link(&link);
@ -368,7 +372,7 @@ fn layout_single_impl(
route: Route::extend(route), 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)) .map(|frame| frame.post_processed(styles))
} }

View File

@ -226,7 +226,10 @@ impl<'a, 'b> Distributor<'a, 'b, '_, '_, '_> {
} }
// Lay out the block. // 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, // If the block doesn't fit and a followup region may improve things,
// finish the region. // finish the region.
@ -422,8 +425,8 @@ impl<'a, 'b> Distributor<'a, 'b, '_, '_, '_> {
for item in &self.items { for item in &self.items {
let Item::Fr(v, Some(single)) = item else { continue }; let Item::Fr(v, Some(single)) = item else { continue };
let length = v.share(frs, fr_space); let length = v.share(frs, fr_space);
let base = Size::new(region.size.x, length); let pod = Region::new(Size::new(region.size.x, length), region.expand);
let frame = single.layout(self.composer.engine, base)?; let frame = single.layout(self.composer.engine, pod)?;
used.x.set_max(frame.width()); used.x.set_max(frame.width());
fr_frames.push(frame); fr_frames.push(frame);
} }

Binary file not shown.

After

Width:  |  Height:  |  Size: 145 B

View File

@ -32,3 +32,7 @@ Hi #box(pad(left: 10pt)[A]) there
--- issue-5044-pad-100-percent --- --- issue-5044-pad-100-percent ---
#set page(width: 30pt, height: 30pt) #set page(width: 30pt, height: 30pt)
#pad(100%, block(width: 1cm, height: 1cm, fill: red)) #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]))