Fix cursor only showing up over left half of wide characters
This commit is contained in:
parent
bdae9f0f28
commit
ca9724a5ef
|
@ -23,6 +23,13 @@ use crate::ansi::CursorStyle;
|
||||||
/// Width/Height of the cursor relative to the font width
|
/// Width/Height of the cursor relative to the font width
|
||||||
pub const CURSOR_WIDTH_PERCENTAGE: i32 = 15;
|
pub const CURSOR_WIDTH_PERCENTAGE: i32 = 15;
|
||||||
|
|
||||||
|
/// A key for caching cursor glyphs
|
||||||
|
#[derive(Debug, Eq, PartialEq, Copy, Clone, Hash, Deserialize)]
|
||||||
|
pub struct CursorKey {
|
||||||
|
pub style: CursorStyle,
|
||||||
|
pub is_wide: bool,
|
||||||
|
}
|
||||||
|
|
||||||
pub fn get_cursor_glyph(
|
pub fn get_cursor_glyph(
|
||||||
cursor: CursorStyle,
|
cursor: CursorStyle,
|
||||||
metrics: Metrics,
|
metrics: Metrics,
|
||||||
|
|
|
@ -438,7 +438,7 @@ impl Display {
|
||||||
|
|
||||||
let window_focused = self.window.is_focused;
|
let window_focused = self.window.is_focused;
|
||||||
let grid_cells: Vec<RenderableCell> =
|
let grid_cells: Vec<RenderableCell> =
|
||||||
terminal.renderable_cells(config, window_focused, metrics).collect();
|
terminal.renderable_cells(config, window_focused).collect();
|
||||||
|
|
||||||
// Get message from terminal to ignore modifications after lock is dropped
|
// Get message from terminal to ignore modifications after lock is dropped
|
||||||
let message_buffer = terminal.message_buffer_mut().message();
|
let message_buffer = terminal.message_buffer_mut().message();
|
||||||
|
|
|
@ -26,8 +26,8 @@ use font::{self, FontDesc, FontKey, GlyphKey, Rasterize, RasterizedGlyph, Raster
|
||||||
use glutin::dpi::PhysicalSize;
|
use glutin::dpi::PhysicalSize;
|
||||||
use notify::{watcher, DebouncedEvent, RecursiveMode, Watcher};
|
use notify::{watcher, DebouncedEvent, RecursiveMode, Watcher};
|
||||||
|
|
||||||
use crate::ansi::CursorStyle;
|
|
||||||
use crate::config::{self, Config, Delta};
|
use crate::config::{self, Config, Delta};
|
||||||
|
use crate::cursor::{get_cursor_glyph, CursorKey};
|
||||||
use crate::gl;
|
use crate::gl;
|
||||||
use crate::gl::types::*;
|
use crate::gl::types::*;
|
||||||
use crate::index::{Column, Line};
|
use crate::index::{Column, Line};
|
||||||
|
@ -160,7 +160,7 @@ pub struct GlyphCache {
|
||||||
cache: HashMap<GlyphKey, Glyph, BuildHasherDefault<FnvHasher>>,
|
cache: HashMap<GlyphKey, Glyph, BuildHasherDefault<FnvHasher>>,
|
||||||
|
|
||||||
/// Cache of buffered cursor glyphs
|
/// Cache of buffered cursor glyphs
|
||||||
cursor_cache: HashMap<CursorStyle, Glyph, BuildHasherDefault<FnvHasher>>,
|
cursor_cache: HashMap<CursorKey, Glyph, BuildHasherDefault<FnvHasher>>,
|
||||||
|
|
||||||
/// Rasterizer for loading new glyphs
|
/// Rasterizer for loading new glyphs
|
||||||
rasterizer: Rasterizer,
|
rasterizer: Rasterizer,
|
||||||
|
@ -994,12 +994,21 @@ impl<'a> RenderApi<'a> {
|
||||||
|
|
||||||
pub fn render_cell(&mut self, cell: RenderableCell, glyph_cache: &mut GlyphCache) {
|
pub fn render_cell(&mut self, cell: RenderableCell, glyph_cache: &mut GlyphCache) {
|
||||||
let chars = match cell.inner {
|
let chars = match cell.inner {
|
||||||
RenderableCellContent::Cursor((cursor_style, ref raw)) => {
|
RenderableCellContent::Cursor(cursor_key) => {
|
||||||
// Raw cell pixel buffers like cursors don't need to go through font lookup
|
// Raw cell pixel buffers like cursors don't need to go through font lookup
|
||||||
let glyph = glyph_cache
|
let metrics = glyph_cache.metrics;
|
||||||
.cursor_cache
|
let glyph = glyph_cache.cursor_cache.entry(cursor_key).or_insert_with(|| {
|
||||||
.entry(cursor_style)
|
let offset_x = self.config.font.offset.x;
|
||||||
.or_insert_with(|| self.load_glyph(raw));
|
let offset_y = self.config.font.offset.y;
|
||||||
|
|
||||||
|
self.load_glyph(&get_cursor_glyph(
|
||||||
|
cursor_key.style,
|
||||||
|
metrics,
|
||||||
|
offset_x,
|
||||||
|
offset_y,
|
||||||
|
cursor_key.is_wide,
|
||||||
|
))
|
||||||
|
});
|
||||||
self.add_render_item(&cell, &glyph);
|
self.add_render_item(&cell, &glyph);
|
||||||
return;
|
return;
|
||||||
},
|
},
|
||||||
|
|
|
@ -18,7 +18,7 @@ use std::ops::{Index, IndexMut, Range, RangeInclusive};
|
||||||
use std::time::{Duration, Instant};
|
use std::time::{Duration, Instant};
|
||||||
use std::{io, mem, ptr};
|
use std::{io, mem, ptr};
|
||||||
|
|
||||||
use font::{self, RasterizedGlyph, Size};
|
use font::{self, Size};
|
||||||
use glutin::MouseCursor;
|
use glutin::MouseCursor;
|
||||||
use unicode_width::UnicodeWidthChar;
|
use unicode_width::UnicodeWidthChar;
|
||||||
|
|
||||||
|
@ -27,7 +27,7 @@ use crate::ansi::{
|
||||||
};
|
};
|
||||||
use crate::clipboard::{Clipboard, ClipboardType};
|
use crate::clipboard::{Clipboard, ClipboardType};
|
||||||
use crate::config::{Config, VisualBellAnimation};
|
use crate::config::{Config, VisualBellAnimation};
|
||||||
use crate::cursor;
|
use crate::cursor::CursorKey;
|
||||||
use crate::grid::{
|
use crate::grid::{
|
||||||
BidirectionalIterator, DisplayIter, Grid, GridCell, IndexRegion, Indexed, Scroll,
|
BidirectionalIterator, DisplayIter, Grid, GridCell, IndexRegion, Indexed, Scroll,
|
||||||
ViewportPosition,
|
ViewportPosition,
|
||||||
|
@ -158,7 +158,7 @@ pub struct RenderableCellsIter<'a> {
|
||||||
grid: &'a Grid<Cell>,
|
grid: &'a Grid<Cell>,
|
||||||
cursor: &'a Point,
|
cursor: &'a Point,
|
||||||
cursor_offset: usize,
|
cursor_offset: usize,
|
||||||
cursor_cell: Option<RasterizedGlyph>,
|
cursor_key: Option<CursorKey>,
|
||||||
cursor_style: CursorStyle,
|
cursor_style: CursorStyle,
|
||||||
config: &'a Config,
|
config: &'a Config,
|
||||||
colors: &'a color::List,
|
colors: &'a color::List,
|
||||||
|
@ -176,7 +176,6 @@ impl<'a> RenderableCellsIter<'a> {
|
||||||
config: &'b Config,
|
config: &'b Config,
|
||||||
selection: Option<Span>,
|
selection: Option<Span>,
|
||||||
mut cursor_style: CursorStyle,
|
mut cursor_style: CursorStyle,
|
||||||
metrics: font::Metrics,
|
|
||||||
) -> RenderableCellsIter<'b> {
|
) -> RenderableCellsIter<'b> {
|
||||||
let grid = &term.grid;
|
let grid = &term.grid;
|
||||||
|
|
||||||
|
@ -226,13 +225,10 @@ impl<'a> RenderableCellsIter<'a> {
|
||||||
// Load cursor glyph
|
// Load cursor glyph
|
||||||
let cursor = &term.cursor.point;
|
let cursor = &term.cursor.point;
|
||||||
let cursor_visible = term.mode.contains(TermMode::SHOW_CURSOR) && grid.contains(cursor);
|
let cursor_visible = term.mode.contains(TermMode::SHOW_CURSOR) && grid.contains(cursor);
|
||||||
let cursor_cell = if cursor_visible {
|
let cursor_key = if cursor_visible {
|
||||||
let offset_x = config.font.offset.x;
|
|
||||||
let offset_y = config.font.offset.y;
|
|
||||||
|
|
||||||
let is_wide = grid[cursor].flags.contains(cell::Flags::WIDE_CHAR)
|
let is_wide = grid[cursor].flags.contains(cell::Flags::WIDE_CHAR)
|
||||||
&& (cursor.col + 1) < grid.num_cols();
|
&& (cursor.col + 1) < grid.num_cols();
|
||||||
Some(cursor::get_cursor_glyph(cursor_style, metrics, offset_x, offset_y, is_wide))
|
Some(CursorKey { style: cursor_style, is_wide })
|
||||||
} else {
|
} else {
|
||||||
// Use hidden cursor so text will not get inverted
|
// Use hidden cursor so text will not get inverted
|
||||||
cursor_style = CursorStyle::Hidden;
|
cursor_style = CursorStyle::Hidden;
|
||||||
|
@ -248,7 +244,7 @@ impl<'a> RenderableCellsIter<'a> {
|
||||||
url_highlight: &grid.url_highlight,
|
url_highlight: &grid.url_highlight,
|
||||||
config,
|
config,
|
||||||
colors: &term.colors,
|
colors: &term.colors,
|
||||||
cursor_cell,
|
cursor_key,
|
||||||
cursor_style,
|
cursor_style,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -257,7 +253,7 @@ impl<'a> RenderableCellsIter<'a> {
|
||||||
#[derive(Clone, Debug)]
|
#[derive(Clone, Debug)]
|
||||||
pub enum RenderableCellContent {
|
pub enum RenderableCellContent {
|
||||||
Chars([char; cell::MAX_ZEROWIDTH_CHARS + 1]),
|
Chars([char; cell::MAX_ZEROWIDTH_CHARS + 1]),
|
||||||
Cursor((CursorStyle, RasterizedGlyph)),
|
Cursor(CursorKey),
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Debug)]
|
#[derive(Clone, Debug)]
|
||||||
|
@ -377,7 +373,7 @@ impl<'a> Iterator for RenderableCellsIter<'a> {
|
||||||
loop {
|
loop {
|
||||||
if self.cursor_offset == self.inner.offset() && self.inner.column() == self.cursor.col {
|
if self.cursor_offset == self.inner.offset() && self.inner.column() == self.cursor.col {
|
||||||
// Handle cursor
|
// Handle cursor
|
||||||
if let Some(cursor_cell) = self.cursor_cell.take() {
|
if let Some(cursor_key) = self.cursor_key.take() {
|
||||||
let cell = Indexed {
|
let cell = Indexed {
|
||||||
inner: self.grid[self.cursor],
|
inner: self.grid[self.cursor],
|
||||||
column: self.cursor.col,
|
column: self.cursor.col,
|
||||||
|
@ -386,8 +382,7 @@ impl<'a> Iterator for RenderableCellsIter<'a> {
|
||||||
let mut renderable_cell =
|
let mut renderable_cell =
|
||||||
RenderableCell::new(self.config, self.colors, cell, false);
|
RenderableCell::new(self.config, self.colors, cell, false);
|
||||||
|
|
||||||
renderable_cell.inner =
|
renderable_cell.inner = RenderableCellContent::Cursor(cursor_key);
|
||||||
RenderableCellContent::Cursor((self.cursor_style, cursor_cell));
|
|
||||||
|
|
||||||
if let Some(color) = self.config.colors.cursor.cursor {
|
if let Some(color) = self.config.colors.cursor.cursor {
|
||||||
renderable_cell.fg = color;
|
renderable_cell.fg = color;
|
||||||
|
@ -1102,7 +1097,6 @@ impl Term {
|
||||||
&'b self,
|
&'b self,
|
||||||
config: &'b Config,
|
config: &'b Config,
|
||||||
window_focused: bool,
|
window_focused: bool,
|
||||||
metrics: font::Metrics,
|
|
||||||
) -> RenderableCellsIter<'_> {
|
) -> RenderableCellsIter<'_> {
|
||||||
let alt_screen = self.mode.contains(TermMode::ALT_SCREEN);
|
let alt_screen = self.mode.contains(TermMode::ALT_SCREEN);
|
||||||
let selection = self.grid.selection.as_ref().and_then(|s| s.to_span(self, alt_screen));
|
let selection = self.grid.selection.as_ref().and_then(|s| s.to_span(self, alt_screen));
|
||||||
|
@ -1113,7 +1107,7 @@ impl Term {
|
||||||
CursorStyle::HollowBlock
|
CursorStyle::HollowBlock
|
||||||
};
|
};
|
||||||
|
|
||||||
RenderableCellsIter::new(&self, config, selection, cursor, metrics)
|
RenderableCellsIter::new(&self, config, selection, cursor)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Resize terminal to new dimensions
|
/// Resize terminal to new dimensions
|
||||||
|
@ -2424,18 +2418,8 @@ mod benches {
|
||||||
let mut terminal = Term::new(&config, size, MessageBuffer::new(), Clipboard::new_nop());
|
let mut terminal = Term::new(&config, size, MessageBuffer::new(), Clipboard::new_nop());
|
||||||
mem::swap(&mut terminal.grid, &mut grid);
|
mem::swap(&mut terminal.grid, &mut grid);
|
||||||
|
|
||||||
let metrics = font::Metrics {
|
|
||||||
descent: 0.,
|
|
||||||
line_height: 0.,
|
|
||||||
average_advance: 0.,
|
|
||||||
underline_position: 0.,
|
|
||||||
underline_thickness: 0.,
|
|
||||||
strikeout_position: 0.,
|
|
||||||
strikeout_thickness: 0.,
|
|
||||||
};
|
|
||||||
|
|
||||||
b.iter(|| {
|
b.iter(|| {
|
||||||
let iter = terminal.renderable_cells(&config, false, metrics);
|
let iter = terminal.renderable_cells(&config, false);
|
||||||
for cell in iter {
|
for cell in iter {
|
||||||
test::black_box(cell);
|
test::black_box(cell);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue