Drawing optimization
This commit is contained in:
@@ -3,8 +3,10 @@ use pango::prelude::*;
|
||||
use pango;
|
||||
|
||||
use sys::pango as sys_pango;
|
||||
use sys::pango::AttrIteratorFactory;
|
||||
|
||||
use ui_model::StyledLine;
|
||||
use super::itemize::ItemizeIterator;
|
||||
|
||||
pub struct Context {
|
||||
state: ContextState,
|
||||
@@ -20,11 +22,20 @@ impl Context {
|
||||
}
|
||||
|
||||
pub fn itemize(&self, line: &StyledLine) -> Vec<sys_pango::Item> {
|
||||
sys_pango::pango_itemize(
|
||||
&self.state.pango_context,
|
||||
line.line_str.trim_right(),
|
||||
&line.attr_list,
|
||||
)
|
||||
let mut attr_iter = line.attr_list.get_iterator();
|
||||
|
||||
ItemizeIterator::new(&line.line_str)
|
||||
.flat_map(|(offset, len)| {
|
||||
sys_pango::pango_itemize(
|
||||
&self.state.pango_context,
|
||||
&line.line_str,
|
||||
offset,
|
||||
len,
|
||||
&line.attr_list,
|
||||
Some(&mut attr_iter),
|
||||
)
|
||||
})
|
||||
.collect()
|
||||
}
|
||||
|
||||
#[inline]
|
||||
@@ -94,4 +105,18 @@ impl CellMetrics {
|
||||
pango::SCALE as f64,
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
pub fn new_hw(line_height: f64, char_width: f64) -> Self {
|
||||
CellMetrics {
|
||||
pango_ascent: 0,
|
||||
pango_descent: 0,
|
||||
pango_char_width: 0,
|
||||
ascent: 0.0,
|
||||
line_height,
|
||||
char_width,
|
||||
underline_position: 0.0,
|
||||
underline_thickness: 0.0,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
58
src/render/itemize.rs
Normal file
58
src/render/itemize.rs
Normal file
@@ -0,0 +1,58 @@
|
||||
use std::str::CharIndices;
|
||||
|
||||
pub struct ItemizeIterator <'a> {
|
||||
char_iter: CharIndices<'a>,
|
||||
line: &'a str,
|
||||
}
|
||||
|
||||
impl <'a> ItemizeIterator <'a> {
|
||||
pub fn new(line: &'a str) -> Self {
|
||||
ItemizeIterator {
|
||||
char_iter: line.char_indices(),
|
||||
line,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl <'a> Iterator for ItemizeIterator<'a> {
|
||||
type Item = (usize, usize);
|
||||
|
||||
fn next(&mut self) -> Option<Self::Item> {
|
||||
let mut start_index = None;
|
||||
|
||||
let end_index = loop {
|
||||
if let Some((index, ch)) = self.char_iter.next() {
|
||||
let is_whitespace = ch.is_whitespace();
|
||||
|
||||
if start_index.is_none() && !is_whitespace {
|
||||
start_index = Some(index);
|
||||
}
|
||||
if start_index.is_some() && is_whitespace {
|
||||
break index;
|
||||
}
|
||||
} else {
|
||||
break self.line.len();
|
||||
}
|
||||
};
|
||||
|
||||
if let Some(start_index) = start_index {
|
||||
Some((start_index, end_index - start_index))
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn test_iterator() {
|
||||
let mut iter = ItemizeIterator::new("Test line ");
|
||||
|
||||
assert_eq!(Some((0, 4)), iter.next());
|
||||
assert_eq!(Some((6, 4)), iter.next());
|
||||
assert_eq!(None, iter.next());
|
||||
}
|
||||
}
|
||||
@@ -1,4 +1,5 @@
|
||||
mod context;
|
||||
mod itemize;
|
||||
|
||||
pub use self::context::Context;
|
||||
pub use self::context::CellMetrics;
|
||||
@@ -77,6 +78,7 @@ pub fn render(
|
||||
|
||||
if cell.attrs.underline || cell.attrs.undercurl {
|
||||
if cell.attrs.undercurl {
|
||||
// TODO: properly draw undercurl
|
||||
let sp = color_model.actual_cell_sp(cell);
|
||||
ctx.set_source_rgba(sp.0, sp.1, sp.2, 0.7);
|
||||
ctx.set_dash(&[4.0, 2.0], 0.0);
|
||||
|
||||
Reference in New Issue
Block a user