2 * Copyright (c) 2020 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
27 #include "tvgRender.h"
31 enum class PaintType { Shape = 0, Scene, Picture };
35 virtual ~StrategyMethod() {}
37 virtual bool dispose(RenderMethod& renderer) = 0;
38 virtual void* update(RenderMethod& renderer, const RenderTransform* transform, uint32_t opacity, Array<RenderData>& clips, RenderUpdateFlag pFlag) = 0; //Return engine data if it has.
39 virtual bool render(RenderMethod& renderer) = 0;
40 virtual bool bounds(float* x, float* y, float* w, float* h) const = 0;
41 virtual RenderRegion bounds(RenderMethod& renderer) const = 0;
42 virtual Paint* duplicate() = 0;
47 StrategyMethod* smethod = nullptr;
48 RenderTransform *rTransform = nullptr;
49 uint32_t flag = RenderUpdateFlag::None;
51 Paint* cmpTarget = nullptr;
52 CompositeMethod cmpMethod = CompositeMethod::None;
54 uint8_t opacity = 255;
59 if (cmpTarget) delete(cmpTarget);
60 if (smethod) delete(smethod);
61 if (rTransform) delete(rTransform);
64 void method(StrategyMethod* method)
69 bool rotate(float degree)
72 if (fabsf(degree - rTransform->degree) <= FLT_EPSILON) return true;
74 if (fabsf(degree) <= FLT_EPSILON) return true;
75 rTransform = new RenderTransform();
76 if (!rTransform) return false;
78 rTransform->degree = degree;
79 if (!rTransform->overriding) flag |= RenderUpdateFlag::Transform;
84 bool scale(float factor)
87 if (fabsf(factor - rTransform->scale) <= FLT_EPSILON) return true;
89 if (fabsf(factor) <= FLT_EPSILON) return true;
90 rTransform = new RenderTransform();
91 if (!rTransform) return false;
93 rTransform->scale = factor;
94 if (!rTransform->overriding) flag |= RenderUpdateFlag::Transform;
99 bool translate(float x, float y)
102 if (fabsf(x - rTransform->x) <= FLT_EPSILON && fabsf(y - rTransform->y) <= FLT_EPSILON) return true;
104 if (fabsf(x) <= FLT_EPSILON && fabsf(y) <= FLT_EPSILON) return true;
105 rTransform = new RenderTransform();
106 if (!rTransform) return false;
110 if (!rTransform->overriding) flag |= RenderUpdateFlag::Transform;
115 bool transform(const Matrix& m)
118 rTransform = new RenderTransform();
119 if (!rTransform) return false;
121 rTransform->override(m);
122 flag |= RenderUpdateFlag::Transform;
127 bool bounds(float* x, float* y, float* w, float* h) const
129 return smethod->bounds(x, y, w, h);
132 RenderRegion bounds(RenderMethod& renderer) const
134 return smethod->bounds(renderer);
137 bool dispose(RenderMethod& renderer)
139 if (cmpTarget) cmpTarget->pImpl->dispose(renderer);
140 return smethod->dispose(renderer);
143 void* update(RenderMethod& renderer, const RenderTransform* pTransform, uint32_t opacity, Array<RenderData>& clips, uint32_t pFlag)
145 if (flag & RenderUpdateFlag::Transform) {
146 if (!rTransform) return nullptr;
147 if (!rTransform->update()) {
149 rTransform = nullptr;
153 void *cmpData = nullptr;
156 cmpData = cmpTarget->pImpl->update(renderer, pTransform, 255, clips, pFlag);
157 if (cmpMethod == CompositeMethod::ClipPath) clips.push(cmpData);
160 void *edata = nullptr;
161 auto newFlag = static_cast<RenderUpdateFlag>(pFlag | flag);
162 flag = RenderUpdateFlag::None;
163 opacity = (opacity * this->opacity) / 255;
165 if (rTransform && pTransform) {
166 RenderTransform outTransform(pTransform, rTransform);
167 edata = smethod->update(renderer, &outTransform, opacity, clips, newFlag);
169 auto outTransform = pTransform ? pTransform : rTransform;
170 edata = smethod->update(renderer, outTransform, opacity, clips, newFlag);
173 if (cmpData && cmpMethod == CompositeMethod::ClipPath) clips.pop();
178 bool render(RenderMethod& renderer)
180 Compositor* cmp = nullptr;
182 /* Note: only ClipPath is processed in update() step.
183 Create a composition image. */
184 if (cmpTarget && cmpMethod != CompositeMethod::ClipPath) {
185 auto region = cmpTarget->pImpl->bounds(renderer);
186 if (region.w == 0 || region.h == 0) return false;
187 cmp = renderer.target(region);
188 renderer.beginComposite(cmp, CompositeMethod::None, 255);
189 cmpTarget->pImpl->render(renderer);
192 if (cmp) renderer.beginComposite(cmp, cmpMethod, cmpTarget->pImpl->opacity);
194 auto ret = smethod->render(renderer);
196 if (cmp) renderer.endComposite(cmp);
203 auto ret = smethod->duplicate();
204 if (!ret) return nullptr;
206 //duplicate Transform
208 ret->pImpl->rTransform = new RenderTransform();
209 if (ret->pImpl->rTransform) {
210 *ret->pImpl->rTransform = *rTransform;
211 ret->pImpl->flag |= RenderUpdateFlag::Transform;
215 ret->pImpl->opacity = opacity;
217 if (cmpTarget) ret->pImpl->cmpTarget = cmpTarget->duplicate();
219 ret->pImpl->cmpMethod = cmpMethod;
224 bool composite(Paint* target, CompositeMethod method)
226 if ((!target && method != CompositeMethod::None) || (target && method == CompositeMethod::None)) return false;
235 struct PaintMethod : StrategyMethod
239 PaintMethod(T* _inst) : inst(_inst) {}
242 bool bounds(float* x, float* y, float* w, float* h) const override
244 return inst->bounds(x, y, w, h);
247 RenderRegion bounds(RenderMethod& renderer) const override
249 return inst->bounds(renderer);
252 bool dispose(RenderMethod& renderer) override
254 return inst->dispose(renderer);
257 void* update(RenderMethod& renderer, const RenderTransform* transform, uint32_t opacity, Array<RenderData>& clips, RenderUpdateFlag flag) override
259 return inst->update(renderer, transform, opacity, clips, flag);
262 bool render(RenderMethod& renderer) override
264 return inst->render(renderer);
267 Paint* duplicate() override
269 return inst->duplicate();
274 #endif //_TVG_PAINT_H_