summaryrefslogtreecommitdiff
path: root/src/gfx.cpp
diff options
context:
space:
mode:
authorrubidium <rubidium@openttd.org>2009-10-13 20:19:34 +0000
committerrubidium <rubidium@openttd.org>2009-10-13 20:19:34 +0000
commit3bb1f4217dcb229c2e064e9f0e1d58a757474cc0 (patch)
treee06f35be311d13016ca78baa6bf5972cf9dff6de /src/gfx.cpp
parent313fb659433b0af187e04185d0b7875889548372 (diff)
downloadopenttd-3bb1f4217dcb229c2e064e9f0e1d58a757474cc0.tar.xz
(svn r17772) -Fix [FS#3264]: CJK languages don't have spaces, so for adding newlines (multi line strings) we need to (properly) handle the case when there are no spaces instead of truncating the string.
Diffstat (limited to 'src/gfx.cpp')
-rw-r--r--src/gfx.cpp57
1 files changed, 45 insertions, 12 deletions
diff --git a/src/gfx.cpp b/src/gfx.cpp
index 328e6da1c..8b9c09360 100644
--- a/src/gfx.cpp
+++ b/src/gfx.cpp
@@ -619,12 +619,13 @@ int DrawString(int left, int right, int top, StringID str, TextColour colour, St
* starting with index 0 is the real string end.
*
* @param str string to check and correct for length restrictions
+ * @param last the last valid location (for '\0') in the buffer of str
* @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)
+uint32 FormatStringLinebreaks(char *str, const char *last, int maxw)
{
FontSize size = _cur_fontsize;
int num = 0;
@@ -632,6 +633,7 @@ uint32 FormatStringLinebreaks(char *str, int maxw)
assert(maxw > 0);
for (;;) {
+ /* The character *after* the last space. */
char *last_space = NULL;
int w = 0;
@@ -641,18 +643,49 @@ uint32 FormatStringLinebreaks(char *str, int maxw)
if (IsWhitespace(c)) last_space = str;
if (IsPrintable(c)) {
- 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 */
+ int char_w = GetCharacterWidth(size, c);
+ w += char_w;
if (w > maxw) {
- if (last_space == NULL) {
- *Utf8PrevChar(str) = '\0';
+ /* The string is longer than maximum width so we need to decide
+ * what to do with it. */
+ if (w == char_w) {
+ /* The character is wider than allowed width; don't know
+ * what to do with this case... bail out! */
return num + (size << 16);
}
- str = last_space;
+ if (last_space == NULL) {
+ /* No space has been found. Just terminate at our current
+ * location. This usually happens for languages that do not
+ * require spaces in strings, like Chinese, Japanese and
+ * Korean. For other languages terminating mid-word might
+ * not be the best, but terminating the whole string instead
+ * of continuing the word at the next line is worse. */
+ str = Utf8PrevChar(str);
+ size_t len = strlen(str);
+ char *terminator = str + len;
+
+ /* The string location + length of the string + 1 for '\0'
+ * always fits; otherwise there's no trailing '\0' and it
+ * it not a valid string. */
+ assert(terminator <= last);
+ assert(*terminator == '\0');
+
+ /* If the string is too long we have to terminate it earlier. */
+ if (terminator == last) {
+ /* Get the 'begin' of the previous character and make that
+ * the terminator of the string; we truncate it 'early'. */
+ *Utf8PrevChar(terminator) = '\0';
+ len = strlen(str);
+ }
+ /* Also move the terminator! */
+ memmove(str + 1, str, len + 1);
+ *str = '\0';
+ /* str needs to point to the character *after* the last space */
+ str++;
+ } else {
+ /* A space is found; perfect place to terminate */
+ str = last_space;
+ }
break;
}
} else {
@@ -721,7 +754,7 @@ int GetStringHeight(StringID str, int maxw)
GetString(buffer, str, lastof(buffer));
- uint32 tmp = FormatStringLinebreaks(buffer, maxw);
+ uint32 tmp = FormatStringLinebreaks(buffer, lastof(buffer), maxw);
return GetMultilineStringHeight(buffer, GB(tmp, 0, 16));
}
@@ -761,7 +794,7 @@ int DrawStringMultiLine(int left, int right, int top, int bottom, StringID str,
char buffer[DRAW_STRING_BUFFER];
GetString(buffer, str, lastof(buffer));
- uint32 tmp = FormatStringLinebreaks(buffer, maxw);
+ uint32 tmp = FormatStringLinebreaks(buffer, lastof(buffer), maxw);
int num = GB(tmp, 0, 16);
int mt = GetCharacterHeight((FontSize)GB(tmp, 16, 16));