[bugfix] font_getstringnsize() incorrect count, add font_measurestring()

rockbox-gerrit-noreply--- via rockbox-cvs <[email protected]> Thu, 14 May 2026 09:53:18 -0400
Newsgroups gmane.comp.systems.archos.rockbox.cvs
Message-ID <[email protected]>
commit db32a7f07efc1696c7e2ddb3e2c914963138ea51
Author: William Wilgus <[email protected]>
Date:   Thu May 14 09:44:58 2026 -0400

    [bugfix] font_getstringnsize() incorrect count, add font_measurestring()
    
    maxbytes counted final characters not actual bytes
    
    font_measurestring() returns the number of bytes of a string that will
    fit in a given width
    
    Change-Id: Id73b763267e399bd558f87872b5e715076f9b7f7

diff --git a/firmware/export/font.h b/firmware/export/font.h
index 604635f985..6ec87b49e3 100644
--- a/firmware/export/font.h
+++ b/firmware/export/font.h
@@ -132,6 +132,7 @@ void font_disable_all(void);
 void font_enable_all(void);
 
 struct font* font_get(int font);
+int font_measurestring(const unsigned char *str, size_t maxbytes, int *max_width, int fontnum);
 int font_getstringnsize(const unsigned char *str, size_t maxbytes, int *w, int *h, int fontnumber);
 int font_getstringsize(const unsigned char *str, int *w, int *h, int fontnumber);
 int font_get_width(struct font* ft, ucschar_t ch);
diff --git a/firmware/font.c b/firmware/font.c
index 689445692b..2c07f8793d 100644
--- a/firmware/font.c
+++ b/firmware/font.c
@@ -1104,6 +1104,43 @@ const unsigned char* font_get_bits(struct font* pf, ucschar_t char_code)
 
 #endif /* BOOTLOADER */
 
+/*
+ * Returns the length (in bytes) of a given NULL terminated string
+ *  stops after max_width, maxbytes or NULL (\0) whichever occurs first.
+ */
+int font_measurestring(const unsigned char *str, size_t maxbytes, int *max_width, int fontnum)
+{
+    const unsigned char *start = str;
+    size_t bytes;
+    struct font* pf = font_get(fontnum);
+    font_lock( fontnum, true );
+    ucschar_t ch;
+    int width = 0;
+
+    while (true)
+    {
+        bytes = str - start;
+        str = utf8decode(str, &ch);
+        if (ch == 0 || bytes >= maxbytes)
+        {
+            break;
+        }
+        if (IS_DIACRITIC(ch))
+            continue;
+        int w = font_get_width(pf,ch);
+        if (width + w > *max_width)
+        {
+            break;
+        }
+        width += w;
+    }
+
+    *max_width = width;
+    font_lock( fontnum, false );
+
+    return bytes;
+}
+
 /*
  * Returns the stringsize of a given NULL terminated string
  *  stops after maxbytes or NULL (\0) whichever occurs first.
@@ -1112,17 +1149,21 @@ const unsigned char* font_get_bits(struct font* pf, ucschar_t char_code)
  */
 int font_getstringnsize(const unsigned char *str, size_t maxbytes, int *w, int *h, int fontnum)
 {
+    const unsigned char *start = str;
+    size_t bytes;
     struct font* pf = font_get(fontnum);
     font_lock( fontnum, true );
     ucschar_t ch;
     int width = 0;
-    size_t b = maxbytes - 1;
 
-    for (str = utf8decode(str, &ch); ch != 0 && b < maxbytes; str = utf8decode(str, &ch), b--)
+    while (true)
     {
+        bytes = str - start;
+        str = utf8decode(str, &ch);
+        if (ch == 0 || bytes >= maxbytes)
+            break;
         if (IS_DIACRITIC(ch))
             continue;
-
         /* get proportional width and glyph bits*/
         width += font_get_width(pf,ch);
     }
-- 
rockbox-cvs mailing list
[email protected]
https://lists.haxx.se/mailman/listinfo/rockbox-cvs