mirror of
https://github.com/alacritty/alacritty.git
synced 2024-11-25 14:05:41 -05:00
Better character cell width with FreeType (#1029)
This should fix #1020, #710, and #902
This commit is contained in:
parent
b396a9a753
commit
59b561b440
1 changed files with 35 additions and 23 deletions
|
@ -86,19 +86,13 @@ impl ::Rasterize for FreeTypeRasterizer {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn metrics(&self, key: FontKey) -> Result<Metrics, Error> {
|
fn metrics(&self, key: FontKey) -> Result<Metrics, Error> {
|
||||||
let face = self.faces
|
let full = self.full_metrics(key)?;
|
||||||
.get(&key)
|
|
||||||
.ok_or(Error::FontNotLoaded)?;
|
|
||||||
|
|
||||||
let size_metrics = face.ft_face.size_metrics()
|
let height = (full.size_metrics.height / 64) as f64;
|
||||||
.ok_or(Error::MissingSizeMetrics)?;
|
let descent = (full.size_metrics.descender / 64) as f32;
|
||||||
|
|
||||||
let width = (size_metrics.max_advance / 64) as f64;
|
|
||||||
let height = (size_metrics.height / 64) as f64;
|
|
||||||
let descent = (size_metrics.descender / 64) as f32;
|
|
||||||
|
|
||||||
Ok(Metrics {
|
Ok(Metrics {
|
||||||
average_advance: width,
|
average_advance: full.cell_width,
|
||||||
line_height: height,
|
line_height: height,
|
||||||
descent: descent,
|
descent: descent,
|
||||||
})
|
})
|
||||||
|
@ -141,6 +135,11 @@ impl IntoFontconfigType for Weight {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct FullMetrics {
|
||||||
|
size_metrics: freetype::ffi::FT_Size_Metrics,
|
||||||
|
cell_width: f64
|
||||||
|
}
|
||||||
|
|
||||||
impl FreeTypeRasterizer {
|
impl FreeTypeRasterizer {
|
||||||
/// Load a font face according to `FontDesc`
|
/// Load a font face according to `FontDesc`
|
||||||
fn get_face(&mut self, desc: &FontDesc, size: Size) -> Result<FontKey, Error> {
|
fn get_face(&mut self, desc: &FontDesc, size: Size) -> Result<FontKey, Error> {
|
||||||
|
@ -159,6 +158,25 @@ impl FreeTypeRasterizer {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn full_metrics(&self, key: FontKey) -> Result<FullMetrics, Error> {
|
||||||
|
let face = self.faces
|
||||||
|
.get(&key)
|
||||||
|
.ok_or(Error::FontNotLoaded)?;
|
||||||
|
|
||||||
|
let size_metrics = face.ft_face.size_metrics()
|
||||||
|
.ok_or(Error::MissingSizeMetrics)?;
|
||||||
|
|
||||||
|
let width = match face.ft_face.load_char('0' as usize, face.load_flags) {
|
||||||
|
Ok(_) => face.ft_face.glyph().metrics().horiAdvance / 64,
|
||||||
|
Err(_) => size_metrics.max_advance / 64
|
||||||
|
} as f64;
|
||||||
|
|
||||||
|
Ok(FullMetrics {
|
||||||
|
size_metrics: size_metrics,
|
||||||
|
cell_width: width
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
fn get_matching_face(
|
fn get_matching_face(
|
||||||
&mut self,
|
&mut self,
|
||||||
desc: &FontDesc,
|
desc: &FontDesc,
|
||||||
|
@ -278,16 +296,13 @@ impl FreeTypeRasterizer {
|
||||||
super::UNDERLINE_CURSOR_CHAR => {
|
super::UNDERLINE_CURSOR_CHAR => {
|
||||||
// Get the primary face metrics
|
// Get the primary face metrics
|
||||||
// This always loads the default face
|
// This always loads the default face
|
||||||
let face = self.faces.get(&glyph_key.font_key).unwrap();
|
let full = self.full_metrics(glyph_key.font_key)?;
|
||||||
let size_metrics = face.ft_face
|
|
||||||
.size_metrics()
|
|
||||||
.ok_or(Error::MissingSizeMetrics)?;
|
|
||||||
|
|
||||||
// Get the bottom of the bounding box
|
// Get the bottom of the bounding box
|
||||||
let descent = (size_metrics.descender / 64) as i32;
|
let descent = (full.size_metrics.descender / 64) as i32;
|
||||||
|
|
||||||
// Get the width of the cell
|
// Get the width of the cell
|
||||||
let width = (size_metrics.max_advance / 64) as i32;
|
let width = full.cell_width as i32;
|
||||||
|
|
||||||
// Return the new custom glyph
|
// Return the new custom glyph
|
||||||
return super::get_underline_cursor_glyph(descent, width);
|
return super::get_underline_cursor_glyph(descent, width);
|
||||||
|
@ -295,20 +310,17 @@ impl FreeTypeRasterizer {
|
||||||
super::BEAM_CURSOR_CHAR | super::BOX_CURSOR_CHAR => {
|
super::BEAM_CURSOR_CHAR | super::BOX_CURSOR_CHAR => {
|
||||||
// Get the primary face metrics
|
// Get the primary face metrics
|
||||||
// This always loads the default face
|
// This always loads the default face
|
||||||
let face = self.faces.get(&glyph_key.font_key).unwrap();
|
let full = self.full_metrics(glyph_key.font_key)?;
|
||||||
let size_metrics = face.ft_face
|
|
||||||
.size_metrics()
|
|
||||||
.ok_or(Error::MissingSizeMetrics)?;
|
|
||||||
|
|
||||||
// Get the height of the cell
|
// Get the height of the cell
|
||||||
let height = (size_metrics.height / 64) as i32;
|
let height = (full.size_metrics.height / 64) as i32;
|
||||||
|
|
||||||
// Get the top of the bounding box
|
// Get the top of the bounding box
|
||||||
let descent = (size_metrics.descender / 64) as i32;
|
let descent = (full.size_metrics.descender / 64) as i32;
|
||||||
let ascent = height + descent;
|
let ascent = height + descent;
|
||||||
|
|
||||||
// Get the width of the cell
|
// Get the width of the cell
|
||||||
let width = (size_metrics.max_advance / 64) as i32;
|
let width = full.cell_width as i32;
|
||||||
|
|
||||||
// Return the new custom glyph
|
// Return the new custom glyph
|
||||||
return if glyph_key.c == super::BEAM_CURSOR_CHAR {
|
return if glyph_key.c == super::BEAM_CURSOR_CHAR {
|
||||||
|
|
Loading…
Reference in a new issue