mirror of
https://github.com/storytold/wordcraft.git
synced 2026-11-13 22:12:22 +00:00
Since content controls are kept (#392), a picture content control puts a zero-width start marker before its picture. Line breaking keeps a line's first item even when it doesn't fit, but counted the marker as that item, so a picture a little wider than its line wrapped onto a second line, leaving a marker-only line above it; in a fixed-height text box the picture's line was then cut off. A logo in a header text box (which 0.5.0 drew) disappeared. Markers before an item no longer count, as a display equation's check already does. Co-authored-by: Naxvog <4963183+naxvog@users.noreply.github.com> Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
2 files changed
+21
-1
No files matched your search
@@ -1728,7 +1728,9 @@ fn break_lines(pl: &mut ParaLayout, env: &ParaEnv, mark_style: u16, level: Optio
|
||||
});
|
||||
let shrink = if shrink_spaces && !has_tab { space_w * MAX_SPACE_SHRINK } else { 0.0 };
|
||||
let fits = absorbs || x + c.adv <= right_edge + shrink + 0.01 || c.kind == ClKind::Space || c.kind == ClKind::Marker;
|
||||
if !fits && j > c0 {
|
||||
// A line's first item stays on it even when it doesn't fit; markers before it
|
||||
// (a content control's start, a bookmark) take no room and don't count (Word).
|
||||
if !fits && (c0..j).any(|k| pl.clusters.get(k).is_some_and(|c| c.kind != ClKind::Marker)) {
|
||||
// Wrap: back up to the last break opportunity on this line.
|
||||
end = LineEnd::Wrap;
|
||||
// Hyphenate only when the plain break leaves more than the hyphenation zone empty.
|
||||
|
||||
@@ -3102,6 +3102,24 @@ fn inline_picture_wider_than_the_text_keeps_its_size() {
|
||||
assert!((r.w - 1000.0).abs() < 0.01 && (r.h - 100.0).abs() < 0.01, "{r:?}");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn a_picture_too_wide_after_a_content_control_start_stays_on_the_first_line() {
|
||||
// The picture opening a picture content control (a logo in a text box a little too
|
||||
// narrow for it): the control's start marker before it takes no room, so the picture is
|
||||
// still the line's first item and stays there instead of leaving an empty line above it.
|
||||
let mut d = Document::from_text("");
|
||||
if let Some(wordcraft_doc::Block::Para(p)) = d.body.get_mut(0).map(std::sync::Arc::make_mut) {
|
||||
p.insert_object(0, picture(500.0, 100.0, Default::default()), &Default::default()).unwrap();
|
||||
let start = InlineObject::ControlStart { control: Box::default() };
|
||||
p.insert_object(0, start, &Default::default()).unwrap();
|
||||
}
|
||||
let l = lay(&d);
|
||||
let Some(Placed::Lines { para, .. }) = l.pages[0].items.iter().find(|i| matches!(i, Placed::Lines { .. })) else { panic!() };
|
||||
assert_eq!(para.lines.len(), 1, "{:?}", para.lines);
|
||||
let line = ¶.lines[0];
|
||||
assert!((line.baseline - line.top - 100.0).abs() < 0.01, "the picture is on the first line: {line:?}");
|
||||
}
|
||||
|
||||
/// The paragraph at `path` on page 0: its first line's x, its y and its line count.
|
||||
fn para_at(l: &DocLayout, path: &[u32]) -> Vec<(f32, f32, usize)> {
|
||||
l.pages[0]
|
||||
|
||||
Reference in new issue
Block a user