[Scummvm-git-logs] scummvm master -> 83b7fe01eac2898f96a2d55057be4d83f5cbdb0a

lephilousophe lephilousophe at users.noreply.github.com
Sat Nov 28 16:04:35 UTC 2020


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:
83b7fe01ea CRYOMNI3D: Don't use U32String with non UTF-32 codepoints


Commit: 83b7fe01eac2898f96a2d55057be4d83f5cbdb0a
    https://github.com/scummvm/scummvm/commit/83b7fe01eac2898f96a2d55057be4d83f5cbdb0a
Author: Le Philousophe (lephilousophe at users.noreply.github.com)
Date: 2020-11-28T17:04:07+01:00

Commit Message:
CRYOMNI3D: Don't use U32String with non UTF-32 codepoints

Create a new CryoString instead which can handle all the cases

Changed paths:
    engines/cryomni3d/font_manager.cpp
    engines/cryomni3d/font_manager.h
    engines/cryomni3d/versailles/data.cpp
    engines/cryomni3d/versailles/engine.h
    engines/cryomni3d/versailles/logic.cpp


diff --git a/engines/cryomni3d/font_manager.cpp b/engines/cryomni3d/font_manager.cpp
index 421d3b486d..65554f5633 100644
--- a/engines/cryomni3d/font_manager.cpp
+++ b/engines/cryomni3d/font_manager.cpp
@@ -155,7 +155,7 @@ void FontManager::loadTTFList(const Common::String &ttfList, Common::CodePage co
 #endif
 }
 
