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:
parent
c772ef3c2b
commit
563f96aa32
11 changed files with 59 additions and 57 deletions
|
@ -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.
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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(),
|
||||
}
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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,
|
||||
_ => (),
|
||||
}
|
||||
},
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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);
|
||||
|
|
Loading…
Reference in a new issue