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 "dashing.h"
16 #include <native_drawing/drawing_brush.h>
17 #include <native_drawing/drawing_color.h>
18 #include <native_drawing/drawing_matrix.h>
19 #include <native_drawing/drawing_path.h>
20 #include <native_drawing/drawing_pen.h>
21 #include <native_drawing/drawing_point.h>
22 #include <native_drawing/drawing_path_effect.h>
23 #include <native_drawing/drawing_rect.h>
24 #include <native_drawing/drawing_round_rect.h>
25 #include <native_drawing/drawing_round_rect.h>
26 #include <native_drawing/drawing_shader_effect.h>
27 #include "common/log_common.h"
28 #include "test_common.h"
29 
30 enum {
31     K_W = 640,
32     K_H = 340,
33 };
34 
drawline(OH_Drawing_Canvas * canvas,int on,int off,OH_Drawing_Pen * pen,Dashings dashings)35 static void drawline(OH_Drawing_Canvas *canvas, int on, int off, OH_Drawing_Pen *pen, Dashings dashings)
36 {
37     float intervals[] = {
38         float(on),
39         float(off),
40     };
41     OH_Drawing_PathEffect *effect = OH_Drawing_CreateDashPathEffect(intervals, 2, dashings.phase);
42     OH_Drawing_PenSetPathEffect(pen, effect);
43     OH_Drawing_CanvasAttachPen(canvas, pen);
44     OH_Drawing_CanvasDrawLine(canvas, dashings.startX, dashings.startY, dashings.finalX, dashings.finalY);
45     OH_Drawing_CanvasDetachPen(canvas);
46     OH_Drawing_PathEffectDestroy(effect);
47 }
48 
show_zero_len_dash(OH_Drawing_Canvas * canvas)49 static void show_zero_len_dash(OH_Drawing_Canvas *canvas)
50 {
51     Dashings dashings;
52     dashings.finalX = (0);
53     OH_Drawing_Pen *pen = OH_Drawing_PenCreate();
54     drawline(canvas, 2, 2, pen, dashings); // 2, 2int on, int off
55     float width = 2;
56     OH_Drawing_PenSetWidth(pen, width);
57     OH_Drawing_CanvasTranslate(canvas, 0, 20); // 0, 20平移坐标
58     drawline(canvas, 4, 4, pen, dashings);     // 4, 4int on, int off
59     OH_Drawing_PenDestroy(pen);
60 }
61 
show_giant_dash(OH_Drawing_Canvas * canvas)62 static void show_giant_dash(OH_Drawing_Canvas *canvas)
63 {
64     Dashings dashings;
65     dashings.finalX = (20 * 1000); // 20, 1000 int on, int off
66     OH_Drawing_Pen *pen = OH_Drawing_PenCreate();
67     drawline(canvas, 1, 1, pen, dashings); // 1,20, 1000 int on, int off
68     OH_Drawing_PenDestroy(pen);
69 }
70 
Dashing()71 Dashing::Dashing()
72 {
73     // file gm/dashing.cpp
74     bitmapWidth_ = K_W;
75     bitmapHeight_ = K_H;
76     fileName_ = "dashing";
77 }
78 
~Dashing()79 Dashing::~Dashing() {}
80 
OnTestFunction(OH_Drawing_Canvas * canvas)81 void Dashing::OnTestFunction(OH_Drawing_Canvas *canvas)
82 {
83     Dashings dashings;
84     OH_Drawing_Pen *pen = OH_Drawing_PenCreate();
85     OH_Drawing_CanvasTranslate(canvas, 20, 20); // 20, 20平移坐标
86     OH_Drawing_CanvasTranslate(canvas, 0, 0.5); // 0, 0.5平移坐标
87     struct Intervals {
88         int fOnInterval;
89         int fOffInterval;
90     };
91     for (int width = 0; width <= 2; ++width) { // 2宽度
92         for (const Intervals &data : { Intervals { 1, 1 }, Intervals { 4, 1 } }) {
93             for (bool aa : { false, true }) {
94                 int w = width * width * width;
95                 OH_Drawing_PenSetAntiAlias(pen, aa);
96                 OH_Drawing_PenSetWidth(pen, w);
97                 int scale = w ? w : 1;
98                 drawline(canvas, data.fOnInterval * scale, data.fOffInterval * scale, pen, dashings);
99                 OH_Drawing_CanvasTranslate(canvas, 0, 20); // 0, 20平移坐标
100             }
101         }
102     }
103     show_giant_dash(canvas);
104     OH_Drawing_CanvasTranslate(canvas, 0, 20); // 0, 20平移坐标
105     show_zero_len_dash(canvas);
106     OH_Drawing_CanvasTranslate(canvas, 0, 20); // 0, 20平移坐标
107     OH_Drawing_PenSetWidth(pen, 8);            // 8宽度
108     drawline(canvas, 0, 0, pen, dashings);
109     OH_Drawing_CanvasDetachPen(canvas);
110     OH_Drawing_PenDestroy(pen);
111 }
112 
make_path_line(OH_Drawing_Path * path,DrawRect rect)113 void make_path_line(OH_Drawing_Path *path, DrawRect rect)
114 {
115     OH_Drawing_PathMoveTo(path, rect.left, rect.top);
116     OH_Drawing_PathLineTo(path, rect.right, rect.bottom);
117 }
118 
make_path_rect(OH_Drawing_Path * path,DrawRect rect)119 void make_path_rect(OH_Drawing_Path *path, DrawRect rect)
120 {
121     OH_Drawing_PathAddRect(path, rect.left, rect.top, rect.right, rect.bottom,
122         OH_Drawing_PathDirection::PATH_DIRECTION_CW);
123 }
124 
make_path_oval(OH_Drawing_Path * path,DrawRect rect)125 void make_path_oval(OH_Drawing_Path *path, DrawRect rect)
126 {
127     OH_Drawing_PathAddOvalWithInitialPoint(path, OH_Drawing_RectCreate(rect.left, rect.top, rect.right, rect.bottom),
128         45, // 45正方形
129         OH_Drawing_PathDirection::PATH_DIRECTION_CW);
130 }
131 
make_path_star(OH_Drawing_Path * path,DrawRect rect)132 void make_path_star(OH_Drawing_Path *path, DrawRect rect)
133 {
134     int n = 5; // star corner count
135     float rad = -M_PI_2;
136     const float drad = (n >> 1) * M_PI * 2 / n;
137 
138     DrawRect r = { 0, 0, 0, 0 };
139     OH_Drawing_PathMoveTo(path, 0, -1.0);
140     DrawPathGetBound(r, 0, -1.0);
141     for (int i = 1; i < n; i++) {
142         rad += drad;
143         OH_Drawing_PathLineTo(path, cos(rad), sin(rad));
144         DrawPathGetBound(r, cos(rad), sin(rad));
145     }
146     OH_Drawing_PathClose(path);
147     OH_Drawing_Matrix *m = OH_Drawing_MatrixCreate();
148     OH_Drawing_MatrixSetRectToRect(m, DrawCreateRect(r), DrawCreateRect(rect),
149         OH_Drawing_ScaleToFit::SCALE_TO_FIT_CENTER);
150     OH_Drawing_PathTransform(path, m);
151 }
152 
Dashing2()153 Dashing2::Dashing2()
154 {
155     // file gm/fontregen.cpp
156     bitmapWidth_ = 640;  // 640宽度
157     bitmapHeight_ = 480; // 480高度
158     fileName_ = "dashing2";
159 }
160 
~Dashing2()161 Dashing2::~Dashing2() {}
162 
OnTestFunction(OH_Drawing_Canvas * canvas)163 void Dashing2::OnTestFunction(OH_Drawing_Canvas *canvas)
164 {
165     constexpr int gIntervals[] = {
166         3, // 3 dashes: each count [0] followed by intervals [1..count]
167         2, 10, 10,
168         4, 20, 5, 5, 5,
169         2, 2, 2
170     };
171 
172     void (*gProc[])(OH_Drawing_Path * path, DrawRect rect) = {
173         make_path_line,
174         make_path_rect,
175         make_path_oval,
176         make_path_star,
177     };
178     OH_Drawing_Pen *pen = OH_Drawing_PenCreate();
179     OH_Drawing_PenSetAntiAlias(pen, true);
180     OH_Drawing_PenSetWidth(pen, 6.0); // 6.0 宽度
181 
182     DrawRect bounds = { 0, 0, 120, 120 };
183     bounds.Offset(20, 20); // 20 坐标
184     float dx = bounds.Width() * 4.0 / 3;
185     float dy = bounds.Height() * 4.0 / 3;
186 
187     const int *intervals = &gIntervals[1];
188     for (int y = 0; y < gIntervals[0]; ++y) {
189         float vals[sizeof(gIntervals) / sizeof(int)];
190         int count = *intervals++;
191         for (int i = 0; i < count; ++i) {
192             vals[i] = *intervals++;
193         }
194         float phase = vals[0] / 2;
195         OH_Drawing_PathEffect *dasheffect = OH_Drawing_CreateDashPathEffect(vals, count, phase);
196         OH_Drawing_PenSetPathEffect(pen, dasheffect);
197         OH_Drawing_CanvasAttachPen(canvas, pen);
198 
199         for (size_t x = 0; x < sizeof(gProc) / sizeof(gProc[0]); ++x) {
200             OH_Drawing_Path *path = OH_Drawing_PathCreate();
201             DrawRect r = bounds;
202             r.Offset(x * dx, y * dy);
203             gProc[x](path, r);
204             OH_Drawing_CanvasDrawPath(canvas, path);
205             OH_Drawing_PathDestroy(path);
206         }
207     }
208 }
209 
Dashing4()210 Dashing4::Dashing4()
211 {
212     // file gm/fontregen.cpp
213     bitmapWidth_ = 640;   // 640宽度
214     bitmapHeight_ = 1100; // 1100高度
215     fileName_ = "dashing4";
216 }
217 
~Dashing4()218 Dashing4::~Dashing4() {}
219 
DashingNum(OH_Drawing_Canvas * canvas,OH_Drawing_Pen * pen)220 void Dashing4::DashingNum(OH_Drawing_Canvas *canvas, OH_Drawing_Pen *pen)
221 {
222     struct Intervals {
223         int fOnInterval;
224         int fOffInterval;
225     };
226     Dashings dashings;
227     for (int width = 0; width <= 2; ++width) { // 2 max
228         for (const Intervals &data : { Intervals { 1, 1 }, Intervals { 4, 2 }, Intervals { 0, 4 } }) {
229             // test for zero length on interval.zero length intervals should draw.a line of squares or circles
230             for (bool aa : { false, true }) {
231                 for (auto cap : { LINE_ROUND_CAP, LINE_SQUARE_CAP }) {
232                     int w = width * width * width;
233                     OH_Drawing_PenSetAntiAlias(pen, aa);
234                     OH_Drawing_PenSetWidth(pen, w);
235                     OH_Drawing_PenSetCap(pen, cap);
236                     int scale = w ? w : 1;
237 
238                     drawline(canvas, data.fOnInterval * scale, data.fOffInterval * scale, pen, dashings);
239                     OH_Drawing_CanvasTranslate(canvas, 0, 20); // 0, 20平移坐标
240                 }
241             }
242         }
243     }
244 }
245 
DashingTow(OH_Drawing_Canvas * canvas,OH_Drawing_Pen * pen)246 void Dashing4::DashingTow(OH_Drawing_Canvas *canvas, OH_Drawing_Pen *pen)
247 {
248     for (int aa = 0; aa <= 1; ++aa) {
249         OH_Drawing_PenSetAntiAlias(pen, aa);
250         OH_Drawing_PenSetWidth(pen, 8.f);
251         OH_Drawing_PenSetCap(pen, LINE_SQUARE_CAP);
252         // Single dash element that is cut off at start and end
253         {
254             Dashings dashings;
255             dashings.finalX = 20.0;                    // 20.0 坐标
256             dashings.phase = 5.0;                      // 5.0 坐标
257             drawline(canvas, 32, 16, pen, dashings);   // canvas, 32, 16, pen, 20.0, 0, 5.0 画线
258             OH_Drawing_CanvasTranslate(canvas, 0, 20); // 0, 20平移坐标
259         }
260 
261         {
262             Dashings dashings;
263             dashings.finalX = 56.0;                    // 56.0 坐标
264             dashings.phase = 5.0;                      // 5.0 坐标
265             // Two dash elements where each one is cut off at beginning and end respectively
266             drawline(canvas, 32, 16, pen, dashings);   // canvas, 32, 16, pen, 56.0, 0, 5.0 画线
267         }
268 
269         {
270             Dashings dashings;
271             OH_Drawing_CanvasTranslate(canvas, 0, 20); // 0, 20平移坐标
272             dashings.finalX = 584.0;                   // 584.0 坐标
273             dashings.phase = 5.0;                      // 5.0 坐标
274             // Many dash elements where first and last are cut off at beginning and end respectively
275             drawline(canvas, 32, 16, pen, dashings);   // canvas, 32, 16, pen, 584.0, 0, 5.0 画线
276             OH_Drawing_CanvasTranslate(canvas, 0, 20); // 0, 20平移坐标
277         }
278 
279         {
280             Dashings dashings;
281             // Diagonal dash line where src pnts are not axis aligned (as apposed to being diagonal from
282             // a canvas rotation)
283             dashings.finalX = 600.0;                   // 600.0 坐标
284             dashings.finalY = 30.0;                    // 30.0 坐标
285             drawline(canvas, 32, 16, pen, dashings);   // canvas, 32, 16, pen, 600.0, 30.0 画线
286             OH_Drawing_CanvasTranslate(canvas, 0, 20); // 0, 20平移坐标
287         }
288 
289         {
290             Dashings dashings;
291             dashings.finalX = 8.0;                     // 8.0 坐标
292             dashings.finalY = 0.0;
293             dashings.phase = 40.0; // 40.0 坐标
294             // Case where only the off interval exists on the line. Thus nothing should be drawn
295             drawline(canvas, 32, 16, pen, dashings);   // canvas, 32, 16, pen, 8.0, 0.0, 40.0 画线
296             OH_Drawing_CanvasTranslate(canvas, 0, 20); // 0, 20平移坐标
297         }
298     }
299 }
300 
DashingThree(OH_Drawing_Canvas * canvas,OH_Drawing_Pen * pen)301 void Dashing4::DashingThree(OH_Drawing_Canvas *canvas, OH_Drawing_Pen *pen)
302 {
303     {
304         Dashings dashings;
305         OH_Drawing_CanvasTranslate(canvas, 5, 20); // 5, 20平移坐标
306         OH_Drawing_PenSetAntiAlias(pen, true);
307         OH_Drawing_PenSetCap(pen, LINE_ROUND_CAP);
308         OH_Drawing_PenSetColor(pen, 0x44000000);
309         OH_Drawing_PenSetWidth(pen, 40);        // 40宽度
310         drawline(canvas, 0, 30, pen, dashings); // 0, 30 int on, int off
311     }
312 
313     {
314         Dashings dashings;
315         OH_Drawing_CanvasTranslate(canvas, 0, 50); // 0, 50平移坐标
316         OH_Drawing_PenSetCap(pen, LINE_SQUARE_CAP);
317         drawline(canvas, 0, 30, pen, dashings); // 0, 30 int on, int off
318     }
319 
320     {
321         Dashings dashings;
322         // Test we draw the cap when the line length is zero.
323         OH_Drawing_CanvasTranslate(canvas, 0, 50); // 0, 50平移坐标
324         OH_Drawing_PenSetCap(pen, LINE_ROUND_CAP);
325         OH_Drawing_PenSetColor(pen, 0xFF000000);
326         OH_Drawing_PenSetWidth(pen, 11); // 11宽度
327         dashings.finalX = 0.0;
328         drawline(canvas, 0, 30, pen, dashings); // 0, 30 int on, int off
329     }
330 
331     {
332         Dashings dashings;
333         dashings.finalX = 0.0;
334         OH_Drawing_CanvasTranslate(canvas, 100, 0); // 100, 0平移坐标
335         drawline(canvas, 1, 30, pen, dashings);     // 1, 30 int on, int off
336     }
337 }
338 
OnTestFunction(OH_Drawing_Canvas * canvas)339 void Dashing4::OnTestFunction(OH_Drawing_Canvas *canvas)
340 {
341     OH_Drawing_Pen *pen = OH_Drawing_PenCreate();
342     OH_Drawing_CanvasTranslate(canvas, 20, 20);   // 20, 20平移坐标
343     OH_Drawing_CanvasTranslate(canvas, 0.5, 0.5); // 0.5, 0.5平移坐标
344     DashingNum(canvas, pen);
345     DashingTow(canvas, pen);
346     DashingThree(canvas, pen);
347     OH_Drawing_PenDestroy(pen);
348 }