From 7067c57399177c0559658086cbf7997fe3b8057a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Ekl=C3=B6f?= Date: Thu, 22 Jul 2021 19:22:52 +0200 Subject: [PATCH] render: render_osd(): set clip region, use background alpha MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Set clip region in render_osd(). This ensures we don’t step outside the pixman buffer when rendering the glyphs. Furthermore, don’t ignore the alpha channel in the background color. Move render_osd() to make it visible to the render_csd_*() functions. --- render.c | 114 +++++++++++++++++++++++++++++-------------------------- 1 file changed, 61 insertions(+), 53 deletions(-) diff --git a/render.c b/render.c index f4ebc086..94651c11 100644 --- a/render.c +++ b/render.c @@ -1576,6 +1576,67 @@ render_csd_part(struct terminal *term, pixman_image_unref(src); } +static void +render_osd(struct terminal *term, + struct wl_surface *surf, struct wl_subsurface *sub_surf, + struct buffer *buf, + const wchar_t *text, uint32_t _fg, uint32_t _bg, + unsigned x, unsigned y) +{ + pixman_region32_t clip; + pixman_region32_init_rect(&clip, 0, 0, buf->width, buf->height); + pixman_image_set_clip_region32(buf->pix[0], &clip); + pixman_region32_fini(&clip); + + uint16_t alpha = _bg >> 24 | (_bg >> 24 << 8); + pixman_color_t bg = color_hex_to_pixman_with_alpha(_bg, alpha); + pixman_image_fill_rectangles( + PIXMAN_OP_SRC, buf->pix[0], &bg, 1, + &(pixman_rectangle16_t){0, 0, buf->width, buf->height}); + + struct fcft_font *font = term->fonts[0]; + pixman_color_t fg = color_hex_to_pixman(_fg); + + const int x_ofs = term->font_x_ofs; + + for (size_t i = 0; i < wcslen(text); i++) { + const struct fcft_glyph *glyph = fcft_glyph_rasterize( + font, text[i], term->font_subpixel); + + if (glyph == NULL) + continue; + + pixman_image_t *src = pixman_image_create_solid_fill(&fg); + pixman_image_composite32( + PIXMAN_OP_OVER, src, glyph->pix, buf->pix[0], 0, 0, 0, 0, + x + x_ofs + glyph->x, y + font_baseline(term) - glyph->y, + glyph->width, glyph->height); + pixman_image_unref(src); + + x += term->cell_width; + } + + pixman_image_set_clip_region32(buf->pix[0], NULL); + + xassert(buf->width % term->scale == 0); + xassert(buf->height % term->scale == 0); + + quirk_weston_subsurface_desync_on(sub_surf); + wl_surface_attach(surf, buf->wl_buf, 0, 0); + wl_surface_damage_buffer(surf, 0, 0, buf->width, buf->height); + wl_surface_set_buffer_scale(surf, term->scale); + + struct wl_region *region = wl_compositor_create_region(term->wl->compositor); + if (region != NULL) { + wl_region_add(region, 0, 0, buf->width, buf->height); + wl_surface_set_opaque_region(surf, region); + wl_region_destroy(region); + } + + wl_surface_commit(surf); + quirk_weston_subsurface_desync_off(sub_surf); +} + static void render_csd_title(struct terminal *term, const struct csd_data *info, struct buffer *buf) @@ -1913,59 +1974,6 @@ render_csd(struct terminal *term) render_csd_title(term, &infos[CSD_SURF_TITLE], bufs[CSD_SURF_TITLE]); } -static void -render_osd(struct terminal *term, - struct wl_surface *surf, struct wl_subsurface *sub_surf, - struct buffer *buf, - const wchar_t *text, uint32_t _fg, uint32_t _bg, - unsigned x, unsigned y) -{ - pixman_color_t bg = color_hex_to_pixman(_bg); - pixman_image_fill_rectangles( - PIXMAN_OP_SRC, buf->pix[0], &bg, 1, - &(pixman_rectangle16_t){0, 0, buf->width, buf->height}); - - struct fcft_font *font = term->fonts[0]; - pixman_color_t fg = color_hex_to_pixman(_fg); - - const int x_ofs = term->font_x_ofs; - - for (size_t i = 0; i < wcslen(text); i++) { - const struct fcft_glyph *glyph = fcft_glyph_rasterize( - font, text[i], term->font_subpixel); - - if (glyph == NULL) - continue; - - pixman_image_t *src = pixman_image_create_solid_fill(&fg); - pixman_image_composite32( - PIXMAN_OP_OVER, src, glyph->pix, buf->pix[0], 0, 0, 0, 0, - x + x_ofs + glyph->x, y + font_baseline(term) - glyph->y, - glyph->width, glyph->height); - pixman_image_unref(src); - - x += term->cell_width; - } - - xassert(buf->width % term->scale == 0); - xassert(buf->height % term->scale == 0); - - quirk_weston_subsurface_desync_on(sub_surf); - wl_surface_attach(surf, buf->wl_buf, 0, 0); - wl_surface_damage_buffer(surf, 0, 0, buf->width, buf->height); - wl_surface_set_buffer_scale(surf, term->scale); - - struct wl_region *region = wl_compositor_create_region(term->wl->compositor); - if (region != NULL) { - wl_region_add(region, 0, 0, buf->width, buf->height); - wl_surface_set_opaque_region(surf, region); - wl_region_destroy(region); - } - - wl_surface_commit(surf); - quirk_weston_subsurface_desync_off(sub_surf); -} - static void render_scrollback_position(struct terminal *term) {