All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 1/2] font: Add font scaling feature to grub_font_draw_glyph()
@ 2022-05-31 10:44 Zhang Boyang
  2022-05-31 10:44 ` [PATCH 2/2] term/gfxterm: Preliminary HiDPI support Zhang Boyang
                   ` (2 more replies)
  0 siblings, 3 replies; 6+ messages in thread
From: Zhang Boyang @ 2022-05-31 10:44 UTC (permalink / raw)
  To: grub-devel; +Cc: Zhang Boyang

This patch adds an argument 'scale' to grub_font_draw_glyph(). If
scale > 1, then the function will scale the bitmap of the drawing glyph
on the fly, and draw the scaled glyph. The scaled bitmap is placed in a
local static buffer, so it will not affect the glyph or font itself.

Signed-off-by: Zhang Boyang <zhangboyang.id@gmail.com>
---
 grub-core/commands/videotest.c |  4 +--
 grub-core/font/font.c          | 54 ++++++++++++++++++++++++++++++----
 grub-core/gfxmenu/font.c       |  2 +-
 grub-core/term/gfxterm.c       |  2 +-
 include/grub/font.h            |  3 +-
 5 files changed, 55 insertions(+), 10 deletions(-)

diff --git a/grub-core/commands/videotest.c b/grub-core/commands/videotest.c
index ac145afc2..d95ee411d 100644
--- a/grub-core/commands/videotest.c
+++ b/grub-core/commands/videotest.c
@@ -87,7 +87,7 @@ grub_cmd_videotest (grub_command_t cmd __attribute__ ((unused)),
       return grub_error (GRUB_ERR_BAD_FONT, "no font loaded");
 
     glyph = grub_font_get_glyph (fixed, '*');
-    grub_font_draw_glyph (glyph, color, 200 ,0);
+    grub_font_draw_glyph (glyph, color, 200, 0, 1);
 
     color = grub_video_map_rgb (255, 255, 255);
 
@@ -148,7 +148,7 @@ grub_cmd_videotest (grub_command_t cmd __attribute__ ((unused)),
       {
 	color = grub_video_map_color (i);
 	palette[i] = color;
-	grub_font_draw_glyph (glyph, color, 16 + i * 16, 220);
+	grub_font_draw_glyph (glyph, color, 16 + i * 16, 220, 1);
       }
   }
 
diff --git a/grub-core/font/font.c b/grub-core/font/font.c
index 42189c325..ab74fddee 100644
--- a/grub-core/font/font.c
+++ b/grub-core/font/font.c
@@ -1568,9 +1568,12 @@ grub_font_construct_glyph (grub_font_t hinted_font,
    side location of the character.  */
 grub_err_t
 grub_font_draw_glyph (struct grub_font_glyph * glyph,
-		      grub_video_color_t color, int left_x, int baseline_y)
+		      grub_video_color_t color, int left_x, int baseline_y,
+		      int scale)
 {
   struct grub_video_bitmap glyph_bitmap;
+  static grub_uint8_t *buffer = NULL;
+  static grub_size_t max_buffer_size = 0;
 
   /* Don't try to draw empty glyphs (U+0020, etc.).  */
   if (glyph->width == 0 || glyph->height == 0)
@@ -1601,11 +1604,52 @@ grub_font_draw_glyph (struct grub_font_glyph * glyph,
 			  &glyph_bitmap.mode_info.fg_alpha);
   glyph_bitmap.data = glyph->bitmap;
 
-  int bitmap_left = left_x + glyph->offset_x;
-  int bitmap_bottom = baseline_y - glyph->offset_y;
-  int bitmap_top = bitmap_bottom - glyph->height;
+  /* Try to scale glyph bitmap */
+  grub_size_t new_buffer_size =
+    ((glyph->width * scale) * (glyph->height * scale) + 7) / 8;
+  if (scale > 1)
+    {
+      if (max_buffer_size < new_buffer_size)
+	{
+	  grub_uint8_t *new_buffer = grub_malloc(new_buffer_size);
+	  if (new_buffer)
+	    {
+	      grub_free(buffer);
+	      buffer = new_buffer;
+	      max_buffer_size = new_buffer_size;
+	    }
+	}
+      if (max_buffer_size < new_buffer_size)
+	{
+	  /* Unable to alloc buffer, fallback to no-scale */
+	  scale = 1;
+	}
+    }
+  if (scale > 1)
+    {
+      /* FIXME: Scale bitmap pixel by pixel is slow */
+      int i, j;
+      grub_memset(buffer, 0, new_buffer_size);
+      for (i = 0; i < glyph->height * scale; i++)
+	for (j = 0; j < glyph->width * scale; j++)
+	  {
+	    int n = (i / scale) * glyph->width + (j / scale);
+	    int m = i * (glyph->width * scale) + j;
+	    int pixel = (glyph->bitmap[n / 8] >> (7 - n % 8)) & 1;
+	    buffer[m / 8] |= pixel << (7 - m % 8);
+	  }
+      glyph_bitmap.mode_info.width = glyph->width * scale;
+      glyph_bitmap.mode_info.height = glyph->height * scale;
+      glyph_bitmap.mode_info.pitch = glyph->width * scale;
+      glyph_bitmap.data = buffer;
+    }
+
+  int bitmap_left = left_x + glyph->offset_x * scale;
+  int bitmap_bottom = baseline_y - glyph->offset_y * scale;
+  int bitmap_top = bitmap_bottom - glyph->height * scale;
 
   return grub_video_blit_bitmap (&glyph_bitmap, GRUB_VIDEO_BLIT_BLEND,
 				 bitmap_left, bitmap_top,
-				 0, 0, glyph->width, glyph->height);
+				 0, 0,
+				 glyph->width * scale, glyph->height * scale);
 }
