@@ -538,7 +538,7 @@ int scene_obj_get_hw(struct scene *scn, uint id, int *widthp)
obj->req_bbox.x1 - obj->req_bbox.x0 : -1;
ret = vidconsole_measure(scn->expo->cons, gen->font_name,
- gen->font_size, str, limit, &bbox,
+ gen->font_size, str, -1, limit, &bbox,
&gen->lines);
if (ret)
return log_msg_ret("mea", ret);
@@ -1004,12 +1004,12 @@ static int truetype_select_font(struct udevice *dev, void *vctx,
}
static int truetype_measure(struct udevice *dev, const char *name, uint size,
- const char *text, int pixel_limit,
+ const char *text, int len, int pixel_limit,
struct vidconsole_bbox *bbox, struct alist *lines)
{
struct console_tt_metrics *met;
struct vidconsole_mline mline;
- const char *s, *last_space;
+ const char *s, *last_space, *end;
int width, last_width;
stbtt_fontinfo *font;
int lsb, advance;
@@ -1030,6 +1030,7 @@ static int truetype_measure(struct udevice *dev, const char *name, uint size,
if (pixel_limit != -1)
limit = tt_ceil((double)pixel_limit / met->scale);
+ end = len < 0 ? NULL : text + len;
font = &met->font;
width = 0;
bbox->y1 = 0;
@@ -1037,7 +1038,7 @@ static int truetype_measure(struct udevice *dev, const char *name, uint size,
start = 0;
last_space = NULL;
last_width = 0;
- for (lastch = 0, s = text; *s; s++) {
+ for (lastch = 0, s = text; *s && s != end; s++) {
int neww;
int ch = *s;
@@ -1069,6 +1070,7 @@ static int truetype_measure(struct udevice *dev, const char *name, uint size,
mline.bbox.x0 = 0;
mline.bbox.y0 = bbox->y1;
mline.bbox.x1 = tt_ceil((double)width * met->scale);
+ mline.xpos = (int)((double)width * met->scale);
bbox->x1 = max(bbox->x1, mline.bbox.x1);
bbox->y1 += met->font_size;
mline.bbox.y1 = bbox->y1;
@@ -1095,6 +1097,7 @@ static int truetype_measure(struct udevice *dev, const char *name, uint size,
mline.bbox.x0 = 0;
mline.bbox.y0 = bbox->y1;
mline.bbox.x1 = tt_ceil((double)width * met->scale);
+ mline.xpos = (int)((double)width * met->scale);
bbox->y1 += met->font_size;
mline.bbox.y1 = bbox->y1;
mline.start = start;
@@ -665,7 +665,7 @@ int vidconsole_select_font(struct udevice *dev, void *ctx, const char *name,
}
int vidconsole_measure(struct udevice *dev, const char *name, uint size,
- const char *text, int limit,
+ const char *text, int len, int limit,
struct vidconsole_bbox *bbox, struct alist *lines)
{
struct vidconsole_ctx *ctx = vidconsole_ctx(dev);
@@ -675,7 +675,8 @@ int vidconsole_measure(struct udevice *dev, const char *name, uint size,
if (ops->measure) {
if (lines)
alist_empty(lines);
- ret = ops->measure(dev, name, size, text, limit, bbox, lines);
+ ret = ops->measure(dev, name, size, text, len, limit, bbox,
+ lines);
if (ret != -ENOSYS)
return ret;
}
@@ -683,7 +684,7 @@ int vidconsole_measure(struct udevice *dev, const char *name, uint size,
bbox->valid = true;
bbox->x0 = 0;
bbox->y0 = 0;
- bbox->x1 = ctx->x_charsize * strlen(text);
+ bbox->x1 = ctx->x_charsize * (len < 0 ? strlen(text) : len);
bbox->y1 = ctx->y_charsize;
return 0;
@@ -221,11 +221,13 @@ struct vidconsole_bbox {
* vidconsole_mline - Holds information about a line of measured text
*
* @bbox: Bounding box of the line, assuming it starts at 0,0
+ * @xpos: Cursor x position at end of line (truncated, not ceiled like bbox.x1)
* @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 xpos;
int start;
int len;
};
@@ -355,6 +357,7 @@ struct vidconsole_ops {
* @name: Font name to use (NULL to use default)
* @size: Font size to use (0 to use default)
* @text: Text to measure
+ * @len: Number of characters to measure, or -1 for whole string
* @limit: Width limit for each line, or -1 if none
* @bbox: Returns bounding box of text, assuming it is positioned
* at 0,0
@@ -365,7 +368,7 @@ struct vidconsole_ops {
* Returns: 0 on success, -ENOENT if no such font
*/
int (*measure)(struct udevice *dev, const char *name, uint size,
- const char *text, int limit,
+ const char *text, int len, int limit,
struct vidconsole_bbox *bbox, struct alist *lines);
/**
@@ -485,6 +488,7 @@ int vidconsole_select_font(struct udevice *dev, void *ctx, const char *name,
* @name: Font name to use (NULL to use default)
* @size: Font size to use (0 to use default)
* @text: Text to measure
+ * @len: Number of characters to measure, or -1 for whole string
* @limit: Width limit for each line, or -1 if none
* @bbox: Returns bounding box of text, assuming it is positioned
* at 0,0
@@ -495,7 +499,7 @@ int vidconsole_select_font(struct udevice *dev, void *ctx, const char *name,
* Returns: 0 on success, -ENOENT if no such font
*/
int vidconsole_measure(struct udevice *dev, const char *name, uint size,
- const char *text, int limit,
+ const char *text, int len, int limit,
struct vidconsole_bbox *bbox, struct alist *lines);
/**
* vidconsole_nominal() - Measure the expected width of a line of text
@@ -982,7 +982,7 @@ static int dm_test_font_measure(struct unit_test_state *uts)
ut_assertok(uclass_get_device(UCLASS_VIDEO_CONSOLE, 0, &con));
vidconsole_position_cursor(con, 0, 0);
alist_init_struct(&lines, struct vidconsole_mline);
- ut_assertok(vidconsole_measure(con, NULL, 0, test_string, -1, &bbox,
+ ut_assertok(vidconsole_measure(con, NULL, 0, test_string, -1, -1, &bbox,
&lines));
ut_asserteq(0, bbox.x0);
ut_asserteq(0, bbox.y0);
@@ -1013,8 +1013,8 @@ static int dm_test_font_measure(struct unit_test_state *uts)
ut_asserteq(strlen(test_string + nl + 1), line->len);
/* now use a limit on the width */
- ut_assertok(vidconsole_measure(con, NULL, 0, test_string, limit, &bbox,
- &lines));
+ ut_assertok(vidconsole_measure(con, NULL, 0, test_string, -1, limit,
+ &bbox, &lines));
ut_asserteq(0, bbox.x0);
ut_asserteq(0, bbox.y0);
ut_asserteq(0x31e, bbox.x1);