mirror of
https://github.com/storytold/wordcraft.git
synced 2026-11-09 11:50:20 -06:00
Gap 19: ODT leading read as an at-least spacing
LibreOffice's leading (`style:line-spacing`, extra space between lines) has no WordCraft line spacing mode. It was read as a multiple of a 12 pt line, which spreads the extra space differently from LibreOffice, so the paragraph started too high. It is now read as at least a 12 pt line and the leading: the extra space goes above each line, as LibreOffice draws leading (it also leaves some after the last line, which isn't followed). A LibreOffice spacing document went from 6,190 px apart after a round trip to 2,973, and WordCraft's drawing of it from 8,570 to 5,521. Regression test: `leading_is_at_least_a_line_and_the_leading`. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01GBVQLyDnrG8Tn1yDQcUabC
This commit is contained in:
@@ -299,9 +299,11 @@ fn paragraph_spacing(a: &Attrs, sp: &mut Spacing) {
|
||||
if let Some(h) = len("style:line-height-at-least").filter(|h| *h >= 0.0) {
|
||||
sp.line = Some(LineSpacing::AtLeast(h.clamp(0.7, MAX_LEN)));
|
||||
}
|
||||
// Leading (extra space between lines) has no WordCraft mode: as a multiple of a 12 pt line.
|
||||
// Leading (§20.336: extra space between lines, above each line as LibreOffice draws it) has
|
||||
// no WordCraft mode: at least a 12 pt line and the leading, which also puts the extra space
|
||||
// above the text.
|
||||
if let Some(l) = len("style:line-spacing").filter(|l| *l >= 0.0) {
|
||||
sp.line = Some(LineSpacing::Multiple(((LEADING_LINE + l.min(MAX_LEN)) / LEADING_LINE).clamp(0.06, 132.0)));
|
||||
sp.line = Some(LineSpacing::AtLeast((LEADING_LINE + l.min(MAX_LEN)).clamp(0.7, MAX_LEN)));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -172,3 +172,15 @@ fn the_list_paragraph_style_is_written() {
|
||||
let r = back.styles.resolve_para(&props(&back)[0]);
|
||||
assert!(r.contextual_spacing && r.space_after == 3.0, "{r:?}");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn leading_is_at_least_a_line_and_the_leading() {
|
||||
// LibreOffice's leading (`style:line-spacing`) draws its extra space above each line, as an
|
||||
// at-least spacing does: a 12 pt line (14 pt high) and 3 mm.
|
||||
let d = import(&package(&content(&p_style("P1", "Standard", r#"style:line-spacing="3mm""#), r#"<text:p text:style-name="P1">x</text:p>"#), None))
|
||||
.unwrap();
|
||||
match props(&d)[0].line_spacing {
|
||||
Some(LineSpacing::AtLeast(h)) => assert!((h - (14.0 + 3.0 * 72.0 / 25.4)).abs() < 0.01, "{h}"),
|
||||
other => panic!("{other:?}"),
|
||||
}
|
||||
}
|
||||
|
||||
File diff suppressed because one or more lines are too long
Reference in New Issue
Block a user