From e8722e1cb295d4920701a50e0ddb3776f426408c Mon Sep 17 00:00:00 2001 From: John Preston Date: Wed, 24 Oct 2018 13:35:53 +0400 Subject: [PATCH] Separate (c), (r), (tm) and emoji. Fixes #3300. --- Telegram/SourceFiles/codegen/emoji/data.cpp | 52 ++++++++++++++----- Telegram/SourceFiles/codegen/emoji/data.h | 2 + .../SourceFiles/codegen/emoji/generator.cpp | 23 +++++--- .../SourceFiles/codegen/emoji/generator.h | 5 +- 4 files changed, 61 insertions(+), 21 deletions(-) diff --git a/Telegram/SourceFiles/codegen/emoji/data.cpp b/Telegram/SourceFiles/codegen/emoji/data.cpp index e0aed486c..ad7a807bf 100644 --- a/Telegram/SourceFiles/codegen/emoji/data.cpp +++ b/Telegram/SourceFiles/codegen/emoji/data.cpp @@ -17,6 +17,7 @@ using uint64 = quint64; using std::vector; using std::map; +using std::set; using std::find; using std::make_pair; using std::move; @@ -81,6 +82,12 @@ Replace Replaces[] = { { { 0xD83DDE08U }, "}:)" }, }; +InputCategory PostfixRequired = { + { 0x2122U, 0xFE0FU, }, + { 0xA9U, 0xFE0FU, }, + { 0xAEU, 0xFE0FU, }, +}; + using ColorId = uint32; ColorId Colors[] = { 0xD83CDFFBU, @@ -1904,35 +1911,46 @@ Id BareIdFromInput(const InputId &id) { return result; } -using VariatedIds = map; -VariatedIds fillVariatedIds() { - auto result = VariatedIds(); - for (auto &row : ColoredEmoji) { +set fillVariatedIds() { + auto result = set(); + for (const auto &row : ColoredEmoji) { auto variatedId = Id(); if (row.size() < 2) { logDataError() << "colored string should have at least two characters."; - return VariatedIds(); + return {}; } for (auto i = size_t(0), size = row.size(); i != size; ++i) { auto code = row[i]; if (i == 1) { if (code != ColorMask) { logDataError() << "color code should appear at index 1."; - return VariatedIds(); + return {}; } } else if (code == ColorMask) { logDataError() << "color code should appear only at index 1."; - return VariatedIds(); + return {}; } else if (code != kPostfix) { append(variatedId, code); } } - result.insert(make_pair(variatedId, true)); + result.emplace(variatedId); } return result; } -void appendCategory(Data &result, const InputCategory &category, const VariatedIds &variatedIds) { +set fillPostfixRequiredIds() { + auto result = set(); + for (const auto &row : PostfixRequired) { + result.emplace(BareIdFromInput(row)); + } + return result; +} + +void appendCategory( + Data &result, + const InputCategory &category, + const set &variatedIds, + const set &postfixRequiredIds) { result.categories.push_back(vector()); for (auto &id : category) { auto emoji = Emoji(); @@ -1956,6 +1974,7 @@ void appendCategory(Data &result, const InputCategory &category, const VariatedI result = Data(); return; } + auto it = result.map.find(bareId); if (it == result.map.cend()) { const auto index = result.list.size(); @@ -1964,6 +1983,9 @@ void appendCategory(Data &result, const InputCategory &category, const VariatedI if (const auto a = Aliases.find(bareId); a != end(Aliases)) { result.map.emplace(a->second, index); } + if (postfixRequiredIds.find(bareId) != end(postfixRequiredIds)) { + result.postfixRequired.emplace(index); + } } else if (result.list[it->second].postfixed != emoji.postfixed) { logDataError() << "same emoji found with different postfixed property."; result = Data(); @@ -1973,7 +1995,7 @@ void appendCategory(Data &result, const InputCategory &category, const VariatedI result = Data(); return; } - if (variatedIds.find(bareId) != variatedIds.cend()) { + if (variatedIds.find(bareId) != end(variatedIds)) { result.list[it->second].variated = true; auto baseId = Id(); @@ -2003,6 +2025,9 @@ void appendCategory(Data &result, const InputCategory &category, const VariatedI if (const auto a = Aliases.find(bareColoredId); a != end(Aliases)) { result.map.emplace(a->second, index); } + if (postfixRequiredIds.find(bareColoredId) != end(postfixRequiredIds)) { + result.postfixRequired.emplace(index); + } } else if (result.list[it->second].postfixed != colored.postfixed) { logDataError() << "same emoji found with different postfixed property."; result = Data(); @@ -2253,8 +2278,9 @@ common::LogStream logDataError() { Data PrepareData() { Data result; - auto variatedIds = fillVariatedIds(); - if (variatedIds.empty()) { + const auto variatedIds = fillVariatedIds(); + const auto postfixRequiredIds = fillPostfixRequiredIds(); + if (variatedIds.empty() || postfixRequiredIds.empty()) { return Data(); } @@ -2277,7 +2303,7 @@ Data PrepareData() { &Category7, }; for (const auto category : categories) { - appendCategory(result, *category, variatedIds); + appendCategory(result, *category, variatedIds, postfixRequiredIds); if (result.list.empty()) { return Data(); } diff --git a/Telegram/SourceFiles/codegen/emoji/data.h b/Telegram/SourceFiles/codegen/emoji/data.h index a0c91a926..eb8551f5e 100644 --- a/Telegram/SourceFiles/codegen/emoji/data.h +++ b/Telegram/SourceFiles/codegen/emoji/data.h @@ -10,6 +10,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "codegen/common/logging.h" #include #include +#include #include #include #include @@ -30,6 +31,7 @@ struct Emoji { struct Data { std::vector list; std::map> map; + std::set postfixRequired; std::vector> categories; std::map> replaces; }; diff --git a/Telegram/SourceFiles/codegen/emoji/generator.cpp b/Telegram/SourceFiles/codegen/emoji/generator.cpp index 660813ef7..1453c41e8 100644 --- a/Telegram/SourceFiles/codegen/emoji/generator.cpp +++ b/Telegram/SourceFiles/codegen/emoji/generator.cpp @@ -640,7 +640,7 @@ int FindIndex(const QChar *start, const QChar *end, int *outLength) {\n\ auto ch = start;\n\ \n"; - if (!writeFindFromDictionary(data_.map, true)) { + if (!writeFindFromDictionary(data_.map, true, data_.postfixRequired)) { return false; } @@ -651,7 +651,10 @@ int FindIndex(const QChar *start, const QChar *end, int *outLength) {\n\ return true; } -bool Generator::writeFindFromDictionary(const std::map> &dictionary, bool skipPostfixes) { +bool Generator::writeFindFromDictionary( + const std::map> &dictionary, + bool skipPostfixes, + const std::set &postfixRequired) { auto tabs = [](int size) { return QString(size, '\t'); }; @@ -672,7 +675,7 @@ bool Generator::writeFindFromDictionary(const std::map(); auto chars = QString(); auto tabsUsed = 1; - auto lengthsCounted = std::map(); + auto lengthsCounted = std::set(); auto writeSkipPostfix = [this, &tabs, skipPostfixes](int tabsCount) { if (skipPostfixes) { @@ -728,8 +731,8 @@ bool Generator::writeFindFromDictionary(const std::mapstream() << tabs(tabsUsed) << "if (outLength) *outLength = (ch - start);\n"; } } @@ -752,8 +755,14 @@ bool Generator::writeFindFromDictionary(const std::mapstream() << tabs(tabsUsed) << "if ((ch - 1)->unicode() != kPostfix) {\n"; + source_->stream() << tabs(tabsUsed + 1) << "return 0;\n"; + source_->stream() << tabs(tabsUsed) << "}\n"; + } + if (lengthsCounted.find(key) == end(lengthsCounted)) { + lengthsCounted.emplace(key); source_->stream() << tabs(tabsUsed) << "if (outLength) *outLength = (ch - start);\n"; } diff --git a/Telegram/SourceFiles/codegen/emoji/generator.h b/Telegram/SourceFiles/codegen/emoji/generator.h index 779fe88c0..b8c8541a7 100644 --- a/Telegram/SourceFiles/codegen/emoji/generator.h +++ b/Telegram/SourceFiles/codegen/emoji/generator.h @@ -48,7 +48,10 @@ private: bool writeGetSections(); bool writeFindReplace(); bool writeFind(); - bool writeFindFromDictionary(const std::map> &dictionary, bool skipPostfixes = false); + bool writeFindFromDictionary( + const std::map> &dictionary, + bool skipPostfixes = false, + const std::set &postfixRequired = {}); bool writeGetReplacements(); void startBinary(); bool writeStringBinary(common::CppFile *source, const QString &string);