1
1
mirror of https://github.com/wez/wezterm.git synced 2024-09-20 11:17:15 +03:00

fix bar cursors when moving through double-width cells

Don't render two copies of the cursor in the same cell,
and compute different graphics for double wide cells.

refs: #1548
This commit is contained in:
Wez Furlong 2022-01-16 12:19:49 -07:00
parent 71630844c8
commit 25c0540875
4 changed files with 29 additions and 23 deletions

View File

@ -3674,11 +3674,14 @@ impl<T: Texture2d> GlyphCache<T> {
&mut self,
shape: Option<CursorShape>,
metrics: &RenderMetrics,
width: u8,
) -> anyhow::Result<Sprite<T>> {
if let Some(sprite) = self.cursor_glyphs.get(&shape) {
if let Some(sprite) = self.cursor_glyphs.get(&(shape, width)) {
return Ok(sprite.clone());
}
let metrics = metrics.scale_cell_width(width);
let mut buffer = Image::new(
metrics.cell_size.width as usize,
metrics.cell_size.height as usize,
@ -3740,7 +3743,7 @@ impl<T: Texture2d> GlyphCache<T> {
}
let sprite = self.atlas.allocate(&buffer)?;
self.cursor_glyphs.insert(shape, sprite.clone());
self.cursor_glyphs.insert((shape, width), sprite.clone());
Ok(sprite)
}

View File

@ -254,7 +254,7 @@ pub struct GlyphCache<T: Texture2d> {
frame_cache: HashMap<[u8; 32], Sprite<T>>,
line_glyphs: HashMap<LineKey, Sprite<T>>,
pub block_glyphs: HashMap<SizedBlockKey, Sprite<T>>,
pub cursor_glyphs: HashMap<Option<CursorShape>, Sprite<T>>,
pub cursor_glyphs: HashMap<(Option<CursorShape>, u8), Sprite<T>>,
pub color: HashMap<(RgbColor, NotNan<f32>), Sprite<T>>,
}

View File

@ -1970,28 +1970,21 @@ impl super::TermWindow {
let pixel_width = glyph.x_advance.get() as f32;
// We'd like to render the cursor with the cell width
// so that double-wide cells look more reasonable.
// If we have a cursor shape, compute the intended cursor
// width. We only use that if we're the first cell that
// comprises this glyph; if for some reason the cursor position
// is in the middle of a glyph we just use a single cell.
let cursor_width = cursor_shape
.map(|_| {
if glyph_idx == 0 {
info.pos.num_cells
} else {
1
}
})
.unwrap_or(1) as f32;
// Note: in use_pixel_positioning mode, we draw backgrounds
// for glyph_idx == 0 based on the whole glyph advance, rather than
// for each of the cells.
if cursor_shape.is_some() {
if !params.use_pixel_positioning || glyph_idx == 0 {
if glyph_idx == 0 {
// We'd like to render the cursor with the cell width
// so that double-wide cells look more reasonable.
// If we have a cursor shape, compute the intended cursor
// width. We only use that if we're the first cell that
// comprises this glyph; if for some reason the cursor position
// is in the middle of a glyph we just use a single cell.
let cursor_width =
cursor_shape.map(|_| info.pos.num_cells).unwrap_or(1);
let mut quad = layers[0].allocate()?;
quad.set_position(
pos_x,
@ -2000,7 +1993,7 @@ impl super::TermWindow {
+ if params.use_pixel_positioning {
pixel_width
} else {
cursor_width * cell_width
cursor_width as f32 * cell_width
},
pos_y + cell_height,
);
@ -2011,7 +2004,11 @@ impl super::TermWindow {
gl_state
.glyph_cache
.borrow_mut()
.cursor_sprite(cursor_shape, &params.render_metrics)?
.cursor_sprite(
cursor_shape,
&params.render_metrics,
cursor_width,
)?
.texture_coords(),
);
@ -2274,7 +2271,7 @@ impl super::TermWindow {
gl_state
.glyph_cache
.borrow_mut()
.cursor_sprite(cursor_shape, &params.render_metrics)?
.cursor_sprite(cursor_shape, &params.render_metrics, 1)?
.texture_coords(),
);
quad.set_fg_color(cursor_border_color);

View File

@ -61,6 +61,12 @@ impl RenderMetrics {
}
}
pub fn scale_cell_width(&self, scale: u8) -> Self {
let mut scaled = self.clone();
scaled.cell_size.width *= scale as isize;
scaled
}
pub fn new(fonts: &Rc<FontConfiguration>) -> anyhow::Result<Self> {
let metrics = fonts
.default_font_metrics()