1
0
mirror of https://github.com/emilk/egui.git synced 2026-08-30 05:10:03 -04:00

Refactor GlyphInfo

This commit is contained in:
Emil Ernerfeldt
2025-09-05 10:07:18 +02:00
committed by valadaptive
parent 686f0709db
commit 6f53261f4a
3 changed files with 29 additions and 33 deletions

View File

@@ -41,25 +41,20 @@ pub struct GlyphInfo {
/// Used for pair-kerning.
///
/// Doesn't need to be unique.
/// Use `ab_glyph::GlyphId(0)` if you just want to have an id, and don't care.
pub(crate) id: ab_glyph::GlyphId,
///
/// Is `None` for a special "invisible" glyph.
pub(crate) id: Option<ab_glyph::GlyphId>,
/// In [`ab_glyph`]s "unscaled" coordinate system.
pub advance_width_unscaled: OrderedFloat<f32>,
/// Whether this glyph has any outlines.
pub visible: bool,
}
impl Default for GlyphInfo {
/// Basically a zero-width space.
fn default() -> Self {
Self {
id: ab_glyph::GlyphId(0),
advance_width_unscaled: 0.0.into(),
visible: false,
}
}
impl GlyphInfo {
/// A valid, but invisible, glyph of zero-width.
pub const INVISIBLE: Self = Self {
id: None,
advance_width_unscaled: OrderedFloat(0.0),
};
}
#[derive(Clone, Copy, Debug, PartialEq, Default)]
@@ -197,7 +192,7 @@ impl FontImpl {
}
if invisible_char(c) {
let glyph_info = GlyphInfo::default();
let glyph_info = GlyphInfo::INVISIBLE;
self.glyph_info_cache.insert(c, glyph_info);
return Some(glyph_info);
}
@@ -209,9 +204,8 @@ impl FontImpl {
None // unsupported character
} else {
let glyph_info = GlyphInfo {
id: glyph_id,
id: Some(glyph_id),
advance_width_unscaled: self.ab_glyph_font.h_advance_unscaled(glyph_id).into(),
visible: true,
};
self.glyph_info_cache.insert(c, glyph_info);
Some(glyph_info)
@@ -259,9 +253,11 @@ impl FontImpl {
font_size: f32,
pixels_per_point: f32,
) -> GlyphAllocation {
if !glyph_info.visible {
let Some(glyph_id) = glyph_info.id else {
// Invisible.
return GlyphAllocation::default();
}
};
// Round to an even number of physical pixels to get even kerning.
// See https://github.com/emilk/egui/issues/382
let scale = self
@@ -275,11 +271,9 @@ impl FontImpl {
std::collections::hash_map::Entry::Vacant(entry) => entry,
};
assert!(glyph_info.id.0 != 0, "Can't allocate glyph for id 0");
debug_assert!(glyph_id.0 != 0, "Can't allocate glyph for id 0");
let glyph = glyph_info
.id
.with_scale_and_position(scale, ab_glyph::Point { x: 0.0, y: 0.0 });
let glyph = glyph_id.with_scale_and_position(scale, ab_glyph::Point { x: 0.0, y: 0.0 });
// Tweak the scale as the user desired
let y_offset_in_points = {
@@ -334,7 +328,7 @@ impl FontImpl {
let uv_rect = uv_rect.unwrap_or_default();
let allocation = GlyphAllocation {
id: glyph_info.id,
id: glyph_id,
advance_width: (glyph_info.advance_width_unscaled.0 * scale
/ self.ab_glyph_font.height_unscaled())
/ pixels_per_point,

View File

@@ -444,7 +444,7 @@ impl CachedFamily {
return Self {
fonts,
characters: None,
replacement_glyph: (FontFaceKey::INVALID, Default::default()),
replacement_glyph: (FontFaceKey::INVALID, GlyphInfo::INVISIBLE),
glyph_info_cache: Default::default(),
};
}
@@ -452,7 +452,7 @@ impl CachedFamily {
let mut slf = Self {
fonts,
characters: None,
replacement_glyph: (FontFaceKey::INVALID, Default::default()),
replacement_glyph: (FontFaceKey::INVALID, GlyphInfo::INVISIBLE),
glyph_info_cache: Default::default(),
};
@@ -467,7 +467,7 @@ impl CachedFamily {
log::warn!(
"Failed to find replacement characters {PRIMARY_REPLACEMENT_CHAR:?} or {FALLBACK_REPLACEMENT_CHAR:?}. Will use empty glyph."
);
(FontFaceKey::INVALID, GlyphInfo::default())
(FontFaceKey::INVALID, GlyphInfo::INVISIBLE)
});
slf.replacement_glyph = replacement_glyph;

View File

@@ -453,12 +453,14 @@ fn replace_last_glyph_with_overflow_character(
// Kerning:
x += section.format.extra_letter_spacing;
if let Some(font_impl) = font_impl {
x += font_impl.pair_kerning(
last_glyph_info.id,
replacement_glyph_alloc.id,
section.format.font_id.size,
pixels_per_point,
);
if let Some(last_glyph_id) = last_glyph_info.id {
x += font_impl.pair_kerning(
last_glyph_id,
replacement_glyph_alloc.id,
section.format.font_id.size,
pixels_per_point,
);
}
}
row.glyphs.push(Glyph {