mirror of
https://github.com/storytold/figcraft.git
synced 2026-10-30 13:26:54 -06:00
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:
co-authored by
Claude Opus 5.5
parent
1c09e8385e
commit
860bc13e79
@@ -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
|
||||
|
||||
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user