common: code refactoring.
[platform/core/graphics/tizenvg.git] / src / lib / tvgPaint.h
1 /*
2  * Copyright (c) 2020 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_PAINT_H_
23 #define _TVG_PAINT_H_
24
25 namespace tvg
26 {
27     struct StrategyMethod
28     {
29         virtual ~StrategyMethod(){}
30
31         virtual bool dispose(RenderMethod& renderer) = 0;
32         virtual bool update(RenderMethod& renderer, const RenderTransform* transform, RenderUpdateFlag pFlag) = 0;
33         virtual bool render(RenderMethod& renderer) = 0;
34         virtual bool bounds(float* x, float* y, float* w, float* h) const = 0;
35         virtual unique_ptr<Paint> duplicate() = 0;
36     };
37
38     struct Paint::Impl
39     {
40         StrategyMethod* smethod = nullptr;
41         RenderTransform *rTransform = nullptr;
42         uint32_t flag = RenderUpdateFlag::None;
43
44         ~Impl() {
45             if (smethod) delete(smethod);
46             if (rTransform) delete(rTransform);
47         }
48
49         void method(StrategyMethod* method)
50         {
51             smethod = method;
52         }
53
54         bool rotate(float degree)
55         {
56             if (rTransform) {
57                 if (fabsf(degree - rTransform->degree) <= FLT_EPSILON) return true;
58             } else {
59                 if (fabsf(degree) <= FLT_EPSILON) return true;
60                 rTransform = new RenderTransform();
61                 if (!rTransform) return false;
62             }
63             rTransform->degree = degree;
64             if (!rTransform->overriding) flag |= RenderUpdateFlag::Transform;
65
66             return true;
67         }
68
69         bool scale(float factor)
70         {
71             if (rTransform) {
72                 if (fabsf(factor - rTransform->scale) <= FLT_EPSILON) return true;
73             } else {
74                 if (fabsf(factor) <= FLT_EPSILON) return true;
75                 rTransform = new RenderTransform();
76                 if (!rTransform) return false;
77             }
78             rTransform->scale = factor;
79             if (!rTransform->overriding) flag |= RenderUpdateFlag::Transform;
80
81             return true;
82         }
83
84         bool translate(float x, float y)
85         {
86             if (rTransform) {
87                 if (fabsf(x - rTransform->x) <= FLT_EPSILON && fabsf(y - rTransform->y) <= FLT_EPSILON) return true;
88             } else {
89                 if (fabsf(x) <= FLT_EPSILON && fabsf(y) <= FLT_EPSILON) return true;
90                 rTransform = new RenderTransform();
91                 if (!rTransform) return false;
92             }
93             rTransform->x = x;
94             rTransform->y = y;
95             if (!rTransform->overriding) flag |= RenderUpdateFlag::Transform;
96
97             return true;
98         }
99
100         bool transform(const Matrix& m)
101         {
102             if (!rTransform) {
103                 rTransform = new RenderTransform();
104                 if (!rTransform) return false;
105             }
106             rTransform->override(m);
107             flag |= RenderUpdateFlag::Transform;
108
109             return true;
110         }
111
112         bool bounds(float* x, float* y, float* w, float* h) const
113         {
114             return smethod->bounds(x, y, w, h);
115         }
116
117         bool dispose(RenderMethod& renderer)
118         {
119             return smethod->dispose(renderer);
120         }
121
122         bool update(RenderMethod& renderer, const RenderTransform* pTransform, uint32_t pFlag)
123         {
124             if (flag & RenderUpdateFlag::Transform) {
125                 if (!rTransform) return false;
126                 if (!rTransform->update()) {
127                     delete(rTransform);
128                     rTransform = nullptr;
129                 }
130             }
131
132             auto newFlag = static_cast<RenderUpdateFlag>(pFlag | flag);
133             flag = RenderUpdateFlag::None;
134
135             if (rTransform && pTransform) {
136                 RenderTransform outTransform(pTransform, rTransform);
137                 return smethod->update(renderer, &outTransform, newFlag);
138             } else {
139                 auto outTransform = pTransform ? pTransform : rTransform;
140                 return smethod->update(renderer, outTransform, newFlag);
141             }
142         }
143
144         bool render(RenderMethod& renderer)
145         {
146             return smethod->render(renderer);
147         }
148
149         unique_ptr<Paint> duplicate()
150         {
151             return smethod->duplicate();
152         }
153     };
154
155
156     template<class T>
157     struct PaintMethod : StrategyMethod
158     {
159         T* inst = nullptr;
160
161         PaintMethod(T* _inst) : inst(_inst) {}
162         ~PaintMethod(){}
163
164         bool bounds(float* x, float* y, float* w, float* h) const override
165         {
166             return inst->bounds(x, y, w, h);
167         }
168
169         bool dispose(RenderMethod& renderer) override
170         {
171             return inst->dispose(renderer);
172         }
173
174         bool update(RenderMethod& renderer, const RenderTransform* transform, RenderUpdateFlag flag) override
175         {
176             return inst->update(renderer, transform, flag);
177         }
178
179         bool render(RenderMethod& renderer) override
180         {
181             return inst->render(renderer);
182         }
183
184         unique_ptr<Paint> duplicate() override
185         {
186             return inst->duplicate();
187         }
188     };
189 }
190
191 #endif //_TVG_PAINT_H_