Create a measured line for the (single) line of text.

Signed-off-by: Simon Glass <s...@chromium.org>
---

 drivers/video/console_truetype.c | 36 +++++++++++++++++++++++---------
 test/dm/video.c                  | 13 +++++++++++-
 2 files changed, 38 insertions(+), 11 deletions(-)

diff --git a/drivers/video/console_truetype.c b/drivers/video/console_truetype.c
index 7b9033818d3..39d77ad9818 100644
--- a/drivers/video/console_truetype.c
+++ b/drivers/video/console_truetype.c
@@ -737,11 +737,13 @@ static int truetype_measure(struct udevice *dev, const 
char *name, uint size,
                            struct alist *lines)
 {
        struct console_tt_metrics *met;
+       struct vidconsole_mline mline;
+       const char *s;
        stbtt_fontinfo *font;
        int lsb, advance;
-       const char *s;
        int width;
-       int last;
+       int start;
+       int lastch;
        int ret;
 
        ret = get_metrics(dev, name, size, &met);
@@ -754,25 +756,39 @@ static int truetype_measure(struct udevice *dev, const 
char *name, uint size,
 
        font = &met->font;
        width = 0;
-       for (last = 0, s = text; *s; s++) {
+       bbox->y1 = 0;
+       start = 0;
+       for (lastch = 0, s = text; *s; s++) {
+               int neww;
                int ch = *s;
 
-               /* Used kerning to fine-tune the position of this character */
-               if (last)
-                       width += stbtt_GetCodepointKernAdvance(font, last, ch);
-
                /* First get some basic metrics about this character */
                stbtt_GetCodepointHMetrics(font, ch, &advance, &lsb);
+               neww = width + advance;
 
-               width += advance;
-               last = ch;
+               /* Use kerning to fine-tune the position of this character */
+               if (lastch)
+                       neww += stbtt_GetCodepointKernAdvance(font, lastch, ch);
+               lastch = ch;
+
+               width = neww;
        }
 
+       /* add the line */
+       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.start = start;
+       mline.len = (s - text) - start;
+       if (lines && !alist_add(lines, mline))
+               return log_msg_ret("ttM", -ENOMEM);
+
        bbox->valid = true;
        bbox->x0 = 0;
        bbox->y0 = 0;
        bbox->x1 = tt_ceil((double)width * met->scale);
-       bbox->y1 = met->font_size;
 
        return 0;
 }
diff --git a/test/dm/video.c b/test/dm/video.c
index cfc831b6931..d3fd74a9a9a 100644
--- a/test/dm/video.c
+++ b/test/dm/video.c
@@ -785,6 +785,7 @@ static int dm_test_font_measure(struct unit_test_state *uts)
                "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.";
+       const struct vidconsole_mline *line;
        struct vidconsole_bbox bbox;
        struct video_priv *priv;
        struct udevice *dev, *con;
@@ -798,13 +799,23 @@ 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);
+       alist_init_struct(&lines, struct vidconsole_mline);
        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);
+       ut_asserteq(1, lines.count);
+
+       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(0x12, line->bbox.y1);
+       ut_asserteq(0, line->start);
+       ut_asserteq(strlen(test_string), line->len);
 
        return 0;
 }
-- 
2.43.0

Reply via email to