Refactor the cell rendering code for greater re-use

Also start work on CoreText based rendering
This commit is contained in:
Kovid Goyal
2017-01-11 12:02:28 +05:30
parent 282d6faa5f
commit dff91759a2
6 changed files with 204 additions and 81 deletions

View File

@@ -2,9 +2,88 @@
# vim:fileencoding=utf-8
# License: GPL v3 Copyright: 2016, Kovid Goyal <kovid at kovidgoyal.net>
from kitty.constants import isosx
import ctypes
from kitty.constants import isosx
from .box_drawing import render_box_char, is_renderable_box_char
if isosx:
from .core_text import set_font_family, render_cell # noqa
from .core_text import set_font_family, render_cell as rc, current_cell # noqa
else:
from .freetype import set_font_family, render_cell # noqa
from .freetype import set_font_family, render_cell as rc, current_cell # noqa
def add_line(buf, cell_width, position, thickness):
y = position - thickness // 2
while thickness:
thickness -= 1
offset = cell_width * y
for x in range(cell_width):
buf[offset + x] = 255
y += 1
def add_curl(buf, cell_width, position, thickness):
for y in range(position - thickness, position):
for x in range(0, cell_width // 2):
offset = cell_width * y
buf[offset + x] = 255
for y in range(position, position + thickness):
for x in range(cell_width // 2, cell_width):
offset = cell_width * y
buf[offset + x] = 255
def render_cell(text=' ', bold=False, italic=False, underline=0, strikethrough=False):
CharTexture, cell_width, cell_height, baseline, underline_thickness, underline_position = current_cell()
if is_renderable_box_char(text):
first, second = render_box_char(text, CharTexture(), cell_width, cell_height), None
else:
first, second = rc(text, bold, italic)
def dl(f, *a):
f(first, cell_width, *a)
if second is not None:
f(second, cell_width, *a)
if underline:
t = underline_thickness
if underline == 2:
t = max(1, min(cell_height - underline_position - 1, t))
dl(add_curl if underline == 2 else add_line, underline_position, t)
if strikethrough:
pos = int(0.65 * baseline)
dl(add_line, pos, underline_thickness)
return first, second
def join_cells(cell_width, cell_height, *cells):
dstride = len(cells) * cell_width
ans = (ctypes.c_ubyte * (cell_height * dstride))()
for r in range(cell_height):
soff = r * cell_width
doff = r * dstride
for cnum, cell in enumerate(cells):
doff2 = doff + (cnum * cell_width)
ans[doff2:doff2 + cell_width] = cell[soff:soff + cell_width]
return ans
def display_bitmap(data, w, h):
from PIL import Image
img = Image.new('L', (w, h))
img.putdata(data)
img.show()
def test_rendering(text='\'Ping👁a⧽', sz=144, family='Ubuntu Mono for Kovid'):
set_font_family(family, sz)
cells = []
for c in text:
f, s = render_cell(c, underline=2, strikethrough=True)
cells.append(f)
if s is not None:
cells.append(s)
cell_width, cell_height = current_cell()[1:3]
char_data = join_cells(cell_width, cell_height, *cells)
display_bitmap(char_data, cell_width * len(cells), cell_height)