mirror of
https://github.com/alacritty/alacritty.git
synced 2024-11-18 13:55:23 -05:00
Fix cursor colors
This fixes a recent regression in
cfc20d4f34
which broke cursor colors when
specified in the `colors.cursor` field in the config.
It also removes a lot of unneeded code from the font crate related to
the cursor rendering.
This fixes #2338.
This commit is contained in:
parent
371d13f8ef
commit
0d060d5d80
6 changed files with 22 additions and 196 deletions
|
@ -449,35 +449,6 @@ impl Font {
|
||||||
_size: f64,
|
_size: f64,
|
||||||
use_thin_strokes: bool,
|
use_thin_strokes: bool,
|
||||||
) -> Result<RasterizedGlyph, Error> {
|
) -> Result<RasterizedGlyph, Error> {
|
||||||
// Render custom symbols for underline and beam cursor
|
|
||||||
match character {
|
|
||||||
super::UNDERLINE_CURSOR_CHAR => {
|
|
||||||
// Get the bottom of the bounding box
|
|
||||||
let descent = -(self.ct_font.descent() as i32);
|
|
||||||
// Get the width of the cell
|
|
||||||
let width = self.glyph_advance('0') as i32;
|
|
||||||
// Return the new custom glyph
|
|
||||||
return super::get_underline_cursor_glyph(descent, width);
|
|
||||||
},
|
|
||||||
super::BEAM_CURSOR_CHAR | super::BOX_CURSOR_CHAR => {
|
|
||||||
// Get the top of the bounding box
|
|
||||||
let metrics = self.metrics();
|
|
||||||
let height = metrics.line_height;
|
|
||||||
let ascent = (height - self.ct_font.descent()).ceil();
|
|
||||||
|
|
||||||
// Get the width of the cell
|
|
||||||
let width = self.glyph_advance('0') as i32;
|
|
||||||
|
|
||||||
// Return the new custom glyph
|
|
||||||
if character == super::BEAM_CURSOR_CHAR {
|
|
||||||
return super::get_beam_cursor_glyph(ascent as i32, height as i32, width);
|
|
||||||
} else {
|
|
||||||
return super::get_box_cursor_glyph(ascent as i32, height as i32, width);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
_ => (),
|
|
||||||
}
|
|
||||||
|
|
||||||
let glyph_index =
|
let glyph_index =
|
||||||
self.glyph_index(character).ok_or_else(|| Error::MissingGlyph(character))?;
|
self.glyph_index(character).ok_or_else(|| Error::MissingGlyph(character))?;
|
||||||
|
|
||||||
|
|
|
@ -45,17 +45,14 @@ impl fmt::Debug for Face {
|
||||||
.field("ft_face", &self.ft_face)
|
.field("ft_face", &self.ft_face)
|
||||||
.field("key", &self.key)
|
.field("key", &self.key)
|
||||||
.field("load_flags", &self.load_flags)
|
.field("load_flags", &self.load_flags)
|
||||||
.field(
|
.field("render_mode", &match self.render_mode {
|
||||||
"render_mode",
|
freetype::RenderMode::Normal => "Normal",
|
||||||
&match self.render_mode {
|
freetype::RenderMode::Light => "Light",
|
||||||
freetype::RenderMode::Normal => "Normal",
|
freetype::RenderMode::Mono => "Mono",
|
||||||
freetype::RenderMode::Light => "Light",
|
freetype::RenderMode::Lcd => "Lcd",
|
||||||
freetype::RenderMode::Mono => "Mono",
|
freetype::RenderMode::LcdV => "LcdV",
|
||||||
freetype::RenderMode::Lcd => "Lcd",
|
freetype::RenderMode::Max => "Max",
|
||||||
freetype::RenderMode::LcdV => "LcdV",
|
})
|
||||||
freetype::RenderMode::Max => "Max",
|
|
||||||
},
|
|
||||||
)
|
|
||||||
.field("lcd_filter", &self.lcd_filter)
|
.field("lcd_filter", &self.lcd_filter)
|
||||||
.finish()
|
.finish()
|
||||||
}
|
}
|
||||||
|
@ -313,47 +310,6 @@ impl FreeTypeRasterizer {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_rendered_glyph(&mut self, glyph_key: GlyphKey) -> Result<RasterizedGlyph, Error> {
|
fn get_rendered_glyph(&mut self, glyph_key: GlyphKey) -> Result<RasterizedGlyph, Error> {
|
||||||
// Render a custom symbol for the underline and beam cursor
|
|
||||||
match glyph_key.c {
|
|
||||||
super::UNDERLINE_CURSOR_CHAR => {
|
|
||||||
// Get the primary face metrics
|
|
||||||
// This always loads the default face
|
|
||||||
let full = self.full_metrics(glyph_key.font_key)?;
|
|
||||||
|
|
||||||
// Get the bottom of the bounding box
|
|
||||||
let descent = (full.size_metrics.descender / 64) as i32;
|
|
||||||
|
|
||||||
// Get the width of the cell
|
|
||||||
let width = full.cell_width as i32;
|
|
||||||
|
|
||||||
// Return the new custom glyph
|
|
||||||
return super::get_underline_cursor_glyph(descent, width);
|
|
||||||
},
|
|
||||||
super::BEAM_CURSOR_CHAR | super::BOX_CURSOR_CHAR => {
|
|
||||||
// Get the primary face metrics
|
|
||||||
// This always loads the default face
|
|
||||||
let full = self.full_metrics(glyph_key.font_key)?;
|
|
||||||
|
|
||||||
// Get the height of the cell
|
|
||||||
let height = (full.size_metrics.height / 64) as i32;
|
|
||||||
|
|
||||||
// Get the top of the bounding box
|
|
||||||
let descent = (full.size_metrics.descender / 64) as i32;
|
|
||||||
let ascent = height + descent;
|
|
||||||
|
|
||||||
// Get the width of the cell
|
|
||||||
let width = full.cell_width as i32;
|
|
||||||
|
|
||||||
// Return the new custom glyph
|
|
||||||
return if glyph_key.c == super::BEAM_CURSOR_CHAR {
|
|
||||||
super::get_beam_cursor_glyph(ascent, height, width)
|
|
||||||
} else {
|
|
||||||
super::get_box_cursor_glyph(ascent, height, width)
|
|
||||||
};
|
|
||||||
},
|
|
||||||
_ => (),
|
|
||||||
}
|
|
||||||
|
|
||||||
// Render a normal character if it's not a cursor
|
// Render a normal character if it's not a cursor
|
||||||
let font_key = self.face_for_glyph(glyph_key, false)?;
|
let font_key = self.face_for_glyph(glyph_key, false)?;
|
||||||
let face = &self.faces[&font_key];
|
let face = &self.faces[&font_key];
|
||||||
|
|
|
@ -45,9 +45,9 @@ extern crate foreign_types;
|
||||||
#[cfg_attr(not(windows), macro_use)]
|
#[cfg_attr(not(windows), macro_use)]
|
||||||
extern crate log;
|
extern crate log;
|
||||||
|
|
||||||
|
use std::fmt;
|
||||||
use std::hash::{Hash, Hasher};
|
use std::hash::{Hash, Hasher};
|
||||||
use std::sync::atomic::{AtomicUsize, Ordering};
|
use std::sync::atomic::{AtomicUsize, Ordering};
|
||||||
use std::{cmp, fmt};
|
|
||||||
|
|
||||||
// If target isn't macos or windows, reexport everything from ft
|
// If target isn't macos or windows, reexport everything from ft
|
||||||
#[cfg(not(any(target_os = "macos", windows)))]
|
#[cfg(not(any(target_os = "macos", windows)))]
|
||||||
|
@ -66,21 +66,6 @@ mod darwin;
|
||||||
#[cfg(target_os = "macos")]
|
#[cfg(target_os = "macos")]
|
||||||
pub use darwin::*;
|
pub use darwin::*;
|
||||||
|
|
||||||
/// Width/Height of the cursor relative to the font width
|
|
||||||
pub const CURSOR_WIDTH_PERCENTAGE: i32 = 15;
|
|
||||||
|
|
||||||
/// Character used for the underline cursor
|
|
||||||
// This is part of the private use area and should not conflict with any font
|
|
||||||
pub const UNDERLINE_CURSOR_CHAR: char = '\u{10a3e2}';
|
|
||||||
|
|
||||||
/// Character used for the beam cursor
|
|
||||||
// This is part of the private use area and should not conflict with any font
|
|
||||||
pub const BEAM_CURSOR_CHAR: char = '\u{10a3e3}';
|
|
||||||
|
|
||||||
/// Character used for the empty box cursor
|
|
||||||
// This is part of the private use area and should not conflict with any font
|
|
||||||
pub const BOX_CURSOR_CHAR: char = '\u{10a3e4}';
|
|
||||||
|
|
||||||
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
|
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
|
||||||
pub struct FontDesc {
|
pub struct FontDesc {
|
||||||
name: String,
|
name: String,
|
||||||
|
@ -229,71 +214,6 @@ impl Default for RasterizedGlyph {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Returns a custom underline cursor character
|
|
||||||
pub fn get_underline_cursor_glyph(descent: i32, width: i32) -> Result<RasterizedGlyph, Error> {
|
|
||||||
// Create a new rectangle, the height is relative to the font width
|
|
||||||
let height = cmp::max(width * CURSOR_WIDTH_PERCENTAGE / 100, 1);
|
|
||||||
let buf = vec![255u8; (width * height * 3) as usize];
|
|
||||||
|
|
||||||
// Create a custom glyph with the rectangle data attached to it
|
|
||||||
Ok(RasterizedGlyph {
|
|
||||||
c: UNDERLINE_CURSOR_CHAR,
|
|
||||||
top: descent + height,
|
|
||||||
left: 0,
|
|
||||||
height,
|
|
||||||
width,
|
|
||||||
buf,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
// Returns a custom beam cursor character
|
|
||||||
pub fn get_beam_cursor_glyph(
|
|
||||||
ascent: i32,
|
|
||||||
height: i32,
|
|
||||||
width: i32,
|
|
||||||
) -> Result<RasterizedGlyph, Error> {
|
|
||||||
// Create a new rectangle that is at least one pixel wide
|
|
||||||
let beam_width = cmp::max(width * CURSOR_WIDTH_PERCENTAGE / 100, 1);
|
|
||||||
let buf = vec![255u8; (beam_width * height * 3) as usize];
|
|
||||||
|
|
||||||
// Create a custom glyph with the rectangle data attached to it
|
|
||||||
Ok(RasterizedGlyph {
|
|
||||||
c: BEAM_CURSOR_CHAR,
|
|
||||||
top: ascent,
|
|
||||||
left: 0,
|
|
||||||
height,
|
|
||||||
width: beam_width,
|
|
||||||
buf,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
// Returns a custom box cursor character
|
|
||||||
pub fn get_box_cursor_glyph(
|
|
||||||
ascent: i32,
|
|
||||||
height: i32,
|
|
||||||
width: i32,
|
|
||||||
) -> Result<RasterizedGlyph, Error> {
|
|
||||||
// Create a new box outline rectangle
|
|
||||||
let border_width = cmp::max(width * CURSOR_WIDTH_PERCENTAGE / 100, 1);
|
|
||||||
let mut buf = Vec::with_capacity((width * height * 3) as usize);
|
|
||||||
for y in 0..height {
|
|
||||||
for x in 0..width {
|
|
||||||
if y < border_width
|
|
||||||
|| y >= height - border_width
|
|
||||||
|| x < border_width
|
|
||||||
|| x >= width - border_width
|
|
||||||
{
|
|
||||||
buf.append(&mut vec![255u8; 3]);
|
|
||||||
} else {
|
|
||||||
buf.append(&mut vec![0u8; 3]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Create a custom glyph with the rectangle data attached to it
|
|
||||||
Ok(RasterizedGlyph { c: BOX_CURSOR_CHAR, top: ascent, left: 0, height, width, buf })
|
|
||||||
}
|
|
||||||
|
|
||||||
struct BufDebugger<'a>(&'a [u8]);
|
struct BufDebugger<'a>(&'a [u8]);
|
||||||
|
|
||||||
impl<'a> fmt::Debug for BufDebugger<'a> {
|
impl<'a> fmt::Debug for BufDebugger<'a> {
|
||||||
|
|
|
@ -84,35 +84,6 @@ impl crate::Rasterize for RustTypeRasterizer {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_glyph(&mut self, glyph_key: GlyphKey) -> Result<RasterizedGlyph, Error> {
|
fn get_glyph(&mut self, glyph_key: GlyphKey) -> Result<RasterizedGlyph, Error> {
|
||||||
match glyph_key.c {
|
|
||||||
super::UNDERLINE_CURSOR_CHAR => {
|
|
||||||
let metrics = self.metrics(glyph_key.font_key, glyph_key.size)?;
|
|
||||||
return super::get_underline_cursor_glyph(
|
|
||||||
metrics.descent as i32,
|
|
||||||
metrics.average_advance as i32,
|
|
||||||
);
|
|
||||||
},
|
|
||||||
super::BEAM_CURSOR_CHAR => {
|
|
||||||
let metrics = self.metrics(glyph_key.font_key, glyph_key.size)?;
|
|
||||||
|
|
||||||
return super::get_beam_cursor_glyph(
|
|
||||||
(metrics.line_height + f64::from(metrics.descent)).round() as i32,
|
|
||||||
metrics.line_height.round() as i32,
|
|
||||||
metrics.average_advance.round() as i32,
|
|
||||||
);
|
|
||||||
},
|
|
||||||
super::BOX_CURSOR_CHAR => {
|
|
||||||
let metrics = self.metrics(glyph_key.font_key, glyph_key.size)?;
|
|
||||||
|
|
||||||
return super::get_box_cursor_glyph(
|
|
||||||
(metrics.line_height + f64::from(metrics.descent)).round() as i32,
|
|
||||||
metrics.line_height.round() as i32,
|
|
||||||
metrics.average_advance.round() as i32,
|
|
||||||
);
|
|
||||||
},
|
|
||||||
_ => (),
|
|
||||||
}
|
|
||||||
|
|
||||||
let scaled_glyph = self.fonts[glyph_key.font_key.token as usize]
|
let scaled_glyph = self.fonts[glyph_key.font_key.token as usize]
|
||||||
.glyph(glyph_key.c)
|
.glyph(glyph_key.c)
|
||||||
.scaled(Scale::uniform(glyph_key.size.as_f32_pts() * self.dpi_ratio * 96. / 72.));
|
.scaled(Scale::uniform(glyph_key.size.as_f32_pts() * self.dpi_ratio * 96. / 72.));
|
||||||
|
|
|
@ -21,7 +21,7 @@ use serde::de::{MapAccess, Unexpected, Visitor};
|
||||||
use serde::{self, de, Deserialize};
|
use serde::{self, de, Deserialize};
|
||||||
use serde_yaml;
|
use serde_yaml;
|
||||||
|
|
||||||
use crate::ansi::{Color, CursorStyle, NamedColor};
|
use crate::ansi::CursorStyle;
|
||||||
use crate::cli::Options;
|
use crate::cli::Options;
|
||||||
use crate::index::{Column, Line};
|
use crate::index::{Column, Line};
|
||||||
use crate::input::{Action, Binding, KeyBinding, MouseBinding};
|
use crate::input::{Action, Binding, KeyBinding, MouseBinding};
|
||||||
|
@ -1877,14 +1877,14 @@ impl Config {
|
||||||
|
|
||||||
/// Cursor foreground color
|
/// Cursor foreground color
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn cursor_text_color(&self) -> Option<Color> {
|
pub fn cursor_text_color(&self) -> Option<Rgb> {
|
||||||
self.colors.cursor.text.map(|_| Color::Named(NamedColor::CursorText))
|
self.colors.cursor.text
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Cursor background color
|
/// Cursor background color
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn cursor_cursor_color(&self) -> Option<Color> {
|
pub fn cursor_cursor_color(&self) -> Option<Rgb> {
|
||||||
self.colors.cursor.cursor.map(|_| Color::Named(NamedColor::Cursor))
|
self.colors.cursor.cursor
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Enable experimental conpty backend (Windows only)
|
/// Enable experimental conpty backend (Windows only)
|
||||||
|
|
|
@ -385,6 +385,10 @@ impl<'a> Iterator for RenderableCellsIter<'a> {
|
||||||
|
|
||||||
renderable_cell.inner = RenderableCellContent::Raw(cursor_cell);
|
renderable_cell.inner = RenderableCellContent::Raw(cursor_cell);
|
||||||
|
|
||||||
|
if let Some(color) = self.config.cursor_cursor_color() {
|
||||||
|
renderable_cell.fg = color;
|
||||||
|
}
|
||||||
|
|
||||||
return Some(renderable_cell);
|
return Some(renderable_cell);
|
||||||
} else {
|
} else {
|
||||||
let mut cell =
|
let mut cell =
|
||||||
|
@ -392,6 +396,10 @@ impl<'a> Iterator for RenderableCellsIter<'a> {
|
||||||
|
|
||||||
if self.cursor_style == CursorStyle::Block {
|
if self.cursor_style == CursorStyle::Block {
|
||||||
std::mem::swap(&mut cell.bg, &mut cell.fg);
|
std::mem::swap(&mut cell.bg, &mut cell.fg);
|
||||||
|
|
||||||
|
if let Some(color) = self.config.cursor_text_color() {
|
||||||
|
cell.fg = color;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return Some(cell);
|
return Some(cell);
|
||||||
|
|
Loading…
Reference in a new issue