1
0
Fork 0
mirror of https://github.com/alacritty/alacritty.git synced 2024-11-25 14:05:41 -05:00

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.
This commit is contained in:
Christian Duerr 2018-07-13 21:33:57 +02:00 committed by Matt Keeler
parent c772ef3c2b
commit 563f96aa32
11 changed files with 59 additions and 57 deletions

View file

@ -93,12 +93,6 @@ font:
x: 0
y: 0
# Scale the font size based on the monitor's DPI. This will lead to bigger text on HiDPI
# screens and make reading text a little easier.
# On X11 it is possible to change the DPI for each instance of alacritty by using
# `WINIT_HIDPI_FACTOR=1.0 alacritty` to scale the font.
scale_with_dpi: true
# 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.

View file

@ -73,10 +73,6 @@ font:
x: 0
y: 0
# Scale the font size based on the monitor's DPI. This will lead to bigger text on HiDPI
# screens and make reading text a little easier.
scale_with_dpi: true
# 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.

View file

@ -183,6 +183,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 {

View file

@ -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 {

View file

@ -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);
}

View file

@ -1585,8 +1585,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 {
@ -1639,11 +1649,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")]
@ -1655,7 +1660,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(),
}
@ -1671,7 +1676,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(),
}

View file

@ -140,23 +140,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()
@ -171,7 +166,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;
}
@ -179,7 +174,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,
@ -217,11 +212,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 = {
@ -255,10 +250,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();
@ -292,19 +288,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 {

View file

@ -339,7 +339,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);
@ -374,7 +374,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,
_ => (),
}
},

View file

@ -735,7 +735,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);

View file

@ -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);
@ -1019,7 +1024,7 @@ impl ShaderProgram {
};
shader.update_projection(size.width as f32, size.height as f32);
shader.deactivate();
Ok(shader)

View file

@ -758,7 +758,7 @@ pub struct SizeInfo {
/// DPI factor of the current window
#[serde(default)]
pub dpi_factor: f64,
pub dpr: f64,
}
impl SizeInfo {
@ -1972,7 +1972,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), &Cell::default());
@ -2016,7 +2016,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), &Cell::default());
@ -2060,7 +2060,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));
@ -2079,7 +2079,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);
@ -2108,7 +2108,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);
@ -2128,7 +2128,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);