From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from list by lists.gnu.org with archive (Exim 4.90_1) id 1nvzN3-0005DI-TT for mharc-grub-devel@gnu.org; Tue, 31 May 2022 06:45:06 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:46770) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1nvzN2-0005Aw-IL for grub-devel@gnu.org; Tue, 31 May 2022 06:45:04 -0400 Received: from mail-pg1-x530.google.com ([2607:f8b0:4864:20::530]:45851) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1nvzN0-0004lX-Fo for grub-devel@gnu.org; Tue, 31 May 2022 06:45:04 -0400 Received: by mail-pg1-x530.google.com with SMTP id a63so6289396pge.12 for ; Tue, 31 May 2022 03:45:01 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; h=from:to:cc:subject:date:message-id:mime-version :content-transfer-encoding; bh=ux9bGhgJfdLen8tq5SNd1NzyAIua3aNjpI+pStzgoMQ=; b=e7Dv5v7RTP0a0bHlNlmpeT2gRA5nK+eMeAy1JWJes6b59gR5fubsrgoE1cKOxD4Bz/ 9v5ntepKNdSX0VUG0uaYsVQtCsgsqQWYxu6U9OcPreOmUANZJ4PtyCgiEqgdFrfllyPT kt0YrUuwoHCB/2O/a3SvvRRqIe3YF3M1eeubVnFdnlUKGHWTMaipV+7t+COzGu7sanvj qqlEJBLYGYf2Y7uS410eRRozf0k2soNsIjO2W0KPkTvES5RmnH3TVopl+UD4E4YbJYvz bMoRLPQ9HMvmZT+o7bry+MI38gir158RAOdKhba/7NbWIMlDFRKFBmLLDGKtwVbi5C58 f9bA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:mime-version :content-transfer-encoding; bh=ux9bGhgJfdLen8tq5SNd1NzyAIua3aNjpI+pStzgoMQ=; b=E7NgfLLccrpxJ5ePbrnO3DQGIkBcBtPtNrt8tdq85AxwCZL1NkccjFqRlgyBS63ljn Pvx0KA0UBX1T9t9d7DgPVqwwlBsMHTuYKh5dMIxc6JOPgeYjCbtl9Z+0OMnfUX5e01YO K+v/hBMF50ONpPxc3DMBf57W2822hIyalf9RkNpdR+u16QSTe9itHG/h+D0DdYAoYDKp CPhsNNhocYV5SkkwX619Ocx02Pua3eGaQCq2n7gArthHC7pV/oUX+JDPQ+bzoEqireRJ PEfJuL4VrF6AvjKwZtb4XLG7nyv5qeWYpyzmAC5hW50uf9gNisX5OU8WnFLTuhdnj7Hy ENjw== X-Gm-Message-State: AOAM533SRLRferX+xp5FKLJGHrid8PAOjCJ5q2ihpTgxl6ky1vwBX+ws ssHToM5j2peVboPLHKMf9euezUHSOOc= X-Google-Smtp-Source: ABdhPJwrHZc9dzOeYVl7FjO0YDVq21oU2kE9MvxVFsbBXEyPOSGRoiKG9fDI5GfBqWJtX6TtHPTKTg== X-Received: by 2002:a63:2c8a:0:b0:3fa:6b31:5918 with SMTP id s132-20020a632c8a000000b003fa6b315918mr33966108pgs.485.1653993900829; Tue, 31 May 2022 03:45:00 -0700 (PDT) Received: from localhost.localdomain (ec2-13-113-80-70.ap-northeast-1.compute.amazonaws.com. [13.113.80.70]) by smtp.gmail.com with ESMTPSA id g2-20020aa796a2000000b00518764d09cdsm10406568pfk.164.2022.05.31.03.44.59 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 31 May 2022 03:45:00 -0700 (PDT) From: Zhang Boyang To: grub-devel@gnu.org Cc: Zhang Boyang Subject: [PATCH 1/2] font: Add font scaling feature to grub_font_draw_glyph() Date: Tue, 31 May 2022 18:44:49 +0800 Message-Id: <20220531104450.427508-1-zhangboyang.id@gmail.com> X-Mailer: git-send-email 2.30.2 MIME-Version: 1.0 Content-Transfer-Encoding: 8bit Received-SPF: pass client-ip=2607:f8b0:4864:20::530; envelope-from=zhangboyang.id@gmail.com; helo=mail-pg1-x530.google.com X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, FREEMAIL_FROM=0.001, RCVD_IN_DNSWL_NONE=-0.0001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001, T_SCC_BODY_TEXT_LINE=-0.01 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: grub-devel@gnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: The development of GNU GRUB List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 31 May 2022 10:45:05 -0000 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 --- 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