emoji_config.h 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184
  1. // This file is part of Desktop App Toolkit,
  2. // a set of libraries for developing nice desktop applications.
  3. //
  4. // For license and copyright information please follow this link:
  5. // https://github.com/desktop-app/legal/blob/master/LEGAL
  6. //
  7. #pragma once
  8. #include "base/basic_types.h"
  9. #include "base/binary_guard.h"
  10. #include "base/qt/qt_string_view.h"
  11. #include "emoji.h"
  12. #include <QtGui/QPainter>
  13. #include <QtGui/QPixmap>
  14. #include <rpl/producer.h>
  15. namespace Ui {
  16. namespace Emoji {
  17. namespace internal {
  18. [[nodiscard]] QString CacheFileFolder();
  19. [[nodiscard]] QString SetDataPath(int id);
  20. } // namespace internal
  21. void Init();
  22. void Clear();
  23. void ClearIrrelevantCache();
  24. // Thread safe, callback is called on main thread.
  25. void SwitchToSet(int id, Fn<void(bool)> callback);
  26. [[nodiscard]] int CurrentSetId();
  27. [[nodiscard]] int NeedToSwitchBackToId();
  28. void ClearNeedSwitchToId();
  29. [[nodiscard]] bool SetIsReady(int id);
  30. [[nodiscard]] rpl::producer<> Updated();
  31. [[nodiscard]] int GetSizeNormal();
  32. [[nodiscard]] int GetSizeLarge();
  33. #ifdef Q_OS_MAC
  34. [[nodiscard]] int GetSizeTouchbar();
  35. #endif
  36. class One {
  37. struct CreationTag {
  38. };
  39. public:
  40. One(One &&other) = default;
  41. One(
  42. const QString &id,
  43. EmojiPtr original,
  44. uint32 index,
  45. bool hasPostfix,
  46. bool colorizable,
  47. const CreationTag &);
  48. [[nodiscard]] QString id() const {
  49. return _id;
  50. }
  51. [[nodiscard]] QString text() const {
  52. return hasPostfix() ? (_id + QChar(kPostfix)) : _id;
  53. }
  54. [[nodiscard]] bool colored() const {
  55. return (_original != nullptr);
  56. }
  57. [[nodiscard]] EmojiPtr original() const {
  58. return _original ? _original : this;
  59. }
  60. [[nodiscard]] QString nonColoredId() const {
  61. return original()->id();
  62. }
  63. [[nodiscard]] bool hasPostfix() const {
  64. return _hasPostfix;
  65. }
  66. [[nodiscard]] bool hasVariants() const {
  67. return _colorizable || colored();
  68. }
  69. [[nodiscard]] int variantsCount() const;
  70. [[nodiscard]] int variantIndex(EmojiPtr variant) const;
  71. [[nodiscard]] EmojiPtr variant(int index) const;
  72. [[nodiscard]] int index() const {
  73. return _index;
  74. }
  75. [[nodiscard]] int sprite() const {
  76. return int(_index >> 9);
  77. }
  78. [[nodiscard]] int row() const {
  79. return int((_index >> 5) & 0x0FU);
  80. }
  81. [[nodiscard]] int column() const {
  82. return int(_index & 0x1FU);
  83. }
  84. [[nodiscard]] QString toUrl() const {
  85. return "emoji://e." + QString::number(index());
  86. }
  87. private:
  88. const QString _id;
  89. const EmojiPtr _original = nullptr;
  90. const uint32 _index = 0;
  91. const bool _hasPostfix = false;
  92. const bool _colorizable = false;
  93. friend void internal::Init();
  94. };
  95. [[nodiscard]] inline EmojiPtr FromUrl(const QString &url) {
  96. auto start = qstr("emoji://e.");
  97. if (url.startsWith(start)) {
  98. return internal::ByIndex(base::StringViewMid(url, start.size()).toInt()); // skip emoji://e.
  99. }
  100. return nullptr;
  101. }
  102. [[nodiscard]] inline EmojiPtr Find(const QChar *start, const QChar *end, int *outLength = nullptr) {
  103. return internal::Find(start, end, outLength);
  104. }
  105. [[nodiscard]] inline EmojiPtr Find(QStringView text, int *outLength = nullptr) {
  106. return Find(text.begin(), text.end(), outLength);
  107. }
  108. [[nodiscard]] QString IdFromOldKey(uint64 oldKey);
  109. [[nodiscard]] inline EmojiPtr FromOldKey(uint64 oldKey) {
  110. return Find(IdFromOldKey(oldKey));
  111. }
  112. [[nodiscard]] inline int ColorIndexFromCode(uint32 code) {
  113. switch (code) {
  114. case 0xD83CDFFBU: return 1;
  115. case 0xD83CDFFCU: return 2;
  116. case 0xD83CDFFDU: return 3;
  117. case 0xD83CDFFEU: return 4;
  118. case 0xD83CDFFFU: return 5;
  119. }
  120. return 0;
  121. }
  122. [[nodiscard]] inline int ColorIndexFromOldKey(uint64 oldKey) {
  123. return ColorIndexFromCode(uint32(oldKey & 0xFFFFFFFFLLU));
  124. }
  125. QVector<EmojiPtr> GetDefaultRecent();
  126. const QPixmap &SinglePixmap(EmojiPtr emoji, int fontHeight);
  127. void Draw(QPainter &p, EmojiPtr emoji, int size, int x, int y);
  128. class UniversalImages {
  129. public:
  130. explicit UniversalImages(int id);
  131. int id() const;
  132. bool ensureLoaded();
  133. void clear();
  134. void draw(QPainter &p, EmojiPtr emoji, int size, int x, int y) const;
  135. // This method must be thread safe and so it is called after
  136. // the _id value is fixed and all _sprites are loaded.
  137. QImage generate(int size, int index) const;
  138. private:
  139. const int _id = 0;
  140. std::vector<QImage> _sprites;
  141. };
  142. [[nodiscard]] const std::shared_ptr<UniversalImages> &SourceImages();
  143. void ClearSourceImages(const std::shared_ptr<UniversalImages> &images);
  144. } // namespace Emoji
  145. } // namespace Ui