This fixes the bidi layout issue.

Needs more testing and cleaning up the previous algorithm.
This commit is contained in:
Hojjat 2022-11-26 22:39:05 -07:00 • committed by Jeremy Soller
parent 2342bf0eae
commit c344eec936

View file

@ -2,7 +2,9 @@
#[cfg(not(feature = "std"))] #[cfg(not(feature = "std"))]
use alloc::vec::Vec; use alloc::vec::Vec;
use unicode_bidi::Level;
use core::mem; use core::mem;
use core::ops::Range;
use unicode_script::{Script, UnicodeScript}; use unicode_script::{Script, UnicodeScript};
use unicode_segmentation::UnicodeSegmentation; use unicode_segmentation::UnicodeSegmentation;
@ -418,6 +420,8 @@ impl ShapeSpan {
pub struct ShapeLine { pub struct ShapeLine {
pub rtl: bool, pub rtl: bool,
pub spans: Vec<ShapeSpan>, pub spans: Vec<ShapeSpan>,
pub levels: Vec<Level>,
pub runs: Vec<Range<usize>>,
} }
impl ShapeLine { impl ShapeLine {
@ -427,6 +431,8 @@ impl ShapeLine {
attrs_list: &AttrsList attrs_list: &AttrsList
) -> Self { ) -> Self {
let mut spans = Vec::new(); let mut spans = Vec::new();
let levels = Vec::new();
let runs = Vec::new();
let bidi = unicode_bidi::BidiInfo::new(line, None); let bidi = unicode_bidi::BidiInfo::new(line, None);
let rtl = if bidi.paragraphs.is_empty() { let rtl = if bidi.paragraphs.is_empty() {
@ -438,40 +444,43 @@ impl ShapeLine {
log::trace!("Line {}: '{}'", if line_rtl { "RTL" } else { "LTR" }, line); log::trace!("Line {}: '{}'", if line_rtl { "RTL" } else { "LTR" }, line);
let paragraph = unicode_bidi::Paragraph::new(&bidi, para_info); let line_range = para_info.range.clone();
let (levels, runs) = bidi.visual_runs(para_info, line_range);
let mut start = 0; if line_rtl {
let mut span_rtl = line_rtl; for range in runs.into_iter().rev() {
for i in paragraph.para.range.clone() { let span_rtl = levels[range.start].is_rtl(); //paragraph.info.levels[i].is_rtl();
let next_rtl = paragraph.info.levels[i].is_rtl();
if span_rtl != next_rtl {
spans.push(ShapeSpan::new( spans.push(ShapeSpan::new(
font_system, font_system,
line, line,
attrs_list, attrs_list,
start, range.start,
i, range.end,
line_rtl,
span_rtl
));
}
}
else {
for range in runs.into_iter() {
let span_rtl = levels[range.start].is_rtl(); //paragraph.info.levels[i].is_rtl();
spans.push(ShapeSpan::new(
font_system,
line,
attrs_list,
range.start,
range.end,
line_rtl, line_rtl,
span_rtl span_rtl
)); ));
span_rtl = next_rtl;
start = i;
} }
} }
spans.push(ShapeSpan::new(
font_system,
line,
attrs_list,
start,
line.len(),
line_rtl,
span_rtl
));
line_rtl line_rtl
}; };
Self { rtl, spans } Self { rtl, spans, levels, runs }
} }
pub fn layout( pub fn layout(