1/*
2 * Copyright (c) 2020-2021 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 "gfx_utils/diagram/common/paint.h"
17namespace OHOS {
18void Paint::InitDash(const Paint& paint)
19{
20#if defined(GRAPHIC_ENABLE_DASH_GENERATE_FLAG) && GRAPHIC_ENABLE_DASH_GENERATE_FLAG
21    if (isDashMode_ && ndashes_ > 0) {
22        dashArray_ = new float[ndashes_];
23        if (dashArray_) {
24            if (memset_s(dashArray_, ndashes_ * sizeof(float), 0, ndashes_ * sizeof(float)) != EOF) {
25            }
26            for (uint32_t i = 0; i < ndashes_; i++) {
27                dashArray_[i] = paint.dashArray_[i];
28            }
29        } else {
30            ndashes_ = 0;
31            dashOffset_ = 0;
32            isDashMode_ = false;
33        }
34    } else {
35        dashArray_ = nullptr;
36    }
37#endif
38}
39
40/*
41 * Initialize data members.
42 * style_:       paint style.
43 * fillColor_:   Sets the fill color of the pen.
44 * strokeColor_: Sets the line color of the pen.
45 * opacity_:     Set transparency.
46 * strokeWidth_: Set lineweight.
47 * lineCap_:     Set pen cap.
48 * lineJoin_:    Sets the style at the path connection of the pen.
49 * miterLimit_:  Sets the spacing limit for sharp corners at path connections.
50 * dashOffset:   dash Point offset.
51 * isDrawDash:   Whether to draw dotted line.
52 * dashArray:    dash Point group.
53 * ndashes:      Number of dotted lines.
54 * globalAlpha:  Set element Global alpha.
55 * shadowBlurRadius:  Sets the shadow blur radius.
56 * shadowOffsetX:     Sets the abscissa offset of the shadow.
57 * shadowOffsetY:     Sets the shadow ordinate offset.
58 * shadowColor:       Set shadow color.
59 */
60void Paint::Init(const Paint& paint)
61{
62    style_ = paint.style_;
63    fillColor_ = paint.fillColor_;
64    strokeColor_ = paint.strokeColor_;
65    strokeWidth_ = paint.strokeWidth_;
66    opacity_ = paint.opacity_;
67#if defined(GRAPHIC_ENABLE_LINECAP_FLAG) && GRAPHIC_ENABLE_LINECAP_FLAG
68    lineCap_ = paint.lineCap_;
69#endif
70#if defined(GRAPHIC_ENABLE_LINEJOIN_FLAG) && GRAPHIC_ENABLE_LINEJOIN_FLAG
71    lineJoin_ = paint.lineJoin_;
72#endif
73#if defined(GRAPHIC_ENABLE_DASH_GENERATE_FLAG) && GRAPHIC_ENABLE_DASH_GENERATE_FLAG
74    isDashMode_ = paint.isDashMode_;
75    dashOffset_ = paint.dashOffset_;
76    dashArray_ = paint.dashArray_;
77    ndashes_ = paint.ndashes_;
78#endif
79    changeFlag_ = paint.changeFlag_;
80    scaleRadioX_ = paint.scaleRadioX_;
81    scaleRadioY_ = paint.scaleRadioY_;
82    translationX_ = paint.translationX_;
83    translationY_ = paint.translationY_;
84    InitDash(paint);
85#if defined(GRAPHIC_ENABLE_LINEJOIN_FLAG) && GRAPHIC_ENABLE_LINEJOIN_FLAG
86    miterLimit_ = paint.miterLimit_;
87#endif
88#if defined(GRAPHIC_ENABLE_GRADIENT_FILL_FLAG) && GRAPHIC_ENABLE_GRADIENT_FILL_FLAG
89    linearGradientPoint_ = paint.linearGradientPoint_;
90    radialGradientPoint_ = paint.radialGradientPoint_;
91    stopAndColors_ = paint.stopAndColors_;
92    gradientflag_ = paint.gradientflag_;
93#endif
94#if defined(GRAPHIC_ENABLE_PATTERN_FILL_FLAG) && GRAPHIC_ENABLE_PATTERN_FILL_FLAG
95    patternRepeat_ = paint.patternRepeat_;
96#endif
97#if defined(GRAPHIC_ENABLE_SHADOW_EFFECT_FLAG) && GRAPHIC_ENABLE_SHADOW_EFFECT_FLAG
98    shadowBlurRadius_ = paint.shadowBlurRadius_;
99    shadowOffsetX_ = paint.shadowOffsetX_;
100    shadowOffsetY_ = paint.shadowOffsetY_;
101    shadowColor_ = paint.shadowColor_;
102    haveShadow_ = paint.haveShadow_;
103#endif
104    globalAlpha_ = paint.globalAlpha_;
105    globalCompositeOperation_ = paint.globalCompositeOperation_;
106    rotateAngle_ = paint.rotateAngle_;
107    transfrom_ = paint.transfrom_;
108    haveComposite_ = paint.haveComposite_;
109}
110
111void Paint::SetStrokeStyle(ColorType color)
112{
113    SetStyle(Paint::STROKE_STYLE);
114    SetStrokeColor(color);
115}
116
117void Paint::SetFillStyle(ColorType color)
118{
119    SetStyle(Paint::FILL_STYLE);
120    SetFillColor(color);
121}
122
123void Paint::SetStrokeColor(ColorType color)
124{
125    strokeColor_ = color;
126    changeFlag_ = true;
127}
128
129void Paint::SetFillColor(ColorType color)
130{
131    fillColor_ = color;
132    changeFlag_ = true;
133}
134
135#if defined(GRAPHIC_ENABLE_LINECAP_FLAG) && GRAPHIC_ENABLE_LINECAP_FLAG
136void Paint::SetLineCap(LineCap lineCap)
137{
138    lineCap_ = lineCap;
139    changeFlag_ = true;
140}
141#endif
142
143#if defined(GRAPHIC_ENABLE_LINEJOIN_FLAG) && GRAPHIC_ENABLE_LINEJOIN_FLAG
144void Paint::SetLineJoin(LineJoin lineJoin)
145{
146    lineJoin_ = lineJoin;
147    changeFlag_ = true;
148}
149#endif
150
151#if defined(GRAPHIC_ENABLE_LINEJOIN_FLAG) && GRAPHIC_ENABLE_LINEJOIN_FLAG
152void Paint::SetMiterLimit(float miterLimit)
153{
154    miterLimit_ = miterLimit;
155    changeFlag_ = true;
156}
157#endif
158
159#if defined(GRAPHIC_ENABLE_DASH_GENERATE_FLAG) && GRAPHIC_ENABLE_DASH_GENERATE_FLAG
160void Paint::SetLineDash(float* lineDashs, const uint32_t ndash)
161{
162    ClearLineDash();
163    if (lineDashs == nullptr || ndash == 0) {
164        return;
165    }
166    ndashes_ = ndash;
167    isDashMode_ = true;
168    dashArray_ = new float[ndashes_];
169    if (dashArray_) {
170        if (memset_s(dashArray_, ndashes_ * sizeof(float), 0, ndashes_ * sizeof(float)) != EOF) {
171        }
172        for (uint32_t iIndex = 0; iIndex < ndashes_; iIndex++) {
173            dashArray_[iIndex] = lineDashs[iIndex];
174        }
175    } else {
176        ndashes_ = 0;
177        dashOffset_ = 0;
178        isDashMode_ = false;
179    }
180    changeFlag_ = true;
181}
182
183void Paint::SetLineDashOffset(float offset)
184{
185    dashOffset_ = offset;
186    changeFlag_ = true;
187    isDashMode_ = true;
188}
189
190void Paint::ClearLineDash(void)
191{
192    dashOffset_ = 0;
193    ndashes_ = 0;
194    isDashMode_ = false;
195    if (dashArray_ != nullptr) {
196        delete[] dashArray_;
197        dashArray_ = nullptr;
198    }
199}
200#endif
201
202#if defined(GRAPHIC_ENABLE_GRADIENT_FILL_FLAG) && GRAPHIC_ENABLE_GRADIENT_FILL_FLAG
203void Paint::createLinearGradient(float startx, float starty, float endx, float endy)
204{
205    gradientflag_ = Linear;
206    linearGradientPoint_.x0 = startx;
207    linearGradientPoint_.y0 = starty;
208    linearGradientPoint_.x1 = endx;
209    linearGradientPoint_.y1 = endy;
210    changeFlag_ = true;
211}
212
213void Paint::addColorStop(float stop, ColorType color)
214{
215    StopAndColor stopAndColor;
216    stopAndColor.stop = stop;
217    stopAndColor.color = color;
218    stopAndColors_.PushBack(stopAndColor);
219}
220
221void Paint::createRadialGradient(float start_x, float start_y, float start_r, float end_x, float end_y, float end_r)
222{
223    gradientflag_ = Radial;
224    radialGradientPoint_.x0 = start_x;
225    radialGradientPoint_.y0 = start_y;
226    radialGradientPoint_.r0 = start_r;
227    radialGradientPoint_.x1 = end_x;
228    radialGradientPoint_.y1 = end_y;
229    radialGradientPoint_.r1 = end_r;
230    changeFlag_ = true;
231}
232#endif
233
234#if defined(GRAPHIC_ENABLE_PATTERN_FILL_FLAG) && GRAPHIC_ENABLE_PATTERN_FILL_FLAG
235void Paint::CreatePattern(const char* img, PatternRepeatMode patternRepeat)
236{
237    image_ = img;
238    patternRepeat_ = patternRepeat;
239    changeFlag_ = true;
240}
241#endif
242
243#if defined(GRAPHIC_ENABLE_SHADOW_EFFECT_FLAG) && GRAPHIC_ENABLE_SHADOW_EFFECT_FLAG
244void Paint::SetShadowBlur(uint16_t radius)
245{
246    shadowBlurRadius_ = radius;
247    changeFlag_ = true;
248}
249
250void Paint::SetShadowOffsetX(float offset)
251{
252    shadowOffsetX_ = offset;
253    changeFlag_ = true;
254}
255
256void Paint::SetShadowOffsetY(float offset)
257{
258    shadowOffsetY_ = offset;
259    changeFlag_ = true;
260}
261
262void Paint::SetShadowColor(ColorType color)
263{
264    shadowColor_ = color;
265    changeFlag_ = true;
266    haveShadow_ = true;
267}
268#endif
269
270void Paint::SetGlobalAlpha(float alphaPercentage)
271{
272    if (alphaPercentage > 1) {
273        globalAlpha_ = 1.0;
274        return;
275    }
276    if (alphaPercentage < 0) {
277        globalAlpha_ = 0.0;
278        return;
279    }
280    globalAlpha_ = alphaPercentage;
281    changeFlag_ = true;
282}
283
284void Paint::SetGlobalCompositeOperation(GlobalCompositeOperation globalCompositeOperation)
285{
286    globalCompositeOperation_ = globalCompositeOperation;
287    changeFlag_ = true;
288    if (globalCompositeOperation != SOURCE_OVER) {
289        haveComposite_ = true;
290    }
291}
292
293void Paint::Scale(float scaleX, float scaleY)
294{
295    this->scaleRadioX_ *= scaleX;
296    this->scaleRadioY_ *= scaleX;
297    if (rotateAngle_ > 0.0f || rotateAngle_ < 0) {
298        transfrom_.Rotate(-rotateAngle_ * PI / BOXER);
299        transfrom_.Scale(scaleX, scaleY);
300        transfrom_.Rotate(rotateAngle_ * PI / BOXER);
301    } else {
302        transfrom_.Scale(scaleX, scaleY);
303    }
304    changeFlag_ = true;
305}
306
307void Paint::Rotate(float angle)
308{
309    changeFlag_ = true;
310    transfrom_.Rotate(angle * PI / BOXER);
311    rotateAngle_ += angle;
312}
313
314void Paint::Rotate(float angle, int16_t x, int16_t y)
315{
316    transfrom_.Translate(-x, -y);
317    transfrom_.Rotate(angle * PI / BOXER);
318    rotateAngle_ += angle;
319    transfrom_.Translate(x, y);
320    changeFlag_ = true;
321}
322
323void Paint::Translate(int16_t x, int16_t y)
324{
325    changeFlag_ = true;
326    transfrom_.Translate(x, y);
327    this->translationX_ += x;
328    this->translationY_ += y;
329}
330
331void Paint::SetTransform(float scaleX, float shearX, float shearY,
332                         float scaleY, int16_t transLateX, int16_t transLateY)
333{
334    transfrom_.Reset();
335    rotateAngle_ = 0;
336    Transform(scaleX, shearX, shearY, scaleY, transLateX, transLateY);
337    changeFlag_ = true;
338}
339
340void Paint::Transform(float scaleX, float shearX, float shearY, float scaleY, int16_t transLateX, int16_t transLateY)
341{
342    changeFlag_ = true;
343    this->translationX_ += transLateX;
344    this->translationY_ += transLateY;
345    transLateX += transfrom_.GetData()[2];
346    transLateY += transfrom_.GetData()[5];
347    transfrom_.Translate(-transfrom_.GetData()[2], -transfrom_.GetData()[5]);
348    Scale(scaleX, scaleY);
349    transfrom_.Translate(transLateX, transLateY);
350    transfrom_.SetData(1, transfrom_.GetData()[1] + shearX);
351    transfrom_.SetData(3, transfrom_.GetData()[3] + shearY);
352}
353} // namespace OHOS