text_custom_emoji.cpp 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154
  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. #include "ui/text/text_custom_emoji.h"
  8. #include "ui/text/text_utilities.h"
  9. #include "ui/text/text.h"
  10. namespace Ui::Text {
  11. int AdjustCustomEmojiSize(int emojiSize) {
  12. return base::SafeRound(emojiSize * 1.12);
  13. }
  14. ShiftedEmoji::ShiftedEmoji(
  15. std::unique_ptr<Ui::Text::CustomEmoji> wrapped,
  16. QPoint shift)
  17. : _wrapped(std::move(wrapped))
  18. , _shift(shift) {
  19. }
  20. int ShiftedEmoji::width() {
  21. return _wrapped->width();
  22. }
  23. QString ShiftedEmoji::entityData() {
  24. return _wrapped->entityData();
  25. }
  26. void ShiftedEmoji::paint(QPainter &p, const Context &context) {
  27. auto copy = context;
  28. copy.position += _shift;
  29. _wrapped->paint(p, copy);
  30. }
  31. void ShiftedEmoji::unload() {
  32. _wrapped->unload();
  33. }
  34. bool ShiftedEmoji::ready() {
  35. return _wrapped->ready();
  36. }
  37. bool ShiftedEmoji::readyInDefaultState() {
  38. return _wrapped->readyInDefaultState();
  39. }
  40. FirstFrameEmoji::FirstFrameEmoji(std::unique_ptr<CustomEmoji> wrapped)
  41. : _wrapped(std::move(wrapped)) {
  42. }
  43. int FirstFrameEmoji::width() {
  44. return _wrapped->width();
  45. }
  46. QString FirstFrameEmoji::entityData() {
  47. return _wrapped->entityData();
  48. }
  49. void FirstFrameEmoji::paint(QPainter &p, const Context &context) {
  50. const auto was = context.internal.forceFirstFrame;
  51. context.internal.forceFirstFrame = true;
  52. _wrapped->paint(p, context);
  53. context.internal.forceFirstFrame = was;
  54. }
  55. void FirstFrameEmoji::unload() {
  56. _wrapped->unload();
  57. }
  58. bool FirstFrameEmoji::ready() {
  59. return _wrapped->ready();
  60. }
  61. bool FirstFrameEmoji::readyInDefaultState() {
  62. return _wrapped->readyInDefaultState();
  63. }
  64. LimitedLoopsEmoji::LimitedLoopsEmoji(
  65. std::unique_ptr<CustomEmoji> wrapped,
  66. int limit,
  67. bool stopOnLast)
  68. : _wrapped(std::move(wrapped))
  69. , _limit(limit)
  70. , _stopOnLast(stopOnLast) {
  71. }
  72. int LimitedLoopsEmoji::width() {
  73. return _wrapped->width();
  74. }
  75. QString LimitedLoopsEmoji::entityData() {
  76. return _wrapped->entityData();
  77. }
  78. void LimitedLoopsEmoji::paint(QPainter &p, const Context &context) {
  79. if (_played < _limit) {
  80. if (_wrapped->readyInDefaultState()) {
  81. if (_inLoop) {
  82. _inLoop = false;
  83. ++_played;
  84. }
  85. } else if (_wrapped->ready()) {
  86. _inLoop = true;
  87. }
  88. }
  89. if (_played == _limit) {
  90. const auto wasFirst = context.internal.forceFirstFrame;
  91. const auto wasLast = context.internal.forceLastFrame;
  92. (_stopOnLast
  93. ? context.internal.forceLastFrame
  94. : context.internal.forceFirstFrame) = true;
  95. _wrapped->paint(p, context);
  96. context.internal.forceFirstFrame = wasFirst;
  97. context.internal.forceLastFrame = wasLast;
  98. } else if (_played + 1 == _limit && _inLoop && _stopOnLast) {
  99. const auto wasLast = context.internal.overrideFirstWithLastFrame;
  100. context.internal.overrideFirstWithLastFrame = true;
  101. _wrapped->paint(p, context);
  102. context.internal.overrideFirstWithLastFrame = wasLast;
  103. } else {
  104. _wrapped->paint(p, context);
  105. }
  106. }
  107. void LimitedLoopsEmoji::unload() {
  108. _wrapped->unload();
  109. _inLoop = false;
  110. _played = 0;
  111. }
  112. bool LimitedLoopsEmoji::ready() {
  113. return _wrapped->ready();
  114. }
  115. bool LimitedLoopsEmoji::readyInDefaultState() {
  116. return _wrapped->readyInDefaultState();
  117. }
  118. std::unique_ptr<CustomEmoji> MakeCustomEmoji(
  119. QStringView data,
  120. const MarkedContext &context) {
  121. if (auto simple = TryMakeSimpleEmoji(data)) {
  122. return simple;
  123. } else if (const auto &factory = context.customEmojiFactory) {
  124. return factory(data, context);
  125. }
  126. return nullptr;
  127. }
  128. } // namespace Ui::Text