address review: blank lines use the same scaled leading tolerance

This commit is contained in:
Dylan M. Taylor
2026-11-11 13:16:42 +00:00
parent 059d3cc21a
commit acb96658ea
2 changed files with 18 additions and 3 deletions
+8 -3
View File
@@ -903,6 +903,12 @@ fn justify_of(anchor: f64) -> Justify {
}
}
/// How far a line's leading may differ from its spacing and still count as it: 0.01 absolute, but
/// never more than a thousandth of the spacing itself (tiny type has tiny gaps).
fn leading_tolerance(spacing: f64) -> f64 {
0.01_f64.min(spacing.abs() * 1e-3)
}
/// Point type: line breaks, baseline shifts and kerning from the positioning lists. Returns the
/// justification, the x of the first line's left (or anchor) edge and, when no character is
/// placed on its own, each line's first character and anchor x.
@@ -950,8 +956,7 @@ fn lines(
// A line's characters take its spacing as leading unless it is their auto leading.
for (k, b) in breaks.iter().enumerate() {
let end = breaks.get(k + 1).map_or(n, |nb| nb.at);
// 0.01 absolute, but never more than a thousandth of the spacing itself (tiny type has tiny gaps).
let tolerance = 0.01_f64.min(b.leading.abs() * 1e-3);
let tolerance = leading_tolerance(b.leading);
if cells[b.at..end].iter().any(|c| (c.style.effective_leading() - b.leading).abs() > tolerance) {
for c in &mut cells[b.at..end] {
c.style.leading = Some(b.leading);
@@ -1076,7 +1081,7 @@ fn assemble(cells: &[Cell], breaks: &[Break]) -> (Runs, Vec<usize>) {
let key = (prev.fill, prev.stroke);
push(&mut out, '\n', prev.final_style(), key);
let mut blank = prev.final_style();
if (blank.effective_leading() - b.leading).abs() > 0.01 {
if (blank.effective_leading() - b.leading).abs() > leading_tolerance(b.leading) {
blank.leading = Some(b.leading);
}
for _ in 1..b.count {
+10
View File
@@ -241,6 +241,16 @@ fn a_small_line_gap_in_tiny_type_keeps_its_leading() {
assert!(two.is_some_and(|l| close(l, 0.0085, 1e-9)), "{two:?}");
}
#[test]
fn blank_lines_in_tiny_type_keep_their_own_spacing() {
// B sits 0.0085 below A (kept as its leading); C is three 0.006 lines below B, so the two blank
// lines between them must be 0.006 apart, not carry B's 0.0085.
let d = open(r#"<text x="1" y="1" font-size="0.005">A<tspan x="1" dy="0.0085">B</tspan><tspan x="1" dy="0.018">C</tspan></text>"#);
let t = only_text(&d);
let blank = t.runs.iter().find(|r| r.text == "\n\n").expect("a run of the two blank lines");
assert!(blank.style.leading.is_some_and(|l| close(l, 0.006, 1e-9)), "{:?}", blank.style.leading);
}
#[test]
fn tspan_lines_dx_and_baseline_shift() {
let d = open(