aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMartin Sucha <2007393+martin-sucha@users.noreply.github.com>2019-02-09 20:04:06 +0100
committerChristian Duerr <chrisduerr@users.noreply.github.com>2019-02-09 19:04:06 +0000
commitb55e219bc4a5378caa9e0070cdf59a9be7ec48d1 (patch)
tree3357c0a24cd55412a97895e3487d5d9553b8c325
parentecd9270ffea36a224e70564604ef1befe05526b8 (diff)
downloadalacritty-b55e219bc4a5378caa9e0070cdf59a9be7ec48d1.tar.gz
alacritty-b55e219bc4a5378caa9e0070cdf59a9be7ec48d1.zip
Change font size only when new metrics are valid
This prevents cell_width or cell_height being zero. Fixes #1693
-rw-r--r--CHANGELOG.md1
-rw-r--r--src/display.rs51
2 files changed, 38 insertions, 14 deletions
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 93826ee6..14fc76cb 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -33,6 +33,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- URLs not opening while terminal is scrolled
- Reliably remove log file when Alacritty is closed and persistent logging is disabled
- Remove selections when clearing the screen partially (scrolling horizontally in less)
+- Crash/Freeze when shrinking the font size too far
### Removed
diff --git a/src/display.rs b/src/display.rs
index 29b79218..ae47b9e3 100644
--- a/src/display.rs
+++ b/src/display.rs
@@ -43,6 +43,9 @@ pub enum Error {
/// Error in renderer
Render(renderer::Error),
+
+ /// Computed cell size is invalid
+ InvalidCellSize,
}
impl ::std::error::Error for Error {
@@ -51,6 +54,7 @@ impl ::std::error::Error for Error {
Error::Window(ref err) => Some(err),
Error::Font(ref err) => Some(err),
Error::Render(ref err) => Some(err),
+ Error::InvalidCellSize => None,
}
}
@@ -59,16 +63,19 @@ impl ::std::error::Error for Error {
Error::Window(ref err) => err.description(),
Error::Font(ref err) => err.description(),
Error::Render(ref err) => err.description(),
+ Error::InvalidCellSize => "cell size is invalid",
}
}
}
impl ::std::fmt::Display for Error {
fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result {
+ use std::error::Error as StdError;
match *self {
Error::Window(ref err) => err.fmt(f),
Error::Font(ref err) => err.fmt(f),
Error::Render(ref err) => err.fmt(f),
+ Error::InvalidCellSize => write!(f, "{}", self.description()),
}
}
}
@@ -255,29 +262,45 @@ impl Display {
// Need font metrics to resize the window properly. This suggests to me the
// font metrics should be computed before creating the window in the first
// place so that a resize is not needed.
- let metrics = glyph_cache.font_metrics();
- let cell_width = metrics.average_advance as f32 + f32::from(font.offset().x);
- let cell_height = metrics.line_height as f32 + f32::from(font.offset().y);
+ let (cell_width, cell_height) =
+ Self::compute_cell_size(&config, &glyph_cache.font_metrics())?;
+
+ Ok((glyph_cache, cell_width, cell_height))
+ }
+
+ fn compute_cell_size(config: &Config, metrics: &font::Metrics) -> Result<(f32, f32), Error> {
+ let cell_width =
+ ((metrics.average_advance + f64::from(config.font().offset().x)) as f32).floor();
+ let cell_height =
+ ((metrics.line_height + f64::from(config.font().offset().y)) as f32).floor();
- // Prevent invalid cell sizes
if cell_width < 1. || cell_height < 1. {
- panic!("font offset is too small");
+ return Err(Error::InvalidCellSize)
}
- Ok((glyph_cache, cell_width.floor(), cell_height.floor()))
+ Ok((cell_width, cell_height))
}
- pub fn update_glyph_cache(&mut self, config: &Config) {
+ pub fn update_glyph_cache(
+ &mut self,
+ config: &Config,
+ size: font::Size
+ ) -> Result<(), Error> {
let dpr = self.size_info.dpr;
let cache = &mut self.glyph_cache;
- let size = self.font_size;
+
+ let (cell_width, cell_height) = Self::compute_cell_size(config, &cache.font_metrics())?;
+
+ self.font_size = size;
+
self.renderer.with_loader(|mut api| {
let _ = cache.update_font_size(config.font(), size, dpr, &mut api);
});
- let metrics = cache.font_metrics();
- self.size_info.cell_width = ((metrics.average_advance + f64::from(config.font().offset().x)) as f32).floor();
- self.size_info.cell_height = ((metrics.line_height + f64::from(config.font().offset().y)) as f32).floor();
+ self.size_info.cell_width = cell_width;
+ self.size_info.cell_height = cell_height;
+
+ Ok(())
}
#[inline]
@@ -323,13 +346,13 @@ impl Display {
));
}
- self.font_size = terminal.font_size;
self.last_message = terminal.message_buffer_mut().message();
self.size_info.dpr = dpr;
}
- if font_changed {
- self.update_glyph_cache(config);
+ if font_changed && self.update_glyph_cache(config, terminal.font_size).is_err() {
+ // Revert the terminal font size back to last known good state
+ terminal.font_size = self.font_size;
}
if let Some(psize) = new_size.take() {