]> git.xonotic.org Git - xonotic/darkplaces.git/commitdiff
improve text word wrapping
authordivverent <divverent@d7cf8633-e32d-0410-b094-e92efae38249>
Fri, 25 Dec 2009 11:52:59 +0000 (11:52 +0000)
committerdivverent <divverent@d7cf8633-e32d-0410-b094-e92efae38249>
Fri, 25 Dec 2009 11:52:59 +0000 (11:52 +0000)
git-svn-id: svn://svn.icculus.org/twilight/trunk/darkplaces@9688 d7cf8633-e32d-0410-b094-e92efae38249

common.c
console.c
gl_draw.c

index c002be8d769b8b8314140f9068e54beb4b4f87f1..26997319654de8e385b1e13e0335fab5be1ffcef 100644 (file)
--- a/common.c
+++ b/common.c
@@ -670,6 +670,9 @@ would be good for any more. At the beginning of the string, it will be called
 for the char 0 to initialize a clean state, and then once with the string " "
 (a space) so the routine knows how long a space is.
 
+In case no single character fits into the given width, the wordWidth function
+must return the width of exactly one character.
+
 Wrapped lines get the isContinuation flag set and are continuationWidth less wide.
 
 The sum of the return values of the processLine function will be returned.
@@ -739,7 +742,7 @@ int COM_Wordwrap(const char *string, size_t length, float continuationWidth, flo
                                }
                                out_inner:
                                spaceUsedForWord = wordWidth(passthroughCW, cursor, &wordLen, maxWidth - continuationWidth); // this may have reduced wordLen when it won't fit - but this is GOOD. TODO fix words that do fit in a non-continuation line
-                               if(wordLen < 1)
+                               if(wordLen < 1) // cannot happen according to current spec of wordWidth
                                {
                                        wordLen = 1;
                                        spaceUsedForWord = maxWidth + 1; // too high, forces it in a line of itself
index 4adf5af4bbe4133cdcf5661cb33ca5cba62ccd94..8bb622aef09866685854faf3111a130ef981897c 100644 (file)
--- a/console.c
+++ b/console.c
@@ -1422,14 +1422,8 @@ float Con_WordWidthFunc(void *passthrough, const char *w, size_t *length, float
                ti->colorindex = -1;
                return ti->fontsize * ti->font->maxwidth;
        }
-       /*
        if(maxWidth >= 0)
-               return DrawQ_TextWidth_Font_UntilWidth(w, length, false, ti->font, maxWidth / ti->fontsize) * ti->fontsize;
-       else if(maxWidth == -1)
-               return DrawQ_TextWidth_Font(w, *length, false, ti->font) * ti->fontsize;
-       */
-       if(maxWidth >= 0)
-               return DrawQ_TextWidth_Font_UntilWidth_Size(w, ti->fontsize, ti->fontsize, length, false, ti->font, maxWidth);
+               return DrawQ_TextWidth_Font_UntilWidth_Size(w, ti->fontsize, ti->fontsize, length, false, ti->font, -maxWidth); // -maxWidth: we want at least one char
        else if(maxWidth == -1)
                return DrawQ_TextWidth_Font_Size(w, ti->fontsize, ti->fontsize, *length, false, ti->font);
        else
index efde7524d59544e7a2aecffbbc582da55b9ae151..1f9aa358bf02dc0e9d505044b6e316d3a9c4c3b6 100644 (file)
--- a/gl_draw.c
+++ b/gl_draw.c
@@ -1073,6 +1073,7 @@ static void DrawQ_GetTextColor(float color[4], int colorindex, float r, float g,
        }
 }
 
+// NOTE: this function always draws exactly one character if maxwidth <= 0
 float DrawQ_TextWidth_Font_UntilWidth_TrackColors_Size(const char *text, float w, float h, size_t *maxlen, int *outcolor, qboolean ignorecolorcodes, const dp_font_t *fnt, float maxwidth)
 {
        const char *text_start = text;
@@ -1091,6 +1092,7 @@ float DrawQ_TextWidth_Font_UntilWidth_TrackColors_Size(const char *text, float w
        ft2_font_t *ft2 = fnt->ft2;
        // float ftbase_x;
        qboolean snap = true;
+       qboolean least_one = false;
 
        if (!h) h = w;
        if (!h) {
@@ -1121,9 +1123,16 @@ float DrawQ_TextWidth_Font_UntilWidth_TrackColors_Size(const char *text, float w
 
        // maxwidth /= fnt->scale; // w and h are multiplied by it already
        // ftbase_x = snap_to_pixel_x(0);
+       
+       if(maxwidth <= 0)
+       {
+               least_one = true;
+               maxwidth = -maxwidth;
+       }
 
        for (i = 0;((bytes_left = *maxlen - (text - text_start)) > 0) && *text;)
        {
+               size_t i0 = i;
                nextch = ch = u8_getnchar(text, &text, bytes_left);
                i = text - text_start;
                if (!ch)
@@ -1132,8 +1141,12 @@ float DrawQ_TextWidth_Font_UntilWidth_TrackColors_Size(const char *text, float w
                        x = snap_to_pixel_x(x, 0.4);
                if (ch == ' ' && !fontmap)
                {
+                       if(!least_one || i0) // never skip the first character
                        if(x + fnt->width_of[(int) ' '] * w > maxwidth)
+                       {
+                               i = i0;
                                break; // oops, can't draw this
+                       }
                        x += fnt->width_of[(int) ' '] * w;
                        continue;
                }
@@ -1200,8 +1213,12 @@ float DrawQ_TextWidth_Font_UntilWidth_TrackColors_Size(const char *text, float w
                        if (fontmap)
                                map = ft2_oldstyle_map;
                        prevch = 0;
+                       if(!least_one || i0) // never skip the first character
                        if(x + fnt->width_of[ch] * w > maxwidth)
+                       {
+                               i = i0;
                                break; // oops, can't draw this
+                       }
                        x += fnt->width_of[ch] * w;
                } else {
                        if (!map || map == ft2_oldstyle_map || map->start < ch || map->start + FONT_CHARS_PER_MAP >= ch)