grub-devel.gnu.org archive mirror
 help / color / mirror / Atom feed
From: Vladimir Serbinenko <phcoder@gmail.com>
To: grub-devel@gnu.org
Cc: Vladimir Serbinenko <phcoder@gmail.com>
Subject: [PATCH 3/3] Improve font fallback scanning and validation for gfxterm
Date: Thu, 16 May 2024 22:31:53 +0300	[thread overview]
Message-ID: <20240516193153.4595-3-phcoder@gmail.com> (raw)
In-Reply-To: <20240516193153.4595-1-phcoder@gmail.com>

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


_______________________________________________
Grub-devel mailing list
Grub-devel@gnu.org
https://lists.gnu.org/mailman/listinfo/grub-devel

      parent reply	other threads:[~2024-05-16 19:32 UTC|newest]

Thread overview: 3+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2024-05-16 19:31 [PATCH 1/3] Add grub_font_get_no_fallback Vladimir Serbinenko
2024-05-16 19:31 ` [PATCH 2/3] gfxmenu: Add missing error handling Vladimir Serbinenko
2024-05-16 19:31 ` Vladimir Serbinenko [this message]

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20240516193153.4595-3-phcoder@gmail.com \
    --to=phcoder@gmail.com \
    --cc=grub-devel@gnu.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).