From 6a4a03ce9db68f3a4490ddf204b5eb607d7ebbf0 Mon Sep 17 00:00:00 2001 From: Emil Ernerfeldt Date: Fri, 11 Dec 2020 23:39:32 +0100 Subject: [PATCH] Make struct Font a wrapper around FontImpl --- egui/src/paint/font.rs | 97 +++++++++++++++++++++++++++++------------ egui/src/paint/fonts.rs | 10 ++++- 2 files changed, 78 insertions(+), 29 deletions(-) diff --git a/egui/src/paint/font.rs b/egui/src/paint/font.rs index 9c7bf5d0..dc0ec9b9 100644 --- a/egui/src/paint/font.rs +++ b/egui/src/paint/font.rs @@ -45,7 +45,7 @@ pub struct GlyphInfo { } /// The interface uses points as the unit for everything. -pub struct Font { +pub struct FontImpl { font: rusttype::Font<'static>, /// Maximum character height scale_in_pixels: f32, @@ -55,13 +55,13 @@ pub struct Font { atlas: Arc>, } -impl Font { +impl FontImpl { pub fn new( atlas: Arc>, font_data: &'static [u8], scale_in_points: f32, pixels_per_point: f32, - ) -> Font { + ) -> FontImpl { assert!(scale_in_points > 0.0); assert!(pixels_per_point > 0.0); @@ -82,7 +82,7 @@ impl Font { ) }); - let font = Font { + let font = Self { font, scale_in_pixels, pixels_per_point, @@ -106,23 +106,6 @@ impl Font { font } - pub fn round_to_pixel(&self, point: f32) -> f32 { - (point * self.pixels_per_point).round() / self.pixels_per_point - } - - /// Height of one row of text. In points - pub fn row_height(&self) -> f32 { - self.scale_in_pixels / self.pixels_per_point - } - - pub fn uv_rect(&self, c: char) -> Option { - self.glyph_infos.read().get(&c).and_then(|gi| gi.uv_rect) - } - - pub fn glyph_width(&self, c: char) -> f32 { - self.glyph_info(c).advance_width - } - /// `\n` will (intentionally) show up as '?' (`REPLACEMENT_CHAR`) fn glyph_info(&self, c: char) -> GlyphInfo { { @@ -145,6 +128,71 @@ impl Font { glyph_info } + pub fn pair_kerning( + &self, + last_glyph_id: rusttype::GlyphId, + glyph_id: rusttype::GlyphId, + ) -> f32 { + let scale_in_pixels = Scale::uniform(self.scale_in_pixels); + self.font + .pair_kerning(scale_in_pixels, last_glyph_id, glyph_id) + / self.pixels_per_point + } + + pub fn round_to_pixel(&self, point: f32) -> f32 { + (point * self.pixels_per_point).round() / self.pixels_per_point + } + + /// Height of one row of text. In points + pub fn row_height(&self) -> f32 { + self.scale_in_pixels / self.pixels_per_point + } + + pub fn uv_rect(&self, c: char) -> Option { + self.glyph_infos.read().get(&c).and_then(|gi| gi.uv_rect) + } + + pub fn glyph_width(&self, c: char) -> f32 { + self.glyph_info(c).advance_width + } + + pub fn pixels_per_point(&self) -> f32 { + self.pixels_per_point + } +} + +// TODO: rename Layouter ? +/// Wrapper over multiple `FontImpl` (commonly two: primary + emoji fallback) +pub struct Font { + font_impl: Arc, +} + +impl Font { + pub fn new(font_impl: Arc) -> Self { + Self { font_impl } + } + + pub fn round_to_pixel(&self, point: f32) -> f32 { + self.font_impl.round_to_pixel(point) + } + + /// Height of one row of text. In points + pub fn row_height(&self) -> f32 { + self.font_impl.row_height() + } + + pub fn uv_rect(&self, c: char) -> Option { + self.font_impl.uv_rect(c) + } + + pub fn glyph_width(&self, c: char) -> f32 { + self.font_impl.glyph_width(c) + } + + fn glyph_info(&self, c: char) -> GlyphInfo { + self.font_impl.glyph_info(c) + } + /// Typeset the given text onto one row. /// Any `\n` will show up as `REPLACEMENT_CHAR` ('?'). /// Always returns exactly one `Row` in the `Galley`. @@ -244,8 +292,6 @@ impl Font { /// Assumes there are no `\n` in the text. /// Return `x_offsets`, one longer than the number of characters in the text. fn layout_single_row_fragment(&self, text: &str) -> Vec { - let scale_in_pixels = Scale::uniform(self.scale_in_pixels); - let mut x_offsets = Vec::with_capacity(text.chars().count() + 1); x_offsets.push(0.0); @@ -256,10 +302,7 @@ impl Font { let glyph = self.glyph_info(c); if let Some(last_glyph_id) = last_glyph_id { - cursor_x_in_points += - self.font - .pair_kerning(scale_in_pixels, last_glyph_id, glyph.id) - / self.pixels_per_point + cursor_x_in_points += self.font_impl.pair_kerning(last_glyph_id, glyph.id) } cursor_x_in_points += glyph.advance_width; cursor_x_in_points = self.round_to_pixel(cursor_x_in_points); diff --git a/egui/src/paint/fonts.rs b/egui/src/paint/fonts.rs index c148059b..dbe725d3 100644 --- a/egui/src/paint/fonts.rs +++ b/egui/src/paint/fonts.rs @@ -124,9 +124,15 @@ impl Fonts { let typeface_data = ttf_data .get(&family) .unwrap_or_else(|| panic!("Missing TTF data for {:?}", family)); - let font = Font::new(atlas.clone(), typeface_data, size, pixels_per_point); + let font_impl = super::font::FontImpl::new( + atlas.clone(), + typeface_data, + size, + pixels_per_point, + ); + let font_impl = Arc::new(font_impl); - (text_style, font) + (text_style, Font::new(font_impl)) }) .collect();