From 53e9f35c1fc4b0cf0cbfbb5015a93cbe117b57dc Mon Sep 17 00:00:00 2001 From: Kovid Goyal Date: Sat, 11 Nov 2017 18:47:34 +0530 Subject: [PATCH] Add test for harfbuzz shaping --- kitty/fonts.c | 16 +++++++++++++++- kitty/fonts/render.py | 16 +++++++++++++++- kitty_tests/fonts.py | 7 ++++++- 3 files changed, 36 insertions(+), 3 deletions(-) diff --git a/kitty/fonts.c b/kitty/fonts.c index 452351401..f439944e0 100644 --- a/kitty/fonts.c +++ b/kitty/fonts.c @@ -485,7 +485,7 @@ shape_run(Cell *first_cell, index_type num_cells, Font *font) { num_glyphs = MIN(info_length, positions_length); #if 0 // You can also generate this easily using hb-shape --show-flags --show-extents --cluster-level=1 --shapers=ot /path/to/font/file text - hb_buffer_serialize_glyphs(harfbuzz_buffer, 0, num_glyphs, (char*)canvas, 4 * cell_width * cell_height, NULL, font->hb_font, HB_BUFFER_SERIALIZE_FORMAT_TEXT, HB_BUFFER_SERIALIZE_FLAG_DEFAULT | HB_BUFFER_SERIALIZE_FLAG_GLYPH_EXTENTS | HB_BUFFER_SERIALIZE_FLAG_GLYPH_FLAGS); + hb_buffer_serialize_glyphs(harfbuzz_buffer, 0, num_glyphs, (char*)canvas, CELLS_IN_CANVAS * cell_width * cell_height, NULL, font->hb_font, HB_BUFFER_SERIALIZE_FORMAT_TEXT, HB_BUFFER_SERIALIZE_FLAG_DEFAULT | HB_BUFFER_SERIALIZE_FLAG_GLYPH_EXTENTS | HB_BUFFER_SERIALIZE_FLAG_GLYPH_FLAGS); printf("\n%s\n", canvas); clear_canvas(); #endif @@ -498,6 +498,19 @@ shape_run(Cell *first_cell, index_type num_cells, Font *font) { } } +static PyObject* +test_shape(PyObject UNUSED *self, Line *line) { + index_type num = 0; + while(num < line->xnum && line->cells[num].ch) num++; + load_hb_buffer(line->cells, num); + Font *font = &medium_font; + hb_shape_full(font->hb_font, harfbuzz_buffer, NULL, 0, SHAPERS); + unsigned int num_glyphs; + hb_buffer_get_glyph_infos(harfbuzz_buffer, &num_glyphs); + hb_buffer_serialize_glyphs(harfbuzz_buffer, 0, num_glyphs, (char*)canvas, CELLS_IN_CANVAS * cell_width * cell_height, NULL, font->hb_font, HB_BUFFER_SERIALIZE_FORMAT_JSON, HB_BUFFER_SERIALIZE_FLAG_DEFAULT | HB_BUFFER_SERIALIZE_FLAG_GLYPH_EXTENTS | HB_BUFFER_SERIALIZE_FLAG_GLYPH_FLAGS); + return Py_BuildValue("s", canvas); +} + static inline void render_run(Cell *first_cell, index_type num_cells, Font *font, FontType ft) { switch(ft) { @@ -726,6 +739,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(test_shape, METH_O), METHODB(current_fonts, METH_NOARGS), METHODB(test_render_line, METH_VARARGS), METHODB(get_fallback_font, METH_VARARGS), diff --git a/kitty/fonts/render.py b/kitty/fonts/render.py index 82ce93e31..8122385ed 100644 --- a/kitty/fonts/render.py +++ b/kitty/fonts/render.py @@ -12,7 +12,7 @@ from kitty.constants import isosx from kitty.fast_data_types import ( Screen, change_wcwidth, get_fallback_font, send_prerendered_sprites, set_font, set_font_size, set_logical_dpi, set_send_sprite_to_gpu, - sprite_map_set_limits, test_render_line + sprite_map_set_limits, test_render_line, test_shape ) from kitty.fonts.box_drawing import render_box_char, render_missing_glyph @@ -187,6 +187,20 @@ def render_string(text, family='monospace', size=11.0, dpi=96.0): return cell_width, cell_height, cells +def shape_string(text="abcd", family='monospace', size=11.0, dpi=96.0): + import json + try: + sprites, cell_width, cell_height = setup_for_testing(family, size, dpi) + s = Screen(None, 1, len(text)*2) + line = s.line(0) + s.draw(text) + data = test_shape(line) + return json.loads('[' + data + ']') + finally: + set_send_sprite_to_gpu(None) + return data + + 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, current_fonts diff --git a/kitty_tests/fonts.py b/kitty_tests/fonts.py index 8129c6d6b..c4b7023a5 100644 --- a/kitty_tests/fonts.py +++ b/kitty_tests/fonts.py @@ -10,7 +10,7 @@ from kitty.fast_data_types import ( sprite_map_set_limits, test_render_line, test_sprite_position_for, wcwidth ) from kitty.fonts.box_drawing import box_chars -from kitty.fonts.render import prerender, render_string, set_font_family +from kitty.fonts.render import prerender, render_string, set_font_family, shape_string from kitty.utils import get_logical_dpi from . import BaseTest @@ -68,3 +68,8 @@ class Rendering(BaseTest): sz = sum(map(lambda x: wcwidth(ord(x)), text)) cells = render_string(text)[-1] self.ae(len(cells), sz) + + def test_shaping(self): + self.assertEqual(len(shape_string('abcd')), 4) + flags = [x.get('fl', 0) for x in shape_string('e\u0347\u0305')] + self.assertEqual(flags, [0, 1, 1])