mirror of
https://codeberg.org/dnkl/foot.git
synced 2026-02-05 04:06:08 -05:00
commit
f84320b5d6
5 changed files with 185 additions and 39 deletions
|
|
@ -39,6 +39,8 @@
|
|||
* PGO build scripts, in the `pgo` directory. See INSTALL.md -
|
||||
_Performance optimized, PGO_, for details
|
||||
(https://codeberg.org/dnkl/foot/issues/701).
|
||||
* Braille characters (U+2800 - U+28FF) are now rendered by foot
|
||||
itself (https://codeberg.org/dnkl/foot/issues/702).
|
||||
|
||||
|
||||
### Changed
|
||||
|
|
|
|||
|
|
@ -1953,6 +1953,95 @@ draw_quadrant(struct buf *buf, wchar_t wc)
|
|||
quad_lower_right(buf);
|
||||
}
|
||||
|
||||
static void NOINLINE
|
||||
draw_braille(struct buf *buf, wchar_t wc)
|
||||
{
|
||||
int w = min(buf->width / 4, buf->height / 8);
|
||||
int x_spacing = buf->width / 4;
|
||||
int y_spacing = buf->height / 8;
|
||||
int x_margin = x_spacing / 2;
|
||||
int y_margin = y_spacing / 2;
|
||||
|
||||
int x_px_left = buf->width - 2 * x_margin - x_spacing - 2 * w;
|
||||
int y_px_left = buf->height - 2 * y_margin - 3 * y_spacing - 4 * w;
|
||||
|
||||
LOG_DBG(
|
||||
"braille: before adjusting: "
|
||||
"cell: %dx%d, margin=%dx%d, spacing=%dx%d, width=%d, left=%dx%d",
|
||||
buf->width, buf->height, x_margin, y_margin, x_spacing, y_spacing,
|
||||
w, x_pix_left, y_pix_left);
|
||||
|
||||
/* First, try hard to ensure the DOT width is non-zero */
|
||||
if (x_px_left >= 2 && y_px_left >= 4 && w == 0) {
|
||||
w++;
|
||||
x_px_left -= 2;
|
||||
y_px_left -= 4;
|
||||
}
|
||||
|
||||
/* Second, prefer a non-zero margin */
|
||||
if (x_px_left >= 2 && x_margin == 0) { x_margin = 1; x_px_left -= 2; }
|
||||
if (y_px_left >= 2 && y_margin == 0) { y_margin = 1; y_px_left -= 2; }
|
||||
|
||||
/* Third, increase spacing */
|
||||
if (x_px_left >= 1) { x_spacing++; x_px_left--; }
|
||||
if (y_px_left >= 3) { y_spacing++; y_px_left -= 3; }
|
||||
|
||||
/* Fourth, margins (“spacing”, but on the sides) */
|
||||
if (x_px_left >= 2) { x_margin++; x_px_left -= 2; }
|
||||
if (y_px_left >= 2) { y_margin++; y_px_left -= 2; }
|
||||
|
||||
/* Last - increase dot width */
|
||||
if (x_px_left >= 2 && y_px_left >= 4) {
|
||||
w++;
|
||||
x_px_left -= 2;
|
||||
y_px_left -= 4;
|
||||
}
|
||||
|
||||
LOG_DBG(
|
||||
"braille: after adjusting: "
|
||||
"cell: %dx%d, margin=%dx%d, spacing=%dx%d, width=%d, left=%dx%d",
|
||||
buf->width, buf->height, x_margin, y_margin, x_spacing, y_spacing,
|
||||
w, x_pix_left, y_pix_left);
|
||||
|
||||
xassert(x_px_left <= 1 || y_px_left <= 1);
|
||||
xassert(2 * x_margin + 2 * w + x_spacing <= buf->width);
|
||||
xassert(2 * y_margin + 4 * w + 3 * y_spacing <= buf->height);
|
||||
|
||||
int x[2], y[4];
|
||||
x[0] = x_margin;
|
||||
x[1] = x_margin + w + x_spacing;
|
||||
y[0] = y_margin;
|
||||
y[1] = y[0] + w + y_spacing;
|
||||
y[2] = y[1] + w + y_spacing;
|
||||
y[3] = y[2] + w + y_spacing;
|
||||
|
||||
assert(wc >= 0x2800);
|
||||
assert(wc <= 0x28ff);
|
||||
uint8_t sym = wc - 0x2800;
|
||||
|
||||
/* Left side */
|
||||
if (sym & 1)
|
||||
rect(x[0], y[0], x[0] + w, y[0] + w);
|
||||
if (sym & 2)
|
||||
rect(x[0], y[1], x[0] + w, y[1] + w);
|
||||
if (sym & 4)
|
||||
rect(x[0], y[2], x[0] + w, y[2] + w);
|
||||
|
||||
/* Right side */
|
||||
if (sym & 8)
|
||||
rect(x[1], y[0], x[1] + w, y[0] + w);
|
||||
if (sym & 16)
|
||||
rect(x[1], y[1], x[1] + w, y[1] + w);
|
||||
if (sym & 32)
|
||||
rect(x[1], y[2], x[1] + w, y[2] + w);
|
||||
|
||||
/* 8-dot patterns */
|
||||
if (sym & 64)
|
||||
rect(x[0], y[3], x[0] + w, y[3] + w);
|
||||
if (sym & 128)
|
||||
rect(x[1], y[3], x[1] + w, y[3] + w);
|
||||
}
|
||||
|
||||
static void
|
||||
sextant_upper_left(struct buf *buf)
|
||||
{
|
||||
|
|
@ -2653,6 +2742,8 @@ draw_glyph(struct buf *buf, wchar_t wc)
|
|||
case 0x2595: draw_right_one_eighth_block(buf); break;
|
||||
case 0x2596 ... 0x259f: draw_quadrant(buf, wc); break;
|
||||
|
||||
case 0x2800 ... 0x28ff: draw_braille(buf, wc); break;
|
||||
|
||||
case 0x1fb00 ... 0x1fb3b: draw_sextant(buf, wc); break;
|
||||
|
||||
case 0x1fb3c ... 0x1fb40:
|
||||
|
|
|
|||
63
render.c
63
render.c
|
|
@ -513,7 +513,12 @@ render_cell(struct terminal *term, pixman_image_t *pix,
|
|||
if (base != 0) {
|
||||
if (unlikely(
|
||||
/* Classic box drawings */
|
||||
(base >= 0x2500 && base <= 0x259f) ||
|
||||
(base >= GLYPH_BOX_DRAWING_FIRST &&
|
||||
base <= GLYPH_BOX_DRAWING_LAST) ||
|
||||
|
||||
/* Braille */
|
||||
(base >= GLYPH_BRAILLE_FIRST &&
|
||||
base <= GLYPH_BRAILLE_LAST) ||
|
||||
|
||||
/*
|
||||
* Unicode 13 "Symbols for Legacy Computing"
|
||||
|
|
@ -521,38 +526,50 @@ render_cell(struct terminal *term, pixman_image_t *pix,
|
|||
*
|
||||
* Note, the full range is U+1FB00 - U+1FBF9
|
||||
*/
|
||||
|
||||
/* Unicode 13 sextants */
|
||||
(base >= 0x1fb00 && base <= 0x1fb8b) ||
|
||||
(base >= 0x1fb9a && base <= 0x1fb9b)) &&
|
||||
(base >= GLYPH_LEGACY_FIRST &&
|
||||
base <= GLYPH_LEGACY_LAST)) &&
|
||||
|
||||
likely(!term->conf->box_drawings_uses_font_glyphs))
|
||||
{
|
||||
/* Box drawing characters */
|
||||
size_t idx = base >= 0x1fb00
|
||||
? (base >= 0x1fb9a
|
||||
? base - 0x1fb9a + 300
|
||||
: base - 0x1fb00 + 160)
|
||||
: base - 0x2500;
|
||||
xassert(idx < ALEN(term->box_drawing));
|
||||
struct fcft_glyph ***arr;
|
||||
size_t count;
|
||||
size_t idx;
|
||||
|
||||
if (likely(term->box_drawing[idx] != NULL))
|
||||
single = term->box_drawing[idx];
|
||||
if (base >= GLYPH_LEGACY_FIRST) {
|
||||
arr = &term->custom_glyphs.legacy;
|
||||
count = GLYPH_LEGACY_COUNT;
|
||||
idx = base - GLYPH_LEGACY_FIRST;
|
||||
} else if (base >= GLYPH_BRAILLE_FIRST) {
|
||||
arr = &term->custom_glyphs.braille;
|
||||
count = GLYPH_BRAILLE_COUNT;
|
||||
idx = base - GLYPH_BRAILLE_FIRST;
|
||||
} else {
|
||||
arr = &term->custom_glyphs.box_drawing;
|
||||
count = GLYPH_BOX_DRAWING_COUNT;
|
||||
idx = base - GLYPH_BOX_DRAWING_FIRST;
|
||||
}
|
||||
|
||||
if (unlikely(*arr == NULL))
|
||||
*arr = xcalloc(count, sizeof((*arr)[0]));
|
||||
|
||||
if (likely((*arr)[idx] != NULL))
|
||||
single = (*arr)[idx];
|
||||
else {
|
||||
mtx_lock(&term->render.workers.lock);
|
||||
|
||||
/* Parallel thread may have instantiated it while we took the lock */
|
||||
if (term->box_drawing[idx] == NULL)
|
||||
term->box_drawing[idx] = box_drawing(term, base);
|
||||
/* Other thread may have instantiated it while we
|
||||
* acquired the lock */
|
||||
single = (*arr)[idx];
|
||||
if (likely(single == NULL))
|
||||
single = (*arr)[idx] = box_drawing(term, base);
|
||||
mtx_unlock(&term->render.workers.lock);
|
||||
|
||||
single = term->box_drawing[idx];
|
||||
xassert(single != NULL);
|
||||
}
|
||||
|
||||
glyph_count = 1;
|
||||
glyphs = &single;
|
||||
cell_cols = single->cols;
|
||||
if (single != NULL) {
|
||||
glyph_count = 1;
|
||||
glyphs = &single;
|
||||
cell_cols = single->cols;
|
||||
}
|
||||
}
|
||||
|
||||
else if (base >= CELL_COMB_CHARS_LO && base <= CELL_COMB_CHARS_HI)
|
||||
|
|
|
|||
42
terminal.c
42
terminal.c
|
|
@ -626,15 +626,28 @@ err_sem_destroy:
|
|||
}
|
||||
|
||||
static void
|
||||
free_box_drawing(struct fcft_glyph **box_drawing)
|
||||
free_custom_glyph(struct fcft_glyph **glyph)
|
||||
{
|
||||
if (*box_drawing == NULL)
|
||||
if (*glyph == NULL)
|
||||
return;
|
||||
|
||||
free(pixman_image_get_data((*box_drawing)->pix));
|
||||
pixman_image_unref((*box_drawing)->pix);
|
||||
free(*box_drawing);
|
||||
*box_drawing = NULL;
|
||||
free(pixman_image_get_data((*glyph)->pix));
|
||||
pixman_image_unref((*glyph)->pix);
|
||||
free(*glyph);
|
||||
*glyph = NULL;
|
||||
}
|
||||
|
||||
static void
|
||||
free_custom_glyphs(struct fcft_glyph ***glyphs, size_t count)
|
||||
{
|
||||
if (*glyphs == NULL)
|
||||
return;
|
||||
|
||||
for (size_t i = 0; i < count; i++)
|
||||
free_custom_glyph(&(*glyphs)[i]);
|
||||
|
||||
free(*glyphs);
|
||||
*glyphs = NULL;
|
||||
}
|
||||
|
||||
static bool
|
||||
|
|
@ -647,8 +660,12 @@ term_set_fonts(struct terminal *term, struct fcft_font *fonts[static 4])
|
|||
term->fonts[i] = fonts[i];
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < ALEN(term->box_drawing); i++)
|
||||
free_box_drawing(&term->box_drawing[i]);
|
||||
free_custom_glyphs(
|
||||
&term->custom_glyphs.box_drawing, GLYPH_BOX_DRAWING_COUNT);
|
||||
free_custom_glyphs(
|
||||
&term->custom_glyphs.braille, GLYPH_BRAILLE_COUNT);
|
||||
free_custom_glyphs(
|
||||
&term->custom_glyphs.legacy, GLYPH_LEGACY_COUNT);
|
||||
|
||||
const int old_cell_width = term->cell_width;
|
||||
const int old_cell_height = term->cell_height;
|
||||
|
|
@ -1590,8 +1607,13 @@ term_destroy(struct terminal *term)
|
|||
for (size_t i = 0; i < 4; i++)
|
||||
free(term->font_sizes[i]);
|
||||
|
||||
for (size_t i = 0; i < ALEN(term->box_drawing); i++)
|
||||
free_box_drawing(&term->box_drawing[i]);
|
||||
|
||||
free_custom_glyphs(
|
||||
&term->custom_glyphs.box_drawing, GLYPH_BOX_DRAWING_COUNT);
|
||||
free_custom_glyphs(
|
||||
&term->custom_glyphs.braille, GLYPH_BRAILLE_COUNT);
|
||||
free_custom_glyphs(
|
||||
&term->custom_glyphs.legacy, GLYPH_LEGACY_COUNT);
|
||||
|
||||
free(term->search.buf);
|
||||
|
||||
|
|
|
|||
26
terminal.h
26
terminal.h
|
|
@ -333,12 +333,26 @@ struct terminal {
|
|||
int16_t font_y_ofs;
|
||||
enum fcft_subpixel font_subpixel;
|
||||
|
||||
/*
|
||||
* 0-159: U+02500+0259F
|
||||
* 160-299: U+1FB00-1FB8B
|
||||
* 300-301: U+1FB9A-1FB9B
|
||||
*/
|
||||
struct fcft_glyph *box_drawing[302];
|
||||
struct {
|
||||
struct fcft_glyph **box_drawing;
|
||||
struct fcft_glyph **braille;
|
||||
struct fcft_glyph **legacy;
|
||||
|
||||
#define GLYPH_BOX_DRAWING_FIRST 0x2500
|
||||
#define GLYPH_BOX_DRAWING_LAST 0x259F
|
||||
#define GLYPH_BOX_DRAWING_COUNT \
|
||||
(GLYPH_BOX_DRAWING_LAST - GLYPH_BOX_DRAWING_FIRST + 1)
|
||||
|
||||
#define GLYPH_BRAILLE_FIRST 0x2800
|
||||
#define GLYPH_BRAILLE_LAST 0x28FF
|
||||
#define GLYPH_BRAILLE_COUNT \
|
||||
(GLYPH_BRAILLE_LAST - GLYPH_BRAILLE_FIRST + 1)
|
||||
|
||||
#define GLYPH_LEGACY_FIRST 0x1FB00
|
||||
#define GLYPH_LEGACY_LAST 0x1FB9B
|
||||
#define GLYPH_LEGACY_COUNT \
|
||||
(GLYPH_LEGACY_LAST - GLYPH_LEGACY_FIRST + 1)
|
||||
} custom_glyphs;
|
||||
|
||||
bool is_sending_paste_data;
|
||||
ptmx_buffer_list_t ptmx_buffers;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue