M4: an emergency break can back up to right after the line's first letter (part of #1219)

The backward search for a safe break started at line_start + 2, so in a
three-letter run like กเม it skipped the only safe boundary and left the
line ending in a leading vowel.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
SusieeTheFemboy
2026-10-27 01:14:05 +01:00
co-authored by Claude Opus 5.5
parent 1c09e8385e
commit 860bc13e79
2 changed files with 17 additions and 1 deletions
+16
View File
@@ -334,6 +334,22 @@ fn thai_comes_from_a_thai_font_when_one_is_installed() {
assert_eq!(drawn, want, "every Thai char is in a drawn cluster");
}
#[test]
fn thai_emergency_break_can_back_up_to_the_first_letter() {
// #1219: in "กเม" the overflow lands between the leading vowel and its consonant; the only
// safe break is right after the first letter, so the vowel moves down with "ม".
let s = "กเม";
let thai = ["Noto Sans Thai", "Noto Sans Thai UI", "Leelawadee UI", "Thonburi", "Tahoma"];
if face().is_none() || !thai.iter().any(|t| find_face(t, "Regular").is_some_and(|t| s.chars().all(|c| t.has_char(c)))) {
return;
}
let mut t = text(s, TextAutoResize::Height);
t.style.font_size = 16.0;
let two = layout(&t, None, None).caret(2).0;
let lines = layout(&t, Some(two + 0.5), None).lines;
assert_eq!(lines.get(1).map(|l| l.char_start), Some(1), "the leading vowel stays with its consonant");
}
#[test]
fn thai_emergency_breaks_keep_marks_and_leading_vowels_with_their_letter() {
// #1219: Thai writes no spaces between words, so a paragraph is one run with no break
+1 -1
View File
@@ -524,7 +524,7 @@ pub fn layout(text: &TextData, box_width: Option<f64>, box_height: Option<f64>)
let carry = (brk + 1..items.len().min(brk + 257))
.take_while(|&k| items.get(k).is_some_and(|it| it.ch != '\n' && it.ch != LINE_SEPARATOR))
.find(|&k| safe(k));
brk = (line_start + 2..brk).rev().find(|&k| safe(k)).or(carry).unwrap_or(brk);
brk = (line_start + 1..brk).rev().find(|&k| safe(k)).or(carry).unwrap_or(brk);
}
lines.push((line_start, brk, false, para));
line_start = brk;