diff --git a/grub-core/gfxmenu/font.c b/grub-core/gfxmenu/font.c
index 756c24f20..ed59ca954 100644
--- a/grub-core/gfxmenu/font.c
+++ b/grub-core/gfxmenu/font.c
@@ -67,7 +67,7 @@ grub_font_draw_string (const char *str, grub_font_t font,
 	  err = grub_errno;
 	  goto out;
 	}
-      err = grub_font_draw_glyph (glyph, color, x, baseline_y);
+      err = grub_font_draw_glyph (glyph, color, x, baseline_y, 1);
       if (err)
 	goto out;
       x += glyph->device_width;
diff --git a/grub-core/term/gfxterm.c b/grub-core/term/gfxterm.c
index 3c468f459..4512dee6f 100644
--- a/grub-core/term/gfxterm.c
+++ b/grub-core/term/gfxterm.c
@@ -656,7 +656,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);
+  grub_font_draw_glyph (glyph, color, x, y + ascent, 1);
   grub_video_set_active_render_target (render_target);
 
   /* Mark character to be drawn.  */
diff --git a/include/grub/font.h b/include/grub/font.h
index 708fa42ac..5d66ba523 100644
--- a/include/grub/font.h
+++ b/include/grub/font.h
@@ -141,7 +141,8 @@ struct grub_font_glyph *EXPORT_FUNC (grub_font_get_glyph_with_fallback) (grub_fo
 
 grub_err_t EXPORT_FUNC (grub_font_draw_glyph) (struct grub_font_glyph *glyph,
 					       grub_video_color_t color,
-					       int left_x, int baseline_y);
+					       int left_x, int baseline_y,
+					       int scale);
 
 int
 EXPORT_FUNC (grub_font_get_constructed_device_width) (grub_font_t hinted_font,
-- 
2.30.2



^ permalink raw reply related	[flat|nested] 6+ messages in thread

end of thread, other threads:[~2022-05-31 13:26 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-05-31 10:44 [PATCH 1/2] font: Add font scaling feature to grub_font_draw_glyph() Zhang Boyang
2022-05-31 10:44 ` [PATCH 2/2] term/gfxterm: Preliminary HiDPI support Zhang Boyang
2022-05-31 11:36 ` [PATCH 1/2] font: Add font scaling feature to grub_font_draw_glyph() Gerd Hoffmann
2022-05-31 12:17   ` Zhang Boyang
2022-05-31 12:51 ` Vladimir 'phcoder' Serbinenko
2022-05-31 13:26   ` Zhang Boyang

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.