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,
txt->font_size, str, &bbox);
txt->font_size, str, &bbox, NULL);
if (ret)
return log_msg_ret("mea", ret);
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,
const char *text, struct vidconsole_bbox *bbox)
const char *text, struct vidconsole_bbox *bbox,
struct alist *lines)
{
struct console_tt_metrics *met;
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,
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_ops *ops = vidconsole_get_ops(dev);
int ret;
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)
return ret;
}

View File

@@ -6,6 +6,7 @@
#ifndef __video_console_h
#define __video_console_h
#include <alist.h>
#include <video.h>
struct abuf;
@@ -119,6 +120,19 @@ struct vidconsole_bbox {
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
*
@@ -228,18 +242,23 @@ struct vidconsole_ops {
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)
* @size: Font size to use (0 to use default)
* @text: Text to measure
* @bbox: Returns bounding box of text, assuming it is positioned
* 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
*/
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
@@ -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);
/*
* vidconsole_measure() - Measuring the bounding box of some text
/**
* vidconsole_measure() - Measure the bounding box of some text
*
* @dev: Console device to use
* @name: Font name, NULL for default
* @size: Font size, ignored if @name is NULL
* @text: Text to measure
* @bbox: Returns nounding box of text
* Returns: 0 if OK, -ve on error
* @dev: Device to adjust
* @name: Font name to use (NULL to use default)
* @size: Font size to use (0 to use default)
* @text: Text to measure
* @bbox: Returns bounding box of text, assuming it is positioned
* 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,
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
*

View File

@@ -788,6 +788,7 @@ static int dm_test_font_measure(struct unit_test_state *uts)
struct vidconsole_bbox bbox;
struct video_priv *priv;
struct udevice *dev, *con;
struct alist lines;
ut_assertok(uclass_get_device(UCLASS_VIDEO, 0, &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 */
ut_assertok(uclass_get_device(UCLASS_VIDEO_CONSOLE, 0, &con));
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.y0);
ut_asserteq(0x47a, bbox.x1);
ut_asserteq(0x12, bbox.y1);
ut_asserteq(0, lines.count);
return 0;
}