[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[PATCH 2/2] term/gfxterm: Preliminary HiDPI support
From: |
Zhang Boyang |
Subject: |
[PATCH 2/2] term/gfxterm: Preliminary HiDPI support |
Date: |
Tue, 31 May 2022 18:44:50 +0800 |
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.id@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