[Scummvm-git-logs] scummvm master -> 2b6754e187c9182122cdf9b7535613d644e16be3
sev-
sev at scummvm.org
Sat Mar 20 14:15:58 UTC 2021
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:
2b6754e187 GRAPHICS: MACGUI: fix the bug of dealing with long word in MacText
Commit: 2b6754e187c9182122cdf9b7535613d644e16be3
https://github.com/scummvm/scummvm/commit/2b6754e187c9182122cdf9b7535613d644e16be3
Author: ysj1173886760 (1173886760 at qq.com)
Date: 2021-03-20T15:15:56+01:00
Commit Message:
GRAPHICS: MACGUI: fix the bug of dealing with long word in MacText
it now can deal with the word with many font
it now can deal with multi paragraph and had it`s own wrapping
empty string and sequence of \n is tested
Changed paths:
graphics/macgui/mactext.cpp
graphics/macgui/mactext.h
diff --git a/graphics/macgui/mactext.cpp b/graphics/macgui/mactext.cpp
index 3c43106623..84e31f9a36 100644
--- a/graphics/macgui/mactext.cpp
+++ b/graphics/macgui/mactext.cpp
@@ -317,6 +317,7 @@ void MacText::chopChunk(const Common::U32String &str, int *curLinePtr) {
Common::Array<Common::U32String> text;
int w = getLineWidth(curLine, true);
+ D(9, "** chopChunk before wrap \"%s\"", Common::toPrintable(str.encode()).c_str());
chunk->getFont()->wordWrapText(str, _maxWidth, text, w);
@@ -328,6 +329,9 @@ void MacText::chopChunk(const Common::U32String &str, int *curLinePtr) {
return;
}
+ for (int i = 0; i < (int)text.size(); i++) {
+ D(9, "** chopChunk result %d \"%s\"", i, toPrintable(text[i].encode()).c_str());
+ }
chunk->text += text[0];
// Recalc dims
@@ -365,21 +369,22 @@ void MacText::splitString(const Common::U32String &str, int curLine) {
_textLines[0].chunks.push_back(_defaultFormatting);
D(9, "** splitString, added default formatting");
} else {
+ _textLines.insert_at(curLine, MacTextLine());
D(9, "** splitString, continuing, %d lines", _textLines.size());
}
+ if (curLine == -1)
+ curLine = _textLines.size() - 1;
+
if (str.empty()) {
- debug(9, "** splitString, empty line");
+ _textLines[curLine].chunks.push_back(_defaultFormatting);
+ debug(9,"** splitString, empty line");
return;
}
Common::U32String paragraph, tmp;
- if (curLine == -1)
- curLine = _textLines.size() - 1;
-
- int curChunk = _textLines[curLine].chunks.size() - 1;
- MacFontRun chunk = _textLines[curLine].chunks[curChunk];
+ MacFontRun current_format = _defaultFormatting;
while (*l) {
paragraph.clear();
@@ -403,41 +408,19 @@ void MacText::splitString(const Common::U32String &str, int curLine) {
// Now process whole paragraph
const Common::U32String::value_type *s = paragraph.c_str();
- tmp.clear();
-
while (*s) {
- // Scan till next font change or end of line
- while (*s && *s != '\001') {
- tmp += *s;
-
- s++;
- }
-
- if (*s) // If it was \001, skip it
- s++;
-
- if (*s == '\001') { // \001\001 -> \001
- tmp += *s++;
-
- if (*s) // Check we reached end of line
- continue;
- }
-
- D(9, "** splitString, chunk: \"%s\"", Common::toPrintable(tmp.encode()).c_str());
-
- // Okay, now we are either at the end of the line, or in the next
- // chunk definition. That means, that we have to store the previous chunk
- chopChunk(tmp, &curLine);
-
tmp.clear();
- // If it is end of the line, we're done
- if (!*s) {
- D(9, "** splitString, end of line");
-
- break;
+ // Skip \001
+ if (*s == '\001') {
+ s++;
+ if (*s == '\001') {
+ tmp += *s;
+ s++;
+ }
}
+ // get format
if (*s == '\015') { // binary format
s++;
@@ -451,7 +434,7 @@ void MacText::splitString(const Common::U32String &str, int curLine) {
D(9, "** splitString: fontId: %d, textSlant: %d, fontSize: %d, p0: %x p1: %x p2: %x",
fontId, textSlant, fontSize, palinfo1, palinfo2, palinfo3);
- chunk.setValues(_wm, fontId, textSlant, fontSize, palinfo1, palinfo2, palinfo3);
+ current_format.setValues(_wm, fontId, textSlant, fontSize, palinfo1, palinfo2, palinfo3);
} else if (*s == '\016') { // human-readable format
s++;
@@ -467,13 +450,104 @@ void MacText::splitString(const Common::U32String &str, int curLine) {
D(9, "** splitString: fontId: %d, textSlant: %d, fontSize: %d, p0: %x p1: %x p2: %x",
fontId, textSlant, fontSize, palinfo1, palinfo2, palinfo3);
- chunk.setValues(_wm, fontId, textSlant, fontSize, palinfo1, palinfo2, palinfo3);
+ current_format.setValues(_wm, fontId, textSlant, fontSize, palinfo1, palinfo2, palinfo3);
+ }
+
+ while (*s && *s != ' ' && *s != '\001') {
+ tmp += *s;
+ s++;
+ }
+ // meaning there is a word with multifont
+ if (*s == '\001') {
+ _textLines[curLine].chunks.push_back(current_format);
+ _textLines[curLine].lastChunk().wordContinuation = true;
+ _textLines[curLine].lastChunk().text = tmp;
+ continue;
+ }
+ // calc word_width, the trick we define here is we don`t count the space
+ int word_width = current_format.getFont()->getStringWidth(tmp);
+ while (*s == ' ') {
+ tmp += *s;
+ s++;
+ }
+ // add all spaces left
+
+ // now let`s try to split
+ // first we have to try to get the whole word
+ Common::Array<MacFontRun> word;
+ word.push_back(current_format);
+ word[0].text = tmp;
+
+ while (!_textLines[curLine].chunks.empty() && _textLines[curLine].lastChunk().wordContinuation) {
+ word.push_back(_textLines[curLine].lastChunk());
+ _textLines[curLine].chunks.pop_back();
+ }
+
+ for (int i = 1; i < (int)word.size(); i++) {
+ word_width += word[i].getFont()->getStringWidth(word[i].text);
+ D(9, "** word \"%s\" textslant [%d]", Common::toPrintable(word[i].text.encode()).c_str(), word[i].textSlant);
+ }
+
+ int cur_width = getLineWidth(curLine, true);
+
+ D(0, "curWidth %d word_width %d", cur_width, word_width);
+ // if cur_width == 0 but there`s chunks, meaning there must be empty string here
+ // if cur_width == 0, then you don`t have to add a newline for it
+ if (cur_width + word_width > _maxWidth && cur_width != 0) {
+ ++curLine;
+ _textLines.insert_at(curLine, MacTextLine());
+ }
+
+ // deal with the super long word situation
+ if (word_width > _maxWidth) {
+ for (int i = word.size() - 1; i >= 0; i--) {
+ cur_width = getLineWidth(curLine, true);
+ // count the size without space
+ // because you don`t want to split a word just for space
+ // actually i think this part can be optimized because only word[0] have space
+ // we just need to deal it specially
+
+ // meaning you have to split this word;
+ int tmp_width = 0;
+ _textLines[curLine].chunks.push_back(word[i]);
+ // empty the string
+ _textLines[curLine].lastChunk().text = Common::U32String();
+ for (Common::U32String::const_iterator it = word[i].text.begin(); it != word[i].text.end(); it++) {
+ Common::U32String::unsigned_type c = *it;
+ if (c == ' ') {
+ // add the space left
+ while (it != word[i].text.end()) {
+ c = *it;
+ _textLines[curLine].lastChunk().text += c;
+ it++;
+ }
+ break;
+ }
+ int char_width = word[i].getFont()->getCharWidth(c);
+ if (char_width + tmp_width + cur_width > _maxWidth) {
+ ++curLine;
+ _textLines.insert_at(curLine, MacTextLine());
+ _textLines[curLine].chunks.push_back(word[i]);
+ _textLines[curLine].lastChunk().text = Common::U32String();
+ tmp_width = 0;
+ cur_width = 0;
+ }
+ tmp_width += char_width;
+ _textLines[curLine].lastChunk().text += c;
+ }
+ }
} else {
- error("MacText: formatting error, got %02x", *s);
+ for (int i = word.size() - 1; i >= 0; i--) {
+ _textLines[curLine].chunks.push_back(word[i]);
+ }
}
- // Push new formatting
- _textLines[curLine].chunks.push_back(chunk);
+ // If it is end of the line, we're done
+ if (!*s) {
+ _textLines[curLine].paragraphEnd = true;
+ D(9, "** splitString, end of line");
+ break;
+ }
}
if (!*l) { // If this is end of the string, we're done here
@@ -487,7 +561,6 @@ void MacText::splitString(const Common::U32String &str, int curLine) {
curLine++;
_textLines.insert_at(curLine, MacTextLine());
- _textLines[curLine].chunks.push_back(chunk);
}
#if DEBUG
@@ -495,7 +568,7 @@ void MacText::splitString(const Common::U32String &str, int curLine) {
debugN(9, "** splitString: %2d ", i);
for (uint j = 0; j < _textLines[i].chunks.size(); j++)
- debugN(9, "[%d] \"%s\"", _textLines[i].chunks[j].fontId, Common::toPrintable(_textLines[i].chunks[j].text.encode()).c_str());
+ debugN(9, "[%d] \"%s\"", _textLines[i].chunks[j].text.size(), Common::toPrintable(_textLines[i].chunks[j].text.encode()).c_str());
debugN(9, "\n");
}
@@ -1416,7 +1489,6 @@ Common::U32String MacText::getTextChunk(int startRow, int startCol, int endRow,
if (endCol == -1)
endCol = getLineCharWidth(endRow);
-
if (_textLines.empty()) {
return res;
}
@@ -1469,8 +1541,6 @@ Common::U32String MacText::getTextChunk(int startRow, int startCol, int endRow,
}
if (newlines)
res += '\n';
- else
- res += ' ';
// We are at the end row, and it could be not completely requested
} else if (i == endRow) {
for (uint chunk = 0; chunk < _textLines[i].chunks.size(); chunk++) {
@@ -1501,8 +1571,6 @@ Common::U32String MacText::getTextChunk(int startRow, int startCol, int endRow,
if (newlines)
res += '\n';
- else
- res += ' ';
}
}
@@ -1546,6 +1614,13 @@ void MacText::insertChar(byte c, int *row, int *col) {
recalcDims();
render(*row, *row);
}
+ for (int i = 0; i < (int)_textLines.size(); i++) {
+ D(9, "**insertChar line %d isEnd %d", i, _textLines[i].paragraphEnd);
+ for (int j = 0; j < (int)_textLines[i].chunks.size(); j++) {
+ D(9, "[%d] \"%s\"",_textLines[i].chunks[j].text.size(), Common::toPrintable(_textLines[i].chunks[j].text.encode()).c_str());
+ }
+ }
+ D(9, "**insertChar cursor row %d col %d", _cursorRow, _cursorCol);
}
void MacText::deletePreviousChar(int *row, int *col) {
@@ -1565,6 +1640,7 @@ void MacText::deletePreviousChar(int *row, int *col) {
_textLines[*row].chunks.push_back(MacFontRun(_textLines[*row + 1].firstChunk()));
_textLines[*row].firstChunk().text.clear();
}
+ _textLines[*row].paragraphEnd = false;
for (uint i = 1; i < _textLines[*row + 1].chunks.size(); i++)
_textLines[*row].chunks.push_back(MacFontRun(_textLines[*row + 1].chunks[i]));
@@ -1584,6 +1660,14 @@ void MacText::deletePreviousChar(int *row, int *col) {
_textLines[*row].width = -1; // flush the cache
+ for (int i = 0; i < (int)_textLines.size(); i++) {
+ D(9, "**deleteChar line %d", i);
+ for (int j = 0; j < (int)_textLines[i].chunks.size(); j++) {
+ D(9, "[%d] \"%s\"",_textLines[i].chunks[j].text.size(), Common::toPrintable(_textLines[i].chunks[j].text.encode()).c_str());
+ }
+ }
+ D(9, "**deleteChar cursor row %d col %d", _cursorRow, _cursorCol);
+
reshuffleParagraph(row, col);
_fullRefresh = true;
@@ -1607,11 +1691,14 @@ void MacText::addNewLine(int *row, int *col) {
newchunk.text = line->chunks[ch].text.substr(pos);
line->chunks[ch].text = line->chunks[ch].text.substr(0, pos);
+ line->paragraphEnd = true;
newline.chunks.push_back(newchunk);
for (uint i = ch + 1; i < line->chunks.size(); i++) {
newline.chunks.push_back(MacFontRun(line->chunks[i]));
- line->chunks[i].text.clear();
+ }
+ for (uint i = line->chunks.size() - 1; i >= ch + 1; i--) {
+ line->chunks.pop_back();
}
line->width = -1; // Drop cache
@@ -1622,6 +1709,16 @@ void MacText::addNewLine(int *row, int *col) {
(*row)++;
*col = 0;
+ reshuffleParagraph(row, col);
+
+ for (int i = 0; i < (int)_textLines.size(); i++) {
+ D(9, "** addNewLine line %d", i);
+ for (int j = 0; j < (int)_textLines[i].chunks.size(); j++) {
+ D(9, "[%d] \"%s\"",_textLines[i].chunks[j].text.size(), Common::toPrintable(_textLines[i].chunks[j].text.encode()).c_str());
+ }
+ }
+ D(9, "** addNewLine cursor row %d col %d", _cursorRow, _cursorCol);
+
_fullRefresh = true;
recalcDims();
render();
@@ -1646,21 +1743,22 @@ void MacText::reshuffleParagraph(int *row, int *col) {
ppos += *col;
// Get whole paragraph
- Common::U32String paragraph = getTextChunk(start, 0, end, -1, true, false);
+ Common::U32String paragraph = getTextChunk(start, 0, end, getLineCharWidth(end, true), true, false);
// Remove it from the text
for (int i = start; i <= end; i++) {
_textLines.remove_at(start);
}
- // And now readd it
+ // And now read it
+ D(9, "start %d end %d", start, end);
splitString(paragraph, start);
// Find new pos within paragraph after reshuffling
*row = start;
- while (ppos > getLineCharWidth(*row)) {
- ppos -= getLineCharWidth(*row);
+ while (ppos > getLineCharWidth(*row, true)) {
+ ppos -= getLineCharWidth(*row, true);
(*row)++;
}
*col = ppos;
diff --git a/graphics/macgui/mactext.h b/graphics/macgui/mactext.h
index 41436d27a6..310c812e12 100644
--- a/graphics/macgui/mactext.h
+++ b/graphics/macgui/mactext.h
@@ -50,7 +50,8 @@ struct MacFontRun {
uint16 palinfo2;
uint16 palinfo3;
uint16 fgcolor;
-
+ // to determine whether the next word is part of this one
+ bool wordContinuation;
const Font *font;
MacWindowManager *wm;
@@ -59,11 +60,13 @@ struct MacFontRun {
fontId = textSlant = fontSize = 0;
palinfo1 = palinfo2 = palinfo3 = 0;
font = nullptr;
+ wordContinuation = false;
}
MacFontRun(MacWindowManager *wm_, uint16 fontId_, byte textSlant_, uint16 fontSize_,
uint16 palinfo1_, uint16 palinfo2_, uint16 palinfo3_) {
setValues(wm_, fontId_, textSlant_, fontSize_, palinfo1_, palinfo2_, palinfo3_);
+ wordContinuation = false;
}
void setValues(MacWindowManager *wm_, uint16 fontId_, byte textSlant_, uint16 fontSize_,
@@ -222,7 +225,7 @@ private:
void reshuffleParagraph(int *row, int *col);
void chopChunk(const Common::U32String &str, int *curLine);
- void splitString(const Common::U32String &s, int curLine = -1);
+ void splitString(const Common::U32String &str, int curLine = -1);
void render(int from, int to);
void recalcDims();
void reallocSurface();
More information about the Scummvm-git-logs
mailing list