Track isOnlyEmojiAndSpaces in Ui::Text::String.

This commit is contained in:
John Preston 2023-01-27 19:00:30 +04:00
parent 7ec9e05510
commit f2e698f220
3 changed files with 37 additions and 0 deletions

View file

@ -872,6 +872,10 @@ OnlyCustomEmoji String::toOnlyCustomEmoji() const {
return result; return result;
} }
bool String::isOnlyEmojiAndSpaces() const {
return _isOnlyEmojiAndSpaces;
}
QString String::toString(TextSelection selection) const { QString String::toString(TextSelection selection) const {
return toText(selection, false, false).rich.text; return toText(selection, false, false).rich.text;
} }

View file

@ -227,6 +227,8 @@ public:
[[nodiscard]] bool isOnlyCustomEmoji() const; [[nodiscard]] bool isOnlyCustomEmoji() const;
[[nodiscard]] OnlyCustomEmoji toOnlyCustomEmoji() const; [[nodiscard]] OnlyCustomEmoji toOnlyCustomEmoji() const;
[[nodiscard]] bool isOnlyEmojiAndSpaces() const;
[[nodiscard]] const style::TextStyle *style() const { [[nodiscard]] const style::TextStyle *style() const {
return _st; return _st;
} }
@ -280,6 +282,7 @@ private:
bool _hasCustomEmoji : 1 = false; bool _hasCustomEmoji : 1 = false;
bool _isIsolatedEmoji : 1 = false; bool _isIsolatedEmoji : 1 = false;
bool _isOnlyCustomEmoji : 1 = false; bool _isOnlyCustomEmoji : 1 = false;
bool _isOnlyEmojiAndSpaces : 1 = false;
QString _text; QString _text;
const style::TextStyle *_st = nullptr; const style::TextStyle *_st = nullptr;

View file

@ -606,6 +606,9 @@ void Parser::finalize(const TextParseOptions &options) {
_t->_hasCustomEmoji = false; _t->_hasCustomEmoji = false;
_t->_isIsolatedEmoji = true; _t->_isIsolatedEmoji = true;
_t->_isOnlyCustomEmoji = true; _t->_isOnlyCustomEmoji = true;
_t->_isOnlyEmojiAndSpaces = true;
auto spacesCheckFrom = uint16(-1);
const auto length = int(_t->_text.size());
for (auto &block : _t->_blocks) { for (auto &block : _t->_blocks) {
if (block->type() == TextBlockTCustomEmoji) { if (block->type() == TextBlockTCustomEmoji) {
_t->_hasCustomEmoji = true; _t->_hasCustomEmoji = true;
@ -615,6 +618,23 @@ void Parser::finalize(const TextParseOptions &options) {
} else if (block->lnkIndex()) { } else if (block->lnkIndex()) {
_t->_isOnlyCustomEmoji = _t->_isIsolatedEmoji = false; _t->_isOnlyCustomEmoji = _t->_isIsolatedEmoji = false;
} }
if (_t->_isOnlyEmojiAndSpaces) {
if (block->type() == TextBlockTText) {
if (spacesCheckFrom == uint16(-1)) {
spacesCheckFrom = block->from();
}
} else if (spacesCheckFrom != uint16(-1)) {
const auto checkTill = block->from();
for (auto i = spacesCheckFrom; i != checkTill; ++i) {
Assert(i < length);
if (!_t->_text[i].isSpace()) {
_t->_isOnlyEmojiAndSpaces = false;
break;
}
}
spacesCheckFrom = uint16(-1);
}
}
if (_t->_isIsolatedEmoji) { if (_t->_isIsolatedEmoji) {
if (block->type() == TextBlockTCustomEmoji if (block->type() == TextBlockTCustomEmoji
|| block->type() == TextBlockTEmoji) { || block->type() == TextBlockTEmoji) {
@ -694,6 +714,16 @@ void Parser::finalize(const TextParseOptions &options) {
if (_t->_blocks.empty() || _t->_spoiler.data) { if (_t->_blocks.empty() || _t->_spoiler.data) {
_t->_isIsolatedEmoji = false; _t->_isIsolatedEmoji = false;
} }
if (_t->_isOnlyEmojiAndSpaces && spacesCheckFrom != uint16(-1)) {
Assert(spacesCheckFrom < length);
for (auto i = spacesCheckFrom; i != length; ++i) {
Assert(i < length);
if (!_t->_text[i].isSpace()) {
_t->_isOnlyEmojiAndSpaces = false;
break;
}
}
}
_t->_links.squeeze(); _t->_links.squeeze();
_t->_blocks.shrink_to_fit(); _t->_blocks.shrink_to_fit();
_t->_text.squeeze(); _t->_text.squeeze();