Infrastructure for rendering cells in the test suite
This commit is contained in:
parent
7d7d82a68d
commit
0518cabef6
@ -13,6 +13,7 @@
|
||||
typedef uint16_t glyph_index;
|
||||
typedef void (*send_sprite_to_gpu_func)(unsigned int, unsigned int, unsigned int, uint8_t*);
|
||||
send_sprite_to_gpu_func current_send_sprite_to_gpu = NULL;
|
||||
static PyObject *python_send_to_gpu_impl = NULL;
|
||||
|
||||
typedef struct SpritePosition SpritePosition;
|
||||
|
||||
@ -166,6 +167,15 @@ free_font(Font *f) {
|
||||
f->bold = false; f->italic = false;
|
||||
}
|
||||
|
||||
static inline void
|
||||
clear_font(Font *f) {
|
||||
f->hb_font = NULL;
|
||||
Py_CLEAR(f->face);
|
||||
clear_sprite_map(f);
|
||||
f->bold = false; f->italic = false;
|
||||
}
|
||||
|
||||
|
||||
static Font medium_font = {0}, bold_font = {0}, italic_font = {0}, bi_font = {0}, box_font = {0}, missing_font = {0}, blank_font = {0};
|
||||
static Font fallback_fonts[256] = {{0}};
|
||||
static PyObject *get_fallback_font = NULL;
|
||||
@ -182,6 +192,16 @@ static unsigned int cell_width = 0, cell_height = 0, baseline = 0, underline_pos
|
||||
static uint8_t *canvas = NULL;
|
||||
static inline void clear_canvas(void) { memset(canvas, 0, cell_width * cell_height); }
|
||||
|
||||
static void
|
||||
python_send_to_gpu(unsigned int x, unsigned int y, unsigned int z, uint8_t* buf) {
|
||||
if (python_send_to_gpu_impl) {
|
||||
PyObject *ret = PyObject_CallFunction(python_send_to_gpu_impl, "IIIy#", x, y, z, buf, cell_width * cell_height);
|
||||
if (ret == NULL) PyErr_Print();
|
||||
else Py_DECREF(ret);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static inline PyObject*
|
||||
update_cell_metrics(float pt_sz, float xdpi, float ydpi) {
|
||||
#define CALL(f) { if ((f)->face) { if(!set_size_for_face((f)->face, pt_sz, xdpi, ydpi)) return NULL; clear_sprite_map(f); } }
|
||||
@ -373,10 +393,15 @@ set_font(PyObject UNUSED *m, PyObject *args) {
|
||||
Py_CLEAR(get_fallback_font); Py_CLEAR(box_drawing_function);
|
||||
if (!PyArg_ParseTuple(args, "OOO!O!fffO|OOO", &get_fallback_font, &box_drawing_function, &PyTuple_Type, &sm, &PyTuple_Type, &smf, &pt_sz, &xdpi, &ydpi, &medium, &bold, &italic, &bi)) return NULL;
|
||||
Py_INCREF(get_fallback_font); Py_INCREF(box_drawing_function);
|
||||
clear_font(&medium_font); clear_font(&bold_font); clear_font(&italic_font); clear_font(&bi_font);
|
||||
if (!alloc_font(&medium_font, medium, false, false)) return PyErr_NoMemory();
|
||||
if (bold && !alloc_font(&bold_font, bold, false, false)) return PyErr_NoMemory();
|
||||
if (italic && !alloc_font(&italic_font, italic, false, false)) return PyErr_NoMemory();
|
||||
if (bi && !alloc_font(&bi_font, bi, false, false)) return PyErr_NoMemory();
|
||||
for (size_t i = 0; fallback_fonts[i].face != NULL; i++) clear_font(fallback_fonts + i);
|
||||
for (size_t i = 0; symbol_map_fonts_count; i++) free_font(symbol_map_fonts + i);
|
||||
free(symbol_maps); free(symbol_map_fonts); symbol_maps = NULL; symbol_map_fonts = NULL;
|
||||
symbol_maps_count = 0; symbol_map_fonts_count = 0;
|
||||
|
||||
symbol_maps_count = PyTuple_GET_SIZE(sm);
|
||||
if (symbol_maps_count > 0) {
|
||||
@ -404,6 +429,7 @@ static hb_buffer_t *harfbuzz_buffer = NULL;
|
||||
|
||||
static void
|
||||
finalize(void) {
|
||||
Py_CLEAR(python_send_to_gpu_impl);
|
||||
free(canvas);
|
||||
Py_CLEAR(get_fallback_font);
|
||||
Py_CLEAR(box_drawing_function);
|
||||
@ -459,6 +485,14 @@ send_prerendered_sprites(PyObject UNUSED *s, PyObject *args) {
|
||||
return Py_BuildValue("H", x);
|
||||
}
|
||||
|
||||
static PyObject*
|
||||
set_send_sprite_to_gpu(PyObject UNUSED *self, PyObject *func) {
|
||||
Py_CLEAR(python_send_to_gpu_impl);
|
||||
python_send_to_gpu_impl = func;
|
||||
Py_INCREF(func);
|
||||
current_send_sprite_to_gpu = func == Py_None ? send_sprite_to_gpu : python_send_to_gpu;
|
||||
Py_RETURN_NONE;
|
||||
}
|
||||
|
||||
static PyMethodDef module_methods[] = {
|
||||
METHODB(set_font_size, METH_VARARGS),
|
||||
@ -467,6 +501,7 @@ static PyMethodDef module_methods[] = {
|
||||
METHODB(sprite_map_set_layout, METH_VARARGS),
|
||||
METHODB(send_prerendered_sprites, METH_VARARGS),
|
||||
METHODB(test_sprite_position_for, METH_VARARGS),
|
||||
METHODB(set_send_sprite_to_gpu, METH_O),
|
||||
{NULL, NULL, 0, NULL} /* Sentinel */
|
||||
};
|
||||
|
||||
|
||||
@ -7,6 +7,7 @@ from collections import namedtuple
|
||||
from math import ceil, floor, pi, sin, sqrt
|
||||
|
||||
from kitty.constants import isosx
|
||||
from kitty.config import defaults
|
||||
from kitty.fast_data_types import (
|
||||
send_prerendered_sprites, set_font, set_font_size
|
||||
)
|
||||
@ -56,13 +57,10 @@ def get_fallback_font(text, bold, italic):
|
||||
)
|
||||
|
||||
|
||||
def set_font_family(opts, override_font_size=None):
|
||||
if hasattr(set_font_family, 'state'):
|
||||
raise ValueError(
|
||||
'Cannot set font family more than once, use resize_fonts() to change size'
|
||||
)
|
||||
def set_font_family(opts=None, override_font_size=None, override_dpi=None):
|
||||
opts = opts or defaults
|
||||
sz = override_font_size or opts.font_size
|
||||
xdpi, ydpi = get_logical_dpi()
|
||||
xdpi, ydpi = get_logical_dpi(override_dpi)
|
||||
set_font_family.state = FontState('', sz, xdpi, ydpi, 0, 0, 0, 0, 0)
|
||||
font_map = get_font_files(opts)
|
||||
faces = [create_face(font_map['medium'])]
|
||||
@ -136,7 +134,7 @@ def render_special(underline=0, strikethrough=False, missing=False):
|
||||
s = set_font_family.state
|
||||
cell_width, cell_height, baseline = s.cell_width, s.cell_height, s.baseline
|
||||
underline_position, underline_thickness = s.underline_position, s.underline_thickness
|
||||
CharTexture = ctypes.c_ubyte * cell_width * cell_height
|
||||
CharTexture = ctypes.c_ubyte * (cell_width * cell_height)
|
||||
ans = CharTexture if missing else CharTexture()
|
||||
|
||||
def dl(f, *a):
|
||||
@ -171,7 +169,7 @@ def prerender():
|
||||
def render_box_drawing(codepoint):
|
||||
s = set_font_family.state
|
||||
cell_width, cell_height = s.cell_width, s.cell_height
|
||||
CharTexture = ctypes.c_ubyte * cell_width * cell_height
|
||||
CharTexture = ctypes.c_ubyte * (cell_width * cell_height)
|
||||
buf = render_box_char(
|
||||
chr(codepoint), CharTexture(), cell_width, cell_height
|
||||
)
|
||||
|
||||
@ -107,9 +107,11 @@ def x11_dpi():
|
||||
pass
|
||||
|
||||
|
||||
def get_logical_dpi():
|
||||
def get_logical_dpi(override_dpi=None):
|
||||
# See https://github.com/glfw/glfw/issues/1019 for why we cant use
|
||||
# glfw_get_physical_dpi()
|
||||
if override_dpi is not None:
|
||||
get_logical_dpi.ans = override_dpi
|
||||
if not hasattr(get_logical_dpi, 'ans'):
|
||||
if isosx:
|
||||
# TODO: Investigate if this needs a different implementation on OS X
|
||||
|
||||
37
kitty_tests/fonts.py
Normal file
37
kitty_tests/fonts.py
Normal file
@ -0,0 +1,37 @@
|
||||
#!/usr/bin/env python
|
||||
# vim:fileencoding=utf-8
|
||||
# License: GPL v3 Copyright: 2017, Kovid Goyal <kovid at kovidgoyal.net>
|
||||
|
||||
from collections import OrderedDict
|
||||
|
||||
from kitty.fast_data_types import set_send_sprite_to_gpu
|
||||
from kitty.fonts.render import set_font_family
|
||||
|
||||
from . import BaseTest
|
||||
|
||||
|
||||
class Rendering(BaseTest):
|
||||
|
||||
sprites = OrderedDict()
|
||||
|
||||
@classmethod
|
||||
def setUpClass(cls):
|
||||
def send_to_gpu(x, y, z, data):
|
||||
cls.sprites[(x, y, z)] = data
|
||||
|
||||
set_send_sprite_to_gpu(send_to_gpu)
|
||||
cls.cell_width, cls.cell_height = set_font_family(override_dpi=(96.0, 96.0))
|
||||
|
||||
@classmethod
|
||||
def tearDownClass(cls):
|
||||
set_send_sprite_to_gpu(None)
|
||||
cls.sprites.clear()
|
||||
|
||||
def setUp(self):
|
||||
self.sprites.clear()
|
||||
|
||||
def tearDown(self):
|
||||
self.sprites.clear()
|
||||
|
||||
def test_box_drawing(self):
|
||||
pass
|
||||
Loading…
x
Reference in New Issue
Block a user