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::ptr;
|
||||
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>)
|
||||
{
|
||||
|
|
@ -78,8 +77,8 @@ pub struct Graphics<D: Display> {
|
|||
disp: D,
|
||||
fonts: Vec<(String, freetype::FT_Long)>,
|
||||
fontbufs: Vec<Vec<u8>>,
|
||||
labels: HashMap<Keysym, ImgVec<u8>>,
|
||||
sublabels: HashMap<Keysym, ImgVec<u8>>,
|
||||
labels: HashMap<String, ImgVec<u8>>,
|
||||
sublabels: HashMap<String, ImgVec<u8>>,
|
||||
ft: AtomicPtr<freetype::FT_LibraryRec_>,
|
||||
|
||||
x_scale: f64,
|
||||
|
|
@ -87,103 +86,54 @@ pub struct Graphics<D: Display> {
|
|||
}
|
||||
|
||||
struct Label<'a> {
|
||||
sym: Keysym,
|
||||
label: &'a str,
|
||||
secondary: bool,
|
||||
small: bool,
|
||||
}
|
||||
|
||||
const LABELS: [Label; 43] = [
|
||||
Label { sym: Keysym::Greek_MU, label: "\u{039C}",
|
||||
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}",
|
||||
const LABELS: [Label; 21] = [
|
||||
Label { label: "Alt",
|
||||
secondary: true, small: true, },
|
||||
Label { sym: Keysym::Return, label: "\u{23CE}",
|
||||
secondary: true, small: false, },
|
||||
Label { sym: Keysym::Escape, label: "Esc",
|
||||
Label { label: "Ctrl",
|
||||
secondary: true, small: true, },
|
||||
Label { sym: Keysym::Home, label: "\u{21E4}",
|
||||
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",
|
||||
Label { label: "Esc",
|
||||
secondary: true, small: true, },
|
||||
Label { sym: Keysym::F1, label: "F1",
|
||||
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",
|
||||
Label { label: "F11",
|
||||
secondary: false, small: true, },
|
||||
Label { sym: Keysym::F12, label: "F12",
|
||||
Label { label: "F12",
|
||||
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, },
|
||||
Label { sym: Keysym::Control_L, label: "Ctrl",
|
||||
secondary: true, small: true, },
|
||||
Label { sym: Keysym::Alt_L, label: "Alt",
|
||||
secondary: true, small: true, },
|
||||
Label { sym: Keysym::Delete, label: "\u{2326}",
|
||||
Label { label: "\u{2191}", // UPWARDS ARROW
|
||||
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, },
|
||||
/*
|
||||
Label { sym: Keysym::approxeq, label: "\u{2248}",
|
||||
secondary: false, small: false, },
|
||||
*/
|
||||
];
|
||||
|
||||
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);
|
||||
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) {
|
||||
match LABELS.binary_search_by_key(&label, |&Label { label, .. }| label) {
|
||||
Ok(idx) => LABELS[idx].small,
|
||||
Err(_) => false,
|
||||
}
|
||||
|
|
@ -367,7 +297,12 @@ impl<D: Display> Graphics<D> {
|
|||
* metrics.x_ppem 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 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
|
||||
* 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) {
|
||||
let label = Self::keysym_to_label(sym);
|
||||
|
||||
let size = if Self::is_keysym_small(sym) {
|
||||
if !self.labels.contains_key(label) {
|
||||
let size = if Self::is_label_small(label) {
|
||||
size * 0.75
|
||||
} else {
|
||||
size
|
||||
};
|
||||
|
||||
let img = self.rasterize_text(size, &label);
|
||||
self.labels.insert(sym, img);
|
||||
let img = self.rasterize_text(size, label);
|
||||
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
|
||||
* 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) {
|
||||
let label = Self::keysym_to_label(sym);
|
||||
|
||||
let size = if Self::is_keysym_small(sym) {
|
||||
if !self.sublabels.contains_key(label) {
|
||||
let size = if Self::is_label_small(label) {
|
||||
size * 0.75
|
||||
} else {
|
||||
size
|
||||
};
|
||||
|
||||
let img = self.rasterize_text(size, &label);
|
||||
self.sublabels.insert(sym, img);
|
||||
let img = self.rasterize_text(size, label);
|
||||
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.sublabels = HashMap::new();
|
||||
|
|
@ -478,23 +409,23 @@ impl<D: Display> Graphics<D> {
|
|||
self.sublabels.reserve(row.len() * 8);
|
||||
|
||||
for key in row {
|
||||
let sym = key.parts[0].display_symbol(mod_state);
|
||||
self.rasterize_label(label_size, sym);
|
||||
let label = key.parts[0].display_label();
|
||||
self.rasterize_label(label_size, label);
|
||||
|
||||
for part in &key.parts[1..] {
|
||||
let sym = part.display_symbol(mod_state);
|
||||
self.rasterize_sublabel(sublabel_size, sym);
|
||||
let label = part.display_label();
|
||||
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,
|
||||
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");
|
||||
|
||||
let x = match x_anchor {
|
||||
|
|
@ -545,7 +476,8 @@ impl<D: Display> Graphics<D> {
|
|||
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 LABELS[idx].secondary {
|
||||
return color_sublabel;
|
||||
|
|
@ -555,8 +487,8 @@ impl<D: Display> Graphics<D> {
|
|||
color_label
|
||||
}
|
||||
|
||||
fn draw_key(labels: &HashMap<Keysym, ImgVec<u8>>,
|
||||
sublabels: &HashMap<Keysym, ImgVec<u8>>,
|
||||
fn draw_key(labels: &HashMap<String, ImgVec<u8>>,
|
||||
sublabels: &HashMap<String, ImgVec<u8>>,
|
||||
x_scale: f64, y_scale: f64,
|
||||
img: &mut ImgRefMut<BGRA<u8>>,
|
||||
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 sym = key.parts[0].display_symbol(mod_state);
|
||||
let label = key.parts[0].display_label();
|
||||
Self::draw_label_part(labels, Anchor::Center, Anchor::Center,
|
||||
&mut keyimg, sym, color);
|
||||
&mut keyimg, label, color);
|
||||
|
||||
for i in 0..8 {
|
||||
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,
|
||||
&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])
|
||||
{
|
||||
self.rasterize_labels(layout, mod_state);
|
||||
self.rasterize_labels(layout);
|
||||
self.draw(layout, mod_state);
|
||||
}
|
||||
|
||||
|
|
@ -664,7 +596,7 @@ impl<D: Display> Graphics<D> {
|
|||
self.x_scale = width as f64 / layout.width();
|
||||
self.y_scale = height as f64 / layout.height();
|
||||
|
||||
self.rasterize_labels(layout, mod_state);
|
||||
self.rasterize_labels(layout);
|
||||
|
||||
self.disp.resize(width, height);
|
||||
self.draw(layout, mod_state);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue