From c340d2f139c8da76d6efe0bcd5fb850542b262a0 Mon Sep 17 00:00:00 2001 From: Emil Ernerfeldt Date: Sat, 28 Mar 2026 16:17:25 +0100 Subject: [PATCH] Deduplicate code --- crates/epaint/src/text/font.rs | 47 +-------------------------- crates/epaint/src/text/text_layout.rs | 36 ++++++++++---------- 2 files changed, 20 insertions(+), 63 deletions(-) diff --git a/crates/epaint/src/text/font.rs b/crates/epaint/src/text/font.rs index a0e3c965d..04cfa4165 100644 --- a/crates/epaint/src/text/font.rs +++ b/crates/epaint/src/text/font.rs @@ -579,8 +579,7 @@ impl FontFace { shaper.shape(buffer, &[]) } - /// Allocate a glyph by its ID directly, using metrics from the shaper. - pub fn allocate_glyph_by_id( + pub fn allocate_glyph( &mut self, atlas: &mut TextureAtlas, metrics: &StyledMetrics, @@ -623,50 +622,6 @@ impl FontFace { (allocation, h_pos_round) } - - pub fn allocate_glyph( - &mut self, - atlas: &mut TextureAtlas, - metrics: &StyledMetrics, - glyph_info: GlyphInfo, - chr: char, - h_pos: f32, - ) -> (GlyphAllocation, i32) { - let advance_width_px = glyph_info.advance_width_unscaled.0 * metrics.px_scale_factor; - - let Some(glyph_id) = glyph_info.id else { - // Invisible. - return (GlyphAllocation::default(), h_pos as i32); - }; - - // CJK scripts contain a lot of characters and could hog the glyph atlas if we stored 4 subpixel offsets per - // glyph. - let (h_pos_round, bin) = if is_cjk(chr) { - (h_pos.round() as i32, SubpixelBin::Zero) - } else { - SubpixelBin::new(h_pos) - }; - - let entry = match self - .glyph_alloc_cache - .entry(GlyphCacheKey::new(glyph_id, metrics, bin)) - { - std::collections::hash_map::Entry::Occupied(glyph_alloc) => { - let mut glyph_alloc = *glyph_alloc.get(); - glyph_alloc.advance_width_px = advance_width_px; // Hack to get `\t` and thin space to work, since they use the same glyph id as ` ` (space). - return (glyph_alloc, h_pos_round); - } - std::collections::hash_map::Entry::Vacant(entry) => entry, - }; - - let allocation = self - .font - .allocate_glyph_uncached(atlas, metrics, &glyph_info, bin, (&metrics.location).into()) - .unwrap_or_default(); - - entry.insert(allocation); - (allocation, h_pos_round) - } } /// A contiguous run of text that maps to a single font face. diff --git a/crates/epaint/src/text/text_layout.rs b/crates/epaint/src/text/text_layout.rs index 9077f33fc..aba003e3d 100644 --- a/crates/epaint/src/text/text_layout.rs +++ b/crates/epaint/src/text/text_layout.rs @@ -239,15 +239,17 @@ fn layout_shaped_run( ff.styled_metrics(ctx.pixels_per_point, ctx.font_size, &Default::default()) }) .unwrap_or_default(); + let shaped = super::font::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, + y_offset_points: 0.0, + is_cjk: is_cjk(chr), + }; let (glyph_alloc, physical_x) = if let Some(ff) = font.fonts_by_id.get_mut(&fallback_key) { - ff.allocate_glyph( - font.atlas, - &fallback_metrics, - glyph_info, - chr, - paragraph.cursor_x_px, - ) + ff.allocate_glyph(font.atlas, &fallback_metrics, &shaped) } else { Default::default() }; @@ -277,7 +279,7 @@ fn layout_shaped_run( let (glyph_alloc, physical_x) = if let Some(ff) = font.fonts_by_id.get_mut(&run.font_key) { - ff.allocate_glyph_by_id(font.atlas, face_metrics, &shaped) + ff.allocate_glyph(font.atlas, face_metrics, &shaped) } else { Default::default() }; @@ -679,17 +681,17 @@ fn replace_last_glyph_with_overflow_character( { // we are done + let shaped = super::font::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, + y_offset_points: 0.0, + is_cjk: is_cjk(overflow_character), + }; let (replacement_glyph_alloc, physical_x) = font_face .as_mut() - .map(|f| { - f.allocate_glyph( - font.atlas, - &font_face_metrics, - glyph_info, - overflow_character, - overflow_glyph_x * pixels_per_point, - ) - }) + .map(|f| f.allocate_glyph(font.atlas, &font_face_metrics, &shaped)) .unwrap_or_default(); let font_metrics =