From c7ec47e2c05944a03fa30ad5706f9a74add1d65a Mon Sep 17 00:00:00 2001 From: Wez Furlong Date: Thu, 10 Jun 2021 20:36:25 -0700 Subject: [PATCH] add sextant glyphs to custom block glyphs While I'm in here, teach the font fallback code that it doesn't need to search for these glyphs when custom block glyphs are enabled. refs: https://github.com/dankamongmen/notcurses/issues/1715 refs: #584 refs: #588 --- docs/changelog.md | 1 + test-data/blocks.py | 9 ++ wezterm-font/src/lib.rs | 5 +- wezterm-gui/src/glyphcache.rs | 141 +++++++++++++++++++++++++++ wezterm-gui/src/termwindow/render.rs | 16 +-- 5 files changed, 165 insertions(+), 7 deletions(-) diff --git a/docs/changelog.md b/docs/changelog.md index e85c486f7..a6fe40342 100644 --- a/docs/changelog.md +++ b/docs/changelog.md @@ -39,6 +39,7 @@ As features stabilize some brief notes about them will accumulate here. * Fixed: `wezterm start --cwd c:/` didn't run `default_prog`. Thanks to [@exactly-one-kas](https://github.com/exactly-one-kas)! [#851](https://github.com/wez/wezterm/pull/851) * Improved: [skip_close_confirmation_for_processes_named](config/lua/config/skip_close_confirmation_for_processes_named.md) now includes common windows shell processes `cmd.exe`, `pwsh.exe` and `powershell.exe`. [#843](https://github.com/wez/wezterm/issues/843) * Fixed: don't keep the window alive after running `something & disown ; exit` [#839](https://github.com/wez/wezterm/issues/839) +* Improved: we now draw sextant glyphs from the Unicode Symbols for Legacy Computing block (1FB00) when `custom_block_glyphs` is enabled. ### 20210502-154244-3f7122cb diff --git a/test-data/blocks.py b/test-data/blocks.py index 5338aa88a..f362afb4b 100755 --- a/test-data/blocks.py +++ b/test-data/blocks.py @@ -9,4 +9,13 @@ for b in range(0x2580, 0x25A0): print(s) print(s) print(s) +print() +s = "" +for b in range(0x1fb00, 0x1fb3c): + s += chr(b) + " " + +print(s) +print(s) +print(s) +print() diff --git a/wezterm-font/src/lib.rs b/wezterm-font/src/lib.rs index 02d4f4f0b..4f6050aaf 100644 --- a/wezterm-font/src/lib.rs +++ b/wezterm-font/src/lib.rs @@ -79,10 +79,11 @@ impl LoadedFont { Ok(loaded) } - pub fn shape( + pub fn shape)>( &self, text: &str, completion: F, + filter_out_synthetic: FS, ) -> anyhow::Result> { let mut no_glyphs = vec![]; @@ -104,6 +105,8 @@ impl LoadedFont { .borrow() .shape(text, self.font_size, self.dpi, &mut no_glyphs); + filter_out_synthetic(&mut no_glyphs); + if !no_glyphs.is_empty() { if let Some(font_config) = self.font_config.upgrade() { font_config.schedule_fallback_resolve( diff --git a/wezterm-gui/src/glyphcache.rs b/wezterm-gui/src/glyphcache.rs index 9f205d182..d39493bdf 100644 --- a/wezterm-gui/src/glyphcache.rs +++ b/wezterm-gui/src/glyphcache.rs @@ -138,6 +138,23 @@ bitflags::bitflags! { } } +bitflags::bitflags! { + pub struct Sextant: u8{ + /// Upper-left + const ONE = 1<<1; + /// Upper-right + const TWO = 1<<2; + /// Middle left + const THREE = 1<<3; + /// Middle Right + const FOUR = 1<<4; + /// Lower left + const FIVE = 1<<5; + /// Lower right + const SIX = 1<<6; + } +} + #[derive(Copy, Clone, PartialEq, Eq, Hash, Debug)] pub enum BlockAlpha { /// 100% @@ -167,9 +184,18 @@ pub enum BlockKey { Full(BlockAlpha), /// A combination of quadrants Quadrants(Quadrant), + /// A combination of sextants + Sextants(Sextant), } impl BlockKey { + pub fn filter_out_synthetic(glyphs: &mut Vec) { + let config = config::configuration(); + if config.custom_block_glyphs { + glyphs.retain(|&c| Self::from_char(c).is_none()); + } + } + pub fn from_char(c: char) -> Option { let c = c as u32; Some(match c { @@ -205,6 +231,84 @@ impl BlockKey { 0x259f => Self::Quadrants( Quadrant::UPPER_RIGHT | Quadrant::LOWER_LEFT | Quadrant::LOWER_RIGHT, ), + 0x1fb00 => Self::Sextants(Sextant::ONE), + 0x1fb01 => Self::Sextants(Sextant::TWO), + 0x1fb02 => Self::Sextants(Sextant::ONE | Sextant::TWO), + 0x1fb03 => Self::Sextants(Sextant::THREE), + 0x1fb04 => Self::Sextants(Sextant::ONE | Sextant::THREE), + 0x1fb05 => Self::Sextants(Sextant::TWO | Sextant::THREE), + 0x1fb06 => Self::Sextants(Sextant::TWO | Sextant::TWO | Sextant::THREE), + 0x1fb07 => Self::Sextants(Sextant::FOUR), + 0x1fb08 => Self::Sextants(Sextant::ONE | Sextant::FOUR), + 0x1fb09 => Self::Sextants(Sextant::TWO | Sextant::FOUR), + 0x1fb0a => Self::Sextants(Sextant::ONE | Sextant::TWO | Sextant::FOUR), + 0x1fb0b => Self::Sextants(Sextant::THREE | Sextant::FOUR), + 0x1fb0c => Self::Sextants(Sextant::ONE | Sextant::THREE | Sextant::FOUR), + 0x1fb0d => Self::Sextants(Sextant::TWO | Sextant::THREE | Sextant::FOUR), + 0x1fb0e => Self::Sextants(Sextant::ONE | Sextant::TWO | Sextant::THREE | Sextant::FOUR), + 0x1fb0f => Self::Sextants(Sextant::FIVE), + 0x1fb10 => Self::Sextants(Sextant::ONE | Sextant::FIVE), + 0x1fb11 => Self::Sextants(Sextant::TWO | Sextant::FIVE), + 0x1fb12 => Self::Sextants(Sextant::ONE | Sextant::TWO | Sextant::FIVE), + 0x1fb13 => Self::Sextants(Sextant::THREE | Sextant::FIVE), + 0x1fb14 => Self::Sextants(Sextant::TWO | Sextant::THREE | Sextant::FIVE), + 0x1fb15 => Self::Sextants(Sextant::ONE | Sextant::TWO | Sextant::THREE | Sextant::FIVE), + 0x1fb16 => Self::Sextants(Sextant::FOUR | Sextant::FIVE), + 0x1fb17 => Self::Sextants(Sextant::ONE | Sextant::FOUR | Sextant::FIVE), + 0x1fb18 => Self::Sextants(Sextant::TWO | Sextant::FOUR | Sextant::FIVE), + 0x1fb19 => Self::Sextants(Sextant::ONE | Sextant::TWO | Sextant::FOUR | Sextant::FIVE), + 0x1fb1a => Self::Sextants(Sextant::THREE | Sextant::FOUR | Sextant::FIVE), + 0x1fb1b => { + Self::Sextants(Sextant::ONE | Sextant::THREE | Sextant::FOUR | Sextant::FIVE) + } + 0x1fb1c => { + Self::Sextants(Sextant::TWO | Sextant::THREE | Sextant::FOUR | Sextant::FIVE) + } + 0x1fb1d => Self::Sextants( + Sextant::ONE | Sextant::TWO | Sextant::THREE | Sextant::FOUR | Sextant::FIVE, + ), + 0x1fb1e => Self::Sextants(Sextant::SIX), + 0x1fb1f => Self::Sextants(Sextant::ONE | Sextant::SIX), + 0x1fb20 => Self::Sextants(Sextant::TWO | Sextant::SIX), + 0x1fb21 => Self::Sextants(Sextant::ONE | Sextant::TWO | Sextant::SIX), + 0x1fb22 => Self::Sextants(Sextant::THREE | Sextant::SIX), + 0x1fb23 => Self::Sextants(Sextant::ONE | Sextant::THREE | Sextant::SIX), + 0x1fb24 => Self::Sextants(Sextant::TWO | Sextant::THREE | Sextant::SIX), + 0x1fb25 => Self::Sextants(Sextant::ONE | Sextant::TWO | Sextant::THREE | Sextant::SIX), + 0x1fb26 => Self::Sextants(Sextant::FOUR | Sextant::SIX), + 0x1fb27 => Self::Sextants(Sextant::ONE | Sextant::FOUR | Sextant::SIX), + 0x1fb28 => Self::Sextants(Sextant::ONE | Sextant::TWO | Sextant::FOUR | Sextant::SIX), + 0x1fb29 => Self::Sextants(Sextant::THREE | Sextant::FOUR | Sextant::SIX), + 0x1fb2a => Self::Sextants(Sextant::ONE | Sextant::THREE | Sextant::FOUR | Sextant::SIX), + 0x1fb2b => Self::Sextants(Sextant::TWO | Sextant::THREE | Sextant::FOUR | Sextant::SIX), + 0x1fb2c => Self::Sextants( + Sextant::ONE | Sextant::TWO | Sextant::THREE | Sextant::FOUR | Sextant::SIX, + ), + 0x1fb2d => Self::Sextants(Sextant::FIVE | Sextant::SIX), + 0x1fb2e => Self::Sextants(Sextant::ONE | Sextant::FIVE | Sextant::SIX), + 0x1fb2f => Self::Sextants(Sextant::TWO | Sextant::FIVE | Sextant::SIX), + 0x1fb30 => Self::Sextants(Sextant::ONE | Sextant::TWO | Sextant::FIVE | Sextant::SIX), + 0x1fb31 => Self::Sextants(Sextant::THREE | Sextant::FIVE | Sextant::SIX), + 0x1fb32 => Self::Sextants(Sextant::ONE | Sextant::THREE | Sextant::FIVE | Sextant::SIX), + 0x1fb33 => Self::Sextants(Sextant::TWO | Sextant::THREE | Sextant::FIVE | Sextant::SIX), + 0x1fb34 => Self::Sextants( + Sextant::ONE | Sextant::TWO | Sextant::THREE | Sextant::FIVE | Sextant::SIX, + ), + 0x1fb35 => Self::Sextants(Sextant::FOUR | Sextant::FIVE | Sextant::SIX), + 0x1fb36 => Self::Sextants(Sextant::ONE | Sextant::FOUR | Sextant::FIVE | Sextant::SIX), + 0x1fb37 => Self::Sextants(Sextant::TWO | Sextant::FOUR | Sextant::FIVE | Sextant::SIX), + 0x1fb38 => Self::Sextants( + Sextant::ONE | Sextant::TWO | Sextant::FOUR | Sextant::FIVE | Sextant::SIX, + ), + 0x1fb39 => { + Self::Sextants(Sextant::THREE | Sextant::FOUR | Sextant::FIVE | Sextant::SIX) + } + 0x1fb3a => Self::Sextants( + Sextant::ONE | Sextant::THREE | Sextant::FOUR | Sextant::FIVE | Sextant::SIX, + ), + 0x1fb3b => Self::Sextants( + Sextant::TWO | Sextant::THREE | Sextant::FOUR | Sextant::FIVE | Sextant::SIX, + ), _ => return None, }) } @@ -824,6 +928,43 @@ impl GlyphCache { draw_quad(&mut buffer, scale(x_half)..width, scale(y_half)..height); } } + BlockKey::Sextants(s) => { + let y_third = self.metrics.cell_size.height as f32 / 3.; + let x_half = self.metrics.cell_size.width as f32 / 2.; + let width = self.metrics.cell_size.width as usize; + let height = self.metrics.cell_size.height as usize; + + if s.contains(Sextant::ONE) { + draw_quad(&mut buffer, 0..scale(x_half), 0..scale(y_third)); + } + if s.contains(Sextant::TWO) { + draw_quad(&mut buffer, scale(x_half)..width, 0..scale(y_third)); + } + if s.contains(Sextant::THREE) { + draw_quad( + &mut buffer, + 0..scale(x_half), + scale(y_third)..scale(y_third * 2.), + ); + } + if s.contains(Sextant::FOUR) { + draw_quad( + &mut buffer, + scale(x_half)..width, + scale(y_third)..scale(y_third * 2.), + ); + } + if s.contains(Sextant::FIVE) { + draw_quad(&mut buffer, 0..scale(x_half), scale(y_third * 2.)..height); + } + if s.contains(Sextant::SIX) { + draw_quad( + &mut buffer, + scale(x_half)..width, + scale(y_third * 2.)..height, + ); + } + } } /* diff --git a/wezterm-gui/src/termwindow/render.rs b/wezterm-gui/src/termwindow/render.rs index 879af7052..b4524fec7 100644 --- a/wezterm-gui/src/termwindow/render.rs +++ b/wezterm-gui/src/termwindow/render.rs @@ -540,9 +540,11 @@ impl super::TermWindow { None => { let font = self.fonts.resolve_font(style)?; let window = self.window.as_ref().unwrap().clone(); - match font.shape(text, move || { - window.notify(TermWindowNotif::InvalidateShapeCache) - }) { + match font.shape( + text, + move || window.notify(TermWindowNotif::InvalidateShapeCache), + BlockKey::filter_out_synthetic, + ) { Ok(info) => { let line = Line::from_text(&text, &CellAttributes::default()); let clusters = line.cluster(); @@ -832,9 +834,11 @@ impl super::TermWindow { None => { let font = self.fonts.resolve_font(style)?; let window = self.window.as_ref().unwrap().clone(); - match font.shape(&cluster.text, move || { - window.notify(TermWindowNotif::InvalidateShapeCache) - }) { + match font.shape( + &cluster.text, + move || window.notify(TermWindowNotif::InvalidateShapeCache), + BlockKey::filter_out_synthetic, + ) { Ok(info) => { let glyphs = self.glyph_infos_to_glyphs( cluster,