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 }