neovim-gtk/src/render/context.rs

157 lines
4.3 KiB
Rust
Raw Normal View History

2017-08-24 14:41:20 +00:00
use pango::prelude::*;
use pango;
2017-08-26 20:17:09 +00:00
use sys::pango as sys_pango;
2017-09-11 15:00:51 +00:00
use sys::pango::AttrIteratorFactory;
2017-08-24 14:41:20 +00:00
use ui_model::StyledLine;
2017-09-11 15:00:51 +00:00
use super::itemize::ItemizeIterator;
2017-08-24 14:41:20 +00:00
pub struct Context {
2018-05-06 12:22:38 +00:00
font_metrics: FontMetrix,
font_features: FontFeatures,
2017-08-24 14:41:20 +00:00
}
impl Context {
2018-04-29 19:43:35 +00:00
pub fn new(pango_context: pango::Context) -> Self {
2018-01-21 20:19:00 +00:00
Context {
2018-05-06 12:22:38 +00:00
font_metrics: FontMetrix::new(pango_context),
font_features: FontFeatures::new(),
2018-01-21 20:19:00 +00:00
}
2017-08-24 14:41:20 +00:00
}
2018-04-29 19:43:35 +00:00
pub fn update(&mut self, pango_context: pango::Context) {
2018-05-06 12:22:38 +00:00
self.font_metrics = FontMetrix::new(pango_context);
}
pub fn update_font_features(&mut self, font_features: FontFeatures) {
self.font_features = font_features;
2017-08-24 14:41:20 +00:00
}
2017-08-26 20:17:09 +00:00
pub fn itemize(&self, line: &StyledLine) -> Vec<sys_pango::Item> {
2017-09-11 15:00:51 +00:00
let mut attr_iter = line.attr_list.get_iterator();
ItemizeIterator::new(&line.line_str)
.flat_map(|(offset, len)| {
sys_pango::pango_itemize(
2018-05-06 12:22:38 +00:00
&self.font_metrics.pango_context,
2017-09-11 15:00:51 +00:00
&line.line_str,
offset,
len,
&line.attr_list,
Some(&mut attr_iter),
)
})
.collect()
2017-08-24 14:41:20 +00:00
}
2017-09-05 15:23:46 +00:00
pub fn create_layout(&self) -> pango::Layout {
2018-05-06 12:22:38 +00:00
pango::Layout::new(&self.font_metrics.pango_context)
}
2017-09-05 15:23:46 +00:00
pub fn font_description(&self) -> &pango::FontDescription {
2018-05-06 12:22:38 +00:00
&self.font_metrics.font_desc
2017-09-05 15:23:46 +00:00
}
pub fn cell_metrics(&self) -> &CellMetrics {
2018-05-06 12:22:38 +00:00
&self.font_metrics.cell_metrics
}
pub fn font_features(&self) -> &FontFeatures {
&self.font_features
2017-09-05 15:23:46 +00:00
}
}
2018-05-06 12:22:38 +00:00
struct FontMetrix {
2017-09-05 15:23:46 +00:00
pango_context: pango::Context,
cell_metrics: CellMetrics,
font_desc: pango::FontDescription,
}
2018-05-06 12:22:38 +00:00
impl FontMetrix {
2018-04-29 19:43:35 +00:00
pub fn new(pango_context: pango::Context) -> Self {
2017-09-05 15:23:46 +00:00
let font_metrics = pango_context.get_metrics(None, None).unwrap();
2018-04-29 19:43:35 +00:00
let font_desc = pango_context.get_font_description().unwrap();
2017-09-05 15:23:46 +00:00
2018-05-06 12:22:38 +00:00
FontMetrix {
2017-09-05 15:23:46 +00:00
pango_context,
cell_metrics: CellMetrics::new(&font_metrics),
font_desc,
}
}
2017-08-24 14:41:20 +00:00
}
2017-09-05 15:23:46 +00:00
pub struct CellMetrics {
pub line_height: f64,
pub char_width: f64,
pub ascent: f64,
2017-09-09 20:02:06 +00:00
pub underline_position: f64,
pub underline_thickness: f64,
2017-09-08 15:26:16 +00:00
pub pango_ascent: i32,
pub pango_descent: i32,
pub pango_char_width: i32,
2017-09-05 15:23:46 +00:00
}
2017-08-24 14:41:20 +00:00
2017-09-05 15:23:46 +00:00
impl CellMetrics {
fn new(font_metrics: &pango::FontMetrics) -> Self {
CellMetrics {
2017-09-08 15:26:16 +00:00
pango_ascent: font_metrics.get_ascent(),
pango_descent: font_metrics.get_descent(),
pango_char_width: font_metrics.get_approximate_digit_width(),
2017-09-05 15:23:46 +00:00
ascent: font_metrics.get_ascent() as f64 / pango::SCALE as f64,
2018-01-21 20:19:00 +00:00
line_height: (font_metrics.get_ascent() + font_metrics.get_descent()) as f64
/ pango::SCALE as f64,
2017-09-05 15:23:46 +00:00
char_width: font_metrics.get_approximate_digit_width() as f64 / pango::SCALE as f64,
2018-01-21 20:19:00 +00:00
underline_position: (font_metrics.get_ascent() - font_metrics.get_underline_position())
as f64 / pango::SCALE as f64,
underline_thickness: font_metrics.get_underline_thickness() as f64
/ pango::SCALE as f64,
2017-09-05 15:23:46 +00:00
}
}
2017-09-11 15:00:51 +00:00
#[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,
}
}
2017-08-24 14:41:20 +00:00
}
2018-05-06 12:22:38 +00:00
pub struct FontFeatures {
features: Option<String>,
}
impl FontFeatures {
pub fn new() -> Self {
FontFeatures {
features: None,
}
}
pub fn from(font_features: String) -> Self {
if font_features.trim().is_empty() {
return Self::new();
}
FontFeatures {
features: Some(font_features)
}
}
pub fn insert_attr(&self, attr_list: &pango::AttrList, end_idx: usize) {
if let Some(ref features) = self.features {
let mut attr = sys_pango::attribute::new_features(features).unwrap();
attr.set_start_index(0);
attr.set_end_index(end_idx as u32);
attr_list.insert(attr);
}
}
}