From d213a6718022ee4faaf4f03ab9a3d5057ac1f11d Mon Sep 17 00:00:00 2001 From: Hermet Park Date: Wed, 28 Jul 2021 14:06:55 +0900 Subject: [PATCH] common loader: code refactoring Bitmap based pictures doesn't need the viewbox, LoaderModule should delegate the viewbox to the derived classes which having vector-based image loaders such as svg, tvg. In that case, paint resizing can be performed by the loaders by own policy. --- src/lib/tvgLoadModule.h | 10 ++++---- src/lib/tvgPictureImpl.h | 41 +++++++------------------------- src/loaders/jpg/tvgJpgLoader.cpp | 8 +++---- src/loaders/png/tvgPngLoader.cpp | 8 +++---- src/loaders/raw/tvgRawLoader.cpp | 8 +++---- src/loaders/svg/tvgSvgLoader.cpp | 35 +++++++++++++++++++++++++++ src/loaders/svg/tvgSvgLoader.h | 14 +++++++---- src/loaders/tvg/tvgTvgLoader.cpp | 28 ++++++++++++++++++++++ src/loaders/tvg/tvgTvgLoader.h | 6 ++--- 9 files changed, 99 insertions(+), 59 deletions(-) diff --git a/src/lib/tvgLoadModule.h b/src/lib/tvgLoadModule.h index 6d214dc8..1025b739 100644 --- a/src/lib/tvgLoadModule.h +++ b/src/lib/tvgLoadModule.h @@ -30,19 +30,17 @@ namespace tvg class LoadModule { public: - //default view box, if any. - float vx = 0; - float vy = 0; - float vw = 0; - float vh = 0; float w = 0, h = 0; //default image size - bool preserveAspect = true; //keep aspect ratio by default. virtual ~LoadModule() {} virtual bool open(const string& path) { return false; }; virtual bool open(const char* data, uint32_t size, bool copy) { return false; }; virtual bool open(const uint32_t* data, uint32_t w, uint32_t h, bool copy) { return false; }; + + //Override this if the vector-format has own resizing policy. + virtual bool resize(Paint* paint, float w, float h) { return false; }; + virtual bool read() = 0; virtual bool close() = 0; virtual const uint32_t* pixels() { return nullptr; }; diff --git a/src/lib/tvgPictureImpl.h b/src/lib/tvgPictureImpl.h index 0a56798a..88f93402 100644 --- a/src/lib/tvgPictureImpl.h +++ b/src/lib/tvgPictureImpl.h @@ -76,37 +76,6 @@ struct Picture::Impl return ret; } - void resize() - { - auto sx = w / loader->vw; - auto sy = h / loader->vh; - - if (loader->preserveAspect) { - //Scale - auto scale = sx < sy ? sx : sy; - paint->scale(scale); - //Align - auto vx = loader->vx * scale; - auto vy = loader->vy * scale; - auto vw = loader->vw * scale; - auto vh = loader->vh * scale; - if (vw > vh) vy -= (h - vh) * 0.5f; - else vx -= (w - vw) * 0.5f; - paint->translate(-vx, -vy); - } else { - //Align - auto vx = loader->vx * sx; - auto vy = loader->vy * sy; - auto vw = loader->vw * sx; - auto vh = loader->vh * sy; - if (vw > vh) vy -= (h - vh) * 0.5f; - else vx -= (w - vw) * 0.5f; - - Matrix m = {sx, 0, -vx, 0, sy, -vy, 0, 0, 1}; - paint->transform(m); - } - resizing = false; - } uint32_t reload() { @@ -115,7 +84,10 @@ struct Picture::Impl if (auto p = loader->paint()) { paint = p.release(); loader->close(); - if (w != loader->w && h != loader->h) resize(); + if (w != loader->w && h != loader->h) { + loader->resize(paint, w, h); + resizing = false; + } if (paint) return RenderUpdateFlag::None; } } @@ -134,7 +106,10 @@ struct Picture::Impl if (pixels) rdata = renderer.prepare(*picture, rdata, transform, opacity, clips, static_cast(pFlag | flag)); else if (paint) { - if (resizing) resize(); + if (resizing) { + loader->resize(paint, w, h); + resizing = false; + } rdata = paint->pImpl->update(renderer, transform, opacity, clips, static_cast(pFlag | flag)); } return rdata; diff --git a/src/loaders/jpg/tvgJpgLoader.cpp b/src/loaders/jpg/tvgJpgLoader.cpp index 03efad2b..f08e0632 100644 --- a/src/loaders/jpg/tvgJpgLoader.cpp +++ b/src/loaders/jpg/tvgJpgLoader.cpp @@ -79,8 +79,8 @@ bool JpgLoader::open(const string& path) int width, height, subSample, colorSpace; if (tjDecompressHeader3(jpegDecompressor, data, size, &width, &height, &subSample, &colorSpace) < 0) goto failure; - vw = w = static_cast(width); - vh = h = static_cast(height); + w = static_cast(width); + h = static_cast(height); ret = true; freeData = true; @@ -111,8 +111,8 @@ bool JpgLoader::open(const char* data, uint32_t size, bool copy) this->data = (unsigned char *) data; } - vw = w = static_cast(width); - vh = h = static_cast(height); + w = static_cast(width); + h = static_cast(height); this->size = size; return true; diff --git a/src/loaders/png/tvgPngLoader.cpp b/src/loaders/png/tvgPngLoader.cpp index 56771297..15ccfaa3 100755 --- a/src/loaders/png/tvgPngLoader.cpp +++ b/src/loaders/png/tvgPngLoader.cpp @@ -45,8 +45,8 @@ bool PngLoader::open(const string& path) if (!png_image_begin_read_from_file(image, path.c_str())) return false; - vw = w = image->width; - vh = h = image->height; + w = image->width; + h = image->height; return true; } @@ -57,8 +57,8 @@ bool PngLoader::open(const char* data, uint32_t size, bool copy) if (!png_image_begin_read_from_memory(image, data, size)) return false; - vw = w = image->width; - vh = h = image->height; + w = image->width; + h = image->height; return true; } diff --git a/src/loaders/raw/tvgRawLoader.cpp b/src/loaders/raw/tvgRawLoader.cpp index b358fe88..41c74302 100644 --- a/src/loaders/raw/tvgRawLoader.cpp +++ b/src/loaders/raw/tvgRawLoader.cpp @@ -45,14 +45,14 @@ bool RawLoader::open(const uint32_t* data, uint32_t w, uint32_t h, bool copy) { if (!data || w == 0 || h == 0) return false; - this->w = vw = w; - this->h = vh = h; + this->w = w; + this->h = h; this->copy = copy; if (copy) { - content = (uint32_t*)malloc(sizeof(uint32_t) * vw * vh); + content = (uint32_t*)malloc(sizeof(uint32_t) * w * h); if (!content) return false; - memcpy((void*)content, data, sizeof(uint32_t) * vw * vh); + memcpy((void*)content, data, sizeof(uint32_t) * w * h); } else content = data; diff --git a/src/loaders/svg/tvgSvgLoader.cpp b/src/loaders/svg/tvgSvgLoader.cpp index 3dd80880..550ad5b8 100644 --- a/src/loaders/svg/tvgSvgLoader.cpp +++ b/src/loaders/svg/tvgSvgLoader.cpp @@ -2850,6 +2850,41 @@ bool SvgLoader::open(const string& path) } +bool SvgLoader::resize(Paint* paint, float w, float h) +{ + if (!paint) return false; + + auto sx = w / vw; + auto sy = h / vh; + + if (preserveAspect) { + //Scale + auto scale = sx < sy ? sx : sy; + paint->scale(scale); + //Align + auto vx = this->vx * scale; + auto vy = this->vy * scale; + auto vw = this->vw * scale; + auto vh = this->vh * scale; + if (vw > vh) vy -= (h - vh) * 0.5f; + else vx -= (w - vw) * 0.5f; + paint->translate(-vx, -vy); + } else { + //Align + auto vx = this->vx * sx; + auto vy = this->vy * sy; + auto vw = this->vw * sx; + auto vh = this->vh * sy; + if (vw > vh) vy -= (h - vh) * 0.5f; + else vx -= (w - vw) * 0.5f; + + Matrix m = {sx, 0, -vx, 0, sy, -vy, 0, 0, 1}; + paint->transform(m); + } + return true; +} + + bool SvgLoader::read() { if (!content || size == 0) return false; diff --git a/src/loaders/svg/tvgSvgLoader.h b/src/loaders/svg/tvgSvgLoader.h index 46af6a82..556a92c3 100644 --- a/src/loaders/svg/tvgSvgLoader.h +++ b/src/loaders/svg/tvgSvgLoader.h @@ -35,7 +35,14 @@ public: SvgLoaderData loaderData; unique_ptr root; + //default view box, if any. + float vx = 0; + float vy = 0; + float vw = 0; + float vh = 0; + bool copy = false; + bool preserveAspect = true; //aspect ratio option SvgLoader(); ~SvgLoader(); @@ -43,16 +50,15 @@ public: using LoadModule::open; bool open(const string& path) override; bool open(const char* data, uint32_t size, bool copy) override; - - bool header(); + bool resize(Paint* paint, float w, float h) override; bool read() override; bool close() override; - void run(unsigned tid) override; - unique_ptr paint() override; private: + bool header(); void clear(); + void run(unsigned tid) override; }; diff --git a/src/loaders/tvg/tvgTvgLoader.cpp b/src/loaders/tvg/tvgTvgLoader.cpp index 5a184fcd..c56fbbde 100644 --- a/src/loaders/tvg/tvgTvgLoader.cpp +++ b/src/loaders/tvg/tvgTvgLoader.cpp @@ -85,6 +85,7 @@ bool TvgLoader::open(const string &path) return tvgValidateData(pointer, size); } + bool TvgLoader::open(const char *data, uint32_t size, bool copy) { clear(); @@ -102,6 +103,30 @@ bool TvgLoader::open(const char *data, uint32_t size, bool copy) return tvgValidateData(pointer, size); } + +bool TvgLoader::resize(Paint* paint, float w, float h) +{ + if (!paint) return false; + + auto sx = w / this->w; + auto sy = h / this->h; + + //Scale + auto scale = sx < sy ? sx : sy; + paint->scale(scale); + + //Align + float tx = 0, ty = 0; + auto sw = this->w * scale; + auto sh = this->h * scale; + if (sw > sh) ty -= (h - sh) * 0.5f; + else tx -= (w - sw) * 0.5f; + paint->translate(-tx, -ty); + + return true; +} + + bool TvgLoader::read() { if (!pointer || size == 0) return false; @@ -111,6 +136,7 @@ bool TvgLoader::read() return true; } + bool TvgLoader::close() { this->done(); @@ -118,6 +144,7 @@ bool TvgLoader::close() return true; } + void TvgLoader::run(unsigned tid) { if (root) root.reset(); @@ -125,6 +152,7 @@ void TvgLoader::run(unsigned tid) if (!root) clear(); } + unique_ptr TvgLoader::paint() { this->done(); diff --git a/src/loaders/tvg/tvgTvgLoader.h b/src/loaders/tvg/tvgTvgLoader.h index 5bb79542..c138ced4 100644 --- a/src/loaders/tvg/tvgTvgLoader.h +++ b/src/loaders/tvg/tvgTvgLoader.h @@ -31,9 +31,7 @@ public: const char* data = nullptr; const char* pointer = nullptr; uint32_t size = 0; - unique_ptr root = nullptr; - bool copy = false; ~TvgLoader(); @@ -43,11 +41,11 @@ public: bool open(const char *data, uint32_t size, bool copy) override; bool read() override; bool close() override; - - void run(unsigned tid) override; + bool resize(Paint* paint, float w, float h) override; unique_ptr paint() override; private: + void run(unsigned tid) override; void clear(); };