1
0
mirror of https://github.com/emilk/egui.git synced 2026-06-27 15:13:12 -04:00

Optimize glyph allocation cache lookups

This commit is contained in:
valadaptive
2025-09-07 21:33:49 -04:00
parent 38fbae0541
commit 4325c8f3c8

View File

@@ -81,8 +81,7 @@ pub struct FontImpl {
ab_glyph_font: ab_glyph::FontArc,
tweak: FontTweak,
glyph_info_cache: ahash::HashMap<char, GlyphInfo>,
glyph_alloc_cache:
ahash::HashMap<(ab_glyph::GlyphId, OrderedFloat<f32>, OrderedFloat<f32>), GlyphAllocation>,
glyph_alloc_cache: ahash::HashMap<(ab_glyph::GlyphId, u64), GlyphAllocation>,
}
trait FontExt {
@@ -262,11 +261,10 @@ impl FontImpl {
return GlyphAllocation::default();
};
let entry = match self.glyph_alloc_cache.entry((
glyph_id,
metrics.px_scale_factor.into(),
metrics.pixels_per_point.into(),
)) {
let entry = match self
.glyph_alloc_cache
.entry((glyph_id, metrics.glyph_cache_key()))
{
std::collections::hash_map::Entry::Occupied(glyph_alloc) => {
return *glyph_alloc.get();
}
@@ -441,6 +439,32 @@ pub struct ScaledMetrics {
pub row_height: f32,
}
impl ScaledMetrics {
fn glyph_cache_key(&self) -> u64 {
// This is faster than hashing two `OrderedFloat`s. Neither scale factor should ever be negative-zero or NaN.
debug_assert!(
self.pixels_per_point.is_finite() && self.pixels_per_point.is_sign_positive(),
"pixels_per_point can be safely hashed as raw bits"
);
debug_assert!(
self.px_scale_factor.is_finite() && self.px_scale_factor.is_sign_positive(),
"px_scale_factor can be safely hashed as raw bits"
);
let dpi_bits = self.pixels_per_point.to_le_bytes();
let scale_bits = self.px_scale_factor.to_le_bytes();
u64::from_le_bytes([
dpi_bits[0],
dpi_bits[1],
dpi_bits[2],
dpi_bits[3],
scale_bits[0],
scale_bits[1],
scale_bits[2],
scale_bits[3],
])
}
}
/// Code points that will always be invisible (zero width).
///
/// See also [`FontImpl::ignore_character`].