Commit 68bf19a1 authored by Christian Duerr's avatar Christian Duerr Committed by Peter van der meulen

Update glyph cache on DPI change

When the DPI is changed, the glyph cache is now properly updated to
make use of the correct font size again.

This solves an issue where alacritty would be moved to a different
monitor and then part of the text would be rendered offscreen with
selection breaking.
parent bb43d45d
......@@ -127,6 +127,12 @@ font:
scale_with_dpi: true
# Display the time it takes to redraw each frame.
# OS X only: use thin stroke font rendering. Thin strokes are suitable
# for retina displays, but for non-retina you probably want this set to
# false.
use_thin_strokes: true
# Should display the render timer
render_timer: false
# Use custom cursor colors. If `true`, the `colors.cursor.foreground` and
......
......@@ -122,6 +122,9 @@ font:
#
# Thin strokes are suitable for retina displays, but for non-retina screens
# it is recommended to set `use_thin_strokes` to `false`
# OS X only: use thin stroke font rendering. Thin strokes are suitable
# for retina displays, but for non-retina you probably want this set to
# false.
use_thin_strokes: true
# Display the time it takes to redraw each frame.
......
......@@ -184,6 +184,10 @@ impl ::Rasterize for Rasterizer {
Err(Error::MissingGlyph(glyph.c))
})
}
fn update_dpr(&mut self, device_pixel_ratio: f32) {
self.device_pixel_ratio = device_pixel_ratio;
}
}
impl Rasterizer {
......
......@@ -106,6 +106,9 @@ impl ::Rasterize for FreeTypeRasterizer {
self.get_rendered_glyph(glyph_key)
}
fn update_dpr(&mut self, device_pixel_ratio: f32) {
self.device_pixel_ratio = device_pixel_ratio;
}
}
pub trait IntoFontconfigType {
......
......@@ -348,4 +348,7 @@ pub trait Rasterize {
/// Rasterize the glyph described by `GlyphKey`.
fn get_glyph(&mut self, GlyphKey) -> Result<RasterizedGlyph, Self::Err>;
/// Update the Rasterizer's DPI factor
fn update_dpr(&mut self, device_pixel_ratio: f32);
}
......@@ -1801,8 +1801,18 @@ pub struct Font {
#[serde(default="true_bool", deserialize_with = "default_true_bool")]
use_thin_strokes: bool,
#[serde(default="true_bool", deserialize_with = "default_true_bool")]
scale_with_dpi: bool,
// TODO: Deprecated
#[serde(default, deserialize_with = "deserialize_scale_with_dpi")]
scale_with_dpi: Option<()>,
}
fn deserialize_scale_with_dpi<'a, D>(_deserializer: D) -> ::std::result::Result<Option<()>, D::Error>
where D: de::Deserializer<'a>
{
panic!(
"The `scale_with_dpi` field has been deprecated, \
on X11 the WINIT_HIDPI_FACTOR environment variable can be used instead."
);
}
fn default_bold_desc() -> FontDescription {
......@@ -1855,11 +1865,6 @@ impl Font {
.. self
}
}
/// Check whether dpi should be applied
pub fn scale_with_dpi(&self) -> bool {
self.scale_with_dpi
}
}
#[cfg(target_os = "macos")]
......@@ -1871,7 +1876,7 @@ impl Default for Font {
italic: FontDescription::new_with_family("Menlo"),
size: Size::new(11.0),
use_thin_strokes: true,
scale_with_dpi: true,
scale_with_dpi: None,
glyph_offset: Default::default(),
offset: Default::default(),
}
......@@ -1887,7 +1892,7 @@ impl Default for Font {
italic: FontDescription::new_with_family("monospace"),
size: Size::new(11.0),
use_thin_strokes: false,
scale_with_dpi: true,
scale_with_dpi: None,
glyph_offset: Default::default(),
offset: Default::default(),
}
......
......@@ -139,23 +139,18 @@ impl Display {
// Create the window where Alacritty will be displayed
let mut window = Window::new(&options, config.window())?;
let dpi_factor = if config.font().scale_with_dpi() {
window.hidpi_factor()
} else {
1.0
};
let dpr = window.hidpi_factor();
info!("device_pixel_ratio: {}", dpr);
// get window properties for initializing the other subsystems
let mut viewport_size = window.inner_size_pixels()
.expect("glutin returns window size").to_physical(dpi_factor);
info!("device_pixel_ratio: {}", dpi_factor);
.expect("glutin returns window size").to_physical(dpr);
// Create renderer
let mut renderer = QuadRenderer::new(config, viewport_size)?;
let (glyph_cache, cell_width, cell_height) =
Self::new_glyph_cache(dpi_factor, &mut renderer, config)?;
Self::new_glyph_cache(dpr, &mut renderer, config)?;
let dimensions = options.dimensions()
......@@ -170,7 +165,7 @@ impl Display {
(width + 2 * u32::from(config.padding().x)) as f64,
(height + 2 * u32::from(config.padding().y)) as f64);
window.set_inner_size(new_viewport_size.to_logical(dpi_factor));
window.set_inner_size(new_viewport_size.to_logical(dpr));
renderer.resize(new_viewport_size);
viewport_size = new_viewport_size;
}
......@@ -178,7 +173,7 @@ impl Display {
info!("Cell Size: ({} x {})", cell_width, cell_height);
let size_info = SizeInfo {
dpi_factor,
dpr,
width: viewport_size.width as f32,
height: viewport_size.height as f32,
cell_width: cell_width as f32,
......@@ -215,11 +210,11 @@ impl Display {
})
}
fn new_glyph_cache(dpi_factor: f64, renderer: &mut QuadRenderer, config: &Config)
fn new_glyph_cache(dpr: f64, renderer: &mut QuadRenderer, config: &Config)
-> Result<(GlyphCache, f32, f32), Error>
{
let font = config.font().clone();
let rasterizer = font::Rasterizer::new(dpi_factor as f32, config.use_thin_strokes())?;
let rasterizer = font::Rasterizer::new(dpr as f32, config.use_thin_strokes())?;
// Initialize glyph cache
let glyph_cache = {
......@@ -253,10 +248,11 @@ impl Display {
}
pub fn update_glyph_cache(&mut self, config: &Config) {
let dpr = self.size_info.dpr;
let cache = &mut self.glyph_cache;
let size = self.font_size;
self.renderer.with_loader(|mut api| {
let _ = cache.update_font_size(config.font(), size, &mut api);
let _ = cache.update_font_size(config.font(), size, dpr, &mut api);
});
let metrics = cache.font_metrics();
......@@ -290,19 +286,14 @@ impl Display {
// Resize events are emitted via glutin/winit with logical sizes
// However the terminal, window and renderer use physical sizes
// so a conversion must be done here
new_size = Some(sz.to_physical(self.window.hidpi_factor()));
new_size = Some(sz.to_physical(self.size_info.dpr));
}
let dpi_factor = if config.font().scale_with_dpi() {
self.window.hidpi_factor()
} else {
1.0
};
// Font size modification detected
if terminal.font_size != self.font_size || dpi_factor != self.size_info.dpi_factor {
self.size_info.dpi_factor = dpi_factor;
// Font size/DPI factor modification detected
let dpr = self.window.hidpi_factor();
if terminal.font_size != self.font_size || dpr != self.size_info.dpr {
self.font_size = terminal.font_size;
self.size_info.dpr = dpr;
self.update_glyph_cache(config);
if new_size == None {
......
......@@ -353,7 +353,7 @@ impl<N: Notify> Processor<N> {
}
},
CursorMoved { position: lpos, modifiers, .. } => {
let (x, y) = lpos.to_physical(processor.ctx.size_info.dpi_factor).into();
let (x, y) = lpos.to_physical(processor.ctx.size_info.dpr).into();
let x: i32 = limit(x, 0, processor.ctx.size_info.width as i32);
let y: i32 = limit(y, 0, processor.ctx.size_info.height as i32);
......@@ -384,7 +384,8 @@ impl<N: Notify> Processor<N> {
use input::ActionContext;
let path: String = path.to_string_lossy().into();
processor.ctx.write_to_pty(path.into_bytes());
}
},
HiDpiFactorChanged(_) => self.terminal.dirty = true,
_ => (),
}
},
......
......@@ -815,7 +815,7 @@ mod tests {
cell_height: 3.0,
padding_x: 0.0,
padding_y: 0.0,
dpi_factor: 1.0,
dpr: 1.0,
};
let mut terminal = Term::new(&config, size);
......
......@@ -294,19 +294,24 @@ impl GlyphCache {
&mut self,
font: &config::Font,
size: font::Size,
dpr: f64,
loader: &mut L
) -> Result<(), font::Error> {
// Clear currently cached data in both GL and the registry
loader.clear();
self.cache = HashMap::default();
// Update dpi scaling
self.rasterizer.update_dpr(dpr as f32);
// Recompute font keys
let font = font.to_owned().with_size(size);
info!("Font size changed: {:?}", font.size);
let (regular, bold, italic) = Self::compute_font_keys(&font, &mut self.rasterizer)?;
self.rasterizer.get_glyph(GlyphKey { font_key: regular, c: 'm', size: font.size() })?;
let metrics = self.rasterizer.metrics(regular)?;
info!("Font size changed: {:?} [DPR: {}]", font.size, dpr);
self.font_size = font.size;
self.font_key = regular;
self.bold_key = bold;
......@@ -715,7 +720,7 @@ impl QuadRenderer {
pub fn resize(&mut self, size: PhysicalSize) {
let (width, height) : (u32, u32) = size.into();
let padding_x = i32::from(self.program.padding_x);
let padding_y = i32::from(self.program.padding_y);
......@@ -1025,7 +1030,7 @@ impl ShaderProgram {
};
shader.update_projection(size.width as f32, size.height as f32);
shader.deactivate();
Ok(shader)
......
......@@ -789,7 +789,7 @@ pub struct SizeInfo {
/// DPI factor of the current window
#[serde(default)]
pub dpi_factor: f64,
pub dpr: f64,
}
impl SizeInfo {
......@@ -2021,7 +2021,7 @@ mod tests {
cell_height: 3.0,
padding_x: 0.0,
padding_y: 0.0,
dpi_factor: 1.0,
dpr: 1.0,
};
let mut term = Term::new(&Default::default(), size);
let mut grid: Grid<Cell> = Grid::new(Line(3), Column(5), 0, Cell::default());
......@@ -2065,7 +2065,7 @@ mod tests {
cell_height: 3.0,
padding_x: 0.0,
padding_y: 0.0,
dpi_factor: 1.0,
dpr: 1.0,
};
let mut term = Term::new(&Default::default(), size);
let mut grid: Grid<Cell> = Grid::new(Line(1), Column(5), 0, Cell::default());
......@@ -2135,7 +2135,7 @@ mod tests {
cell_height: 3.0,
padding_x: 0.0,
padding_y: 0.0,
dpi_factor: 1.0,
dpr: 1.0,
};
let mut term = Term::new(&Default::default(), size);
let cursor = Point::new(Line(0), Column(0));
......@@ -2154,7 +2154,7 @@ mod tests {
cell_height: 3.0,
padding_x: 0.0,
padding_y: 0.0,
dpi_factor: 1.0,
dpr: 1.0,
};
let config: Config = Default::default();
let mut term: Term = Term::new(&config, size);
......@@ -2183,7 +2183,7 @@ mod tests {
cell_height: 3.0,
padding_x: 0.0,
padding_y: 0.0,
dpi_factor: 1.0,
dpr: 1.0,
};
let config: Config = Default::default();
let mut term: Term = Term::new(&config, size);
......@@ -2203,7 +2203,7 @@ mod tests {
cell_height: 3.0,
padding_x: 0.0,
padding_y: 0.0,
dpi_factor: 1.0,
dpr: 1.0,
};
let config: Config = Default::default();
let mut term: Term = Term::new(&config, size);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment