From: divverent Date: Fri, 25 Dec 2009 11:52:59 +0000 (+0000) Subject: improve text word wrapping X-Git-Tag: xonotic-v0.1.0preview~960 X-Git-Url: https://git.rm.cloudns.org/?a=commitdiff_plain;h=c9f38312122eeb50f64dd2432243f1e587f50ac7;p=xonotic%2Fdarkplaces.git improve text word wrapping git-svn-id: svn://svn.icculus.org/twilight/trunk/darkplaces@9688 d7cf8633-e32d-0410-b094-e92efae38249 --- diff --git a/common.c b/common.c index c002be8d..26997319 100644 --- 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 diff --git a/console.c b/console.c index 4adf5af4..8bb622ae 100644 --- 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 diff --git a/gl_draw.c b/gl_draw.c index efde7524..1f9aa358 100644 --- 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)