From 27e6bca65e8991ec1525dafd9ac966ae614bc003 Mon Sep 17 00:00:00 2001 From: ouwou <26526779+ouwou@users.noreply.github.com> Date: Tue, 6 Apr 2021 00:56:24 -0400 Subject: allow usage of multiple emoji shortcodes also raise max completer entries --- components/completer.cpp | 6 +++- emojis.cpp | 91 +++++++++++++++++++---------------------------- emojis.hpp | 4 +-- res/emojis.bin | Bin 3157174 -> 3176057 bytes 4 files changed, 42 insertions(+), 59 deletions(-) diff --git a/components/completer.cpp b/components/completer.cpp index e37e11e..f32bbd5 100644 --- a/components/completer.cpp +++ b/components/completer.cpp @@ -1,9 +1,10 @@ +#include #include "completer.hpp" #include "../abaddon.hpp" #include "../util.hpp" constexpr const int CompleterHeight = 150; -constexpr const int MaxCompleterEntries = 15; +constexpr const int MaxCompleterEntries = 30; Completer::Completer() { set_reveal_child(false); @@ -204,13 +205,16 @@ done: // if <15 guild emojis match then load up stock if (i < 15) { + std::unordered_set added_patterns; auto &emojis = Abaddon::Get().GetEmojis(); const auto &shortcodes = emojis.GetShortCodes(); for (const auto &[shortcode, pattern] : shortcodes) { + if (added_patterns.find(pattern) != added_patterns.end()) continue; if (!StringContainsCaseless(shortcode, term)) continue; if (i++ > 15) break; const auto &pb = emojis.GetPixBuf(pattern); if (!pb) continue; + added_patterns.insert(pattern); const auto entry = make_entry(shortcode, pattern); entry->SetImage(pb->scale_simple(CompleterImageSize, CompleterImageSize, Gdk::INTERP_BILINEAR)); } diff --git a/emojis.cpp b/emojis.cpp index bdf3d35..dd7193a 100644 --- a/emojis.cpp +++ b/emojis.cpp @@ -7,32 +7,43 @@ EmojiResource::EmojiResource(std::string filepath) bool EmojiResource::Load() { m_fp = std::fopen(m_filepath.c_str(), "rb"); if (m_fp == nullptr) return false; - int index_pos; - std::fread(&index_pos, 4, 1, m_fp); - std::fseek(m_fp, index_pos, SEEK_SET); - int num_entries; - std::fread(&num_entries, 4, 1, m_fp); - for (int i = 0; i < num_entries; i++) { - static int pattern_strlen, shortcode_strlen, len, pos; - std::fread(&pattern_strlen, 4, 1, m_fp); - std::string pattern(pattern_strlen, '\0'); - std::fread(pattern.data(), pattern_strlen, 1, m_fp); - - const auto pattern_hex = HexToPattern(pattern); - - std::fread(&shortcode_strlen, 4, 1, m_fp); - std::string shortcode(shortcode_strlen, '\0'); - if (shortcode_strlen > 0) { - std::fread(shortcode.data(), shortcode_strlen, 1, m_fp); - m_shortcode_index[shortcode] = pattern_hex; - m_pattern_shortcode_index[pattern_hex] = shortcode; + + int index_offset; + std::fread(&index_offset, 4, 1, m_fp); + std::fseek(m_fp, index_offset, SEEK_SET); + + int emojis_count; + std::fread(&emojis_count, 4, 1, m_fp); + for (int i = 0; i < emojis_count; i++) { + std::vector shortcodes; + + int shortcodes_count; + std::fread(&shortcodes_count, 4, 1, m_fp); + for (int j = 0; j < shortcodes_count; j++) { + int shortcode_length; + std::fread(&shortcode_length, 4, 1, m_fp); + std::string shortcode(shortcode_length, '\0'); + std::fread(shortcode.data(), shortcode_length, 1, m_fp); + shortcodes.push_back(std::move(shortcode)); } - std::fread(&len, 4, 1, m_fp); - std::fread(&pos, 4, 1, m_fp); - m_index[pattern] = std::make_pair(pos, len); - m_patterns.push_back(pattern_hex); + int surrogates_count; + std::fread(&surrogates_count, 4, 1, m_fp); + std::string surrogates(surrogates_count, '\0'); + std::fread(surrogates.data(), surrogates_count, 1, m_fp); + m_patterns.push_back(surrogates); + + int data_size, data_offset; + std::fread(&data_size, 4, 1, m_fp); + std::fread(&data_offset, 4, 1, m_fp); + m_index[surrogates] = { data_offset, data_size }; + + for (const auto &shortcode : shortcodes) + m_shortcode_index[shortcode] = surrogates; + + m_pattern_shortcode_index[surrogates] = std::move(shortcodes); } + std::sort(m_patterns.begin(), m_patterns.end(), [](const Glib::ustring &a, const Glib::ustring &b) { return a.size() > b.size(); }); @@ -40,8 +51,7 @@ bool EmojiResource::Load() { } Glib::RefPtr EmojiResource::GetPixBuf(const Glib::ustring &pattern) { - Glib::ustring key = PatternToHex(pattern); - const auto it = m_index.find(key); + const auto it = m_index.find(pattern); if (it == m_index.end()) return Glib::RefPtr(); const int pos = it->second.first; const int len = it->second.second; @@ -54,35 +64,6 @@ Glib::RefPtr EmojiResource::GetPixBuf(const Glib::ustring &pattern) return loader->get_pixbuf(); } -Glib::ustring EmojiResource::PatternToHex(const Glib::ustring &pattern) { - Glib::ustring ret; - for (int i = 0; i < pattern.size(); i++) { - auto c = pattern.at(i); - ret += Glib::ustring::format(std::hex, c); - ret += "-"; - } - return ret.substr(0, ret.size() - 1); -} - -Glib::ustring EmojiResource::HexToPattern(Glib::ustring hex) { - std::vector parts; - Glib::ustring::size_type pos = 0; - Glib::ustring token; - while ((pos = hex.find("-")) != Glib::ustring::npos) { - token = hex.substr(0, pos); - if (token.length() % 2 == 1) - token = "0" + token; - parts.push_back(token); - hex.erase(0, pos + 1); - } - parts.push_back(hex); - Glib::ustring ret; - for (const auto &part : parts) { - auto x = static_cast(std::stoul(part.c_str(), nullptr, 16)); - ret += x; - } - return ret; -} void EmojiResource::ReplaceEmojis(Glib::RefPtr buf, int size) { auto get_text = [&]() -> auto { Gtk::TextBuffer::iterator a, b; @@ -124,7 +105,7 @@ void EmojiResource::ReplaceEmojis(Glib::RefPtr buf, int size) { std::string EmojiResource::GetShortCodeForPattern(const Glib::ustring &pattern) { auto it = m_pattern_shortcode_index.find(pattern); if (it != m_pattern_shortcode_index.end()) - return it->second; + return it->second.front(); return ""; } diff --git a/emojis.hpp b/emojis.hpp index cbcb2ca..61b8a71 100644 --- a/emojis.hpp +++ b/emojis.hpp @@ -12,15 +12,13 @@ public: EmojiResource(std::string filepath); bool Load(); Glib::RefPtr GetPixBuf(const Glib::ustring &pattern); - static Glib::ustring PatternToHex(const Glib::ustring &pattern); - static Glib::ustring HexToPattern(Glib::ustring hex); const std::vector &GetPatterns() const; const std::map &GetShortCodes() const; void ReplaceEmojis(Glib::RefPtr buf, int size = 24); std::string GetShortCodeForPattern(const Glib::ustring &pattern); private: - std::unordered_map m_pattern_shortcode_index; + std::unordered_map> m_pattern_shortcode_index; std::map m_shortcode_index; // shortcode -> pattern std::unordered_map> m_index; // pattern -> [pos, len] FILE *m_fp = nullptr; diff --git a/res/emojis.bin b/res/emojis.bin index 6c89d74..fd659ca 100644 Binary files a/res/emojis.bin and b/res/emojis.bin differ -- cgit v1.2.3