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:
@@ -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];
|
||||
|
||||
@@ -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
|
||||
-------------
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
/*
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user