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 }