1 /*
2  * Copyright (c) 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 #include "circular_arcs.h"
16 
17 #include <cmath>
18 #include <native_drawing/drawing_brush.h>
19 #include <native_drawing/drawing_color.h>
20 #include <native_drawing/drawing_matrix.h>
21 #include <native_drawing/drawing_path.h>
22 #include <native_drawing/drawing_pen.h>
23 #include <native_drawing/drawing_point.h>
24 #include <native_drawing/drawing_round_rect.h>
25 #include <native_drawing/drawing_shader_effect.h>
26 #include <vector>
27 
28 #include "test_common.h"
29 
30 #include "common/log_common.h"
31 
32 enum {
33     K_W = 820,
34     K_H = 1090,
35 };
36 
CircularArcStrokeMatrix()37 CircularArcStrokeMatrix::CircularArcStrokeMatrix()
38 {
39     // file gm/circulararcs.cpp
40     bitmapWidth_ = K_W;
41     bitmapHeight_ = K_H;
42     fileName_ = "circular_arc_stroke_matrix";
43 }
44 
OnTestFunction(OH_Drawing_Canvas * canvas)45 void CircularArcStrokeMatrix::OnTestFunction(OH_Drawing_Canvas* canvas)
46 {
47     static constexpr float coordinate = 40.f;
48     static constexpr float kStrokeWidth = 5.f;
49     static constexpr float kStart = 89.f;
50     static constexpr float kSweep = 180.f / M_PI; // one radian
51 
52     std::vector<OH_Drawing_Matrix*> matrices = CreateMatrices(coordinate);
53     int baseMatrixCnt = matrices.size();
54     ApplyRotations(matrices, baseMatrixCnt, coordinate);
55     int x = 0;
56     int y = 0;
57     static constexpr float kPad = 2 * kStrokeWidth;
58     OH_Drawing_CanvasTranslate(canvas, kPad, kPad);
59     auto bounds = OH_Drawing_RectCreate(0, 0, 2 * coordinate, 2 * coordinate); // 2cout
60 
61     for (auto cap : { LINE_ROUND_CAP, LINE_FLAT_CAP, LINE_SQUARE_CAP }) {
62         for (const auto m : matrices) {
63             auto pen = OH_Drawing_PenCreate();
64             OH_Drawing_PenSetCap(pen, cap);
65             OH_Drawing_PenSetAntiAlias(pen, true);
66             OH_Drawing_PenSetWidth(pen, kStrokeWidth);
67             OH_Drawing_CanvasSave(canvas);
68             {
69                 OH_Drawing_CanvasTranslate(canvas, x * (2 * coordinate + kPad), y * (2 * coordinate + kPad)); // 2 距离
70                 OH_Drawing_CanvasConcatMatrix(canvas, m);
71                 OH_Drawing_PenSetColor(pen, 0x80FF0000); // red
72                 OH_Drawing_CanvasAttachPen(canvas, pen);
73                 OH_Drawing_CanvasDrawArc(canvas, bounds, kStart, kSweep);
74                 OH_Drawing_PenSetColor(pen, 0x800000FF); // blue
75                 OH_Drawing_CanvasAttachPen(canvas, pen);
76                 OH_Drawing_CanvasDrawArc(canvas, bounds, kStart, kSweep - 360.f); // kSweep - 360.f坐标
77             }
78             OH_Drawing_CanvasRestore(canvas);
79             OH_Drawing_CanvasDetachPen(canvas);
80             OH_Drawing_PenDestroy(pen);
81             ++x;
82             if (x == baseMatrixCnt) {
83                 x = 0;
84                 ++y;
85             }
86         }
87     }
88 
89     for (auto m : matrices) {
90         OH_Drawing_MatrixDestroy(m);
91     }
92     OH_Drawing_RectDestroy(bounds);
93 }
94 
CreateMatrices(float coordinate)95 std::vector<OH_Drawing_Matrix*> CircularArcStrokeMatrix::CreateMatrices(float coordinate)
96 {
97     std::vector<OH_Drawing_Matrix*> matrices;
98 
99     matrices.push_back(OH_Drawing_MatrixCreateRotation(coordinate, coordinate, 45.f));
100 
101     OH_Drawing_Matrix* mI = OH_Drawing_MatrixCreate();
102     OH_Drawing_MatrixSetMatrix(mI, 1, 0, 0, 0, 1, 0, 0, 0, 1); // 1矩阵
103     matrices.push_back(mI);
104 
105     OH_Drawing_Matrix* m1 = OH_Drawing_MatrixCreate();
106     OH_Drawing_MatrixSetMatrix(m1, -1, 0, 2 * coordinate, 0, 1, 0, 0, 0, 1); // -1, 2, 1矩阵
107     OH_Drawing_Matrix* m2 = OH_Drawing_MatrixCreate();
108     OH_Drawing_MatrixSetMatrix(m2, 1, 0, 0, 0, -1, 2 * coordinate, 0, 0, 1); // 1, -1, 2矩阵
109     OH_Drawing_Matrix* m3 = OH_Drawing_MatrixCreate();
110     OH_Drawing_MatrixSetMatrix(m3, 1, 0, 0, 0, -1, 2 * coordinate, 0, 0, 1); // -1, 1, 2矩阵
111     OH_Drawing_Matrix* m4 = OH_Drawing_MatrixCreate();
112     OH_Drawing_MatrixSetMatrix(m4, 0, -1, 2 * coordinate, -1, 0, 2 * coordinate, 0, 0, 1); // 1,-1,2矩阵
113     OH_Drawing_Matrix* m5 = OH_Drawing_MatrixCreate();
114     OH_Drawing_MatrixSetMatrix(m5, 0, -1, 2 * coordinate, 1, 0, 0, 0, 0, 1); // -1,1,2矩阵
115     OH_Drawing_Matrix* m6 = OH_Drawing_MatrixCreate();
116     OH_Drawing_MatrixSetMatrix(m6, 0, 1, 0, 1, 0, 0, 0, 0, 1); // 1矩阵
117     OH_Drawing_Matrix* m7 = OH_Drawing_MatrixCreate();
118     OH_Drawing_MatrixSetMatrix(m7, 0, 1, 0, -1, 0, 2 * coordinate, 0, 0, 1); // -1, 1, 2矩阵
119 
120     matrices.push_back(m1);
121     matrices.push_back(m2);
122     matrices.push_back(m3);
123     matrices.push_back(m4);
124     matrices.push_back(m5);
125     matrices.push_back(m6);
126     matrices.push_back(m7);
127     return matrices;
128 }
129 
ApplyRotations(std::vector<OH_Drawing_Matrix * > & matrices,int baseMatrixCnt,float coordinate)130 void CircularArcStrokeMatrix::ApplyRotations(
131     std::vector<OH_Drawing_Matrix*>& matrices, int baseMatrixCnt, float coordinate)
132 {
133     OH_Drawing_Matrix* tinyCW = OH_Drawing_MatrixCreateRotation(0.001f, coordinate, coordinate); // 0.001f 旋转角度
134     for (int i = 0; i < baseMatrixCnt; ++i) {
135         OH_Drawing_Matrix* mTotal = OH_Drawing_MatrixCreate();
136         OH_Drawing_MatrixConcat(mTotal, matrices[i], tinyCW);
137         matrices.push_back(mTotal);
138     }
139     OH_Drawing_MatrixDestroy(tinyCW);
140 
141     OH_Drawing_Matrix* tinyCCW = OH_Drawing_MatrixCreateRotation(-0.001f, coordinate, coordinate); // -0.001f 旋转角度
142     for (int i = 0; i < baseMatrixCnt; ++i) {
143         OH_Drawing_Matrix* mTotal = OH_Drawing_MatrixCreate();
144         OH_Drawing_MatrixConcat(mTotal, matrices[i], tinyCCW);
145         matrices.push_back(mTotal);
146     }
147     OH_Drawing_MatrixDestroy(tinyCCW);
148 
149     OH_Drawing_Matrix* cw45 = OH_Drawing_MatrixCreateRotation(45.f, coordinate, coordinate); // 45.f 旋转角度
150     for (int i = 0; i < baseMatrixCnt; ++i) {
151         OH_Drawing_Matrix* mTotal = OH_Drawing_MatrixCreate();
152         OH_Drawing_MatrixConcat(mTotal, matrices[i], cw45);
153         matrices.push_back(mTotal);
154     }
155     OH_Drawing_MatrixDestroy(cw45);
156 }