1 | /* |
2 | * Copyright (c) 2020 - 2023 the ThorVG project. 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 | |
23 | #ifndef _TVG_PAINT_H_ |
24 | #define _TVG_PAINT_H_ |
25 | |
26 | #include "tvgRender.h" |
27 | |
28 | |
29 | namespace tvg |
30 | { |
31 | enum ContextFlag : uint8_t {Invalid = 0, FastTrack = 1}; |
32 | |
33 | struct Iterator |
34 | { |
35 | virtual ~Iterator() {} |
36 | virtual const Paint* next() = 0; |
37 | virtual uint32_t count() = 0; |
38 | virtual void begin() = 0; |
39 | }; |
40 | |
41 | struct StrategyMethod |
42 | { |
43 | virtual ~StrategyMethod() {} |
44 | |
45 | virtual bool dispose(RenderMethod& renderer) = 0; |
46 | virtual void* update(RenderMethod& renderer, const RenderTransform* transform, Array<RenderData>& clips, uint8_t opacity, RenderUpdateFlag pFlag, bool clipper) = 0; //Return engine data if it has. |
47 | virtual bool render(RenderMethod& renderer) = 0; |
48 | virtual bool bounds(float* x, float* y, float* w, float* h) = 0; |
49 | virtual RenderRegion bounds(RenderMethod& renderer) const = 0; |
50 | virtual Paint* duplicate() = 0; |
51 | virtual Iterator* iterator() = 0; |
52 | }; |
53 | |
54 | struct Composite |
55 | { |
56 | Paint* target; |
57 | Paint* source; |
58 | CompositeMethod method; |
59 | }; |
60 | |
61 | struct Paint::Impl |
62 | { |
63 | StrategyMethod* smethod = nullptr; |
64 | RenderTransform* rTransform = nullptr; |
65 | Composite* compData = nullptr; |
66 | BlendMethod blendMethod = BlendMethod::Normal; //uint8_t |
67 | uint8_t renderFlag = RenderUpdateFlag::None; |
68 | uint8_t ctxFlag = ContextFlag::Invalid; |
69 | uint8_t id; |
70 | uint8_t opacity = 255; |
71 | |
72 | ~Impl() |
73 | { |
74 | if (compData) { |
75 | delete(compData->target); |
76 | free(compData); |
77 | } |
78 | delete(smethod); |
79 | delete(rTransform); |
80 | } |
81 | |
82 | void method(StrategyMethod* method) |
83 | { |
84 | smethod = method; |
85 | } |
86 | |
87 | bool transform(const Matrix& m) |
88 | { |
89 | if (!rTransform) { |
90 | rTransform = new RenderTransform(); |
91 | if (!rTransform) return false; |
92 | } |
93 | rTransform->override(m); |
94 | renderFlag |= RenderUpdateFlag::Transform; |
95 | |
96 | return true; |
97 | } |
98 | |
99 | Matrix* transform() |
100 | { |
101 | if (rTransform) { |
102 | rTransform->update(); |
103 | return &rTransform->m; |
104 | } |
105 | return nullptr; |
106 | } |
107 | |
108 | RenderRegion bounds(RenderMethod& renderer) const |
109 | { |
110 | return smethod->bounds(renderer); |
111 | } |
112 | |
113 | bool dispose(RenderMethod& renderer) |
114 | { |
115 | if (compData) compData->target->pImpl->dispose(renderer); |
116 | return smethod->dispose(renderer); |
117 | } |
118 | |
119 | Iterator* iterator() |
120 | { |
121 | return smethod->iterator(); |
122 | } |
123 | |
124 | bool composite(Paint* source, Paint* target, CompositeMethod method) |
125 | { |
126 | //Invalid case |
127 | if ((!target && method != CompositeMethod::None) || (target && method == CompositeMethod::None)) return false; |
128 | |
129 | if (compData) { |
130 | delete(compData->target); |
131 | //Reset scenario |
132 | if (!target && method == CompositeMethod::None) { |
133 | free(compData); |
134 | compData = nullptr; |
135 | return true; |
136 | } |
137 | } else { |
138 | if (!target && method == CompositeMethod::None) return true; |
139 | compData = static_cast<Composite*>(calloc(1, sizeof(Composite))); |
140 | } |
141 | compData->target = target; |
142 | compData->source = source; |
143 | compData->method = method; |
144 | return true; |
145 | } |
146 | |
147 | bool rotate(float degree); |
148 | bool scale(float factor); |
149 | bool translate(float x, float y); |
150 | bool bounds(float* x, float* y, float* w, float* h, bool transformed); |
151 | RenderData update(RenderMethod& renderer, const RenderTransform* pTransform, Array<RenderData>& clips, uint8_t opacity, RenderUpdateFlag pFlag, bool clipper = false); |
152 | bool render(RenderMethod& renderer); |
153 | Paint* duplicate(); |
154 | }; |
155 | |
156 | |
157 | template<class T> |
158 | struct PaintMethod : StrategyMethod |
159 | { |
160 | T* inst = nullptr; |
161 | |
162 | PaintMethod(T* _inst) : inst(_inst) {} |
163 | ~PaintMethod() {} |
164 | |
165 | bool bounds(float* x, float* y, float* w, float* h) override |
166 | { |
167 | return inst->bounds(x, y, w, h); |
168 | } |
169 | |
170 | RenderRegion bounds(RenderMethod& renderer) const override |
171 | { |
172 | return inst->bounds(renderer); |
173 | } |
174 | |
175 | bool dispose(RenderMethod& renderer) override |
176 | { |
177 | return inst->dispose(renderer); |
178 | } |
179 | |
180 | RenderData update(RenderMethod& renderer, const RenderTransform* transform, Array<RenderData>& clips, uint8_t opacity, RenderUpdateFlag renderFlag, bool clipper) override |
181 | { |
182 | return inst->update(renderer, transform, clips, opacity, renderFlag, clipper); |
183 | } |
184 | |
185 | bool render(RenderMethod& renderer) override |
186 | { |
187 | return inst->render(renderer); |
188 | } |
189 | |
190 | Paint* duplicate() override |
191 | { |
192 | return inst->duplicate(); |
193 | } |
194 | |
195 | Iterator* iterator() override |
196 | { |
197 | return inst->iterator(); |
198 | } |
199 | }; |
200 | } |
201 | |
202 | #endif //_TVG_PAINT_H_ |
203 | |