diff --git a/crates/layout/src/lib.rs b/crates/layout/src/lib.rs index dd57aef8e7..26c6d6fbb6 100644 --- a/crates/layout/src/lib.rs +++ b/crates/layout/src/lib.rs @@ -3368,6 +3368,9 @@ fn place_objects( // first once all are placed, as Word stacks floating objects by `relativeHeight`, not by // their order in the paragraph. Inline objects and objects without one keep their order. let mut stack: Vec<(u32, Vec, Vec)> = Vec::new(); + // The highest order so far: an object without one (inserted here) stacks above the objects + // before it, as the writer gives it the next order up on save. + let mut z_top = 0u32; let Some(fl) = pl.lines.get(l0) else { return (Vec::new(), Vec::new()) }; // Objects left out of the layout (hidden, or deleted in the final text) aren't placed. let left_out = left_out_objects(ctx.doc, p, at.table_chr, ctx.opts.show_hidden, ctx.hide_deleted); @@ -3458,7 +3461,13 @@ fn place_objects( } continue; } - stack.push((if floating { float.z } else { 0 }, behind, front)); + let z = if floating && float.z > 0 { + z_top = z_top.max(float.z); + float.z + } else { + z_top + }; + stack.push((z, behind, front)); } } // Stable: equal orders (none given) keep the paragraph's order. diff --git a/crates/layout/src/tests.rs b/crates/layout/src/tests.rs index d015faa453..86cfb835ee 100644 --- a/crates/layout/src/tests.rs +++ b/crates/layout/src/tests.rs @@ -4053,6 +4053,14 @@ fn floats_are_drawn_in_their_stacking_order() { } let xs: Vec = shapes(&lay(&d).pages[0].items).iter().map(|r| r.x).collect(); assert_eq!(xs, [200.0, 100.0], "behind the text: lowest first"); + // One without an order, anchored after ordered ones, is drawn above them. + let mut d = Document::from_text("Text"); + for (i, (x, z)) in [(100.0, 30), (200.0, 10), (300.0, 0)].into_iter().enumerate() { + let off = 4 + i * wordcraft_doc::para::OBJ.len_utf8(); + d.insert_object(&Pos::body(0, off), at(x, z), &Default::default()).unwrap(); + } + let xs: Vec = shapes(&lay(&d).pages[0].items).iter().map(|r| r.x).collect(); + assert_eq!(xs, [200.0, 100.0, 300.0], "no order after ordered ones: drawn last"); } #[test]