diff --git a/CMakeLists.txt b/CMakeLists.txt index 36a2548..13b7a19 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -47,6 +47,7 @@ PRIVATE ui/effects/cross_line.h ui/effects/fade_animation.cpp ui/effects/fade_animation.h + ui/effects/frame_generator.cpp ui/effects/frame_generator.h ui/effects/gradient.cpp ui/effects/gradient.h diff --git a/ui/effects/frame_generator.cpp b/ui/effects/frame_generator.cpp new file mode 100644 index 0000000..329bad0 --- /dev/null +++ b/ui/effects/frame_generator.cpp @@ -0,0 +1,58 @@ +// 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 "ui/effects/frame_generator.h" + +#include "ui/image/image_prepare.h" + +namespace Ui { + +ImageFrameGenerator::ImageFrameGenerator(const QByteArray &bytes) +: _bytes(bytes) { +} + +int ImageFrameGenerator::count() { + return 1; +} + +FrameGenerator::Frame ImageFrameGenerator::renderNext( + QImage storage, + QSize size, + Qt::AspectRatioMode mode) { + storage = Images::Read({ + .content = _bytes, + }).image; + if (storage.isNull()) { + return {}; + } + auto scaled = storage.scaled( + size, + mode, + Qt::SmoothTransformation + ).convertToFormat(QImage::Format_ARGB32_Premultiplied); + if (scaled.size() == size) { + return { .image = std::move(scaled) }; + } + auto result = QImage(size, QImage::Format_ARGB32_Premultiplied); + result.fill(Qt::transparent); + + const auto skipx = (size.width() - scaled.width()) / 2; + const auto skipy = (size.height() - scaled.height()) / 2; + const auto fromPerLine = scaled.bytesPerLine(); + const auto toPerLine = result.bytesPerLine(); + const auto lineBytes = scaled.width() * 4; + auto from = scaled.constBits(); + auto to = result.bits() + (skipx * 4) + (skipy * fromPerLine); + for (auto y = 0, height = scaled.height(); y != height; ++y) { + memcpy(to, from, lineBytes); + from += fromPerLine; + to += toPerLine; + } + + return { .image = std::move(result) }; +} + +} // namespace Ui diff --git a/ui/effects/frame_generator.h b/ui/effects/frame_generator.h index 0cc300e..9aec154 100644 --- a/ui/effects/frame_generator.h +++ b/ui/effects/frame_generator.h @@ -26,4 +26,19 @@ public: Qt::AspectRatioMode mode = Qt::IgnoreAspectRatio) = 0; }; +class ImageFrameGenerator final : public Ui::FrameGenerator { +public: + explicit ImageFrameGenerator(const QByteArray &bytes); + + int count() override; + Frame renderNext( + QImage storage, + QSize size, + Qt::AspectRatioMode mode = Qt::IgnoreAspectRatio) override; + +private: + QByteArray _bytes; + +}; + } // namespace Ui