From: Simon Glass Date: Tue, 1 Apr 2025 17:29:38 +0000 (+1300) Subject: video: truetype: Support newlines in the measured string X-Git-Tag: v2025.07-rc2~43^2~6 X-Git-Url: http://git.openpandora.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=030e53aaaa0f050a4059d4ae6297c224c9013d88;p=pandora-u-boot.git video: truetype: Support newlines in the measured string 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 --- 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; }