video: truetype: Handle rendering of bitmap fonts

Complete the support for this feature by dealing with rendering, the
moving to a particular row/column and scrolling.

Provide a simple test to check that things look right.

Allow omitting the font name to request the default font.

Fix an errant tab nearby.

Co-developed-by: Claude <noreply@anthropic.com>
Signed-off-by: Simon Glass <sjg@chromium.org>
This commit is contained in:
Simon Glass
2025-09-18 06:42:21 -06:00
parent 1fe8824fb9
commit cca7523800
6 changed files with 89 additions and 18 deletions

View File

@@ -31,9 +31,6 @@ static int do_font_select(struct cmd_tbl *cmdtp, int flag, int argc,
uint size = 0;
int ret;
if (argc < 2)
return CMD_RET_USAGE;
if (uclass_first_device_err(UCLASS_VIDEO_CONSOLE, &dev))
return CMD_RET_FAILURE;
name = argv[1];

View File

@@ -12,7 +12,7 @@ Synopsis
::
font list
font select <name> [<size>]
font select [<name> [<size>]]
font size [<size>]
Description
@@ -25,11 +25,13 @@ font list
~~~~~~~~~
This lists the available fonts, using the name of the font file in the build.
Any enabled bitmap fonts are listed as well.
font select
~~~~~~~~~~~
This selects a new font and optionally changes the size.
This selects a new font and optionally changes the size. If the name is not
provided, the default font is used.
font size
~~~~~~~~~
@@ -50,6 +52,16 @@ Examples
=> font select cantoraone_regular 20
=>
This shows an example of selecting a bitmap font Truetype is active::
=> font list
8x16
12x22
nimbus_sans_l_regular
cantoraone_regular
=> font sel 8x16
Configuration
-------------

View File

@@ -13,6 +13,7 @@
#include <video.h>
#include <video_console.h>
#include <video_font.h>
#include "vidconsole_internal.h"
/* Functions needed by stb_truetype.h */
static int tt_floor(double val)
@@ -197,11 +198,17 @@ static int console_truetype_set_row(struct udevice *dev, uint row, int clr)
struct video_priv *vid_priv = dev_get_uclass_priv(dev->parent);
struct vidconsole_priv *vc_priv = dev_get_uclass_priv(dev);
struct console_tt_priv *priv = dev_get_priv(dev);
struct console_tt_metrics *met = priv->cur_met;
void *end, *line;
int font_height;
line = vid_priv->fb + row * met->font_size * vid_priv->line_length;
end = line + met->font_size * vid_priv->line_length;
/* Get font height from current font type */
if (priv->cur_fontdata)
font_height = priv->cur_fontdata->height;
else
font_height = priv->cur_met->font_size;
line = vid_priv->fb + row * font_height * vid_priv->line_length;
end = line + font_height * vid_priv->line_length;
switch (vid_priv->bpix) {
case VIDEO_BPP8: {
@@ -250,17 +257,22 @@ static int console_truetype_move_rows(struct udevice *dev, uint rowdst,
struct video_priv *vid_priv = dev_get_uclass_priv(dev->parent);
struct vidconsole_priv *vc_priv = dev_get_uclass_priv(dev);
struct console_tt_priv *priv = dev_get_priv(dev);
struct console_tt_metrics *met = priv->cur_met;
void *dst;
void *src;
int i, diff;
int i, diff, font_height;
dst = vid_priv->fb + rowdst * met->font_size * vid_priv->line_length;
src = vid_priv->fb + rowsrc * met->font_size * vid_priv->line_length;
memmove(dst, src, met->font_size * vid_priv->line_length * count);
/* Get font height from current font type */
if (priv->cur_fontdata)
font_height = priv->cur_fontdata->height;
else
font_height = priv->cur_met->font_size;
dst = vid_priv->fb + rowdst * font_height * vid_priv->line_length;
src = vid_priv->fb + rowsrc * font_height * vid_priv->line_length;
memmove(dst, src, font_height * vid_priv->line_length * count);
/* Scroll up our position history */
diff = (rowsrc - rowdst) * met->font_size;
diff = (rowsrc - rowdst) * font_height;
for (i = 0; i < priv->pos_ptr; i++)
priv->pos[i].ypos -= diff;
@@ -281,7 +293,7 @@ static int console_truetype_putc_xy(struct udevice *dev, uint x, uint y,
struct video_priv *vid_priv = dev_get_uclass_priv(vid);
struct console_tt_priv *priv = dev_get_priv(dev);
struct console_tt_metrics *met = priv->cur_met;
stbtt_fontinfo *font = &met->font;
stbtt_fontinfo *font;
int width, height, xoff, yoff;
double xpos, x_shift;
int lsb;
@@ -292,7 +304,12 @@ static int console_truetype_putc_xy(struct udevice *dev, uint x, uint y,
void *start, *end, *line;
int row, kern;
/* Use fixed font if selected */
if (priv->cur_fontdata)
return console_fixed_putc_xy(dev, x, y, cp, priv->cur_fontdata);
/* First get some basic metrics about this character */
font = &met->font;
stbtt_GetCodepointHMetrics(font, cp, &advance, &lsb);
/*

View File

@@ -835,4 +835,5 @@ void vidconsole_set_bitmap_font(struct udevice *dev,
vc_priv->rows = vid_priv->ysize / fontdata->height;
/* xsize_frac is set in vidconsole_pre_probe() */
}
vc_priv->xstart_frac = 0;
}

View File

@@ -82,9 +82,12 @@ static int font_test_base(struct unit_test_state *uts)
ut_assert_nextline("30");
ut_assertok(ut_check_console_end(uts));
ut_assertok(run_command("font select", 0));
ut_assertok(ut_check_console_end(uts));
ut_assertok(vidconsole_get_font_size(dev, &name, &size));
ut_asserteq_str("cantoraone_regular", name);
ut_asserteq(30, size);
ut_asserteq_str("nimbus_sans_l_regular", name);
ut_asserteq(CONFIG_CONSOLE_TRUETYPE_SIZE, size);
return 0;
}

View File

@@ -944,7 +944,7 @@ static int dm_test_video_box(struct unit_test_state *uts)
video_draw_box(dev, 500, 100, 600, 200, 20,
video_index_to_colour(priv, VID_LIGHT_RED), false);
ut_asserteq(133, video_compress_fb(uts, dev, false));
/* test filled boxes */
video_draw_box(dev, 150, 250, 200, 300, 0,
video_index_to_colour(priv, VID_GREEN), true);
@@ -956,3 +956,44 @@ static int dm_test_video_box(struct unit_test_state *uts)
return 0;
}
DM_TEST(dm_test_video_box, UTF_SCAN_FDT);
/* font switching between TrueType and bitmap fonts */
static int dm_test_video_font_switch(struct unit_test_state *uts)
{
struct udevice *dev, *con;
const char *truetype_text =
"This is a long line of text written with TrueType font that "
"should wrap to multiple lines to test the multi-line "
"functionality properly. This is the second part of TrueType "
"text that should also be long enough to wrap and test the "
"line handling.";
const char *bitmap_text =
"Now this is bitmap font text that spans multiple lines and "
"should be rendered with the standard 8x16 bitmap font instead "
"of TrueType. More of the line of-bitmap text for testing "
"purposes.";
const char *final_truetype_text =
"Finally back to TrueType font for this concluding multi-line "
"text that demonstrates the font switching functionality "
"working correctly.\nFinal line of TrueType text to complete "
"the test.\n";
ut_assertok(video_get_nologo(uts, &dev));
ut_assertok(uclass_get_device(UCLASS_VIDEO_CONSOLE, 0, &con));
/* Start with TrueType font and write multi-line text */
vidconsole_put_string(con, truetype_text);
/* Switch to bitmap font */
ut_assertok(vidconsole_select_font(con, "8x16", 0));
vidconsole_put_string(con, bitmap_text);
/* Switch back to TrueType font */
ut_assertok(vidconsole_select_font(con, NULL, 0));
vidconsole_put_string(con, final_truetype_text);
ut_asserteq(14892, video_compress_fb(uts, dev, false));
return 0;
}
DM_TEST(dm_test_video_font_switch, UTF_SCAN_PDATA | UTF_SCAN_FDT);