From: Simon Glass <sjg@chromium.org>
It is sometimes useful to use a bitmap font for the console even when
truetype fonts are available. As a starting point, pull in the
font table and provide information about font sizes. Allow selection of
a bitmap font by name, as well as listing available bitmap fonts.
Co-developed-by: Claude <noreply@anthropic.com>
Signed-off-by: Simon Glass <sjg@chromium.org>
---
drivers/video/console_truetype.c | 64 ++++++++++++++++++++++++++++++--
test/cmd/font.c | 8 +++-
2 files changed, 67 insertions(+), 5 deletions(-)
@@ -12,6 +12,7 @@
#include <spl.h>
#include <video.h>
#include <video_console.h>
+#include <video_font.h>
/* Functions needed by stb_truetype.h */
static int tt_floor(double val)
@@ -169,6 +170,7 @@ struct console_tt_metrics {
* last character. We record enough characters to go back to the
* start of the current command line.
* @pos_ptr: Current position in the position history
+ * @cur_fontdata: Current fixed font data (NULL if using TrueType)
*/
struct console_tt_priv {
struct console_tt_metrics *cur_met;
@@ -176,6 +178,7 @@ struct console_tt_priv {
int num_metrics;
struct pos_info pos[POS_HISTORY_SIZE];
int pos_ptr;
+ struct video_fontdata *cur_fontdata;
};
/**
@@ -595,9 +598,19 @@ int console_truetype_get_font(struct udevice *dev, int seq,
struct vidfont_info *info)
{
struct font_info *tab;
+ struct video_fontdata *fontdata;
int i;
- for (i = 0, tab = font_table; tab->begin; tab++, i++) {
+ /* List fixed fonts first */
+ for (i = 0, fontdata = fonts; fontdata->name; fontdata++, i++) {
+ if (i == seq) {
+ info->name = fontdata->name;
+ return 0;
+ }
+ }
+
+ /* then list TrueType fonts */
+ for (tab = font_table; tab->begin; tab++, i++) {
if (i == seq && font_valid(tab)) {
info->name = tab->name;
return 0;
@@ -671,6 +684,27 @@ static struct console_tt_metrics *find_metrics(struct udevice *dev,
return NULL;
}
+/**
+ * set_bitmap_font() - Set up console to use a fixed font
+ *
+ * @dev: Console device
+ * @fontdata: Fixed font data to use
+ * Return: 0 if OK, -ve on error
+ */
+static void set_bitmap_font(struct udevice *dev,
+ struct video_fontdata *fontdata)
+{
+ struct vidconsole_priv *vc_priv = dev_get_uclass_priv(dev);
+ struct console_tt_priv *priv = dev_get_priv(dev);
+
+ priv->cur_fontdata = fontdata;
+ priv->cur_met = NULL;
+
+ vidconsole_set_bitmap_font(dev, fontdata);
+
+ vc_priv->tab_width_frac = VID_TO_POS(fontdata->width) * 8 / 2;
+}
+
static void select_metrics(struct udevice *dev, struct console_tt_metrics *met)
{
struct vidconsole_priv *vc_priv = dev_get_uclass_priv(dev);
@@ -734,9 +768,24 @@ static int get_metrics(struct udevice *dev, const char *name, uint size,
static int truetype_select_font(struct udevice *dev, const char *name,
uint size)
{
+ struct console_tt_priv *priv = dev_get_priv(dev);
struct console_tt_metrics *met;
+ struct video_fontdata *fontdata;
int ret;
+ /* Check if this is a request for a fixed font */
+ if (name) {
+ for (fontdata = fonts; fontdata->name; fontdata++) {
+ if (!strcmp(name, fontdata->name)) {
+ /* Switch to fixed-font mode */
+ set_bitmap_font(dev, fontdata);
+ return 0;
+ }
+ }
+ }
+
+ /* Continue with TrueType font selection */
+ priv->cur_fontdata = NULL;
ret = get_metrics(dev, name, size, &met);
if (ret)
return log_msg_ret("sel", ret);
@@ -1036,11 +1085,18 @@ static int truetype_set_cursor_visible(struct udevice *dev, bool visible,
const char *console_truetype_get_font_size(struct udevice *dev, uint *sizep)
{
struct console_tt_priv *priv = dev_get_priv(dev);
- struct console_tt_metrics *met = priv->cur_met;
- *sizep = met->font_size;
+ if (priv->cur_fontdata) {
+ /* Using fixed font */
+ *sizep = priv->cur_fontdata->height;
+ return priv->cur_fontdata->name;
+ } else {
+ /* Using TrueType font */
+ struct console_tt_metrics *met = priv->cur_met;
- return met->font_name;
+ *sizep = met->font_size;
+ return met->font_name;
+ }
}
static int console_truetype_probe(struct udevice *dev)
@@ -26,6 +26,10 @@ static int font_test_base(struct unit_test_state *uts)
ut_assertok(uclass_first_device_err(UCLASS_VIDEO_CONSOLE, &dev));
ut_assertok(run_command("font list", 0));
+ if (IS_ENABLED(CONFIG_VIDEO_FONT_8X16))
+ ut_assert_nextline("8x16");
+ if (IS_ENABLED(CONFIG_VIDEO_FONT_SUN12X22))
+ ut_assert_nextline("12x22");
if (IS_ENABLED(CONFIG_CONSOLE_TRUETYPE_NIMBUS))
ut_assert_nextline("nimbus_sans_l_regular");
if (IS_ENABLED(CONFIG_CONSOLE_TRUETYPE_ANKACODER))
@@ -37,8 +41,10 @@ static int font_test_base(struct unit_test_state *uts)
ut_assertok(vidconsole_get_font_size(dev, &name, &size));
if (IS_ENABLED(CONFIG_CONSOLE_TRUETYPE_ANKACODER))
ut_asserteq_str("ankacoder_c75_r", name);
- else
+ else if (IS_ENABLED(CONFIG_CONSOLE_TRUETYPE_NIMBUS))
ut_asserteq_str("nimbus_sans_l_regular", name);
+ else
+ ut_asserteq_str("8x16", name);
ut_asserteq(CONFIG_CONSOLE_TRUETYPE_SIZE, size);
if (!IS_ENABLED(CONFIG_CONSOLE_TRUETYPE_CANTORAONE))