expo: Support rendering multiple lines of text

Use the measurement info to write each line of text separately, thus
respecting word-wrapping and newlines.

Fix up the comment for scene_obj_render() while we are here.

Since a lineedit does not support alignment, add a special case to just
display the text if there is no measurement. This happens assuming the
lineedit is initially empty.

Signed-off-by: Simon Glass <sjg@chromium.org>
This commit is contained in:
Simon Glass
2025-05-02 08:46:42 -06:00
parent 638ba1db72
commit a2d70450dd
4 changed files with 41 additions and 5 deletions

View File

@@ -8,6 +8,7 @@
#define LOG_CATEGORY LOGC_EXPO
#include <alist.h>
#include <dm.h>
#include <expo.h>
#include <malloc.h>
@@ -163,6 +164,7 @@ int scene_txt_generic_init(struct expo *exp, struct scene_txt_generic *gen,
}
gen->str_id = str_id;
alist_init_struct(&gen->lines, struct vidconsole_mline);
return 0;
}
@@ -336,8 +338,8 @@ int scene_obj_get_hw(struct scene *scn, uint id, int *widthp)
struct scene_txt_generic *gen = &((struct scene_obj_txt *)obj)->gen;
struct expo *exp = scn->expo;
struct vidconsole_bbox bbox;
int len, ret, limit;
const char *str;
int len, ret;
str = expo_get_str(exp, gen->str_id);
if (!str)
@@ -351,8 +353,12 @@ int scene_obj_get_hw(struct scene *scn, uint id, int *widthp)
return 16;
}
limit = obj->flags & SCENEOF_SIZE_VALID ?
obj->bbox.x1 - obj->bbox.x0 : -1;
ret = vidconsole_measure(scn->expo->cons, gen->font_name,
gen->font_size, str, -1, &bbox, NULL);
gen->font_size, str, limit, &bbox,
&gen->lines);
if (ret)
return log_msg_ret("mea", ret);
if (widthp)
@@ -418,6 +424,7 @@ static int scene_txt_render(struct expo *exp, struct udevice *dev,
struct scene_txt_generic *gen, int x, int y,
int menu_inset)
{
const struct vidconsole_mline *mline;
struct video_priv *vid_priv;
struct vidconsole_colour old;
enum colour_idx fore, back;
@@ -453,8 +460,16 @@ static int scene_txt_render(struct expo *exp, struct udevice *dev,
video_fill_part(dev, x - menu_inset, y, obj->bbox.x1,
obj->bbox.y1, vid_priv->colour_bg);
}
vidconsole_set_cursor_pos(cons, x, y);
vidconsole_put_string(cons, str);
if (!gen->lines.count) {
vidconsole_set_cursor_pos(cons, x, y);
vidconsole_put_string(cons, str);
}
alist_for_each(mline, &gen->lines) {
vidconsole_set_cursor_pos(cons, x + mline->bbox.x0,
y + mline->bbox.y0);
vidconsole_put_stringn(cons, str + mline->start, mline->len);
}
if (obj->flags & SCENEOF_POINT)
vidconsole_pop_colour(cons, &old);
@@ -464,6 +479,9 @@ static int scene_txt_render(struct expo *exp, struct udevice *dev,
/**
* scene_obj_render() - Render an object
*
* @obj: Object to render
* @text_mode: true to use text mode
* Return: 0 if OK, -ve on error
*/
static int scene_obj_render(struct scene_obj *obj, bool text_mode)
{