forked from 1b-agent/opencadstudio-upstream
review(#1629): one direction mark, no dead RTL paragraph path, tests follow the new layout
- One visible-named LRM constant (ttf_glyph) instead of two invisible literals. Stroke and SDF text skip it, so a right-to-left script the shaper does not handle no longer gets a 6-unit gap per mark; vertical MTEXT does not insert it at all. - Shaped cells keep a cluster the shaper merged into the leading mark. - The always-false RTL paragraph flag, its indent/anchor branches and the unused reorder_line_atoms are gone; its test now covers reorder_rtl_runs. - Underline, overline and strike follow each drawn run of a mixed word. - Justify/distribute count only the gaps the measured width holds. - The two RTL alignment tests assert the new left-to-right behaviour; glyph_boxes keeps its own doc comment. Co-Authored-By: Claude Opus 5.5 <[email protected]>
This commit is contained in:
1 parent
36871044a6
commit
864c644222
5 files changed
+99
-242
No files matched your search
@@ -338,6 +338,10 @@ pub(crate) fn tokenize_run(text: &str) -> Vec<Tok> {
|
||||
let mut toks = Vec::new();
|
||||
let mut chars = text.chars().peekable();
|
||||
while let Some(ch) = chars.next() {
|
||||
// A direction mark only steers shaping; it draws nothing.
|
||||
if ch == crate::scene::text::ttf_glyph::LRM {
|
||||
continue;
|
||||
}
|
||||
if ch == '\\' {
|
||||
match chars.peek().copied() {
|
||||
Some('L') => {
|
||||
|
||||
+14
-10
@@ -603,8 +603,9 @@ pub fn char_cells(run: &ShapedRun, text: &str) -> Vec<(f32, f32)> {
|
||||
.collect()
|
||||
}
|
||||
|
||||
/// Left-to-right mark shaped ahead of every run.
|
||||
const BASE_MARK: char = '';
|
||||
/// Left-to-right mark, shaped ahead of every run so its base direction is
|
||||
/// left to right; layout also uses it to close a right-to-left run.
|
||||
pub(crate) const LRM: char = '\u{200E}';
|
||||
|
||||
type ShapeCache = HashMap<(String, String), Option<Arc<ShapedRun>>>;
|
||||
|
||||
@@ -907,7 +908,7 @@ fn build_shaped(_family: &str, text: &str) -> Option<ShapedRun> {
|
||||
// A leading left-to-right mark keeps the paragraph direction left to
|
||||
// right, as the reference lays text out (right-to-left runs still read
|
||||
// backwards); `cells` stay relative to `text`.
|
||||
let marked = format!("{BASE_MARK}{text}");
|
||||
let marked = format!("{LRM}{text}");
|
||||
buffer.set_text(&mut font_system, &marked, &attrs, Shaping::Advanced, None);
|
||||
buffer.shape_until_scroll(&mut font_system, false);
|
||||
|
||||
@@ -917,9 +918,11 @@ fn build_shaped(_family: &str, text: &str) -> Option<ShapedRun> {
|
||||
for run in buffer.layout_runs() {
|
||||
advance = advance.max(run.line_w * px_to_9);
|
||||
for glyph in run.glyphs.iter() {
|
||||
if glyph.start >= BASE_MARK.len_utf8() {
|
||||
let m = BASE_MARK.len_utf8();
|
||||
cells.push((glyph.start - m, glyph.end - m, glyph.x * px_to_9, (glyph.x + glyph.w) * px_to_9));
|
||||
// A cluster the shaper merged into the mark keeps its own part.
|
||||
let m = LRM.len_utf8();
|
||||
if glyph.end > m {
|
||||
let start = glyph.start.saturating_sub(m);
|
||||
cells.push((start, glyph.end - m, glyph.x * px_to_9, (glyph.x + glyph.w) * px_to_9));
|
||||
}
|
||||
let face_index = font_system
|
||||
.db_mut()
|
||||
@@ -991,7 +994,7 @@ fn build_shaped(family: &str, text: &str) -> Option<ShapedRun> {
|
||||
// A leading left-to-right mark keeps the paragraph direction left to
|
||||
// right, as the reference lays text out (right-to-left runs still read
|
||||
// backwards); `cells` stay relative to `text`.
|
||||
let marked = format!("{BASE_MARK}{text}");
|
||||
let marked = format!("{LRM}{text}");
|
||||
buf.set_text(&mut fs, &marked, &attrs, Shaping::Advanced, None);
|
||||
buf.shape_until_scroll(&mut fs, false);
|
||||
|
||||
@@ -1031,9 +1034,10 @@ fn build_shaped(family: &str, text: &str) -> Option<ShapedRun> {
|
||||
for run in buf.layout_runs() {
|
||||
advance = advance.max(run.line_w * px_to_9);
|
||||
for g in run.glyphs.iter() {
|
||||
if g.start >= BASE_MARK.len_utf8() {
|
||||
let m = BASE_MARK.len_utf8();
|
||||
cells.push((g.start - m, g.end - m, g.x * px_to_9, (g.x + g.w) * px_to_9));
|
||||
// A cluster the shaper merged into the mark keeps its own part.
|
||||
let m = LRM.len_utf8();
|
||||
if g.end > m {
|
||||
cells.push((g.start.saturating_sub(m), g.end - m, g.x * px_to_9, (g.x + g.w) * px_to_9));
|
||||
}
|
||||
let face_index = fs.db_mut().face(g.font_id).map(|f| f.index).unwrap_or(0);
|
||||
let Some(font) = fs.get_font(g.font_id, g.font_weight) else {
|
||||
|
||||
Reference in new issue
Block a user