mirror of
https://github.com/typst/typst
synced 2025-05-14 04:56:26 +08:00
Allow unbreakable multi-layouters to expand (#5162)
This commit is contained in:
parent
fc5858c982
commit
b7725a7442
@ -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()
|
||||
}
|
||||
};
|
||||
|
@ -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))
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
}
|
||||
|
BIN
tests/ref/issue-5160-unbreakable-pad.png
Normal file
BIN
tests/ref/issue-5160-unbreakable-pad.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 145 B |
@ -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]))
|
||||
|
Loading…
x
Reference in New Issue
Block a user