Make size and alignment of emoji-icon-font match the rest of the fonts

This is done via a hack (for now).
This commit is contained in:
Emil Ernerfeldt 2021-01-10 10:20:50 +01:00
parent a30eef11bc
commit 987c7ddf98
5 changed files with 40 additions and 12 deletions

View file

@ -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`. * Add `ui.allocate_at_least` and `ui.allocate_exact_size`.
### Changed 🔧
* Tweak size and alignment of some emojis to match other text.
### Fixed 🐛 ### Fixed 🐛
* Fixed a bug that would sometimes trigger a "Mismatching panels" panic in debug builds. * Fixed a bug that would sometimes trigger a "Mismatching panels" panic in debug builds.

View file

@ -34,6 +34,9 @@ impl From<&[f32; 2]> for Vec2 {
} }
impl 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 { pub fn zero() -> Self {
Self { x: 0.0, y: 0.0 } Self { x: 0.0, y: 0.0 }
} }

View file

@ -57,6 +57,9 @@ pub struct FontImpl {
rusttype_font: Arc<rusttype::Font<'static>>, rusttype_font: Arc<rusttype::Font<'static>>,
/// Maximum character height /// Maximum character height
scale_in_pixels: f32, scale_in_pixels: f32,
height_in_points: f32,
// move each character by this much (hack)
y_offset: f32,
pixels_per_point: f32, pixels_per_point: f32,
glyph_info_cache: RwLock<AHashMap<char, GlyphInfo>>, // TODO: standard Mutex glyph_info_cache: RwLock<AHashMap<char, GlyphInfo>>, // TODO: standard Mutex
atlas: Arc<Mutex<TextureAtlas>>, atlas: Arc<Mutex<TextureAtlas>>,
@ -68,15 +71,24 @@ impl FontImpl {
pixels_per_point: f32, pixels_per_point: f32,
rusttype_font: Arc<rusttype::Font<'static>>, rusttype_font: Arc<rusttype::Font<'static>>,
scale_in_points: f32, scale_in_points: f32,
y_offset: f32,
) -> FontImpl { ) -> FontImpl {
assert!(scale_in_points > 0.0); assert!(scale_in_points > 0.0);
assert!(pixels_per_point > 0.0); assert!(pixels_per_point > 0.0);
let scale_in_pixels = pixels_per_point * scale_in_points; 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 { Self {
rusttype_font, rusttype_font,
scale_in_pixels, scale_in_pixels,
height_in_points,
y_offset,
pixels_per_point, pixels_per_point,
glyph_info_cache: Default::default(), glyph_info_cache: Default::default(),
atlas, atlas,
@ -100,6 +112,7 @@ impl FontImpl {
&mut self.atlas.lock(), &mut self.atlas.lock(),
glyph, glyph,
self.scale_in_pixels, self.scale_in_pixels,
self.y_offset,
self.pixels_per_point, self.pixels_per_point,
); );
self.glyph_info_cache.write().insert(c, glyph_info); self.glyph_info_cache.write().insert(c, glyph_info);
@ -120,7 +133,7 @@ impl FontImpl {
/// Height of one row of text. In points /// Height of one row of text. In points
pub fn row_height(&self) -> f32 { 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 { pub fn pixels_per_point(&self) -> f32 {
@ -452,6 +465,7 @@ fn allocate_glyph(
atlas: &mut TextureAtlas, atlas: &mut TextureAtlas,
glyph: rusttype::Glyph<'static>, glyph: rusttype::Glyph<'static>,
scale_in_pixels: f32, scale_in_pixels: f32,
y_offset: f32,
pixels_per_point: f32, pixels_per_point: f32,
) -> GlyphInfo { ) -> GlyphInfo {
assert!(glyph.id().0 != 0); assert!(glyph.id().0 != 0);
@ -477,13 +491,10 @@ fn allocate_glyph(
} }
}); });
let offset_y_in_pixels = let offset_in_pixels = vec2(bb.min.x as f32, scale_in_pixels as f32 + bb.min.y as f32);
scale_in_pixels as f32 + bb.min.y as f32 - 4.0 * pixels_per_point; // TODO: use font.v_metrics let offset = offset_in_pixels / pixels_per_point + y_offset * Vec2::Y;
Some(UvRect { Some(UvRect {
offset: vec2( offset,
bb.min.x as f32 / pixels_per_point,
offset_y_in_pixels / pixels_per_point,
),
size: vec2(glyph_width as f32, glyph_height as f32) / pixels_per_point, size: vec2(glyph_width as f32, glyph_height as f32) / pixels_per_point,
min: (glyph_pos.0 as u16, glyph_pos.1 as u16), min: (glyph_pos.0 as u16, glyph_pos.1 as u16),
max: ( max: (

View file

@ -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( let font_impl = Arc::new(FontImpl::new(
self.atlas.clone(), self.atlas.clone(),
self.pixels_per_point, self.pixels_per_point,
self.rusttype_font(font_name), self.rusttype_font(font_name),
scale_in_points, scale_in_points,
y_offset,
)); ));
self.cache self.cache
.push((font_name.to_owned(), scale_in_points, font_impl.clone())); .push((font_name.to_owned(), scale_in_points, font_impl.clone()));

View file

@ -845,14 +845,12 @@ impl Tessellator {
let tex_w = fonts.texture().width as f32; let tex_w = fonts.texture().width as f32;
let tex_h = fonts.texture().height 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 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 font = &fonts[text_style];
let mut chars = galley.text.chars(); let mut chars = galley.text.chars();
for line in &galley.rows { 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 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; 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) { if let Some(glyph) = font.uv_rect(c) {
let mut left_top = let mut left_top = pos + glyph.offset + vec2(*x_offset, line.y_min);
pos + glyph.offset + vec2(*x_offset, line.y_min) + text_offset;
left_top.x = font.round_to_pixel(left_top.x); // Pixel-perfection. left_top.x = font.round_to_pixel(left_top.x); // Pixel-perfection.
left_top.y = font.round_to_pixel(left_top.y); // Pixel-perfection. left_top.y = font.round_to_pixel(left_top.y); // Pixel-perfection.