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
|
x: 0
|
||||||
y: 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
|
# 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
|
# for retina displays, but for non-retina you probably want this set to
|
||||||
# false.
|
# false.
|
||||||
|
|
|
@ -73,10 +73,6 @@ font:
|
||||||
x: 0
|
x: 0
|
||||||
y: 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
|
# 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
|
# for retina displays, but for non-retina you probably want this set to
|
||||||
# false.
|
# false.
|
||||||
|
|
|
@ -183,6 +183,10 @@ impl ::Rasterize for Rasterizer {
|
||||||
Err(Error::MissingGlyph(glyph.c))
|
Err(Error::MissingGlyph(glyph.c))
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn update_dpr(&mut self, device_pixel_ratio: f32) {
|
||||||
|
self.device_pixel_ratio = device_pixel_ratio;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Rasterizer {
|
impl Rasterizer {
|
||||||
|
|
|
@ -106,6 +106,9 @@ impl ::Rasterize for FreeTypeRasterizer {
|
||||||
self.get_rendered_glyph(glyph_key)
|
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 {
|
pub trait IntoFontconfigType {
|
||||||
|
|
|
@ -348,4 +348,7 @@ pub trait Rasterize {
|
||||||
|
|
||||||
/// Rasterize the glyph described by `GlyphKey`.
|
/// Rasterize the glyph described by `GlyphKey`.
|
||||||
fn get_glyph(&mut self, GlyphKey) -> Result<RasterizedGlyph, Self::Err>;
|
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")]
|
#[serde(default="true_bool", deserialize_with = "default_true_bool")]
|
||||||
use_thin_strokes: bool,
|
use_thin_strokes: bool,
|
||||||
|
|
||||||
#[serde(default="true_bool", deserialize_with = "default_true_bool")]
|
// TODO: Deprecated
|
||||||
scale_with_dpi: bool,
|
#[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 {
|
fn default_bold_desc() -> FontDescription {
|
||||||
|
@ -1639,11 +1649,6 @@ impl Font {
|
||||||
.. self
|
.. self
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Check whether dpi should be applied
|
|
||||||
pub fn scale_with_dpi(&self) -> bool {
|
|
||||||
self.scale_with_dpi
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(target_os = "macos")]
|
#[cfg(target_os = "macos")]
|
||||||
|
@ -1655,7 +1660,7 @@ impl Default for Font {
|
||||||
italic: FontDescription::new_with_family("Menlo"),
|
italic: FontDescription::new_with_family("Menlo"),
|
||||||
size: Size::new(11.0),
|
size: Size::new(11.0),
|
||||||
use_thin_strokes: true,
|
use_thin_strokes: true,
|
||||||
scale_with_dpi: true,
|
scale_with_dpi: None,
|
||||||
glyph_offset: Default::default(),
|
glyph_offset: Default::default(),
|
||||||
offset: Default::default(),
|
offset: Default::default(),
|
||||||
}
|
}
|
||||||
|
@ -1671,7 +1676,7 @@ impl Default for Font {
|
||||||
italic: FontDescription::new_with_family("monospace"),
|
italic: FontDescription::new_with_family("monospace"),
|
||||||
size: Size::new(11.0),
|
size: Size::new(11.0),
|
||||||
use_thin_strokes: false,
|
use_thin_strokes: false,
|
||||||
scale_with_dpi: true,
|
scale_with_dpi: None,
|
||||||
glyph_offset: Default::default(),
|
glyph_offset: Default::default(),
|
||||||
offset: Default::default(),
|
offset: Default::default(),
|
||||||
}
|
}
|
||||||
|
|
|
@ -140,23 +140,18 @@ impl Display {
|
||||||
// Create the window where Alacritty will be displayed
|
// Create the window where Alacritty will be displayed
|
||||||
let mut window = Window::new(&options, config.window())?;
|
let mut window = Window::new(&options, config.window())?;
|
||||||
|
|
||||||
let dpi_factor = if config.font().scale_with_dpi() {
|
let dpr = window.hidpi_factor();
|
||||||
window.hidpi_factor()
|
info!("device_pixel_ratio: {}", dpr);
|
||||||
} else {
|
|
||||||
1.0
|
|
||||||
};
|
|
||||||
// get window properties for initializing the other subsystems
|
// get window properties for initializing the other subsystems
|
||||||
let mut viewport_size = window.inner_size_pixels()
|
let mut viewport_size = window.inner_size_pixels()
|
||||||
.expect("glutin returns window size").to_physical(dpi_factor);
|
.expect("glutin returns window size").to_physical(dpr);
|
||||||
|
|
||||||
|
|
||||||
info!("device_pixel_ratio: {}", dpi_factor);
|
|
||||||
|
|
||||||
// Create renderer
|
// Create renderer
|
||||||
let mut renderer = QuadRenderer::new(config, viewport_size)?;
|
let mut renderer = QuadRenderer::new(config, viewport_size)?;
|
||||||
|
|
||||||
let (glyph_cache, cell_width, cell_height) =
|
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()
|
let dimensions = options.dimensions()
|
||||||
|
@ -171,7 +166,7 @@ impl Display {
|
||||||
(width + 2 * u32::from(config.padding().x)) as f64,
|
(width + 2 * u32::from(config.padding().x)) as f64,
|
||||||
(height + 2 * u32::from(config.padding().y)) 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);
|
renderer.resize(new_viewport_size);
|
||||||
viewport_size = new_viewport_size;
|
viewport_size = new_viewport_size;
|
||||||
}
|
}
|
||||||
|
@ -179,7 +174,7 @@ impl Display {
|
||||||
info!("Cell Size: ({} x {})", cell_width, cell_height);
|
info!("Cell Size: ({} x {})", cell_width, cell_height);
|
||||||
|
|
||||||
let size_info = SizeInfo {
|
let size_info = SizeInfo {
|
||||||
dpi_factor,
|
dpr,
|
||||||
width: viewport_size.width as f32,
|
width: viewport_size.width as f32,
|
||||||
height: viewport_size.height as f32,
|
height: viewport_size.height as f32,
|
||||||
cell_width: cell_width 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>
|
-> Result<(GlyphCache, f32, f32), Error>
|
||||||
{
|
{
|
||||||
let font = config.font().clone();
|
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
|
// Initialize glyph cache
|
||||||
let glyph_cache = {
|
let glyph_cache = {
|
||||||
|
@ -255,10 +250,11 @@ impl Display {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn update_glyph_cache(&mut self, config: &Config) {
|
pub fn update_glyph_cache(&mut self, config: &Config) {
|
||||||
|
let dpr = self.size_info.dpr;
|
||||||
let cache = &mut self.glyph_cache;
|
let cache = &mut self.glyph_cache;
|
||||||
let size = self.font_size;
|
let size = self.font_size;
|
||||||
self.renderer.with_loader(|mut api| {
|
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();
|
let metrics = cache.font_metrics();
|
||||||
|
@ -292,19 +288,14 @@ impl Display {
|
||||||
// Resize events are emitted via glutin/winit with logical sizes
|
// Resize events are emitted via glutin/winit with logical sizes
|
||||||
// However the terminal, window and renderer use physical sizes
|
// However the terminal, window and renderer use physical sizes
|
||||||
// so a conversion must be done here
|
// 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() {
|
// Font size/DPI factor modification detected
|
||||||
self.window.hidpi_factor()
|
let dpr = self.window.hidpi_factor();
|
||||||
} else {
|
if terminal.font_size != self.font_size || dpr != self.size_info.dpr {
|
||||||
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;
|
|
||||||
self.font_size = terminal.font_size;
|
self.font_size = terminal.font_size;
|
||||||
|
self.size_info.dpr = dpr;
|
||||||
self.update_glyph_cache(config);
|
self.update_glyph_cache(config);
|
||||||
|
|
||||||
if new_size == None {
|
if new_size == None {
|
||||||
|
|
|
@ -339,7 +339,7 @@ impl<N: Notify> Processor<N> {
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
CursorMoved { position: lpos, modifiers, .. } => {
|
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 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);
|
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;
|
use input::ActionContext;
|
||||||
let path: String = path.to_string_lossy().into();
|
let path: String = path.to_string_lossy().into();
|
||||||
processor.ctx.write_to_pty(path.into_bytes());
|
processor.ctx.write_to_pty(path.into_bytes());
|
||||||
}
|
},
|
||||||
|
HiDpiFactorChanged(_) => self.terminal.dirty = true,
|
||||||
_ => (),
|
_ => (),
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
|
@ -735,7 +735,7 @@ mod tests {
|
||||||
cell_height: 3.0,
|
cell_height: 3.0,
|
||||||
padding_x: 0.0,
|
padding_x: 0.0,
|
||||||
padding_y: 0.0,
|
padding_y: 0.0,
|
||||||
dpi_factor: 1.0,
|
dpr: 1.0,
|
||||||
};
|
};
|
||||||
|
|
||||||
let mut terminal = Term::new(&config, size);
|
let mut terminal = Term::new(&config, size);
|
||||||
|
|
|
@ -294,19 +294,24 @@ impl GlyphCache {
|
||||||
&mut self,
|
&mut self,
|
||||||
font: &config::Font,
|
font: &config::Font,
|
||||||
size: font::Size,
|
size: font::Size,
|
||||||
|
dpr: f64,
|
||||||
loader: &mut L
|
loader: &mut L
|
||||||
) -> Result<(), font::Error> {
|
) -> Result<(), font::Error> {
|
||||||
// Clear currently cached data in both GL and the registry
|
// Clear currently cached data in both GL and the registry
|
||||||
loader.clear();
|
loader.clear();
|
||||||
self.cache = HashMap::default();
|
self.cache = HashMap::default();
|
||||||
|
|
||||||
|
// Update dpi scaling
|
||||||
|
self.rasterizer.update_dpr(dpr as f32);
|
||||||
|
|
||||||
// Recompute font keys
|
// Recompute font keys
|
||||||
let font = font.to_owned().with_size(size);
|
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)?;
|
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() })?;
|
self.rasterizer.get_glyph(GlyphKey { font_key: regular, c: 'm', size: font.size() })?;
|
||||||
let metrics = self.rasterizer.metrics(regular)?;
|
let metrics = self.rasterizer.metrics(regular)?;
|
||||||
|
|
||||||
|
info!("Font size changed: {:?} [DPR: {}]", font.size, dpr);
|
||||||
|
|
||||||
self.font_size = font.size;
|
self.font_size = font.size;
|
||||||
self.font_key = regular;
|
self.font_key = regular;
|
||||||
self.bold_key = bold;
|
self.bold_key = bold;
|
||||||
|
@ -715,7 +720,7 @@ impl QuadRenderer {
|
||||||
|
|
||||||
pub fn resize(&mut self, size: PhysicalSize) {
|
pub fn resize(&mut self, size: PhysicalSize) {
|
||||||
let (width, height) : (u32, u32) = size.into();
|
let (width, height) : (u32, u32) = size.into();
|
||||||
|
|
||||||
let padding_x = i32::from(self.program.padding_x);
|
let padding_x = i32::from(self.program.padding_x);
|
||||||
let padding_y = i32::from(self.program.padding_y);
|
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.update_projection(size.width as f32, size.height as f32);
|
||||||
|
|
||||||
shader.deactivate();
|
shader.deactivate();
|
||||||
|
|
||||||
Ok(shader)
|
Ok(shader)
|
||||||
|
|
|
@ -758,7 +758,7 @@ pub struct SizeInfo {
|
||||||
|
|
||||||
/// DPI factor of the current window
|
/// DPI factor of the current window
|
||||||
#[serde(default)]
|
#[serde(default)]
|
||||||
pub dpi_factor: f64,
|
pub dpr: f64,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl SizeInfo {
|
impl SizeInfo {
|
||||||
|
@ -1972,7 +1972,7 @@ mod tests {
|
||||||
cell_height: 3.0,
|
cell_height: 3.0,
|
||||||
padding_x: 0.0,
|
padding_x: 0.0,
|
||||||
padding_y: 0.0,
|
padding_y: 0.0,
|
||||||
dpi_factor: 1.0,
|
dpr: 1.0,
|
||||||
};
|
};
|
||||||
let mut term = Term::new(&Default::default(), size);
|
let mut term = Term::new(&Default::default(), size);
|
||||||
let mut grid: Grid<Cell> = Grid::new(Line(3), Column(5), &Cell::default());
|
let mut grid: Grid<Cell> = Grid::new(Line(3), Column(5), &Cell::default());
|
||||||
|
@ -2016,7 +2016,7 @@ mod tests {
|
||||||
cell_height: 3.0,
|
cell_height: 3.0,
|
||||||
padding_x: 0.0,
|
padding_x: 0.0,
|
||||||
padding_y: 0.0,
|
padding_y: 0.0,
|
||||||
dpi_factor: 1.0,
|
dpr: 1.0,
|
||||||
};
|
};
|
||||||
let mut term = Term::new(&Default::default(), size);
|
let mut term = Term::new(&Default::default(), size);
|
||||||
let mut grid: Grid<Cell> = Grid::new(Line(1), Column(5), &Cell::default());
|
let mut grid: Grid<Cell> = Grid::new(Line(1), Column(5), &Cell::default());
|
||||||
|
@ -2060,7 +2060,7 @@ mod tests {
|
||||||
cell_height: 3.0,
|
cell_height: 3.0,
|
||||||
padding_x: 0.0,
|
padding_x: 0.0,
|
||||||
padding_y: 0.0,
|
padding_y: 0.0,
|
||||||
dpi_factor: 1.0,
|
dpr: 1.0,
|
||||||
};
|
};
|
||||||
let mut term = Term::new(&Default::default(), size);
|
let mut term = Term::new(&Default::default(), size);
|
||||||
let cursor = Point::new(Line(0), Column(0));
|
let cursor = Point::new(Line(0), Column(0));
|
||||||
|
@ -2079,7 +2079,7 @@ mod tests {
|
||||||
cell_height: 3.0,
|
cell_height: 3.0,
|
||||||
padding_x: 0.0,
|
padding_x: 0.0,
|
||||||
padding_y: 0.0,
|
padding_y: 0.0,
|
||||||
dpi_factor: 1.0,
|
dpr: 1.0,
|
||||||
};
|
};
|
||||||
let config: Config = Default::default();
|
let config: Config = Default::default();
|
||||||
let mut term: Term = Term::new(&config, size);
|
let mut term: Term = Term::new(&config, size);
|
||||||
|
@ -2108,7 +2108,7 @@ mod tests {
|
||||||
cell_height: 3.0,
|
cell_height: 3.0,
|
||||||
padding_x: 0.0,
|
padding_x: 0.0,
|
||||||
padding_y: 0.0,
|
padding_y: 0.0,
|
||||||
dpi_factor: 1.0,
|
dpr: 1.0,
|
||||||
};
|
};
|
||||||
let config: Config = Default::default();
|
let config: Config = Default::default();
|
||||||
let mut term: Term = Term::new(&config, size);
|
let mut term: Term = Term::new(&config, size);
|
||||||
|
@ -2128,7 +2128,7 @@ mod tests {
|
||||||
cell_height: 3.0,
|
cell_height: 3.0,
|
||||||
padding_x: 0.0,
|
padding_x: 0.0,
|
||||||
padding_y: 0.0,
|
padding_y: 0.0,
|
||||||
dpi_factor: 1.0,
|
dpr: 1.0,
|
||||||
};
|
};
|
||||||
let config: Config = Default::default();
|
let config: Config = Default::default();
|
||||||
let mut term: Term = Term::new(&config, size);
|
let mut term: Term = Term::new(&config, size);
|
||||||
|
|
Loading…
Reference in a new issue