mirror of
https://github.com/wez/wezterm.git
synced 2024-12-23 05:12:40 +03:00
wezterm-font: move caching of freetype font size into Face
Profiling showed that set_font_size was a hotspot. While there was caching of the size info at the shaper layer, it was also needed in the raster layer, so move it into the raster layer from the shaper layer. refs: #353
This commit is contained in:
parent
c7dc44a538
commit
58eb8e3614
1
.gitignore
vendored
1
.gitignore
vendored
@ -25,3 +25,4 @@
|
|||||||
/wezterm*-src.tar.gz
|
/wezterm*-src.tar.gz
|
||||||
/wezterm-linuxbrew.rb
|
/wezterm-linuxbrew.rb
|
||||||
/wezterm.rb
|
/wezterm.rb
|
||||||
|
/perf.data*
|
||||||
|
@ -3,3 +3,4 @@ members = ["wezterm-mux-server", "wezterm", "wezterm-gui", "strip-ansi-escapes"]
|
|||||||
|
|
||||||
[profile.release]
|
[profile.release]
|
||||||
opt-level = 3
|
opt-level = 3
|
||||||
|
# debug = 1
|
||||||
|
@ -63,6 +63,7 @@ pub fn compute_load_flags_from_config() -> (i32, FT_Render_Mode) {
|
|||||||
pub struct Face {
|
pub struct Face {
|
||||||
pub face: FT_Face,
|
pub face: FT_Face,
|
||||||
_bytes: Vec<u8>,
|
_bytes: Vec<u8>,
|
||||||
|
size: Option<FaceSize>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Drop for Face {
|
impl Drop for Face {
|
||||||
@ -73,14 +74,27 @@ impl Drop for Face {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct FaceSize {
|
||||||
|
size: f64,
|
||||||
|
dpi: u32,
|
||||||
|
cell_width: f64,
|
||||||
|
cell_height: f64,
|
||||||
|
}
|
||||||
|
|
||||||
impl Face {
|
impl Face {
|
||||||
/// This is a wrapper around set_char_size and select_size
|
/// This is a wrapper around set_char_size and select_size
|
||||||
/// that accounts for some weirdness with eg: color emoji
|
/// that accounts for some weirdness with eg: color emoji
|
||||||
pub fn set_font_size(&mut self, size: f64, dpi: u32) -> anyhow::Result<(f64, f64)> {
|
pub fn set_font_size(&mut self, point_size: f64, dpi: u32) -> anyhow::Result<(f64, f64)> {
|
||||||
log::debug!("set_char_size {} dpi={}", size, dpi);
|
if let Some(face_size) = self.size.as_ref() {
|
||||||
|
if face_size.size == point_size && face_size.dpi == dpi {
|
||||||
|
return Ok((face_size.cell_width, face_size.cell_height));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
log::debug!("set_char_size computing {} dpi={}", point_size, dpi);
|
||||||
// Scaling before truncating to integer minimizes the chances of hitting
|
// Scaling before truncating to integer minimizes the chances of hitting
|
||||||
// the fallback code for set_pixel_sizes below.
|
// the fallback code for set_pixel_sizes below.
|
||||||
let size = (size * 64.0) as FT_F26Dot6;
|
let size = (point_size * 64.0) as FT_F26Dot6;
|
||||||
|
|
||||||
let (cell_width, cell_height) = match self.set_char_size(size, size, dpi, dpi) {
|
let (cell_width, cell_height) = match self.set_char_size(size, size, dpi, dpi) {
|
||||||
Ok(_) => {
|
Ok(_) => {
|
||||||
@ -116,6 +130,13 @@ impl Face {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
self.size.replace(FaceSize {
|
||||||
|
size: point_size,
|
||||||
|
dpi,
|
||||||
|
cell_width,
|
||||||
|
cell_height,
|
||||||
|
});
|
||||||
|
|
||||||
Ok((cell_width, cell_height))
|
Ok((cell_width, cell_height))
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -263,6 +284,7 @@ impl Library {
|
|||||||
)
|
)
|
||||||
})?,
|
})?,
|
||||||
_bytes: data,
|
_bytes: data,
|
||||||
|
size: None,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -283,6 +305,7 @@ impl Library {
|
|||||||
face: ft_result(res, face)
|
face: ft_result(res, face)
|
||||||
.with_context(|| format!("FT_New_Memory_Face for index {}", face_index))?,
|
.with_context(|| format!("FT_New_Memory_Face for index {}", face_index))?,
|
||||||
_bytes: data,
|
_bytes: data,
|
||||||
|
size: None,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -50,10 +50,6 @@ fn make_glyphinfo(text: &str, font_idx: usize, info: &Info) -> GlyphInfo {
|
|||||||
struct FontPair {
|
struct FontPair {
|
||||||
face: ftwrap::Face,
|
face: ftwrap::Face,
|
||||||
font: harfbuzz::Font,
|
font: harfbuzz::Font,
|
||||||
size: f64,
|
|
||||||
dpi: u32,
|
|
||||||
cell_width: f64,
|
|
||||||
cell_height: f64,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Hash, PartialEq, Eq, Clone)]
|
#[derive(Debug, Hash, PartialEq, Eq, Clone)]
|
||||||
@ -133,14 +129,7 @@ impl HarfbuzzShaper {
|
|||||||
let mut font = harfbuzz::Font::new(face.face);
|
let mut font = harfbuzz::Font::new(face.face);
|
||||||
let (load_flags, _) = ftwrap::compute_load_flags_from_config();
|
let (load_flags, _) = ftwrap::compute_load_flags_from_config();
|
||||||
font.set_load_flags(load_flags);
|
font.set_load_flags(load_flags);
|
||||||
*opt_pair = Some(FontPair {
|
*opt_pair = Some(FontPair { face, font });
|
||||||
face,
|
|
||||||
font,
|
|
||||||
size: 0.,
|
|
||||||
dpi: 0,
|
|
||||||
cell_width: 0.,
|
|
||||||
cell_height: 0.,
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(Some(RefMut::map(opt_pair, |opt_pair| {
|
Ok(Some(RefMut::map(opt_pair, |opt_pair| {
|
||||||
@ -180,14 +169,8 @@ impl HarfbuzzShaper {
|
|||||||
match self.load_fallback(font_idx)? {
|
match self.load_fallback(font_idx)? {
|
||||||
#[allow(clippy::float_cmp)]
|
#[allow(clippy::float_cmp)]
|
||||||
Some(mut pair) => {
|
Some(mut pair) => {
|
||||||
if pair.size != font_size || pair.dpi != dpi {
|
let (width, _height) = pair.face.set_font_size(font_size, dpi)?;
|
||||||
let (width, height) = pair.face.set_font_size(font_size, dpi)?;
|
cell_width = width;
|
||||||
pair.size = font_size;
|
|
||||||
pair.dpi = dpi;
|
|
||||||
pair.cell_width = width;
|
|
||||||
pair.cell_height = height;
|
|
||||||
}
|
|
||||||
cell_width = pair.cell_width;
|
|
||||||
pair.font.shape(&mut buf, Some(features.as_slice()));
|
pair.font.shape(&mut buf, Some(features.as_slice()));
|
||||||
}
|
}
|
||||||
None => {
|
None => {
|
||||||
|
Loading…
Reference in New Issue
Block a user