From dddff91fad0bbe5a438185f8a908da192c274aba Mon Sep 17 00:00:00 2001 From: Kovid Goyal Date: Sun, 6 Feb 2022 13:20:55 +0530 Subject: [PATCH] Linux: Fix rendering of emoji when using scalable fonts such as Segoe UI Emoji --- docs/changelog.rst | 2 ++ kitty/freetype.c | 25 +++++++++++++------------ kitty/freetype_render_ui_text.c | 4 ++-- 3 files changed, 17 insertions(+), 14 deletions(-) diff --git a/docs/changelog.rst b/docs/changelog.rst index 8dffc93ea..083de6361 100644 --- a/docs/changelog.rst +++ b/docs/changelog.rst @@ -103,6 +103,8 @@ Detailed list of changes for the :doc:`launch ` command to be used for pager positioning. (:iss:`4462`) +- Linux: Fix rendering of emoji when using scalable fonts such as Segoe UI Emoji + 0.24.2 [2022-02-03] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ diff --git a/kitty/freetype.c b/kitty/freetype.c index 0f4d12a86..5e187c06f 100644 --- a/kitty/freetype.c +++ b/kitty/freetype.c @@ -522,19 +522,20 @@ detect_right_edge(ProcessedBitmap *ans) { static bool render_color_bitmap(Face *self, int glyph_id, ProcessedBitmap *ans, unsigned int cell_width, unsigned int cell_height, unsigned int num_cells, unsigned int baseline UNUSED) { unsigned short best = 0, diff = USHRT_MAX; - const short limit = self->face->num_fixed_sizes; - for (short i = 0; i < limit; i++) { - unsigned short w = self->face->available_sizes[i].width; - unsigned short d = w > (unsigned short)cell_width ? w - (unsigned short)cell_width : (unsigned short)cell_width - w; - if (d < diff) { - diff = d; - best = i; + if (self->face->num_fixed_sizes > 0) { + const short limit = self->face->num_fixed_sizes; + for (short i = 0; i < limit; i++) { + unsigned short w = self->face->available_sizes[i].width; + unsigned short d = w > (unsigned short)cell_width ? w - (unsigned short)cell_width : (unsigned short)cell_width - w; + if (d < diff) { + diff = d; + best = i; + } } - } - FT_Error error = FT_Select_Size(self->face, best); - if (error) { set_freetype_error("Failed to set char size for non-scalable font, with error:", error); return false; } - if (!load_glyph(self, glyph_id, FT_LOAD_COLOR)) return false; - FT_Set_Char_Size(self->face, 0, self->char_height, self->xdpi, self->ydpi); + FT_Error error = FT_Select_Size(self->face, best); + if (error) { set_freetype_error("Failed to set char size for non-scalable font, with error:", error); return false; } + } else FT_Set_Char_Size(self->face, 0, self->char_height, self->xdpi, self->ydpi); + if (!load_glyph(self, glyph_id, FT_LOAD_COLOR | FT_LOAD_RENDER)) return false; FT_Bitmap *bitmap = &self->face->glyph->bitmap; if (bitmap->pixel_mode != FT_PIXEL_MODE_BGRA) return false; ans->buf = bitmap->buffer; diff --git a/kitty/freetype_render_ui_text.c b/kitty/freetype_render_ui_text.c index c5e3abfa2..7e514b9dc 100644 --- a/kitty/freetype_render_ui_text.c +++ b/kitty/freetype_render_ui_text.c @@ -134,7 +134,7 @@ choose_bitmap_size(FT_Face face, FT_UInt desired_height) { static void set_pixel_size(RenderCtx *ctx, Face *face, FT_UInt sz, bool get_metrics UNUSED) { if (sz != face->pixel_size) { - if (FT_HAS_COLOR(face->freetype)) sz = choose_bitmap_size(face->freetype, font_units_to_pixels_y(main_face.freetype, main_face.freetype->height)); + if (face->freetype->num_fixed_sizes > 0 && FT_HAS_COLOR(face->freetype)) choose_bitmap_size(face->freetype, font_units_to_pixels_y(main_face.freetype, main_face.freetype->height)); else FT_Set_Pixel_Sizes(face->freetype, sz, sz); hb_ft_font_changed(face->hb); hb_ft_font_set_load_flags(face->hb, get_load_flags(face->hinting, face->hintstyle, FT_LOAD_DEFAULT)); @@ -304,7 +304,7 @@ render_run(RenderCtx *ctx, RenderState *rs) { hb_glyph_info_t *info = hb_buffer_get_glyph_infos(hb_buffer, NULL); hb_glyph_position_t *positions = hb_buffer_get_glyph_positions(hb_buffer, NULL); int baseline = font_units_to_pixels_y(face, face->ascender); - int load_flags = get_load_flags(rs->current_face->hinting, rs->current_face->hintstyle, has_color ? FT_LOAD_COLOR : FT_LOAD_RENDER); + int load_flags = get_load_flags(rs->current_face->hinting, rs->current_face->hintstyle, FT_LOAD_RENDER | (has_color ? FT_LOAD_COLOR : 0)); float pos = rs->x; unsigned int limit = len; for (unsigned int i = 0; i < len; i++) {