Add bold italic font support

If the terminal escape sequences for bold and italic text are active,
the text should be rendered as bold and italic. However, due to missing
support in Alacritty, it would always render this text in bold.

This adds support for combining the bold and italic escapes to render
text in both styles and allows users to override the font for this
scenario using the `font.bold_italic` configuration option.
This commit is contained in:
Chris Morgan 2019-08-25 20:46:52 +10:00 committed by Christian Duerr
parent ad0365219f
commit e69f259d0e
No known key found for this signature in database
GPG Key ID: 85CDAE3C164BA7B4
4 changed files with 56 additions and 18 deletions

View File

@ -17,6 +17,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- Config option `window.gtk_theme_variant` to set GTK theme variant - Config option `window.gtk_theme_variant` to set GTK theme variant
- Completions for `--class` and `-t` (short title) - Completions for `--class` and `-t` (short title)
- Change the mouse cursor when hovering over the message bar and its close button - Change the mouse cursor when hovering over the message bar and its close button
- Support combined bold and italic text (with `font.bold_italic` to customize it)
### Changed ### Changed

View File

@ -145,6 +145,17 @@ font:
# The `style` can be specified to pick a specific face. # The `style` can be specified to pick a specific face.
#style: Italic #style: Italic
# Bold italic font face
#bold_italic:
# Font family
#
# If the bold italic family is not specified, it will fall back to the
# value specified for the normal font.
#family: monospace
# The `style` can be specified to pick a specific face.
#style: Bold Italic
# Point size # Point size
size: 11.0 size: 11.0

View File

