diff options
| -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;  }  // =============================================================== | 
