Fix two times repaint

This commit is contained in:
daa84 2017-04-26 12:35:09 +03:00
parent 83b5798f6f
commit 389f47738e

View File

@ -137,6 +137,7 @@ impl State {
let mut rect = rect.as_ref().clone();
// this need to repain also line under curren line
// in case underscore or 'g' symbol is go here
// right one for italic symbol
rect.extend(0, 1, 0, 1);
let (x, y, width, height) = rect.to_area(line_height, char_width);
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)
}
#[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]
fn get_model_clip(state: &State,
line_height: f64,
@ -456,6 +437,7 @@ fn get_model_clip(state: &State,
#[inline]
fn draw_backgound(state: &State,
draw_bitmap: &ModelBitamp,
ctx: &cairo::Context,
line_height: f64,
char_width: f64,
@ -463,40 +445,25 @@ fn draw_backgound(state: &State,
let line_x = model_clip.left as f64 * char_width;
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);
// 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() {
let current_point = ctx.get_current_point();
if !draw_bitmap.get(col_idx, line_idx) {
let (bg, _) = state.colors(cell);
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;
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();
}
}
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;
}
}
@ -510,6 +477,7 @@ fn draw(state: &State, ctx: &cairo::Context) {
let line_height = state.line_height.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.paint();
@ -526,16 +494,18 @@ fn draw(state: &State, ctx: &cairo::Context) {
let line_x = model_clip.left as f64 * char_width;
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) {
ctx.move_to(line_x, line_y);
for (col_idx, cell) in line.iter() {
let double_width = line.is_double_width(col_idx);
let current_point = ctx.get_current_point();
if !draw_bitmap.get(col_idx, line_idx) {
let double_width = line.is_double_width(col_idx);
let (bg, fg) = state.colors(cell);
if row == line_idx && col == col_idx {
@ -604,12 +574,15 @@ fn draw(state: &State, ctx: &cairo::Context) {
ctx.stroke();
}
}
}
ctx.move_to(current_point.0 + char_width, current_point.1);
}
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);
}
}
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));
}
}