@ -23,11 +23,15 @@ pub struct Font {
/// Bold font face /// Bold font face
#[serde(deserialize_with = "failure_default")] #[serde(deserialize_with = "failure_default")]
italic: SecondaryFontDescription, bold: SecondaryFontDescription,
/// Italic font face /// Italic font face
#[serde(deserialize_with = "failure_default")] #[serde(deserialize_with = "failure_default")]
bold: SecondaryFontDescription, italic: SecondaryFontDescription,
/// Bold italic font face
#[serde(deserialize_with = "failure_default")]
bold_italic: SecondaryFontDescription,
/// Font size in points /// Font size in points
#[serde(deserialize_with = "DeserializeSize::deserialize")] #[serde(deserialize_with = "DeserializeSize::deserialize")]
@ -53,6 +57,7 @@ impl Default for Font {
normal: Default::default(), normal: Default::default(),
bold: Default::default(), bold: Default::default(),
italic: Default::default(), italic: Default::default(),
bold_italic: Default::default(),
glyph_offset: Default::default(), glyph_offset: Default::default(),
offset: Default::default(), offset: Default::default(),
#[cfg(target_os = "macos")] #[cfg(target_os = "macos")]
@ -72,14 +77,19 @@ impl Font {
&self.normal &self.normal
} }
// Get bold font description
pub fn bold(&self) -> FontDescription {
self.bold.desc(&self.normal)
}
// Get italic font description // Get italic font description
pub fn italic(&self) -> FontDescription { pub fn italic(&self) -> FontDescription {
self.italic.desc(&self.normal) self.italic.desc(&self.normal)
} }
// Get bold font description // Get bold italic font description
pub fn bold(&self) -> FontDescription { pub fn bold_italic(&self) -> FontDescription {
self.bold.desc(&self.normal) self.bold_italic.desc(&self.normal)
} }
#[cfg(target_os = "macos")] #[cfg(target_os = "macos")]

View File

@ -164,11 +164,14 @@ pub struct GlyphCache {
/// regular font /// regular font
font_key: FontKey, font_key: FontKey,
/// bold font
bold_key: FontKey,
/// italic font /// italic font
italic_key: FontKey, italic_key: FontKey,
/// bold font /// bold italic font
bold_key: FontKey, bold_italic_key: FontKey,
/// font size /// font size
font_size: font::Size, font_size: font::Size,
@ -188,7 +191,7 @@ impl GlyphCache {
where where
L: LoadGlyph, L: LoadGlyph,
{ {
let (regular, bold, italic) = Self::compute_font_keys(font, &mut rasterizer)?; let (regular, bold, italic, bold_italic) = Self::compute_font_keys(font, &mut rasterizer)?;
// Need to load at least one glyph for the face before calling metrics. // Need to load at least one glyph for the face before calling metrics.
// The glyph requested here ('m' at the time of writing) has no special // The glyph requested here ('m' at the time of writing) has no special
@ -205,6 +208,7 @@ impl GlyphCache {
font_key: regular, font_key: regular,
bold_key: bold, bold_key: bold,
italic_key: italic, italic_key: italic,
bold_italic_key: bold_italic,
glyph_offset: font.glyph_offset, glyph_offset: font.glyph_offset,
metrics, metrics,
}; };
@ -212,6 +216,7 @@ impl GlyphCache {
cache.load_glyphs_for_font(regular, loader); cache.load_glyphs_for_font(regular, loader);
cache.load_glyphs_for_font(bold, loader); cache.load_glyphs_for_font(bold, loader);
cache.load_glyphs_for_font(italic, loader); cache.load_glyphs_for_font(italic, loader);
cache.load_glyphs_for_font(bold_italic, loader);
Ok(cache) Ok(cache)
} }
@ -223,11 +228,11 @@ impl GlyphCache {
} }
} }
/// Computes font keys for (Regular, Bold, Italic) /// Computes font keys for (Regular, Bold, Italic, Bold Italic)
fn compute_font_keys( fn compute_font_keys(
font: &config::Font, font: &config::Font,
rasterizer: &mut Rasterizer, rasterizer: &mut Rasterizer,
) -> Result<(FontKey, FontKey, FontKey), font::Error> { ) -> Result<(FontKey, FontKey, FontKey, FontKey), font::Error> {
let size = font.size; let size = font.size;
// Load regular font // Load regular font
@ -256,7 +261,13 @@ impl GlyphCache {
let italic = load_or_regular(italic_desc); let italic = load_or_regular(italic_desc);
Ok((regular, bold, italic)) // Load bold italic font
let bold_italic_desc =
Self::make_desc(&font.bold_italic(), font::Slant::Italic, font::Weight::Bold);
let bold_italic = load_or_regular(bold_italic_desc);
Ok((regular, bold, italic, bold_italic))
} }
fn make_desc( fn make_desc(
@ -314,7 +325,8 @@ impl GlyphCache {
// Recompute font keys // Recompute font keys
let font = font.to_owned().with_size(size); let font = font.to_owned().with_size(size);
let (regular, bold, italic) = Self::compute_font_keys(&font, &mut self.rasterizer)?; let (regular, bold, italic, bold_italic) =
Self::compute_font_keys(&font, &mut self.rasterizer)?;
self.rasterizer.get_glyph(GlyphKey { font_key: regular, c: 'm', size: font.size })?; self.rasterizer.get_glyph(GlyphKey { font_key: regular, c: 'm', size: font.size })?;
let metrics = self.rasterizer.metrics(regular, size)?; let metrics = self.rasterizer.metrics(regular, size)?;
@ -325,11 +337,13 @@ impl GlyphCache {
self.font_key = regular; self.font_key = regular;
self.bold_key = bold; self.bold_key = bold;
self.italic_key = italic; self.italic_key = italic;
self.bold_italic_key = bold_italic;
self.metrics = metrics; self.metrics = metrics;
self.load_glyphs_for_font(regular, loader); self.load_glyphs_for_font(regular, loader);
self.load_glyphs_for_font(bold, loader); self.load_glyphs_for_font(bold, loader);
self.load_glyphs_for_font(italic, loader); self.load_glyphs_for_font(italic, loader);
self.load_glyphs_for_font(bold_italic, loader);
Ok(()) Ok(())
} }
@ -1013,12 +1027,14 @@ impl<'a> RenderApi<'a> {
// Get font key for cell // Get font key for cell
// FIXME this is super inefficient. // FIXME this is super inefficient.
let font_key = if cell.flags.contains(cell::Flags::BOLD) { let font_key = match (
glyph_cache.bold_key cell.flags.contains(cell::Flags::BOLD),
} else if cell.flags.contains(cell::Flags::ITALIC) { cell.flags.contains(cell::Flags::ITALIC),
glyph_cache.italic_key ) {
} else { (false, false) => glyph_cache.font_key,
glyph_cache.font_key (true, false) => glyph_cache.bold_key,
(false, true) => glyph_cache.italic_key,
(true, true) => glyph_cache.bold_italic_key,
}; };
// Don't render text of HIDDEN cells // Don't render text of HIDDEN cells