-Common::U32String FontManager::toU32(const Common::String &str) const {
+CryoString FontManager::toU32(const Common::String &str) const {
 	assert(_codepage != Common::kCodePageInvalid);
 
 	if (_toUnicode) {
@@ -170,7 +170,7 @@ Common::U32String FontManager::toU32(const Common::String &str) const {
 	case Common::kWindows950: {
 		/* if high-order bit is 1, then character is 2 bytes else it's 1 byte
 		 * We don't check validity of the codepoint */
-		Common::U32String ret;
+		CryoString ret;
 		for (uint32 i = 0; i < str.size(); i++) {
 			uint32 c = (byte)str[i];
 			if ((c & 0x80) && (i + 1 < str.size())) {
@@ -208,18 +208,18 @@ void FontManager::setSpaceWidth(uint additionalSpace) {
 }
 
 uint FontManager::displayStr_(uint x, uint y,
-                              const Common::U32String &text) const {
+                              const CryoString &text) const {
 	uint offset = 0;
-	for (Common::U32String::const_iterator it = text.begin(); it != text.end(); it++) {
+	for (CryoString::const_iterator it = text.begin(); it != text.end(); it++) {
 		_currentFont->drawChar(_currentSurface, *it, x + offset, y, _foreColor);
 		offset += _currentFont->getCharWidth(*it) + _charSpacing;
 	}
 	return offset;
 }
 
-uint FontManager::getStrWidth(const Common::U32String &text) const {
+uint FontManager::getStrWidth(const CryoString &text) const {
 	uint width = 0;
-	for (Common::U32String::const_iterator it = text.begin(); it != text.end(); it++) {
+	for (CryoString::const_iterator it = text.begin(); it != text.end(); it++) {
 		uint32 c = *it;
 		if (c == ' ') {
 			width += _spaceWidth;
@@ -230,11 +230,11 @@ uint FontManager::getStrWidth(const Common::U32String &text) const {
 	return width;
 }
 
-bool FontManager::displayBlockText(const Common::U32String &text,
-                                   Common::U32String::const_iterator begin) {
+bool FontManager::displayBlockText(const CryoString &text,
+                                   CryoString::const_iterator begin) {
 	bool notEnoughSpace = false;
-	Common::U32String::const_iterator ptr = begin;
-	Common::Array<Common::U32String> words;
+	CryoString::const_iterator ptr = begin;
+	Common::Array<CryoString> words;
 
 	if (begin != text.end()) {
 		_blockTextRemaining = nullptr;
@@ -251,7 +251,7 @@ bool FontManager::displayBlockText(const Common::U32String &text,
 			} else {
 				spaceWidthPerWord = (double)spacesWidth / (double)words.size();
 			}
-			Common::Array<Common::U32String>::const_iterator word;
+			Common::Array<CryoString>::const_iterator word;
 			uint word_i;
 			for (word = words.begin(), word_i = 0; word != words.end(); word++, word_i++) {
 				_blockPos.x += displayStr_(_blockPos.x, _blockPos.y, *word);
@@ -276,7 +276,7 @@ bool FontManager::displayBlockText(const Common::U32String &text,
 	return notEnoughSpace;
 }
 
-uint FontManager::getLinesCount(const Common::U32String &text, uint width) {
+uint FontManager::getLinesCount(const CryoString &text, uint width) {
 	if (text.size() == 0) {
 		// One line even if it's empty
 		return 1;
@@ -287,11 +287,11 @@ uint FontManager::getLinesCount(const Common::U32String &text, uint width) {
 	}
 
 	uint lineCount = 0;
-	Common::U32String::const_iterator textP = text.begin();
+	CryoString::const_iterator textP = text.begin();
 	uint len = text.size();
 
 	while (len > 0) {
-		Common::U32String buffer;
+		CryoString buffer;
 		uint lineWidth = 0;
 		lineCount++;
 		while (lineWidth < width && len > 0 && *textP != '\r') {
@@ -348,14 +348,14 @@ uint FontManager::getLinesCount(const Common::U32String &text, uint width) {
 	return lineCount;
 }
 
-void FontManager::calculateWordWrap(const Common::U32String &text,
-                                    Common::U32String::const_iterator *position, uint *finalPos, bool *hasCr,
-                                    Common::Array<Common::U32String> &words) const {
+void FontManager::calculateWordWrap(const CryoString &text,
+                                    CryoString::const_iterator *position, uint *finalPos, bool *hasCr,
+                                    Common::Array<CryoString> &words) const {
 	*hasCr = false;
 	uint offset = 0;
 	bool wordWrap = false;
 	uint lineWidth = _blockRect.right - _blockRect.left;
-	Common::U32String::const_iterator ptr = *position;
+	CryoString::const_iterator ptr = *position;
 
 	words.clear();
 
@@ -368,9 +368,9 @@ void FontManager::calculateWordWrap(const Common::U32String &text,
 	}
 
 	while (!wordWrap) {
-		Common::U32String::const_iterator begin = ptr;
+		CryoString::const_iterator begin = ptr;
 		for (; ptr != text.end() && *ptr != '\r' && (!_useSpaceDelimiter || *ptr != ' '); ptr++) { }
-		Common::U32String word(begin, ptr);
+		CryoString word(begin, ptr);
 		uint width = getStrWidth(word);
 		if (width + offset >= lineWidth) {
 			wordWrap = true;
@@ -391,10 +391,10 @@ void FontManager::calculateWordWrap(const Common::U32String &text,
 		offset -= _spaceWidth;
 	} /**/ else {
 		// couldn't get a word (too long): we are at start of line
-		Common::U32String::const_iterator begin = ptr;
+		CryoString::const_iterator begin = ptr;
 		// Start with one character
 		for (ptr++; ptr != text.end(); ptr++) {
-			Common::U32String word(begin, ptr);
+			CryoString word(begin, ptr);
 			uint width = getStrWidth(word);
 			if (width >= lineWidth) {
 				break;
@@ -406,7 +406,7 @@ void FontManager::calculateWordWrap(const Common::U32String &text,
 			ptr--;
 		}
 		if (_keepASCIIjoined) {
-			Common::U32String::const_iterator end = ptr;
+			CryoString::const_iterator end = ptr;
 			// Until now ptr was pointing after the last character
 			// As we want to look at it, go back
 			if (ptr != begin) {
@@ -429,7 +429,7 @@ void FontManager::calculateWordWrap(const Common::U32String &text,
 				ptr++;
 			}
 		}
-		Common::U32String word(begin, ptr);
+		CryoString word(begin, ptr);
 		words.push_back(word);
 	} /**/
 	*finalPos = offset;
diff --git a/engines/cryomni3d/font_manager.h b/engines/cryomni3d/font_manager.h
index 6e0b7c6615..9312fd2235 100644
--- a/engines/cryomni3d/font_manager.h
+++ b/engines/cryomni3d/font_manager.h
@@ -37,6 +37,71 @@ class ManagedSurface;
 
 namespace CryOmni3D {
 
+// This is a special simplified U32String which can contain either conforming UTF-32 data, 16-bits CJK codepoints or 8-bits characters
+// We must use this because depending on the localization, all of those were used and we don't always know which encoding is which
+// This class is only used when displaying stuff, hence its location
+class CryoString : public Common::BaseString<Common::u32char_type_t> {
+public:
+	CryoString() : Common::BaseString<Common::u32char_type_t>() {}
+
+	CryoString(const CryoString &str) : BaseString<Common::u32char_type_t>(str) {}
+	CryoString &operator=(const CryoString &str) {
+		assign(str);
+		return *this;
+	}
+
+	// Constructor to build UTF-32 based strings
+	CryoString(const Common::U32String &ustr) : Common::BaseString<Common::u32char_type_t>(ustr) {}
+
+	// Constructors to build 8-bits strings
+	CryoString(const char *str, uint32 len) {
+		initWithChars(str, len);
+	}
+	explicit CryoString(const char *str) {
+		if (str == nullptr) {
+			return;
+		}
+		uint32 len = 0;
+		const char *s = str;
+		while (*s++) {
+			++len;
+		}
+		initWithChars(str, len);
+	}
+	CryoString(const Common::String &str) {
+		initWithChars(str.c_str(), str.size());
+	}
+
+	// Used when building 16-bits CJK strings
+	CryoString &operator+=(value_type c) {
+		assignAppend(c);
+		return *this;
+	}
+
+	// Various constructors
+	CryoString(const value_type *beginP, const value_type *endP) :
+		Common::BaseString<Common::u32char_type_t>(beginP, endP) {}
+	CryoString(const value_type *str, uint32 len) :
+		Common::BaseString<Common::u32char_type_t>(str, len) {}
+#ifdef USE_CXX11
+	explicit CryoString(const uint32 *str) :
+		Common::BaseString<Common::u32char_type_t>((const value_type *) str) {}
+	CryoString(const uint32 *str, uint32 len) :
+		Common::BaseString<Common::u32char_type_t>((const value_type *) str, len) {}
+	CryoString(const uint32 *beginP, const uint32 *endP) :
+		Common::BaseString<Common::u32char_type_t>((const value_type *) beginP,
+		        (const value_type *) endP) {}
+#endif
+private:
+	void initWithChars(const char *str, uint32 len) {
+		ensureCapacity(len, false);
+		for (; len > 0; str++, len--) {
+			_str[_size++] = (uint8)(*str);
+		}
+		_str[_size] = 0;
+	}
+};
+
 class FontManager {
 public:
 	FontManager();
@@ -61,9 +126,9 @@ public:
 		            toU32(Common::String::format("%d", value)));
 	}
 	void displayStr(uint x, uint y, const Common::String &text) const { displayStr_(x, y, toU32(text)); }
-	void displayStr(uint x, uint y, const Common::U32String &text) const { displayStr_(x, y, text); }
+	void displayStr(uint x, uint y, const CryoString &text) const { displayStr_(x, y, text); }
 	uint getStrWidth(const Common::String &text) const { return getStrWidth(toU32(text)); }
-	uint getStrWidth(const Common::U32String &text) const;
+	uint getStrWidth(const CryoString &text) const;
 
 	uint getLinesCount(const Common::String &text, uint width) { return getLinesCount(toU32(text), width); }
 
@@ -81,13 +146,13 @@ public:
 	Common::Point blockTextLastPos() { return _blockPos; }
 
 private:
-	Common::U32String toU32(const Common::String &text) const;
+	CryoString toU32(const Common::String &text) const;
 
-	uint displayStr_(uint x, uint y, const Common::U32String &text) const;
-	uint getLinesCount(const Common::U32String &text, uint width);
-	bool displayBlockText(const Common::U32String &text, Common::U32String::const_iterator begin);
-	void calculateWordWrap(const Common::U32String &text, Common::U32String::const_iterator *position,
-	                       uint *finalPos, bool *has_br, Common::Array<Common::U32String> &words) const;
+	uint displayStr_(uint x, uint y, const CryoString &text) const;
+	uint getLinesCount(const CryoString &text, uint width);
+	bool displayBlockText(const CryoString &text, CryoString::const_iterator begin);
+	void calculateWordWrap(const CryoString &text, CryoString::const_iterator *position,
+	                       uint *finalPos, bool *has_br, Common::Array<CryoString> &words) const;
 
 	Common::CodePage _codepage;
 	bool _toUnicode;
@@ -106,8 +171,8 @@ private:
 	Common::Point _blockPos;
 	int _lineHeight;
 	bool _justifyText;
-	Common::U32String _blockTextStr;
-	Common::U32String::const_iterator _blockTextRemaining;
+	CryoString _blockTextStr;
+	CryoString::const_iterator _blockTextRemaining;
 
 	// Specific parameters for non alphabetic languages
 	void setupWrapParameters();
diff --git a/engines/cryomni3d/versailles/data.cpp b/engines/cryomni3d/versailles/data.cpp
index d04420bc01..7256086aa5 100644
--- a/engines/cryomni3d/versailles/data.cpp
+++ b/engines/cryomni3d/versailles/data.cpp
@@ -102,11 +102,12 @@ void CryOmni3DEngine_Versailles::loadStaticData() {
 	_epigraphContent = data->readString16();
 	_epigraphPassword = data->readString16();
 
+	// Japanese is the only language (for now) where the password isn't 8-bit ASCII string
 	if (getLanguage() == Common::JA_JPN) {
 		_bombAlphabet = data->readString16().decode(Common::kWindows932);
 		_bombPassword = data->readString16().decode(Common::kWindows932);
 	} else {
-		_bombAlphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZ '";
+		_bombAlphabet = CryoString("ABCDEFGHIJKLMNOPQRSTUVWXYZ '");
 		_bombPassword = data->readString16();
 	}
 
diff --git a/engines/cryomni3d/versailles/engine.h b/engines/cryomni3d/versailles/engine.h
index 3b6823df96..430fcd799d 100644
--- a/engines/cryomni3d/versailles/engine.h
+++ b/engines/cryomni3d/versailles/engine.h
@@ -246,7 +246,7 @@ public:
 		return prepareFileName(baseName, extensions);
 	}
 	Common::String prepareFileName(const Common::String &baseName,
-	                                       const char *const *extensions) const override;
+	                               const char *const *extensions) const override;
 
 	void setupPalette(const byte *colors, uint start, uint num) override { setupPalette(colors, start, num, true); }
 	void makeTranslucent(Graphics::Surface &dst, const Graphics::Surface &src) const override;
@@ -560,8 +560,8 @@ private:
 	IMG_CB(88003d);
 	IMG_CB(88003e);
 	IMG_CB(88003f);
-	Common::U32String _bombAlphabet; // For Japanese edition
-	Common::U32String _bombPassword;
+	CryoString _bombAlphabet; // For Japanese edition
+	CryoString _bombPassword;
 	static const uint kBombPasswordSmallLength = 40;
 	static const uint kBombPasswordMaxLength = 60;
 	static const uint16 kBombLettersPos[2][kBombPasswordMaxLength][2];
diff --git a/engines/cryomni3d/versailles/logic.cpp b/engines/cryomni3d/versailles/logic.cpp
index 3e583ea11f..8354e46460 100644
--- a/engines/cryomni3d/versailles/logic.cpp
+++ b/engines/cryomni3d/versailles/logic.cpp
@@ -3222,7 +3222,7 @@ void CryOmni3DEngine_Versailles::drawBombLetters(Graphics::ManagedSurface &surfa
 			surface.fillRect(rct, 239);
 
 			uint32 letter = bombPossibilites[i][bombCurrentLetters[i]];
-			Common::U32String str(&letter, 1);
+			CryoString str(&letter, 1);
 
 			_fontManager.displayStr(rct.left + (34 - _fontManager.getStrWidth(str)) / 2,
 			                        rct.top + 5, str);




More information about the Scummvm-git-logs mailing list