Fix two times repaint
This commit is contained in:
parent
83b5798f6f
commit
389f47738e
240
src/shell.rs
240
src/shell.rs
@ -137,6 +137,7 @@ impl State {
|
|||||||
let mut rect = rect.as_ref().clone();
|
let mut rect = rect.as_ref().clone();
|
||||||
// this need to repain also line under curren line
|
// this need to repain also line under curren line
|
||||||
// in case underscore or 'g' symbol is go here
|
// in case underscore or 'g' symbol is go here
|
||||||
|
// right one for italic symbol
|
||||||
rect.extend(0, 1, 0, 1);
|
rect.extend(0, 1, 0, 1);
|
||||||
let (x, y, width, height) = rect.to_area(line_height, char_width);
|
let (x, y, width, height) = rect.to_area(line_height, char_width);
|
||||||
self.drawing_area.queue_draw_area(x, y, width, height);
|
self.drawing_area.queue_draw_area(x, y, width, height);
|
||||||
@ -416,26 +417,6 @@ fn gtk_draw(parent: &ui::Components, state: &mut State, ctx: &cairo::Context) ->
|
|||||||
Inhibit(false)
|
Inhibit(false)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn draw_joined_rect(state: &State,
|
|
||||||
ctx: &cairo::Context,
|
|
||||||
from_col_idx: usize,
|
|
||||||
col_idx: usize,
|
|
||||||
char_width: f64,
|
|
||||||
line_height: f64,
|
|
||||||
color: &Color) {
|
|
||||||
let current_point = ctx.get_current_point();
|
|
||||||
let rect_width = char_width * (col_idx - from_col_idx) as f64;
|
|
||||||
|
|
||||||
if &state.bg_color != color {
|
|
||||||
ctx.set_source_rgb(color.0, color.1, color.2);
|
|
||||||
ctx.rectangle(current_point.0, current_point.1, rect_width, line_height);
|
|
||||||
ctx.fill();
|
|
||||||
}
|
|
||||||
|
|
||||||
ctx.move_to(current_point.0 + rect_width, current_point.1);
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn get_model_clip(state: &State,
|
fn get_model_clip(state: &State,
|
||||||
line_height: f64,
|
line_height: f64,
|
||||||
@ -456,6 +437,7 @@ fn get_model_clip(state: &State,
|
|||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn draw_backgound(state: &State,
|
fn draw_backgound(state: &State,
|
||||||
|
draw_bitmap: &ModelBitamp,
|
||||||
ctx: &cairo::Context,
|
ctx: &cairo::Context,
|
||||||
line_height: f64,
|
line_height: f64,
|
||||||
char_width: f64,
|
char_width: f64,
|
||||||
@ -463,40 +445,25 @@ fn draw_backgound(state: &State,
|
|||||||
let line_x = model_clip.left as f64 * char_width;
|
let line_x = model_clip.left as f64 * char_width;
|
||||||
let mut line_y: f64 = model_clip.top as f64 * line_height;
|
let mut line_y: f64 = model_clip.top as f64 * line_height;
|
||||||
|
|
||||||
for (_, line) in state.model.clip_model(model_clip) {
|
for (line_idx, line) in state.model.clip_model(model_clip) {
|
||||||
ctx.move_to(line_x, line_y);
|
ctx.move_to(line_x, line_y);
|
||||||
|
|
||||||
// first draw background
|
|
||||||
// here we join same bg color for given line
|
|
||||||
// this gives less drawing primitives
|
|
||||||
let mut from_col_idx = model_clip.left;
|
|
||||||
let mut from_bg = None;
|
|
||||||
for (col_idx, cell) in line.iter() {
|
for (col_idx, cell) in line.iter() {
|
||||||
let (bg, _) = state.colors(cell);
|
let current_point = ctx.get_current_point();
|
||||||
|
|
||||||
|
if !draw_bitmap.get(col_idx, line_idx) {
|
||||||
|
let (bg, _) = state.colors(cell);
|
||||||
|
|
||||||
|
if &state.bg_color != bg {
|
||||||
|
ctx.set_source_rgb(bg.0, bg.1, bg.2);
|
||||||
|
ctx.rectangle(current_point.0, current_point.1, char_width, line_height);
|
||||||
|
ctx.fill();
|
||||||
|
}
|
||||||
|
|
||||||
if from_bg.is_none() {
|
|
||||||
from_bg = Some(bg);
|
|
||||||
from_col_idx = col_idx;
|
|
||||||
} else if from_bg != Some(bg) {
|
|
||||||
draw_joined_rect(state,
|
|
||||||
ctx,
|
|
||||||
from_col_idx,
|
|
||||||
col_idx,
|
|
||||||
char_width,
|
|
||||||
line_height,
|
|
||||||
from_bg.take().unwrap());
|
|
||||||
from_bg = Some(bg);
|
|
||||||
from_col_idx = col_idx;
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
draw_joined_rect(state,
|
|
||||||
ctx,
|
|
||||||
from_col_idx,
|
|
||||||
model_clip.right + 1,
|
|
||||||
char_width,
|
|
||||||
line_height,
|
|
||||||
from_bg.take().unwrap());
|
|
||||||
|
|
||||||
|
ctx.move_to(current_point.0 + char_width, current_point.1);
|
||||||
|
}
|
||||||
line_y += line_height;
|
line_y += line_height;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -510,6 +477,7 @@ fn draw(state: &State, ctx: &cairo::Context) {
|
|||||||
|
|
||||||
let line_height = state.line_height.unwrap();
|
let line_height = state.line_height.unwrap();
|
||||||
let char_width = state.char_width.unwrap();
|
let char_width = state.char_width.unwrap();
|
||||||
|
let mut draw_bitmap = ModelBitamp::new(state.model.columns, state.model.rows);
|
||||||
|
|
||||||
ctx.set_source_rgb(state.bg_color.0, state.bg_color.1, state.bg_color.2);
|
ctx.set_source_rgb(state.bg_color.0, state.bg_color.1, state.bg_color.2);
|
||||||
ctx.paint();
|
ctx.paint();
|
||||||
@ -526,82 +494,85 @@ fn draw(state: &State, ctx: &cairo::Context) {
|
|||||||
let line_x = model_clip.left as f64 * char_width;
|
let line_x = model_clip.left as f64 * char_width;
|
||||||
let mut line_y: f64 = model_clip.top as f64 * line_height;
|
let mut line_y: f64 = model_clip.top as f64 * line_height;
|
||||||
|
|
||||||
draw_backgound(state, ctx, line_height, char_width, &model_clip);
|
draw_backgound(state, &draw_bitmap, ctx, line_height, char_width, &model_clip);
|
||||||
|
|
||||||
for (line_idx, line) in state.model.clip_model(&model_clip) {
|
for (line_idx, line) in state.model.clip_model(&model_clip) {
|
||||||
|
|
||||||
ctx.move_to(line_x, line_y);
|
ctx.move_to(line_x, line_y);
|
||||||
|
|
||||||
for (col_idx, cell) in line.iter() {
|
for (col_idx, cell) in line.iter() {
|
||||||
let double_width = line.is_double_width(col_idx);
|
|
||||||
let current_point = ctx.get_current_point();
|
let current_point = ctx.get_current_point();
|
||||||
|
|
||||||
let (bg, fg) = state.colors(cell);
|
if !draw_bitmap.get(col_idx, line_idx) {
|
||||||
|
let double_width = line.is_double_width(col_idx);
|
||||||
|
|
||||||
if row == line_idx && col == col_idx {
|
let (bg, fg) = state.colors(cell);
|
||||||
state
|
|
||||||
.cursor
|
|
||||||
.as_ref()
|
|
||||||
.unwrap()
|
|
||||||
.draw(ctx,
|
|
||||||
state,
|
|
||||||
char_width,
|
|
||||||
line_height,
|
|
||||||
line_y,
|
|
||||||
double_width,
|
|
||||||
bg);
|
|
||||||
|
|
||||||
ctx.move_to(current_point.0, current_point.1);
|
if row == line_idx && col == col_idx {
|
||||||
}
|
state
|
||||||
|
.cursor
|
||||||
|
.as_ref()
|
||||||
|
.unwrap()
|
||||||
|
.draw(ctx,
|
||||||
|
state,
|
||||||
|
char_width,
|
||||||
|
line_height,
|
||||||
|
line_y,
|
||||||
|
double_width,
|
||||||
|
bg);
|
||||||
|
|
||||||
|
ctx.move_to(current_point.0, current_point.1);
|
||||||
if !cell.ch.is_whitespace() {
|
|
||||||
update_font_description(&mut desc, &cell.attrs);
|
|
||||||
|
|
||||||
layout.set_font_description(Some(&desc));
|
|
||||||
buf.clear();
|
|
||||||
buf.push(cell.ch);
|
|
||||||
layout.set_text(&buf, -1);
|
|
||||||
|
|
||||||
// correct layout for double_width chars
|
|
||||||
if double_width {
|
|
||||||
let (dw_width, dw_height) = layout.get_pixel_size();
|
|
||||||
let x_offset = (char_width * 2.0 - dw_width as f64) / 2.0;
|
|
||||||
let y_offset = (line_height - dw_height as f64) / 2.0;
|
|
||||||
ctx.rel_move_to(x_offset, y_offset);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ctx.set_source_rgb(fg.0, fg.1, fg.2);
|
|
||||||
pc::update_layout(ctx, &layout);
|
|
||||||
pc::show_layout(ctx, &layout);
|
|
||||||
}
|
|
||||||
|
|
||||||
if cell.attrs.underline || cell.attrs.undercurl {
|
if !cell.ch.is_whitespace() {
|
||||||
// [TODO]: Current gtk-rs bindings does not provide fontmetrics access
|
update_font_description(&mut desc, &cell.attrs);
|
||||||
// so it is not possible to find right position for underline or undercurl position
|
|
||||||
// > update_font_description(&mut desc, &cell.attrs);
|
|
||||||
// > layout.get_context().unwrap().get_metrics();
|
|
||||||
let top_offset = line_height * 0.9;
|
|
||||||
|
|
||||||
let sp = if let Some(ref sp) = cell.attrs.special {
|
layout.set_font_description(Some(&desc));
|
||||||
sp
|
buf.clear();
|
||||||
} else {
|
buf.push(cell.ch);
|
||||||
&state.sp_color
|
layout.set_text(&buf, -1);
|
||||||
};
|
|
||||||
|
|
||||||
ctx.set_source_rgba(sp.0, sp.1, sp.2, 0.7);
|
// correct layout for double_width chars
|
||||||
if cell.attrs.undercurl {
|
if double_width {
|
||||||
ctx.set_dash(&[4.0, 2.0], 0.0);
|
let (dw_width, dw_height) = layout.get_pixel_size();
|
||||||
ctx.set_line_width(2.0);
|
let x_offset = (char_width * 2.0 - dw_width as f64) / 2.0;
|
||||||
ctx.move_to(current_point.0, line_y + top_offset);
|
let y_offset = (line_height - dw_height as f64) / 2.0;
|
||||||
ctx.line_to(current_point.0 + char_width, line_y + top_offset);
|
ctx.rel_move_to(x_offset, y_offset);
|
||||||
ctx.stroke();
|
}
|
||||||
ctx.set_dash(&[], 0.0);
|
|
||||||
} else if cell.attrs.underline {
|
ctx.set_source_rgb(fg.0, fg.1, fg.2);
|
||||||
ctx.set_line_width(1.0);
|
pc::update_layout(ctx, &layout);
|
||||||
ctx.move_to(current_point.0, line_y + top_offset);
|
pc::show_layout(ctx, &layout);
|
||||||
ctx.line_to(current_point.0 + char_width, line_y + top_offset);
|
}
|
||||||
ctx.stroke();
|
|
||||||
|
if cell.attrs.underline || cell.attrs.undercurl {
|
||||||
|
// [TODO]: Current gtk-rs bindings does not provide fontmetrics access
|
||||||
|
// so it is not possible to find right position for underline or undercurl position
|
||||||
|
// > update_font_description(&mut desc, &cell.attrs);
|
||||||
|
// > layout.get_context().unwrap().get_metrics();
|
||||||
|
let top_offset = line_height * 0.9;
|
||||||
|
|
||||||
|
let sp = if let Some(ref sp) = cell.attrs.special {
|
||||||
|
sp
|
||||||
|
} else {
|
||||||
|
&state.sp_color
|
||||||
|
};
|
||||||
|
|
||||||
|
ctx.set_source_rgba(sp.0, sp.1, sp.2, 0.7);
|
||||||
|
if cell.attrs.undercurl {
|
||||||
|
ctx.set_dash(&[4.0, 2.0], 0.0);
|
||||||
|
ctx.set_line_width(2.0);
|
||||||
|
ctx.move_to(current_point.0, line_y + top_offset);
|
||||||
|
ctx.line_to(current_point.0 + char_width, line_y + top_offset);
|
||||||
|
ctx.stroke();
|
||||||
|
ctx.set_dash(&[], 0.0);
|
||||||
|
} else if cell.attrs.underline {
|
||||||
|
ctx.set_line_width(1.0);
|
||||||
|
ctx.move_to(current_point.0, line_y + top_offset);
|
||||||
|
ctx.line_to(current_point.0 + char_width, line_y + top_offset);
|
||||||
|
ctx.stroke();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -610,6 +581,8 @@ fn draw(state: &State, ctx: &cairo::Context) {
|
|||||||
|
|
||||||
line_y += line_height;
|
line_y += line_height;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
draw_bitmap.fill_from_model(&model_clip);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -894,3 +867,54 @@ impl GuiApi for State {
|
|||||||
settings.set_font_source(FontSource::Rpc);
|
settings.set_font_source(FontSource::Rpc);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub struct ModelBitamp {
|
||||||
|
words_for_cols: usize,
|
||||||
|
model: Vec<u64>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ModelBitamp {
|
||||||
|
pub fn new(cols: usize, rows: usize) -> ModelBitamp {
|
||||||
|
let words_for_cols = cols / 64 + 1;
|
||||||
|
|
||||||
|
ModelBitamp {
|
||||||
|
words_for_cols: words_for_cols,
|
||||||
|
model: vec![0; rows * words_for_cols],
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn fill_from_model(&mut self, rect: &ModelRect) {
|
||||||
|
for row in rect.top..rect.bot + 1 {
|
||||||
|
let row_pos = self.words_for_cols * row;
|
||||||
|
for col in rect.left..rect.right + 1 {
|
||||||
|
let col_pos = col / 64;
|
||||||
|
let col_offset = col % 64;
|
||||||
|
self.model[row_pos + col_pos] |= 1 << col_offset;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn get(&self, col: usize, row: usize) -> bool {
|
||||||
|
let row_pos = self.words_for_cols * row;
|
||||||
|
let col_pos = col / 64;
|
||||||
|
let col_offset = col % 64;
|
||||||
|
self.model[row_pos + col_pos] & (1 << col_offset) != 0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests {
|
||||||
|
use super::*;
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_bitmap() {
|
||||||
|
let mut bitmap = ModelBitamp::new(80, 24);
|
||||||
|
bitmap.fill_from_model(&ModelRect::new(22, 22, 63, 68));
|
||||||
|
|
||||||
|
assert_eq!(true, bitmap.get(63, 22));
|
||||||
|
assert_eq!(true, bitmap.get(68, 22));
|
||||||
|
assert_eq!(false, bitmap.get(62, 22));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user