video: Begin support for measuring multiple lines of text

Update the vidconsole API so that measure() can measure multiple lines
of text. This will make it easier to implement multi-line fields in
expo.

Tidy up the function comments while we are here.

Signed-off-by: Simon Glass <sjg@chromium.org>
This commit is contained in:
Simon Glass
2025-04-02 06:29:36 +13:00
committed by Tom Rini
parent 0d0b2341dd
commit 236ae39fb0
5 changed files with 49 additions and 18 deletions

View File

@@ -298,7 +298,7 @@ int scene_obj_get_hw(struct scene *scn, uint id, int *widthp)
} }
ret = vidconsole_measure(scn->expo->cons, txt->font_name, ret = vidconsole_measure(scn->expo->cons, txt->font_name,
txt->font_size, str, &bbox); txt->font_size, str, &bbox, NULL);
if (ret) if (ret)
return log_msg_ret("mea", ret); return log_msg_ret("mea", ret);
if (widthp) if (widthp)

View File

@@ -733,7 +733,8 @@ static int truetype_select_font(struct udevice *dev, const char *name,
} }
static int truetype_measure(struct udevice *dev, const char *name, uint size, static int truetype_measure(struct udevice *dev, const char *name, uint size,
const char *text, struct vidconsole_bbox *bbox) const char *text, struct vidconsole_bbox *bbox,
struct alist *lines)
{ {
struct console_tt_metrics *met; struct console_tt_metrics *met;
stbtt_fontinfo *font; stbtt_fontinfo *font;

View File

@@ -608,14 +608,17 @@ int vidconsole_select_font(struct udevice *dev, const char *name, uint size)
} }
int vidconsole_measure(struct udevice *dev, const char *name, uint size, int vidconsole_measure(struct udevice *dev, const char *name, uint size,
const char *text, struct vidconsole_bbox *bbox) const char *text, struct vidconsole_bbox *bbox,
struct alist *lines)
{ {
struct vidconsole_priv *priv = dev_get_uclass_priv(dev); struct vidconsole_priv *priv = dev_get_uclass_priv(dev);
struct vidconsole_ops *ops = vidconsole_get_ops(dev); struct vidconsole_ops *ops = vidconsole_get_ops(dev);
int ret; int ret;
if (ops->measure) { if (ops->measure) {
ret = ops->measure(dev, name, size, text, bbox); if (lines)
alist_empty(lines);
ret = ops->measure(dev, name, size, text, bbox, lines);
if (ret != -ENOSYS) if (ret != -ENOSYS)
return ret; return ret;
} }

View File

@@ -6,6 +6,7 @@
#ifndef __video_console_h #ifndef __video_console_h
#define __video_console_h #define __video_console_h
#include <alist.h>
#include <video.h> #include <video.h>
struct abuf; struct abuf;
@@ -119,6 +120,19 @@ struct vidconsole_bbox {
int y1; int y1;
}; };
/**
* vidconsole_mline - Holds information about a line of measured text
*
* @bbox: Bounding box of the line, assuming it starts at 0,0
* @start: String index of the first character in the line
* @len: Number of characters in the line
*/
struct vidconsole_mline {
struct vidconsole_bbox bbox;
int start;
int len;
};
/** /**
* struct vidconsole_ops - Video console operations * struct vidconsole_ops - Video console operations
* *
@@ -228,18 +242,23 @@ struct vidconsole_ops {
int (*select_font)(struct udevice *dev, const char *name, uint size); int (*select_font)(struct udevice *dev, const char *name, uint size);
/** /**
* measure() - Measure the bounds of some text * measure() - Measure the bounding box of some text
* *
* @dev: Device to adjust * @dev: Console device to use
* @name: Font name to use (NULL to use default) * @name: Font name to use (NULL to use default)
* @size: Font size to use (0 to use default) * @size: Font size to use (0 to use default)
* @text: Text to measure * @text: Text to measure
* @bbox: Returns bounding box of text, assuming it is positioned * @bbox: Returns bounding box of text, assuming it is positioned
* at 0,0 * at 0,0
* @lines: If non-NULL, this must be an alist of
* struct vidconsole_mline inited by caller. A separate
* record is added for each line of text
*
* Returns: 0 on success, -ENOENT if no such font * Returns: 0 on success, -ENOENT if no such font
*/ */
int (*measure)(struct udevice *dev, const char *name, uint size, int (*measure)(struct udevice *dev, const char *name, uint size,
const char *text, struct vidconsole_bbox *bbox); const char *text, struct vidconsole_bbox *bbox,
struct alist *lines);
/** /**
* nominal() - Measure the expected width of a line of text * nominal() - Measure the expected width of a line of text
@@ -320,19 +339,24 @@ int vidconsole_get_font(struct udevice *dev, int seq,
*/ */
int vidconsole_select_font(struct udevice *dev, const char *name, uint size); int vidconsole_select_font(struct udevice *dev, const char *name, uint size);
/* /**
* vidconsole_measure() - Measuring the bounding box of some text * vidconsole_measure() - Measure the bounding box of some text
* *
* @dev: Console device to use * @dev: Device to adjust
* @name: Font name, NULL for default * @name: Font name to use (NULL to use default)
* @size: Font size, ignored if @name is NULL * @size: Font size to use (0 to use default)
* @text: Text to measure * @text: Text to measure
* @bbox: Returns nounding box of text * @bbox: Returns bounding box of text, assuming it is positioned
* Returns: 0 if OK, -ve on error * at 0,0
* @lines: If non-NULL, this must be an alist of
* struct vidconsole_mline inited by caller. The list is emptied
* and then a separate record is added for each line of text
*
* Returns: 0 on success, -ENOENT if no such font
*/ */
int vidconsole_measure(struct udevice *dev, const char *name, uint size, int vidconsole_measure(struct udevice *dev, const char *name, uint size,
const char *text, struct vidconsole_bbox *bbox); const char *text, struct vidconsole_bbox *bbox,
struct alist *lines);
/** /**
* vidconsole_nominal() - Measure the expected width of a line of text * vidconsole_nominal() - Measure the expected width of a line of text
* *

View File

@@ -788,6 +788,7 @@ static int dm_test_font_measure(struct unit_test_state *uts)
struct vidconsole_bbox bbox; struct vidconsole_bbox bbox;
struct video_priv *priv; struct video_priv *priv;
struct udevice *dev, *con; struct udevice *dev, *con;
struct alist lines;
ut_assertok(uclass_get_device(UCLASS_VIDEO, 0, &dev)); ut_assertok(uclass_get_device(UCLASS_VIDEO, 0, &dev));
priv = dev_get_uclass_priv(dev); priv = dev_get_uclass_priv(dev);
@@ -797,11 +798,13 @@ static int dm_test_font_measure(struct unit_test_state *uts)
/* this is using the Nimbus font with size of 18 pixels */ /* this is using the Nimbus font with size of 18 pixels */
ut_assertok(uclass_get_device(UCLASS_VIDEO_CONSOLE, 0, &con)); ut_assertok(uclass_get_device(UCLASS_VIDEO_CONSOLE, 0, &con));
vidconsole_position_cursor(con, 0, 0); vidconsole_position_cursor(con, 0, 0);
ut_assertok(vidconsole_measure(con, NULL, 0, test_string, &bbox)); ut_assertok(vidconsole_measure(con, NULL, 0, test_string, &bbox,
&lines));
ut_asserteq(0, bbox.x0); ut_asserteq(0, bbox.x0);
ut_asserteq(0, bbox.y0); ut_asserteq(0, bbox.y0);
ut_asserteq(0x47a, bbox.x1); ut_asserteq(0x47a, bbox.x1);
ut_asserteq(0x12, bbox.y1); ut_asserteq(0x12, bbox.y1);
ut_asserteq(0, lines.count);
return 0; return 0;
} }