Move rendering to pangocairo

This commit is contained in:
daa 2017-03-06 01:28:07 +03:00
parent 265f525cb6
commit 2a9b71b0fb
4 changed files with 50 additions and 43 deletions

1
Cargo.lock generated
View File

@ -9,6 +9,7 @@ dependencies = [
"glib-sys 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", "glib-sys 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)",
"gtk 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", "gtk 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
"neovim-lib 0.2.0 (git+https://github.com/daa84/neovim-lib)", "neovim-lib 0.2.0 (git+https://github.com/daa84/neovim-lib)",
"pango 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
"pangocairo 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "pangocairo 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
"phf 0.7.21 (registry+https://github.com/rust-lang/crates.io-index)", "phf 0.7.21 (registry+https://github.com/rust-lang/crates.io-index)",
"phf_codegen 0.7.21 (registry+https://github.com/rust-lang/crates.io-index)", "phf_codegen 0.7.21 (registry+https://github.com/rust-lang/crates.io-index)",

View File

@ -6,6 +6,7 @@ build = "build.rs"
[dependencies] [dependencies]
cairo-rs = "0.1" cairo-rs = "0.1"
pango = "0.1"
pangocairo = "0.1" pangocairo = "0.1"
glib = "0.1" glib = "0.1"
glib-sys = "0.3" glib-sys = "0.3"

View File

@ -2,8 +2,10 @@ extern crate gtk;
extern crate gdk; extern crate gdk;
extern crate gdk_sys; extern crate gdk_sys;
extern crate glib; extern crate glib;
extern crate glib_sys; //extern crate glib_sys;
extern crate cairo; extern crate cairo;
extern crate pango;
extern crate pangocairo;
extern crate neovim_lib; extern crate neovim_lib;
extern crate phf; extern crate phf;

View File

@ -4,8 +4,9 @@ use std::collections::HashMap;
use std::string::String; use std::string::String;
use cairo; use cairo;
use cairo::TextExtents; use pangocairo as pc;
use cairo::enums::{FontWeight, FontSlant}; use pango;
use pango::FontDescription;
use gtk; use gtk;
use gtk::prelude::*; use gtk::prelude::*;
use gtk::{Window, WindowType, DrawingArea, Grid, ToolButton, Image, Toolbar, IconSize}; use gtk::{Window, WindowType, DrawingArea, Grid, ToolButton, Image, Toolbar, IconSize};
@ -20,10 +21,9 @@ use nvim::RedrawEvents;
use input::{convert_key, keyval_to_input_string}; use input::{convert_key, keyval_to_input_string};
#[cfg(target_os = "linux")] #[cfg(target_os = "linux")]
const FONT_NAME: &'static str = "Droid Sans Mono for Powerline"; const FONT_NAME: &'static str = "Droid Sans Mono for Powerline 12";
#[cfg(target_os = "windows")] #[cfg(target_os = "windows")]
const FONT_NAME: &'static str = "DejaVu Sans Mono"; const FONT_NAME: &'static str = "DejaVu Sans Mono 12";
const FONT_SIZE: f64 = 12.0;
thread_local!(pub static UI: RefCell<Ui> = { thread_local!(pub static UI: RefCell<Ui> = {
let thread = thread::current(); let thread = thread::current();
@ -204,21 +204,13 @@ fn gtk_key_press(_: &Window, ev: &EventKey) -> Inhibit {
} }
} }
fn calc_char_bounds(ctx: &cairo::Context) -> TextExtents {
let font_face = cairo::FontFace::toy_create(FONT_NAME, FontSlant::Normal, FontWeight::Normal);
ctx.set_font_size(FONT_SIZE);
ctx.set_font_face(font_face);
ctx.text_extents("A")
}
fn gtk_draw(_: &DrawingArea, ctx: &cairo::Context) -> Inhibit { fn gtk_draw(_: &DrawingArea, ctx: &cairo::Context) -> Inhibit {
UI.with(|ui_cell| { UI.with(|ui_cell| {
let mut ui = ui_cell.borrow_mut(); let mut ui = ui_cell.borrow_mut();
let char_bounds = calc_char_bounds(ctx); let (width, height) = calc_char_bounds(ctx);
let font_extents = ctx.font_extents(); ui.line_height = Some(height as f64);
ui.line_height = Some(font_extents.height.round()); ui.char_width = Some(width as f64);
ui.char_width = Some(char_bounds.width.round());
draw(&*ui, ctx); draw(&*ui, ctx);
request_width(&*ui); request_width(&*ui);
@ -259,43 +251,42 @@ fn gtk_configure_event(_: &DrawingArea, ev: &EventConfigure) -> bool {
false false
} }
fn font_description() -> FontDescription {
FontDescription::from_string(FONT_NAME)
}
fn draw(ui: &Ui, ctx: &cairo::Context) { fn draw(ui: &Ui, ctx: &cairo::Context) {
ctx.set_source_rgb(ui.bg_color.0, ui.bg_color.1, ui.bg_color.2); ctx.set_source_rgb(ui.bg_color.0, ui.bg_color.1, ui.bg_color.2);
ctx.paint(); ctx.paint();
let font_extents = ctx.font_extents();
let line_height = ui.line_height.unwrap(); let line_height = ui.line_height.unwrap();
let char_width = ui.char_width.unwrap(); let char_width = ui.char_width.unwrap();
let (row, col) = ui.model.get_cursor(); let (row, col) = ui.model.get_cursor();
let mut line_y = line_height; let mut line_y: f64 = 0.0;
let layout = pc::create_layout(ctx);
for (line_idx, line) in ui.model.model().iter().enumerate() { for (line_idx, line) in ui.model.model().iter().enumerate() {
ctx.move_to(0.0, line_y - font_extents.descent); ctx.move_to(0.0, line_y);
for (col_idx, cell) in line.iter().enumerate() { for (col_idx, cell) in line.iter().enumerate() {
let slant = if cell.attrs.italic { let mut desc = font_description();
FontSlant::Italic if cell.attrs.italic {
} else { desc.set_style(pango::Style::Italic);
FontSlant::Normal }
}; if cell.attrs.bold {
desc.set_weight(pango::Weight::Bold);
}
layout.set_font_description(Some(&desc));
layout.set_text(&cell.ch.to_string(), -1);
let weight = if cell.attrs.bold {
FontWeight::Bold
} else {
FontWeight::Normal
};
let font_face = cairo::FontFace::toy_create(FONT_NAME, slant, weight);
ctx.set_font_face(font_face);
ctx.set_font_size(FONT_SIZE);
let current_point = ctx.get_current_point(); let current_point = ctx.get_current_point();
if let Some(ref bg) = cell.attrs.background { if let Some(ref bg) = cell.attrs.background {
ctx.set_source_rgb(bg.0, bg.1, bg.2); ctx.set_source_rgb(bg.0, bg.1, bg.2);
ctx.rectangle(current_point.0, ctx.rectangle(current_point.0, line_y, char_width, line_height);
line_y - line_height,
char_width,
line_height);
ctx.fill(); ctx.fill();
ctx.move_to(current_point.0, current_point.1); ctx.move_to(current_point.0, current_point.1);
@ -322,20 +313,32 @@ fn draw(ui: &Ui, ctx: &cairo::Context) {
char_width char_width
}; };
ctx.rectangle(current_point.0, ctx.rectangle(current_point.0, line_y, cursor_width, line_height);
line_y - line_height,
cursor_width,
line_height);
ctx.fill(); ctx.fill();
ctx.move_to(current_point.0, current_point.1); ctx.move_to(current_point.0, current_point.1);
} }
ctx.set_source_rgb(fg.0, fg.1, fg.2); ctx.set_source_rgb(fg.0, fg.1, fg.2);
ctx.show_text(&cell.ch.to_string()); pc::update_layout(ctx, &layout);
pc::show_layout(ctx, &layout);
ctx.move_to(current_point.0 + char_width, current_point.1); ctx.move_to(current_point.0 + char_width, current_point.1);
} }
line_y += line_height; line_y += line_height;
} }
}
fn calc_char_bounds(ctx: &cairo::Context) -> (i32, i32) {
let layout = pc::create_layout(ctx);
let desc = font_description();
layout.set_font_description(Some(&desc));
layout.set_text("A", -1);
layout.get_pixel_size()
} }
fn request_width(ui: &Ui) { fn request_width(ui: &Ui) {