1 /*
2 * Copyright (c) 2021-2024 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16 #include "drawing_pen.h"
17
18 #include "drawing_canvas_utils.h"
19 #include "drawing_helper.h"
20
21 #include "draw/pen.h"
22
23 using namespace OHOS;
24 using namespace Rosen;
25 using namespace Drawing;
26
CastToMatrix(const OH_Drawing_Matrix * cMatrix)27 static const Matrix* CastToMatrix(const OH_Drawing_Matrix* cMatrix)
28 {
29 return reinterpret_cast<const Matrix*>(cMatrix);
30 }
31
CastToPath(const OH_Drawing_Path * cPath)32 static const Path* CastToPath(const OH_Drawing_Path* cPath)
33 {
34 return reinterpret_cast<const Path*>(cPath);
35 }
36
CastToPath(OH_Drawing_Path * cPath)37 static Path* CastToPath(OH_Drawing_Path* cPath)
38 {
39 return reinterpret_cast<Path*>(cPath);
40 }
41
CastToPen(OH_Drawing_Pen * cPen)42 static Pen* CastToPen(OH_Drawing_Pen* cPen)
43 {
44 return reinterpret_cast<Pen*>(cPen);
45 }
46
CastToPen(const OH_Drawing_Pen & cPen)47 static const Pen& CastToPen(const OH_Drawing_Pen& cPen)
48 {
49 return reinterpret_cast<const Pen&>(cPen);
50 }
51
CastToRect(const OH_Drawing_Rect * cRect)52 static const Rect* CastToRect(const OH_Drawing_Rect* cRect)
53 {
54 return reinterpret_cast<const Rect*>(cRect);
55 }
56
CastToShaderEffect(OH_Drawing_ShaderEffect * cShaderEffect)57 static ShaderEffect* CastToShaderEffect(OH_Drawing_ShaderEffect* cShaderEffect)
58 {
59 return reinterpret_cast<ShaderEffect*>(cShaderEffect);
60 }
61
CastToFilter(const OH_Drawing_Filter & cFilter)62 static const Filter& CastToFilter(const OH_Drawing_Filter& cFilter)
63 {
64 return reinterpret_cast<const Filter&>(cFilter);
65 }
66
CastToFilter(const OH_Drawing_Filter * cFilter)67 static const Filter* CastToFilter(const OH_Drawing_Filter* cFilter)
68 {
69 return reinterpret_cast<const Filter*>(cFilter);
70 }
71
CapCastToCCap(Pen::CapStyle cap)72 static OH_Drawing_PenLineCapStyle CapCastToCCap(Pen::CapStyle cap)
73 {
74 OH_Drawing_PenLineCapStyle cCap = LINE_FLAT_CAP;
75 switch (cap) {
76 case Pen::CapStyle::FLAT_CAP:
77 cCap = LINE_FLAT_CAP;
78 break;
79 case Pen::CapStyle::SQUARE_CAP:
80 cCap = LINE_SQUARE_CAP;
81 break;
82 case Pen::CapStyle::ROUND_CAP:
83 cCap = LINE_ROUND_CAP;
84 break;
85 default:
86 break;
87 }
88 return cCap;
89 }
90
CCapCastToCap(OH_Drawing_PenLineCapStyle cCap)91 static Pen::CapStyle CCapCastToCap(OH_Drawing_PenLineCapStyle cCap)
92 {
93 Pen::CapStyle cap = Pen::CapStyle::FLAT_CAP;
94 switch (cCap) {
95 case LINE_FLAT_CAP:
96 cap = Pen::CapStyle::FLAT_CAP;
97 break;
98 case LINE_SQUARE_CAP:
99 cap = Pen::CapStyle::SQUARE_CAP;
100 break;
101 case LINE_ROUND_CAP:
102 cap = Pen::CapStyle::ROUND_CAP;
103 break;
104 default:
105 break;
106 }
107 return cap;
108 }
109
OH_Drawing_PenCreate()110 OH_Drawing_Pen* OH_Drawing_PenCreate()
111 {
112 return (OH_Drawing_Pen*)new Pen;
113 }
114
OH_Drawing_PenCopy(OH_Drawing_Pen * cPen)115 OH_Drawing_Pen* OH_Drawing_PenCopy(OH_Drawing_Pen* cPen)
116 {
117 Pen* pen = CastToPen(cPen);
118 if (pen == nullptr) {
119 g_drawingErrorCode = OH_DRAWING_ERROR_INVALID_PARAMETER;
120 return nullptr;
121 }
122 return (OH_Drawing_Pen*)new Pen(*pen);
123 }
124
OH_Drawing_PenDestroy(OH_Drawing_Pen * cPen)125 void OH_Drawing_PenDestroy(OH_Drawing_Pen* cPen)
126 {
127 if (!cPen) {
128 return;
129 }
130 delete CastToPen(cPen);
131 }
132
OH_Drawing_PenIsAntiAlias(const OH_Drawing_Pen * cPen)133 bool OH_Drawing_PenIsAntiAlias(const OH_Drawing_Pen* cPen)
134 {
135 if (cPen == nullptr) {
136 g_drawingErrorCode = OH_DRAWING_ERROR_INVALID_PARAMETER;
137 return false;
138 }
139 return CastToPen(*cPen).IsAntiAlias();
140 }
141
OH_Drawing_PenSetAntiAlias(OH_Drawing_Pen * cPen,bool aa)142 void OH_Drawing_PenSetAntiAlias(OH_Drawing_Pen* cPen, bool aa)
143 {
144 Pen* pen = CastToPen(cPen);
145 if (pen == nullptr) {
146 g_drawingErrorCode = OH_DRAWING_ERROR_INVALID_PARAMETER;
147 return;
148 }
149 pen->SetAntiAlias(aa);
150 }
151
OH_Drawing_PenGetColor(const OH_Drawing_Pen * cPen)152 uint32_t OH_Drawing_PenGetColor(const OH_Drawing_Pen* cPen)
153 {
154 if (cPen == nullptr) {
155 g_drawingErrorCode = OH_DRAWING_ERROR_INVALID_PARAMETER;
156 return 0;
157 }
158 return CastToPen(*cPen).GetColor().CastToColorQuad();
159 }
160
OH_Drawing_PenSetColor(OH_Drawing_Pen * cPen,uint32_t color)161 void OH_Drawing_PenSetColor(OH_Drawing_Pen* cPen, uint32_t color)
162 {
163 Pen* pen = CastToPen(cPen);
164 if (pen == nullptr) {
165 g_drawingErrorCode = OH_DRAWING_ERROR_INVALID_PARAMETER;
166 return;
167 }
168 pen->SetColor(color);
169 }
170
OH_Drawing_PenGetAlpha(const OH_Drawing_Pen * cPen)171 uint8_t OH_Drawing_PenGetAlpha(const OH_Drawing_Pen* cPen)
172 {
173 if (cPen == nullptr) {
174 g_drawingErrorCode = OH_DRAWING_ERROR_INVALID_PARAMETER;
175 return 0;
176 }
177 return CastToPen(*cPen).GetAlpha();
178 }
179
OH_Drawing_PenSetAlpha(OH_Drawing_Pen * cPen,uint8_t alpha)180 void OH_Drawing_PenSetAlpha(OH_Drawing_Pen* cPen, uint8_t alpha)
181 {
182 Pen* pen = CastToPen(cPen);
183 if (pen == nullptr) {
184 g_drawingErrorCode = OH_DRAWING_ERROR_INVALID_PARAMETER;
185 return;
186 }
187 pen->SetAlpha(alpha);
188 }
189
OH_Drawing_PenGetWidth(const OH_Drawing_Pen * cPen)190 float OH_Drawing_PenGetWidth(const OH_Drawing_Pen* cPen)
191 {
192 if (cPen == nullptr) {
193 g_drawingErrorCode = OH_DRAWING_ERROR_INVALID_PARAMETER;
194 return 0.f;
195 }
196 return CastToPen(*cPen).GetWidth();
197 }
198
OH_Drawing_PenSetWidth(OH_Drawing_Pen * cPen,float width)199 void OH_Drawing_PenSetWidth(OH_Drawing_Pen* cPen, float width)
200 {
201 Pen* pen = CastToPen(cPen);
202 if (pen == nullptr) {
203 g_drawingErrorCode = OH_DRAWING_ERROR_INVALID_PARAMETER;
204 return;
205 }
206 pen->SetWidth(width);
207 }
208
OH_Drawing_PenGetMiterLimit(const OH_Drawing_Pen * cPen)209 float OH_Drawing_PenGetMiterLimit(const OH_Drawing_Pen* cPen)
210 {
211 if (cPen == nullptr) {
212 g_drawingErrorCode = OH_DRAWING_ERROR_INVALID_PARAMETER;
213 return 0.f;
214 }
215 return CastToPen(*cPen).GetMiterLimit();
216 }
217
OH_Drawing_PenSetMiterLimit(OH_Drawing_Pen * cPen,float miter)218 void OH_Drawing_PenSetMiterLimit(OH_Drawing_Pen* cPen, float miter)
219 {
220 Pen* pen = CastToPen(cPen);
221 if (pen == nullptr) {
222 g_drawingErrorCode = OH_DRAWING_ERROR_INVALID_PARAMETER;
223 return;
224 }
225 pen->SetMiterLimit(miter);
226 }
227
OH_Drawing_PenGetCap(const OH_Drawing_Pen * cPen)228 OH_Drawing_PenLineCapStyle OH_Drawing_PenGetCap(const OH_Drawing_Pen* cPen)
229 {
230 if (cPen == nullptr) {
231 g_drawingErrorCode = OH_DRAWING_ERROR_INVALID_PARAMETER;
232 return LINE_FLAT_CAP;
233 }
234 Pen::CapStyle cap = CastToPen(*cPen).GetCapStyle();
235 OH_Drawing_PenLineCapStyle cCap = CapCastToCCap(cap);
236 return cCap;
237 }
238
OH_Drawing_PenSetCap(OH_Drawing_Pen * cPen,OH_Drawing_PenLineCapStyle cCap)239 void OH_Drawing_PenSetCap(OH_Drawing_Pen* cPen, OH_Drawing_PenLineCapStyle cCap)
240 {
241 if (cCap < LINE_FLAT_CAP || cCap > LINE_ROUND_CAP) {
242 g_drawingErrorCode = OH_DRAWING_ERROR_PARAMETER_OUT_OF_RANGE;
243 return;
244 }
245 Pen* pen = CastToPen(cPen);
246 if (pen == nullptr) {
247 g_drawingErrorCode = OH_DRAWING_ERROR_INVALID_PARAMETER;
248 return;
249 }
250 Pen::CapStyle cap = CCapCastToCap(cCap);
251 pen->SetCapStyle(cap);
252 }
253
OH_Drawing_PenGetJoin(const OH_Drawing_Pen * cPen)254 OH_Drawing_PenLineJoinStyle OH_Drawing_PenGetJoin(const OH_Drawing_Pen* cPen)
255 {
256 if (cPen == nullptr) {
257 g_drawingErrorCode = OH_DRAWING_ERROR_INVALID_PARAMETER;
258 return LINE_MITER_JOIN;
259 }
260 Pen::JoinStyle join = CastToPen(*cPen).GetJoinStyle();
261 OH_Drawing_PenLineJoinStyle cJoin = static_cast<OH_Drawing_PenLineJoinStyle>(join);
262 return cJoin;
263 }
264
OH_Drawing_PenSetJoin(OH_Drawing_Pen * cPen,OH_Drawing_PenLineJoinStyle cJoin)265 void OH_Drawing_PenSetJoin(OH_Drawing_Pen* cPen, OH_Drawing_PenLineJoinStyle cJoin)
266 {
267 if (cJoin < LINE_MITER_JOIN || cJoin > LINE_BEVEL_JOIN) {
268 g_drawingErrorCode = OH_DRAWING_ERROR_PARAMETER_OUT_OF_RANGE;
269 return;
270 }
271 Pen* pen = CastToPen(cPen);
272 if (pen == nullptr) {
273 g_drawingErrorCode = OH_DRAWING_ERROR_INVALID_PARAMETER;
274 return;
275 }
276 Pen::JoinStyle join = static_cast<Pen::JoinStyle>(cJoin);
277 pen->SetJoinStyle(join);
278 }
279
OH_Drawing_PenSetShaderEffect(OH_Drawing_Pen * cPen,OH_Drawing_ShaderEffect * cShaderEffect)280 void OH_Drawing_PenSetShaderEffect(OH_Drawing_Pen* cPen, OH_Drawing_ShaderEffect* cShaderEffect)
281 {
282 Pen* pen = CastToPen(cPen);
283 if (pen == nullptr) {
284 g_drawingErrorCode = OH_DRAWING_ERROR_INVALID_PARAMETER;
285 return;
286 }
287 if (cShaderEffect == nullptr) {
288 pen->SetShaderEffect(nullptr);
289 return;
290 }
291 pen->SetShaderEffect(std::shared_ptr<ShaderEffect>{CastToShaderEffect(cShaderEffect), [](auto p) {}});
292 }
293
OH_Drawing_PenSetPathEffect(OH_Drawing_Pen * cPen,OH_Drawing_PathEffect * cPathEffect)294 void OH_Drawing_PenSetPathEffect(OH_Drawing_Pen* cPen, OH_Drawing_PathEffect* cPathEffect)
295 {
296 Pen* pen = CastToPen(cPen);
297 if (pen == nullptr) {
298 g_drawingErrorCode = OH_DRAWING_ERROR_INVALID_PARAMETER;
299 return;
300 }
301 if (cPathEffect == nullptr) {
302 pen->SetPathEffect(nullptr);
303 return;
304 }
305 auto pathEffectHandle = Helper::CastTo<OH_Drawing_PathEffect*, NativeHandle<PathEffect>*>(cPathEffect);
306 pen->SetPathEffect(pathEffectHandle->value);
307 }
308
OH_Drawing_PenSetShadowLayer(OH_Drawing_Pen * cPen,OH_Drawing_ShadowLayer * cShadowlayer)309 void OH_Drawing_PenSetShadowLayer(OH_Drawing_Pen* cPen, OH_Drawing_ShadowLayer* cShadowlayer)
310 {
311 Pen* pen = CastToPen(cPen);
312 if (pen == nullptr) {
313 g_drawingErrorCode = OH_DRAWING_ERROR_INVALID_PARAMETER;
314 return;
315 }
316 if (cShadowlayer == nullptr) {
317 pen->SetLooper(nullptr);
318 return;
319 }
320 auto blurDrawLooperHandle = Helper::CastTo<OH_Drawing_ShadowLayer*, NativeHandle<BlurDrawLooper>*>(cShadowlayer);
321 pen->SetLooper(blurDrawLooperHandle->value);
322 }
323
OH_Drawing_PenSetFilter(OH_Drawing_Pen * cPen,OH_Drawing_Filter * cFilter)324 void OH_Drawing_PenSetFilter(OH_Drawing_Pen* cPen, OH_Drawing_Filter* cFilter)
325 {
326 Pen* pen = CastToPen(cPen);
327 if (pen == nullptr) {
328 g_drawingErrorCode = OH_DRAWING_ERROR_INVALID_PARAMETER;
329 return;
330 }
331 if (cFilter == nullptr) {
332 Filter filter;
333 pen->SetFilter(filter);
334 return;
335 }
336 pen->SetFilter(CastToFilter(*cFilter));
337 }
338
OH_Drawing_PenGetFilter(OH_Drawing_Pen * cPen,OH_Drawing_Filter * cFilter)339 void OH_Drawing_PenGetFilter(OH_Drawing_Pen* cPen, OH_Drawing_Filter* cFilter)
340 {
341 Pen* pen = CastToPen(cPen);
342 Filter* filter = const_cast<Filter*>(CastToFilter(cFilter));
343 if (pen == nullptr || filter == nullptr) {
344 g_drawingErrorCode = OH_DRAWING_ERROR_INVALID_PARAMETER;
345 return;
346 }
347 *filter = pen->GetFilter();
348 }
349
OH_Drawing_PenSetBlendMode(OH_Drawing_Pen * cPen,OH_Drawing_BlendMode cBlendMode)350 void OH_Drawing_PenSetBlendMode(OH_Drawing_Pen* cPen, OH_Drawing_BlendMode cBlendMode)
351 {
352 if (cBlendMode < BLEND_MODE_CLEAR || cBlendMode > BLEND_MODE_LUMINOSITY) {
353 g_drawingErrorCode = OH_DRAWING_ERROR_PARAMETER_OUT_OF_RANGE;
354 return;
355 }
356 Pen* pen = CastToPen(cPen);
357 if (pen == nullptr) {
358 g_drawingErrorCode = OH_DRAWING_ERROR_INVALID_PARAMETER;
359 return;
360 }
361 pen->SetBlendMode(static_cast<BlendMode>(cBlendMode));
362 }
363
OH_Drawing_PenGetFillPath(OH_Drawing_Pen * cPen,const OH_Drawing_Path * src,OH_Drawing_Path * dst,const OH_Drawing_Rect * cRect,const OH_Drawing_Matrix * cMatrix)364 bool OH_Drawing_PenGetFillPath(OH_Drawing_Pen* cPen, const OH_Drawing_Path* src, OH_Drawing_Path* dst,
365 const OH_Drawing_Rect* cRect, const OH_Drawing_Matrix* cMatrix)
366 {
367 Pen* pen = CastToPen(cPen);
368 const Path* srcPath = CastToPath(src);
369 Path* dstPath = CastToPath(dst);
370 if (!pen || !srcPath || !dstPath) {
371 g_drawingErrorCode = OH_DRAWING_ERROR_INVALID_PARAMETER;
372 return false;
373 }
374 return pen->GetFillPath(*srcPath, *dstPath, cRect ? CastToRect(cRect): nullptr,
375 cMatrix ? *CastToMatrix(cMatrix) : Matrix());
376 }
377
OH_Drawing_PenReset(OH_Drawing_Pen * cPen)378 void OH_Drawing_PenReset(OH_Drawing_Pen* cPen)
379 {
380 Pen* pen = CastToPen(cPen);
381 if (pen == nullptr) {
382 g_drawingErrorCode = OH_DRAWING_ERROR_INVALID_PARAMETER;
383 return;
384 }
385 pen->Reset();
386 }