Use pango for text layout
This commit is contained in:
parent
dc62753629
commit
673fef7c84
4 changed files with 88 additions and 18 deletions
53
Cargo.lock
generated
53
Cargo.lock
generated
|
@ -909,6 +909,58 @@ version = "1.8.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "692fcb63b64b1758029e0a96ee63e049ce8c5948587f2f7208df04625e5f6b56"
|
checksum = "692fcb63b64b1758029e0a96ee63e049ce8c5948587f2f7208df04625e5f6b56"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "pango"
|
||||||
|
version = "0.14.8"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "546fd59801e5ca735af82839007edd226fe7d3bb06433ec48072be4439c28581"
|
||||||
|
dependencies = [
|
||||||
|
"bitflags",
|
||||||
|
"glib",
|
||||||
|
"libc",
|
||||||
|
"once_cell",
|
||||||
|
"pango-sys",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "pango-sys"
|
||||||
|
version = "0.14.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "2367099ca5e761546ba1d501955079f097caa186bb53ce0f718dca99ac1942fe"
|
||||||
|
dependencies = [
|
||||||
|
"glib-sys",
|
||||||
|
"gobject-sys",
|
||||||
|
"libc",
|
||||||
|
"system-deps",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "pangocairo"
|
||||||
|
version = "0.14.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "f03ac1e8d456f8f436168aeac41201f0bf49d1dc6c8d01bfb04de2cca25df631"
|
||||||
|
dependencies = [
|
||||||
|
"bitflags",
|
||||||
|
"cairo-rs",
|
||||||
|
"glib",
|
||||||
|
"libc",
|
||||||
|
"pango",
|
||||||
|
"pangocairo-sys",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "pangocairo-sys"
|
||||||
|
version = "0.14.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "f3b9b679ad5c8503e3e533ce06e1619d033274b246e977a6fa1655a6c6ef2b51"
|
||||||
|
dependencies = [
|
||||||
|
"cairo-sys-rs",
|
||||||
|
"glib-sys",
|
||||||
|
"libc",
|
||||||
|
"pango-sys",
|
||||||
|
"system-deps",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "parking_lot"
|
name = "parking_lot"
|
||||||
version = "0.11.2"
|
version = "0.11.2"
|
||||||
|
@ -1099,6 +1151,7 @@ dependencies = [
|
||||||
"log",
|
"log",
|
||||||
"mlua",
|
"mlua",
|
||||||
"nix 0.23.0",
|
"nix 0.23.0",
|
||||||
|
"pangocairo",
|
||||||
"rayon",
|
"rayon",
|
||||||
"walkdir",
|
"walkdir",
|
||||||
"winit",
|
"winit",
|
||||||
|
|
|
@ -13,6 +13,7 @@ rayon = "1.5.1"
|
||||||
winit = {git="https://github.com/rust-windowing/winit"}
|
winit = {git="https://github.com/rust-windowing/winit"}
|
||||||
cairo-rs = {version = "0.14.0", features = ["xcb"]}
|
cairo-rs = {version = "0.14.0", features = ["xcb"]}
|
||||||
cairo-sys-rs = {version = "0.14.0", features = ["xcb"]}
|
cairo-sys-rs = {version = "0.14.0", features = ["xcb"]}
|
||||||
|
pangocairo = "0.14.0"
|
||||||
xcb = "0.9.0"
|
xcb = "0.9.0"
|
||||||
xcb-util = {version = "0.3.0", features = ["ewmh", "icccm"]}
|
xcb-util = {version = "0.3.0", features = ["ewmh", "icccm"]}
|
||||||
|
|
||||||
|
|
|
@ -64,7 +64,7 @@ impl<'a> Painter<'a> {
|
||||||
ctx.fill().unwrap();
|
ctx.fill().unwrap();
|
||||||
|
|
||||||
// draw text
|
// draw text
|
||||||
ctx.move_to(x + 0.2, y + 0.8);
|
ctx.move_to(x + 0.2, y+0.8);
|
||||||
ctx.theme_text(&input, false, &[], &self.theme);
|
ctx.theme_text(&input, false, &[], &self.theme);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,8 +1,11 @@
|
||||||
|
use log::debug;
|
||||||
|
use pangocairo::pango::{self, AttrList, Attribute, FontDescription};
|
||||||
|
|
||||||
// (r,g,b,a)
|
// (r,g,b,a)
|
||||||
#[derive(Clone, Copy)]
|
#[derive(Clone, Copy)]
|
||||||
pub struct Color(f64, f64, f64, f64);
|
pub struct Color(f64, f64, f64, f64);
|
||||||
// (name, size)
|
// (name, size)
|
||||||
pub struct Font(String, f64);
|
pub struct Font(String, i32);
|
||||||
|
|
||||||
struct ColorScheme {
|
struct ColorScheme {
|
||||||
base: Color,
|
base: Color,
|
||||||
|
@ -44,7 +47,7 @@ impl Default for Theme {
|
||||||
|
|
||||||
Theme {
|
Theme {
|
||||||
colors,
|
colors,
|
||||||
font: Font("sans".into(), 17.0),
|
font: Font("Sans Regular".into(), 13),
|
||||||
|
|
||||||
border: 2.0,
|
border: 2.0,
|
||||||
divider: 3.0
|
divider: 3.0
|
||||||
|
@ -94,27 +97,40 @@ impl ThemedContextExt for cairo::Context {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn theme_text(&self, text: &str, selected: bool, indices: &[usize], theme: &Theme) {
|
fn theme_text(&self, text: &str, selected: bool, indices: &[usize], theme: &Theme) {
|
||||||
|
self.save().unwrap();
|
||||||
|
|
||||||
|
self.identity_matrix(); // this is extremely important otherwise pango
|
||||||
|
// gets totally confused by active cairo transformations
|
||||||
|
// which then messes with font size, size of attributes, etc
|
||||||
|
|
||||||
let Color(r,g,b,a) = if selected { theme.colors.text_highlight }
|
let Color(r,g,b,a) = if selected { theme.colors.text_highlight }
|
||||||
else { theme.colors.text };
|
else { theme.colors.text };
|
||||||
self.set_source_rgba(r,g,b,a);
|
self.set_source_rgba(r,g,b,a);
|
||||||
|
|
||||||
let font_size = self.device_to_user_point(theme.font.1);
|
let layout = pangocairo::create_layout(self).unwrap();
|
||||||
self.set_font_size(font_size);
|
pangocairo::update_layout(self, &layout);
|
||||||
|
|
||||||
for i in 0..text.len() {
|
let attrlist = AttrList::new();
|
||||||
if indices.contains(&i) {
|
for i in indices {
|
||||||
self.select_font_face(&theme.font.0,
|
let (start, end) = ((*i as u32), (*i as u32)+1);
|
||||||
cairo::FontSlant::Italic,
|
let mut attr = Attribute::new_underline(pangocairo::pango::Underline::Single);
|
||||||
cairo::FontWeight::Normal);
|
attr.set_start_index(start);
|
||||||
} else {
|
attr.set_end_index(end);
|
||||||
self.select_font_face(&theme.font.0,
|
attrlist.insert(attr);
|
||||||
cairo::FontSlant::Normal,
|
|
||||||
cairo::FontWeight::Normal);
|
|
||||||
}
|
|
||||||
|
|
||||||
self.show_text(&text[i..i+1])
|
|
||||||
.expect("Could not draw themed text");
|
|
||||||
}
|
}
|
||||||
|
layout.set_attributes(Some(&attrlist));
|
||||||
|
|
||||||
|
let mut font = FontDescription::default();
|
||||||
|
font.set_family(&theme.font.0);
|
||||||
|
font.set_size(theme.font.1*pango::SCALE);
|
||||||
|
layout.set_font_description(Some(&font));
|
||||||
|
|
||||||
|
layout.set_text(text);
|
||||||
|
|
||||||
|
let (_width,height) = layout.size();
|
||||||
|
self.rel_move_to(0.0, -(height as f64)/(pango::SCALE as f64));
|
||||||
|
pangocairo::show_layout(self, &layout);
|
||||||
|
self.restore().unwrap();
|
||||||
}
|
}
|
||||||
|
|
||||||
fn device_to_user_point(&self, point: f64) -> f64 {
|
fn device_to_user_point(&self, point: f64) -> f64 {
|
||||||
|
|
Loading…
Reference in a new issue