diff options
author | Martin Kiewitz | 2016-02-05 14:13:45 +0100 |
---|---|---|
committer | Martin Kiewitz | 2016-02-05 14:13:45 +0100 |
commit | efb65324688f20cc534a25312f558f9264125762 (patch) | |
tree | f181d4b800f8ce6421a0356f228d7cc89141a5e6 /engines/agi | |
parent | 29b37f473cf7fdab300d3a2cc389741722495fb1 (diff) | |
download | scummvm-rg350-efb65324688f20cc534a25312f558f9264125762.tar.gz scummvm-rg350-efb65324688f20cc534a25312f558f9264125762.tar.bz2 scummvm-rg350-efb65324688f20cc534a25312f558f9264125762.zip |
AGI: Rewrote stringWordWrap()
Original code wasn't accurate
Diffstat (limited to 'engines/agi')
-rw-r--r-- | engines/agi/text.cpp | 138 |
1 files changed, 79 insertions, 59 deletions
diff --git a/engines/agi/text.cpp b/engines/agi/text.cpp index fbc626ca9c..965de69335 100644 --- a/engines/agi/text.cpp +++ b/engines/agi/text.cpp @@ -921,91 +921,111 @@ void TextMgr::stringRememberForAutoComplete(bool entered) { } /** - * Wrap text line to the specified width. - * @param str String to wrap. - * @param len Length of line. - * - * Based on GBAGI implementation with permission from the author + * Wraps text line to the specified width. + * @param originalText String to wrap. + * @param maxWidth Length of line. */ char *TextMgr::stringWordWrap(const char *originalText, int16 maxWidth, int16 *calculatedWidthPtr, int16 *calculatedHeightPtr) { - static char resultWrapBuffer[2000]; - char *outStr = resultWrapBuffer; - const char *wordStartPtr; - int16 lineLen = 0; - int16 wordLen = 0; - int curMaxWidth = 0; - int curHeight = 0; + static char resultWrappedBuffer[2000]; + int16 boxWidth = 0; + int16 boxHeight = 0; + int16 lineWidth = 0; // width of current line - assert(maxWidth > 0); // this routine would create heap corruption in case maxWidth <= 0 + int16 lineWidthLeft = maxWidth; // width left of current line - while (*originalText) { - wordStartPtr = originalText; + int16 wordStartPos = 0; + int16 wordLen = 0; + int16 curReadPos = 0; + int16 curWritePos = 0; + byte wordEndChar = 0; - while (*originalText != '\0' && *originalText != ' ' && *originalText != '\n' && *originalText != '\r') - originalText++; + //memset(resultWrappedBuffer, 0, sizeof(resultWrappedBuffer)); for debugging - wordLen = originalText - wordStartPtr; + while (originalText[curReadPos]) { + // Try to find out length of next word + while (originalText[curReadPos]) { + if (originalText[curReadPos] == ' ') + break; + if (originalText[curReadPos] == 0x0A) + break; + curReadPos++; + } + wordEndChar = originalText[curReadPos]; - if (wordLen && *originalText == '\n' && originalText[-1] == ' ') - wordLen--; + // Calculate word length + wordLen = curReadPos - wordStartPos; - if (wordLen + lineLen >= maxWidth) { - // Check if outStr isn't msgBuf. If this is the case, outStr hasn't advanced - // yet, so no output has been written yet - if (outStr != resultWrapBuffer) { - if (outStr[-1] == ' ') - outStr[-1] = '\n'; - else - *outStr++ = '\n'; + if (wordLen >= lineWidthLeft) { + // Not enough space left + if (wordLen > maxWidth) { + // Word way too long, split it in half + curReadPos = curReadPos - (wordLen - maxWidth); + wordLen = maxWidth; } - curHeight++; - - lineLen = 0; - while (wordLen >= maxWidth) { - curMaxWidth = maxWidth; + // Add new line + resultWrappedBuffer[curWritePos++] = 0x0A; + if (lineWidth > boxWidth) + boxWidth = lineWidth; + boxHeight++; lineWidth = 0; + lineWidthLeft = maxWidth; - memcpy(outStr, wordStartPtr, maxWidth); + // Reached absolute maximum? -> exit now + if (boxHeight >= HEIGHT_MAX) + break; - wordLen -= maxWidth; - outStr += maxWidth; - wordStartPtr += maxWidth; - *outStr++ = '\n'; - curHeight++; + // If first character right after the new line is a space, skip over it + if (wordLen) { + if (originalText[wordStartPos] == ' ') { + wordStartPos++; + wordLen--; + } } } - if (wordLen) { - memcpy(outStr, wordStartPtr, wordLen); - outStr += wordLen; - } - lineLen += wordLen + 1; + // Copy current word over + memcpy(&resultWrappedBuffer[curWritePos], &originalText[wordStartPos], wordLen); + lineWidth += wordLen; + lineWidthLeft -= wordLen; + curWritePos += wordLen; - if (lineLen > curMaxWidth) { - curMaxWidth = lineLen; + if (wordEndChar == 0x0A) { + // original text had a new line, so force it + curReadPos++; - if (*originalText == '\0' || *originalText == ' ' || *originalText == '\n' || *originalText == '\r') - curMaxWidth--; - } + resultWrappedBuffer[curWritePos++] = 0x0A; + if (lineWidth > boxWidth) + boxWidth = lineWidth; + boxHeight++; lineWidth = 0; + lineWidthLeft = maxWidth; - if (*originalText == '\n') { - lineLen = 0; - curHeight++; + // Reached absolute maximum? -> exit now + if (boxHeight >= HEIGHT_MAX) + break; } - if (*originalText) - *outStr++ = *originalText++; + wordStartPos = curReadPos; + + // Last word ended with a space, skip this space for reading the next word + if (wordEndChar == ' ') + curReadPos++; + } + + resultWrappedBuffer[curWritePos] = 0; + + if (curReadPos > 0) { + if (lineWidth > boxWidth) + boxWidth = lineWidth; + boxHeight++; } - *outStr = '\0'; - curHeight++; if (calculatedWidthPtr) { - *calculatedWidthPtr = curMaxWidth; + *calculatedWidthPtr = boxWidth; } if (calculatedHeightPtr) { - *calculatedHeightPtr = curHeight; + *calculatedHeightPtr = boxHeight; } - return resultWrapBuffer; + return resultWrappedBuffer; } // =============================================================== |