core: graphics: use key part text
Some keys may have no XKB key symbols. Instead of a hash table mapping XKB key symbols to their labels, repurpose the text from the key part.
This commit is contained in:
parent
5aaaedb887
commit
bc9056aa8d
1 changed files with 73 additions and 141 deletions
|
|
@ -19,7 +19,6 @@ use std::io::Read;
|
||||||
use std::iter;
|
use std::iter;
|
||||||
use std::ptr;
|
use std::ptr;
|
||||||
use std::sync::atomic::AtomicPtr;
|
use std::sync::atomic::AtomicPtr;
|
||||||
use xkeysym::Keysym;
|
|
||||||
|
|
||||||
fn convert_gray_to_bgrx(mut dest: ImgRefMut<BGRA<u8>>, src: ImgRef<u8>, fg_color: BGR<f32>)
|
fn convert_gray_to_bgrx(mut dest: ImgRefMut<BGRA<u8>>, src: ImgRef<u8>, fg_color: BGR<f32>)
|
||||||
{
|
{
|
||||||
|
|
@ -78,8 +77,8 @@ pub struct Graphics<D: Display> {
|
||||||
disp: D,
|
disp: D,
|
||||||
fonts: Vec<(String, freetype::FT_Long)>,
|
fonts: Vec<(String, freetype::FT_Long)>,
|
||||||
fontbufs: Vec<Vec<u8>>,
|
fontbufs: Vec<Vec<u8>>,
|
||||||
labels: HashMap<Keysym, ImgVec<u8>>,
|
labels: HashMap<String, ImgVec<u8>>,
|
||||||
sublabels: HashMap<Keysym, ImgVec<u8>>,
|
sublabels: HashMap<String, ImgVec<u8>>,
|
||||||
ft: AtomicPtr<freetype::FT_LibraryRec_>,
|
ft: AtomicPtr<freetype::FT_LibraryRec_>,
|
||||||
|
|
||||||
x_scale: f64,
|
x_scale: f64,
|
||||||
|
|
@ -87,103 +86,54 @@ pub struct Graphics<D: Display> {
|
||||||
}
|
}
|
||||||
|
|
||||||
struct Label<'a> {
|
struct Label<'a> {
|
||||||
sym: Keysym,
|
|
||||||
label: &'a str,
|
label: &'a str,
|
||||||
secondary: bool,
|
secondary: bool,
|
||||||
small: bool,
|
small: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
const LABELS: [Label; 43] = [
|
const LABELS: [Label; 21] = [
|
||||||
Label { sym: Keysym::Greek_MU, label: "\u{039C}",
|
Label { label: "Alt",
|
||||||
secondary: false, small: false, },
|
|
||||||
Label { sym: Keysym::emdash, label: "\u{2014}",
|
|
||||||
secondary: false, small: false, },
|
|
||||||
Label { sym: Keysym::endash, label: "\u{2013}",
|
|
||||||
secondary: false, small: false, },
|
|
||||||
Label { sym: Keysym::ellipsis, label: "\u{2026}",
|
|
||||||
secondary: false, small: false, },
|
|
||||||
Label { sym: Keysym::leftsinglequotemark, label: "\u{2018}",
|
|
||||||
secondary: false, small: false, },
|
|
||||||
Label { sym: Keysym::rightsinglequotemark, label: "\u{2019}",
|
|
||||||
secondary: false, small: false, },
|
|
||||||
Label { sym: Keysym::leftdoublequotemark, label: "\u{201C}",
|
|
||||||
secondary: false, small: false, },
|
|
||||||
Label { sym: Keysym::rightdoublequotemark, label: "\u{201D}",
|
|
||||||
secondary: false, small: false, },
|
|
||||||
Label { sym: Keysym::permille, label: "\u{2030}",
|
|
||||||
secondary: false, small: false, },
|
|
||||||
Label { sym: Keysym::singlelowquotemark, label: "\u{201A}",
|
|
||||||
secondary: false, small: false, },
|
|
||||||
Label { sym: Keysym::doublelowquotemark, label: "\u{201E}",
|
|
||||||
secondary: false, small: false, },
|
|
||||||
Label { sym: Keysym::OE, label: "\u{0152}",
|
|
||||||
secondary: false, small: false, },
|
|
||||||
Label { sym: Keysym::oe, label: "\u{0153}",
|
|
||||||
secondary: false, small: false, },
|
|
||||||
Label { sym: Keysym::BackSpace, label: "\u{232B}",
|
|
||||||
secondary: true, small: false, },
|
|
||||||
Label { sym: Keysym::Tab, label: "\u{2B7E}",
|
|
||||||
secondary: true, small: true, },
|
secondary: true, small: true, },
|
||||||
Label { sym: Keysym::Return, label: "\u{23CE}",
|
Label { label: "Ctrl",
|
||||||
secondary: true, small: false, },
|
|
||||||
Label { sym: Keysym::Escape, label: "Esc",
|
|
||||||
secondary: true, small: true, },
|
secondary: true, small: true, },
|
||||||
Label { sym: Keysym::Home, label: "\u{21E4}",
|
Label { label: "Esc",
|
||||||
secondary: true, small: false, },
|
|
||||||
Label { sym: Keysym::Left, label: "\u{2190}",
|
|
||||||
secondary: true, small: false, },
|
|
||||||
Label { sym: Keysym::Up, label: "\u{2191}",
|
|
||||||
secondary: true, small: false, },
|
|
||||||
Label { sym: Keysym::Right, label: "\u{2192}",
|
|
||||||
secondary: true, small: false, },
|
|
||||||
Label { sym: Keysym::Down, label: "\u{2193}",
|
|
||||||
secondary: true, small: false, },
|
|
||||||
Label { sym: Keysym::Page_Up, label: "\u{21D1}",
|
|
||||||
secondary: true, small: false, },
|
|
||||||
Label { sym: Keysym::Page_Down, label: "\u{21D3}",
|
|
||||||
secondary: true, small: false, },
|
|
||||||
Label { sym: Keysym::End, label: "\u{21E5}",
|
|
||||||
secondary: true, small: false, },
|
|
||||||
Label { sym: Keysym::Insert, label: "Ins",
|
|
||||||
secondary: true, small: true, },
|
secondary: true, small: true, },
|
||||||
Label { sym: Keysym::F1, label: "F1",
|
Label { label: "F11",
|
||||||
secondary: false, small: false, },
|
|
||||||
Label { sym: Keysym::F2, label: "F2",
|
|
||||||
secondary: false, small: false, },
|
|
||||||
Label { sym: Keysym::F3, label: "F3",
|
|
||||||
secondary: false, small: false, },
|
|
||||||
Label { sym: Keysym::F4, label: "F4",
|
|
||||||
secondary: false, small: false, },
|
|
||||||
Label { sym: Keysym::F5, label: "F5",
|
|
||||||
secondary: false, small: false, },
|
|
||||||
Label { sym: Keysym::F6, label: "F6",
|
|
||||||
secondary: false, small: false, },
|
|
||||||
Label { sym: Keysym::F7, label: "F7",
|
|
||||||
secondary: false, small: false, },
|
|
||||||
Label { sym: Keysym::F8, label: "F8",
|
|
||||||
secondary: false, small: false, },
|
|
||||||
Label { sym: Keysym::F9, label: "F9",
|
|
||||||
secondary: false, small: false, },
|
|
||||||
Label { sym: Keysym::F10, label: "F10",
|
|
||||||
secondary: false, small: false, },
|
|
||||||
Label { sym: Keysym::F11, label: "F11",
|
|
||||||
secondary: false, small: true, },
|
secondary: false, small: true, },
|
||||||
Label { sym: Keysym::F12, label: "F12",
|
Label { label: "F12",
|
||||||
secondary: false, small: true, },
|
secondary: false, small: true, },
|
||||||
Label { sym: Keysym::Shift_L, label: "\u{21E7}",
|
Label { label: "Fn",
|
||||||
|
secondary: true, small: true, },
|
||||||
|
Label { label: "Ins",
|
||||||
|
secondary: true, small: true, },
|
||||||
|
Label { label: "\u{2190}", // LEFTWARDS ARROW
|
||||||
secondary: true, small: false, },
|
secondary: true, small: false, },
|
||||||
Label { sym: Keysym::Control_L, label: "Ctrl",
|
Label { label: "\u{2191}", // UPWARDS ARROW
|
||||||
secondary: true, small: true, },
|
|
||||||
Label { sym: Keysym::Alt_L, label: "Alt",
|
|
||||||
secondary: true, small: true, },
|
|
||||||
Label { sym: Keysym::Delete, label: "\u{2326}",
|
|
||||||
secondary: true, small: false, },
|
secondary: true, small: false, },
|
||||||
Label { sym: Keysym::XF86_Fn, label: "Fn",
|
Label { label: "\u{2192}", // RIGHTWARDS ARROW
|
||||||
|
secondary: true, small: false, },
|
||||||
|
Label { label: "\u{2193}", // DOWNWARDS ARROW
|
||||||
|
secondary: true, small: false, },
|
||||||
|
Label { label: "\u{21D1}", // UPWARDS DOUBLE ARROW
|
||||||
|
secondary: true, small: false, },
|
||||||
|
Label { label: "\u{21D3}", // DOWNWARDS DOUBLE ARROW
|
||||||
|
secondary: true, small: false, },
|
||||||
|
Label { label: "\u{21E4}", // LEFTWARDS ARROW TO BAR
|
||||||
|
secondary: true, small: false, },
|
||||||
|
Label { label: "\u{21E5}", // RIGHTWARDS ARROW TO BAR
|
||||||
|
secondary: true, small: false, },
|
||||||
|
Label { label: "\u{21E7}", // UPWARDS WHITE ARROW
|
||||||
|
secondary: true, small: false, },
|
||||||
|
Label { label: "\u{2326}", // ERASE TO THE RIGHT
|
||||||
|
secondary: true, small: false, },
|
||||||
|
Label { label: "\u{232B}", // ERASE TO THE LEFT
|
||||||
|
secondary: true, small: false, },
|
||||||
|
Label { label: "\u{23CE}", // RETURN SYMBOL
|
||||||
|
secondary: true, small: false, },
|
||||||
|
Label { label: "\u{2423}", // OPEN BOX
|
||||||
|
secondary: true, small: true, },
|
||||||
|
Label { label: "\u{2B7E}", // HORIZONTAL TAB KEY
|
||||||
secondary: true, small: true, },
|
secondary: true, small: true, },
|
||||||
/*
|
|
||||||
Label { sym: Keysym::approxeq, label: "\u{2248}",
|
|
||||||
secondary: false, small: false, },
|
|
||||||
*/
|
|
||||||
];
|
];
|
||||||
|
|
||||||
const ANCHORS: [(Anchor, Anchor); 8] = [
|
const ANCHORS: [(Anchor, Anchor); 8] = [
|
||||||
|
|
@ -250,29 +200,9 @@ impl<D: Display> Graphics<D> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn keysym_to_label(sym: Keysym) -> String
|
fn is_label_small(label: &str) -> bool
|
||||||
{
|
{
|
||||||
let res = LABELS.binary_search_by_key(&sym, |&Label { sym, .. }| sym);
|
match LABELS.binary_search_by_key(&label, |&Label { label, .. }| label) {
|
||||||
if let Ok(idx) = res {
|
|
||||||
return String::from(LABELS[idx].label);
|
|
||||||
}
|
|
||||||
|
|
||||||
// The ! symbol is bitwise NOT.
|
|
||||||
match char::from_u32(sym.raw() & !0x01000000) {
|
|
||||||
Some(c) => {
|
|
||||||
let mut label = String::new();
|
|
||||||
label.push(c);
|
|
||||||
label
|
|
||||||
},
|
|
||||||
None => {
|
|
||||||
format!("U+{}", sym.raw())
|
|
||||||
},
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn is_keysym_small(sym: Keysym) -> bool
|
|
||||||
{
|
|
||||||
match LABELS.binary_search_by_key(&sym, |&Label { sym, .. }| sym) {
|
|
||||||
Ok(idx) => LABELS[idx].small,
|
Ok(idx) => LABELS[idx].small,
|
||||||
Err(_) => false,
|
Err(_) => false,
|
||||||
}
|
}
|
||||||
|
|
@ -367,7 +297,12 @@ impl<D: Display> Graphics<D> {
|
||||||
* metrics.x_ppem as usize
|
* metrics.x_ppem as usize
|
||||||
/ units_per_em as usize;
|
/ units_per_em as usize;
|
||||||
|
|
||||||
let stride = metrics.max_advance as usize / 64 * (text.len() - 1) + glyph_width;
|
let stride = if text.is_empty() {
|
||||||
|
1
|
||||||
|
} else {
|
||||||
|
metrics.max_advance as usize / 64 * (text.len() - 1) + glyph_width
|
||||||
|
};
|
||||||
|
|
||||||
let height = (metrics.ascender - metrics.descender) as usize / 64;
|
let height = (metrics.ascender - metrics.descender) as usize / 64;
|
||||||
|
|
||||||
let vec: Vec<u8> = vec![0; stride * height];
|
let vec: Vec<u8> = vec![0; stride * height];
|
||||||
|
|
@ -424,19 +359,17 @@ impl<D: Display> Graphics<D> {
|
||||||
* table cannot be mutable at the same time, this cannot be abstracted to a
|
* table cannot be mutable at the same time, this cannot be abstracted to a
|
||||||
* mutable self and mutable hash table.
|
* mutable self and mutable hash table.
|
||||||
*/
|
*/
|
||||||
fn rasterize_label(&mut self, size: f64, sym: Keysym)
|
fn rasterize_label(&mut self, size: f64, label: &str)
|
||||||
{
|
{
|
||||||
if !self.labels.contains_key(&sym) {
|
if !self.labels.contains_key(label) {
|
||||||
let label = Self::keysym_to_label(sym);
|
let size = if Self::is_label_small(label) {
|
||||||
|
|
||||||
let size = if Self::is_keysym_small(sym) {
|
|
||||||
size * 0.75
|
size * 0.75
|
||||||
} else {
|
} else {
|
||||||
size
|
size
|
||||||
};
|
};
|
||||||
|
|
||||||
let img = self.rasterize_text(size, &label);
|
let img = self.rasterize_text(size, label);
|
||||||
self.labels.insert(sym, img);
|
self.labels.insert(String::from(label), img);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -449,23 +382,21 @@ impl<D: Display> Graphics<D> {
|
||||||
* table cannot be mutable at the same time, this cannot be abstracted to a
|
* table cannot be mutable at the same time, this cannot be abstracted to a
|
||||||
* mutable self and mutable hash table.
|
* mutable self and mutable hash table.
|
||||||
*/
|
*/
|
||||||
fn rasterize_sublabel(&mut self, size: f64, sym: Keysym)
|
fn rasterize_sublabel(&mut self, size: f64, label: &str)
|
||||||
{
|
{
|
||||||
if !self.sublabels.contains_key(&sym) {
|
if !self.sublabels.contains_key(label) {
|
||||||
let label = Self::keysym_to_label(sym);
|
let size = if Self::is_label_small(label) {
|
||||||
|
|
||||||
let size = if Self::is_keysym_small(sym) {
|
|
||||||
size * 0.75
|
size * 0.75
|
||||||
} else {
|
} else {
|
||||||
size
|
size
|
||||||
};
|
};
|
||||||
|
|
||||||
let img = self.rasterize_text(size, &label);
|
let img = self.rasterize_text(size, label);
|
||||||
self.sublabels.insert(sym, img);
|
self.sublabels.insert(String::from(label), img);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn rasterize_labels(&mut self, layout: &Layout, mod_state: &[ModState])
|
fn rasterize_labels(&mut self, layout: &Layout)
|
||||||
{
|
{
|
||||||
self.labels = HashMap::new();
|
self.labels = HashMap::new();
|
||||||
self.sublabels = HashMap::new();
|
self.sublabels = HashMap::new();
|
||||||
|
|
@ -478,23 +409,23 @@ impl<D: Display> Graphics<D> {
|
||||||
self.sublabels.reserve(row.len() * 8);
|
self.sublabels.reserve(row.len() * 8);
|
||||||
|
|
||||||
for key in row {
|
for key in row {
|
||||||
let sym = key.parts[0].display_symbol(mod_state);
|
let label = key.parts[0].display_label();
|
||||||
self.rasterize_label(label_size, sym);
|
self.rasterize_label(label_size, label);
|
||||||
|
|
||||||
for part in &key.parts[1..] {
|
for part in &key.parts[1..] {
|
||||||
let sym = part.display_symbol(mod_state);
|
let label = part.display_label();
|
||||||
self.rasterize_sublabel(sublabel_size, sym);
|
self.rasterize_sublabel(sublabel_size, label);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn draw_label_part(labels: &HashMap<Keysym, ImgVec<u8>>,
|
fn draw_label_part(labels: &HashMap<String, ImgVec<u8>>,
|
||||||
x_anchor: Anchor, y_anchor: Anchor,
|
x_anchor: Anchor, y_anchor: Anchor,
|
||||||
img: &mut ImgRefMut<BGRA<u8>>,
|
img: &mut ImgRefMut<BGRA<u8>>,
|
||||||
sym: Keysym, fg_color: BGR<f32>)
|
label: &str, fg_color: BGR<f32>)
|
||||||
{
|
{
|
||||||
let src = labels.get(&sym)
|
let src = labels.get(label)
|
||||||
.expect("Layout and size should be set before drawing");
|
.expect("Layout and size should be set before drawing");
|
||||||
|
|
||||||
let x = match x_anchor {
|
let x = match x_anchor {
|
||||||
|
|
@ -545,7 +476,8 @@ impl<D: Display> Graphics<D> {
|
||||||
return color_sublabel;
|
return color_sublabel;
|
||||||
}
|
}
|
||||||
|
|
||||||
let res = LABELS.binary_search_by_key(&part.sym(), |&Label { sym, .. }| sym);
|
let label = part.display_label();
|
||||||
|
let res = LABELS.binary_search_by_key(&label, |&Label { label, .. }| label);
|
||||||
if let Ok(idx) = res {
|
if let Ok(idx) = res {
|
||||||
if LABELS[idx].secondary {
|
if LABELS[idx].secondary {
|
||||||
return color_sublabel;
|
return color_sublabel;
|
||||||
|
|
@ -555,8 +487,8 @@ impl<D: Display> Graphics<D> {
|
||||||
color_label
|
color_label
|
||||||
}
|
}
|
||||||
|
|
||||||
fn draw_key(labels: &HashMap<Keysym, ImgVec<u8>>,
|
fn draw_key(labels: &HashMap<String, ImgVec<u8>>,
|
||||||
sublabels: &HashMap<Keysym, ImgVec<u8>>,
|
sublabels: &HashMap<String, ImgVec<u8>>,
|
||||||
x_scale: f64, y_scale: f64,
|
x_scale: f64, y_scale: f64,
|
||||||
img: &mut ImgRefMut<BGRA<u8>>,
|
img: &mut ImgRefMut<BGRA<u8>>,
|
||||||
key: &Key, mod_state: &[ModState])
|
key: &Key, mod_state: &[ModState])
|
||||||
|
|
@ -589,15 +521,15 @@ impl<D: Display> Graphics<D> {
|
||||||
}
|
}
|
||||||
|
|
||||||
let color = Self::keypart_to_color(&key.parts[0], false, mod_state);
|
let color = Self::keypart_to_color(&key.parts[0], false, mod_state);
|
||||||
let sym = key.parts[0].display_symbol(mod_state);
|
let label = key.parts[0].display_label();
|
||||||
Self::draw_label_part(labels, Anchor::Center, Anchor::Center,
|
Self::draw_label_part(labels, Anchor::Center, Anchor::Center,
|
||||||
&mut keyimg, sym, color);
|
&mut keyimg, label, color);
|
||||||
|
|
||||||
for i in 0..8 {
|
for i in 0..8 {
|
||||||
let color = Self::keypart_to_color(&key.parts[i + 1], true, mod_state);
|
let color = Self::keypart_to_color(&key.parts[i + 1], true, mod_state);
|
||||||
let sym = key.parts[i + 1].display_symbol(mod_state);
|
let label = key.parts[i + 1].display_label();
|
||||||
Self::draw_label_part(sublabels, ANCHORS[i].0, ANCHORS[i].1,
|
Self::draw_label_part(sublabels, ANCHORS[i].0, ANCHORS[i].1,
|
||||||
&mut keyimg, sym, color);
|
&mut keyimg, label, color);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -653,7 +585,7 @@ impl<D: Display> Graphics<D> {
|
||||||
|
|
||||||
pub fn change_layout(&mut self, layout: &Layout, mod_state: &[ModState])
|
pub fn change_layout(&mut self, layout: &Layout, mod_state: &[ModState])
|
||||||
{
|
{
|
||||||
self.rasterize_labels(layout, mod_state);
|
self.rasterize_labels(layout);
|
||||||
self.draw(layout, mod_state);
|
self.draw(layout, mod_state);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -664,7 +596,7 @@ impl<D: Display> Graphics<D> {
|
||||||
self.x_scale = width as f64 / layout.width();
|
self.x_scale = width as f64 / layout.width();
|
||||||
self.y_scale = height as f64 / layout.height();
|
self.y_scale = height as f64 / layout.height();
|
||||||
|
|
||||||
self.rasterize_labels(layout, mod_state);
|
self.rasterize_labels(layout);
|
||||||
|
|
||||||
self.disp.resize(width, height);
|
self.disp.resize(width, height);
|
||||||
self.draw(layout, mod_state);
|
self.draw(layout, mod_state);
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue