[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[PATCH 3/3] Improve font fallback scanning and validation for gfxterm
From: |
Vladimir Serbinenko |
Subject: |
[PATCH 3/3] Improve font fallback scanning and validation for gfxterm |
Date: |
Thu, 16 May 2024 22:31:53 +0300 |
Choosing a font which is too large breaks gfxterm. Be more diligent in
font choice. This being said it's better to specify the correct font explicitly
in config when several fonts are loaded.
Signed-off-by: Vladimir Serbinenko <phcoder@gmail.com>
---
grub-core/gfxmenu/view.c | 7 +----
grub-core/term/gfxterm.c | 56 ++++++++++++++++++++++++++++++++--------
2 files changed, 46 insertions(+), 17 deletions(-)
diff --git a/grub-core/gfxmenu/view.c b/grub-core/gfxmenu/view.c
index 19d3f2f14..d96b5cdc9 100644
--- a/grub-core/gfxmenu/view.c
+++ b/grub-core/gfxmenu/view.c
@@ -524,12 +524,7 @@ init_terminal (grub_gfxmenu_view_t view)
{
grub_font_t terminal_font;
- terminal_font = grub_font_get (view->terminal_font_name);
- if (!terminal_font)
- {
- grub_error (GRUB_ERR_BAD_FONT, "no font loaded");
- return;
- }
+ terminal_font = grub_font_get_no_fallback (view->terminal_font_name);
/* Check that terminal window size and position are sane. */
terminal_sanity_check (view);
diff --git a/grub-core/term/gfxterm.c b/grub-core/term/gfxterm.c
index 3c468f459..addad5ee2 100644
--- a/grub-core/term/gfxterm.c
+++ b/grub-core/term/gfxterm.c
@@ -293,12 +293,56 @@ grub_gfxterm_schedule_repaint (void)
repaint_scheduled = 1;
}
+static int
+font_validate (grub_font_t font, int width, int height)
+{
+ int normal_char_width = calculate_normal_character_width (font);
+ int normal_char_height = grub_font_get_max_char_height (font);
+ if (normal_char_height == 0)
+ normal_char_height = 16;
+ if (normal_char_width == 0)
+ normal_char_width = 8;
+
+ /* Calculate size of text buffer. */
+ int columns = width / normal_char_width;
+ int rows = height / normal_char_height;
+
+ return columns >= 40 && rows >= 12;
+}
+
grub_err_t
grub_gfxterm_set_window (struct grub_video_render_target *target,
int x, int y, int width, int height,
int double_repaint,
grub_font_t font, int border_width)
{
+ if (!font)
+ {
+ const char *font_name;
+ /* Select the font to use. */
+ font_name = grub_env_get ("gfxterm_font");
+ if (! font_name)
+ font_name = ""; /* Allow fallback to any font. */
+
+ font = grub_font_get_no_fallback (font_name);
+ }
+
+ if (!font || !font_validate(font, width, height))
+ {
+ struct grub_font_node *node;
+
+ font = NULL;
+
+ for (node = grub_font_list; node; node = node->next)
+ if (font_validate(node->value, width, height))
+ font = node->value;
+
+ if (!font)
+ font = grub_font_get("");
+ }
+ if (!font)
+ return grub_error (GRUB_ERR_BAD_FONT, "no font loaded");
+
/* Clean up any prior instance. */
destroy_window ();
@@ -331,12 +375,10 @@ grub_gfxterm_set_window (struct grub_video_render_target
*target,
static grub_err_t
grub_gfxterm_fullscreen (void)
{
- const char *font_name;
struct grub_video_mode_info mode_info;
grub_video_color_t color;
grub_err_t err;
int double_redraw;
- grub_font_t font;
err = grub_video_get_info (&mode_info);
/* Figure out what mode we ended up. */
@@ -357,21 +399,13 @@ grub_gfxterm_fullscreen (void)
grub_video_fill_rect (color, 0, 0, mode_info.width, mode_info.height);
}
- /* Select the font to use. */
- font_name = grub_env_get ("gfxterm_font");
- if (! font_name)
- font_name = ""; /* Allow fallback to any font. */
-
- font = grub_font_get (font_name);
- if (!font)
- return grub_error (GRUB_ERR_BAD_FONT, "no font loaded");
grub_gfxterm_decorator_hook = NULL;
return grub_gfxterm_set_window (GRUB_VIDEO_RENDER_TARGET_DISPLAY,
0, 0, mode_info.width, mode_info.height,
double_redraw,
- font, DEFAULT_BORDER_WIDTH);
+ NULL, DEFAULT_BORDER_WIDTH);
}
static grub_err_t
--
2.39.2