aboutsummaryrefslogtreecommitdiff
path: root/engines/agi
diff options
context:
space:
mode:
authorMartin Kiewitz2016-02-05 14:13:45 +0100
committerMartin Kiewitz2016-02-05 14:13:45 +0100
commitefb65324688f20cc534a25312f558f9264125762 (patch)
treef181d4b800f8ce6421a0356f228d7cc89141a5e6 /engines/agi
parent29b37f473cf7fdab300d3a2cc389741722495fb1 (diff)
downloadscummvm-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.cpp138
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;
}
// ===============================================================