From f917a4beabff01e85159de6a34fd705470ba993c Mon Sep 17 00:00:00 2001 From: Alyssa Milburn Date: Fri, 24 Aug 2012 22:35:22 +0200 Subject: TONY: Use Common::String in writeText. This uses an array of lines rather than trying to stick nulls into the string, and so fixes wrapping on hyphens (which overwrote the character before the hyphen). Thanks to eriktorbjorn for both finding the bug and working out what was going wrong. --- engines/tony/font.cpp | 77 +++++++++++++++++++++++++++------------------------ engines/tony/font.h | 4 +-- engines/tony/game.cpp | 8 +++--- 3 files changed, 47 insertions(+), 42 deletions(-) diff --git a/engines/tony/font.cpp b/engines/tony/font.cpp index 2d334434d4..7e65369bfc 100644 --- a/engines/tony/font.cpp +++ b/engines/tony/font.cpp @@ -1801,7 +1801,7 @@ void RMText::removeThis(CORO_PARAM, bool &result) { result = true; } -void RMText::writeText(const RMString &text, int nFont, int *time) { +void RMText::writeText(const Common::String &text, int nFont, int *time) { // Initializes the font (only once) if (_fonts[0] == NULL) { _fonts[0] = new RMFontDialog; @@ -1817,15 +1817,13 @@ void RMText::writeText(const RMString &text, int nFont, int *time) { writeText(text, _fonts[nFont], time); } -void RMText::writeText(const RMString &text, RMFontColor *font, int *time) { +void RMText::writeText(Common::String text, RMFontColor *font, int *time) { RMGfxPrimitive *prim; - char *p, *old_p; - int i, j, x, y; + uint p, old_p; + int j, x, y; int len; int numchar; int width, height; - char *string; - int numlines; // Set the base color font->setBaseColor(_textR, _textG, _textB); @@ -1834,17 +1832,18 @@ void RMText::writeText(const RMString &text, RMFontColor *font, int *time) { destroy(); // If the string is empty, do nothing - if (text == NULL || text[0] == '\0') + if (text.empty()) return; // Divide the words into lines. In this cycle, X contains the maximum length reached by a line, // and the number of lines - string = p = text; - i = j = x = 0; - while (*p != '\0') { - j += font->stringLen(*p); - if (j > (((_aHorType == HLEFTPAR) && (i > 0)) ? _maxLineLength - 25 : _maxLineLength)) { - j -= font->stringLen(*p, p[1]); + Common::Array lines; + p = 0; + j = x = 0; + while (p < text.size()) { + j += font->stringLen(text[p]); + if (j > (((_aHorType == HLEFTPAR) && (lines.size() > 0)) ? _maxLineLength - 25 : _maxLineLength)) { + j -= font->stringLen(text[p], (p + 1 == text.size()) ? '\0' : text[p + 1]); if (j > x) x = j; @@ -1855,21 +1854,24 @@ void RMText::writeText(const RMString &text, RMFontColor *font, int *time) { // This workaround has the partial word broken up so it will still display // old_p = p; - while (*p != ' ' && *p != '-' && p > string) + while (text[p] != ' ' && text[p] != '-' && p > 0) p--; - if (p == string) + if (p == 0) p = old_p; // Check if there are any blanks to end - while (*p == ' ' && *p != '\0') + while ((text[p] == ' ' || text[p] == '-') && p + 1 < text.size()) p++; - if (*p == '\0') + if (p == text.size()) break; - p--; - i++; - *p = '\0'; + lines.push_back(Common::String(text.c_str(), p)); + if (text[p] == ' ') + p++; + text = text.c_str() + p; + p = 0; j = 0; + continue; } p++; } @@ -1877,27 +1879,29 @@ void RMText::writeText(const RMString &text, RMFontColor *font, int *time) { if (j > x) x = j; - i++; - numlines = i; + // Add the last line of text. + lines.push_back(text); x += 8; // Starting position for the surface: X1, Y width = x; - height = (numlines - 1) * font->letterHeight() + font->_fontDimy; + height = (lines.size() - 1) * font->letterHeight() + font->_fontDimy; // Create the surface create(width, height); Common::fill(_buf, _buf + width * height * 2, 0); - p = string; + p = 0; y = 0; numchar = 0; - for (; i > 0; i--) { + for (uint i = 0; i < lines.size(); ++i) { + const Common::String &line = lines[i]; + // Measure the length of the line x = 0; - j = font->stringLen(RMString(p)); + j = font->stringLen(RMString(line.c_str())); switch (_aHorType) { case HLEFT: @@ -1905,7 +1909,7 @@ void RMText::writeText(const RMString &text, RMFontColor *font, int *time) { break; case HLEFTPAR: - if (i == numlines) + if (i == 0) x = 0; else x = 25; @@ -1920,21 +1924,22 @@ void RMText::writeText(const RMString &text, RMFontColor *font, int *time) { break; } - while (*p != '\0') { - if (*p == ' ') { - x += font->stringLen(*p); + p = 0; + while (p < line.size()) { + if (line[p] == ' ') { + x += font->stringLen(line[p]); p++; continue; } - prim = font->makeLetterPrimitive(*p, len); + prim = font->makeLetterPrimitive(line[p], len); prim->getDst()._x1 = x; prim->getDst()._y1 = y; addPrim(prim); numchar++; - x += font->stringLen(*p, p[1]); + x += font->stringLen(line[p], (p + 1 == line.size()) ? '\0' : line[p + 1]); p++; } p++; @@ -2021,14 +2026,14 @@ void RMTextDialog::hide(CORO_PARAM) { } void RMTextDialog::writeText(const RMString &text, int font, int *time) { - RMText::writeText(text, font, &_time); + RMText::writeText(Common::String(text), font, &_time); if (time != NULL) *time = _time; } void RMTextDialog::writeText(const RMString &text, RMFontColor *font, int *time) { - RMText::writeText(text, font, &_time); + RMText::writeText(Common::String(text), font, &_time); if (time != NULL) *time = _time; @@ -2251,7 +2256,7 @@ void RMTextItemName::doFrame(CORO_PARAM, RMGfxTargetBuffer &bigBuf, RMLocation & _item->getName(itemName); // Write it - writeText(itemName, 1); + writeText(Common::String(itemName), 1); // Handle the change If the selected item is different from the previous one if (_ctx->lastItem != _item) { @@ -2389,7 +2394,7 @@ void RMDialogChoice::setNumChoices(int num) { void RMDialogChoice::addChoice(const RMString &string) { // Draw the string assert(_curAdded < _numChoices); - _drawedStrings[_curAdded++].writeText(string, 0); + _drawedStrings[_curAdded++].writeText(Common::String(string), 0); } void RMDialogChoice::prepare(CORO_PARAM) { diff --git a/engines/tony/font.h b/engines/tony/font.h index 9971e536ed..1e84ecb527 100644 --- a/engines/tony/font.h +++ b/engines/tony/font.h @@ -215,8 +215,8 @@ public: void setMaxLineLength(int max); // Write the text - void writeText(const RMString &text, int font, int *time = NULL); - void writeText(const RMString &text, RMFontColor *font, int *time = NULL); + void writeText(const Common::String &text, int font, int *time = NULL); + void writeText(Common::String text, RMFontColor *font, int *time = NULL); // Overloaded function to decide when you delete the object from the OT list virtual void removeThis(CORO_PARAM, bool &result); diff --git a/engines/tony/game.cpp b/engines/tony/game.cpp index a27b8ea544..b3b6fe2347 100644 --- a/engines/tony/game.cpp +++ b/engines/tony/game.cpp @@ -506,15 +506,15 @@ void RMOptionScreen::refreshAll(CORO_PARAM) { } for (_ctx->i = 0; _ctx->i < 6; _ctx->i++) { - RMString s; + Common::String s; if (_bEditSaveName && _nEditPos == _ctx->i) - s.format("%02d)%s*", _statePos + _ctx->i, _editName); + s = Common::String::format("%02d)%s*", _statePos + _ctx->i, _editName); else { if (_statePos == 0 && _ctx->i == 0) - s.format("Autosave"); + s = "Autosave"; else - s.format("%02d)%s", _statePos + _ctx->i, (const char *)_curThumbName[_ctx->i]); + s = Common::String::format("%02d)%s", _statePos + _ctx->i, (const char *)_curThumbName[_ctx->i]); } _ctx->num[_ctx->i] = new RMText; -- cgit v1.2.3