It is useful to be able to embed newline characters in the string and have the text measured into multiple lines. Add support for this.
Signed-off-by: Simon Glass <s...@chromium.org> --- drivers/video/console_truetype.c | 25 ++++++++++++++++++++++++- include/video_console.h | 4 ++++ test/dm/video.c | 26 ++++++++++++++++++++------ 3 files changed, 48 insertions(+), 7 deletions(-) diff --git a/drivers/video/console_truetype.c b/drivers/video/console_truetype.c index 39d77ad9818..6eca5d7f543 100644 --- a/drivers/video/console_truetype.c +++ b/drivers/video/console_truetype.c @@ -771,10 +771,33 @@ static int truetype_measure(struct udevice *dev, const char *name, uint size, neww += stbtt_GetCodepointKernAdvance(font, lastch, ch); lastch = ch; + /* see if we need to start a new line */ + if (ch == '\n') { + mline.bbox.x0 = 0; + mline.bbox.y0 = bbox->y1; + mline.bbox.x1 = tt_ceil((double)width * met->scale); + bbox->y1 += met->font_size; + mline.bbox.y1 = bbox->y1; + mline.bbox.valid = true; + mline.start = start; + mline.len = (s - text) - start; + if (lines && !alist_add(lines, mline)) + return log_msg_ret("ttm", -ENOMEM); + log_debug("line x1 %d y0 %d y1 %d start %d len %d text '%.*s'\n", + mline.bbox.x1, mline.bbox.y0, mline.bbox.y1, + mline.start, mline.len, mline.len, text + mline.start); + + start = s - text; + if (ch == '\n') + start++; + lastch = 0; + neww = 0; + } + width = neww; } - /* add the line */ + /* add the final line */ mline.bbox.x0 = 0; mline.bbox.y0 = bbox->y1; mline.bbox.x1 = tt_ceil((double)width * met->scale); diff --git a/include/video_console.h b/include/video_console.h index ee9ce3c0e37..a0ee9ab62e9 100644 --- a/include/video_console.h +++ b/include/video_console.h @@ -244,6 +244,8 @@ struct vidconsole_ops { /** * measure() - Measure the bounding box of some text * + * The text can include newlines + * * @dev: Console device to use * @name: Font name to use (NULL to use default) * @size: Font size to use (0 to use default) @@ -342,6 +344,8 @@ int vidconsole_select_font(struct udevice *dev, const char *name, uint size); /** * vidconsole_measure() - Measure the bounding box of some text * + * The text can include newlines + * * @dev: Device to adjust * @name: Font name to use (NULL to use default) * @size: Font size to use (0 to use default) diff --git a/test/dm/video.c b/test/dm/video.c index d3fd74a9a9a..a3f3b046882 100644 --- a/test/dm/video.c +++ b/test/dm/video.c @@ -781,7 +781,7 @@ DM_TEST(dm_test_video_damage, UTF_SCAN_PDATA | UTF_SCAN_FDT); /* Test font measurement */ static int dm_test_font_measure(struct unit_test_state *uts) { - const char *test_string = "There is always much to be said for not " + const char *test_string = "There is always much\nto be said for not " "attempting more than you can do and for making a certainty of " "what you try. But this principle, like others in life and " "war, has its exceptions."; @@ -790,6 +790,7 @@ static int dm_test_font_measure(struct unit_test_state *uts) struct video_priv *priv; struct udevice *dev, *con; struct alist lines; + int nl; ut_assertok(uclass_get_device(UCLASS_VIDEO, 0, &dev)); priv = dev_get_uclass_priv(dev); @@ -804,18 +805,31 @@ static int dm_test_font_measure(struct unit_test_state *uts) &lines)); ut_asserteq(0, bbox.x0); ut_asserteq(0, bbox.y0); - ut_asserteq(0x47a, bbox.x1); - ut_asserteq(0x12, bbox.y1); - ut_asserteq(1, lines.count); + ut_asserteq(0x3ea, bbox.x1); + ut_asserteq(0x24, bbox.y1); + ut_asserteq(2, lines.count); + + nl = strchr(test_string, '\n') - test_string; line = alist_get(&lines, 0, struct vidconsole_mline); ut_assertnonnull(line); ut_asserteq(0, line->bbox.x0); ut_asserteq(0, line->bbox.y0); - ut_asserteq(0x47a, line->bbox.x1); + ut_asserteq(0x8c, line->bbox.x1); ut_asserteq(0x12, line->bbox.y1); ut_asserteq(0, line->start); - ut_asserteq(strlen(test_string), line->len); + ut_asserteq(20, line->len); + ut_asserteq(nl, line->len); + + line++; + ut_asserteq(0x0, line->bbox.x0); + ut_asserteq(0x12, line->bbox.y0); + ut_asserteq(0x3ea, line->bbox.x1); + ut_asserteq(0x24, line->bbox.y1); + ut_asserteq(21, line->start); + ut_asserteq(nl + 1, line->start); + ut_asserteq(163, line->len); + ut_asserteq(strlen(test_string + nl + 1), line->len); return 0; } -- 2.43.0