diff --git a/Telegram/CMakeLists.txt b/Telegram/CMakeLists.txt index c1f0fbfc7..a855f2f6f 100644 --- a/Telegram/CMakeLists.txt +++ b/Telegram/CMakeLists.txt @@ -660,6 +660,9 @@ PRIVATE history/view/media/history_view_slot_machine.cpp history/view/media/history_view_sticker.h history/view/media/history_view_sticker.cpp + history/view/media/history_view_sticker_player.cpp + history/view/media/history_view_sticker_player.h + history/view/media/history_view_sticker_player_abstract.h history/view/media/history_view_theme_document.h history/view/media/history_view_theme_document.cpp history/view/media/history_view_web_page.h diff --git a/Telegram/SourceFiles/history/view/media/history_view_sticker.cpp b/Telegram/SourceFiles/history/view/media/history_view_sticker.cpp index 5f3837fd0..bd9768df6 100644 --- a/Telegram/SourceFiles/history/view/media/history_view_sticker.cpp +++ b/Telegram/SourceFiles/history/view/media/history_view_sticker.cpp @@ -14,6 +14,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "history/view/history_view_element.h" #include "history/view/history_view_cursor_state.h" #include "history/view/media/history_view_media_common.h" +#include "history/view/media/history_view_sticker_player.h" #include "ui/image/image.h" #include "ui/chat/chat_style.h" #include "ui/effects/path_shift_gradient.h" @@ -27,8 +28,6 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "data/data_document_media.h" #include "data/data_file_click_handler.h" #include "data/data_file_origin.h" -#include "lottie/lottie_single_player.h" -#include "media/clip/media_clip_reader.h" #include "chat_helpers/stickers_lottie.h" #include "styles/style_chat.h" @@ -40,8 +39,6 @@ constexpr auto kMaxEmojiSizeFixed = 256; constexpr auto kPremiumMultiplier = (1 + 0.245 * 2); constexpr auto kEmojiMultiplier = 3; -using ClipNotification = ::Media::Clip::Notification; - [[nodiscard]] QImage CacheDiceImage( const QString &emoji, int index, @@ -56,154 +53,6 @@ using ClipNotification = ::Media::Clip::Notification; return image; } -class LottiePlayer final : public StickerPlayer { -public: - explicit LottiePlayer(std::unique_ptr lottie); - - void setRepaintCallback(Fn callback) override; - bool ready() override; - int framesCount() override; - FrameInfo frame( - QSize size, - QColor colored, - bool mirrorHorizontal, - crl::time now, - bool paused) override; - bool markFrameShown() override; - -private: - std::unique_ptr _lottie; - rpl::lifetime _repaintLifetime; - -}; - -LottiePlayer::LottiePlayer(std::unique_ptr lottie) -: _lottie(std::move(lottie)) { -} - -void LottiePlayer::setRepaintCallback(Fn callback) { - _repaintLifetime = _lottie->updates( - ) | rpl::start_with_next([=](Lottie::Update update) { - v::match(update.data, [&](const Lottie::Information &information) { - callback(); - //markFramesTillExternal(); - }, [&](const Lottie::DisplayFrameRequest &request) { - callback(); - }); - }); -} - -bool LottiePlayer::ready() { - return _lottie->ready(); -} - -int LottiePlayer::framesCount() { - return _lottie->information().framesCount; -} - -LottiePlayer::FrameInfo LottiePlayer::frame( - QSize size, - QColor colored, - bool mirrorHorizontal, - crl::time now, - bool paused) { - auto request = Lottie::FrameRequest(); - request.box = size * style::DevicePixelRatio(); - request.colored = colored; - request.mirrorHorizontal = mirrorHorizontal; - const auto info = _lottie->frameInfo(request); - return { .image = info.image, .index = info.index }; -} - -bool LottiePlayer::markFrameShown() { - return _lottie->markFrameShown(); -} - -class WebmPlayer final : public StickerPlayer { -public: - WebmPlayer( - const Core::FileLocation &location, - const QByteArray &data, - QSize size); - - void setRepaintCallback(Fn callback) override; - bool ready() override; - int framesCount() override; - FrameInfo frame( - QSize size, - QColor colored, - bool mirrorHorizontal, - crl::time now, - bool paused) override; - bool markFrameShown() override; - -private: - void clipCallback(ClipNotification notification); - - ::Media::Clip::ReaderPointer _reader; - Fn _repaintCallback; - QSize _size; - -}; - -WebmPlayer::WebmPlayer( - const Core::FileLocation &location, - const QByteArray &data, - QSize size) -: _reader( - ::Media::Clip::MakeReader(location, data, [=](ClipNotification update) { - clipCallback(update); -})) -, _size(size) { -} - -void WebmPlayer::clipCallback(ClipNotification notification) { - switch (notification) { - case ClipNotification::Reinit: { - if (_reader->state() == ::Media::Clip::State::Error) { - _reader.setBad(); - } else if (_reader->ready() && !_reader->started()) { - _reader->start({ .frame = _size, .keepAlpha = true }); - } - } break; - - case ClipNotification::Repaint: break; - } - - _repaintCallback(); -} - -void WebmPlayer::setRepaintCallback(Fn callback) { - _repaintCallback = std::move(callback); -} - -bool WebmPlayer::ready() { - return _reader && _reader->started(); -} - -int WebmPlayer::framesCount() { - return -1; -} - -WebmPlayer::FrameInfo WebmPlayer::frame( - QSize size, - QColor colored, - bool mirrorHorizontal, - crl::time now, - bool paused) { - auto request = ::Media::Clip::FrameRequest(); - request.frame = size; - request.factor = style::DevicePixelRatio(); - request.keepAlpha = true; - request.colored = colored; - const auto info = _reader->frameInfo(request, paused ? 0 : now); - return { .image = info.image, .index = info.index }; -} - -bool WebmPlayer::markFrameShown() { - return _reader->moveToNextFrame(); -} - } // namespace Sticker::Sticker( diff --git a/Telegram/SourceFiles/history/view/media/history_view_sticker.h b/Telegram/SourceFiles/history/view/media/history_view_sticker.h index 351ff5d07..7faf3bfa8 100644 --- a/Telegram/SourceFiles/history/view/media/history_view_sticker.h +++ b/Telegram/SourceFiles/history/view/media/history_view_sticker.h @@ -8,6 +8,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #pragma once #include "history/view/media/history_view_media_unwrapped.h" +#include "history/view/media/history_view_sticker_player_abstract.h" #include "base/weak_ptr.h" namespace Main { @@ -20,7 +21,6 @@ class DocumentMedia; } // namespace Data namespace Lottie { -class SinglePlayer; struct ColorReplacements; } // namespace Lottie @@ -30,26 +30,6 @@ enum class StickerLottieSize : uint8; namespace HistoryView { -class StickerPlayer { -public: - virtual ~StickerPlayer() = default; - - struct FrameInfo { - QImage image; - int index = 0; - }; - virtual void setRepaintCallback(Fn callback) = 0; - [[nodiscard]] virtual bool ready() = 0; - [[nodiscard]] virtual int framesCount() = 0; - [[nodiscard]] virtual FrameInfo frame( - QSize size, - QColor colored, - bool mirrorHorizontal, - crl::time now, - bool paused) = 0; - virtual bool markFrameShown() = 0; -}; - class Sticker final : public UnwrappedMedia::Content , public base::has_weak_ptr { diff --git a/Telegram/SourceFiles/history/view/media/history_view_sticker_player.cpp b/Telegram/SourceFiles/history/view/media/history_view_sticker_player.cpp new file mode 100644 index 000000000..f82565ec4 --- /dev/null +++ b/Telegram/SourceFiles/history/view/media/history_view_sticker_player.cpp @@ -0,0 +1,117 @@ +/* +This file is part of Telegram Desktop, +the official desktop application for the Telegram messaging service. + +For license and copyright information please follow this link: +https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL +*/ +#include "history/view/media/history_view_sticker_player.h" + +namespace HistoryView { +namespace { + +using ClipNotification = ::Media::Clip::Notification; + +} // namespace + +LottiePlayer::LottiePlayer(std::unique_ptr lottie) +: _lottie(std::move(lottie)) { +} + +void LottiePlayer::setRepaintCallback(Fn callback) { + _repaintLifetime = _lottie->updates( + ) | rpl::start_with_next([=](Lottie::Update update) { + v::match(update.data, [&](const Lottie::Information &) { + callback(); + //markFramesTillExternal(); + }, [&](const Lottie::DisplayFrameRequest &) { + callback(); + }); + }); +} + +bool LottiePlayer::ready() { + return _lottie->ready(); +} + +int LottiePlayer::framesCount() { + return _lottie->information().framesCount; +} + +LottiePlayer::FrameInfo LottiePlayer::frame( + QSize size, + QColor colored, + bool mirrorHorizontal, + crl::time now, + bool paused) { + auto request = Lottie::FrameRequest(); + request.box = size * style::DevicePixelRatio(); + request.colored = colored; + request.mirrorHorizontal = mirrorHorizontal; + const auto info = _lottie->frameInfo(request); + return { .image = info.image, .index = info.index }; +} + +bool LottiePlayer::markFrameShown() { + return _lottie->markFrameShown(); +} + +WebmPlayer::WebmPlayer( + const Core::FileLocation &location, + const QByteArray &data, + QSize size) +: _reader( + ::Media::Clip::MakeReader(location, data, [=](ClipNotification update) { + clipCallback(update); +})) +, _size(size) { +} + +void WebmPlayer::clipCallback(ClipNotification notification) { + switch (notification) { + case ClipNotification::Reinit: { + if (_reader->state() == ::Media::Clip::State::Error) { + _reader.setBad(); + } else if (_reader->ready() && !_reader->started()) { + _reader->start({ .frame = _size, .keepAlpha = true }); + } + } break; + + case ClipNotification::Repaint: break; + } + + _repaintCallback(); +} + +void WebmPlayer::setRepaintCallback(Fn callback) { + _repaintCallback = std::move(callback); +} + +bool WebmPlayer::ready() { + return _reader && _reader->started(); +} + +int WebmPlayer::framesCount() { + return -1; +} + +WebmPlayer::FrameInfo WebmPlayer::frame( + QSize size, + QColor colored, + bool mirrorHorizontal, + crl::time now, + bool paused) { + auto request = ::Media::Clip::FrameRequest(); + request.frame = size; + request.factor = style::DevicePixelRatio(); + request.keepAlpha = true; + request.colored = colored; + const auto info = _reader->frameInfo(request, paused ? 0 : now); + return { .image = info.image, .index = info.index }; +} + +bool WebmPlayer::markFrameShown() { + return _reader->moveToNextFrame(); +} + +} // namespace HistoryView diff --git a/Telegram/SourceFiles/history/view/media/history_view_sticker_player.h b/Telegram/SourceFiles/history/view/media/history_view_sticker_player.h new file mode 100644 index 000000000..176a84f35 --- /dev/null +++ b/Telegram/SourceFiles/history/view/media/history_view_sticker_player.h @@ -0,0 +1,69 @@ +/* +This file is part of Telegram Desktop, +the official desktop application for the Telegram messaging service. + +For license and copyright information please follow this link: +https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL +*/ +#pragma once + +#include "history/view/media/history_view_sticker_player_abstract.h" + +#include "lottie/lottie_single_player.h" +#include "media/clip/media_clip_reader.h" + +namespace Core { +class FileLocation; +} // namespace Core + +namespace HistoryView { + +class LottiePlayer final : public StickerPlayer { +public: + explicit LottiePlayer(std::unique_ptr lottie); + + void setRepaintCallback(Fn callback) override; + bool ready() override; + int framesCount() override; + FrameInfo frame( + QSize size, + QColor colored, + bool mirrorHorizontal, + crl::time now, + bool paused) override; + bool markFrameShown() override; + +private: + std::unique_ptr _lottie; + rpl::lifetime _repaintLifetime; + +}; + +class WebmPlayer final : public StickerPlayer { +public: + WebmPlayer( + const Core::FileLocation &location, + const QByteArray &data, + QSize size); + + void setRepaintCallback(Fn callback) override; + bool ready() override; + int framesCount() override; + FrameInfo frame( + QSize size, + QColor colored, + bool mirrorHorizontal, + crl::time now, + bool paused) override; + bool markFrameShown() override; + +private: + void clipCallback(::Media::Clip::Notification notification); + + ::Media::Clip::ReaderPointer _reader; + Fn _repaintCallback; + QSize _size; + +}; + +} // namespace HistoryView diff --git a/Telegram/SourceFiles/history/view/media/history_view_sticker_player_abstract.h b/Telegram/SourceFiles/history/view/media/history_view_sticker_player_abstract.h new file mode 100644 index 000000000..491c655f8 --- /dev/null +++ b/Telegram/SourceFiles/history/view/media/history_view_sticker_player_abstract.h @@ -0,0 +1,33 @@ +/* +This file is part of Telegram Desktop, +the official desktop application for the Telegram messaging service. + +For license and copyright information please follow this link: +https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL +*/ +#pragma once + +namespace HistoryView { + +class StickerPlayer { +public: + virtual ~StickerPlayer() = default; + + struct FrameInfo { + QImage image; + int index = 0; + }; + virtual void setRepaintCallback(Fn callback) = 0; + [[nodiscard]] virtual bool ready() = 0; + [[nodiscard]] virtual int framesCount() = 0; + [[nodiscard]] virtual FrameInfo frame( + QSize size, + QColor colored, + bool mirrorHorizontal, + crl::time now, + bool paused) = 0; + virtual bool markFrameShown() = 0; + +}; + +} // namespace HistoryView