Currently GRUB's default font is too small to see on a HiDPI monitor. This patch adds preliminary HiDPI support to gfxterm. If default font and a HiDPI monitor are both detected, it will scale the font size on the fly.
Signed-off-by: Zhang Boyang <zhangboyang...@gmail.com> --- grub-core/term/gfxterm.c | 55 +++++++++++++++++++++++++--------------- 1 file changed, 35 insertions(+), 20 deletions(-) diff --git a/grub-core/term/gfxterm.c b/grub-core/term/gfxterm.c index 4512dee6f..8c6bb8e83 100644 --- a/grub-core/term/gfxterm.c +++ b/grub-core/term/gfxterm.c @@ -82,6 +82,7 @@ struct grub_virtual_screen /* Font settings. */ grub_font_t font; + unsigned int scale; /* Terminal color settings. */ grub_uint8_t standard_color_setting; @@ -204,7 +205,7 @@ grub_virtual_screen_free (void) static grub_err_t grub_virtual_screen_setup (unsigned int x, unsigned int y, unsigned int width, unsigned int height, - grub_font_t font) + grub_font_t font, unsigned int scale) { unsigned int i; @@ -213,6 +214,7 @@ grub_virtual_screen_setup (unsigned int x, unsigned int y, /* Initialize with default data. */ virtual_screen.font = font; + virtual_screen.scale = scale; virtual_screen.width = width; virtual_screen.height = height; virtual_screen.offset_x = x; @@ -220,9 +222,9 @@ grub_virtual_screen_setup (unsigned int x, unsigned int y, virtual_screen.normal_char_width = calculate_normal_character_width (virtual_screen.font); virtual_screen.normal_char_height = - grub_font_get_max_char_height (virtual_screen.font); + grub_font_get_max_char_height (virtual_screen.font) * virtual_screen.scale; if (virtual_screen.normal_char_height == 0) - virtual_screen.normal_char_height = 16; + virtual_screen.normal_char_height = 16 * virtual_screen.scale; virtual_screen.cursor_x = 0; virtual_screen.cursor_y = 0; virtual_screen.cursor_state = 1; @@ -299,17 +301,29 @@ grub_gfxterm_set_window (struct grub_video_render_target *target, int double_repaint, grub_font_t font, int border_width) { + int scale; + /* Clean up any prior instance. */ destroy_window (); /* Set the render target. */ render_target = target; + /* Decide font scale factor. */ + scale = 1; + if (font->max_char_height == 16) /* FIXME: Better logic */ + { + if (width > 3840 && height > 2160) + scale = 4; + else if (width > 1920 && height > 1080) + scale = 2; + } + /* Create virtual screen. */ - if (grub_virtual_screen_setup (border_width, border_width, - width - 2 * border_width, - height - 2 * border_width, - font) + if (grub_virtual_screen_setup (border_width * scale, border_width * scale, + width - 2 * border_width * scale, + height - 2 * border_width * scale, + font, scale) != GRUB_ERR_NONE) { return grub_errno; @@ -642,7 +656,7 @@ paint_char (unsigned cx, unsigned cy) grub_errno = GRUB_ERR_NONE; return; } - ascent = grub_font_get_ascent (virtual_screen.font); + ascent = grub_font_get_ascent (virtual_screen.font) * virtual_screen.scale; width = virtual_screen.normal_char_width * calculate_character_width(glyph); height = virtual_screen.normal_char_height; @@ -656,7 +670,7 @@ paint_char (unsigned cx, unsigned cy) /* Render glyph to text layer. */ grub_video_set_active_render_target (text_layer); grub_video_fill_rect (bgcolor, x, y, width, height); - grub_font_draw_glyph (glyph, color, x, y + ascent, 1); + grub_font_draw_glyph (glyph, color, x, y + ascent, virtual_screen.scale); grub_video_set_active_render_target (render_target); /* Mark character to be drawn. */ @@ -690,9 +704,9 @@ draw_cursor (int show) return; /* Ensure that cursor doesn't go outside of character box. */ - ascent = grub_font_get_ascent(virtual_screen.font); - if (ascent > virtual_screen.normal_char_height - 2) - ascent = virtual_screen.normal_char_height - 2; + ascent = grub_font_get_ascent(virtual_screen.font) * virtual_screen.scale; + if (ascent > virtual_screen.normal_char_height - 2 * virtual_screen.scale) + ascent = virtual_screen.normal_char_height - 2 * virtual_screen.scale; /* Determine cursor properties and position on text layer. */ x = virtual_screen.cursor_x * virtual_screen.normal_char_width; @@ -701,7 +715,7 @@ draw_cursor (int show) y = ((virtual_screen.cursor_y + virtual_screen.total_scroll) * virtual_screen.normal_char_height + ascent); - height = 2; + height = 2 * virtual_screen.scale; /* Render cursor to text layer. */ grub_video_set_active_render_target (text_layer); @@ -957,18 +971,18 @@ calculate_normal_character_width (grub_font_t font) width = glyph->device_width; } if (!width) - return 8; + return 8 * virtual_screen.scale; - return width; + return width * virtual_screen.scale; } static unsigned char calculate_character_width (struct grub_font_glyph *glyph) { if (! glyph || glyph->device_width == 0) - return 1; + return 1 * virtual_screen.scale; - return (glyph->device_width + return (glyph->device_width * virtual_screen.scale + (virtual_screen.normal_char_width - 1)) / virtual_screen.normal_char_width; } @@ -981,10 +995,11 @@ grub_gfxterm_getcharwidth (struct grub_term_output *term __attribute__ ((unused) dev_width = grub_font_get_constructed_device_width (virtual_screen.font, c); if (dev_width == 0) - return 1; + return 1 * virtual_screen.scale; - return (dev_width + (virtual_screen.normal_char_width - 1)) - / virtual_screen.normal_char_width; + return (dev_width * virtual_screen.scale + + (virtual_screen.normal_char_width - 1)) + / virtual_screen.normal_char_width; } static struct grub_term_coordinate -- 2.30.2 _______________________________________________ Grub-devel mailing list Grub-devel@gnu.org https://lists.gnu.org/mailman/listinfo/grub-devel