[Scummvm-cvs-logs] scummvm master -> efb65324688f20cc534a25312f558f9264125762

m-kiewitz m_kiewitz at users.sourceforge.net
Fri Feb 5 14:14:17 CET 2016


This automated email contains information about 1 new commit which have been
pushed to the 'scummvm' repo located at https://github.com/scummvm/scummvm .

Summary:
efb6532468 AGI: Rewrote stringWordWrap()


Commit: efb65324688f20cc534a25312f558f9264125762
    https://github.com/scummvm/scummvm/commit/efb65324688f20cc534a25312f558f9264125762
Author: Martin Kiewitz (m_kiewitz at users.sourceforge.net)
Date: 2016-02-05T14:13:45+01:00

Commit Message:
AGI: Rewrote stringWordWrap()

Original code wasn't accurate

Changed paths:
    engines/agi/text.cpp



diff --git a/engines/agi/text.cpp b/engines/agi/text.cpp
index fbc626c..965de69 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;
 }
 
 // ===============================================================






More information about the Scummvm-git-logs mailing list