Starting point on fix of grapheme rendering

This commit is contained in:
daa 2018-04-08 00:04:31 +03:00
parent d8d33edb19
commit 2b818d0847
8 changed files with 31 additions and 19 deletions

7
Cargo.lock generated
View File

@ -394,6 +394,7 @@ dependencies = [
"serde_derive 1.0.27 (registry+https://github.com/rust-lang/crates.io-index)", "serde_derive 1.0.27 (registry+https://github.com/rust-lang/crates.io-index)",
"serde_json 1.0.9 (registry+https://github.com/rust-lang/crates.io-index)", "serde_json 1.0.9 (registry+https://github.com/rust-lang/crates.io-index)",
"toml 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)", "toml 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)",
"unicode-segmentation 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
"unicode-width 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", "unicode-width 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)",
] ]
@ -682,6 +683,11 @@ dependencies = [
"serde 1.0.27 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.27 (registry+https://github.com/rust-lang/crates.io-index)",
] ]
[[package]]
name = "unicode-segmentation"
version = "1.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]] [[package]]
name = "unicode-width" name = "unicode-width"
version = "0.1.4" version = "0.1.4"
@ -817,6 +823,7 @@ dependencies = [
"checksum thread_local 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)" = "279ef31c19ededf577bfd12dfae728040a21f635b06a24cd670ff510edd38963" "checksum thread_local 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)" = "279ef31c19ededf577bfd12dfae728040a21f635b06a24cd670ff510edd38963"
"checksum time 0.1.39 (registry+https://github.com/rust-lang/crates.io-index)" = "a15375f1df02096fb3317256ce2cee6a1f42fc84ea5ad5fc8c421cfe40c73098" "checksum time 0.1.39 (registry+https://github.com/rust-lang/crates.io-index)" = "a15375f1df02096fb3317256ce2cee6a1f42fc84ea5ad5fc8c421cfe40c73098"
"checksum toml 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)" = "a7540f4ffc193e0d3c94121edb19b055670d369f77d5804db11ae053a45b6e7e" "checksum toml 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)" = "a7540f4ffc193e0d3c94121edb19b055670d369f77d5804db11ae053a45b6e7e"
"checksum unicode-segmentation 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "a8083c594e02b8ae1654ae26f0ade5158b119bd88ad0e8227a5d8fcd72407946"
"checksum unicode-width 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "bf3a113775714a22dcb774d8ea3655c53a32debae63a063acc00a91cc586245f" "checksum unicode-width 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "bf3a113775714a22dcb774d8ea3655c53a32debae63a063acc00a91cc586245f"
"checksum unicode-xid 0.0.4 (registry+https://github.com/rust-lang/crates.io-index)" = "8c1f860d7d29cf02cb2f3f359fd35991af3d30bac52c57d265a3c461074cb4dc" "checksum unicode-xid 0.0.4 (registry+https://github.com/rust-lang/crates.io-index)" = "8c1f860d7d29cf02cb2f3f359fd35991af3d30bac52c57d265a3c461074cb4dc"
"checksum unix_socket 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "6aa2700417c405c38f5e6902d699345241c28c0b7ade4abaad71e35a87eb1564" "checksum unix_socket 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "6aa2700417c405c38f5e6902d699345241c28c0b7ade4abaad71e35a87eb1564"

View File

@ -36,6 +36,7 @@ percent-encoding = "1.0"
regex = "0.2" regex = "0.2"
lazy_static = "1.0" lazy_static = "1.0"
unicode-width = "0.1.4" unicode-width = "0.1.4"
unicode-segmentation = "1.2.0"
serde = "1.0" serde = "1.0"
serde_derive = "1.0" serde_derive = "1.0"

View File

@ -28,7 +28,7 @@ pub struct Level {
} }
impl Level { impl Level {
pub fn insert(&mut self, c: &str, shift: bool, render_state: &shell::RenderState) { pub fn insert(&mut self, c: String, shift: bool, render_state: &shell::RenderState) {
self.model_layout.insert_char(c, shift); self.model_layout.insert_char(c, shift);
self.update_preferred_size(render_state); self.update_preferred_size(render_state);
} }
@ -405,7 +405,7 @@ impl CmdLine {
let mut state = self.state.borrow_mut(); let mut state = self.state.borrow_mut();
if let Some(level) = state.levels.get_mut((level - 1) as usize) { if let Some(level) = state.levels.get_mut((level - 1) as usize) {
level.insert(&c, shift, render_state); level.insert(c, shift, render_state);
level.update_cache(&*render_state); level.update_cache(&*render_state);
} else { } else {
error!("Level {} does not exists", level); error!("Level {} does not exists", level);

View File

@ -1156,9 +1156,8 @@ impl State {
} }
pub fn on_put(&mut self, text: String) -> RepaintMode { pub fn on_put(&mut self, text: String) -> RepaintMode {
let ch = text.chars().last().unwrap_or(' ');
let double_width = text.is_empty(); let double_width = text.is_empty();
RepaintMode::Area(self.model.put(ch, double_width, self.cur_attrs.as_ref())) RepaintMode::Area(self.model.put(text, double_width, self.cur_attrs.as_ref()))
} }
pub fn on_clear(&mut self) -> RepaintMode { pub fn on_clear(&mut self) -> RepaintMode {

View File

@ -76,24 +76,30 @@ impl Attrs {
} }
} }
const EMPTY_STRING: String = String::new();
#[derive(Clone)] #[derive(Clone)]
pub struct Cell { pub struct Cell {
pub attrs: Attrs, pub attrs: Attrs,
pub ch: char, pub ch: String,
pub dirty: bool, pub dirty: bool,
} }
impl Cell { impl Cell {
pub fn new(ch: char) -> Cell { pub fn new_empty() -> Cell {
Cell::new(EMPTY_STRING)
}
pub fn new(ch: String) -> Cell {
Cell { Cell {
attrs: Attrs::new(), attrs: Attrs::new(),
ch: ch, ch,
dirty: true, dirty: true,
} }
} }
pub fn clear(&mut self) { pub fn clear(&mut self) {
self.ch = ' '; self.ch = EMPTY_STRING;
self.attrs.clear(); self.attrs.clear();
self.dirty = true; self.dirty = true;
} }

View File

@ -21,7 +21,7 @@ pub struct Line {
impl Line { impl Line {
pub fn new(columns: usize) -> Self { pub fn new(columns: usize) -> Self {
Line { Line {
line: vec![Cell::new(' '); columns].into_boxed_slice(), line: vec![Cell::new_empty(); columns].into_boxed_slice(),
item_line: vec![None; columns].into_boxed_slice(), item_line: vec![None; columns].into_boxed_slice(),
cell_to_item: vec![-1; columns].into_boxed_slice(), cell_to_item: vec![-1; columns].into_boxed_slice(),
dirty_line: true, dirty_line: true,
@ -257,7 +257,7 @@ impl StyledLine {
continue; continue;
} }
line_str.push(cell.ch); line_str.push_str(&cell.ch);
let len = line_str.len() - byte_offset; let len = line_str.len() - byte_offset;
for _ in 0..len { for _ in 0..len {

View File

@ -93,7 +93,7 @@ impl UiModel {
(self.cur_row, self.cur_col) (self.cur_row, self.cur_col)
} }
pub fn put(&mut self, ch: char, double_width: bool, attrs: Option<&Attrs>) -> ModelRect { pub fn put(&mut self, ch: String, double_width: bool, attrs: Option<&Attrs>) -> ModelRect {
let mut changed_region = self.cur_point(); let mut changed_region = self.cur_point();
let line = &mut self.model[self.cur_row]; let line = &mut self.model[self.cur_row];
line.dirty_line = true; line.dirty_line = true;

View File

@ -8,7 +8,7 @@ pub struct ModelLayout {
pub model: UiModel, pub model: UiModel,
rows_filled: usize, rows_filled: usize,
cols_filled: usize, cols_filled: usize,
lines: Vec<Vec<(Option<Attrs>, Vec<char>)>>, lines: Vec<Vec<(Option<Attrs>, Vec<String>)>>,
} }
impl ModelLayout { impl ModelLayout {
@ -23,7 +23,7 @@ impl ModelLayout {
} }
} }
pub fn layout_append(&mut self, mut lines: Vec<Vec<(Option<Attrs>, Vec<char>)>>) { pub fn layout_append(&mut self, mut lines: Vec<Vec<(Option<Attrs>, Vec<String>)>>) {
let rows_filled = self.rows_filled; let rows_filled = self.rows_filled;
let take_from = self.lines.len(); let take_from = self.lines.len();
@ -32,7 +32,7 @@ impl ModelLayout {
self.layout_replace(rows_filled, take_from); self.layout_replace(rows_filled, take_from);
} }
pub fn layout(&mut self, lines: Vec<Vec<(Option<Attrs>, Vec<char>)>>) { pub fn layout(&mut self, lines: Vec<Vec<(Option<Attrs>, Vec<String>)>>) {
self.lines = lines; self.lines = lines;
self.layout_replace(0, 0); self.layout_replace(0, 0);
} }
@ -67,12 +67,11 @@ impl ModelLayout {
} }
} }
pub fn insert_char(&mut self, c: &str, shift: bool) { pub fn insert_char(&mut self, ch: String, shift: bool) {
if c.is_empty() { if ch.is_empty() {
return; return;
} }
let ch = c.chars().next().unwrap();
let (row, col) = self.model.get_cursor(); let (row, col) = self.model.get_cursor();
if shift { if shift {
@ -85,7 +84,7 @@ impl ModelLayout {
self.model.set_cursor(row, col); self.model.set_cursor(row, col);
} }
fn insert_into_lines(&mut self, ch: char) { fn insert_into_lines(&mut self, ch: String) {
let line = &mut self.lines[0]; let line = &mut self.lines[0];
let cur_col = self.model.cur_col; let cur_col = self.model.cur_col;
@ -152,7 +151,7 @@ impl ModelLayout {
} }
} }
fn count_lines(lines: &[Vec<(Option<Attrs>, Vec<char>)>], max_columns: usize) -> usize { fn count_lines(lines: &[Vec<(Option<Attrs>, Vec<String>)>], max_columns: usize) -> usize {
let mut row_count = 0; let mut row_count = 0;
for line in lines { for line in lines {