Mercurial > hg > openttd
changeset 4954:e49e661e7761 draft
(svn r6953) -Codechange: Change FormatStringLinebreaks in such a way that if no whitespace was seen
for the 'current line' of a certain maximum width, the string will be truncated instead
of the old behaviour which just left it alone.
author | Darkvater <Darkvater@openttd.org> |
---|---|
date | Fri, 27 Oct 2006 09:55:38 +0000 |
parents | f53a206177ca |
children | 54ec41999863 |
files | gfx.c gfx.h |
diffstat | 2 files changed, 44 insertions(+), 18 deletions(-) [+] |
line wrap: on
line diff
--- a/gfx.c +++ b/gfx.c @@ -415,41 +415,66 @@ GfxFillRect((xl + xr - w) / 2, y + 10, (xl + xr + w) / 2, y + 10, _string_colorremap[1]); } -static uint32 FormatStringLinebreaks(char *str, int maxw) +/** 'Correct' a string to a maximum length. Longer strings will be cut into + * additional lines at whitespace characters if possible. The string parameter + * is modified with terminating characters mid-string which are the + * placeholders for the newlines.<br/> + * The string WILL be truncated if there was no whitespace for the current + * line's maximum width. + * + * @note To know if the the terminating '\0' is the string end or just a + * newline, the returned 'num' value should be consulted. The num'th '\0', + * starting with index 0 is the real string end. + * + * @param str string to check and correct for length restrictions + * @param maxw the maximum width the string can have on one line + * @return return a 32bit wide number consisting of 2 packed values: + * 0 - 15 the number of lines ADDED to the string + * 16 - 31 the fontsize in which the length calculation was done at */ +uint32 FormatStringLinebreaks(char *str, int maxw) { - int num = 0; FontSize size = _cur_fontsize; - int w; - char *last_space; - byte c; + int num = 0; + + assert(maxw > 0); for (;;) { - w = 0; - last_space = NULL; + char *last_space = NULL; + int w = 0; for (;;) { - c = *str++; + byte c = *str++; + /* whitespace is where we will insert the line-break */ if (c == ASCII_LETTERSTART) last_space = str; if (c >= ASCII_LETTERSTART) { w += GetCharacterWidth(size, c); + /* string is longer than maximum width so we need to decide what to + * do. We can do two things: + * 1. If no whitespace was found at all up until now (on this line) then + * we will truncate the string and bail out. + * 2. In all other cases force a linebreak at the last seen whitespace */ if (w > maxw) { + if (last_space == NULL) { + str[-1] = '\0'; + return num + (size << 16); + } str = last_space; - if (str == NULL) - return num + (size << 16); break; } } else { - if (c == 0) return num + (size << 16); - if (c == ASCII_NL) break; - - if (c == ASCII_SETX) str++; - else if (c == ASCII_SETXY) str += 2; - else if (c == ASCII_TINYFONT) size = FS_SMALL; - else if (c == ASCII_BIGFONT) size = FS_LARGE; + switch (c) { + case '\0': return num + (size << 16); break; + case ASCII_SETX: str++; break; + case ASCII_SETXY: str +=2; break; + case ASCII_TINYFONT: size = FS_SMALL; break; + case ASCII_BIGFONT: size = FS_LARGE; break; + case ASCII_NL: goto end_of_inner_loop; + } } } - +end_of_inner_loop: + /* string didn't fit on line, so 'dummy' terminate and increase linecount */ num++; str[-1] = '\0'; }
--- a/gfx.h +++ b/gfx.h @@ -68,6 +68,7 @@ void GfxDrawLine(int left, int top, int right, int bottom, int color); BoundingRect GetStringBoundingBox(const char *str); +uint32 FormatStringLinebreaks(char *str, int maxw); void LoadStringWidthTable(void); void DrawStringMultiCenter(int x, int y, StringID str, int maxw); uint DrawStringMultiLine(int x, int y, StringID str, int maxw);