fixed issues with surrogate pairs in text selection and rendering
This commit is contained in:
@@ -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(
|
||||||
|
|||||||
@@ -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();
|
||||||
|
|||||||
Reference in New Issue
Block a user