Integration: shatai glyphs in right-to-left lines always take a tagged run

8806a223 (next, for #392) drew a slanted glyph with run while a
right-to-left line span was open, so its tagged span would not nest in
the line span. pdf-rtl-text (8f30ba1c) removes the line span and its
line_span flag, so the glyph always goes through tagged_run. The
regression test keeps its export of tagged and untagged PDFs with shatai
Hebrew and checks what the branch's tests check: reading-order text,
no marked content opened inside an ActualText span, and no ActualText
wider than a word.
This commit is contained in:
aiongg
2026-10-11 12:28:34 +00:00
parent eda793e300
commit d5fe4ec201
2 changed files with 6 additions and 9 deletions
+5 -4
View File
@@ -227,10 +227,10 @@ fn right_to_left_lines_carry_actual_text_only_on_their_clusters() {
}
}
/// A slanted (shatai) glyph in a right-to-left line is drawn inside the line's span, not in a span
/// of its own (marked content can't nest).
/// A slanted (shatai) glyph in a right-to-left line is drawn through its own tagged run; tagged
/// exports must not nest marked content (krilla panics on it).
#[test]
fn shatai_glyphs_in_right_to_left_lines_stay_in_the_line_span() {
fn shatai_glyphs_in_right_to_left_lines_export_in_reading_order() {
hebrew_font();
let text = "דוד & שרה";
let mut d = doc(text, HEBREW, Rect::new(36.0, 36.0, 576.0, 300.0), rtl());
@@ -238,7 +238,8 @@ fn shatai_glyphs_in_right_to_left_lines_stay_in_the_line_span() {
d.story_mut(sid).unwrap().format_chars(0.."דוד".len(), |f| f.over.shatai_magnification = Some(30.0));
for tagged in [false, true] {
let bytes = export_pdf(&d, &Cache::new(), &PdfOptions { tagged, ..PdfOptions::default() }).unwrap();
assert_eq!(line_actual_texts(&bytes), [text], "tagged: {tagged}");
assert_eq!(opened_inside_actual_text(&bytes), 0, "tagged: {tagged}");
assert!(actual_texts(&bytes).iter().all(|t| !t.contains(' ')), "tagged: {tagged}");
assert_eq!(extract_text(&bytes)[0], text, "tagged: {tagged}");
}
}
+1 -5
View File
@@ -242,11 +242,7 @@ impl Exporter<'_> {
if turn.is_some() || shatai.is_some() {
let m = turn.unwrap_or(Affine::IDENTITY) * shatai.unwrap_or(Affine::IDENTITY);
s.push_transform(&crate::export::tf(m));
if line_span {
self.run(s, cs, &gs[i..i + 1], l.baseline, story);
} else {
self.tagged_run(s, cs, &gs[i..i + 1], l.baseline, story);
}
self.tagged_run(s, cs, &gs[i..i + 1], l.baseline, story);
s.pop();
i += 1;
continue;