From 12cfe6d1d1546444c1d99025d9a36872f665b510 Mon Sep 17 00:00:00 2001 From: Daniel Hahler Date: Sat, 29 Sep 2018 18:38:53 +0200 Subject: [PATCH] render_line: use cells based on bitmap width [ci skip] --- kitty/fonts.c | 13 +++++++++++++ kitty/fonts.h | 1 + kitty/freetype.c | 14 ++++++++++++++ 3 files changed, 28 insertions(+) diff --git a/kitty/fonts.c b/kitty/fonts.c index 2e964e178..8cf99685c 100644 --- a/kitty/fonts.c +++ b/kitty/fonts.c @@ -1008,12 +1008,25 @@ render_line(FONTS_DATA_HANDLE fg_, Line *line) { CPUCell *cpu_cell = line->cpu_cells + i; GPUCell *gpu_cell = line->gpu_cells + i; ssize_t cell_font_idx = font_for_cell(fg, cpu_cell, gpu_cell); + if (is_private_use(cpu_cell->ch) && cell_font_idx != BOX_FONT && cell_font_idx != MISSING_FONT) { + int cells; + if (cell_font_idx > 0) { + Font *font = (fg->fonts + cell_font_idx); + glyph_index glyph_id = glyph_id_for_codepoint(font->face, cpu_cell->ch); + + int width = get_glyph_width(font->face, glyph_id); + cells = ceilf((float)width / fg->cell_width); + } else { + cells = 1; + } + int j = 0; while ((line->cpu_cells[i+j+1].ch == ' ' || line->cpu_cells[i+j+1].ch == 0) && j < MAX_NUM_EXTRA_GLYPHS_PUA + && j < cells && i + j + 1 < line->xnum) { j++; // We have a private use char followed by space(s), render it as a multi-cell ligature. diff --git a/kitty/fonts.h b/kitty/fonts.h index 1a05f1b0c..1ddc6c5ff 100644 --- a/kitty/fonts.h +++ b/kitty/fonts.h @@ -17,6 +17,7 @@ // API that font backends need to implement typedef uint16_t glyph_index; unsigned int glyph_id_for_codepoint(PyObject *, char_type); +int get_glyph_width(PyObject *, glyph_index); bool is_glyph_empty(PyObject *, glyph_index); hb_font_t* harfbuzz_font_for_face(PyObject*); bool set_size_for_face(PyObject*, unsigned int, bool, FONTS_DATA_HANDLE); diff --git a/kitty/freetype.c b/kitty/freetype.c index e844d062f..2937b9e40 100644 --- a/kitty/freetype.c +++ b/kitty/freetype.c @@ -294,6 +294,20 @@ is_glyph_empty(PyObject *s, glyph_index g) { #undef M } +int +get_glyph_width(PyObject *s, glyph_index g) { + Face *self = (Face*)s; + if (!load_glyph(self, g, FT_LOAD_DEFAULT)) { PyErr_Print(); return false; } + FT_Bitmap *bitmap = &self->face->glyph->bitmap; +#define M self->face->glyph->metrics +#define B self->face->glyph->bitmap + /* printf("glyph: %u bitmap.width: %d bitmap.rows: %d horiAdvance: %ld horiBearingX: %ld horiBearingY: %ld vertBearingX: %ld vertBearingY: %ld vertAdvance: %ld width: %ld height: %ld\n", */ + /* g, B.width, B.rows, M.horiAdvance, M.horiBearingX, M.horiBearingY, M.vertBearingX, M.vertBearingY, M.vertAdvance, M.width, M.height); */ + return bitmap->width; +#undef M +#undef B +} + hb_font_t* harfbuzz_font_for_face(PyObject *self) { return ((Face*)self)->harfbuzz_font; }