2 * Copyright (c) 2020-2021 Samsung Electronics Co., Ltd. All rights reserved.
4 * Permission is hereby granted, free of charge, to any person obtaining a copy
5 * of this software and associated documentation files (the "Software"), to deal
6 * in the Software without restriction, including without limitation the rights
7 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8 * copies of the Software, and to permit persons to whom the Software is
9 * furnished to do so, subject to the following conditions:
11 * The above copyright notice and this permission notice shall be included in all
12 * copies or substantial portions of the Software.
14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22 #ifndef _TVG_PICTURE_IMPL_H_
23 #define _TVG_PICTURE_IMPL_H_
27 #include "tvgLoader.h"
29 /************************************************************************/
30 /* Internal Class Implementation */
31 /************************************************************************/
33 struct PictureIterator : Iterator
35 Paint* paint = nullptr;
38 PictureIterator(Paint* p) : paint(p) {}
40 const Paint* next() override
42 if (!ptr) ptr = paint;
47 uint32_t count() override
62 shared_ptr<LoadModule> loader = nullptr;
63 Paint* paint = nullptr;
64 uint32_t* pixels = nullptr;
65 Picture* picture = nullptr;
66 void* rdata = nullptr; //engine data
68 bool resizing = false;
70 Impl(Picture* p) : picture(p)
76 if (paint) delete(paint);
79 bool dispose(RenderMethod& renderer)
83 ret = paint->pImpl->dispose(renderer);
85 ret = renderer.dispose(rdata);
95 if (auto p = loader->paint()) {
98 if (w != loader->w || h != loader->h) {
99 loader->resize(paint, w, h);
102 if (paint) return RenderUpdateFlag::None;
106 pixels = const_cast<uint32_t*>(loader->pixels());
108 if (pixels) return RenderUpdateFlag::Image;
111 return RenderUpdateFlag::None;
114 RenderTransform resizeTransform(const RenderTransform* pTransform)
116 //Overriding Transformation by the desired image size
117 auto sx = w / loader->w;
118 auto sy = h / loader->h;
119 auto scale = sx < sy ? sx : sy;
122 tmp.m = {scale, 0, 0, 0, scale, 0, 0, 0, 1};
124 if (!pTransform) return tmp;
125 else return RenderTransform(pTransform, &tmp);
128 void* update(RenderMethod &renderer, const RenderTransform* pTransform, uint32_t opacity, Array<RenderData>& clips, RenderUpdateFlag pFlag)
130 auto flag = reload();
133 auto transform = resizeTransform(pTransform);
134 rdata = renderer.prepare(*picture, rdata, &transform, opacity, clips, static_cast<RenderUpdateFlag>(pFlag | flag));
137 loader->resize(paint, w, h);
140 rdata = paint->pImpl->update(renderer, pTransform, opacity, clips, static_cast<RenderUpdateFlag>(pFlag | flag));
145 bool render(RenderMethod &renderer)
147 if (pixels) return renderer.renderImage(rdata);
148 else if (paint) return paint->pImpl->render(renderer);
152 bool viewbox(float* x, float* y, float* w, float* h) const
154 if (!loader) return false;
155 if (x) *x = loader->vx;
156 if (y) *y = loader->vy;
157 if (w) *w = loader->vw;
158 if (h) *h = loader->vh;
162 bool size(float w, float h)
170 bool bounds(float* x, float* y, float* w, float* h)
180 RenderRegion bounds(RenderMethod& renderer)
182 if (rdata) return renderer.region(rdata);
183 if (paint) return paint->pImpl->bounds(renderer);
187 Result load(const string& path)
189 if (paint || pixels) return Result::InsufficientCondition;
190 if (loader) loader->close();
191 bool invalid; //Invalid Path
192 loader = LoaderMgr::loader(path, &invalid);
194 if (invalid) return Result::InvalidArguments;
195 return Result::NonSupport;
197 if (!loader->read()) return Result::Unknown;
200 return Result::Success;
203 Result load(const char* data, uint32_t size, const string& mimeType, bool copy)
205 if (paint || pixels) return Result::InsufficientCondition;
206 if (loader) loader->close();
207 loader = LoaderMgr::loader(data, size, mimeType, copy);
208 if (!loader) return Result::NonSupport;
209 if (!loader->read()) return Result::Unknown;
212 return Result::Success;
215 Result load(uint32_t* data, uint32_t w, uint32_t h, bool copy)
217 if (paint || pixels) return Result::InsufficientCondition;
218 if (loader) loader->close();
219 loader = LoaderMgr::loader(data, w, h, copy);
220 if (!loader) return Result::NonSupport;
223 return Result::Success;
230 auto ret = Picture::gen();
231 if (!ret) return nullptr;
233 auto dup = ret.get()->pImpl;
234 if (paint) dup->paint = paint->duplicate();
236 dup->loader = loader;
237 dup->pixels = pixels;
240 dup->resizing = resizing;
242 return ret.release();
248 return new PictureIterator(paint);
252 #endif //_TVG_PICTURE_IMPL_H_