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,
|
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()
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -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))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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);
|
||||||
}
|
}
|
||||||
|
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 ---
|
--- 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]))
|
||||||
|
Loading…
x
Reference in New Issue
Block a user