1885b47fbSopenharmony_ci/*
2885b47fbSopenharmony_ci * Copyright (C) 2023 Huawei Device Co., Ltd.
3885b47fbSopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License");
4885b47fbSopenharmony_ci * you may not use this file except in compliance with the License.
5885b47fbSopenharmony_ci * You may obtain a copy of the License at
6885b47fbSopenharmony_ci *
7885b47fbSopenharmony_ci *     http://www.apache.org/licenses/LICENSE-2.0
8885b47fbSopenharmony_ci *
9885b47fbSopenharmony_ci * Unless required by applicable law or agreed to in writing, software
10885b47fbSopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS,
11885b47fbSopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12885b47fbSopenharmony_ci * See the License for the specific language governing permissions and
13885b47fbSopenharmony_ci * limitations under the License.
14885b47fbSopenharmony_ci */
15885b47fbSopenharmony_ci
16885b47fbSopenharmony_ci#include "accessibility_circle_drawing_manager.h"
17885b47fbSopenharmony_ci#ifdef OHOS_BUILD_ENABLE_DISPLAY_MANAGER
18885b47fbSopenharmony_ci#include "accessibility_display_manager.h"
19885b47fbSopenharmony_ci#endif
20885b47fbSopenharmony_ci#include "hilog_wrapper.h"
21885b47fbSopenharmony_ci#include "pipeline/rs_recording_canvas.h"
22885b47fbSopenharmony_ci#include "recording/recording_canvas.h"
23885b47fbSopenharmony_ci
24885b47fbSopenharmony_cinamespace OHOS {
25885b47fbSopenharmony_cinamespace Accessibility {
26885b47fbSopenharmony_ci
27885b47fbSopenharmony_ciconstexpr int32_t DEFAULT_VALUE = -1;
28885b47fbSopenharmony_ci
29885b47fbSopenharmony_ciconstexpr int32_t OUT_CIRCLE_RADIUS = 49; // outer circle
30885b47fbSopenharmony_ciconstexpr int32_t PROGRESS_RADIUS = 46; // progress circle background
31885b47fbSopenharmony_ciconstexpr int32_t CENTER_CIRCLE_RADIUS = 6; // center circle
32885b47fbSopenharmony_ciconstexpr int32_t PROGRESS_STROKE_WIDTH = 2; // progress stroke
33885b47fbSopenharmony_ci
34885b47fbSopenharmony_ciconstexpr int32_t OUT_CIRCLE_BACKGROUND_ALPHA = 64;
35885b47fbSopenharmony_ciconstexpr int32_t PROGRESS_BACKGROUND_ALPHA = 153;
36885b47fbSopenharmony_ciconstexpr int32_t CENTER_CIRCLE_BACKGROUND_ALPHA = 230;
37885b47fbSopenharmony_ciconstexpr int32_t PROGRESS_BAR_BACKGROUND_ALPHA = 230;
38885b47fbSopenharmony_ci
39885b47fbSopenharmony_ciconst std::string PROGRESS_BACKGROUND_COLOR_TYPE = "#0A59F7"; // progress circle background
40885b47fbSopenharmony_ciconst std::string PROGRESS_COLOR_TYPE = "#FFFFFF"; // center circle
41885b47fbSopenharmony_ciconst std::string OUT_CIRCLE_BACKGROUND_COLOR_TYPE = "#1756C4"; // outer circle
42885b47fbSopenharmony_ci
43885b47fbSopenharmony_ciconstexpr int32_t DEFAULT_WIDTH = 500;
44885b47fbSopenharmony_ciconstexpr int32_t DEFAULT_HEIGHT = 500;
45885b47fbSopenharmony_ciconstexpr int32_t DEFAULT_HALF = 2;
46885b47fbSopenharmony_ci
47885b47fbSopenharmony_ciconstexpr int32_t DEFAULT_PIXEL_DENSITY = 160;
48885b47fbSopenharmony_ci
49885b47fbSopenharmony_ciconstexpr int32_t HEXADECIMAL = 16;
50885b47fbSopenharmony_ciconstexpr int32_t DECIMAL = 10;
51885b47fbSopenharmony_ciconstexpr char CHAR_0 = '0';
52885b47fbSopenharmony_ciconstexpr char CHAR_9 = '9';
53885b47fbSopenharmony_ciconstexpr char CHAR_A = 'A';
54885b47fbSopenharmony_ciconstexpr char CHAR_B = 'B';
55885b47fbSopenharmony_ciconstexpr char CHAR_C = 'C';
56885b47fbSopenharmony_ciconstexpr char CHAR_D = 'D';
57885b47fbSopenharmony_ciconstexpr char CHAR_E = 'E';
58885b47fbSopenharmony_ciconstexpr char CHAR_F = 'F';
59885b47fbSopenharmony_ci
60885b47fbSopenharmony_ciconstexpr int32_t COLOR_STRING_LENGTH = 2;
61885b47fbSopenharmony_ciconstexpr int32_t RED_START_INDEX = 1;
62885b47fbSopenharmony_ciconstexpr int32_t GREEN_START_INDEX = 3;
63885b47fbSopenharmony_ciconstexpr int32_t BLUE_START_INDEX = 5;
64885b47fbSopenharmony_ci
65885b47fbSopenharmony_ciconstexpr int32_t NUMBER_0 = 0;
66885b47fbSopenharmony_ciconstexpr int32_t NUMBER_1 = 1;
67885b47fbSopenharmony_ciconstexpr int32_t NUMBER_2 = 2;
68885b47fbSopenharmony_ci
69885b47fbSopenharmony_cistd::shared_ptr<AccessibilityCircleDrawingManager> AccessibilityCircleDrawingManager::pointDrawMgr_ = nullptr;
70885b47fbSopenharmony_ci
71885b47fbSopenharmony_cistd::shared_ptr<AccessibilityCircleDrawingManager> AccessibilityCircleDrawingManager::GetInstance()
72885b47fbSopenharmony_ci{
73885b47fbSopenharmony_ci    HILOG_DEBUG();
74885b47fbSopenharmony_ci    if (pointDrawMgr_ == nullptr) {
75885b47fbSopenharmony_ci        pointDrawMgr_ = std::make_shared<AccessibilityCircleDrawingManager>();
76885b47fbSopenharmony_ci    }
77885b47fbSopenharmony_ci    return pointDrawMgr_;
78885b47fbSopenharmony_ci}
79885b47fbSopenharmony_ci
80885b47fbSopenharmony_civoid AccessibilityCircleDrawingManager::DeleteInstance()
81885b47fbSopenharmony_ci{
82885b47fbSopenharmony_ci    HILOG_DEBUG();
83885b47fbSopenharmony_ci    if (pointDrawMgr_ == nullptr) {
84885b47fbSopenharmony_ci        HILOG_ERROR("surfaceNode_ is nullptr");
85885b47fbSopenharmony_ci        return;
86885b47fbSopenharmony_ci    }
87885b47fbSopenharmony_ci    pointDrawMgr_ = nullptr;
88885b47fbSopenharmony_ci}
89885b47fbSopenharmony_ci
90885b47fbSopenharmony_ciAccessibilityCircleDrawingManager::AccessibilityCircleDrawingManager()
91885b47fbSopenharmony_ci{
92885b47fbSopenharmony_ci    HILOG_DEBUG();
93885b47fbSopenharmony_ci    imageWidth_ = DEFAULT_WIDTH;
94885b47fbSopenharmony_ci    imageHeight_ = DEFAULT_HEIGHT;
95885b47fbSopenharmony_ci    half_ = DEFAULT_WIDTH / DEFAULT_HALF;
96885b47fbSopenharmony_ci
97885b47fbSopenharmony_ci#ifdef OHOS_BUILD_ENABLE_DISPLAY_MANAGER
98885b47fbSopenharmony_ci    AccessibilityDisplayManager &displayMgr = Singleton<AccessibilityDisplayManager>::GetInstance();
99885b47fbSopenharmony_ci    screenId_ = displayMgr.GetDefaultDisplayId(); // default screenId 0
100885b47fbSopenharmony_ci    auto dpi = displayMgr.GetDefaultDisplayDpi();
101885b47fbSopenharmony_ci    dispalyDensity_ = static_cast<float>(dpi) / DEFAULT_PIXEL_DENSITY;
102885b47fbSopenharmony_ci#else
103885b47fbSopenharmony_ci    HILOG_DEBUG("not support display manager");
104885b47fbSopenharmony_ci    screenId_ = 0;
105885b47fbSopenharmony_ci    dispalyDensity_ = 1;
106885b47fbSopenharmony_ci#endif
107885b47fbSopenharmony_ci}
108885b47fbSopenharmony_ci
109885b47fbSopenharmony_ciAccessibilityCircleDrawingManager::~AccessibilityCircleDrawingManager()
110885b47fbSopenharmony_ci{
111885b47fbSopenharmony_ci    HILOG_DEBUG();
112885b47fbSopenharmony_ci    if (surfaceNode_ == nullptr) {
113885b47fbSopenharmony_ci        HILOG_ERROR("surfaceNode_ is nullptr");
114885b47fbSopenharmony_ci        return;
115885b47fbSopenharmony_ci    }
116885b47fbSopenharmony_ci
117885b47fbSopenharmony_ci    surfaceNode_->ClearChildren();
118885b47fbSopenharmony_ci    surfaceNode_->DetachToDisplay(screenId_);
119885b47fbSopenharmony_ci    surfaceNode_ = nullptr;
120885b47fbSopenharmony_ci    canvasNode_ = nullptr;
121885b47fbSopenharmony_ci    Rosen::RSTransaction::FlushImplicitTransaction();
122885b47fbSopenharmony_ci}
123885b47fbSopenharmony_ci
124885b47fbSopenharmony_civoid AccessibilityCircleDrawingManager::UpdatePointerVisible(bool state)
125885b47fbSopenharmony_ci{
126885b47fbSopenharmony_ci    HILOG_DEBUG("state %{public}s", state ? "true" : "false");
127885b47fbSopenharmony_ci    if (surfaceNode_ == nullptr) {
128885b47fbSopenharmony_ci        HILOG_ERROR("surfaceNode_ is nullptr");
129885b47fbSopenharmony_ci        return;
130885b47fbSopenharmony_ci    }
131885b47fbSopenharmony_ci
132885b47fbSopenharmony_ci    surfaceNode_->SetVisible(state);
133885b47fbSopenharmony_ci    Rosen::RSTransaction::FlushImplicitTransaction();
134885b47fbSopenharmony_ci}
135885b47fbSopenharmony_ci
136885b47fbSopenharmony_civoid AccessibilityCircleDrawingManager::CreatePointerWindow(int32_t physicalX, int32_t physicalY, uint64_t screenId)
137885b47fbSopenharmony_ci{
138885b47fbSopenharmony_ci    HILOG_DEBUG();
139885b47fbSopenharmony_ci    Rosen::RSSurfaceNodeConfig surfaceNodeConfig;
140885b47fbSopenharmony_ci    surfaceNodeConfig.SurfaceNodeName = "screen touch progress";
141885b47fbSopenharmony_ci    Rosen::RSSurfaceNodeType surfaceNodeType = Rosen::RSSurfaceNodeType::SELF_DRAWING_WINDOW_NODE;
142885b47fbSopenharmony_ci    surfaceNode_ = Rosen::RSSurfaceNode::Create(surfaceNodeConfig, surfaceNodeType);
143885b47fbSopenharmony_ci    if (surfaceNode_ == nullptr) {
144885b47fbSopenharmony_ci        HILOG_ERROR("create surfaceNode_ fail");
145885b47fbSopenharmony_ci        return;
146885b47fbSopenharmony_ci    }
147885b47fbSopenharmony_ci
148885b47fbSopenharmony_ci    surfaceNode_->SetFrameGravity(Rosen::Gravity::RESIZE_ASPECT_FILL);
149885b47fbSopenharmony_ci    surfaceNode_->SetPositionZ(Rosen::RSSurfaceNode::POINTER_WINDOW_POSITION_Z);
150885b47fbSopenharmony_ci    surfaceNode_->SetBounds(physicalX - half_, physicalY - half_, imageWidth_, imageHeight_);
151885b47fbSopenharmony_ci    surfaceNode_->SetBackgroundColor(SK_ColorTRANSPARENT); // USE_ROSEN_DRAWING
152885b47fbSopenharmony_ci    screenId_ = screenId;
153885b47fbSopenharmony_ci    surfaceNode_->AttachToDisplay(screenId);
154885b47fbSopenharmony_ci    surfaceNode_->SetRotation(0);
155885b47fbSopenharmony_ci
156885b47fbSopenharmony_ci    canvasNode_ = Rosen::RSCanvasNode::Create();
157885b47fbSopenharmony_ci    if (canvasNode_ == nullptr) {
158885b47fbSopenharmony_ci        HILOG_ERROR("create canvasNode_ fail");
159885b47fbSopenharmony_ci        return;
160885b47fbSopenharmony_ci    }
161885b47fbSopenharmony_ci
162885b47fbSopenharmony_ci    surfaceNode_->AddChild(canvasNode_, DEFAULT_VALUE);
163885b47fbSopenharmony_ci    canvasNode_->SetBounds(0, 0, imageWidth_, imageHeight_);
164885b47fbSopenharmony_ci    canvasNode_->SetFrame(0, 0, imageWidth_, imageHeight_);
165885b47fbSopenharmony_ci    canvasNode_->SetBackgroundColor(SK_ColorTRANSPARENT); // USE_ROSEN_DRAWING
166885b47fbSopenharmony_ci    canvasNode_->SetCornerRadius(1);
167885b47fbSopenharmony_ci    canvasNode_->SetPositionZ(Rosen::RSSurfaceNode::POINTER_WINDOW_POSITION_Z);
168885b47fbSopenharmony_ci    canvasNode_->SetRotation(0);
169885b47fbSopenharmony_ci    Rosen::RSTransaction::FlushImplicitTransaction();
170885b47fbSopenharmony_ci}
171885b47fbSopenharmony_ci
172885b47fbSopenharmony_ci#ifndef USE_ROSEN_DRAWING
173885b47fbSopenharmony_civoid AccessibilityCircleDrawingManager::DrawingProgressByOpenSource(int32_t physicalX, int32_t physicalY, int32_t angle)
174885b47fbSopenharmony_ci{
175885b47fbSopenharmony_ci    HILOG_DEBUG();
176885b47fbSopenharmony_ci    auto canvas = static_cast<Rosen::RSRecordingCanvas *>(canvasNode_->BeginRecording(imageWidth_, imageHeight_));
177885b47fbSopenharmony_ci
178885b47fbSopenharmony_ci    // outer circle
179885b47fbSopenharmony_ci    SkPaint outCirclePaint;
180885b47fbSopenharmony_ci    outCirclePaint.setAntiAlias(true);
181885b47fbSopenharmony_ci    outCirclePaint.setAlphaf(OUT_CIRCLE_BACKGROUND_ALPHA);
182885b47fbSopenharmony_ci
183885b47fbSopenharmony_ci    std::vector<int32_t> outCircleColor = ParseColorString(OUT_CIRCLE_BACKGROUND_COLOR_TYPE);
184885b47fbSopenharmony_ci    outCirclePaint.setARGB(OUT_CIRCLE_BACKGROUND_ALPHA, outCircleColor[NUMBER_0], outCircleColor[NUMBER_1],
185885b47fbSopenharmony_ci        outCircleColor[NUMBER_2]);
186885b47fbSopenharmony_ci    outCirclePaint.setStyle(SkPaint::kFill_Style);
187885b47fbSopenharmony_ci    canvas->drawCircle(half_, half_, dispalyDensity_ * OUT_CIRCLE_RADIUS, outCirclePaint);
188885b47fbSopenharmony_ci
189885b47fbSopenharmony_ci    // center circle
190885b47fbSopenharmony_ci    SkPaint centerCirclePaint;
191885b47fbSopenharmony_ci    centerCirclePaint.setAntiAlias(true);
192885b47fbSopenharmony_ci    centerCirclePaint.setAlphaf(CENTER_CIRCLE_BACKGROUND_ALPHA);
193885b47fbSopenharmony_ci    std::vector<int32_t> centerCircleColor = ParseColorString(PROGRESS_COLOR_TYPE);
194885b47fbSopenharmony_ci    centerCirclePaint.setARGB(CENTER_CIRCLE_BACKGROUND_ALPHA, centerCircleColor[NUMBER_0],
195885b47fbSopenharmony_ci        centerCircleColor[NUMBER_1], centerCircleColor[NUMBER_2]);
196885b47fbSopenharmony_ci    centerCirclePaint.setStyle(SkPaint::kFill_Style);
197885b47fbSopenharmony_ci    canvas->drawCircle(half_, half_, dispalyDensity_ * CENTER_CIRCLE_RADIUS, centerCirclePaint);
198885b47fbSopenharmony_ci
199885b47fbSopenharmony_ci    // progress circle
200885b47fbSopenharmony_ci    SkPaint progressCirclePaint;
201885b47fbSopenharmony_ci    progressCirclePaint.setAntiAlias(true);
202885b47fbSopenharmony_ci    progressCirclePaint.setAlphaf(PROGRESS_BACKGROUND_ALPHA);
203885b47fbSopenharmony_ci    std::vector<int32_t> progressCircleColor = ParseColorString(PROGRESS_BACKGROUND_COLOR_TYPE);
204885b47fbSopenharmony_ci    progressCirclePaint.setARGB(PROGRESS_BACKGROUND_ALPHA, progressCircleColor[NUMBER_0],
205885b47fbSopenharmony_ci        progressCircleColor[NUMBER_1], progressCircleColor[NUMBER_2]);
206885b47fbSopenharmony_ci    progressCirclePaint.setStrokeWidth(PROGRESS_STROKE_WIDTH * dispalyDensity_);
207885b47fbSopenharmony_ci    progressCirclePaint.setStyle(SkPaint::kStroke_Style);
208885b47fbSopenharmony_ci    canvas->drawCircle(half_, half_, dispalyDensity_ * PROGRESS_RADIUS, progressCirclePaint);
209885b47fbSopenharmony_ci
210885b47fbSopenharmony_ci    // progress arc
211885b47fbSopenharmony_ci    SkPaint progressArcPaint;
212885b47fbSopenharmony_ci    progressArcPaint.setAntiAlias(true);
213885b47fbSopenharmony_ci    progressArcPaint.setAlphaf(PROGRESS_BAR_BACKGROUND_ALPHA);
214885b47fbSopenharmony_ci    std::vector<int32_t> progressArcColor = ParseColorString(PROGRESS_COLOR_TYPE);
215885b47fbSopenharmony_ci    progressArcPaint.setARGB(PROGRESS_BAR_BACKGROUND_ALPHA, progressArcColor[NUMBER_0],
216885b47fbSopenharmony_ci        progressArcColor[NUMBER_1], progressArcColor[NUMBER_2]);
217885b47fbSopenharmony_ci    progressArcPaint.setStrokeWidth(PROGRESS_STROKE_WIDTH * dispalyDensity_);
218885b47fbSopenharmony_ci    progressArcPaint.setStyle(SkPaint::kStroke_Style);
219885b47fbSopenharmony_ci
220885b47fbSopenharmony_ci    SkRect arcRect = SkRect::MakeLTRB(half_ - dispalyDensity_ * PROGRESS_RADIUS,
221885b47fbSopenharmony_ci        half_ - dispalyDensity_ * PROGRESS_RADIUS,
222885b47fbSopenharmony_ci        half_ + dispalyDensity_ * PROGRESS_RADIUS,
223885b47fbSopenharmony_ci        half_ + dispalyDensity_ * PROGRESS_RADIUS);
224885b47fbSopenharmony_ci    canvas->drawArc(arcRect, startAngle_, angle, false, progressArcPaint);
225885b47fbSopenharmony_ci
226885b47fbSopenharmony_ci    canvasNode_->FinishRecording();
227885b47fbSopenharmony_ci    Rosen::RSTransaction::FlushImplicitTransaction();
228885b47fbSopenharmony_ci}
229885b47fbSopenharmony_ci#else
230885b47fbSopenharmony_civoid AccessibilityCircleDrawingManager::DrawingProgressByRosenDrawing(int32_t physicalX, int32_t physicalY,
231885b47fbSopenharmony_ci    int32_t angle)
232885b47fbSopenharmony_ci{
233885b47fbSopenharmony_ci    HILOG_DEBUG();
234885b47fbSopenharmony_ci    auto canvas = canvasNode_->BeginRecording(imageWidth_, imageHeight_);
235885b47fbSopenharmony_ci
236885b47fbSopenharmony_ci    // outer circle
237885b47fbSopenharmony_ci    Rosen::Drawing::Brush outCircleBrush;
238885b47fbSopenharmony_ci    outCircleBrush.SetAntiAlias(true);
239885b47fbSopenharmony_ci    outCircleBrush.SetAlphaF(OUT_CIRCLE_BACKGROUND_ALPHA);
240885b47fbSopenharmony_ci    std::vector<int32_t> outCircleColor = ParseColorString(OUT_CIRCLE_BACKGROUND_COLOR_TYPE);
241885b47fbSopenharmony_ci    outCircleBrush.SetARGB(OUT_CIRCLE_BACKGROUND_ALPHA, outCircleColor[NUMBER_0], outCircleColor[NUMBER_1],
242885b47fbSopenharmony_ci        outCircleColor[NUMBER_2]);
243885b47fbSopenharmony_ci
244885b47fbSopenharmony_ci    canvas->AttachBrush(outCircleBrush);
245885b47fbSopenharmony_ci    canvas->DrawCircle(Rosen::Drawing::Point(half_, half_), dispalyDensity_ * OUT_CIRCLE_RADIUS);
246885b47fbSopenharmony_ci    canvas->DetachBrush();
247885b47fbSopenharmony_ci
248885b47fbSopenharmony_ci    // center circle
249885b47fbSopenharmony_ci    Rosen::Drawing::Brush centerCircleBrush;
250885b47fbSopenharmony_ci    centerCircleBrush.SetAntiAlias(true);
251885b47fbSopenharmony_ci    centerCircleBrush.SetAlphaF(CENTER_CIRCLE_BACKGROUND_ALPHA);
252885b47fbSopenharmony_ci    std::vector<int32_t> centerCircleColor = ParseColorString(PROGRESS_COLOR_TYPE);
253885b47fbSopenharmony_ci    centerCircleBrush.SetARGB(CENTER_CIRCLE_BACKGROUND_ALPHA, centerCircleColor[NUMBER_0],
254885b47fbSopenharmony_ci        centerCircleColor[NUMBER_1], centerCircleColor[NUMBER_2]);
255885b47fbSopenharmony_ci
256885b47fbSopenharmony_ci    canvas->AttachBrush(centerCircleBrush);
257885b47fbSopenharmony_ci    canvas->DrawCircle(Rosen::Drawing::Point(half_, half_), dispalyDensity_ * CENTER_CIRCLE_RADIUS);
258885b47fbSopenharmony_ci    canvas->DetachBrush();
259885b47fbSopenharmony_ci
260885b47fbSopenharmony_ci    // progress circle
261885b47fbSopenharmony_ci    Rosen::Drawing::Pen progressPen;
262885b47fbSopenharmony_ci    progressPen.SetAntiAlias(true);
263885b47fbSopenharmony_ci    progressPen.SetAlphaF(PROGRESS_BACKGROUND_ALPHA);
264885b47fbSopenharmony_ci    std::vector<int32_t> progressCircleColor = ParseColorString(PROGRESS_BACKGROUND_COLOR_TYPE);
265885b47fbSopenharmony_ci    progressPen.SetARGB(PROGRESS_BACKGROUND_ALPHA, progressCircleColor[NUMBER_0],
266885b47fbSopenharmony_ci        progressCircleColor[NUMBER_1], progressCircleColor[NUMBER_2]);
267885b47fbSopenharmony_ci    progressPen.SetWidth(PROGRESS_STROKE_WIDTH * dispalyDensity_);
268885b47fbSopenharmony_ci
269885b47fbSopenharmony_ci    canvas->AttachPen(progressPen);
270885b47fbSopenharmony_ci    canvas->DrawCircle(Rosen::Drawing::Point(half_, half_), dispalyDensity_ * PROGRESS_RADIUS);
271885b47fbSopenharmony_ci    canvas->DetachPen();
272885b47fbSopenharmony_ci
273885b47fbSopenharmony_ci    // progress arc
274885b47fbSopenharmony_ci    Rosen::Drawing::Pen progressArcPen;
275885b47fbSopenharmony_ci    progressArcPen.SetAntiAlias(true);
276885b47fbSopenharmony_ci    progressArcPen.SetAlphaF(PROGRESS_BAR_BACKGROUND_ALPHA);
277885b47fbSopenharmony_ci    std::vector<int32_t> progressArcColor = ParseColorString(PROGRESS_COLOR_TYPE);
278885b47fbSopenharmony_ci    progressArcPen.SetARGB(PROGRESS_BAR_BACKGROUND_ALPHA, progressArcColor[NUMBER_0],
279885b47fbSopenharmony_ci        progressArcColor[NUMBER_1], progressArcColor[NUMBER_2]);
280885b47fbSopenharmony_ci    progressArcPen.SetWidth(PROGRESS_STROKE_WIDTH * dispalyDensity_);
281885b47fbSopenharmony_ci
282885b47fbSopenharmony_ci    Rosen::Drawing::Rect rect(half_ - dispalyDensity_ * PROGRESS_RADIUS,
283885b47fbSopenharmony_ci        half_ - dispalyDensity_ * PROGRESS_RADIUS,
284885b47fbSopenharmony_ci        half_ + dispalyDensity_ * PROGRESS_RADIUS,
285885b47fbSopenharmony_ci        half_ + dispalyDensity_ * PROGRESS_RADIUS);
286885b47fbSopenharmony_ci    canvas->AttachPen(progressArcPen);
287885b47fbSopenharmony_ci    canvas->DrawArc(rect, startAngle_, angle);
288885b47fbSopenharmony_ci    canvas->DetachPen();
289885b47fbSopenharmony_ci
290885b47fbSopenharmony_ci    canvasNode_->FinishRecording();
291885b47fbSopenharmony_ci    Rosen::RSTransaction::FlushImplicitTransaction();
292885b47fbSopenharmony_ci}
293885b47fbSopenharmony_ci#endif
294885b47fbSopenharmony_ci
295885b47fbSopenharmony_civoid AccessibilityCircleDrawingManager::DrawingProgress(int32_t physicalX, int32_t physicalY, int32_t angle)
296885b47fbSopenharmony_ci{
297885b47fbSopenharmony_ci#ifndef USE_ROSEN_DRAWING
298885b47fbSopenharmony_ci    DrawingProgressByOpenSource(physicalX, physicalY, angle);
299885b47fbSopenharmony_ci#else
300885b47fbSopenharmony_ci    DrawingProgressByRosenDrawing(physicalX, physicalY, angle);
301885b47fbSopenharmony_ci#endif
302885b47fbSopenharmony_ci}
303885b47fbSopenharmony_ci
304885b47fbSopenharmony_civoid AccessibilityCircleDrawingManager::SetPointerLocation(int32_t physicalX, int32_t physicalY, uint64_t screenId)
305885b47fbSopenharmony_ci{
306885b47fbSopenharmony_ci    HILOG_DEBUG("Pointer window move, x:%{public}d, y:%{public}d", physicalX, physicalY);
307885b47fbSopenharmony_ci    if (surfaceNode_ != nullptr) {
308885b47fbSopenharmony_ci        surfaceNode_->SetBounds(physicalX - half_,
309885b47fbSopenharmony_ci            physicalY - half_,
310885b47fbSopenharmony_ci            surfaceNode_->GetStagingProperties().GetBounds().z_,
311885b47fbSopenharmony_ci            surfaceNode_->GetStagingProperties().GetBounds().w_);
312885b47fbSopenharmony_ci        screenId_ = screenId;
313885b47fbSopenharmony_ci        surfaceNode_->AttachToDisplay(screenId);
314885b47fbSopenharmony_ci        Rosen::RSTransaction::FlushImplicitTransaction();
315885b47fbSopenharmony_ci    }
316885b47fbSopenharmony_ci
317885b47fbSopenharmony_ci    if (canvasNode_ != nullptr) {
318885b47fbSopenharmony_ci        canvasNode_->SetBounds(0,
319885b47fbSopenharmony_ci            0,
320885b47fbSopenharmony_ci            canvasNode_->GetStagingProperties().GetBounds().z_,
321885b47fbSopenharmony_ci            canvasNode_->GetStagingProperties().GetBounds().w_);
322885b47fbSopenharmony_ci        canvasNode_->SetFrame(0,
323885b47fbSopenharmony_ci            0,
324885b47fbSopenharmony_ci            canvasNode_->GetStagingProperties().GetBounds().z_,
325885b47fbSopenharmony_ci            canvasNode_->GetStagingProperties().GetBounds().w_);
326885b47fbSopenharmony_ci        Rosen::RSTransaction::FlushImplicitTransaction();
327885b47fbSopenharmony_ci    }
328885b47fbSopenharmony_ci}
329885b47fbSopenharmony_ci
330885b47fbSopenharmony_civoid AccessibilityCircleDrawingManager::DrawPointer(int32_t physicalX, int32_t physicalY, int32_t angle,
331885b47fbSopenharmony_ci    uint64_t screenId, int32_t startAngle)
332885b47fbSopenharmony_ci{
333885b47fbSopenharmony_ci    HILOG_DEBUG();
334885b47fbSopenharmony_ci    startAngle_ = startAngle;
335885b47fbSopenharmony_ci    if (surfaceNode_ != nullptr) {
336885b47fbSopenharmony_ci        SetPointerLocation(physicalX, physicalY, screenId);
337885b47fbSopenharmony_ci        DrawingProgress(physicalX, physicalY, angle);
338885b47fbSopenharmony_ci        UpdatePointerVisible(true);
339885b47fbSopenharmony_ci        HILOG_DEBUG("surfaceNode_ is existed");
340885b47fbSopenharmony_ci        return;
341885b47fbSopenharmony_ci    }
342885b47fbSopenharmony_ci
343885b47fbSopenharmony_ci    CreatePointerWindow(physicalX, physicalY, screenId);
344885b47fbSopenharmony_ci    if (surfaceNode_ == nullptr) {
345885b47fbSopenharmony_ci        HILOG_ERROR("surfaceNode_ is nullptr");
346885b47fbSopenharmony_ci        return;
347885b47fbSopenharmony_ci    }
348885b47fbSopenharmony_ci
349885b47fbSopenharmony_ci    DrawingProgress(physicalX, physicalY, angle);
350885b47fbSopenharmony_ci    UpdatePointerVisible(true);
351885b47fbSopenharmony_ci}
352885b47fbSopenharmony_ci
353885b47fbSopenharmony_ciint32_t AccessibilityCircleDrawingManager::ParseStringToInteger(const std::string& color)
354885b47fbSopenharmony_ci{
355885b47fbSopenharmony_ci    int32_t val = 0;
356885b47fbSopenharmony_ci    int32_t base = 1;
357885b47fbSopenharmony_ci    if (color.size() < 1) {
358885b47fbSopenharmony_ci        return val;
359885b47fbSopenharmony_ci    }
360885b47fbSopenharmony_ci    for (int32_t index = static_cast<int32_t>(color.size() - 1); index >= 0; index--) {
361885b47fbSopenharmony_ci        if (color[index] >= CHAR_0 && color[index] <= CHAR_9) {
362885b47fbSopenharmony_ci            val += base * static_cast<int32_t>(color[index] - CHAR_0);
363885b47fbSopenharmony_ci        }
364885b47fbSopenharmony_ci
365885b47fbSopenharmony_ci        if (color[index] == CHAR_A) {
366885b47fbSopenharmony_ci            val += base * static_cast<int32_t>(color[index] - CHAR_A + DECIMAL);
367885b47fbSopenharmony_ci        }
368885b47fbSopenharmony_ci
369885b47fbSopenharmony_ci        if (color[index] == CHAR_B) {
370885b47fbSopenharmony_ci            val += base * static_cast<int32_t>(color[index] - CHAR_A + DECIMAL);
371885b47fbSopenharmony_ci        }
372885b47fbSopenharmony_ci
373885b47fbSopenharmony_ci        if (color[index] == CHAR_C) {
374885b47fbSopenharmony_ci            val += base * static_cast<int32_t>(color[index] - CHAR_A + DECIMAL);
375885b47fbSopenharmony_ci        }
376885b47fbSopenharmony_ci
377885b47fbSopenharmony_ci        if (color[index] == CHAR_D) {
378885b47fbSopenharmony_ci            val += base * static_cast<int32_t>(color[index] - CHAR_A + DECIMAL);
379885b47fbSopenharmony_ci        }
380885b47fbSopenharmony_ci
381885b47fbSopenharmony_ci        if (color[index] == CHAR_E) {
382885b47fbSopenharmony_ci            val += base * static_cast<int32_t>(color[index] - CHAR_A + DECIMAL);
383885b47fbSopenharmony_ci        }
384885b47fbSopenharmony_ci
385885b47fbSopenharmony_ci        if (color[index] == CHAR_F) {
386885b47fbSopenharmony_ci            val += base * static_cast<int32_t>(color[index] - CHAR_A + DECIMAL);
387885b47fbSopenharmony_ci        }
388885b47fbSopenharmony_ci
389885b47fbSopenharmony_ci        base = base * HEXADECIMAL;
390885b47fbSopenharmony_ci    }
391885b47fbSopenharmony_ci
392885b47fbSopenharmony_ci    return val;
393885b47fbSopenharmony_ci}
394885b47fbSopenharmony_ci
395885b47fbSopenharmony_cistd::vector<int32_t> AccessibilityCircleDrawingManager::ParseColorString(const std::string& color)
396885b47fbSopenharmony_ci{
397885b47fbSopenharmony_ci    std::string r = color.substr(RED_START_INDEX, COLOR_STRING_LENGTH);
398885b47fbSopenharmony_ci    std::string g = color.substr(GREEN_START_INDEX, COLOR_STRING_LENGTH);
399885b47fbSopenharmony_ci    std::string b = color.substr(BLUE_START_INDEX, COLOR_STRING_LENGTH);
400885b47fbSopenharmony_ci
401885b47fbSopenharmony_ci    int32_t rValue = ParseStringToInteger(r);
402885b47fbSopenharmony_ci    int32_t gValue = ParseStringToInteger(g);
403885b47fbSopenharmony_ci    int32_t bValue = ParseStringToInteger(b);
404885b47fbSopenharmony_ci
405885b47fbSopenharmony_ci    std::vector<int32_t> rgbValue = {rValue, gValue, bValue};
406885b47fbSopenharmony_ci    return rgbValue;
407885b47fbSopenharmony_ci}
408885b47fbSopenharmony_ci} // namespace Accessibility
409885b47fbSopenharmony_ci} // namespace OHOS