diff options
| author | Laurenz <laurmaedje@gmail.com> | 2024-10-08 15:13:14 +0200 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2024-10-08 13:13:14 +0000 |
| commit | fc5858c98256b32eca798a0df1bf96f426416bd2 (patch) | |
| tree | 732716b713c5e098babbc13e988914a5fdfef4b6 | |
| parent | 7a96c86487fe2eb35d88bd8314b26feec6118898 (diff) | |
Allow sticky blocks to be breakable (#5161)
| -rw-r--r-- | crates/typst/src/layout/container.rs | 2 | ||||
| -rw-r--r-- | crates/typst/src/layout/flow/collect.rs | 4 | ||||
| -rw-r--r-- | crates/typst/src/layout/flow/distribute.rs | 8 | ||||
| -rw-r--r-- | tests/ref/block-sticky-breakable.png | bin | 0 -> 405 bytes | |||
| -rw-r--r-- | tests/suite/layout/container.typ | 6 |
5 files changed, 13 insertions, 7 deletions
diff --git a/crates/typst/src/layout/container.rs b/crates/typst/src/layout/container.rs index 996ef6c9..9fdef0be 100644 --- a/crates/typst/src/layout/container.rs +++ b/crates/typst/src/layout/container.rs @@ -422,8 +422,6 @@ pub struct BlockElem { /// This is, by default, set on heading blocks to prevent orphaned headings /// at the bottom of the page. /// - /// Marking a block as sticky makes it unbreakable. - /// /// ```example /// >>> #set page(height: 140pt) /// // Disable stickiness of headings. diff --git a/crates/typst/src/layout/flow/collect.rs b/crates/typst/src/layout/flow/collect.rs index 9fc64f06..a477c334 100644 --- a/crates/typst/src/layout/flow/collect.rs +++ b/crates/typst/src/layout/flow/collect.rs @@ -189,7 +189,7 @@ impl<'a> Collector<'a, '_, '_> { self.output.push(spacing(elem.above(styles))); - if !breakable || sticky || fr.is_some() { + if !breakable || fr.is_some() { self.output.push(Child::Single(self.boxed(SingleChild { align, sticky, @@ -203,6 +203,7 @@ impl<'a> Collector<'a, '_, '_> { let alone = self.children.len() == 1; self.output.push(Child::Multi(self.boxed(MultiChild { align, + sticky, alone, elem, styles, @@ -375,6 +376,7 @@ fn layout_single_impl( #[derive(Debug)] pub struct MultiChild<'a> { pub align: Axes<FixedAlignment>, + pub sticky: bool, alone: bool, elem: &'a Packed<BlockElem>, styles: StyleChain<'a>, diff --git a/crates/typst/src/layout/flow/distribute.rs b/crates/typst/src/layout/flow/distribute.rs index 65516ccd..a30b71ba 100644 --- a/crates/typst/src/layout/flow/distribute.rs +++ b/crates/typst/src/layout/flow/distribute.rs @@ -247,7 +247,7 @@ impl<'a, 'b> Distributor<'a, 'b, '_, '_, '_> { // Lay out the block. let (frame, spill) = multi.layout(self.composer.engine, self.regions)?; - self.frame(frame, multi.align, false, true)?; + self.frame(frame, multi.align, multi.sticky, true)?; // If the block didn't fully fit into the current region, save it into // the `spill` and finish the region. @@ -292,9 +292,9 @@ impl<'a, 'b> Distributor<'a, 'b, '_, '_, '_> { breakable: bool, ) -> FlowResult<()> { if sticky { - // If the frame is sticky and we haven't remember a preceding sticky - // element, make a checkpoint which we can restore should we end on - // this sticky element. + // If the frame is sticky and we haven't remembered a preceding + // sticky element, make a checkpoint which we can restore should we + // end on this sticky element. if self.stickable && self.sticky.is_none() { self.sticky = Some(self.snapshot()); } diff --git a/tests/ref/block-sticky-breakable.png b/tests/ref/block-sticky-breakable.png Binary files differnew file mode 100644 index 00000000..91287a7e --- /dev/null +++ b/tests/ref/block-sticky-breakable.png diff --git a/tests/suite/layout/container.typ b/tests/suite/layout/container.typ index d054175a..e1367967 100644 --- a/tests/suite/layout/container.typ +++ b/tests/suite/layout/container.typ @@ -180,6 +180,12 @@ A #colbreak() C +--- block-sticky-breakable --- +// Ensure that sticky blocks are still breakable. +#set page(height: 60pt) +#block(sticky: true, lines(4)) +E + --- box-clip-rect --- // Test box clipping with a rectangle Hello #box(width: 1em, height: 1em, clip: false)[#rect(width: 3em, height: 3em, fill: red)] |
