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 "conic_paths.h"
16
17 #include <native_drawing/drawing_brush.h>
18 #include <native_drawing/drawing_path.h>
19 #include <native_drawing/drawing_pen.h>
20 #include <native_drawing/drawing_rect.h>
21
22 const float WEIGHT = sqrt(2.0f) / 2; // 2 曲线参数
23
Makepath1()24 void ConicPaths::Makepath1()
25 {
26 OH_Drawing_Path* conicCircle = OH_Drawing_PathCreate();
27 OH_Drawing_PathMoveTo(conicCircle, 0, 0);
28 OH_Drawing_PathConicTo(conicCircle, 0, 50, 50, 50, WEIGHT); // 50曲线
29 OH_Drawing_PathRConicTo(conicCircle, 50, 0, 50, -50, WEIGHT); // 50,-50曲线
30 OH_Drawing_PathRConicTo(conicCircle, 0, -50, -50, -50, WEIGHT); // -50曲线
31 OH_Drawing_PathRConicTo(conicCircle, -50, 0, -50, 50, WEIGHT); // 50,-50曲线
32 fPaths.push_back(conicCircle);
33
34 OH_Drawing_Path* hyperbola = OH_Drawing_PathCreate();
35 OH_Drawing_PathMoveTo(hyperbola, 0, 0);
36 OH_Drawing_PathConicTo(hyperbola, 0, 100, 100, 100, 2); // 100,2曲线
37 fPaths.push_back(hyperbola);
38
39 OH_Drawing_Path* thinHyperbola = OH_Drawing_PathCreate();
40 OH_Drawing_PathMoveTo(thinHyperbola, 0, 0);
41 OH_Drawing_PathConicTo(thinHyperbola, 100, 100, 5, 0, 2); // 100,5,2曲线
42 fPaths.push_back(thinHyperbola);
43
44 OH_Drawing_Path* veryThinHyperbola = OH_Drawing_PathCreate();
45 OH_Drawing_PathMoveTo(veryThinHyperbola, 0, 0);
46 OH_Drawing_PathConicTo(veryThinHyperbola, 100, 100, 1, 0, 2); // 100,1,2曲线
47 fPaths.push_back(veryThinHyperbola);
48
49 OH_Drawing_Path* closedHyperbola = OH_Drawing_PathCreate();
50 OH_Drawing_PathMoveTo(closedHyperbola, 0, 0);
51 OH_Drawing_PathConicTo(closedHyperbola, 100, 100, 0, 0, 2); // 100,2曲线
52 fPaths.push_back(closedHyperbola);
53 }
54
Makepath2()55 void ConicPaths::Makepath2()
56 {
57 OH_Drawing_Path* nearParabola = OH_Drawing_PathCreate();
58 // using 1 as weight defaults to using quadTo
59 OH_Drawing_PathMoveTo(nearParabola, 0, 0);
60 OH_Drawing_PathConicTo(nearParabola, 0, 100, 100, 100, 0.999f); // 0, 100, 100, 100, 0.999f曲线
61 fPaths.push_back(nearParabola);
62
63 OH_Drawing_Path* thinEllipse = OH_Drawing_PathCreate();
64 OH_Drawing_PathMoveTo(thinEllipse, 0, 0);
65 OH_Drawing_PathConicTo(thinEllipse, 100, 100, 5, 0, 0.5f); // 100, 100, 5, 0, 0.5f曲线
66 fPaths.push_back(thinEllipse);
67
68 OH_Drawing_Path* veryThinEllipse = OH_Drawing_PathCreate();
69 OH_Drawing_PathMoveTo(veryThinEllipse, 0, 0);
70 OH_Drawing_PathConicTo(veryThinEllipse, 100, 100, 1, 0, 0.5f); // 100, 100, 1, 0, 0.5f曲线
71 fPaths.push_back(veryThinEllipse);
72
73 OH_Drawing_Path* closedEllipse = OH_Drawing_PathCreate();
74 OH_Drawing_PathMoveTo(closedEllipse, 0, 0);
75 OH_Drawing_PathConicTo(closedEllipse, 100, 100, 0, 0, 0.5f); // 100, 100, 0, 0, 0.5f曲线
76 fPaths.push_back(closedEllipse);
77 }
78
Makepath()79 void ConicPaths::Makepath()
80 {
81 Makepath1();
82 Makepath2();
83 }
84
~ConicPaths()85 ConicPaths::~ConicPaths() {}
86
DrawSence(OH_Drawing_Canvas * canvas,OH_Drawing_Pen * pen,OH_Drawing_Brush * brush,uint8_t a,int p)87 void ConicPaths::DrawSence(OH_Drawing_Canvas* canvas, OH_Drawing_Pen* pen, OH_Drawing_Brush* brush, uint8_t a, int p)
88 {
89 OH_Drawing_Rect* bounds = OH_Drawing_RectCreate(0, 0, 0, 0);
90 for (int aa = 0; aa < 2; ++aa) { // 2 max
91 for (int fh = 0; fh < 2; ++fh) { // 2 max
92 OH_Drawing_PathGetBounds(fPaths[p], bounds);
93 OH_Drawing_CanvasSave(canvas);
94 OH_Drawing_CanvasTranslate(canvas, -OH_Drawing_RectGetLeft(bounds), -OH_Drawing_RectGetTop(bounds));
95 if (fh != 0) {
96 OH_Drawing_PenSetColor(pen, OH_Drawing_ColorSetArgb(a, 0, 0, 0));
97 OH_Drawing_PenSetAntiAlias(pen, (bool)aa);
98 OH_Drawing_CanvasAttachPen(canvas, pen);
99 OH_Drawing_CanvasDrawPath(canvas, fPaths[p]);
100 OH_Drawing_CanvasDetachPen(canvas);
101 } else {
102 OH_Drawing_BrushSetColor(brush, OH_Drawing_ColorSetArgb(a, 0, 0, 0));
103 OH_Drawing_BrushSetAntiAlias(brush, (bool)aa);
104 OH_Drawing_CanvasAttachBrush(canvas, brush);
105 OH_Drawing_CanvasDrawPath(canvas, fPaths[p]);
106 OH_Drawing_CanvasDetachBrush(canvas);
107 }
108 OH_Drawing_CanvasRestore(canvas);
109
110 OH_Drawing_CanvasTranslate(canvas, 110, 0); // 110距离
111 }
112 }
113 OH_Drawing_RectDestroy(bounds);
114 }
115
OnTestFunction(OH_Drawing_Canvas * canvas)116 void ConicPaths::OnTestFunction(OH_Drawing_Canvas* canvas)
117 {
118 constexpr uint8_t kAlphaValue[] = { 0xFF, 0x40 };
119 constexpr float margin = 15;
120 OH_Drawing_CanvasTranslate(canvas, margin, margin);
121
122 Makepath();
123 OH_Drawing_Pen* pen = OH_Drawing_PenCreate();
124 OH_Drawing_Brush* brush = OH_Drawing_BrushCreate();
125
126 for (int p = 0; p < fPaths.size(); ++p) {
127 OH_Drawing_CanvasSave(canvas);
128 DrawSence(canvas, pen, brush, kAlphaValue[0], p);
129 DrawSence(canvas, pen, brush, kAlphaValue[1], p);
130
131 OH_Drawing_CanvasRestore(canvas);
132 OH_Drawing_CanvasTranslate(canvas, 0, 110); // 110距离
133 }
134 OH_Drawing_CanvasRestore(canvas);
135 OH_Drawing_CanvasDetachBrush(canvas);
136
137 // draw fGiantCircle path
138 OH_Drawing_Path* fGiantCircle = OH_Drawing_PathCreate();
139 OH_Drawing_PathMoveTo(fGiantCircle, 2.1e+11f, -1.05e+11f);
140 OH_Drawing_PathConicTo(fGiantCircle, 2.1e+11f, 0, 1.05e+11f, 0, WEIGHT);
141 OH_Drawing_PathConicTo(fGiantCircle, 0, 0, 0, -1.05e+11f, WEIGHT);
142 OH_Drawing_PathConicTo(fGiantCircle, 0, -2.1e+11f, 1.05e+11f, -2.1e+11f, WEIGHT);
143 OH_Drawing_PathConicTo(fGiantCircle, 2.1e+11f, -2.1e+11f, 2.1e+11f, -1.05e+11f, WEIGHT);
144 OH_Drawing_CanvasAttachPen(canvas, pen);
145 OH_Drawing_CanvasDrawPath(canvas, fGiantCircle);
146
147 OH_Drawing_CanvasDetachPen(canvas);
148 OH_Drawing_PenDestroy(pen);
149 OH_Drawing_BrushDestroy(brush);
150
151 OH_Drawing_PathDestroy(fGiantCircle);
152 for (int f = 0; f < fPaths.size(); ++f) {
153 OH_Drawing_PathDestroy(fPaths[f]);
154 }
155 fPaths.clear();
156 }
157