mirror of
https://github.com/emilk/egui.git
synced 2026-06-26 22:53:14 -04:00
Simplify advance_width
This commit is contained in:
@@ -2,7 +2,7 @@
|
||||
|
||||
use emath::{GuiRounding as _, OrderedFloat, Vec2, vec2};
|
||||
use self_cell::self_cell;
|
||||
use skrifa::MetadataProvider as _;
|
||||
use skrifa::{GlyphId, MetadataProvider as _};
|
||||
use std::collections::BTreeMap;
|
||||
use vello_cpu::{color, kurbo};
|
||||
|
||||
@@ -44,7 +44,7 @@ pub struct GlyphInfo {
|
||||
/// Doesn't need to be unique.
|
||||
///
|
||||
/// Is `None` for a special "invisible" glyph.
|
||||
pub(crate) id: Option<skrifa::GlyphId>,
|
||||
pub(crate) id: Option<GlyphId>,
|
||||
|
||||
/// In [`skrifa`]s "unscaled" coordinate system.
|
||||
pub advance_width_unscaled: OrderedFloat<f32>,
|
||||
@@ -119,11 +119,8 @@ impl SubpixelBin {
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy, Debug, PartialEq, Default)]
|
||||
#[derive(Clone, Copy, Debug, Default, PartialEq, Eq)]
|
||||
pub struct GlyphAllocation {
|
||||
/// Unit: screen pixels.
|
||||
pub advance_width_px: f32,
|
||||
|
||||
/// UV rectangle for drawing.
|
||||
pub uv_rect: UvRect,
|
||||
}
|
||||
@@ -134,7 +131,7 @@ struct GlyphCacheKey(u64);
|
||||
impl nohash_hasher::IsEnabled for GlyphCacheKey {}
|
||||
|
||||
impl GlyphCacheKey {
|
||||
fn new(glyph_id: skrifa::GlyphId, metrics: &StyledMetrics, bin: SubpixelBin) -> Self {
|
||||
fn new(glyph_id: GlyphId, metrics: &StyledMetrics, bin: SubpixelBin) -> Self {
|
||||
let StyledMetrics {
|
||||
pixels_per_point,
|
||||
px_scale_factor,
|
||||
@@ -187,12 +184,10 @@ impl FontCell {
|
||||
&mut self,
|
||||
atlas: &mut TextureAtlas,
|
||||
metrics: &StyledMetrics,
|
||||
glyph_info: &GlyphInfo,
|
||||
glyph_id: GlyphId,
|
||||
bin: SubpixelBin,
|
||||
location: skrifa::instance::LocationRef<'_>,
|
||||
) -> Option<GlyphAllocation> {
|
||||
let glyph_id = glyph_info.id?;
|
||||
|
||||
debug_assert!(
|
||||
glyph_id != skrifa::GlyphId::NOTDEF,
|
||||
"Can't allocate glyph for id 0"
|
||||
@@ -277,10 +272,7 @@ impl FontCell {
|
||||
}
|
||||
};
|
||||
|
||||
Some(GlyphAllocation {
|
||||
advance_width_px: glyph_info.advance_width_unscaled.0 * metrics.px_scale_factor,
|
||||
uv_rect,
|
||||
})
|
||||
Some(GlyphAllocation { uv_rect })
|
||||
}
|
||||
}
|
||||
|
||||
@@ -478,7 +470,7 @@ impl FontFace {
|
||||
let glyph_id = font_data
|
||||
.charmap
|
||||
.map(c)
|
||||
.filter(|id| *id != skrifa::GlyphId::NOTDEF)?;
|
||||
.filter(|id| *id != GlyphId::NOTDEF)?;
|
||||
|
||||
let glyph_info = GlyphInfo {
|
||||
id: Some(glyph_id),
|
||||
@@ -554,12 +546,11 @@ impl FontFace {
|
||||
) -> (GlyphAllocation, i32) {
|
||||
let ShapedGlyph {
|
||||
glyph_id,
|
||||
advance_width_px,
|
||||
h_pos,
|
||||
is_cjk,
|
||||
} = *shaped;
|
||||
|
||||
if glyph_id == skrifa::GlyphId::NOTDEF {
|
||||
if glyph_id == GlyphId::NOTDEF {
|
||||
return (GlyphAllocation::default(), h_pos.round() as i32);
|
||||
}
|
||||
|
||||
@@ -570,41 +561,28 @@ impl FontFace {
|
||||
};
|
||||
|
||||
let cache_key = GlyphCacheKey::new(glyph_id, metrics, bin);
|
||||
if let Some(cached) = self.glyph_alloc_cache.get(&cache_key) {
|
||||
let mut alloc = *cached;
|
||||
alloc.advance_width_px = advance_width_px;
|
||||
(alloc, h_pos_round)
|
||||
} else {
|
||||
let glyph_info = GlyphInfo {
|
||||
id: Some(glyph_id),
|
||||
advance_width_unscaled: OrderedFloat(advance_width_px / metrics.px_scale_factor),
|
||||
};
|
||||
|
||||
let alloc = if let Some(cached) = self.glyph_alloc_cache.get(&cache_key) {
|
||||
*cached
|
||||
} else {
|
||||
let alloc = self
|
||||
.font
|
||||
.allocate_glyph_uncached(
|
||||
atlas,
|
||||
metrics,
|
||||
&glyph_info,
|
||||
bin,
|
||||
(&metrics.location).into(),
|
||||
)
|
||||
.allocate_glyph_uncached(atlas, metrics, glyph_id, bin, (&metrics.location).into())
|
||||
.unwrap_or_default();
|
||||
|
||||
self.glyph_alloc_cache.insert(cache_key, alloc);
|
||||
|
||||
(alloc, h_pos_round)
|
||||
}
|
||||
alloc
|
||||
};
|
||||
|
||||
(alloc, h_pos_round)
|
||||
}
|
||||
}
|
||||
|
||||
/// Positioning info for a single glyph, ready for atlas allocation.
|
||||
#[derive(Clone, Copy, Debug)]
|
||||
pub(crate) struct ShapedGlyph {
|
||||
pub glyph_id: skrifa::GlyphId,
|
||||
|
||||
/// How far the cursor advances after this glyph, in physical pixels.
|
||||
pub advance_width_px: f32,
|
||||
pub glyph_id: GlyphId,
|
||||
|
||||
/// Horizontal position of the glyph origin, in physical pixels.
|
||||
pub h_pos: f32,
|
||||
|
||||
@@ -259,6 +259,8 @@ fn layout_shaped_run(
|
||||
ff.styled_metrics(ctx.pixels_per_point, ctx.font_size, &Default::default())
|
||||
})
|
||||
.unwrap_or_default();
|
||||
let advance_width_px =
|
||||
glyph_info.advance_width_unscaled.0 * fallback_metrics.px_scale_factor;
|
||||
let (glyph_alloc, physical_x) =
|
||||
if let Some(ff) = font.fonts_by_id.get_mut(&fallback_key) {
|
||||
ff.allocate_glyph(
|
||||
@@ -266,8 +268,6 @@ fn layout_shaped_run(
|
||||
&fallback_metrics,
|
||||
&ShapedGlyph {
|
||||
glyph_id: glyph_info.id.unwrap_or(skrifa::GlyphId::NOTDEF),
|
||||
advance_width_px: glyph_info.advance_width_unscaled.0
|
||||
* fallback_metrics.px_scale_factor,
|
||||
h_pos: paragraph.cursor_x_px,
|
||||
is_cjk: is_cjk(chr),
|
||||
},
|
||||
@@ -279,7 +279,7 @@ fn layout_shaped_run(
|
||||
paragraph.glyphs.push(Glyph {
|
||||
chr,
|
||||
pos: pos2(physical_x as f32 / ctx.pixels_per_point, f32::NAN),
|
||||
advance_width: glyph_alloc.advance_width_px / ctx.pixels_per_point,
|
||||
advance_width: advance_width_px / ctx.pixels_per_point,
|
||||
line_height: ctx.line_height,
|
||||
font_face_height: fallback_metrics.row_height,
|
||||
font_face_ascent: fallback_metrics.ascent,
|
||||
@@ -289,7 +289,7 @@ fn layout_shaped_run(
|
||||
section_index: ctx.section_index,
|
||||
first_vertex: 0,
|
||||
});
|
||||
paragraph.cursor_x_px += glyph_alloc.advance_width_px;
|
||||
paragraph.cursor_x_px += advance_width_px;
|
||||
} else {
|
||||
let (mut glyph_alloc, physical_x) =
|
||||
if let Some(ff) = font.fonts_by_id.get_mut(&run.font_key) {
|
||||
@@ -298,7 +298,6 @@ fn layout_shaped_run(
|
||||
face_metrics,
|
||||
&ShapedGlyph {
|
||||
glyph_id,
|
||||
advance_width_px,
|
||||
h_pos: paragraph.cursor_x_px + x_offset_px,
|
||||
is_cjk: is_cjk(chr),
|
||||
},
|
||||
@@ -695,9 +694,9 @@ fn replace_last_glyph_with_overflow_character(
|
||||
0.0 // TODO(emilk): heed paragraph leading_space 😬
|
||||
};
|
||||
|
||||
let replacement_glyph_width = glyph_info.advance_width_unscaled.0
|
||||
* font_face_metrics.px_scale_factor
|
||||
/ pixels_per_point;
|
||||
let advance_width_px =
|
||||
glyph_info.advance_width_unscaled.0 * font_face_metrics.px_scale_factor;
|
||||
let replacement_glyph_width = advance_width_px / pixels_per_point;
|
||||
|
||||
// Check if we're within width budget:
|
||||
if overflow_glyph_x + replacement_glyph_width <= job.effective_wrap_width()
|
||||
@@ -713,8 +712,6 @@ fn replace_last_glyph_with_overflow_character(
|
||||
&font_face_metrics,
|
||||
&ShapedGlyph {
|
||||
glyph_id: glyph_info.id.unwrap_or(skrifa::GlyphId::NOTDEF),
|
||||
advance_width_px: glyph_info.advance_width_unscaled.0
|
||||
* font_face_metrics.px_scale_factor,
|
||||
h_pos: overflow_glyph_x * pixels_per_point,
|
||||
is_cjk: is_cjk(overflow_character),
|
||||
},
|
||||
@@ -732,7 +729,7 @@ fn replace_last_glyph_with_overflow_character(
|
||||
row.glyphs.push(Glyph {
|
||||
chr: overflow_character,
|
||||
pos: pos2(physical_x as f32 / pixels_per_point, f32::NAN),
|
||||
advance_width: replacement_glyph_alloc.advance_width_px / pixels_per_point,
|
||||
advance_width: advance_width_px / pixels_per_point,
|
||||
line_height,
|
||||
font_face_height: font_face_metrics.row_height,
|
||||
font_face_ascent: font_face_metrics.ascent,
|
||||
|
||||
Reference in New Issue
Block a user