From ae31640c0a62d26b7f2a7a38579293ae48c7c7b7 Mon Sep 17 00:00:00 2001 From: Laurenz Date: Tue, 27 Feb 2024 13:34:26 +0100 Subject: [PATCH] Fix out-of-order floats (#3506) --- crates/typst/src/layout/flow.rs | 10 ++++++---- crates/typst/src/layout/place.rs | 5 ++--- tests/ref/bugs/2715-float-order.png | Bin 0 -> 12944 bytes tests/typ/bugs/2715-float-order.typ | 19 +++++++++++++++++++ 4 files changed, 27 insertions(+), 7 deletions(-) create mode 100644 tests/ref/bugs/2715-float-order.png create mode 100644 tests/typ/bugs/2715-float-order.typ diff --git a/crates/typst/src/layout/flow.rs b/crates/typst/src/layout/flow.rs index 003c9db7d..8701d35d9 100644 --- a/crates/typst/src/layout/flow.rs +++ b/crates/typst/src/layout/flow.rs @@ -312,7 +312,7 @@ impl<'a> FlowLayouter<'a> { align.x().unwrap_or_default().resolve(styles) }); let y_align = alignment.map(|align| align.y().map(|y| y.resolve(styles))); - let mut frame = placed.layout(engine, styles, self.regions)?.into_frame(); + let mut frame = placed.layout(engine, styles, self.regions.base())?.into_frame(); frame.meta(styles, false); let item = FlowItem::Placed { frame, x_align, y_align, delta, float, clearance }; self.layout_item(engine, item) @@ -427,9 +427,11 @@ impl<'a> FlowLayouter<'a> { clearance, .. } => { - // If the float doesn't fit, queue it for the next region. - if !self.regions.size.y.fits(frame.height() + clearance) - && !self.regions.in_last() + // If there is a queued float in front or if the float doesn't + // fit, queue it for the next region. + if !self.pending_floats.is_empty() + || (!self.regions.size.y.fits(frame.height() + clearance) + && !self.regions.in_last()) { self.pending_floats.push(item); return Ok(()); diff --git a/crates/typst/src/layout/place.rs b/crates/typst/src/layout/place.rs index b29060244..61b07308d 100644 --- a/crates/typst/src/layout/place.rs +++ b/crates/typst/src/layout/place.rs @@ -2,7 +2,7 @@ use crate::diag::{bail, At, Hint, SourceResult}; use crate::engine::Engine; use crate::foundations::{elem, Content, Packed, Smart, StyleChain}; use crate::layout::{ - Alignment, Axes, Em, Fragment, LayoutMultiple, Length, Regions, Rel, VAlignment, + Alignment, Axes, Em, Fragment, LayoutMultiple, Length, Regions, Rel, Size, VAlignment, }; use crate::realize::{Behave, Behaviour}; @@ -93,11 +93,10 @@ impl Packed { &self, engine: &mut Engine, styles: StyleChain, - regions: Regions, + base: Size, ) -> SourceResult { // The pod is the base area of the region because for absolute // placement we don't really care about the already used area. - let base = regions.base(); let float = self.float(styles); let alignment = self.alignment(styles); diff --git a/tests/ref/bugs/2715-float-order.png b/tests/ref/bugs/2715-float-order.png new file mode 100644 index 0000000000000000000000000000000000000000..76e6db9e6d36544023dd7f091eae5486f2245b97 GIT binary patch literal 12944 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