From ce0e5a893f0e0dd3973c2c928aa9c8b33b596be2 Mon Sep 17 00:00:00 2001 From: Kovid Goyal Date: Sun, 5 Nov 2017 12:07:40 +0530 Subject: [PATCH] Make the showcase output a little nicer --- kitty/core_text.m | 6 ++++++ kitty/fonts.c | 28 ++++++++++++++++++++++++++++ kitty/fonts/render.py | 12 ++++++++---- kitty/freetype.c | 9 +++++++++ 4 files changed, 51 insertions(+), 4 deletions(-) diff --git a/kitty/core_text.m b/kitty/core_text.m index ec8875040..f2089a720 100644 --- a/kitty/core_text.m +++ b/kitty/core_text.m @@ -308,6 +308,12 @@ repr(Face *self) { ); } +static PyObject* +display_name(Face *self) { +#define R(x) if (self->x) { Py_INCREF(self->x); return self->x; } + R(full_name); R(postscript_name); R(family_name); R(path); +#undef R +} // Boilerplate {{{ diff --git a/kitty/fonts.c b/kitty/fonts.c index 978c524c8..242fedada 100644 --- a/kitty/fonts.c +++ b/kitty/fonts.c @@ -657,6 +657,33 @@ concat_cells(PyObject UNUSED *self, PyObject *args) { return ans; } +static PyObject* +current_fonts(PyObject UNUSED *self) { + PyObject *ans = PyDict_New(); + if (!ans) return NULL; +#define SET(key, val) {if (PyDict_SetItemString(ans, #key, val) != 0) { goto error; }} + SET(medium, medium_font.face); + if (bold_font.face) SET(bold, bold_font.face); + if (italic_font.face) SET(italic, italic_font.face); + if (bi_font.face) SET(bi, bi_font.face); + int num = 0; + while (fallback_fonts[num].face) num++; + PyObject *ff = PyTuple_New(num); + if (!ff) goto error; + num = 0; + while (fallback_fonts[num].face) { + Py_INCREF(fallback_fonts[num].face); + PyTuple_SET_ITEM(ff, num, fallback_fonts[num].face); + num++; + } + SET(fallback, ff); + Py_CLEAR(ff); + return ans; +error: + Py_CLEAR(ans); return NULL; +#undef SET +} + static PyMethodDef module_methods[] = { METHODB(set_font_size, METH_VARARGS), METHODB(set_font, METH_VARARGS), @@ -666,6 +693,7 @@ static PyMethodDef module_methods[] = { METHODB(test_sprite_position_for, METH_VARARGS), METHODB(concat_cells, METH_VARARGS), METHODB(set_send_sprite_to_gpu, METH_O), + METHODB(current_fonts, METH_NOARGS), METHODB(test_render_line, METH_VARARGS), {NULL, NULL, 0, NULL} /* Sentinel */ }; diff --git a/kitty/fonts/render.py b/kitty/fonts/render.py index c23d18ad9..d859e6133 100644 --- a/kitty/fonts/render.py +++ b/kitty/fonts/render.py @@ -180,7 +180,7 @@ def render_box_drawing(codepoint): def test_render_string(text='Hello, world!', family='monospace', size=144.0, dpi=96.0): from tempfile import NamedTemporaryFile - from kitty.fast_data_types import concat_cells, set_send_sprite_to_gpu, Screen, sprite_map_set_limits, test_render_line + from kitty.fast_data_types import concat_cells, set_send_sprite_to_gpu, Screen, sprite_map_set_limits, test_render_line, current_fonts from kitty.icat import detect_support, show if not detect_support(): raise SystemExit('Your terminal does not support the graphics protocol') @@ -208,12 +208,16 @@ def test_render_string(text='Hello, world!', family='monospace', size=144.0, dpi rgb_data = concat_cells(cell_width, cell_height, tuple(cells)) with NamedTemporaryFile(delete=False) as f: f.write(rgb_data) - print('Rendered string {!r} below, with font: {}'.format(text, family)) + cf = current_fonts() + fonts = [cf['medium'].display_name()] + fonts.extend(f.display_name() for f in cf['fallback']) + print('Rendered string {} below, with fonts: {}'.format(text, ', '.join(fonts))) show(f.name, cell_width * len(cells), cell_height, 24) print('\n') def showcase(): - test_render_string('He\u0347\u0305llo\u0341, w\u0302or\u0306l\u0354d!', family='Consolas') - test_render_string('你好,世界') + test_render_string('He\u0347\u0305llo\u0341, w\u0302or\u0306l\u0354d!', family='Noto Sans Mono') + test_render_string('你好,世界', family='Noto Sans Mono') + test_render_string('|\U0001F929|\U0001F921|\U0001F91f|', family='Noto Sans Mono') test_render_string('A=>>B!=C', family='Fira Code Medium') diff --git a/kitty/freetype.c b/kitty/freetype.c index 9b35cfba5..e73208a75 100644 --- a/kitty/freetype.c +++ b/kitty/freetype.c @@ -301,6 +301,14 @@ render_glyphs_in_cells(PyObject *f, bool bold, bool italic, hb_glyph_info_t *inf return true; } +static PyObject* +display_name(Face *self) { + const char *psname = FT_Get_Postscript_Name(self->face); + if (psname) return Py_BuildValue("s", psname); + Py_INCREF(self->path); + return self->path; +} + // Boilerplate {{{ static PyMemberDef members[] = { @@ -319,6 +327,7 @@ static PyMemberDef members[] = { }; static PyMethodDef methods[] = { + METHODB(display_name, METH_NOARGS), {NULL} /* Sentinel */ };