From 561a6d89356cb76fdc8d9232c401201255173487 Mon Sep 17 00:00:00 2001 From: Hermet Park Date: Mon, 13 Nov 2023 19:10:20 +0900 Subject: [PATCH] savers: provides a background setting. Allow users to set a custom background with a saver. API: - Result Saver::background(std::unique_ptr paint); --- inc/thorvg.h | 9 +++++++++ src/renderer/tvgSaveModule.h | 4 ++-- src/renderer/tvgSaver.cpp | 20 ++++++++++++++++---- src/savers/gif/tvgGifSaver.cpp | 18 +++++++++--------- src/savers/gif/tvgGifSaver.h | 5 +++-- src/savers/tvg/tvgTvgSaver.cpp | 28 +++++++++++++++++----------- src/savers/tvg/tvgTvgSaver.h | 5 +++-- 7 files changed, 59 insertions(+), 30 deletions(-) diff --git a/inc/thorvg.h b/inc/thorvg.h index 14f97816..1d780649 100644 --- a/inc/thorvg.h +++ b/inc/thorvg.h @@ -1751,6 +1751,15 @@ class TVG_API Saver final public: ~Saver(); + /** + * @brief Sets the base background content for the saved image. + * + * @param[in] paint The paint to be drawn as the background image for the saving paint. + * + * @note Experimental API + */ + Result background(std::unique_ptr paint) noexcept; + /** * @brief Exports the given @p paint data to the given @p path * diff --git a/src/renderer/tvgSaveModule.h b/src/renderer/tvgSaveModule.h index e85a37c6..86d8dd33 100644 --- a/src/renderer/tvgSaveModule.h +++ b/src/renderer/tvgSaveModule.h @@ -33,8 +33,8 @@ class SaveModule public: virtual ~SaveModule() {} - virtual bool save(Paint* paint, const string& path, uint32_t quality) = 0; - virtual bool save(Animation* animation, const string& path, uint32_t quality, uint32_t fps) = 0; + virtual bool save(Paint* paint, Paint* bg, const string& path, uint32_t quality) = 0; + virtual bool save(Animation* animation, Paint* bg, const string& path, uint32_t quality, uint32_t fps) = 0; virtual bool close() = 0; }; diff --git a/src/renderer/tvgSaver.cpp b/src/renderer/tvgSaver.cpp index 04306308..fe5bcc4e 100644 --- a/src/renderer/tvgSaver.cpp +++ b/src/renderer/tvgSaver.cpp @@ -37,9 +37,12 @@ struct Saver::Impl { SaveModule* saveModule = nullptr; + Paint* bg = nullptr; + ~Impl() { delete(saveModule); + delete(bg); } }; @@ -113,7 +116,7 @@ Saver::~Saver() } -Result Saver::save(std::unique_ptr paint, const string& path, uint32_t quality) noexcept +Result Saver::save(unique_ptr paint, const string& path, uint32_t quality) noexcept { auto p = paint.release(); if (!p) return Result::MemoryCorruption; @@ -125,7 +128,7 @@ Result Saver::save(std::unique_ptr paint, const string& path, uint32_t qu } if (auto saveModule = _find(path)) { - if (saveModule->save(p, path, quality)) { + if (saveModule->save(p, pImpl->bg, path, quality)) { pImpl->saveModule = saveModule; return Result::Success; } else { @@ -139,7 +142,16 @@ Result Saver::save(std::unique_ptr paint, const string& path, uint32_t qu } -Result Saver::save(std::unique_ptr animation, const string& path, uint32_t quality, uint32_t fps) noexcept +Result Saver::background(unique_ptr paint) noexcept +{ + delete(pImpl->bg); + pImpl->bg = paint.release(); + + return Result::Success; +} + + +Result Saver::save(unique_ptr animation, const string& path, uint32_t quality, uint32_t fps) noexcept { auto a = animation.release(); if (!a) return Result::MemoryCorruption; @@ -156,7 +168,7 @@ Result Saver::save(std::unique_ptr animation, const string& path, uin } if (auto saveModule = _find(path)) { - if (saveModule->save(a, path, quality, fps)) { + if (saveModule->save(a, pImpl->bg, path, quality, fps)) { pImpl->saveModule = saveModule; return Result::Success; } else { diff --git a/src/savers/gif/tvgGifSaver.cpp b/src/savers/gif/tvgGifSaver.cpp index dd81bc76..84a53804 100644 --- a/src/savers/gif/tvgGifSaver.cpp +++ b/src/savers/gif/tvgGifSaver.cpp @@ -42,13 +42,7 @@ void GifSaver::run(unsigned tid) buffer = (uint32_t*)realloc(buffer, sizeof(uint32_t) * w * h); canvas->target(buffer, w, w, h, tvg::SwCanvas::ABGR8888); - - //base white background - auto bg = Shape::gen(); - bg->appendRect(0, 0, vsize[0], vsize[1]); - bg->fill(255, 255, 255); - canvas->push(std::move(bg)); - + canvas->push(cast(bg)); canvas->push(cast(animation->picture())); //use the default fps @@ -81,6 +75,8 @@ void GifSaver::run(unsigned tid) } if (!GifEnd(&writer)) TVGERR("GIF_SAVER", "Failed gif encoding"); + + this->bg = nullptr; } @@ -98,6 +94,9 @@ bool GifSaver::close() { this->done(); + delete(bg); + bg = nullptr; + delete(animation); animation = nullptr; @@ -111,14 +110,14 @@ bool GifSaver::close() } -bool GifSaver::save(TVG_UNUSED Paint* paint, TVG_UNUSED const string& path, TVG_UNUSED uint32_t quality) +bool GifSaver::save(TVG_UNUSED Paint* paint, TVG_UNUSED Paint* bg, TVG_UNUSED const string& path, TVG_UNUSED uint32_t quality) { TVGLOG("GIF_SAVER", "Paint is not supported."); return false; } -bool GifSaver::save(Animation* animation, const string& path, TVG_UNUSED uint32_t quality, uint32_t fps) +bool GifSaver::save(Animation* animation, Paint* bg, const string& path, TVG_UNUSED uint32_t quality, uint32_t fps) { close(); @@ -140,6 +139,7 @@ bool GifSaver::save(Animation* animation, const string& path, TVG_UNUSED uint32_ if (!this->path) return false; this->animation = animation; + if (bg) this->bg = bg->duplicate(); this->fps = static_cast(fps); TaskScheduler::request(this); diff --git a/src/savers/gif/tvgGifSaver.h b/src/savers/gif/tvgGifSaver.h index d20a7617..bd73ebe6 100644 --- a/src/savers/gif/tvgGifSaver.h +++ b/src/savers/gif/tvgGifSaver.h @@ -34,6 +34,7 @@ class GifSaver : public SaveModule, public Task private: uint32_t* buffer = nullptr; Animation* animation = nullptr; + Paint* bg = nullptr; char *path = nullptr; float vsize[2] = {0.0f, 0.0f}; float fps = 0.0f; @@ -43,8 +44,8 @@ private: public: ~GifSaver(); - bool save(Paint* paint, const string& path, uint32_t quality) override; - bool save(Animation* animation, const string& path, uint32_t quality, uint32_t fps) override; + bool save(Paint* paint, Paint* bg, const string& path, uint32_t quality) override; + bool save(Animation* animation, Paint* bg, const string& path, uint32_t quality, uint32_t fps) override; bool close() override; }; diff --git a/src/savers/tvg/tvgTvgSaver.cpp b/src/savers/tvg/tvgTvgSaver.cpp index a49a5a74..682ae28b 100644 --- a/src/savers/tvg/tvgTvgSaver.cpp +++ b/src/savers/tvg/tvgTvgSaver.cpp @@ -772,20 +772,19 @@ bool TvgSaver::close() { this->done(); - if (paint) { - delete(paint); - paint = nullptr; - } - if (path) { - free(path); - path = nullptr; - } + delete(paint); + paint = nullptr; + + free(path); + path = nullptr; + buffer.reset(); + return true; } -bool TvgSaver::save(Paint* paint, const string& path, TVG_UNUSED uint32_t quality) +bool TvgSaver::save(Paint* paint, Paint* bg, const string& path, TVG_UNUSED uint32_t quality) { close(); @@ -805,7 +804,14 @@ bool TvgSaver::save(Paint* paint, const string& path, TVG_UNUSED uint32_t qualit this->path = strdup(path.c_str()); if (!this->path) return false; - this->paint = paint; + if (bg) { + auto scene = Scene::gen(); + scene->push(cast(bg->duplicate())); + scene->push(cast(paint)); + this->paint = scene.release(); + } else { + this->paint = paint; + } TaskScheduler::request(this); @@ -813,7 +819,7 @@ bool TvgSaver::save(Paint* paint, const string& path, TVG_UNUSED uint32_t qualit } -bool TvgSaver::save(TVG_UNUSED Animation* animation, TVG_UNUSED const string& path, TVG_UNUSED uint32_t quality, TVG_UNUSED uint32_t fps) +bool TvgSaver::save(TVG_UNUSED Animation* animation, TVG_UNUSED Paint* bg, TVG_UNUSED const string& path, TVG_UNUSED uint32_t quality, TVG_UNUSED uint32_t fps) { TVGLOG("TVG_SAVER", "Animation is not supported."); return false; diff --git a/src/savers/tvg/tvgTvgSaver.h b/src/savers/tvg/tvgTvgSaver.h index 659b31f0..6d21b4d6 100644 --- a/src/savers/tvg/tvgTvgSaver.h +++ b/src/savers/tvg/tvgTvgSaver.h @@ -35,6 +35,7 @@ class TvgSaver : public SaveModule, public Task private: Array buffer; Paint* paint = nullptr; + Paint* bg = nullptr; char *path = nullptr; uint32_t headerSize; float vsize[2] = {0.0f, 0.0f}; @@ -69,8 +70,8 @@ private: public: ~TvgSaver(); - bool save(Paint* paint, const string& path, uint32_t quality) override; - bool save(Animation* animation, const string& path, uint32_t quality, uint32_t fps) override; + bool save(Paint* paint, Paint* bg, const string& path, uint32_t quality) override; + bool save(Animation* animation, Paint* bg, const string& path, uint32_t quality, uint32_t fps) override; bool close() override; };