From 3a7e53e2e476d0a5cb11f4ecd7d6dbcb3cf7d569 Mon Sep 17 00:00:00 2001 From: Mitchell Hashimoto Date: Thu, 6 Oct 2022 14:12:03 -0700 Subject: [PATCH] font: calculate correct offset for non-scalable emoji fonts --- src/font/Face.zig | 24 +++++++++++++++++++----- 1 file changed, 19 insertions(+), 5 deletions(-) diff --git a/src/font/Face.zig b/src/font/Face.zig index 244c3bc51..6f21d5920 100644 --- a/src/font/Face.zig +++ b/src/font/Face.zig @@ -209,11 +209,25 @@ pub fn renderGlyph(self: Face, alloc: Allocator, atlas: *Atlas, glyph_index: u32 atlas.set(region, buffer); } - // The Y offset is the offset of the top of our bitmap PLUS our - // baseline calculation. The baseline calculation is so that everything - // is properly centered when we render it out into a monospace grid. - // Note: we add here because our X/Y is actually reversed, adding goes UP. - const offset_y = glyph.*.bitmap_top + @floatToInt(c_int, self.metrics.cell_baseline); + const offset_y = offset_y: { + // For non-scalable colorized fonts, we assume they are pictographic + // and just center the glyph. So far this has only applied to emoji + // fonts. Emoji fonts don't always report a correct ascender/descender + // (mainly Apple Emoji) so we just center them. Also, since emoji font + // aren't scalable, cell_baseline is incorrect anyways. + // + // NOTE(mitchellh): I don't know if this is right, this doesn't + // _feel_ right, but it makes all my limited test cases work. + if (self.face.hasColor() and !self.face.isScalable()) { + break :offset_y @intCast(c_int, tgt_h); + } + + // The Y offset is the offset of the top of our bitmap PLUS our + // baseline calculation. The baseline calculation is so that everything + // is properly centered when we render it out into a monospace grid. + // Note: we add here because our X/Y is actually reversed, adding goes UP. + break :offset_y glyph.*.bitmap_top + @floatToInt(c_int, self.metrics.cell_baseline); + }; // Store glyph metadata return Glyph{