box-drawing: add braille characters

Render braille ourselves, instead of using font glyphs. Decoding a
braille character is easy enough; there are 256 codepoints,
represented by an 8-bit integer (i.e. subtract the Unicode codepoint
offset, 0x2800, and you’re left with an integer in the range 0-255).

Each bit corresponds to a dot. The first 6 bits represent the upper 6
dots, while the two last bits represent the fourth (and last) row of
dots.

The hard part is sizing the dots and the spacing between them.

The aim is to have the spacing between the dots be the same size as
the dots themselves, and to have the margins on each side be half the
size of the dots.

In a perfectly sized cell, this means two braille characters next to
each other will be evenly spaced.

This is however almost never the case. The layout logic currently:

* Set dot size to either the width / 4, or height / 8, depending on
  which one is smallest.

* Horizontal spacing is initialized to the width / 4

* Vertical spacing is initialized to the height / 8

* Horizontal margins are initialized to the horizontal spacing / 2

* Vertical margins are initialized to the vertical spacing / 2.

Next, we calculate the number of “remaining” pixels. That is, if we
add the left margin, two dots and the spacing between, how many pixels
are left on the horizontal axis?

These pixels are distributed in the following order (we “stop” as soon
as we run out of pixels):

* If the dot size is 0 (happens for very small font sizes), increase
  it to 1.
* If the margins are 0, increase them to 1.
* If we have enough pixels (need at 2 horizontal and 4 vertical),
  increase the dot size.
* Increase spacing.
* Increase margins.

Closes #702
This commit is contained in:
Daniel Eklöf 2021-09-02 14:55:26 +02:00
parent f9d968b4c7
commit b4c759e2de
No known key found for this signature in database
GPG key ID: 5BBD4992C116573F
4 changed files with 105 additions and 7 deletions

View file

@ -515,6 +515,9 @@ render_cell(struct terminal *term, pixman_image_t *pix,
/* Classic box drawings */
(base >= 0x2500 && base <= 0x259f) ||
/* Braille */
(base >= 0x2800 && base <= 0x28ff) ||
/*
* Unicode 13 "Symbols for Legacy Computing"
* sub-ranges below.
@ -531,9 +534,12 @@ render_cell(struct terminal *term, pixman_image_t *pix,
/* Box drawing characters */
size_t idx = base >= 0x1fb00
? (base >= 0x1fb9a
? base - 0x1fb9a + 300
: base - 0x1fb00 + 160)
: base - 0x2500;
? base - 0x1fb9a + 556
: base - 0x1fb00 + 416)
: (base >= 0x2800
? base - 0x2800 + 160
: base - 0x2500);
xassert(idx < ALEN(term->box_drawing));
if (likely(term->box_drawing[idx] != NULL))
@ -541,7 +547,8 @@ render_cell(struct terminal *term, pixman_image_t *pix,
else {
mtx_lock(&term->render.workers.lock);
/* Parallel thread may have instantiated it while we took the lock */
/* Other thread may have instantiated it while we
* aquired the lock */
if (term->box_drawing[idx] == NULL)
term->box_drawing[idx] = box_drawing(term, base);
mtx_unlock(&term->render.workers.lock);