| 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798 |
- // This file is part of Desktop App Toolkit,
- // a set of libraries for developing nice desktop applications.
- //
- // For license and copyright information please follow this link:
- // https://github.com/desktop-app/legal/blob/master/LEGAL
- //
- #include "lottie/lottie_frame_generator.h"
- #include "lottie/lottie_common.h"
- #include "ui/image/image_prepare.h"
- #include <rlottie.h>
- namespace Lottie {
- FrameGenerator::FrameGenerator(const QByteArray &bytes)
- : _rlottie(
- rlottie::Animation::loadFromData(
- ReadUtf8(Images::UnpackGzip(bytes)),
- std::string(),
- std::string(),
- false)) {
- if (_rlottie) {
- const auto rate = _rlottie->frameRate();
- _multiplier = (rate == 60) ? 2 : 1;
- auto width = size_t();
- auto height = size_t();
- _rlottie->size(width, height);
- _size = QSize(width, height);
- _framesCount = (_rlottie->totalFrame() + _multiplier - 1)
- / _multiplier;
- _frameDuration = (rate > 0) ? (1000 * _multiplier / rate) : 0;
- }
- if (!_framesCount || !_frameDuration || _size.isEmpty()) {
- _rlottie = nullptr;
- _framesCount = _frameDuration = 0;
- _size = QSize();
- }
- }
- FrameGenerator::~FrameGenerator() = default;
- int FrameGenerator::count() {
- return _framesCount;
- }
- double FrameGenerator::rate() {
- return _rlottie ? (_rlottie->frameRate() / _multiplier) : 0.;
- }
- FrameGenerator::Frame FrameGenerator::renderNext(
- QImage storage,
- QSize size,
- Qt::AspectRatioMode mode) {
- if (!_framesCount || _frameIndex == _framesCount) {
- return {};
- }
- ++_frameIndex;
- return renderCurrent(std::move(storage), size, mode);
- }
- FrameGenerator::Frame FrameGenerator::renderCurrent(
- QImage storage,
- QSize size,
- Qt::AspectRatioMode mode) {
- Expects(_frameIndex > 0);
- const auto index = _frameIndex - 1;
- if (storage.format() != kImageFormat
- || storage.size() != size) {
- storage = CreateFrameStorage(size);
- }
- storage.fill(Qt::transparent);
- const auto scaled = _size.scaled(size, mode);
- const auto render = QSize(
- std::max(scaled.width(), size.width()),
- std::max(scaled.height(), size.height()));
- const auto xskip = (size.width() - render.width()) / 2;
- const auto yskip = (size.height() - render.height());
- const auto skip = (yskip * storage.bytesPerLine() / 4) + xskip;
- auto surface = rlottie::Surface(
- reinterpret_cast<uint32_t*>(storage.bits()) + skip,
- render.width(),
- render.height(),
- storage.bytesPerLine());
- _rlottie->renderSync(index * _multiplier, std::move(surface));
- return {
- .duration = _frameDuration,
- .image = std::move(storage),
- .last = (_frameIndex == _framesCount),
- };
- }
- void FrameGenerator::jumpToStart() {
- _frameIndex = 0;
- }
- } // namespace Lottie
|