From ec6e5618e234c4fd88b3c1d79e4c6686321d4cba Mon Sep 17 00:00:00 2001 From: Hermet Park Date: Thu, 30 Jul 2020 16:50:29 +0900 Subject: [PATCH] common picture: introduce picture feature which is for vector file extensions. Now Scene is only specialized for composition of Paint objects. Change-Id: I16426913f029c89e9f9ac4d5e0afed11d1a228d0 --- inc/thorvg.h | 24 ++++++- src/lib/meson.build | 2 + src/lib/tvgCommon.h | 5 -- src/lib/tvgPicture.cpp | 57 +++++++++++++++ src/lib/tvgPictureImpl.h | 179 +++++++++++++++++++++++++++++++++++++++++++++++ src/lib/tvgScene.cpp | 10 +-- src/lib/tvgSceneImpl.h | 75 ++++++-------------- src/lib/tvgShape.cpp | 1 - src/lib/tvgShapeImpl.h | 1 + test/testSvg.cpp | 8 +-- 10 files changed, 290 insertions(+), 72 deletions(-) create mode 100644 src/lib/tvgPicture.cpp create mode 100644 src/lib/tvgPictureImpl.h diff --git a/inc/thorvg.h b/inc/thorvg.h index 36fed95..7c725bc 100644 --- a/inc/thorvg.h +++ b/inc/thorvg.h @@ -268,6 +268,28 @@ public: /** + * @class Picture + * + * @ingroup ThorVG + * + * @brief description... + * + */ +class TVG_EXPORT Picture final : public Paint +{ +public: + ~Picture(); + + Result load(const std::string& path) noexcept; + Result size(float* w, float* h) const noexcept; + + static std::unique_ptr gen() noexcept; + + _TVG_DECLARE_PRIVATE(Picture); +}; + + +/** * @class Scene * * @ingroup ThorVG @@ -282,11 +304,11 @@ public: Result push(std::unique_ptr paint) noexcept; Result reserve(uint32_t size) noexcept; - Result load(const std::string& path) noexcept; static std::unique_ptr gen() noexcept; _TVG_DECLARE_PRIVATE(Scene); + _TVG_DECLARE_ACCESSOR(Picture); }; diff --git a/src/lib/meson.build b/src/lib/meson.build index 64cedbd..631016d 100644 --- a/src/lib/meson.build +++ b/src/lib/meson.build @@ -16,6 +16,7 @@ source_file = [ 'tvgBezier.h', 'tvgLoader.h', 'tvgLoaderMgr.h', + 'tvgPictureImpl.h', 'tvgRender.h', 'tvgSceneImpl.h', 'tvgShapePath.h', @@ -28,6 +29,7 @@ source_file = [ 'tvgLinearGradient.cpp', 'tvgLoaderMgr.cpp', 'tvgPaint.cpp', + 'tvgPicture.cpp', 'tvgRadialGradient.cpp', 'tvgRender.cpp', 'tvgScene.cpp', diff --git a/src/lib/tvgCommon.h b/src/lib/tvgCommon.h index 4cec18f..dddac62 100644 --- a/src/lib/tvgCommon.h +++ b/src/lib/tvgCommon.h @@ -31,8 +31,6 @@ using namespace std; using namespace tvg; #define IMPL pImpl.get() -#define SCENE_IMPL scene->pImpl.get() -#define SHAPE_IMPL shape->pImpl.get() #define FILL_ID_LINEAR 0 #define FILL_ID_RADIAL 1 @@ -42,8 +40,5 @@ using namespace tvg; #include "tvgLoaderMgr.h" #include "tvgRender.h" #include "tvgPaint.h" -#include "tvgShapePath.h" -#include "tvgShapeImpl.h" -#include "tvgSceneImpl.h" #endif //_TVG_COMMON_H_ diff --git a/src/lib/tvgPicture.cpp b/src/lib/tvgPicture.cpp new file mode 100644 index 0000000..6d6ae47 --- /dev/null +++ b/src/lib/tvgPicture.cpp @@ -0,0 +1,57 @@ +/* + * Copyright (c) 2020 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ +#ifndef _TVG_PICTURE_CPP_ +#define _TVG_PICTURE_CPP_ + +#include "tvgPictureImpl.h" + +/************************************************************************/ +/* External Class Implementation */ +/************************************************************************/ + +Picture::Picture() : pImpl(make_unique()) +{ + Paint::IMPL->method(new PaintMethod(IMPL)); +} + + +Picture::~Picture() +{ +} + + +unique_ptr Picture::gen() noexcept +{ + return unique_ptr(new Picture); +} + + +Result Picture::load(const std::string& path) noexcept +{ + if (path.empty()) return Result::InvalidArguments; + + return IMPL->load(path); +} + + +Result Picture::size(float* w, float* h) const noexcept +{ + if (IMPL->size(w, h)) return Result::Success; + return Result::InsufficientCondition; +} + +#endif /* _TVG_PICTURE_CPP_ */ \ No newline at end of file diff --git a/src/lib/tvgPictureImpl.h b/src/lib/tvgPictureImpl.h new file mode 100644 index 0000000..b72c556 --- /dev/null +++ b/src/lib/tvgPictureImpl.h @@ -0,0 +1,179 @@ +/* + * Copyright (c) 2020 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ +#ifndef _TVG_PICTURE_IMPL_H_ +#define _TVG_PICTURE_IMPL_H_ + +#include "tvgCommon.h" +#include "tvgSceneImpl.h" + +/************************************************************************/ +/* Internal Class Implementation */ +/************************************************************************/ + +struct Picture::Impl +{ + unique_ptr loader = nullptr; + Scene* scene = nullptr; + RenderTransform *rTransform = nullptr; + uint32_t flag = RenderUpdateFlag::None; + + ~Impl() + { + if (rTransform) delete(rTransform); + } + + bool dispose(RenderMethod& renderer) + { + if (!scene) return false; + + scene->IMPL->dispose(renderer); + delete(scene); + + return true; + } + + bool update(RenderMethod &renderer, const RenderTransform* pTransform, uint32_t pFlag) + { + if (loader) { + auto scene = loader->data(); + if (scene) { + this->scene = scene.release(); + if (!this->scene) return false; + loader->close(); + } + } + + if (!scene) return false; + + if (flag & RenderUpdateFlag::Transform) { + if (!rTransform) return false; + if (!rTransform->update()) { + delete(rTransform); + rTransform = nullptr; + } + } + + auto ret = true; + + if (rTransform && pTransform) { + RenderTransform outTransform(pTransform, rTransform); + ret = scene->IMPL->update(renderer, &outTransform, flag); + } else { + auto outTransform = pTransform ? pTransform : rTransform; + ret = scene->IMPL->update(renderer, outTransform, flag); + } + + flag = RenderUpdateFlag::None; + + return ret; + } + + bool render(RenderMethod &renderer) + { + if (!scene) return false; + return scene->IMPL->render(renderer); + } + + + bool size(float* w, float* h) + { + if (loader) { + if (w) *w = loader->vw; + if (h) *h = loader->vh; + return true; + } + + return false; + } + + bool bounds(float* x, float* y, float* w, float* h) + { + if (!scene) return false; + return scene->IMPL->bounds(x, y, w, h); + } + + bool scale(float factor) + { + if (rTransform) { + if (fabsf(factor - rTransform->scale) <= FLT_EPSILON) return true; + } else { + if (fabsf(factor) <= FLT_EPSILON) return true; + rTransform = new RenderTransform(); + if (!rTransform) return false; + } + rTransform->scale = factor; + flag |= RenderUpdateFlag::Transform; + + return true; + } + + bool rotate(float degree) + { + if (rTransform) { + if (fabsf(degree - rTransform->degree) <= FLT_EPSILON) return true; + } else { + if (fabsf(degree) <= FLT_EPSILON) return true; + rTransform = new RenderTransform(); + if (!rTransform) return false; + } + rTransform->degree = degree; + flag |= RenderUpdateFlag::Transform; + + return true; + } + + bool translate(float x, float y) + { + if (rTransform) { + if (fabsf(x - rTransform->x) <= FLT_EPSILON && fabsf(y - rTransform->y) <= FLT_EPSILON) return true; + } else { + if (fabsf(x) <= FLT_EPSILON && fabsf(y) <= FLT_EPSILON) return true; + rTransform = new RenderTransform(); + if (!rTransform) return false; + } + rTransform->x = x; + rTransform->y = y; + flag |= RenderUpdateFlag::Transform; + + return true; + } + + + bool transform(const Matrix& m) + { + if (!rTransform) { + rTransform = new RenderTransform(); + if (!rTransform) return false; + } + rTransform->override(m); + flag |= RenderUpdateFlag::Transform; + + return true; + } + + + Result load(const string& path) + { + if (loader) loader->close(); + loader = LoaderMgr::loader(path.c_str()); + if (!loader || !loader->open(path.c_str())) return Result::NonSupport; + if (!loader->read()) return Result::Unknown; + return Result::Success; + } +}; + +#endif //_TVG_PICTURE_IMPL_H_ \ No newline at end of file diff --git a/src/lib/tvgScene.cpp b/src/lib/tvgScene.cpp index d34d57a..ff3aca8 100644 --- a/src/lib/tvgScene.cpp +++ b/src/lib/tvgScene.cpp @@ -17,7 +17,7 @@ #ifndef _TVG_SCENE_CPP_ #define _TVG_SCENE_CPP_ -#include "tvgCommon.h" +#include "tvgSceneImpl.h" /************************************************************************/ /* External Class Implementation */ @@ -57,12 +57,4 @@ Result Scene::reserve(uint32_t size) noexcept return Result::Success; } - -Result Scene::load(const std::string& path) noexcept -{ - if (path.empty()) return Result::InvalidArguments; - - return IMPL->load(path); -} - #endif /* _TVG_SCENE_CPP_ */ \ No newline at end of file diff --git a/src/lib/tvgSceneImpl.h b/src/lib/tvgSceneImpl.h index 0ba1f1f..84bdd7e 100644 --- a/src/lib/tvgSceneImpl.h +++ b/src/lib/tvgSceneImpl.h @@ -28,12 +28,9 @@ struct Scene::Impl vector paints; RenderTransform *rTransform = nullptr; uint32_t flag = RenderUpdateFlag::None; - unique_ptr loader = nullptr; ~Impl() { - //Are you sure clear() prior to this? - assert(paints.empty()); if (rTransform) delete(rTransform); } @@ -58,16 +55,6 @@ struct Scene::Impl bool update(RenderMethod &renderer, const RenderTransform* pTransform, uint32_t pFlag) { - if (loader) { - auto scene = loader->data(); - if (scene) { - auto p = scene.release(); - if (!p) return false; - paints.push_back(p); - loader->close(); - } - } - if (flag & RenderUpdateFlag::Transform) { if (!rTransform) return false; if (!rTransform->update()) { @@ -101,37 +88,31 @@ struct Scene::Impl bool bounds(float* px, float* py, float* pw, float* ph) { - if (loader) { - if (px) *px = loader->vx; - if (py) *py = loader->vy; - if (pw) *pw = loader->vw; - if (ph) *ph = loader->vh; - } else { - auto x = FLT_MAX; - auto y = FLT_MAX; - auto w = 0.0f; - auto h = 0.0f; - - for(auto paint: paints) { - auto x2 = FLT_MAX; - auto y2 = FLT_MAX; - auto w2 = 0.0f; - auto h2 = 0.0f; - - if (paint->IMPL->method()->bounds(&x2, &y2, &w2, &h2)) return false; - - //Merge regions - if (x2 < x) x = x2; - if (x + w < x2 + w2) w = (x2 + w2) - x; - if (y2 < y) y = x2; - if (y + h < y2 + h2) h = (y2 + h2) - y; - } + auto x = FLT_MAX; + auto y = FLT_MAX; + auto w = 0.0f; + auto h = 0.0f; - if (px) *px = x; - if (py) *py = y; - if (pw) *pw = w; - if (ph) *ph = h; + for(auto paint: paints) { + auto x2 = FLT_MAX; + auto y2 = FLT_MAX; + auto w2 = 0.0f; + auto h2 = 0.0f; + + if (paint->IMPL->method()->bounds(&x2, &y2, &w2, &h2)) return false; + + //Merge regions + if (x2 < x) x = x2; + if (x + w < x2 + w2) w = (x2 + w2) - x; + if (y2 < y) y = x2; + if (y + h < y2 + h2) h = (y2 + h2) - y; } + + if (px) *px = x; + if (py) *py = y; + if (pw) *pw = w; + if (ph) *ph = h; + return true; } @@ -193,16 +174,6 @@ struct Scene::Impl return true; } - - - Result load(const string& path) - { - if (loader) loader->close(); - loader = LoaderMgr::loader(path.c_str()); - if (!loader || !loader->open(path.c_str())) return Result::NonSupport; - if (!loader->read()) return Result::Unknown; - return Result::Success; - } }; #endif //_TVG_SCENE_IMPL_H_ \ No newline at end of file diff --git a/src/lib/tvgShape.cpp b/src/lib/tvgShape.cpp index 7d26614..59718d8 100644 --- a/src/lib/tvgShape.cpp +++ b/src/lib/tvgShape.cpp @@ -17,7 +17,6 @@ #ifndef _TVG_SHAPE_CPP_ #define _TVG_SHAPE_CPP_ -#include "tvgCommon.h" #include "tvgShapeImpl.h" /************************************************************************/ diff --git a/src/lib/tvgShapeImpl.h b/src/lib/tvgShapeImpl.h index a7755da..2a7005e 100644 --- a/src/lib/tvgShapeImpl.h +++ b/src/lib/tvgShapeImpl.h @@ -18,6 +18,7 @@ #define _TVG_SHAPE_IMPL_H_ #include "tvgCommon.h" +#include "tvgShapePath.h" /************************************************************************/ /* Internal Class Implementation */ diff --git a/test/testSvg.cpp b/test/testSvg.cpp index b8eb2ba..5f05370 100644 --- a/test/testSvg.cpp +++ b/test/testSvg.cpp @@ -14,15 +14,15 @@ void svgDirCallback(const char* name, const char* path, void* data) { tvg::Canvas* canvas = static_cast(data); - auto scene = tvg::Scene::gen(); + auto picture = tvg::Picture::gen(); char buf[PATH_MAX]; sprintf(buf,"%s/%s", path, name); - if (scene->load(buf) != tvg::Result::Success) return; + if (picture->load(buf) != tvg::Result::Success) return; - scene->translate(((WIDTH - (x * 2)) / NUM_PER_LINE) * (count % NUM_PER_LINE) + x, ((HEIGHT - (y * 2))/ NUM_PER_LINE) * (int)((float)count / (float)NUM_PER_LINE) + y); - canvas->push(move(scene)); + picture->translate(((WIDTH - (x * 2)) / NUM_PER_LINE) * (count % NUM_PER_LINE) + x, ((HEIGHT - (y * 2))/ NUM_PER_LINE) * (int)((float)count / (float)NUM_PER_LINE) + y); + canvas->push(move(picture)); count++; -- 2.7.4