From 2dcfbb0bf02626b76f0714cca29cec1772fee16f Mon Sep 17 00:00:00 2001 From: ham9zah Date: Thu, 29 Oct 2026 10:37:09 +0300 Subject: [PATCH] Import: a right-to-left paragraph of the editing data lays out right to left The text document's paragraph key 33 (from the paragraph or the document's defaults) said a paragraph runs right to left, but the reader only used it to swap left and right alignment: the paragraph's direction stayed unset, so it went by its first strong letter, and a label with no Arabic or Hebrew letters (" 120.5 mm ") laid out left to right instead of reading "mm 120.5". The paragraph style now gets that direction. --- crates/eps/src/import/ate.rs | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) diff --git a/crates/eps/src/import/ate.rs b/crates/eps/src/import/ate.rs index 24a3a2736..ff5b2906e 100644 --- a/crates/eps/src/import/ate.rs +++ b/crates/eps/src/import/ate.rs @@ -24,7 +24,7 @@ use std::collections::BTreeMap; use kurbo::{BezPath, CubicBez, ParamCurve, ParamCurveArclen}; use vectorcraft_color::{Color, Paint}; -use vectorcraft_doc::{CharStyle, Justify, Node, NodeId, NodeKind, ParaStyle, TextKind, TextObject, TextRun}; +use vectorcraft_doc::{CharStyle, Justify, Node, NodeId, NodeKind, ParaDirection, ParaStyle, TextKind, TextObject, TextRun}; use vectorcraft_geom::{Affine, PathData, Point, Rect}; /// Longest story read (bytes). @@ -790,6 +790,9 @@ fn para_style(p: &Para, scale: f64) -> ParaStyle { space_before: p.space_before * scale, space_after: p.space_after * scale, hyphenate: p.hyphenate, + // A right-to-left paragraph lays its text out from the right whatever letters it has + // (" 120.5 mm " reads "mm 120.5"); without the key, from its first strong letter. + direction: p.rtl.then_some(ParaDirection::RightToLeft), ..ParaStyle::default() } } @@ -838,6 +841,20 @@ mod tests { assert_eq!(justify(b"/0 1 /33 0"), Justify::Right); } + /// A right-to-left paragraph is laid out right to left even when it has no right-to-left + /// letters (a dimension's label " 120.5 mm " reads "mm 120.5"); a left-to-right one, or one + /// that doesn't say, goes by its letters. + #[test] + fn right_to_left_paragraphs_set_their_direction() { + let texts = + Texts { stories: vec![], fonts: vec![], defaults: Val::Dict(BTreeMap::new()), para_defaults: read(b"/33 1").unwrap(), frames: vec![] }; + let direction = |own: &[u8]| para_style(&texts.para(Some(&read(own).unwrap())), 1.0).direction; + assert_eq!(direction(b"/0 2"), Some(ParaDirection::RightToLeft), "from the document's defaults"); + assert_eq!(direction(b"/0 2 /33 0"), None, "the paragraph's own"); + let plain = Texts { para_defaults: Val::Dict(BTreeMap::new()), ..texts }; + assert_eq!(para_style(&plain.para(None), 1.0).direction, None); + } + #[test] fn values_read_nested_dictionaries_lists_and_utf16_strings() { let v = read(b" /1 << /0 [ 1 2.5 -3 ] /2 (\xfe\xff\x00h\x00i) /3 true /99 /Name >> /0 (a\\)b\\n)").unwrap();