1
1
mirror of https://github.com/wez/wezterm.git synced 2024-11-22 13:16:39 +03:00

bidi: feed reordered runs through to harfbuzz

Two problems:

* Need reordered_runs method to populate ranges based on
  the reordered levels!
* Use reordered runs to get the *logical* bounds of those
  runs and pass those to harfbuzz.

Now the text is ordered correctly, but the rendering advances
by the wrong amount for the reordered clusters and looks bad
unless experimental_pixel_positioning=true.

refs: #784
This commit is contained in:
Wez Furlong 2022-01-28 23:13:29 -07:00
parent 66183ed336
commit 75c80ca322
2 changed files with 27 additions and 7 deletions

View File

@ -187,19 +187,34 @@ impl BidiContext {
}
pub fn reordered_runs(&self, line_range: Range<usize>) -> Vec<ReorderedRun> {
// reorder_line's `level` result includes entries that were
// removed_by_x9() but `reordered` does NOT (for compatibility with
// the UCD test suite).
// We need to account for that when we reorder the levels here!
let (levels, reordered) = self.reorder_line(line_range);
let mut reordered_levels = vec![Level(NO_LEVEL); reordered.len()];
for (vis_idx, &log_idx) in reordered.iter().enumerate() {
reordered_levels[vis_idx] = levels[log_idx];
}
reordered_levels.retain(|l| !l.removed_by_x9());
let mut runs = vec![];
let mut idx = 0;
while idx < levels.len() {
let len = span_len(idx, &levels);
let level = levels[idx];
while idx < reordered_levels.len() {
let len = span_len(idx, &reordered_levels);
let level = reordered_levels[idx];
if !level.removed_by_x9() {
let idx_range = idx..idx + len;
let start = reordered[idx_range.clone()].iter().min().unwrap();
let end = reordered[idx_range.clone()].iter().max().unwrap();
runs.push(ReorderedRun {
direction: level.direction(),
level,
range: idx..idx + len,
indices: reordered[idx..idx + len].to_vec(),
range: *start..*end + 1,
indices: reordered[idx_range].to_vec(),
});
}
idx += len;

View File

@ -174,14 +174,19 @@ impl CellCluster {
}
context.resolve_paragraph(&paragraph, hint);
for run in context.runs() {
for run in context.reordered_runs(0..paragraph.len()) {
let mut text = String::with_capacity(run.range.end - run.range.start);
let mut byte_to_cell_idx = vec![];
let mut byte_to_cell_width = vec![];
let mut width = 0usize;
let mut first_cell_idx = None;
for cp_idx in run.indices() {
// Note: if we wanted the actual bidi-re-ordered
// text we should iterate over run.indices here,
// however, cluster.text will be fed into harfbuzz
// and that requires the original logical order
// for the text, so we look at run.range instead.
for cp_idx in run.range.clone() {
let cp = paragraph[cp_idx];
text.push(cp);