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