- do {
- idx = finder.toNextBoundary();
- if(idx < 0) {
- idx = length;
- wordStart = false;
- wordEnd = false;
- mode = SearchStart;
- } else {
- wordStart = finder.boundaryReasons().testFlag(QTextBoundaryFinder::StartWord);
- wordEnd = finder.boundaryReasons().testFlag(QTextBoundaryFinder::EndWord);
- }
-
- //if(flg) qDebug() << idx << mode << wordStart << wordEnd << contents->plainText.left(idx) << contents->plainText.mid(idx);
-
- if(mode == SearchEnd || (!wordStart && wordEnd)) {
- if(wordStart || !wordEnd) continue;
- oldidx = idx;
- mode = SearchStart;
- continue;
- }
- qreal wordendx = line.cursorToX(oldidx);
- qreal trailingendx = line.cursorToX(idx);
- word.endX = wordendx;
- word.width = wordendx - wordstartx;
- word.trailing = trailingendx - wordendx;
- wordstartx = trailingendx;
- wplist.append(word);
-
- if(wordStart) {
- word.start = idx;
- mode = SearchEnd;
- }
- // the part " || (finder.position() == contents->plainText.length())" shouldn't be necessary
- // but in rare and indeterministic cases Qt states that the end of the text is not a boundary o_O
- } while(finder.isAtBoundary() || (finder.position() == length));
-
- // A QVector needs less space than a QList
- _wrapList.resize(wplist.count());
- for(int i = 0; i < wplist.count(); i++) {
- _wrapList[i] = wplist.at(i);
- }
- }
-
- ChatLineModel::WrapList _wrapList;
- Message *_msgBuffer;
- UiStyle::StyledMessage *_styledMsg;
-
- static unsigned char *TextBoundaryFinderBuffer;
- static int TextBoundaryFinderBufferSize;
-};
+ while ((idx = finder.toNextBoundary()) >= 0 && idx <= length) {
+ // QTextBoundaryFinder has inconsistent behavior in Qt version up to and including 4.6.3 (at least).
+ // It doesn't point to the position we should break, but to the character before that.
+ // Unfortunately Qt decided to fix this by changing the behavior of QTBF, so now we have to add a version
+ // check. At the time of this writing, I'm still trying to get this reverted upstream...
+ //
+ // cf. https://bugs.webkit.org/show_bug.cgi?id=31076 and Qt commit e6ac173
+ static int needWorkaround = -1;
+ if (needWorkaround < 0) {
+ needWorkaround = 0;
+ QStringList versions = QString(qVersion()).split('.');
+ if (versions.count() == 3 && versions.at(0).toInt() == 4) {
+ if (versions.at(1).toInt() <= 6 && versions.at(2).toInt() <= 3)
+ needWorkaround = 1;
+ }
+ }
+ if (needWorkaround == 1) {
+ if (idx < length)
+ idx++;
+ }