mirror of
https://github.com/kovidgoyal/kitty
synced 2026-07-18 14:34:52 +02:00
More work on scaled font rendering
This commit is contained in:
@@ -614,6 +614,8 @@ in_symbol_maps(FontGroup *fg, char_type ch) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static bool allow_use_of_box_fonts = true;
|
||||||
|
|
||||||
// Decides which 'font' to use for a given cell.
|
// Decides which 'font' to use for a given cell.
|
||||||
//
|
//
|
||||||
// Possible results:
|
// Possible results:
|
||||||
@@ -646,7 +648,8 @@ START_ALLOW_CASE_RANGE
|
|||||||
case 0xee00 ... 0xee0b: // fira code progress bar/spinner
|
case 0xee00 ... 0xee0b: // fira code progress bar/spinner
|
||||||
case 0x1fb00 ... 0x1fbae: // symbols for legacy computing
|
case 0x1fb00 ... 0x1fbae: // symbols for legacy computing
|
||||||
case 0xf5d0 ... 0xf60d: // branch drawing characters
|
case 0xf5d0 ... 0xf60d: // branch drawing characters
|
||||||
return BOX_FONT;
|
if (allow_use_of_box_fonts) return BOX_FONT;
|
||||||
|
/* fallthrough */
|
||||||
default:
|
default:
|
||||||
*is_emoji_presentation = has_emoji_presentation(cpu_cell, lc);
|
*is_emoji_presentation = has_emoji_presentation(cpu_cell, lc);
|
||||||
ans = in_symbol_maps(fg, lc->chars[0]);
|
ans = in_symbol_maps(fg, lc->chars[0]);
|
||||||
@@ -782,6 +785,9 @@ apply_scale_to_font_group(FontGroup *fg, RunFont *rf) {
|
|||||||
copy.font_sz_in_pts -= 0.1;
|
copy.font_sz_in_pts -= 0.1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
sfd.fcm = copy.fcm; sfd.font_sz_in_pts = copy.font_sz_in_pts;
|
||||||
|
sfd.fcm.cell_width = scaled_cell_width; sfd.fcm.cell_height = scaled_cell_height;
|
||||||
|
if (vt_is_end(vt_insert(&fg->scaled_font_map, scale, sfd))) fatal("Out of memory inserting scaled font data into map");
|
||||||
} else sfd = i.data->val;
|
} else sfd = i.data->val;
|
||||||
fg->font_sz_in_pts = sfd.font_sz_in_pts;
|
fg->font_sz_in_pts = sfd.font_sz_in_pts;
|
||||||
fg->fcm = sfd.fcm;
|
fg->fcm = sfd.fcm;
|
||||||
@@ -799,14 +805,14 @@ extract_cell_from_canvas(FontGroup *fg, unsigned int i, unsigned int num_cells)
|
|||||||
|
|
||||||
static pixel*
|
static pixel*
|
||||||
extract_scaled_cell_from_canvas(
|
extract_scaled_cell_from_canvas(
|
||||||
Canvas *canvas, unsigned i, unsigned num_cells, Region src, Region dest,
|
Canvas *canvas, unsigned i, Region src, Region dest,
|
||||||
unsigned unscaled_cell_width, unsigned unscaled_cell_height, unsigned scaled_cell_width, unsigned scaled_cell_height
|
unsigned unscaled_cell_width, unsigned unscaled_cell_height, unsigned scaled_cell_height
|
||||||
) {
|
) {
|
||||||
unsigned unscaled_cell_area = unscaled_cell_width * unscaled_cell_height;
|
unsigned unscaled_cell_area = unscaled_cell_width * unscaled_cell_height;
|
||||||
pixel *ans = canvas->buf + (canvas->size_in_bytes / sizeof(canvas->buf[0]) - unscaled_cell_area);
|
pixel *ans = canvas->buf + (canvas->size_in_bytes / sizeof(canvas->buf[0]) - unscaled_cell_area);
|
||||||
memset(ans, 0, sizeof(ans[0]) * unscaled_cell_area);
|
memset(ans, 0, sizeof(ans[0]) * unscaled_cell_area);
|
||||||
unsigned xoff = i * unscaled_cell_width;
|
unsigned xoff = i * unscaled_cell_width;
|
||||||
unsigned src_row_size = scaled_cell_width * num_cells;
|
unsigned src_row_size = src.right;
|
||||||
if (xoff >= src_row_size) return ans; // nothing to copy
|
if (xoff >= src_row_size) return ans; // nothing to copy
|
||||||
unsigned width = MIN(src_row_size - xoff, unscaled_cell_width);
|
unsigned width = MIN(src_row_size - xoff, unscaled_cell_width);
|
||||||
/*printf("extracting width: %u ------------------------\n", width);*/
|
/*printf("extracting width: %u ------------------------\n", width);*/
|
||||||
@@ -910,7 +916,7 @@ render_box_cell(FontGroup *fg, RunFont rf, CPUCell *cpu_cell, GPUCell *gpu_cell,
|
|||||||
calculate_regions_for_line(rf, fg->fcm.cell_height, &src, &dest);
|
calculate_regions_for_line(rf, fg->fcm.cell_height, &src, &dest);
|
||||||
/*printf("width: %u height: %u unscaled_cell_width: %u unscaled_cell_height: %u src.top: %u src.bottom: %u rf.scale: %u\n", width, height, fg->fcm.cell_width, fg->fcm.cell_height, src.top, src.bottom, rf.scale);*/
|
/*printf("width: %u height: %u unscaled_cell_width: %u unscaled_cell_height: %u src.top: %u src.bottom: %u rf.scale: %u\n", width, height, fg->fcm.cell_width, fg->fcm.cell_height, src.top, src.bottom, rf.scale);*/
|
||||||
for (unsigned i = 0; i < rf.scale; i++) {
|
for (unsigned i = 0; i < rf.scale; i++) {
|
||||||
pixel *b = extract_scaled_cell_from_canvas(&fg->canvas, i, 1, src, dest, fg->fcm.cell_width, fg->fcm.cell_height, width, height);
|
pixel *b = extract_scaled_cell_from_canvas(&fg->canvas, i, src, dest, fg->fcm.cell_width, fg->fcm.cell_height, height);
|
||||||
/*printf("Sprite %u: pos: (%u, %u, %u) sz: (%u, %u)\n", i, sp[i]->x, sp[i]->y, sp[i]->z, fg->fcm.cell_width, fg->fcm.cell_height); for (unsigned y = 0; y < fg->fcm.cell_height; y++) { for (unsigned x = 0; x < fg->fcm.cell_width; x++) { printf("%d ", (b + fg->fcm.cell_width * y)[x] != 0); } printf("\n"); }*/
|
/*printf("Sprite %u: pos: (%u, %u, %u) sz: (%u, %u)\n", i, sp[i]->x, sp[i]->y, sp[i]->z, fg->fcm.cell_width, fg->fcm.cell_height); for (unsigned y = 0; y < fg->fcm.cell_height; y++) { for (unsigned x = 0; x < fg->fcm.cell_width; x++) { printf("%d ", (b + fg->fcm.cell_width * y)[x] != 0); } printf("\n"); }*/
|
||||||
sp[i]->rendered = true;
|
sp[i]->rendered = true;
|
||||||
current_send_sprite_to_gpu((FONTS_DATA_HANDLE)fg, sp[i]->x, sp[i]->y, sp[i]->z, b);
|
current_send_sprite_to_gpu((FONTS_DATA_HANDLE)fg, sp[i]->x, sp[i]->y, sp[i]->z, b);
|
||||||
@@ -920,17 +926,16 @@ render_box_cell(FontGroup *fg, RunFont rf, CPUCell *cpu_cell, GPUCell *gpu_cell,
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
load_hb_buffer(CPUCell *first_cpu_cell, GPUCell *first_gpu_cell, index_type num_cells, const TextCache *tc) {
|
load_hb_buffer(CPUCell *first_cpu_cell, GPUCell *first_gpu_cell, index_type num_cells, const TextCache *tc, ListOfChars *lc) {
|
||||||
index_type num;
|
index_type num;
|
||||||
hb_buffer_clear_contents(harfbuzz_buffer);
|
hb_buffer_clear_contents(harfbuzz_buffer);
|
||||||
RAII_ListOfChars(lc);
|
|
||||||
while (num_cells) {
|
while (num_cells) {
|
||||||
for (num = 0; num_cells; first_cpu_cell++, first_gpu_cell++, num_cells--) {
|
for (num = 0; num_cells; first_cpu_cell++, first_gpu_cell++, num_cells--) {
|
||||||
text_in_cell(first_cpu_cell, tc, &lc);
|
text_in_cell(first_cpu_cell, tc, lc);
|
||||||
if (first_cpu_cell->is_multicell && (first_cpu_cell->x + first_cpu_cell->y)) continue;
|
if (first_cpu_cell->is_multicell && first_cpu_cell->x) continue;
|
||||||
if (lc.count + num > arraysz(shape_buffer)) break;
|
if (lc->count + num > arraysz(shape_buffer)) break;
|
||||||
memcpy(shape_buffer + num, lc.chars, lc.count * sizeof(shape_buffer[0]));
|
memcpy(shape_buffer + num, lc->chars, lc->count * sizeof(shape_buffer[0]));
|
||||||
num += lc.count;
|
num += lc->count;
|
||||||
}
|
}
|
||||||
hb_buffer_add_utf32(harfbuzz_buffer, shape_buffer, num, 0, num);
|
hb_buffer_add_utf32(harfbuzz_buffer, shape_buffer, num, 0, num);
|
||||||
}
|
}
|
||||||
@@ -954,53 +959,71 @@ render_group(
|
|||||||
#define sp global_glyph_render_scratch.sprite_positions
|
#define sp global_glyph_render_scratch.sprite_positions
|
||||||
int error = 0;
|
int error = 0;
|
||||||
bool all_rendered = true;
|
bool all_rendered = true;
|
||||||
bool is_infinite_ligature = num_cells > 9 && num_glyphs == num_cells;
|
unsigned num_scaled_cells = num_cells / rf.scale;
|
||||||
|
bool is_infinite_ligature = num_scaled_cells > 9 && num_glyphs == num_scaled_cells;
|
||||||
Font *font = fg->fonts + rf.font_idx;
|
Font *font = fg->fonts + rf.font_idx;
|
||||||
for (unsigned i = 0, ligature_index = 0; i < num_cells; i++) {
|
const FontCellMetrics scaled_metrics = fg->fcm;
|
||||||
bool is_repeat_glyph = is_infinite_ligature && i > 1 && i + 1 < num_cells && glyphs[i] == glyphs[i-1] && glyphs[i] == glyphs[i-2] && glyphs[i] == glyphs[i+1];
|
for (unsigned scaled_cell = 0, ligature_index = 0; scaled_cell < num_scaled_cells; scaled_cell++) {
|
||||||
if (is_repeat_glyph) {
|
bool is_repeat_glyph = is_infinite_ligature && scaled_cell > 1 && scaled_cell + 1 < num_scaled_cells && glyphs[scaled_cell] == glyphs[scaled_cell-1] && glyphs[scaled_cell] == glyphs[scaled_cell-2] && glyphs[scaled_cell] == glyphs[scaled_cell+1];
|
||||||
sp[i] = sp[i-1];
|
for (unsigned i = scaled_cell; i < rf.scale + scaled_cell; i++) {
|
||||||
} else {
|
sp[i] = is_repeat_glyph ? sp[i-1] : sprite_position_for(fg, rf, glyphs, glyph_count, ligature_index++, num_cells, &error);
|
||||||
sp[i] = sprite_position_for(fg, rf, glyphs, glyph_count, ligature_index++, num_cells, &error);
|
if (error != 0) { sprite_map_set_error(error); PyErr_Print(); return; }
|
||||||
|
if (!sp[i]->rendered) all_rendered = false;
|
||||||
}
|
}
|
||||||
if (error != 0) { sprite_map_set_error(error); PyErr_Print(); return; }
|
|
||||||
if (!sp[i]->rendered) all_rendered = false;
|
|
||||||
}
|
}
|
||||||
if (all_rendered) {
|
if (all_rendered) {
|
||||||
for (unsigned i = 0; i < num_cells; i++) { set_cell_sprite(gpu_cells + i, sp[i]); }
|
for (unsigned i = 0; i < num_cells; i++) set_cell_sprite(gpu_cells + i, sp[i]);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
ensure_canvas_can_fit(fg, num_cells + 1, rf.scale);
|
ensure_canvas_can_fit(fg, num_cells + 1, rf.scale);
|
||||||
text_in_cell(cpu_cells, tc, global_glyph_render_scratch.lc);
|
text_in_cell(cpu_cells, tc, global_glyph_render_scratch.lc);
|
||||||
|
bool is_only_filled_boxes = false;
|
||||||
bool was_colored = has_emoji_presentation(cpu_cells, global_glyph_render_scratch.lc);
|
bool was_colored = has_emoji_presentation(cpu_cells, global_glyph_render_scratch.lc);
|
||||||
render_glyphs_in_cells(font->face, font->bold, font->italic, info, positions, num_glyphs, fg->canvas.buf, fg->fcm.cell_width, fg->fcm.cell_height, num_cells, fg->fcm.baseline, &was_colored, (FONTS_DATA_HANDLE)fg, center_glyph);
|
if (global_glyph_render_scratch.lc->chars[0] == 0x2588) {
|
||||||
|
glyph_index box_glyph_id = global_glyph_render_scratch.glyphs[0];
|
||||||
|
is_only_filled_boxes = true;
|
||||||
|
for (unsigned i = 1; i < num_glyphs && is_only_filled_boxes; i++) if (global_glyph_render_scratch.glyphs[i] != box_glyph_id) is_only_filled_boxes = false;
|
||||||
|
}
|
||||||
|
for (unsigned i = 0; i < global_glyph_render_scratch.lc->count && is_only_filled_boxes; i++) if (global_glyph_render_scratch.lc->chars[i] != 0x2588) is_only_filled_boxes = false;
|
||||||
|
if (is_only_filled_boxes) {
|
||||||
|
// special case rendering of █ for tests
|
||||||
|
memset(fg->canvas.buf, 0xff, num_glyphs * scaled_metrics.cell_height * scaled_metrics.cell_width * sizeof(fg->canvas.buf[0]));
|
||||||
|
was_colored = false;
|
||||||
|
} else render_glyphs_in_cells(font->face, font->bold, font->italic, info, positions, num_glyphs, fg->canvas.buf, scaled_metrics.cell_width, scaled_metrics.cell_height, num_scaled_cells, scaled_metrics.baseline, &was_colored, (FONTS_DATA_HANDLE)fg, center_glyph);
|
||||||
if (PyErr_Occurred()) PyErr_Print();
|
if (PyErr_Occurred()) PyErr_Print();
|
||||||
|
|
||||||
#define sendtogpu { FontCellMetrics scaled = fg->fcm; current_send_sprite_to_gpu((FONTS_DATA_HANDLE)fg, sp[i]->x, sp[i]->y, sp[i]->z, b); fg->fcm = scaled; }
|
#define sendtogpu { \
|
||||||
|
sp[i]->rendered = true; sp[i]->colored = was_colored; \
|
||||||
|
current_send_sprite_to_gpu((FONTS_DATA_HANDLE)fg, sp[i]->x, sp[i]->y, sp[i]->z, b); \
|
||||||
|
}
|
||||||
|
|
||||||
|
fg->fcm = unscaled_metrics; // needed for current_send_sprite_to_gpu()
|
||||||
|
|
||||||
if (scale == 1.f && rf.scale == 1 && !rf.subscale_n) {
|
if (scale == 1.f && rf.scale == 1 && !rf.subscale_n) {
|
||||||
for (unsigned i = 0; i < num_cells; i++) {
|
for (unsigned i = 0; i < num_cells; i++) {
|
||||||
if (!sp[i]->rendered) {
|
if (!sp[i]->rendered) {
|
||||||
sp[i]->rendered = true;
|
|
||||||
sp[i]->colored = was_colored;
|
|
||||||
pixel *b = num_cells == 1 ? fg->canvas.buf : extract_cell_from_canvas(fg, i, num_cells);
|
pixel *b = num_cells == 1 ? fg->canvas.buf : extract_cell_from_canvas(fg, i, num_cells);
|
||||||
sendtogpu;
|
sendtogpu;
|
||||||
}
|
}
|
||||||
set_cell_sprite(gpu_cells + i, sp[i]);
|
set_cell_sprite(gpu_cells + i, sp[i]);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
Region src={.bottom=fg->fcm.cell_height, .right=fg->fcm.cell_width * num_cells}, dest={0};
|
Region src={.bottom=scaled_metrics.cell_height, .right=scaled_metrics.cell_width * num_scaled_cells}, dest={0};
|
||||||
calculate_regions_for_line(rf, unscaled_metrics.cell_height, &src, &dest);
|
calculate_regions_for_line(rf, unscaled_metrics.cell_height, &src, &dest);
|
||||||
for (unsigned i = 0; i < num_cells; i++) {
|
for (unsigned i = 0; i < num_cells; i++) {
|
||||||
if (!sp[i]->rendered) {
|
if (!sp[i]->rendered) {
|
||||||
pixel *b = extract_scaled_cell_from_canvas(&fg->canvas, i, num_cells, src, dest, unscaled_metrics.cell_width, unscaled_metrics.cell_height, fg->fcm.cell_width, fg->fcm.cell_height);
|
pixel *b = extract_scaled_cell_from_canvas(
|
||||||
|
&fg->canvas, i, src, dest, unscaled_metrics.cell_width, unscaled_metrics.cell_height, scaled_metrics.cell_height);
|
||||||
sendtogpu;
|
sendtogpu;
|
||||||
}
|
}
|
||||||
set_cell_sprite(gpu_cells + i, sp[i]);
|
set_cell_sprite(gpu_cells + i, sp[i]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fg->fcm = scaled_metrics;
|
||||||
#undef sp
|
#undef sp
|
||||||
|
#undef sendtogpu
|
||||||
}
|
}
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
@@ -1056,7 +1079,7 @@ shape(CPUCell *first_cpu_cell, GPUCell *first_gpu_cell, index_type num_cells, hb
|
|||||||
group_state.first_gpu_cell = first_gpu_cell;
|
group_state.first_gpu_cell = first_gpu_cell;
|
||||||
group_state.last_cpu_cell = first_cpu_cell + (num_cells ? num_cells - 1 : 0);
|
group_state.last_cpu_cell = first_cpu_cell + (num_cells ? num_cells - 1 : 0);
|
||||||
group_state.last_gpu_cell = first_gpu_cell + (num_cells ? num_cells - 1 : 0);
|
group_state.last_gpu_cell = first_gpu_cell + (num_cells ? num_cells - 1 : 0);
|
||||||
load_hb_buffer(first_cpu_cell, first_gpu_cell, num_cells, tc);
|
load_hb_buffer(first_cpu_cell, first_gpu_cell, num_cells, tc, &lc);
|
||||||
|
|
||||||
size_t num_features = fobj->num_ffs_hb_features;
|
size_t num_features = fobj->num_ffs_hb_features;
|
||||||
if (num_features && !disable_ligature) num_features--; // the last feature is always -calt
|
if (num_features && !disable_ligature) num_features--; // the last feature is always -calt
|
||||||
@@ -1455,7 +1478,7 @@ split_run_at_offset(index_type cursor_offset, index_type *left, index_type *righ
|
|||||||
static void
|
static void
|
||||||
render_groups(FontGroup *fg, RunFont rf, bool center_glyph, const TextCache *tc) {
|
render_groups(FontGroup *fg, RunFont rf, bool center_glyph, const TextCache *tc) {
|
||||||
unsigned idx = 0;
|
unsigned idx = 0;
|
||||||
FontCellMetrics unscaled_metrics = fg->fcm;
|
const FontCellMetrics unscaled_metrics = fg->fcm;
|
||||||
float scale = apply_scale_to_font_group(fg, &rf);
|
float scale = apply_scale_to_font_group(fg, &rf);
|
||||||
if (scale != 1.f) if (!face_apply_scaling(fg->fonts[rf.font_idx].face, (FONTS_DATA_HANDLE)fg) && PyErr_Occurred()) PyErr_Print();
|
if (scale != 1.f) if (!face_apply_scaling(fg->fonts[rf.font_idx].face, (FONTS_DATA_HANDLE)fg) && PyErr_Occurred()) PyErr_Print();
|
||||||
while (idx <= G(group_idx)) {
|
while (idx <= G(group_idx)) {
|
||||||
@@ -2088,6 +2111,12 @@ pyspecialize_font_descriptor(PyObject *self UNUSED, PyObject *args) {
|
|||||||
return specialize_font_descriptor(desc, font_sz, dpi_x, dpi_y);
|
return specialize_font_descriptor(desc, font_sz, dpi_x, dpi_y);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static PyObject*
|
||||||
|
set_allow_use_of_box_fonts(PyObject *self UNUSED, PyObject *val) {
|
||||||
|
allow_use_of_box_fonts = PyObject_IsTrue(val);
|
||||||
|
Py_RETURN_NONE;
|
||||||
|
}
|
||||||
|
|
||||||
static PyMethodDef module_methods[] = {
|
static PyMethodDef module_methods[] = {
|
||||||
METHODB(set_font_data, METH_VARARGS),
|
METHODB(set_font_data, METH_VARARGS),
|
||||||
METHODB(free_font_data, METH_NOARGS),
|
METHODB(free_font_data, METH_NOARGS),
|
||||||
@@ -2096,6 +2125,7 @@ static PyMethodDef module_methods[] = {
|
|||||||
METHODB(test_sprite_position_for, METH_VARARGS),
|
METHODB(test_sprite_position_for, METH_VARARGS),
|
||||||
METHODB(concat_cells, METH_VARARGS),
|
METHODB(concat_cells, METH_VARARGS),
|
||||||
METHODB(set_send_sprite_to_gpu, METH_O),
|
METHODB(set_send_sprite_to_gpu, METH_O),
|
||||||
|
METHODB(set_allow_use_of_box_fonts, METH_O),
|
||||||
METHODB(test_shape, METH_VARARGS),
|
METHODB(test_shape, METH_VARARGS),
|
||||||
METHODB(current_fonts, METH_VARARGS),
|
METHODB(current_fonts, METH_VARARGS),
|
||||||
METHODB(test_render_line, METH_VARARGS),
|
METHODB(test_render_line, METH_VARARGS),
|
||||||
|
|||||||
@@ -13,6 +13,7 @@ from kitty.fast_data_types import (
|
|||||||
DECAWM,
|
DECAWM,
|
||||||
ParsedFontFeature,
|
ParsedFontFeature,
|
||||||
get_fallback_font,
|
get_fallback_font,
|
||||||
|
set_allow_use_of_box_fonts,
|
||||||
sprite_map_set_layout,
|
sprite_map_set_layout,
|
||||||
sprite_map_set_limits,
|
sprite_map_set_limits,
|
||||||
test_render_line,
|
test_render_line,
|
||||||
@@ -216,7 +217,7 @@ def block_helpers(s, sprites, cell_width, cell_height):
|
|||||||
if a != b:
|
if a != b:
|
||||||
msg = msg or 'block not equal'
|
msg = msg or 'block not equal'
|
||||||
if len(a) != len(b):
|
if len(a) != len(b):
|
||||||
assert_blocks.__msg = msg + f'block lengths not equal: {len(a)/4} != {len(b)/4}'
|
assert_blocks.__msg = msg + f' block lengths not equal: {len(a)/4} != {len(b)/4}'
|
||||||
else:
|
else:
|
||||||
assert_blocks.__msg = msg + '\n' + block_as_str(a) + '\n\n' + block_as_str(b)
|
assert_blocks.__msg = msg + '\n' + block_as_str(a) + '\n\n' + block_as_str(b)
|
||||||
del a, b
|
del a, b
|
||||||
@@ -297,6 +298,16 @@ class Rendering(FontBaseTest):
|
|||||||
self.assertEqual(len(self.sprites) - prerendered, len(box_chars))
|
self.assertEqual(len(self.sprites) - prerendered, len(box_chars))
|
||||||
|
|
||||||
def test_scaled_box_drawing(self):
|
def test_scaled_box_drawing(self):
|
||||||
|
self.scaled_drawing_test()
|
||||||
|
|
||||||
|
def test_scaled_font_drawing(self):
|
||||||
|
set_allow_use_of_box_fonts(False)
|
||||||
|
try:
|
||||||
|
self.scaled_drawing_test()
|
||||||
|
finally:
|
||||||
|
set_allow_use_of_box_fonts(True)
|
||||||
|
|
||||||
|
def scaled_drawing_test(self):
|
||||||
s = self.create_screen(cols=8, lines=8, scrollback=0)
|
s = self.create_screen(cols=8, lines=8, scrollback=0)
|
||||||
full_block, empty_block, upper_half_block, lower_half_block, quarter_block, block_as_str, block_test = block_helpers(
|
full_block, empty_block, upper_half_block, lower_half_block, quarter_block, block_as_str, block_test = block_helpers(
|
||||||
s, self.sprites, self.cell_width, self.cell_height)
|
s, self.sprites, self.cell_width, self.cell_height)
|
||||||
|
|||||||
Reference in New Issue
Block a user