Only call render_menu once per frame

An actual surface is not needed to estimate font sizes; a 1x1 image
will do, as long as the cairo context has the same options.
This commit is contained in:
M Stoeckl 2024-10-31 10:27:47 -04:00
parent 12b8f83be4
commit 94beb524d2
3 changed files with 16 additions and 3 deletions

5
menu.c
View file

@ -33,6 +33,8 @@ struct menu *menu_create(menu_callback callback) {
menu->selectionbg = 0x005577ff;
menu->selectionfg = 0xeeeeeeff;
menu->callback = callback;
menu->test_surface = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, 1, 1);
menu->test_cairo = cairo_create(menu->test_surface);
return menu;
}
@ -63,6 +65,8 @@ static void free_items(struct menu *menu) {
void menu_destroy(struct menu *menu) {
free_pages(menu);
free_items(menu);
cairo_destroy(menu->test_cairo);
cairo_surface_destroy(menu->test_surface);
free(menu);
}
@ -368,7 +372,6 @@ static void match_items(struct menu *menu) {
// Render menu items.
void menu_render_items(struct menu *menu) {
render_menu(menu);
calc_widths(menu);
match_items(menu);
render_menu(menu);

5
menu.h
View file

@ -1,6 +1,7 @@
#ifndef WMENU_MENU_H
#define WMENU_MENU_H
#include <cairo/cairo.h>
#include <stdbool.h>
#include <sys/types.h>
#include <xkbcommon/xkbcommon.h>
@ -52,6 +53,10 @@ struct menu {
struct wl_context *context;
// 1x1 surface used estimate text sizes with pango
cairo_surface_t *test_surface;
cairo_t *test_cairo;
int width;
int height;
int line_height;

View file

@ -13,8 +13,13 @@
// Calculate text widths.
void calc_widths(struct menu *menu) {
struct wl_context *context = menu->context;
struct pool_buffer *current = context_get_current_buffer(context);
cairo_t *cairo = current->cairo;
int scale = context_get_scale(context);
cairo_surface_set_device_scale(menu->test_surface, scale, scale);
cairo_set_antialias(menu->test_cairo, CAIRO_ANTIALIAS_BEST);
cairo_font_options_t *fo = cairo_font_options_create();
cairo_set_font_options(menu->test_cairo, fo);
cairo_font_options_destroy(fo);
cairo_t *cairo = menu->test_cairo;
// Calculate prompt width
if (menu->prompt) {