mirror of
https://github.com/telegramdesktop/tdesktop
synced 2025-03-25 04:38:23 +00:00
Repaint skin-toned animated emoji.
This commit is contained in:
parent
61c1c10ed9
commit
bc83df9d7f
@ -1115,13 +1115,13 @@ template <typename Method>
|
||||
auto LottieCachedFromContent(
|
||||
Method &&method,
|
||||
Storage::Cache::Key baseKey,
|
||||
LottieSize sizeTag,
|
||||
uint8 keyShift,
|
||||
not_null<Main::Session*> session,
|
||||
const QByteArray &content,
|
||||
QSize box) {
|
||||
const auto key = Storage::Cache::Key{
|
||||
baseKey.high,
|
||||
baseKey.low + int(sizeTag)
|
||||
baseKey.low + keyShift
|
||||
};
|
||||
const auto get = [=](FnMut<void(QByteArray &&cached)> handler) {
|
||||
session->data().cacheBigFile().get(
|
||||
@ -1145,7 +1145,7 @@ template <typename Method>
|
||||
auto LottieFromDocument(
|
||||
Method &&method,
|
||||
not_null<DocumentData*> document,
|
||||
LottieSize sizeTag,
|
||||
uint8 keyShift,
|
||||
QSize box) {
|
||||
const auto data = document->data();
|
||||
const auto filepath = document->filepath();
|
||||
@ -1159,7 +1159,7 @@ auto LottieFromDocument(
|
||||
return LottieCachedFromContent(
|
||||
std::forward<Method>(method),
|
||||
*baseKey,
|
||||
sizeTag,
|
||||
keyShift,
|
||||
&document->session(),
|
||||
Lottie::ReadContent(data, filepath),
|
||||
box);
|
||||
@ -1175,11 +1175,32 @@ std::unique_ptr<Lottie::SinglePlayer> LottiePlayerFromDocument(
|
||||
QSize box,
|
||||
Lottie::Quality quality,
|
||||
std::shared_ptr<Lottie::FrameRenderer> renderer) {
|
||||
return LottiePlayerFromDocument(
|
||||
document,
|
||||
nullptr,
|
||||
sizeTag,
|
||||
box,
|
||||
quality,
|
||||
std::move(renderer));
|
||||
}
|
||||
|
||||
std::unique_ptr<Lottie::SinglePlayer> LottiePlayerFromDocument(
|
||||
not_null<DocumentData*> document,
|
||||
const Lottie::ColorReplacements *replacements,
|
||||
LottieSize sizeTag,
|
||||
QSize box,
|
||||
Lottie::Quality quality,
|
||||
std::shared_ptr<Lottie::FrameRenderer> renderer) {
|
||||
const auto method = [&](auto &&...args) {
|
||||
return std::make_unique<Lottie::SinglePlayer>(
|
||||
std::forward<decltype(args)>(args)..., quality, std::move(renderer));
|
||||
std::forward<decltype(args)>(args)...,
|
||||
quality,
|
||||
replacements,
|
||||
std::move(renderer));
|
||||
};
|
||||
return LottieFromDocument(method, document, sizeTag, box);
|
||||
const auto tag = replacements ? replacements->tag : uint8(0);
|
||||
const auto keyShift = ((tag << 4) & 0xF0) | (uint8(sizeTag) & 0x0F);
|
||||
return LottieFromDocument(method, document, uint8(keyShift), box);
|
||||
}
|
||||
|
||||
not_null<Lottie::Animation*> LottieAnimationFromDocument(
|
||||
@ -1190,7 +1211,7 @@ not_null<Lottie::Animation*> LottieAnimationFromDocument(
|
||||
const auto method = [&](auto &&...args) {
|
||||
return player->append(std::forward<decltype(args)>(args)...);
|
||||
};
|
||||
return LottieFromDocument(method, document, sizeTag, box);
|
||||
return LottieFromDocument(method, document, uint8(sizeTag), box);
|
||||
}
|
||||
|
||||
bool HasLottieThumbnail(
|
||||
@ -1243,7 +1264,7 @@ std::unique_ptr<Lottie::SinglePlayer> LottieThumbnail(
|
||||
return LottieCachedFromContent(
|
||||
method,
|
||||
*baseKey,
|
||||
sizeTag,
|
||||
uint8(sizeTag),
|
||||
&sticker->session(),
|
||||
content,
|
||||
box);
|
||||
|
@ -28,6 +28,7 @@ class MultiPlayer;
|
||||
class FrameRenderer;
|
||||
class Animation;
|
||||
enum class Quality : char;
|
||||
struct ColorReplacements;
|
||||
} // namespace Lottie
|
||||
|
||||
namespace Stickers {
|
||||
@ -140,6 +141,13 @@ enum class LottieSize : uchar {
|
||||
QSize box,
|
||||
Lottie::Quality quality = Lottie::Quality(),
|
||||
std::shared_ptr<Lottie::FrameRenderer> renderer = nullptr);
|
||||
[[nodiscard]] std::unique_ptr<Lottie::SinglePlayer> LottiePlayerFromDocument(
|
||||
not_null<DocumentData*> document,
|
||||
const Lottie::ColorReplacements *replacements,
|
||||
LottieSize sizeTag,
|
||||
QSize box,
|
||||
Lottie::Quality quality = Lottie::Quality(),
|
||||
std::shared_ptr<Lottie::FrameRenderer> renderer = nullptr);
|
||||
[[nodiscard]] not_null<Lottie::Animation*> LottieAnimationFromDocument(
|
||||
not_null<Lottie::MultiPlayer*> player,
|
||||
not_null<DocumentData*> document,
|
||||
|
@ -8,6 +8,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
#include "chat_helpers/stickers_emoji_pack.h"
|
||||
|
||||
#include "history/history_item.h"
|
||||
#include "lottie/lottie_common.h"
|
||||
#include "ui/emoji_config.h"
|
||||
#include "ui/text/text_isolated_emoji.h"
|
||||
#include "ui/image/image_source.h"
|
||||
@ -54,6 +55,64 @@ constexpr auto kClearSourceTimeout = 10 * crl::time(1000);
|
||||
) * cIntRetinaFactor();
|
||||
}
|
||||
|
||||
[[nodiscard]] const Lottie::ColorReplacements *ColorReplacements(int index) {
|
||||
Expects(index >= 1 && index <= 5);
|
||||
|
||||
static const auto color1 = Lottie::ColorReplacements{
|
||||
{
|
||||
{ 0xf77e41U, 0xca907aU },
|
||||
{ 0xffb139U, 0xedc5a5U },
|
||||
{ 0xffd140U, 0xf7e3c3U },
|
||||
{ 0xffdf79U, 0xfbefd6U },
|
||||
},
|
||||
1,
|
||||
};
|
||||
static const auto color2 = Lottie::ColorReplacements{
|
||||
{
|
||||
{ 0xf77e41U, 0xaa7c60U },
|
||||
{ 0xffb139U, 0xc8a987U },
|
||||
{ 0xffd140U, 0xddc89fU },
|
||||
{ 0xffdf79U, 0xe6d6b2U },
|
||||
},
|
||||
2,
|
||||
};
|
||||
static const auto color3 = Lottie::ColorReplacements{
|
||||
{
|
||||
{ 0xf77e41U, 0x8c6148U },
|
||||
{ 0xffb139U, 0xad8562U },
|
||||
{ 0xffd140U, 0xc49e76U },
|
||||
{ 0xffdf79U, 0xd4b188U },
|
||||
},
|
||||
3,
|
||||
};
|
||||
static const auto color4 = Lottie::ColorReplacements{
|
||||
{
|
||||
{ 0xf77e41U, 0x6e3c2cU },
|
||||
{ 0xffb139U, 0x925a34U },
|
||||
{ 0xffd140U, 0xa16e46U },
|
||||
{ 0xffdf79U, 0xac7a52U },
|
||||
},
|
||||
4,
|
||||
};
|
||||
static const auto color5 = Lottie::ColorReplacements{
|
||||
{
|
||||
{ 0xf77e41U, 0x291c12U },
|
||||
{ 0xffb139U, 0x472a22U },
|
||||
{ 0xffd140U, 0x573b30U },
|
||||
{ 0xffdf79U, 0x68493cU },
|
||||
},
|
||||
5,
|
||||
};
|
||||
static const auto list = std::array{
|
||||
&color1,
|
||||
&color2,
|
||||
&color3,
|
||||
&color4,
|
||||
&color5,
|
||||
};
|
||||
return list[index - 1];
|
||||
}
|
||||
|
||||
class ImageSource : public Images::Source {
|
||||
public:
|
||||
explicit ImageSource(
|
||||
@ -388,14 +447,26 @@ void EmojiPack::remove(not_null<const HistoryItem*> item) {
|
||||
}
|
||||
}
|
||||
|
||||
DocumentData *EmojiPack::stickerForEmoji(const IsolatedEmoji &emoji) {
|
||||
auto EmojiPack::stickerForEmoji(const IsolatedEmoji &emoji) -> Sticker {
|
||||
Expects(!emoji.empty());
|
||||
|
||||
if (emoji.items[1] != nullptr) {
|
||||
return nullptr;
|
||||
return Sticker();
|
||||
}
|
||||
const auto i = _map.find(emoji.items[0]);
|
||||
return (i != end(_map)) ? i->second.get() : nullptr;
|
||||
const auto first = emoji.items[0];
|
||||
const auto i = _map.find(first);
|
||||
if (i != end(_map)) {
|
||||
return { i->second.get(), nullptr };
|
||||
}
|
||||
if (!first->colored()) {
|
||||
return Sticker();
|
||||
}
|
||||
const auto j = _map.find(first->original());
|
||||
if (j != end(_map)) {
|
||||
const auto index = first->variantIndex(first);
|
||||
return { j->second.get(), details::ColorReplacements(index) };
|
||||
}
|
||||
return Sticker();
|
||||
}
|
||||
|
||||
std::shared_ptr<Image> EmojiPack::image(EmojiPtr emoji) {
|
||||
|
@ -12,12 +12,16 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
|
||||
#include <crl/crl_object_on_queue.h>
|
||||
|
||||
class HistoryItem;
|
||||
class DocumentData;
|
||||
|
||||
namespace Main {
|
||||
class Session;
|
||||
} // namespace Main
|
||||
|
||||
class HistoryItem;
|
||||
class DocumentData;
|
||||
namespace Lottie {
|
||||
struct ColorReplacements;
|
||||
} // namespace Lottie
|
||||
|
||||
namespace Ui {
|
||||
namespace Text {
|
||||
@ -37,13 +41,25 @@ using IsolatedEmoji = Ui::Text::IsolatedEmoji;
|
||||
|
||||
class EmojiPack final {
|
||||
public:
|
||||
struct Sticker {
|
||||
DocumentData *document = nullptr;
|
||||
const Lottie::ColorReplacements *replacements = nullptr;
|
||||
|
||||
[[nodiscard]] bool empty() const {
|
||||
return (document == nullptr);
|
||||
}
|
||||
[[nodiscard]] explicit operator bool() const {
|
||||
return !empty();
|
||||
}
|
||||
};
|
||||
|
||||
explicit EmojiPack(not_null<Main::Session*> session);
|
||||
~EmojiPack();
|
||||
|
||||
bool add(not_null<HistoryItem*> item);
|
||||
void remove(not_null<const HistoryItem*> item);
|
||||
|
||||
[[nodiscard]] DocumentData *stickerForEmoji(const IsolatedEmoji &emoji);
|
||||
[[nodiscard]] Sticker stickerForEmoji(const IsolatedEmoji &emoji);
|
||||
[[nodiscard]] std::shared_ptr<Image> image(EmojiPtr emoji);
|
||||
|
||||
private:
|
||||
|
@ -349,10 +349,13 @@ void Element::refreshMedia() {
|
||||
&& session->settings().largeEmoji()) {
|
||||
const auto emoji = _data->isolatedEmoji();
|
||||
const auto emojiStickers = &session->emojiStickersPack();
|
||||
if (const auto document = emojiStickers->stickerForEmoji(emoji)) {
|
||||
if (const auto sticker = emojiStickers->stickerForEmoji(emoji)) {
|
||||
_media = std::make_unique<UnwrappedMedia>(
|
||||
this,
|
||||
std::make_unique<Sticker>(this, document));
|
||||
std::make_unique<Sticker>(
|
||||
this,
|
||||
sticker.document,
|
||||
sticker.replacements));
|
||||
} else {
|
||||
_media = std::make_unique<UnwrappedMedia>(
|
||||
this,
|
||||
|
@ -37,9 +37,11 @@ double GetEmojiStickerZoom(not_null<Main::Session*> session) {
|
||||
|
||||
Sticker::Sticker(
|
||||
not_null<Element*> parent,
|
||||
not_null<DocumentData*> document)
|
||||
not_null<DocumentData*> document,
|
||||
const Lottie::ColorReplacements *replacements)
|
||||
: _parent(parent)
|
||||
, _document(document) {
|
||||
, _document(document)
|
||||
, _replacements(replacements) {
|
||||
_document->loadThumbnail(parent->data()->fullId());
|
||||
}
|
||||
|
||||
@ -82,7 +84,7 @@ void Sticker::draw(Painter &p, const QRect &r, bool selected) {
|
||||
|
||||
if (_lottie && _lottie->ready()) {
|
||||
paintLottie(p, r, selected);
|
||||
} else {
|
||||
} else if (!_lottie || !_replacements) {
|
||||
paintPixmap(p, r, selected);
|
||||
}
|
||||
}
|
||||
@ -185,8 +187,9 @@ void Sticker::refreshLink() {
|
||||
void Sticker::setupLottie() {
|
||||
_lottie = Stickers::LottiePlayerFromDocument(
|
||||
_document,
|
||||
_replacements,
|
||||
Stickers::LottieSize::MessageHistory,
|
||||
QSize(st::maxStickerSize, st::maxStickerSize) * cIntRetinaFactor(),
|
||||
_size * cIntRetinaFactor(),
|
||||
Lottie::Quality::High);
|
||||
_parent->data()->history()->owner().registerHeavyViewPart(_parent);
|
||||
|
||||
|
@ -16,6 +16,7 @@ struct FileOrigin;
|
||||
|
||||
namespace Lottie {
|
||||
class SinglePlayer;
|
||||
struct ColorReplacements;
|
||||
} // namespace Lottie
|
||||
|
||||
namespace HistoryView {
|
||||
@ -26,7 +27,8 @@ class Sticker final
|
||||
public:
|
||||
Sticker(
|
||||
not_null<Element*> parent,
|
||||
not_null<DocumentData*> document);
|
||||
not_null<DocumentData*> document,
|
||||
const Lottie::ColorReplacements *replacements = nullptr);
|
||||
~Sticker();
|
||||
|
||||
QSize size() override;
|
||||
@ -57,6 +59,7 @@ private:
|
||||
|
||||
const not_null<Element*> _parent;
|
||||
const not_null<DocumentData*> _document;
|
||||
const Lottie::ColorReplacements *_replacements = nullptr;
|
||||
std::unique_ptr<Lottie::SinglePlayer> _lottie;
|
||||
ClickHandlerPtr _link;
|
||||
QSize _size;
|
||||
|
@ -81,11 +81,12 @@ details::InitData CheckSharedState(std::unique_ptr<SharedState> state) {
|
||||
details::InitData Init(
|
||||
const QByteArray &content,
|
||||
const FrameRequest &request,
|
||||
Quality quality) {
|
||||
Quality quality,
|
||||
const ColorReplacements *replacements) {
|
||||
if (const auto error = ContentError(content)) {
|
||||
return *error;
|
||||
}
|
||||
auto animation = details::CreateFromContent(content);
|
||||
auto animation = details::CreateFromContent(content, replacements);
|
||||
return animation
|
||||
? CheckSharedState(std::make_unique<SharedState>(
|
||||
std::move(animation),
|
||||
@ -99,7 +100,8 @@ details::InitData Init(
|
||||
FnMut<void(QByteArray &&cached)> put,
|
||||
const QByteArray &cached,
|
||||
const FrameRequest &request,
|
||||
Quality quality) {
|
||||
Quality quality,
|
||||
const ColorReplacements *replacements) {
|
||||
Expects(!request.empty());
|
||||
|
||||
if (const auto error = ContentError(content)) {
|
||||
@ -108,10 +110,13 @@ details::InitData Init(
|
||||
auto cache = std::make_unique<Cache>(cached, request, std::move(put));
|
||||
const auto prepare = !cache->framesCount()
|
||||
|| (cache->framesReady() < cache->framesCount());
|
||||
auto animation = prepare ? details::CreateFromContent(content) : nullptr;
|
||||
auto animation = prepare
|
||||
? details::CreateFromContent(content, replacements)
|
||||
: nullptr;
|
||||
return (!prepare || animation)
|
||||
? CheckSharedState(std::make_unique<SharedState>(
|
||||
content,
|
||||
replacements,
|
||||
std::move(animation),
|
||||
std::move(cache),
|
||||
request,
|
||||
@ -124,7 +129,8 @@ details::InitData Init(
|
||||
namespace details {
|
||||
|
||||
std::unique_ptr<rlottie::Animation> CreateFromContent(
|
||||
const QByteArray &content) {
|
||||
const QByteArray &content,
|
||||
const ColorReplacements *replacements) {
|
||||
const auto string = UnpackGzip(content);
|
||||
Assert(string.size() <= kMaxFileSize);
|
||||
|
||||
@ -132,7 +138,10 @@ std::unique_ptr<rlottie::Animation> CreateFromContent(
|
||||
string,
|
||||
std::string(),
|
||||
std::string(),
|
||||
false);
|
||||
false,
|
||||
(replacements
|
||||
? replacements->replacements
|
||||
: std::vector<std::pair<std::uint32_t, std::uint32_t>>()));
|
||||
if (!result) {
|
||||
LOG(("Lottie Error: Parse failed."));
|
||||
}
|
||||
@ -146,8 +155,8 @@ std::shared_ptr<FrameRenderer> MakeFrameRenderer() {
|
||||
}
|
||||
|
||||
QImage ReadThumbnail(const QByteArray &content) {
|
||||
return Init(content, FrameRequest(), Quality::High).match([](
|
||||
const std::unique_ptr<SharedState> &state) {
|
||||
return Init(content, FrameRequest(), Quality::High, nullptr).match([](
|
||||
const std::unique_ptr<SharedState> &state) {
|
||||
return state->frameForPaint()->original;
|
||||
}, [](Error) {
|
||||
return QImage();
|
||||
@ -158,11 +167,13 @@ Animation::Animation(
|
||||
not_null<Player*> player,
|
||||
const QByteArray &content,
|
||||
const FrameRequest &request,
|
||||
Quality quality)
|
||||
Quality quality,
|
||||
const ColorReplacements *replacements)
|
||||
: _player(player) {
|
||||
const auto weak = base::make_weak(this);
|
||||
crl::async([=] {
|
||||
crl::on_main(weak, [=, data = Init(content, request, quality)]() mutable {
|
||||
auto result = Init(content, request, quality, replacements);
|
||||
crl::on_main(weak, [=, data = std::move(result)]() mutable {
|
||||
initDone(std::move(data));
|
||||
});
|
||||
});
|
||||
@ -174,12 +185,19 @@ Animation::Animation(
|
||||
FnMut<void(QByteArray &&cached)> put, // Unknown thread.
|
||||
const QByteArray &content,
|
||||
const FrameRequest &request,
|
||||
Quality quality)
|
||||
Quality quality,
|
||||
const ColorReplacements *replacements)
|
||||
: _player(player) {
|
||||
const auto weak = base::make_weak(this);
|
||||
get([=, put = std::move(put)](QByteArray &&cached) mutable {
|
||||
crl::async([=, put = std::move(put)]() mutable {
|
||||
auto result = Init(content, std::move(put), cached, request, quality);
|
||||
auto result = Init(
|
||||
content,
|
||||
std::move(put),
|
||||
cached,
|
||||
request,
|
||||
quality,
|
||||
replacements);
|
||||
crl::on_main(weak, [=, data = std::move(result)]() mutable {
|
||||
initDone(std::move(data));
|
||||
});
|
||||
|
@ -34,7 +34,8 @@ namespace details {
|
||||
using InitData = base::variant<std::unique_ptr<SharedState>, Error>;
|
||||
|
||||
std::unique_ptr<rlottie::Animation> CreateFromContent(
|
||||
const QByteArray &content);
|
||||
const QByteArray &content,
|
||||
const ColorReplacements *replacements);
|
||||
|
||||
} // namespace details
|
||||
|
||||
@ -49,14 +50,16 @@ public:
|
||||
not_null<Player*> player,
|
||||
const QByteArray &content,
|
||||
const FrameRequest &request,
|
||||
Quality quality);
|
||||
Quality quality,
|
||||
const ColorReplacements *replacements = nullptr);
|
||||
Animation(
|
||||
not_null<Player*> player,
|
||||
FnMut<void(FnMut<void(QByteArray &&cached)>)> get, // Main thread.
|
||||
FnMut<void(QByteArray &&cached)> put, // Unknown thread.
|
||||
const QByteArray &content,
|
||||
const FrameRequest &request,
|
||||
Quality quality);
|
||||
Quality quality,
|
||||
const ColorReplacements *replacements = nullptr);
|
||||
|
||||
[[nodiscard]] bool ready() const;
|
||||
[[nodiscard]] QImage frame() const;
|
||||
|
@ -55,6 +55,11 @@ enum class Quality : char {
|
||||
High,
|
||||
};
|
||||
|
||||
struct ColorReplacements {
|
||||
std::vector<std::pair<std::uint32_t, std::uint32_t>> replacements;
|
||||
uint8 tag = 0;
|
||||
};
|
||||
|
||||
QByteArray ReadContent(const QByteArray &data, const QString &filepath);
|
||||
|
||||
} // namespace Lottie
|
||||
|
@ -255,6 +255,7 @@ SharedState::SharedState(
|
||||
|
||||
SharedState::SharedState(
|
||||
const QByteArray &content,
|
||||
const ColorReplacements *replacements,
|
||||
std::unique_ptr<rlottie::Animation> animation,
|
||||
std::unique_ptr<Cache> cache,
|
||||
const FrameRequest &request,
|
||||
@ -263,7 +264,8 @@ SharedState::SharedState(
|
||||
, _quality(quality)
|
||||
, _cache(std::move(cache))
|
||||
, _animation(std::move(animation))
|
||||
, _content(content) {
|
||||
, _content(content)
|
||||
, _replacements(replacements) {
|
||||
construct(request);
|
||||
}
|
||||
|
||||
@ -310,7 +312,7 @@ void SharedState::renderFrame(
|
||||
if (_cache && _cache->renderFrame(image, request, index)) {
|
||||
return;
|
||||
} else if (!_animation) {
|
||||
_animation = details::CreateFromContent(_content);
|
||||
_animation = details::CreateFromContent(_content, _replacements);
|
||||
}
|
||||
|
||||
image.fill(Qt::transparent);
|
||||
|
@ -57,6 +57,7 @@ public:
|
||||
Quality quality);
|
||||
SharedState(
|
||||
const QByteArray &content,
|
||||
const ColorReplacements *replacements,
|
||||
std::unique_ptr<rlottie::Animation> animation,
|
||||
std::unique_ptr<Cache> cache,
|
||||
const FrameRequest &request,
|
||||
@ -129,6 +130,7 @@ private:
|
||||
|
||||
std::unique_ptr<rlottie::Animation> _animation;
|
||||
const QByteArray _content;
|
||||
const ColorReplacements *_replacements = nullptr;
|
||||
|
||||
};
|
||||
|
||||
|
@ -15,8 +15,9 @@ SinglePlayer::SinglePlayer(
|
||||
const QByteArray &content,
|
||||
const FrameRequest &request,
|
||||
Quality quality,
|
||||
const ColorReplacements *replacements,
|
||||
std::shared_ptr<FrameRenderer> renderer)
|
||||
: _animation(this, content, request, quality)
|
||||
: _animation(this, content, request, quality, replacements)
|
||||
, _timer([=] { checkNextFrameRender(); })
|
||||
, _renderer(renderer ? renderer : FrameRenderer::Instance()) {
|
||||
}
|
||||
@ -27,8 +28,16 @@ SinglePlayer::SinglePlayer(
|
||||
const QByteArray &content,
|
||||
const FrameRequest &request,
|
||||
Quality quality,
|
||||
const ColorReplacements *replacements,
|
||||
std::shared_ptr<FrameRenderer> renderer)
|
||||
: _animation(this, std::move(get), std::move(put), content, request, quality)
|
||||
: _animation(
|
||||
this,
|
||||
std::move(get),
|
||||
std::move(put),
|
||||
content,
|
||||
request,
|
||||
quality,
|
||||
replacements)
|
||||
, _timer([=] { checkNextFrameRender(); })
|
||||
, _renderer(renderer ? renderer : FrameRenderer::Instance()) {
|
||||
}
|
||||
|
@ -32,6 +32,7 @@ public:
|
||||
const QByteArray &content,
|
||||
const FrameRequest &request,
|
||||
Quality quality = Quality::Default,
|
||||
const ColorReplacements *replacements = nullptr,
|
||||
std::shared_ptr<FrameRenderer> renderer = nullptr);
|
||||
SinglePlayer(
|
||||
FnMut<void(FnMut<void(QByteArray &&cached)>)> get, // Main thread.
|
||||
@ -39,6 +40,7 @@ public:
|
||||
const QByteArray &content,
|
||||
const FrameRequest &request,
|
||||
Quality quality = Quality::Default,
|
||||
const ColorReplacements *replacements = nullptr,
|
||||
std::shared_ptr<FrameRenderer> renderer = nullptr);
|
||||
~SinglePlayer();
|
||||
|
||||
|
2
Telegram/ThirdParty/rlottie
vendored
2
Telegram/ThirdParty/rlottie
vendored
@ -1 +1 @@
|
||||
Subproject commit bd9ee5239c8caca95fee017a46c8e9198d7cdb21
|
||||
Subproject commit d08a03b6508b390af20491f2dbeee3453594afc8
|
Loading…
Reference in New Issue
Block a user