1 /*
2  * Copyright (c) 2020 - 2024 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 #include "../../lv_conf_internal.h"
24 #if LV_USE_THORVG_INTERNAL
25 
26 #include "tvgFill.h"
27 
28 /************************************************************************/
29 /* Internal Class Implementation                                        */
30 /************************************************************************/
31 
duplicate()32 Fill* RadialGradient::Impl::duplicate()
33 {
34     auto ret = RadialGradient::gen();
35     if (!ret) return nullptr;
36 
37     ret->pImpl->cx = cx;
38     ret->pImpl->cy = cy;
39     ret->pImpl->r = r;
40     ret->pImpl->fx = fx;
41     ret->pImpl->fy = fy;
42     ret->pImpl->fr = fr;
43 
44     return ret.release();
45 }
46 
47 
radial(float cx,float cy,float r,float fx,float fy,float fr)48 Result RadialGradient::Impl::radial(float cx, float cy, float r, float fx, float fy, float fr)
49 {
50     if (r < 0 || fr < 0) return Result::InvalidArguments;
51 
52     this->cx = cx;
53     this->cy = cy;
54     this->r = r;
55     this->fx = fx;
56     this->fy = fy;
57     this->fr = fr;
58 
59     return Result::Success;
60 };
61 
62 
duplicate()63 Fill* LinearGradient::Impl::duplicate()
64 {
65     auto ret = LinearGradient::gen();
66     if (!ret) return nullptr;
67 
68     ret->pImpl->x1 = x1;
69     ret->pImpl->y1 = y1;
70     ret->pImpl->x2 = x2;
71     ret->pImpl->y2 = y2;
72 
73     return ret.release();
74 };
75 
76 
77 /************************************************************************/
78 /* External Class Implementation                                        */
79 /************************************************************************/
80 
Fill()81 Fill::Fill():pImpl(new Impl())
82 {
83 }
84 
85 
~Fill()86 Fill::~Fill()
87 {
88     delete(pImpl);
89 }
90 
91 
colorStops(const ColorStop * colorStops,uint32_t cnt)92 Result Fill::colorStops(const ColorStop* colorStops, uint32_t cnt) noexcept
93 {
94     if ((!colorStops && cnt > 0) || (colorStops && cnt == 0)) return Result::InvalidArguments;
95 
96     if (cnt == 0) {
97         if (pImpl->colorStops) {
98             free(pImpl->colorStops);
99             pImpl->colorStops = nullptr;
100             pImpl->cnt = 0;
101         }
102         return Result::Success;
103     }
104 
105     if (pImpl->cnt != cnt) {
106         pImpl->colorStops = static_cast<ColorStop*>(realloc(pImpl->colorStops, cnt * sizeof(ColorStop)));
107     }
108 
109     pImpl->cnt = cnt;
110     memcpy(pImpl->colorStops, colorStops, cnt * sizeof(ColorStop));
111 
112     return Result::Success;
113 }
114 
115 
colorStops(const ColorStop ** colorStops) const116 uint32_t Fill::colorStops(const ColorStop** colorStops) const noexcept
117 {
118     if (colorStops) *colorStops = pImpl->colorStops;
119 
120     return pImpl->cnt;
121 }
122 
123 
spread(FillSpread s)124 Result Fill::spread(FillSpread s) noexcept
125 {
126     pImpl->spread = s;
127 
128     return Result::Success;
129 }
130 
131 
spread() const132 FillSpread Fill::spread() const noexcept
133 {
134     return pImpl->spread;
135 }
136 
137 
transform(const Matrix & m)138 Result Fill::transform(const Matrix& m) noexcept
139 {
140     if (!pImpl->transform) {
141         pImpl->transform = static_cast<Matrix*>(malloc(sizeof(Matrix)));
142     }
143     *pImpl->transform = m;
144     return Result::Success;
145 }
146 
147 
transform() const148 Matrix Fill::transform() const noexcept
149 {
150     if (pImpl->transform) return *pImpl->transform;
151     return {1, 0, 0, 0, 1, 0, 0, 0, 1};
152 }
153 
154 
duplicate() const155 Fill* Fill::duplicate() const noexcept
156 {
157     return pImpl->duplicate();
158 }
159 
160 
identifier() const161 TVG_DEPRECATED uint32_t Fill::identifier() const noexcept
162 {
163     return (uint32_t) type();
164 }
165 
166 
RadialGradient()167 RadialGradient::RadialGradient():pImpl(new Impl())
168 {
169     Fill::pImpl->method(new FillDup<RadialGradient::Impl>(pImpl));
170 }
171 
172 
~RadialGradient()173 RadialGradient::~RadialGradient()
174 {
175     delete(pImpl);
176 }
177 
178 
radial(float cx,float cy,float r)179 Result RadialGradient::radial(float cx, float cy, float r) noexcept
180 {
181     return pImpl->radial(cx, cy, r, cx, cy, 0.0f);
182 }
183 
184 
radial(float * cx,float * cy,float * r) const185 Result RadialGradient::radial(float* cx, float* cy, float* r) const noexcept
186 {
187     if (cx) *cx = pImpl->cx;
188     if (cy) *cy = pImpl->cy;
189     if (r) *r = pImpl->r;
190 
191     return Result::Success;
192 }
193 
194 
gen()195 unique_ptr<RadialGradient> RadialGradient::gen() noexcept
196 {
197     return unique_ptr<RadialGradient>(new RadialGradient);
198 }
199 
200 
identifier()201 TVG_DEPRECATED uint32_t RadialGradient::identifier() noexcept
202 {
203     return (uint32_t) Type::RadialGradient;
204 }
205 
206 
type() const207 Type RadialGradient::type() const noexcept
208 {
209     return Type::RadialGradient;
210 }
211 
212 
LinearGradient()213 LinearGradient::LinearGradient():pImpl(new Impl())
214 {
215     Fill::pImpl->method(new FillDup<LinearGradient::Impl>(pImpl));
216 }
217 
218 
~LinearGradient()219 LinearGradient::~LinearGradient()
220 {
221     delete(pImpl);
222 }
223 
224 
linear(float x1,float y1,float x2,float y2)225 Result LinearGradient::linear(float x1, float y1, float x2, float y2) noexcept
226 {
227     pImpl->x1 = x1;
228     pImpl->y1 = y1;
229     pImpl->x2 = x2;
230     pImpl->y2 = y2;
231 
232     return Result::Success;
233 }
234 
235 
linear(float * x1,float * y1,float * x2,float * y2) const236 Result LinearGradient::linear(float* x1, float* y1, float* x2, float* y2) const noexcept
237 {
238     if (x1) *x1 = pImpl->x1;
239     if (x2) *x2 = pImpl->x2;
240     if (y1) *y1 = pImpl->y1;
241     if (y2) *y2 = pImpl->y2;
242 
243     return Result::Success;
244 }
245 
246 
gen()247 unique_ptr<LinearGradient> LinearGradient::gen() noexcept
248 {
249     return unique_ptr<LinearGradient>(new LinearGradient);
250 }
251 
252 
identifier()253 TVG_DEPRECATED uint32_t LinearGradient::identifier() noexcept
254 {
255     return (uint32_t) Type::LinearGradient;
256 }
257 
258 
type() const259 Type LinearGradient::type() const noexcept
260 {
261     return Type::LinearGradient;
262 }
263 
264 #endif /* LV_USE_THORVG_INTERNAL */
265 
266