[PATCH v2 14/25] video: Add font functions to the vidconsole API

Simon Glass sjg at chromium.org
Fri Nov 4 23:48:32 CET 2022


Support for fonts currently depends on the type of vidconsole in use. Add
two new methods to enumerate fonts and to set the font.

Fix a few other method comments while we are here.

Signed-off-by: Simon Glass <sjg at chromium.org>
---

Changes in v2:
- Rename vidconsole_get_font() to vidconsole_get_font_size()

 cmd/font.c                        | 11 ++++-
 drivers/video/console_truetype.c  | 27 +++++++----
 drivers/video/vidconsole-uclass.c | 33 ++++++++++++++
 include/video_console.h           | 75 ++++++++++++++++++++++++++-----
 test/cmd/font.c                   |  6 +--
 5 files changed, 127 insertions(+), 25 deletions(-)

diff --git a/cmd/font.c b/cmd/font.c
index 3e522f3aaa1..7b4347f32b5 100644
--- a/cmd/font.c
+++ b/cmd/font.c
@@ -15,7 +15,11 @@
 static int do_font_list(struct cmd_tbl *cmdtp, int flag, int argc,
 			char *const argv[])
 {
-	vidconsole_list_fonts();
+	struct udevice *dev;
+
+	if (uclass_first_device_err(UCLASS_VIDEO_CONSOLE, &dev))
+		return CMD_RET_FAILURE;
+	vidconsole_list_fonts(dev);
 
 	return 0;
 }
