/* 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 "ui/text/text_lottie_custom_emoji.h" #include "lottie/lottie_icon.h" #include "ui/text/text_utilities.h" namespace Ui::Text { LottieCustomEmoji::LottieCustomEmoji(Lottie::IconDescriptor &&descriptor) : LottieCustomEmoji(std::move(descriptor), nullptr) { } LottieCustomEmoji::LottieCustomEmoji( Lottie::IconDescriptor &&descriptor, Fn repaint) : _entityData(!descriptor.name.isEmpty() ? descriptor.name : !descriptor.path.isEmpty() ? descriptor.path : (Unexpected("LottieCustomEmoji: descriptor.name or descriptor.path"), QString())) , _width(descriptor.sizeOverride.width()) , _icon(Lottie::MakeIcon(std::move(descriptor))) , _repaint(std::move(repaint)) { if (!_width && _icon && _icon->valid()) { _width = _icon->width(); startAnimation(); } } int LottieCustomEmoji::width() { return _width; } QString LottieCustomEmoji::entityData() { return _entityData; } void LottieCustomEmoji::paint(QPainter &p, const Context &context) { if (!_icon || !_icon->valid()) { return; } const auto paused = context.paused || context.internal.forceFirstFrame || context.internal.overrideFirstWithLastFrame; if (paused) { const auto frame = context.internal.forceLastFrame ? _icon->framesCount() - 1 : 0; _icon->jumpTo(frame, _repaint); } else if (!_icon->animating()) { startAnimation(); } _icon->paint( p, context.position.x(), context.position.y(), context.textColor); } void LottieCustomEmoji::unload() { if (_icon) { _icon->jumpTo(0, nullptr); } } bool LottieCustomEmoji::ready() { return _icon && _icon->valid(); } bool LottieCustomEmoji::readyInDefaultState() { return _icon && _icon->valid() && _icon->frameIndex() == 0; } void LottieCustomEmoji::startAnimation() { if (!_icon || !_icon->valid() || _icon->framesCount() <= 1) { return; } _icon->animate( _repaint, 0, _icon->framesCount() - 1); } QString LottieEmojiData(Lottie::IconDescriptor descriptor) { return !descriptor.name.isEmpty() ? descriptor.name : !descriptor.path.isEmpty() ? descriptor.path : QString(); } TextWithEntities LottieEmoji(Lottie::IconDescriptor descriptor) { return SingleCustomEmoji(LottieEmojiData(std::move(descriptor))); } MarkedContext LottieEmojiContext(Lottie::IconDescriptor descriptor) { auto customEmojiFactory = [descriptor = std::move(descriptor)]( QStringView data, const MarkedContext &context ) mutable -> std::unique_ptr { if (data == LottieEmojiData(descriptor)) { return std::make_unique( std::move(descriptor), context.repaint); } return nullptr; }; return { .customEmojiFactory = std::move(customEmojiFactory) }; } } // namespace Ui::Text