diff --git a/inc/thorvg.h b/inc/thorvg.h index 97eb1dbb..47c41340 100644 --- a/inc/thorvg.h +++ b/inc/thorvg.h @@ -282,6 +282,9 @@ public: Result load(uint32_t* data, uint32_t w, uint32_t h, bool copy) noexcept; Result viewbox(float* x, float* y, float* w, float* h) const noexcept; + Result size(uint32_t w, uint32_t h) noexcept; + Result size(uint32_t* w, uint32_t* h) const noexcept; + static std::unique_ptr gen() noexcept; _TVG_DECLARE_PRIVATE(Picture); diff --git a/src/examples/Svg.cpp b/src/examples/Svg.cpp index 2ce73384..4c074201 100644 --- a/src/examples/Svg.cpp +++ b/src/examples/Svg.cpp @@ -25,25 +25,8 @@ void svgDirCallback(const char* name, const char* path, void* data) if (picture->load(buf) != tvg::Result::Success) return; - float x, y, w, h; - picture->viewbox(&x, &y, &w, &h); - - float rate = (SIZE/(w > h ? w : h)); - picture->scale(rate); - - x *= rate; - y *= rate; - w *= rate; - h *= rate; - - //Center Align ? - if (w > h) { - y -= (SIZE - h) * 0.5f; - } else { - x -= (SIZE - w) * 0.5f; - } - - picture->translate((count % NUM_PER_LINE) * SIZE - x, SIZE * (count / NUM_PER_LINE) - y); + picture->size(SIZE, SIZE); + picture->translate((count % NUM_PER_LINE) * SIZE, SIZE * (count / NUM_PER_LINE)); pictures.push_back(move(picture)); diff --git a/src/lib/tvgLoader.h b/src/lib/tvgLoader.h index b8d348e5..0d99207a 100644 --- a/src/lib/tvgLoader.h +++ b/src/lib/tvgLoader.h @@ -36,6 +36,10 @@ public: float vw = 0; float vh = 0; + uint32_t w = 0; //default size + uint32_t h = 0; //default size + bool preserveAspect = true; //keep aspect ratio by default. + virtual ~Loader() {} virtual bool open(const string& path) { /* Not supported */ return false; }; diff --git a/src/lib/tvgPicture.cpp b/src/lib/tvgPicture.cpp index 7ecb62e4..9ea0bff2 100644 --- a/src/lib/tvgPicture.cpp +++ b/src/lib/tvgPicture.cpp @@ -73,3 +73,19 @@ Result Picture::viewbox(float* x, float* y, float* w, float* h) const noexcept if (pImpl->viewbox(x, y, w, h)) return Result::Success; return Result::InsufficientCondition; } + + +Result Picture::size(uint32_t w, uint32_t h) noexcept +{ + if (pImpl->size(w, h)) return Result::Success; + return Result::InsufficientCondition; +} + + +Result Picture::size(uint32_t* w, uint32_t* h) const noexcept +{ + if (w) *w = pImpl->w; + if (h) *h = pImpl->h; + return Result::Success; +} + diff --git a/src/lib/tvgPictureImpl.h b/src/lib/tvgPictureImpl.h index 79d60f98..a692ec94 100644 --- a/src/lib/tvgPictureImpl.h +++ b/src/lib/tvgPictureImpl.h @@ -38,6 +38,9 @@ struct Picture::Impl Picture *picture = nullptr; void *edata = nullptr; //engine data + uint32_t w = 0, h = 0; + bool resizing = false; + Impl(Picture* p) : picture(p) { } @@ -56,6 +59,36 @@ struct Picture::Impl return false; } + void resize() + { + uint32_t w = 0, h = 0; + if (this->w != 0 && this->h != 0) { + w = this->w; + h = this->h; + } + else if (loader->w != 0 && loader->h != 0) { + w = loader->w; + h = loader->h; + } + if (w != 0 && h != 0) { + auto sx = w / (loader->vw + (loader->vx > 0 ? loader->vx : -1 * loader->vx)); + auto sy = h / (loader->vh + (loader->vy > 0 ? loader->vy : -1 * loader->vy)); + if (!loader->preserveAspect) { + Matrix m = {sx, 0, -loader->vx, + 0, sy, -loader->vy, + 0, 0, 1}; + paint->transform(m); + } + else { + auto scale = sx < sy ? sx : sy; + paint->translate(((w - loader->vw) * scale) / 2.0, ((h - loader->vh) * scale) / 2.0); + paint->scale(scale); + paint->translate(-loader->vx, -loader->vy); + } + resizing = false; + } + } + uint32_t reload() { if (loader) { @@ -63,6 +96,7 @@ struct Picture::Impl auto scene = loader->scene(); if (scene) { paint = scene.release(); + resizing = true; loader->close(); if (paint) return RenderUpdateFlag::None; } @@ -80,7 +114,10 @@ struct Picture::Impl uint32_t flag = reload(); if (pixels) edata = renderer.prepare(*picture, edata, pixels, transform, opacity, compList, static_cast(pFlag | flag)); - else if (paint) edata = paint->pImpl->update(renderer, transform, opacity, compList, static_cast(pFlag | flag)); + else if (paint) { + if (resizing) resize(); + edata = paint->pImpl->update(renderer, transform, opacity, compList, static_cast(pFlag | flag)); + } return edata; } @@ -101,6 +138,14 @@ struct Picture::Impl return true; } + bool size(uint32_t w, uint32_t h) + { + this->w = w; + this->h = h; + resizing = true; + return true; + } + bool bounds(float* x, float* y, float* w, float* h) { if (!paint) return false; diff --git a/src/loaders/svg/tvgSvgLoader.cpp b/src/loaders/svg/tvgSvgLoader.cpp index d6dc59de..d1912cfd 100644 --- a/src/loaders/svg/tvgSvgLoader.cpp +++ b/src/loaders/svg/tvgSvgLoader.cpp @@ -2466,10 +2466,15 @@ bool SvgLoader::header() if (loaderData.doc && loaderData.doc->type == SvgNodeType::Doc) { //Return the brief resource info such as viewbox: - this->vx = loaderData.doc->node.doc.vx; - this->vy = loaderData.doc->node.doc.vy; - this->vw = loaderData.doc->node.doc.vw; - this->vh = loaderData.doc->node.doc.vh; + vx = loaderData.doc->node.doc.vx; + vy = loaderData.doc->node.doc.vy; + vw = loaderData.doc->node.doc.vw; + vh = loaderData.doc->node.doc.vh; + + w = loaderData.doc->node.doc.w; + h = loaderData.doc->node.doc.h; + + preserveAspect = loaderData.doc->node.doc.preserveAspect; } else { //LOG: No SVG File. There is no return false; diff --git a/src/loaders/svg/tvgSvgSceneBuilder.cpp b/src/loaders/svg/tvgSvgSceneBuilder.cpp index e1c1c0a4..dc26c014 100644 --- a/src/loaders/svg/tvgSvgSceneBuilder.cpp +++ b/src/loaders/svg/tvgSvgSceneBuilder.cpp @@ -384,10 +384,5 @@ unique_ptr SvgSceneBuilder::build(SvgNode* node) { if (!node || (node->type != SvgNodeType::Doc)) return nullptr; - viewBox.x = node->node.doc.vx; - viewBox.y = node->node.doc.vy; - viewBox.w = node->node.doc.vw; - viewBox.h = node->node.doc.vh; - preserveAspect = node->node.doc.preserveAspect; - return _sceneBuildHelper(node, viewBox.x, viewBox.y, viewBox.w, viewBox.h, 255); + return _sceneBuildHelper(node, node->node.doc.vx, node->node.doc.vy, node->node.doc.vw, node->node.doc.vh, 255); } diff --git a/src/loaders/svg/tvgSvgSceneBuilder.h b/src/loaders/svg/tvgSvgSceneBuilder.h index 79f111bc..275c40f5 100644 --- a/src/loaders/svg/tvgSvgSceneBuilder.h +++ b/src/loaders/svg/tvgSvgSceneBuilder.h @@ -27,13 +27,6 @@ class SvgSceneBuilder { -private: - struct { - int x, y; - uint32_t w, h; - } viewBox = {0, 0, 0, 0}; - bool preserveAspect = false; - public: SvgSceneBuilder(); ~SvgSceneBuilder();