From afa28e97543c81da98f47c9ca17eaaa00f61be70 Mon Sep 17 00:00:00 2001 From: John Preston Date: Mon, 13 Jul 2015 13:45:09 +0300 Subject: [PATCH] optimized emoji insertion --- Telegram/SourceFiles/gui/flattextarea.cpp | 45 +++++++++++++++++------ Telegram/SourceFiles/gui/flattextarea.h | 2 + 2 files changed, 36 insertions(+), 11 deletions(-) diff --git a/Telegram/SourceFiles/gui/flattextarea.cpp b/Telegram/SourceFiles/gui/flattextarea.cpp index 1aaece3e7e..730c72bf10 100644 --- a/Telegram/SourceFiles/gui/flattextarea.cpp +++ b/Telegram/SourceFiles/gui/flattextarea.cpp @@ -174,7 +174,10 @@ EmojiPtr FlatTextarea::getSingleEmoji() const { if (!text.isEmpty()) { QTextCharFormat format = fragment.charFormat(); - return emojiFromUrl(static_cast(&format)->name()); + QString imageName = static_cast(&format)->name(); + if (imageName.startsWith(qstr("emoji://e."))) { + return emojiFromUrl(imageName); + } } return 0; } @@ -530,17 +533,25 @@ void FlatTextarea::insertFromMimeData(const QMimeData *source) { } void FlatTextarea::insertEmoji(EmojiPtr emoji, QTextCursor c) { - c.removeSelectedText(); - - QPixmap img(App::emojiSingle(emoji, _st.font->height)); - QString url = qsl("emoji://e.") + QString::number(emojiKey(emoji), 16); - document()->addResource(QTextDocument::ImageResource, QUrl(url), QVariant(img)); QTextImageFormat imageFormat; - imageFormat.setWidth(img.width() / cIntRetinaFactor()); - imageFormat.setHeight(img.height() / cIntRetinaFactor()); - imageFormat.setName(url); + int32 ew = ESize + st::emojiPadding * cIntRetinaFactor() * 2, eh = _st.font->height * cIntRetinaFactor(); + imageFormat.setWidth(ew / cIntRetinaFactor()); + imageFormat.setHeight(eh / cIntRetinaFactor()); + imageFormat.setName(qsl("emoji://e.") + QString::number(emojiKey(emoji), 16)); imageFormat.setVerticalAlignment(QTextCharFormat::AlignBaseline); - c.insertImage(imageFormat); + + static QString objectReplacement(QChar::ObjectReplacementCharacter); + c.insertText(objectReplacement, imageFormat); +} + +QVariant FlatTextarea::loadResource(int type, const QUrl &name) { + QString imageName = name.toDisplayString(); + if (imageName.startsWith(qstr("emoji://e."))) { + if (EmojiPtr emoji = emojiFromUrl(imageName)) { + return QVariant(App::emojiSingle(emoji, _st.font->height)); + } + } + return QVariant(); } void FlatTextarea::processDocumentContentsChange(int position, int charsAdded) { @@ -579,6 +590,10 @@ void FlatTextarea::processDocumentContentsChange(int position, int charsAdded) { if (emoji) break; } if (emoji) { + if (!document()->pageSize().isNull()) { + document()->setPageSize(QSizeF(0, 0)); + } + QTextCursor c(doc->docHandle(), emojiPosition); c.setPosition(emojiPosition + emojiLen, QTextCursor::KeepAnchor); int32 removedUpto = c.position(); @@ -608,6 +623,8 @@ void FlatTextarea::processDocumentContentsChange(int position, int charsAdded) { } void FlatTextarea::onDocumentContentsChange(int position, int charsRemoved, int charsAdded) { + if (_replacingEmojis) return; + if (!_links.isEmpty()) { bool changed = false; for (LinkRanges::iterator i = _links.begin(); i != _links.end();) { @@ -624,7 +641,7 @@ void FlatTextarea::onDocumentContentsChange(int position, int charsRemoved, int if (changed) emit linksChanged(); } - if (_replacingEmojis || document()->availableRedoSteps() > 0) return; + if (document()->availableRedoSteps() > 0) return; const int takeBack = 3; @@ -647,6 +664,8 @@ void FlatTextarea::onDocumentContentsChanged() { _insertions.clear(); } else { _replacingEmojis = true; + QSizeF s = document()->pageSize(); + do { Insertion i = _insertions.front(); _insertions.pop_front(); @@ -654,6 +673,10 @@ void FlatTextarea::onDocumentContentsChanged() { processDocumentContentsChange(i.first, i.second); } } while (!_insertions.isEmpty()); + + if (document()->pageSize() != s) { + document()->setPageSize(s); + } _replacingEmojis = false; } } diff --git a/Telegram/SourceFiles/gui/flattextarea.h b/Telegram/SourceFiles/gui/flattextarea.h index fc69f0e9f3..0173e284b4 100644 --- a/Telegram/SourceFiles/gui/flattextarea.h +++ b/Telegram/SourceFiles/gui/flattextarea.h @@ -103,6 +103,8 @@ protected: return QTextEdit::leaveEvent(e); } + QVariant loadResource(int type, const QUrl &name); + private: void getSingleEmojiFragment(QString &text, QTextFragment &fragment) const;