Implement font features (#94)
This commit is contained in:
parent
2dc10aa611
commit
ad0ea04f93
@ -6,7 +6,6 @@ build = "build.rs"
|
||||
|
||||
[dependencies]
|
||||
cairo-rs = "0.4"
|
||||
pango = "0.4"
|
||||
pango-sys = "0.6"
|
||||
pangocairo = "0.5"
|
||||
pangocairo-sys = "0.7"
|
||||
@ -51,6 +50,10 @@ atty = "0.2"
|
||||
[build-dependencies]
|
||||
phf_codegen = "0.7"
|
||||
|
||||
[dependencies.pango]
|
||||
features = ["v1_38"]
|
||||
version = "0.4"
|
||||
|
||||
[dependencies.gtk]
|
||||
version = "0.4"
|
||||
features = ["v3_22"]
|
||||
|
@ -52,8 +52,10 @@ function s:GuiFontCommand(fname, bang) abort
|
||||
call GuiFont(a:fname, a:bang ==# '!')
|
||||
endif
|
||||
endfunction
|
||||
command! -nargs=? -bang Guifont call s:GuiFontCommand("<args>", "<bang>")
|
||||
command! -nargs=? -bang GuiFont call s:GuiFontCommand("<args>", "<bang>")
|
||||
command! -nargs=1 -bang Guifont call s:GuiFontCommand("<args>", "<bang>")
|
||||
command! -nargs=1 -bang GuiFont call s:GuiFontCommand("<args>", "<bang>")
|
||||
|
||||
command! -nargs=? GuiFontFeatures call rpcnotify(1, 'Gui', 'FontFeatures', <q-args>)
|
||||
|
||||
command! NGToggleSidebar call rpcnotify(1, 'Gui', 'Command', 'ToggleSidebar')
|
||||
|
||||
|
@ -86,6 +86,7 @@ pub fn call_gui_event(
|
||||
) -> result::Result<(), String> {
|
||||
match method {
|
||||
"Font" => call!(ui->set_font(args: str)),
|
||||
"FontFeatures" => call!(ui->set_font_features(args: str)),
|
||||
"Clipboard" => match try_str!(args[0]) {
|
||||
"Set" => match try_str!(args[1]) {
|
||||
"*" => ui.clipboard_primary_set(try_str!(args[2])),
|
||||
|
@ -8,18 +8,24 @@ use ui_model::StyledLine;
|
||||
use super::itemize::ItemizeIterator;
|
||||
|
||||
pub struct Context {
|
||||
state: ContextState,
|
||||
font_metrics: FontMetrix,
|
||||
font_features: FontFeatures,
|
||||
}
|
||||
|
||||
impl Context {
|
||||
pub fn new(pango_context: pango::Context) -> Self {
|
||||
Context {
|
||||
state: ContextState::new(pango_context),
|
||||
font_metrics: FontMetrix::new(pango_context),
|
||||
font_features: FontFeatures::new(),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn update(&mut self, pango_context: pango::Context) {
|
||||
self.state = ContextState::new(pango_context);
|
||||
self.font_metrics = FontMetrix::new(pango_context);
|
||||
}
|
||||
|
||||
pub fn update_font_features(&mut self, font_features: FontFeatures) {
|
||||
self.font_features = font_features;
|
||||
}
|
||||
|
||||
pub fn itemize(&self, line: &StyledLine) -> Vec<sys_pango::Item> {
|
||||
@ -28,7 +34,7 @@ impl Context {
|
||||
ItemizeIterator::new(&line.line_str)
|
||||
.flat_map(|(offset, len)| {
|
||||
sys_pango::pango_itemize(
|
||||
&self.state.pango_context,
|
||||
&self.font_metrics.pango_context,
|
||||
&line.line_str,
|
||||
offset,
|
||||
len,
|
||||
@ -40,32 +46,34 @@ impl Context {
|
||||
}
|
||||
|
||||
pub fn create_layout(&self) -> pango::Layout {
|
||||
pango::Layout::new(&self.state.pango_context)
|
||||
pango::Layout::new(&self.font_metrics.pango_context)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn font_description(&self) -> &pango::FontDescription {
|
||||
&self.state.font_desc
|
||||
&self.font_metrics.font_desc
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn cell_metrics(&self) -> &CellMetrics {
|
||||
&self.state.cell_metrics
|
||||
&self.font_metrics.cell_metrics
|
||||
}
|
||||
|
||||
pub fn font_features(&self) -> &FontFeatures {
|
||||
&self.font_features
|
||||
}
|
||||
}
|
||||
|
||||
struct ContextState {
|
||||
struct FontMetrix {
|
||||
pango_context: pango::Context,
|
||||
cell_metrics: CellMetrics,
|
||||
font_desc: pango::FontDescription,
|
||||
}
|
||||
|
||||
impl ContextState {
|
||||
impl FontMetrix {
|
||||
pub fn new(pango_context: pango::Context) -> Self {
|
||||
let font_metrics = pango_context.get_metrics(None, None).unwrap();
|
||||
let font_desc = pango_context.get_font_description().unwrap();
|
||||
|
||||
ContextState {
|
||||
FontMetrix {
|
||||
pango_context,
|
||||
cell_metrics: CellMetrics::new(&font_metrics),
|
||||
font_desc,
|
||||
@ -115,3 +123,34 @@ impl CellMetrics {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -2,7 +2,7 @@ mod context;
|
||||
mod itemize;
|
||||
mod model_clip_iterator;
|
||||
|
||||
pub use self::context::Context;
|
||||
pub use self::context::{Context, FontFeatures};
|
||||
pub use self::context::CellMetrics;
|
||||
use self::model_clip_iterator::{ModelClipIteratorFactory, RowView};
|
||||
|
||||
@ -210,7 +210,7 @@ pub fn shape_dirty(
|
||||
) {
|
||||
for line in ui_model.model_mut() {
|
||||
if line.dirty_line {
|
||||
let styled_line = ui_model::StyledLine::from(line, color_model);
|
||||
let styled_line = ui_model::StyledLine::from(line, color_model, ctx.font_features());
|
||||
let items = ctx.itemize(&styled_line);
|
||||
line.merge(&styled_line, &items);
|
||||
|
||||
|
11
src/shell.rs
11
src/shell.rs
@ -276,6 +276,17 @@ impl State {
|
||||
self.on_redraw(&RepaintMode::All);
|
||||
}
|
||||
|
||||
pub fn set_font_features(&mut self, font_features: String) {
|
||||
let font_features = render::FontFeatures::from(font_features);
|
||||
|
||||
self.render_state
|
||||
.borrow_mut()
|
||||
.font_ctx
|
||||
.update_font_features(font_features);
|
||||
self.model.clear_glyphs();
|
||||
self.on_redraw(&RepaintMode::All);
|
||||
}
|
||||
|
||||
pub fn open_file(&self, path: &str) {
|
||||
if let Some(mut nvim) = self.nvim() {
|
||||
nvim.command_async(&format!("e {}", path))
|
||||
|
12
src/sys/pango/attribute.rs
Normal file
12
src/sys/pango/attribute.rs
Normal file
@ -0,0 +1,12 @@
|
||||
use pango_sys;
|
||||
use pango;
|
||||
|
||||
use glib::translate::*;
|
||||
|
||||
pub fn new_features(features: &str) -> Option<pango::Attribute> {
|
||||
unsafe {
|
||||
from_glib_full(pango_sys::pango_attr_font_features_new(
|
||||
features.to_glib_none().0,
|
||||
))
|
||||
}
|
||||
}
|
@ -2,6 +2,8 @@ mod item;
|
||||
mod analysis;
|
||||
mod attr_iterator;
|
||||
|
||||
pub mod attribute;
|
||||
|
||||
pub use self::item::Item;
|
||||
pub use self::analysis::Analysis;
|
||||
pub use self::attr_iterator::{AttrIterator, AttrIteratorFactory};
|
||||
|
@ -1,10 +1,12 @@
|
||||
use std::ops::{Index, IndexMut};
|
||||
|
||||
use sys::pango as sys_pango;
|
||||
use pango;
|
||||
|
||||
use render;
|
||||
use color;
|
||||
use super::cell::Cell;
|
||||
use super::item::Item;
|
||||
use sys::pango as sys_pango;
|
||||
use pango;
|
||||
|
||||
pub struct Line {
|
||||
pub line: Box<[Cell]>,
|
||||
@ -242,8 +244,7 @@ pub struct StyledLine {
|
||||
}
|
||||
|
||||
impl StyledLine {
|
||||
pub fn from(line: &Line, color_model: &color::ColorModel) -> Self {
|
||||
|
||||
pub fn from(line: &Line, color_model: &color::ColorModel, font_features: &render::FontFeatures) -> Self {
|
||||
let average_capacity = line.line.len() * 4 * 2; // code bytes * grapheme cluster
|
||||
|
||||
let mut line_str = String::with_capacity(average_capacity);
|
||||
@ -278,6 +279,7 @@ impl StyledLine {
|
||||
}
|
||||
|
||||
style_attr.insert(&attr_list);
|
||||
font_features.insert_attr(&attr_list, line_str.len());
|
||||
|
||||
StyledLine {
|
||||
line_str,
|
||||
@ -410,7 +412,7 @@ mod tests {
|
||||
line[1].ch = "b".to_owned();
|
||||
line[2].ch = "c".to_owned();
|
||||
|
||||
let styled_line = StyledLine::from(&line, &color::ColorModel::new());
|
||||
let styled_line = StyledLine::from(&line, &color::ColorModel::new(), &render::FontFeatures::new());
|
||||
assert_eq!("abc", styled_line.line_str);
|
||||
assert_eq!(3, styled_line.cell_to_byte.len());
|
||||
assert_eq!(0, styled_line.cell_to_byte[0]);
|
||||
|
Loading…
Reference in New Issue
Block a user