summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--crates/typst/src/layout/container.rs2
-rw-r--r--crates/typst/src/layout/flow/collect.rs4
-rw-r--r--crates/typst/src/layout/flow/distribute.rs8
-rw-r--r--tests/ref/block-sticky-breakable.pngbin0 -> 405 bytes
-rw-r--r--tests/suite/layout/container.typ6
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
new file mode 100644
index 00000000..91287a7e
--- /dev/null
+++ b/tests/ref/block-sticky-breakable.png
Binary files differ
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)]