Rendering ligatures now works
This commit is contained in:
@@ -387,10 +387,10 @@ set_cell_sprite(Cell *cell, SpritePosition *sp) {
|
||||
}
|
||||
|
||||
static inline uint8_t*
|
||||
extract_cell_from_canvas(unsigned int i) {
|
||||
uint8_t *ans = canvas + (cell_width * cell_height * (CELLS_IN_CANVAS - 1)), *dest = ans;
|
||||
uint8_t *src = canvas + (cell_width * cell_height * i);
|
||||
for (unsigned int r = 0; r < cell_height; r++, dest += cell_width, src += cell_width) memcpy(dest, src, cell_width);
|
||||
extract_cell_from_canvas(unsigned int i, unsigned int num_cells) {
|
||||
uint8_t *ans = canvas + (cell_width * cell_height * (CELLS_IN_CANVAS - 1)), *dest = ans, *src = canvas + (i * cell_width);
|
||||
unsigned int stride = cell_width * num_cells;
|
||||
for (unsigned int r = 0; r < cell_height; r++, dest += cell_width, src += stride) memcpy(dest, src, cell_width);
|
||||
return ans;
|
||||
}
|
||||
|
||||
@@ -434,7 +434,7 @@ render_group(unsigned int num_cells, unsigned int num_glyphs, Cell *cells, hb_gl
|
||||
for (unsigned int i = 0; i < num_cells; i++) {
|
||||
sprite_position[i]->rendered = true;
|
||||
set_cell_sprite(cells + i, sprite_position[i]);
|
||||
uint8_t *buf = num_cells == 1 ? canvas : extract_cell_from_canvas(i);
|
||||
uint8_t *buf = num_cells == 1 ? canvas : extract_cell_from_canvas(i, num_cells);
|
||||
current_send_sprite_to_gpu(sprite_position[i]->x, sprite_position[i]->y, sprite_position[i]->z, buf);
|
||||
}
|
||||
|
||||
|
||||
@@ -177,7 +177,7 @@ def render_box_drawing(codepoint):
|
||||
return ctypes.addressof(buf), buf
|
||||
|
||||
|
||||
def test_render_string(text='\'Qing👁a⧽', size=200.0, dpi=96.0):
|
||||
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.icat import detect_support, show
|
||||
@@ -190,8 +190,9 @@ def test_render_string(text='\'Qing👁a⧽', size=200.0, dpi=96.0):
|
||||
|
||||
sprite_map_set_limits(100000, 100)
|
||||
set_send_sprite_to_gpu(send_to_gpu)
|
||||
opts = defaults._replace(font_family=family)
|
||||
try:
|
||||
cell_width, cell_height = set_font_family(override_dpi=(dpi, dpi), override_font_size=size)
|
||||
cell_width, cell_height = set_font_family(opts, override_dpi=(dpi, dpi), override_font_size=size)
|
||||
s = Screen(None, 1, len(text)*2)
|
||||
line = s.line(0)
|
||||
s.draw(text)
|
||||
@@ -206,6 +207,11 @@ def test_render_string(text='\'Qing👁a⧽', size=200.0, dpi=96.0):
|
||||
rgb_data = concat_cells(cell_width, cell_height, tuple(cells))
|
||||
with NamedTemporaryFile(delete=False) as f:
|
||||
f.write(rgb_data)
|
||||
print('Rendered string below: ({}x{})'.format(cell_width, cell_height))
|
||||
print('Rendered string {!r} below: ({}x{})'.format(text, cell_width, cell_height))
|
||||
show(f.name, cell_width * len(cells), cell_height, 24)
|
||||
print()
|
||||
print('\n')
|
||||
|
||||
|
||||
def showcase():
|
||||
test_render_string(family='Fira Code Medium')
|
||||
test_render_string('==A=== -> -->', family='Fira Code Medium')
|
||||
|
||||
@@ -251,12 +251,13 @@ render_bitmap(Face *self, int glyph_id, ProcessedBitmap *ans, unsigned int cell_
|
||||
}
|
||||
|
||||
static inline void
|
||||
place_bitmap_in_cell(unsigned char *cell, ProcessedBitmap *bm, size_t cell_width, size_t cell_height, float x_offset, float y_offset, FT_Glyph_Metrics *metrics, size_t baseline) {
|
||||
place_bitmap_in_canvas(unsigned char *cell, ProcessedBitmap *bm, size_t cell_width, size_t cell_height, float x_offset, float y_offset, FT_Glyph_Metrics *metrics, size_t baseline) {
|
||||
// We want the glyph to be positioned inside the cell based on the bearingX
|
||||
// and bearingY values, making sure that it does not overflow the cell.
|
||||
|
||||
// Calculate column bounds
|
||||
ssize_t xoff = (ssize_t)(x_offset + (float)metrics->horiBearingX / 64.f);
|
||||
float bearing_x = (float)metrics->horiBearingX / 64.f;
|
||||
ssize_t xoff = (ssize_t)(x_offset + bearing_x);
|
||||
size_t src_start_column = bm->start_x, dest_start_column = 0, extra;
|
||||
if (xoff < 0) src_start_column += -xoff;
|
||||
else dest_start_column = xoff;
|
||||
@@ -267,7 +268,8 @@ place_bitmap_in_cell(unsigned char *cell, ProcessedBitmap *bm, size_t cell_width
|
||||
}
|
||||
|
||||
// Calculate row bounds
|
||||
ssize_t yoff = (ssize_t)(y_offset + (float)metrics->horiBearingY / 64.f);
|
||||
float bearing_y = (float)metrics->horiBearingY / 64.f;
|
||||
ssize_t yoff = (ssize_t)(y_offset + bearing_y);
|
||||
size_t src_start_row, dest_start_row;
|
||||
if (yoff > 0 && (size_t)yoff > baseline) {
|
||||
src_start_row = 0;
|
||||
@@ -299,7 +301,7 @@ render_glyphs_in_cells(PyObject *f, bool bold, bool italic, hb_glyph_info_t *inf
|
||||
if (!render_bitmap(self, info[i].codepoint, &bm, cell_width, num_cells, bold, italic, true)) return false;
|
||||
x += (float)positions[i].x_offset / 64.0f;
|
||||
y = (float)positions[i].y_offset / 64.0f;
|
||||
place_bitmap_in_cell(canvas, &bm, cell_width * num_cells, cell_height, x, y, &self->face->glyph->metrics, baseline);
|
||||
if (self->face->glyph->metrics.width > 0 && bm.width > 0) place_bitmap_in_canvas(canvas, &bm, cell_width * num_cells, cell_height, x, y, &self->face->glyph->metrics, baseline);
|
||||
x += (float)positions[i].x_advance / 64.0f;
|
||||
}
|
||||
return true;
|
||||
|
||||
Reference in New Issue
Block a user