(svn r6953) -Codechange: Change FormatStringLinebreaks in such a way that if no whitespace was seen
authorDarkvater
Fri, 27 Oct 2006 09:55:38 +0000
changeset 4954 d773d01b35f5
parent 4953 6c40b2b16164
child 4955 e3496ee0e37d
(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.
gfx.c
gfx.h
--- a/gfx.c	Thu Oct 26 19:16:10 2006 +0000
+++ b/gfx.c	Fri Oct 27 09:55:38 2006 +0000
@@ -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)
 {
+	FontSize size = _cur_fontsize;
 	int num = 0;
-	FontSize size = _cur_fontsize;
-	int w;
-	char *last_space;
-	byte c;
+
+	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	Thu Oct 26 19:16:10 2006 +0000
+++ b/gfx.h	Fri Oct 27 09:55:38 2006 +0000
@@ -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);