mirror of
https://codeberg.org/dnkl/foot.git
synced 2026-02-05 04:06:08 -05:00
render: underlines: improve the appearance of the 'dotted' style
Try to make the 'dotted' style appear more even, and less like each cell is rendered separately (even though they are). Algorithm: Each dot is a square; it's sides are that of the font's line thickness. The spacing (gaps) between the dots is initially the same width as the dots themselves. This means the number of dots per cell is the cell width divided by the dots' length/width, divided by two. At this point, there may be "left-over" pixels.I.e. the widths of the dots and the gaps between them may not add up to the width of the cell. These pixels are evenly (as possible) across the gaps. There are still visual inaccuracies at small font sizes. This is impossible to fix without changing the way underlines are rendered, to render an entire line in one go. This is not something we want to do, since it'll make styled underlines, for a specific cell/character, look differently, depending on the surrounding context.
This commit is contained in:
parent
0d3f2f27e3
commit
19bf558e6c
1 changed files with 33 additions and 7 deletions
40
render.c
40
render.c
|
|
@ -432,17 +432,43 @@ draw_styled_underline(const struct terminal *term, pixman_image_t *pix,
|
|||
PIXMAN_OP_SRC, pix, color, 2, rects);
|
||||
break;
|
||||
}
|
||||
case CURLY_DOTTED: {
|
||||
const int ceil_w = cols * term->cell_width;
|
||||
const int nrects = min(ceil_w / thickness / 2, 16);
|
||||
pixman_rectangle16_t rects[16] = {0};
|
||||
|
||||
for (int i = 0; i < nrects; i++) {
|
||||
case CURLY_DOTTED: {
|
||||
/* Number of dots per cell */
|
||||
int per_cell = (term->cell_width / thickness) / 2;
|
||||
if (per_cell == 0)
|
||||
per_cell = 1;
|
||||
|
||||
xassert(per_cell >= 1);
|
||||
|
||||
/* Spacing between dots; start with the same width as the dots
|
||||
themselves, then widen them if necessary, to consume unused
|
||||
pixels */
|
||||
int spacing[per_cell];
|
||||
for (int i = 0; i < per_cell; i++)
|
||||
spacing[i] = thickness;
|
||||
|
||||
/* Pixels remaining at the end of the cell */
|
||||
int remaining = term->cell_width - (per_cell * 2) * thickness;
|
||||
|
||||
/* Spread out the left-over pixels across the spacing between
|
||||
the dots */
|
||||
for (int i = 0; remaining > 0; i = (i + 1) % per_cell, remaining--)
|
||||
spacing[i]++;
|
||||
|
||||
xassert(remaining <= 0);
|
||||
|
||||
pixman_rectangle16_t rects[per_cell];
|
||||
int dot_x = x;
|
||||
for (int i = 0; i < per_cell; i++) {
|
||||
rects[i] = (pixman_rectangle16_t){
|
||||
x + i * thickness * 2, y + y_ofs, thickness, thickness};
|
||||
dot_x, y + y_ofs, thickness, thickness
|
||||
};
|
||||
|
||||
dot_x += thickness + spacing[i];
|
||||
}
|
||||
|
||||
pixman_image_fill_rectangles(PIXMAN_OP_SRC, pix, color, nrects, rects);
|
||||
pixman_image_fill_rectangles(PIXMAN_OP_SRC, pix, color, per_cell, rects);
|
||||
break;
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue