fixed issues with surrogate pairs in text selection and rendering

This commit is contained in:
fourtf
2018-10-21 13:03:26 +02:00
parent 1fde45f59b
commit f4cf464ddb
2 changed files with 29 additions and 14 deletions
+19 -11
View File
@@ -159,7 +159,7 @@ void TextElement::addToContainer(MessageLayoutContainer &container,
for (Word &word : this->words_) { for (Word &word : this->words_) {
auto getTextLayoutElement = [&](QString text, int width, auto getTextLayoutElement = [&](QString text, int width,
bool trailingSpace) { bool trailingSpace) {
QColor color = this->color_.getColor(*app->themes); auto color = this->color_.getColor(*app->themes);
app->themes->normalizeColor(color); app->themes->normalizeColor(color);
auto e = (new TextLayoutElement( auto e = (new TextLayoutElement(
@@ -205,26 +205,34 @@ void TextElement::addToContainer(MessageLayoutContainer &container,
QString text = word.text; QString text = word.text;
int textLength = text.length(); int textLength = text.length();
int wordStart = 0; int wordStart = 0;
int width = metrics.width(text[0]); int width = 0;
for (int i = 1; i < textLength; i++) { // QChar::isHighSurrogate(text[0].unicode()) ? 2 : 1
int charWidth = metrics.width(text[i]);
if (!container.fitsInLine(width + charWidth)) { for (int i = 0; i < textLength; i++) //
{
auto isSurrogate = text.size() > i + 1 &&
QChar::isHighSurrogate(text[i].unicode());
auto charWidth = isSurrogate ? metrics.width(text.mid(i, 2))
: metrics.width(text[i]);
if (!container.fitsInLine(width + charWidth)) //
{
container.addElementNoLineBreak(getTextLayoutElement( container.addElementNoLineBreak(getTextLayoutElement(
text.mid(wordStart, i - wordStart), width, false)); text.mid(wordStart, i - wordStart), width, false));
container.breakLine(); container.breakLine();
wordStart = i; wordStart = i;
width = 0; width = charWidth;
if (textLength > i + 2) {
width += metrics.width(text[i]); if (isSurrogate) i++;
width += metrics.width(text[i + 1]);
i += 1;
}
continue; continue;
} }
width += charWidth; width += charWidth;
if (isSurrogate) i++;
} }
container.addElement(getTextLayoutElement( container.addElement(getTextLayoutElement(
+10 -3
View File
@@ -214,13 +214,20 @@ int TextLayoutElement::getMouseOverIndex(const QPoint &abs) const
int x = this->getRect().left(); int x = this->getRect().left();
for (int i = 0; i < this->getText().size(); i++) { for (int i = 0; i < this->getText().size(); i++) {
int w = metrics.width(this->getText()[i]); auto &text = this->getText();
auto width = metrics.width(this->getText()[i]);
if (x + width > abs.x()) {
if (text.size() > i + 1 &&
QChar::isLowSurrogate(text[i].unicode())) //
{
i++;
}
if (x + w > abs.x()) {
return i; return i;
} }
x += w; x += width;
} }
return this->getSelectionIndexCount(); return this->getSelectionIndexCount();