1
1
mirror of https://github.com/wez/wezterm.git synced 2024-11-23 06:54:45 +03:00

fonts: adjust descender for scaled fallback fonts

The gist of the issue is that when setting eg: scale=1.2 to draw
a larger CJK glyph, it is drawn at the same descender level, which
makes it more likely to leave the top of the cell.

This commit adjusts the y position by the difference between the
original and the scaled descender so that is less likely to cause
problems.

refs: https://github.com/wez/wezterm/issues/1803
This commit is contained in:
Wez Furlong 2022-04-03 09:39:48 -07:00
parent 7526b0567c
commit 14323a08d1
3 changed files with 29 additions and 14 deletions

View File

@ -568,9 +568,11 @@ impl FontShaper for HarfbuzzShaper {
return Ok(metrics.clone()); return Ok(metrics.clone());
} }
let selected_size = pair.face.set_font_size(size, dpi)?; let scale = self.handles[font_idx].scale.unwrap_or(1.);
let selected_size = pair.face.set_font_size(size * scale, dpi)?;
let y_scale = unsafe { (*(*pair.face.face).size).metrics.y_scale as f64 / 65536.0 }; let y_scale = unsafe { (*(*pair.face.face).size).metrics.y_scale as f64 / 65536.0 };
let metrics = FontMetrics { let mut metrics = FontMetrics {
cell_height: PixelLength::new(selected_size.height), cell_height: PixelLength::new(selected_size.height),
cell_width: PixelLength::new(selected_size.width), cell_width: PixelLength::new(selected_size.width),
// Note: face.face.descender is useless, we have to go through // Note: face.face.descender is useless, we have to go through
@ -588,8 +590,17 @@ impl FontShaper for HarfbuzzShaper {
cap_height: selected_size.cap_height.map(PixelLength::new), cap_height: selected_size.cap_height.map(PixelLength::new),
is_scaled: selected_size.is_scaled, is_scaled: selected_size.is_scaled,
presentation: pair.presentation, presentation: pair.presentation,
force_y_adjust: PixelLength::new(0.),
}; };
// When the user has overridden the scale, we need to stash a y-adjustment
// so that the glyphs are better vertically aligned
// <https://github.com/wez/wezterm/issues/1803>
if scale != 1.0 && metrics.is_scaled {
let diff = metrics.descender - (metrics.descender / scale);
metrics.force_y_adjust = diff;
}
self.metrics.borrow_mut().insert(key, metrics.clone()); self.metrics.borrow_mut().insert(key, metrics.clone());
log::trace!( log::trace!(
@ -625,7 +636,9 @@ impl FontShaper for HarfbuzzShaper {
self.handles self.handles
); );
while let Ok(Some(mut pair)) = self.load_fallback(metrics_idx) { while let Ok(Some(mut pair)) = self.load_fallback(metrics_idx) {
let selected_size = pair.face.set_font_size(size, dpi)?; let selected_size = pair
.face
.set_font_size(size * self.handles[metrics_idx].scale.unwrap_or(1.), dpi)?;
let diff = (theoretical_height - selected_size.height).abs(); let diff = (theoretical_height - selected_size.height).abs();
let factor = diff / theoretical_height; let factor = diff / theoretical_height;
if factor < 2.0 { if factor < 2.0 {

View File

@ -71,6 +71,14 @@ pub struct FontMetrics {
pub is_scaled: bool, pub is_scaled: bool,
pub presentation: Presentation, pub presentation: Presentation,
/// When the user has configured a fallback-specific override,
/// this field contains the difference in the descender heights
/// between the scaled and unscaled versions of the descender.
/// This represents a y-adjustment that should be applied to
/// the glyph to make it appear to line up better.
/// <https://github.com/wez/wezterm/issues/1803>
pub force_y_adjust: PixelLength,
} }
pub struct PresentationWidth<'a> { pub struct PresentationWidth<'a> {

View File

@ -496,17 +496,11 @@ impl<T: Texture2d> GlyphCache<T> {
} }
}; };
let descender_adjust = PixelLength::new(0.0); let descender_adjust = if info.font_idx == 0 {
/* It seems like we don't really need this bit any more. PixelLength::new(0.0)
* See #1203 and #1499 } else {
if info.font_idx == 0 { idx_metrics.force_y_adjust
PixelLength::new(0.0) };
} else {
let descender = idx_metrics.descender * scale;
base_metrics.descender - descender;
PixelLength::new(0.0)
}
*/
let (cell_width, cell_height) = (base_metrics.cell_width, base_metrics.cell_height); let (cell_width, cell_height) = (base_metrics.cell_width, base_metrics.cell_height);