@@ -47,6 +51,7 @@ static int do_font_select(struct cmd_tbl *cmdtp, int flag, int argc,
 static int do_font_size(struct cmd_tbl *cmdtp, int flag, int argc,
 			char *const argv[])
 {
+	const char *font_name;
 	struct udevice *dev;
 	uint size;
 	int ret;
@@ -56,9 +61,11 @@ static int do_font_size(struct cmd_tbl *cmdtp, int flag, int argc,
 
 	if (uclass_first_device_err(UCLASS_VIDEO_CONSOLE, &dev))
 		return CMD_RET_FAILURE;
+	font_name = vidconsole_get_font_size(dev, &size);
 
 	size = dectoul(argv[1], NULL);
-	ret = vidconsole_select_font(dev, NULL, size);
+
+	ret = vidconsole_select_font(dev, font_name, size);
 	if (ret) {
 		printf("Failed (error %d)\n", ret);
 		return CMD_RET_FAILURE;
diff --git a/drivers/video/console_truetype.c b/drivers/video/console_truetype.c
index 4abc0bc2ff1..9cac9a6de4d 100644
--- a/drivers/video/console_truetype.c
+++ b/drivers/video/console_truetype.c
@@ -584,14 +584,20 @@ static struct font_info *console_truetype_find_font(void)
 	return NULL;
 }
 
-void vidconsole_list_fonts(void)
+int console_truetype_get_font(struct udevice *dev, int seq,
+			      struct vidfont_info *info)
 {
 	struct font_info *tab;
+	int i;
 
-	for (tab = font_table; tab->begin; tab++) {
-		if (abs(tab->begin - tab->end) > 4)
-			printf("%s\n", tab->name);
+	for (i = 0, tab = font_table; tab->begin; tab++, i++) {
+		if (i == seq && font_valid(tab)) {
+			info->name = tab->name;
+			return 0;
+		}
 	}
+
+	return -ENOENT;
 }
 
 /**
@@ -674,7 +680,8 @@ static void select_metrics(struct udevice *dev, struct console_tt_metrics *met)
 	vc_priv->tab_width_frac = VID_TO_POS(met->font_size) * 8 / 2;
 }
 
-int vidconsole_select_font(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;
@@ -684,7 +691,7 @@ int vidconsole_select_font(struct udevice *dev, const char *name, uint size)
 		if (!size)
 			size = CONFIG_CONSOLE_TRUETYPE_SIZE;
 		if (!name)
-			name = priv->cur_met->font_name;
+			name = font_table->name;
 
 		met = find_metrics(dev, name, size);
 		if (!met) {
@@ -694,7 +701,9 @@ int vidconsole_select_font(struct udevice *dev, const char *name, uint size)
 					int ret;
 
 					ret = truetype_add_metrics(dev,
-						tab->name, size, tab->begin);
+								   tab->name,
+								   size,
+								   tab->begin);
 					if (ret < 0)
 						return log_msg_ret("add", ret);
 
@@ -715,7 +724,7 @@ int vidconsole_select_font(struct udevice *dev, const char *name, uint size)
 	return 0;
 }
 
-const char *vidconsole_get_font(struct udevice *dev, uint *sizep)
+const char *vidconsole_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;
@@ -763,6 +772,8 @@ struct vidconsole_ops console_truetype_ops = {
 	.set_row	= console_truetype_set_row,
 	.backspace	= console_truetype_backspace,
 	.entry_start	= console_truetype_entry_start,
+	.get_font	= console_truetype_get_font,
+	.select_font	= truetype_select_font,
 };
 
 U_BOOT_DRIVER(vidconsole_truetype) = {
diff --git a/drivers/video/vidconsole-uclass.c b/drivers/video/vidconsole-uclass.c
index 6bdfb6e37dd..aadd54bfd4f 100644
--- a/drivers/video/vidconsole-uclass.c
+++ b/drivers/video/vidconsole-uclass.c
@@ -557,6 +557,39 @@ static void vidconsole_puts(struct stdio_dev *sdev, const char *s)
 	}
 }
 
+void vidconsole_list_fonts(struct udevice *dev)
+{
+	struct vidfont_info info;
+	int ret, i;
+
+	for (i = 0, ret = 0; !ret; i++) {
+		ret = vidconsole_get_font(dev, i, &info);
+		if (!ret)
+			printf("%s\n", info.name);
+	}
+}
+
+int vidconsole_get_font(struct udevice *dev, int seq,
+			struct vidfont_info *info)
+{
+	struct vidconsole_ops *ops = vidconsole_get_ops(dev);
+
+	if (!ops->get_font)
+		return -ENOSYS;
+
+	return ops->get_font(dev, seq, info);
+}
+
+int vidconsole_select_font(struct udevice *dev, const char *name, uint size)
+{
+	struct vidconsole_ops *ops = vidconsole_get_ops(dev);
+
+	if (!ops->select_font)
+		return -ENOSYS;
+
+	return ops->select_font(dev, name, size);
+}
+
 /* Set up the number of rows and colours (rotated drivers override this) */
 static int vidconsole_pre_probe(struct udevice *dev)
 {
diff --git a/include/video_console.h b/include/video_console.h
index d755eb73cf2..9d2c0f210e4 100644
--- a/include/video_console.h
+++ b/include/video_console.h
@@ -62,6 +62,15 @@ struct vidconsole_priv {
 	char escape_buf[32];
 };
 
+/**
+ * struct vidfont_info - information about a font
+ *
+ * @name: Font name, e.g. nimbus_sans_l_regular
+ */
+struct vidfont_info {
+	const char *name;
+};
+
 /**
  * struct vidconsole_ops - Video console operations
  *
@@ -111,6 +120,9 @@ struct vidconsole_ops {
 	/**
 	 * entry_start() - Indicate that text entry is starting afresh
 	 *
+	 * @dev:	Device to adjust
+	 * Returns: 0 on success, -ve on error
+	 *
 	 * Consoles which use proportional fonts need to track the position of
 	 * each character output so that backspace will return to the correct
 	 * place. This method signals to the console driver that a new entry
@@ -123,6 +135,9 @@ struct vidconsole_ops {
 	/**
 	 * backspace() - Handle erasing the last character
 	 *
+	 * @dev:	Device to adjust
+	 * Returns: 0 on success, -ve on error
+	 *
 	 * With proportional fonts the vidconsole uclass cannot itself erase
 	 * the previous character. This optional method will be called when
 	 * a backspace is needed. The driver should erase the previous
@@ -133,11 +148,53 @@ struct vidconsole_ops {
 	 * characters.
 	 */
 	int (*backspace)(struct udevice *dev);
+
+	/**
+	 * get_font() - Obtain information about a font (optional)
+	 *
+	 * @dev:	Device to check
+	 * @seq:	Font number to query (0=first, 1=second, etc.)
+	 * @info:	Returns font information on success
+	 * Returns: 0 on success, -ENOENT if no such font
+	 */
+	int (*get_font)(struct udevice *dev, int seq,
+			struct vidfont_info *info);
+
+	/**
+	 * select_font() - Select a particular font by name / size
+	 *
+	 * @dev:	Device to adjust
+	 * @name:	Font name to use (NULL to use default)
+	 * @size:	Font size to use (0 to use default)
+	 * Returns: 0 on success, -ENOENT if no such font
+	 */
+	int (*select_font)(struct udevice *dev, const char *name, uint size);
 };
 
 /* Get a pointer to the driver operations for a video console device */
 #define vidconsole_get_ops(dev)  ((struct vidconsole_ops *)(dev)->driver->ops)
 
+/**
+ * vidconsole_get_font() - Obtain information about a font
+ *
+ * @dev:	Device to check
+ * @seq:	Font number to query (0=first, 1=second, etc.)
+ * @info:	Returns font information on success
+ * Returns: 0 on success, -ENOENT if no such font, -ENOSYS if there is no such
+ * method
+ */
+int vidconsole_get_font(struct udevice *dev, int seq,
+			struct vidfont_info *info);
+
+/**
+ * vidconsole_select_font() - Select a particular font by name / size
+ *
+ * @dev:	Device to adjust
+ * @name:	Font name to use (NULL to use default)
+ * @size:	Font size to use (0 to use default)
+ */
+int vidconsole_select_font(struct udevice *dev, const char *name, uint size);
+
 /**
  * vidconsole_putc_xy() - write a single character to a position
  *
@@ -234,27 +291,21 @@ void vidconsole_set_cursor_pos(struct udevice *dev, int x, int y);
 /**
  * vidconsole_list_fonts() - List the available fonts
  *
- * This shows a list on the console
- */
-void vidconsole_list_fonts(void);
-
-/**
- * vidconsole_select_font() - Select a font to use
+ * @dev: vidconsole device to check
  *
- * @dev: vidconsole device
- * @name: Font name
- * @size: Size of the font (norminal pixel height) or 0 for default
+ * This shows a list of fonts known by this vidconsole. The list is displayed on
+ * the console (not necessarily @dev but probably)
  */
-int vidconsole_select_font(struct udevice *dev, const char *name, uint size);
+void vidconsole_list_fonts(struct udevice *dev);
 
 /**
- * vidconsole_get_font() - get the current font name and size
+ * vidconsole_get_font_size() - get the current font name and size
  *
  * @dev: vidconsole device
  * @sizep: Place to put the font size (nominal height in pixels)
  * Returns: Current font name
  */
-const char *vidconsole_get_font(struct udevice *dev, uint *sizep);
+const char *vidconsole_get_font_size(struct udevice *dev, uint *sizep);
 
 #ifdef CONFIG_VIDEO_COPY
 /**
diff --git a/test/cmd/font.c b/test/cmd/font.c
index 7a4156ade62..adb353965a7 100644
--- a/test/cmd/font.c
+++ b/test/cmd/font.c
@@ -33,7 +33,7 @@ static int font_test_base(struct unit_test_state *uts)
 	ut_assertok(ut_check_console_end(uts));
 
 	ut_asserteq_str("nimbus_sans_l_regular",
-			vidconsole_get_font(dev, &size));
+			vidconsole_get_font_size(dev, &size));
 	ut_asserteq(18, size);
 
 	max_metrics = 1;
@@ -53,14 +53,14 @@ static int font_test_base(struct unit_test_state *uts)
 	ut_assertok(ut_check_console_end(uts));
 
 	ut_asserteq_str("cantoraone_regular",
-			vidconsole_get_font(dev, &size));
+			vidconsole_get_font_size(dev, &size));
 	ut_asserteq(40, size);
 
 	ut_assertok(run_command("font size 30", 0));
 	ut_assertok(ut_check_console_end(uts));
 
 	ut_asserteq_str("cantoraone_regular",
-			vidconsole_get_font(dev, &size));
+			vidconsole_get_font_size(dev, &size));
 	ut_asserteq(30, size);
 
 	return 0;
-- 
2.38.1.431.g37b22c650d-goog



More information about the U-Boot mailing list