diff --git a/CHANGELOG.md b/CHANGELOG.md index 7acd002b..2b4f4102 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -13,6 +13,10 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). * Add `ui.allocate_at_least` and `ui.allocate_exact_size`. +### Changed 🔧 + +* Tweak size and alignment of some emojis to match other text. + ### Fixed 🐛 * Fixed a bug that would sometimes trigger a "Mismatching panels" panic in debug builds. diff --git a/egui/src/math/vec2.rs b/egui/src/math/vec2.rs index e5b8877e..5596cbbc 100644 --- a/egui/src/math/vec2.rs +++ b/egui/src/math/vec2.rs @@ -34,6 +34,9 @@ impl From<&[f32; 2]> for Vec2 { } impl Vec2 { + pub const X: Vec2 = Vec2 { x: 1.0, y: 0.0 }; + pub const Y: Vec2 = Vec2 { x: 0.0, y: 1.0 }; + pub fn zero() -> Self { Self { x: 0.0, y: 0.0 } } diff --git a/egui/src/paint/font.rs b/egui/src/paint/font.rs index cbb15680..bc206b87 100644 --- a/egui/src/paint/font.rs +++ b/egui/src/paint/font.rs @@ -57,6 +57,9 @@ pub struct FontImpl { rusttype_font: Arc>, /// Maximum character height scale_in_pixels: f32, + height_in_points: f32, + // move each character by this much (hack) + y_offset: f32, pixels_per_point: f32, glyph_info_cache: RwLock>, // TODO: standard Mutex atlas: Arc>, @@ -68,15 +71,24 @@ impl FontImpl { pixels_per_point: f32, rusttype_font: Arc>, scale_in_points: f32, + y_offset: f32, ) -> FontImpl { assert!(scale_in_points > 0.0); assert!(pixels_per_point > 0.0); let scale_in_pixels = pixels_per_point * scale_in_points; + let height_in_points = scale_in_points; + // TODO: use v_metrics for line spacing ? + // let v = rusttype_font.v_metrics(Scale::uniform(scale_in_pixels)); + // let height_in_pixels = v.ascent - v.descent + v.line_gap; + // let height_in_points = height_in_pixels / pixels_per_point; + Self { rusttype_font, scale_in_pixels, + height_in_points, + y_offset, pixels_per_point, glyph_info_cache: Default::default(), atlas, @@ -100,6 +112,7 @@ impl FontImpl { &mut self.atlas.lock(), glyph, self.scale_in_pixels, + self.y_offset, self.pixels_per_point, ); self.glyph_info_cache.write().insert(c, glyph_info); @@ -120,7 +133,7 @@ impl FontImpl { /// Height of one row of text. In points pub fn row_height(&self) -> f32 { - self.scale_in_pixels / self.pixels_per_point + self.height_in_points } pub fn pixels_per_point(&self) -> f32 { @@ -452,6 +465,7 @@ fn allocate_glyph( atlas: &mut TextureAtlas, glyph: rusttype::Glyph<'static>, scale_in_pixels: f32, + y_offset: f32, pixels_per_point: f32, ) -> GlyphInfo { assert!(glyph.id().0 != 0); @@ -477,13 +491,10 @@ fn allocate_glyph( } }); - let offset_y_in_pixels = - scale_in_pixels as f32 + bb.min.y as f32 - 4.0 * pixels_per_point; // TODO: use font.v_metrics + let offset_in_pixels = vec2(bb.min.x as f32, scale_in_pixels as f32 + bb.min.y as f32); + let offset = offset_in_pixels / pixels_per_point + y_offset * Vec2::Y; Some(UvRect { - offset: vec2( - bb.min.x as f32 / pixels_per_point, - offset_y_in_pixels / pixels_per_point, - ), + offset, size: vec2(glyph_width as f32, glyph_height as f32) / pixels_per_point, min: (glyph_pos.0 as u16, glyph_pos.1 as u16), max: ( diff --git a/egui/src/paint/fonts.rs b/egui/src/paint/fonts.rs index 881f77ae..67fcc2f4 100644 --- a/egui/src/paint/fonts.rs +++ b/egui/src/paint/fonts.rs @@ -322,11 +322,24 @@ impl FontImplCache { } } + let y_offset = if font_name == "emoji-icon-font" { + 1.0 // TODO: remove font alignment hack + } else { + -3.0 // TODO: remove font alignment hack + }; + + let scale_in_points = if font_name == "emoji-icon-font" { + scale_in_points - 2.0 // TODO: remove HACK! + } else { + scale_in_points + }; + let font_impl = Arc::new(FontImpl::new( self.atlas.clone(), self.pixels_per_point, self.rusttype_font(font_name), scale_in_points, + y_offset, )); self.cache .push((font_name.to_owned(), scale_in_points, font_impl.clone())); diff --git a/egui/src/paint/tessellator.rs b/egui/src/paint/tessellator.rs index 5af17374..bfb19a72 100644 --- a/egui/src/paint/tessellator.rs +++ b/egui/src/paint/tessellator.rs @@ -845,14 +845,12 @@ impl Tessellator { let tex_w = fonts.texture().width as f32; let tex_h = fonts.texture().height as f32; - let text_offset = vec2(0.0, 1.0); // Eye-balled for buttons. TODO: why is this needed? - let clip_rect = self.clip_rect.expand(2.0); // Some fudge to handle letters that are slightly larger than expected. let font = &fonts[text_style]; let mut chars = galley.text.chars(); for line in &galley.rows { - let line_min_y = pos.y + line.y_min + text_offset.x; + let line_min_y = pos.y + line.y_min; let line_max_y = line_min_y + font.row_height(); let is_line_visible = line_max_y >= clip_rect.min.y && line_min_y <= clip_rect.max.y; @@ -866,8 +864,7 @@ impl Tessellator { } if let Some(glyph) = font.uv_rect(c) { - let mut left_top = - pos + glyph.offset + vec2(*x_offset, line.y_min) + text_offset; + let mut left_top = pos + glyph.offset + vec2(*x_offset, line.y_min); left_top.x = font.round_to_pixel(left_top.x); // Pixel-perfection. left_top.y = font.round_to_pixel(left_top.y); // Pixel-perfection.