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 
16 #include "knuckle_glow_point.h"
17 
18 #include "include/core/SkColorFilter.h"
19 #include "mmi_log.h"
20 #include "platform/ohos/overdraw/rs_overdraw_controller.h"
21 
22 #undef MMI_LOG_TAG
23 #define MMI_LOG_TAG "KnuckleGlowPoint"
24 
25 namespace OHOS {
26 namespace MMI {
27 namespace {
28 constexpr int32_t SEC_TO_NANOSEC { 1000000000 };
29 constexpr int32_t NANOSECOND_TO_MILLISECOND { 1000000 };
30 constexpr int32_t PAINT_WIDTH { 20 };
31 constexpr int32_t ARGB_A { 0 };
32 constexpr int32_t ARGB_RGB { 255 };
33 constexpr double BASIC_LIFESPAN { 200.0f };
34 constexpr int32_t TRACE_COLOR { 255 };
35 constexpr float BASIC_SIZE { 100.0f };
36 constexpr int32_t ARGB_COLOR_ARRAY { 0x11c8ffff };
37 constexpr double HALF { 2.0 };
38 } // namespace
39 
KnuckleGlowPoint(std::shared_ptr<OHOS::Media::PixelMap> pixelMap)40 KnuckleGlowPoint::KnuckleGlowPoint(std::shared_ptr<OHOS::Media::PixelMap> pixelMap) : traceShadow_(pixelMap)
41 {
42     OHOS::Rosen::Drawing::Filter filter;
43     OHOS::Rosen::OverdrawColorArray colorArray = {
44         0x00000000,
45         0x00000000,
46         0x00000000,
47         0x00000000,
48         0x00000000,
49         ARGB_COLOR_ARRAY,
50     };
51     auto protanomalyMat = OHOS::Rosen::Drawing::ColorFilter::CreateOverDrawColorFilter(colorArray.data());
52     filter.SetColorFilter(protanomalyMat);
53     OHOS::Rosen::Drawing::Brush brush;
54     brush_.SetFilter(filter);
55 }
56 
GetNanoTime() const57 int64_t KnuckleGlowPoint::GetNanoTime() const
58 {
59     CALL_DEBUG_ENTER;
60     struct timespec time = { 0 };
61     clock_gettime(CLOCK_MONOTONIC, &time);
62     return static_cast<int64_t>(time.tv_sec) * SEC_TO_NANOSEC + time.tv_nsec;
63 }
64 
Update()65 void KnuckleGlowPoint::Update()
66 {
67     CALL_DEBUG_ENTER;
68     if (IsEnded()) {
69         return;
70     }
71     int64_t currentTime = GetNanoTime() / NANOSECOND_TO_MILLISECOND;
72     int64_t timeInterval = currentTime - lastUpdateTimeMillis_;
73     if (timeInterval < 0) {
74         timeInterval = 0;
75     }
76 
77     lastUpdateTimeMillis_ = currentTime;
78     lifespan_ -= timeInterval;
79     traceSize_ = static_cast<float>((lifespan_ / BASIC_LIFESPAN) * BASIC_SIZE);
80     UpdateMatrix();
81 }
82 
Draw(Rosen::ExtendRecordingCanvas * canvas)83 void KnuckleGlowPoint::Draw(Rosen::ExtendRecordingCanvas* canvas)
84 {
85     CALL_DEBUG_ENTER;
86     CHKPV(canvas);
87     CHKPV(traceShadow_);
88     if (IsEnded() || pointX_ <= 0 || pointY_ <= 0) {
89         return;
90     }
91     canvas->SetMatrix(traceMatrix_);
92     canvas->AttachBrush(brush_);
93     Rosen::Drawing::Rect src = Rosen::Drawing::Rect(0, 0, traceShadow_->GetWidth(), traceShadow_->GetHeight());
94     Rosen::Drawing::Rect dst = Rosen::Drawing::Rect(pointX_ - traceShadow_->GetWidth() / HALF,
95         pointY_ - traceShadow_->GetHeight() / HALF, pointX_ + traceShadow_->GetWidth() / HALF,
96         pointY_ + traceShadow_->GetHeight());
97     canvas->DrawPixelMapRect(traceShadow_, src, dst, Rosen::Drawing::SamplingOptions());
98     canvas->DetachBrush();
99 }
100 
Reset(double pointX,double pointY,float lifespanOffset)101 void KnuckleGlowPoint::Reset(double pointX, double pointY, float lifespanOffset)
102 {
103     CALL_DEBUG_ENTER;
104     pointX_ = pointX;
105     pointY_ = pointY;
106     lifespan_ = BASIC_LIFESPAN - lifespanOffset;
107     traceSize_ = BASIC_SIZE;
108     lastUpdateTimeMillis_ = GetNanoTime() / NANOSECOND_TO_MILLISECOND;
109 }
110 
IsEnded() const111 bool KnuckleGlowPoint::IsEnded() const
112 {
113     CALL_DEBUG_ENTER;
114     return lifespan_ < 0;
115 }
116 
UpdateMatrix()117 void KnuckleGlowPoint::UpdateMatrix()
118 {
119     CALL_DEBUG_ENTER;
120     CHKPV(traceShadow_);
121     traceMatrix_.Reset();
122     float proportion = traceSize_ / traceShadow_->GetWidth();
123     traceMatrix_.PostScale(proportion, proportion, pointX_, pointY_);
124 }
125 } // namespace MMI
126 } // namespace OHOS
127