From 290c7bc27f2df03b7d826f15b99f29d4e3492c6c Mon Sep 17 00:00:00 2001 From: Guldoman Date: Fri, 21 Jun 2024 01:56:51 +0200 Subject: [PATCH] Update font scale on monitor scale change for `RENDERER` backend (macOS) (#1650) * Update font scale on monitor scale change for `RENDERER` backend (macOS) * fix(renderer): check every font of a fontgroup for scale changes in `update_font_scale` It is needed because fonts can be reused between groups and outside of them. So if the first font of a group has already been scaled, we still need to check if the others still needs to be scaled. --- src/api/renderer.c | 22 ++++++++++++++-------- src/renderer.c | 18 ++++++++++++++++++ src/renderer.h | 3 +++ src/renwindow.c | 9 ++++++--- 4 files changed, 41 insertions(+), 11 deletions(-) diff --git a/src/api/renderer.c b/src/api/renderer.c index 7f66c860..2a57e23a 100644 --- a/src/api/renderer.c +++ b/src/api/renderer.c @@ -98,18 +98,24 @@ static int f_font_load(lua_State *L) { } static bool font_retrieve(lua_State* L, RenFont** fonts, int idx) { + bool is_table; memset(fonts, 0, sizeof(RenFont*)*FONT_FALLBACK_MAX); if (lua_type(L, idx) != LUA_TTABLE) { fonts[0] = *(RenFont**)luaL_checkudata(L, idx, API_TYPE_FONT); - return false; + is_table = false; + } else { + is_table = true; + int len = luaL_len(L, idx); len = len > FONT_FALLBACK_MAX ? FONT_FALLBACK_MAX : len; + for (int i = 0; i < len; i++) { + lua_rawgeti(L, idx, i+1); + fonts[i] = *(RenFont**) luaL_checkudata(L, -1, API_TYPE_FONT); + lua_pop(L, 1); + } } - int len = luaL_len(L, idx); len = len > FONT_FALLBACK_MAX ? FONT_FALLBACK_MAX : len; - for (int i = 0; i < len; i++) { - lua_rawgeti(L, idx, i+1); - fonts[i] = *(RenFont**) luaL_checkudata(L, -1, API_TYPE_FONT); - lua_pop(L, 1); - } - return true; +#ifdef LITE_USE_SDL_RENDERER + update_font_scale(window_renderer, fonts); +#endif + return is_table; } static int f_font_copy(lua_State *L) { diff --git a/src/renderer.c b/src/renderer.c index 65fa8aa6..80b2b057 100644 --- a/src/renderer.c +++ b/src/renderer.c @@ -54,6 +54,9 @@ typedef struct RenFont { FT_StreamRec stream; GlyphSet* sets[SUBPIXEL_BITMAPS_CACHED][MAX_LOADABLE_GLYPHSETS]; float size, space_advance, tab_advance; +#ifdef LITE_USE_SDL_RENDERER + int scale; +#endif unsigned short max_height, baseline, height; ERenFontAntialiasing antialiasing; ERenFontHinting hinting; @@ -62,6 +65,18 @@ typedef struct RenFont { char path[]; } RenFont; +#ifdef LITE_USE_SDL_RENDERER +void update_font_scale(RenWindow *window_renderer, RenFont **fonts) { + const int surface_scale = renwin_get_surface(window_renderer).scale; + for (int i = 0; i < FONT_FALLBACK_MAX && fonts[i]; ++i) { + if (fonts[i]->scale != surface_scale) { + ren_font_group_set_size(window_renderer, fonts, fonts[0]->size); + return; + } + } +} +#endif + static const char* utf8_to_codepoint(const char *p, unsigned *dst) { const unsigned char *up = (unsigned char*)p; unsigned res, n; @@ -336,6 +351,9 @@ void ren_font_group_set_size(RenWindow *window_renderer, RenFont **fonts, float FT_Face face = fonts[i]->face; FT_Set_Pixel_Sizes(face, 0, (int)(size*surface_scale)); fonts[i]->size = size; +#ifdef LITE_USE_SDL_RENDERER + fonts[i]->scale = surface_scale; +#endif fonts[i]->height = (short)((face->height / (float)face->units_per_EM) * size); fonts[i]->baseline = (short)((face->ascender / (float)face->units_per_EM) * size); FT_Load_Char(face, ' ', font_set_load_options(fonts[i])); diff --git a/src/renderer.h b/src/renderer.h index 78811341..1cd6bc88 100644 --- a/src/renderer.h +++ b/src/renderer.h @@ -33,6 +33,9 @@ int ren_font_group_get_tab_size(RenFont **font); int ren_font_group_get_height(RenFont **font); float ren_font_group_get_size(RenFont **font); void ren_font_group_set_size(RenWindow *window_renderer, RenFont **font, float size); +#ifdef LITE_USE_SDL_RENDERER +void update_font_scale(RenWindow *window_renderer, RenFont **fonts); +#endif void ren_font_group_set_tab_size(RenFont **font, int n); double ren_font_group_get_width(RenWindow *window_renderer, RenFont **font, const char *text, size_t len, int *x_offset); double ren_draw_text(RenSurface *rs, RenFont **font, const char *text, size_t len, float x, int y, RenColor color); diff --git a/src/renwindow.c b/src/renwindow.c index 15c9e86c..abc2c910 100644 --- a/src/renwindow.c +++ b/src/renwindow.c @@ -83,12 +83,15 @@ RenSurface renwin_get_surface(RenWindow *ren) { #endif } -void renwin_resize_surface(UNUSED RenWindow *ren) { +void renwin_resize_surface(RenWindow *ren) { #ifdef LITE_USE_SDL_RENDERER - int new_w, new_h; + int new_w, new_h, new_scale; SDL_GL_GetDrawableSize(ren->window, &new_w, &new_h); + new_scale = query_surface_scale(ren); /* Note that (w, h) may differ from (new_w, new_h) on retina displays. */ - if (new_w != ren->rensurface.surface->w || new_h != ren->rensurface.surface->h) { + if (new_scale != ren->rensurface.scale || + new_w != ren->rensurface.surface->w || + new_h != ren->rensurface.surface->h) { renwin_init_surface(ren); renwin_clip_to_surface(ren); setup_renderer(ren, new_w, new_h);