Merge pull request #2815 from dotCooCoo/fix/rtf-rtl-justify

Place: justified RTF paragraphs marked right to left end their last line on the right
This commit is contained in:
BFlat
2026-10-18 13:19:24 +07:00
committed by GitHub
+19 -1
View File
@@ -14,6 +14,8 @@
//! superscript and subscript, baseline shift (`\up`, `\dn`) and the color table's color (`\cf`).
//! - Paragraph formatting, reset by `\pard`: alignment (`\ql`, `\qc`, `\qr`, `\qj`, `\qd`), left,
//! right and first-line indents, space before and after, and direction (`\rtlpar`, `\ltrpar`).
//! `\ql` and `\qr` are the left and right edges in either direction, and a justified (`\qj`)
//! paragraph marked right to left (`\rtlpar`) ends its last line on the right.
//!
//! Other control words are skipped, and so are hidden text (`\v`) and the groups of destinations
//! that are not the document's text: every `\*` destination, the style sheet, document
@@ -608,7 +610,11 @@ impl Reader {
.paras
.iter()
.map(|p| ParaStyle {
justify: p.justify,
// `\qj` in an `\rtlpar` paragraph justifies it with its last line on the right.
justify: match p.justify {
Justify::JustifyLeft if p.rtl == Some(true) => Justify::JustifyRight,
j => j,
},
left_indent: twips(p.left),
right_indent: twips(p.right),
first_line_indent: twips(p.first),
@@ -682,6 +688,18 @@ mod tests {
assert_eq!(s.paras.last().map(|p| p.left_indent), Some(20.0));
}
#[test]
fn justified_right_to_left_paragraphs_end_their_last_line_on_the_right() {
let s = read(concat!(
r"{\rtf1\pard\rtlpar\qj a\par\pard\qj\rtlpar b\par\pard\qj c\par\pard\rtlpar\ltrpar\qj d\par",
r"\pard\rtlpar\ql e\par\pard\rtlpar\qr f\par\pard\rtlpar\qc g\par\pard\rtlpar\qd h}"
));
let justify: Vec<Justify> = s.paras.iter().map(|p| p.justify).collect();
use Justify::*;
assert_eq!(justify, [JustifyRight, JustifyRight, JustifyLeft, JustifyLeft, Left, Right, Center, JustifyAll]);
assert_eq!(s.paras.first().and_then(|p| p.direction), Some(ParaDirection::RightToLeft));
}
#[test]
fn deep_nesting_and_stray_braces_end_cleanly() {
let deep = format!("{{\\rtf1 {}x{}}}", "{".repeat(5000), "}".repeat(5000));