example: just renamed the svg file.
[platform/core/graphics/tizenvg.git] / src / lib / tvgPictureImpl.h
1 /*
2  * Copyright (c) 2020 - 2022 Samsung Electronics Co., Ltd. All rights reserved.
3
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:
10
11  * The above copyright notice and this permission notice shall be included in all
12  * copies or substantial portions of the Software.
13
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
20  * SOFTWARE.
21  */
22 #ifndef _TVG_PICTURE_IMPL_H_
23 #define _TVG_PICTURE_IMPL_H_
24
25 #include <string>
26 #include "tvgPaint.h"
27 #include "tvgLoader.h"
28
29 /************************************************************************/
30 /* Internal Class Implementation                                        */
31 /************************************************************************/
32
33 struct PictureIterator : Iterator
34 {
35     Paint* paint = nullptr;
36     Paint* ptr = nullptr;
37
38     PictureIterator(Paint* p) : paint(p) {}
39
40     const Paint* next() override
41     {
42         if (!ptr) ptr = paint;
43         else ptr = nullptr;
44         return ptr;
45     }
46
47     uint32_t count() override
48     {
49         if (paint) return 1;
50         else return 0;
51     }
52
53     void begin() override
54     {
55         ptr = nullptr;
56     }
57 };
58
59
60 struct Picture::Impl
61 {
62     shared_ptr<LoadModule> loader = nullptr;
63
64     Paint* paint = nullptr;           //vector picture uses
65     Surface* surface = nullptr;       //bitmap picture uses
66     void* rdata = nullptr;            //engine data
67     float w = 0, h = 0;
68     bool resizing = false;
69
70     ~Impl()
71     {
72         if (paint) delete(paint);
73         free(surface);
74     }
75
76     bool dispose(RenderMethod& renderer)
77     {
78         bool ret = true;
79         if (paint) {
80             ret = paint->pImpl->dispose(renderer);
81         } else if (surface) {
82             ret =  renderer.dispose(rdata);
83             rdata = nullptr;
84         }
85         return ret;
86     }
87
88     uint32_t reload()
89     {
90         if (loader) {
91             if (!paint) {
92                 if (auto p = loader->paint()) {
93                     paint = p.release();
94                     loader->close();
95                     if (w != loader->w || h != loader->h) {
96                         loader->resize(paint, w, h);
97                         resizing = false;
98                     }
99                     if (paint) return RenderUpdateFlag::None;
100                 }
101             }
102             free(surface);
103             if ((surface = loader->bitmap().release())) {
104                 loader->close();
105                 return RenderUpdateFlag::Image;
106             }
107         }
108         return RenderUpdateFlag::None;
109     }
110
111     RenderTransform resizeTransform(const RenderTransform* pTransform)
112     {
113         //Overriding Transformation by the desired image size
114         auto sx = w / loader->w;
115         auto sy = h / loader->h;
116         auto scale = sx < sy ? sx : sy;
117
118         RenderTransform tmp;
119         tmp.m = {scale, 0, 0, 0, scale, 0, 0, 0, 1};
120
121         if (!pTransform) return tmp;
122         else return RenderTransform(pTransform, &tmp);
123     }
124
125     void* update(RenderMethod &renderer, const RenderTransform* pTransform, uint32_t opacity, Array<RenderData>& clips, RenderUpdateFlag pFlag)
126     {
127         auto flag = reload();
128
129         if (surface) {
130             auto transform = resizeTransform(pTransform);
131             rdata = renderer.prepare(surface, rdata, &transform, opacity, clips, static_cast<RenderUpdateFlag>(pFlag | flag));
132         } else if (paint) {
133             if (resizing) {
134                 loader->resize(paint, w, h);
135                 resizing = false;
136             }
137             rdata = paint->pImpl->update(renderer, pTransform, opacity, clips, static_cast<RenderUpdateFlag>(pFlag | flag));
138         }
139         return rdata;
140     }
141
142     bool render(RenderMethod &renderer)
143     {
144         if (surface) return renderer.renderImage(rdata);
145         else if (paint) return paint->pImpl->render(renderer);
146         return false;
147     }
148
149     bool viewbox(float* x, float* y, float* w, float* h) const
150     {
151         if (!loader) return false;
152         if (x) *x = loader->vx;
153         if (y) *y = loader->vy;
154         if (w) *w = loader->vw;
155         if (h) *h = loader->vh;
156         return true;
157     }
158
159     bool size(float w, float h)
160     {
161         this->w = w;
162         this->h = h;
163         resizing = true;
164         return true;
165     }
166
167     bool bounds(float* x, float* y, float* w, float* h)
168     {
169         if (x) *x = 0;
170         if (y) *y = 0;
171         if (w) *w = this->w;
172         if (h) *h = this->h;
173  
174         return true;
175     }
176
177     RenderRegion bounds(RenderMethod& renderer)
178     {
179         if (rdata) return renderer.region(rdata);
180         if (paint) return paint->pImpl->bounds(renderer);
181         return {0, 0, 0, 0};
182     }
183
184     Result load(const string& path)
185     {
186         if (paint || surface) return Result::InsufficientCondition;
187         if (loader) loader->close();
188         bool invalid;  //Invalid Path
189         loader = LoaderMgr::loader(path, &invalid);
190         if (!loader) {
191             if (invalid) return Result::InvalidArguments;
192             return Result::NonSupport;
193         }
194         if (!loader->read()) return Result::Unknown;
195         w = loader->w;
196         h = loader->h;
197         return Result::Success;
198     }
199
200     Result load(const char* data, uint32_t size, const string& mimeType, bool copy)
201     {
202         if (paint || surface) return Result::InsufficientCondition;
203         if (loader) loader->close();
204         loader = LoaderMgr::loader(data, size, mimeType, copy);
205         if (!loader) return Result::NonSupport;
206         if (!loader->read()) return Result::Unknown;
207         w = loader->w;
208         h = loader->h;
209         return Result::Success;
210     }
211
212     Result load(uint32_t* data, uint32_t w, uint32_t h, bool copy)
213     {
214         if (paint || surface) return Result::InsufficientCondition;
215         if (loader) loader->close();
216         loader = LoaderMgr::loader(data, w, h, copy);
217         if (!loader) return Result::NonSupport;
218         this->w = loader->w;
219         this->h = loader->h;
220         return Result::Success;
221     }
222
223     Paint* duplicate()
224     {
225         reload();
226
227         auto ret = Picture::gen();
228
229         auto dup = ret.get()->pImpl;
230         if (paint) dup->paint = paint->duplicate();
231
232         dup->loader = loader;
233         if (surface) {
234             dup->surface = static_cast<Surface*>(malloc(sizeof(Surface)));
235             *dup->surface = *surface;
236         }
237         dup->w = w;
238         dup->h = h;
239         dup->resizing = resizing;
240
241         return ret.release();
242     }
243
244     Iterator* iterator()
245     {
246         reload();
247         return new PictureIterator(paint);
248     }
249 };
250
251 #endif //_TVG_PICTURE_IMPL_H_