Merge branch 'clip-to-cell'

This commit is contained in:
Daniel Eklöf 2020-06-03 19:24:44 +02:00
commit 0d0df56796
No known key found for this signature in database
GPG key ID: 5BBD4992C116573F
2 changed files with 43 additions and 37 deletions

View file

@ -50,6 +50,9 @@
* Draw hollow block cursor on top of character.
* Set an initial `TIOCSWINSZ`. This ensures clients never reads a
`0x0` terminal size (https://codeberg.org/dnkl/foot/issues/20).
* Glyphs overflowing into surrounding cells
(https://codeberg.org/dnkl/foot/issues/21).
### Security

View file

@ -437,39 +437,57 @@ render_cell(struct terminal *term, pixman_image_t *pix,
pixman_image_t *clr_pix = pixman_image_create_solid_fill(&fg);
if (glyph != NULL) {
/*
* Clip to cell.
*
* What we'd really like to do here is use normal destination
* clipping on the pixman image. Unfortunately, that's not
* possible since we have multiple threads accessing the same
* pixman image.
*
* Instead, manually adjust the destination offsets and
* width/heights.
*/
int glyph_x = max(x + glyph->x, x);
int mask_x = max(0, -glyph->x);
int glyph_w = min(glyph->width, glyph->cols * term->cell_width);
int glyph_y = max(y + font_baseline(term) - glyph->y, y);
int mask_y = max(0, -font_baseline(term) + glyph->y);
int glyph_h = min(glyph->height, term->cell_height);
if (unlikely(pixman_image_get_format(glyph->pix) == PIXMAN_a8r8g8b8)) {
/* Glyph surface is a pre-rendered image (typically a color emoji...) */
if (!(cell->attrs.blink && term->blink.state == BLINK_OFF)) {
pixman_image_composite32(
PIXMAN_OP_OVER, glyph->pix, NULL, pix, 0, 0, 0, 0,
x + glyph->x, y + font_baseline(term) - glyph->y,
glyph->width, glyph->height);
glyph_x, glyph_y, glyph_w, glyph_h);
}
} else {
/* Glyph surface is an alpha mask */
pixman_image_composite32(
PIXMAN_OP_OVER, clr_pix, glyph->pix, pix, 0, 0, 0, 0,
x + glyph->x, y + font_baseline(term) - glyph->y,
glyph->width, glyph->height);
}
}
PIXMAN_OP_OVER, clr_pix, glyph->pix, pix, 0, 0,
mask_x, mask_y, glyph_x, glyph_y, glyph_w, glyph_h);
/* Combining characters */
if (composed != NULL) {
for (size_t i = 0; i < composed->count; i++) {
const struct fcft_glyph *g = fcft_glyph_rasterize(
font, composed->combining[i], term->font_subpixel);
/* Combining characters */
if (composed != NULL) {
for (size_t i = 0; i < composed->count; i++) {
const struct fcft_glyph *g = fcft_glyph_rasterize(
font, composed->combining[i], term->font_subpixel);
if (g == NULL)
continue;
if (g == NULL)
continue;
pixman_image_composite32(
PIXMAN_OP_OVER, clr_pix, g->pix, pix, 0, 0, 0, 0,
/* Some fonts use a negative offset, while others use a
* "normal" offset */
x + (g->x < 0 ? term->cell_width : 0) + g->x,
y + font_baseline(term) - g->y,
g->width, g->height);
/* TODO: clip to cell */
pixman_image_composite32(
PIXMAN_OP_OVER, clr_pix, g->pix, pix, 0, 0, 0, 0,
/* Some fonts use a negative offset, while others use a
* "normal" offset */
x + (g->x < 0 ? term->cell_width : 0) + g->x,
y + font_baseline(term) - g->y,
g->width, g->height);
}
}
}
}
@ -622,7 +640,6 @@ grid_render_scroll(struct terminal *term, struct buffer *buf,
}
if (did_shm_scroll) {
/* Restore margins */
render_margin(
term, buf, dmg->region.end - dmg->lines, term->rows,
@ -1259,8 +1276,6 @@ grid_render(struct terminal *term)
struct buffer *buf = shm_get_buffer(
term->wl->shm, term->width, term->height, cookie, true);
pixman_image_set_clip_region(buf->pix, NULL);
/* If we resized the window, or is flashing, or just stopped flashing */
if (term->render.last_buf != buf ||
term->flash.active || term->render.was_flashing ||
@ -1297,14 +1312,6 @@ grid_render(struct terminal *term)
term->render.was_searching = term->is_searching;
}
/* Set clip region to prevent cells from overflowing into the margins */
pixman_region16_t clip;
pixman_region_init_rect(
&clip,
term->margins.left, term->margins.top,
term->cols * term->cell_width, term->rows * term->cell_height);
pixman_image_set_clip_region(buf->pix, &clip);
/* Erase old cursor (if we rendered a cursor last time) */
if (term->render.last_cursor.row != NULL) {
@ -1351,9 +1358,6 @@ grid_render(struct terminal *term)
tll_remove(term->grid->scroll_damage, it);
}
/* Reset clip region since scrolling may have instantiated a new pixman image */
pixman_image_set_clip_region(buf->pix, &clip);
/*
* Ensure selected cells have their 'selected' bit set. This is
* normally "automatically" true - the bit is set when the
@ -1480,7 +1484,6 @@ grid_render(struct terminal *term)
if (term->flash.active) {
/* Note: alpha is pre-computed in each color component */
/* TODO: dim while searching */
pixman_image_set_clip_region(buf->pix, NULL);
pixman_image_fill_rectangles(
PIXMAN_OP_OVER, buf->pix,
&(pixman_color_t){.red=0x7fff, .green=0x7fff, .blue=0, .alpha=0x7fff},