Support custom emoji in IsolatedEmoji.

This commit is contained in:
John Preston 2022-07-25 17:54:15 +03:00
parent c5b32c53ef
commit a5d7b23a63
3 changed files with 43 additions and 40 deletions

View file

@ -22,8 +22,7 @@
#include <private/qharfbuzz_p.h>
#endif // Qt < 6.0.0
namespace Ui {
namespace Text {
namespace Ui::Text {
namespace {
constexpr auto kStringLinkIndexShift = uint16(0x8000);
@ -169,8 +168,7 @@ void InitTextItemWithScriptItem(QTextItemInt &ti, const QScriptItem &si) {
}
} // namespace
} // namespace Text
} // namespace Ui
} // namespace Ui::Text
const TextParseOptions kDefaultTextOptions = {
TextParseLinks | TextParseMultiline, // flags
@ -3723,17 +3721,20 @@ IsolatedEmoji String::toIsolatedEmoji() const {
|| _blocks.back()->type() != TextBlockTSkip) ? 0 : 1;
if ((_blocks.size() > kIsolatedEmojiLimit + skip)
|| !_spoilers.empty()) {
return IsolatedEmoji();
return {};
}
auto index = 0;
for (const auto &block : _blocks) {
const auto type = block->type();
if (block->lnkIndex()) {
return IsolatedEmoji();
return {};
} else if (type == TextBlockTEmoji) {
result.items[index++] = block.unsafe<EmojiBlock>()._emoji;
} else if (type == TextBlockTCustomEmoji) {
result.items[index++]
= block.unsafe<CustomEmojiBlock>()._custom->entityData();
} else if (type != TextBlockTSkip) {
return IsolatedEmoji();
return {};
}
}
return result;

View file

@ -60,8 +60,7 @@ inline bool operator!=(TextSelection a, TextSelection b) {
static constexpr TextSelection AllTextSelection = { 0, 0xFFFF };
namespace Ui {
namespace Text {
namespace Ui::Text {
struct IsolatedEmoji;
@ -110,31 +109,31 @@ public:
String &operator=(String &&other) = default;
~String() = default;
int countWidth(int width, bool breakEverywhere = false) const;
int countHeight(int width, bool breakEverywhere = false) const;
[[nodiscard]] int countWidth(int width, bool breakEverywhere = false) const;
[[nodiscard]] int countHeight(int width, bool breakEverywhere = false) const;
void countLineWidths(int width, QVector<int> *lineWidths, bool breakEverywhere = false) const;
void setText(const style::TextStyle &st, const QString &text, const TextParseOptions &options = kDefaultTextOptions);
void setMarkedText(const style::TextStyle &st, const TextWithEntities &textWithEntities, const TextParseOptions &options = kMarkupTextOptions, const std::any &context = {});
void setLink(uint16 lnkIndex, const ClickHandlerPtr &lnk);
bool hasLinks() const;
[[nodiscard]] bool hasLinks() const;
void setSpoiler(
uint16 lnkIndex,
const std::shared_ptr<SpoilerClickHandler> &lnk);
void setSpoilerShown(uint16 lnkIndex, bool shown);
int spoilersCount() const;
[[nodiscard]] int spoilersCount() const;
bool hasSkipBlock() const;
[[nodiscard]] bool hasSkipBlock() const;
bool updateSkipBlock(int width, int height);
bool removeSkipBlock();
int maxWidth() const {
[[nodiscard]] int maxWidth() const {
return _maxWidth.ceil().toInt();
}
int minHeight() const {
[[nodiscard]] int minHeight() const {
return _minHeight;
}
int countMaxMonospaceWidth() const;
[[nodiscard]] int countMaxMonospaceWidth() const;
void draw(Painter &p, int32 left, int32 top, int32 width, style::align align = style::al_left, int32 yFrom = 0, int32 yTo = -1, TextSelection selection = { 0, 0 }, bool fullWidthSelection = true) const;
void drawElided(Painter &p, int32 left, int32 top, int32 width, int32 lines = 1, style::align align = style::al_left, int32 yFrom = 0, int32 yTo = -1, int32 removeFromEnd = 0, bool breakEverywhere = false, TextSelection selection = { 0, 0 }) const;
@ -143,35 +142,36 @@ public:
void drawRight(Painter &p, int32 right, int32 top, int32 width, int32 outerw, style::align align = style::al_left, int32 yFrom = 0, int32 yTo = -1, TextSelection selection = { 0, 0 }) const;
void drawRightElided(Painter &p, int32 right, int32 top, int32 width, int32 outerw, int32 lines = 1, style::align align = style::al_left, int32 yFrom = 0, int32 yTo = -1, int32 removeFromEnd = 0, bool breakEverywhere = false, TextSelection selection = { 0, 0 }) const;
StateResult getState(QPoint point, int width, StateRequest request = StateRequest()) const;
StateResult getStateLeft(QPoint point, int width, int outerw, StateRequest request = StateRequest()) const;
StateResult getStateElided(QPoint point, int width, StateRequestElided request = StateRequestElided()) const;
StateResult getStateElidedLeft(QPoint point, int width, int outerw, StateRequestElided request = StateRequestElided()) const;
[[nodiscard]] StateResult getState(QPoint point, int width, StateRequest request = StateRequest()) const;
[[nodiscard]] StateResult getStateLeft(QPoint point, int width, int outerw, StateRequest request = StateRequest()) const;
[[nodiscard]] StateResult getStateElided(QPoint point, int width, StateRequestElided request = StateRequestElided()) const;
[[nodiscard]] StateResult getStateElidedLeft(QPoint point, int width, int outerw, StateRequestElided request = StateRequestElided()) const;
[[nodiscard]] TextSelection adjustSelection(TextSelection selection, TextSelectType selectType) const;
bool isFullSelection(TextSelection selection) const {
[[nodiscard]] bool isFullSelection(TextSelection selection) const {
return (selection.from == 0) && (selection.to >= _text.size());
}
bool isEmpty() const;
bool isNull() const {
[[nodiscard]] bool isEmpty() const;
[[nodiscard]] bool isNull() const {
return !_st;
}
int length() const {
[[nodiscard]] int length() const {
return _text.size();
}
[[nodiscard]] bool hasCustomEmoji() const;
void unloadCustomEmoji();
QString toString(TextSelection selection = AllTextSelection) const;
TextWithEntities toTextWithEntities(
[[nodiscard]] QString toString(
TextSelection selection = AllTextSelection) const;
TextForMimeData toTextForMimeData(
[[nodiscard]] TextWithEntities toTextWithEntities(
TextSelection selection = AllTextSelection) const;
IsolatedEmoji toIsolatedEmoji() const;
[[nodiscard]] TextForMimeData toTextForMimeData(
TextSelection selection = AllTextSelection) const;
[[nodiscard]] IsolatedEmoji toIsolatedEmoji() const;
const style::TextStyle *style() const {
[[nodiscard]] const style::TextStyle *style() const {
return _st;
}
@ -200,7 +200,7 @@ private:
// it is also called from move constructor / assignment operator
void clearFields();
ClickHandlerPtr spoilerLink(uint16 spoilerIndex) const;
[[nodiscard]] ClickHandlerPtr spoilerLink(uint16 spoilerIndex) const;
TextForMimeData toText(
TextSelection selection,
@ -241,8 +241,7 @@ private:
[[nodiscard]] bool IsReplacedBySpace(QChar ch);
[[nodiscard]] bool IsTrimmed(QChar ch);
} // namespace Text
} // namespace Ui
} // namespace Ui::Text
inline TextSelection snapSelection(int from, int to) {
return { static_cast<uint16>(std::clamp(from, 0, 0xFFFF)), static_cast<uint16>(std::clamp(to, 0, 0xFFFF)) };

View file

@ -6,17 +6,19 @@
//
#pragma once
namespace Ui {
namespace Text {
#include "base/variant.h"
namespace Ui::Text {
inline constexpr auto kIsolatedEmojiLimit = 3;
struct IsolatedEmoji {
using Items = std::array<EmojiPtr, kIsolatedEmojiLimit>;
Items items = { { nullptr } };
using Item = std::variant<v::null_t, EmojiPtr, QString>;
using Items = std::array<Item, kIsolatedEmojiLimit>;
Items items = {};
[[nodiscard]] bool empty() const {
return items[0] == nullptr;
return v::is_null(items[0]);
}
[[nodiscard]] explicit operator bool() const {
return !empty();
@ -41,5 +43,6 @@ struct IsolatedEmoji {
}
};
} // namespace Text
} // namespace Ui
constexpr auto t = sizeof(IsolatedEmoji);
} // namespace Ui::Text