1 /*
2  * Copyright (c) 2022-2023 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 "platform/ohos/overdraw/rs_cpu_overdraw_canvas_listener.h"
17 
18 #include "utils/region.h"
19 
20 #include "platform/ohos/overdraw/rs_overdraw_controller.h"
21 
22 namespace OHOS {
23 namespace Rosen {
RSCPUOverdrawCanvasListener(Drawing::Canvas & canvas)24 RSCPUOverdrawCanvasListener::RSCPUOverdrawCanvasListener(Drawing::Canvas &canvas)
25     : RSCanvasListener(canvas)
26 {
27 }
28 
Draw()29 void RSCPUOverdrawCanvasListener::Draw()
30 {
31     auto overdrawColorMap = RSOverdrawController::GetInstance().GetColorMap();
32 
33     Drawing::Brush brush;
34     brush.SetAntiAlias(true);
35 
36     Drawing::Region drawed;
37     for (size_t i = regions_.size(); i > 0; i--) {
38         if (overdrawColorMap.find(i) != overdrawColorMap.end()) {
39             brush.SetColor(overdrawColorMap.at(i));
40         } else {
41             brush.SetColor(overdrawColorMap.at(0));
42         }
43 
44         auto toDraw = regions_[i];
45         toDraw.Op(drawed, Drawing::RegionOp::DIFFERENCE);
46         canvas_.AttachBrush(brush);
47         canvas_.DrawRegion(toDraw);
48         canvas_.DetachBrush();
49         drawed.Op(toDraw, Drawing::RegionOp::UNION);
50     }
51 }
52 
DrawPoint(const Drawing::Point & point)53 void RSCPUOverdrawCanvasListener::DrawPoint(const Drawing::Point& point)
54 {
55     DrawRect(Drawing::Rect(point.GetX(), point.GetY(), 1 + point.GetX(), 1 + point.GetY()));
56 }
57 
DrawLine(const Drawing::Point & startPt,const Drawing::Point & endPt)58 void RSCPUOverdrawCanvasListener::DrawLine(const Drawing::Point& startPt, const Drawing::Point& endPt)
59 {
60     Drawing::Path path;
61     path.MoveTo(startPt.GetX(), startPt.GetY());
62     path.LineTo(endPt.GetX(), endPt.GetY());
63     AppendRegion(path);
64 }
65 
DrawRect(const Drawing::Rect & rect)66 void RSCPUOverdrawCanvasListener::DrawRect(const Drawing::Rect& rect)
67 {
68     Drawing::Path path;
69     path.AddRect(rect);
70     AppendRegion(path);
71 }
72 
DrawRoundRect(const Drawing::RoundRect & roundRect)73 void RSCPUOverdrawCanvasListener::DrawRoundRect(const Drawing::RoundRect& roundRect)
74 {
75     Drawing::Path path;
76     path.AddRoundRect(roundRect);
77     AppendRegion(path);
78 }
79 
DrawNestedRoundRect(const Drawing::RoundRect & outer,const Drawing::RoundRect & inner)80 void RSCPUOverdrawCanvasListener::DrawNestedRoundRect(const Drawing::RoundRect& outer, const Drawing::RoundRect& inner)
81 {
82     Drawing::Path path;
83     path.AddRoundRect(outer);
84     path.AddRoundRect(inner);
85     AppendRegion(path);
86 }
87 
DrawArc(const Drawing::Rect & oval,Drawing::scalar startAngle,Drawing::scalar sweepAngle)88 void RSCPUOverdrawCanvasListener::DrawArc(
89     const Drawing::Rect& oval, Drawing::scalar startAngle, Drawing::scalar sweepAngle)
90 {
91     Drawing::Path path;
92     path.AddArc(oval, startAngle, sweepAngle);
93     AppendRegion(path);
94 }
95 
DrawPie(const Drawing::Rect & oval,Drawing::scalar startAngle,Drawing::scalar sweepAngle)96 void RSCPUOverdrawCanvasListener::DrawPie(
97     const Drawing::Rect& oval, Drawing::scalar startAngle, Drawing::scalar sweepAngle)
98 {
99     Drawing::Path path;
100     path.AddArc(oval, startAngle, sweepAngle);
101     AppendRegion(path);
102 }
103 
DrawOval(const Drawing::Rect & oval)104 void RSCPUOverdrawCanvasListener::DrawOval(const Drawing::Rect& oval)
105 {
106     Drawing::Path path;
107     path.AddOval(oval);
108     AppendRegion(path);
109 }
110 
DrawCircle(const Drawing::Point & centerPt,Drawing::scalar radius)111 void RSCPUOverdrawCanvasListener::DrawCircle(const Drawing::Point& centerPt, Drawing::scalar radius)
112 {
113     Drawing::Path path;
114     path.AddCircle(centerPt.GetX(), centerPt.GetY(), radius);
115     AppendRegion(path);
116 }
117 
DrawPath(const Drawing::Path & path)118 void RSCPUOverdrawCanvasListener::DrawPath(const Drawing::Path& path)
119 {
120     Drawing::Path tPath = path;
121     AppendRegion(tPath);
122 }
123 
DrawBackground(const Drawing::Brush & brush)124 void RSCPUOverdrawCanvasListener::DrawBackground(const Drawing::Brush& brush)
125 {
126     // need know canvas rect region
127 }
128 
DrawShadow(const Drawing::Path & path,const Drawing::Point3 & planeParams,const Drawing::Point3 & devLightPos,Drawing::scalar lightRadius,Drawing::Color ambientColor,Drawing::Color spotColor,Drawing::ShadowFlags flag)129 void RSCPUOverdrawCanvasListener::DrawShadow(const Drawing::Path& path, const Drawing::Point3& planeParams,
130     const Drawing::Point3& devLightPos, Drawing::scalar lightRadius, Drawing::Color ambientColor,
131     Drawing::Color spotColor, Drawing::ShadowFlags flag)
132 {
133     // need know shadow rect region
134 }
135 
DrawShadowStyle(const Drawing::Path & path,const Drawing::Point3 & planeParams,const Drawing::Point3 & devLightPos,Drawing::scalar lightRadius,Drawing::Color ambientColor,Drawing::Color spotColor,Drawing::ShadowFlags flag,bool isLimitElevation)136 void RSCPUOverdrawCanvasListener::DrawShadowStyle(const Drawing::Path& path, const Drawing::Point3& planeParams,
137     const Drawing::Point3& devLightPos, Drawing::scalar lightRadius, Drawing::Color ambientColor,
138     Drawing::Color spotColor, Drawing::ShadowFlags flag, bool isLimitElevation)
139 {
140     // need know shadow rect region
141 }
142 
DrawRegion(const Drawing::Region & region)143 void RSCPUOverdrawCanvasListener::DrawRegion(const Drawing::Region& region)
144 {
145     // need know region path region
146 }
147 
DrawTextBlob(const Drawing::TextBlob * blob,const Drawing::scalar x,const Drawing::scalar y)148 void RSCPUOverdrawCanvasListener::DrawTextBlob(
149     const Drawing::TextBlob* blob, const Drawing::scalar x, const Drawing::scalar y)
150 {
151     if (blob == nullptr) {
152         return;
153     }
154 
155     auto rect = blob->Bounds();
156     rect->Offset(x, y);
157     DrawRect(*rect);
158 }
159 
DrawBitmap(const Drawing::Bitmap & bitmap,const Drawing::scalar px,const Drawing::scalar py)160 void RSCPUOverdrawCanvasListener::DrawBitmap(
161     const Drawing::Bitmap& bitmap, const Drawing::scalar px, const Drawing::scalar py)
162 {
163     DrawRect(Drawing::Rect(px, py, bitmap.GetWidth() + px, bitmap.GetHeight() + py));
164 }
165 
DrawImage(const Drawing::Image & image,const Drawing::scalar px,const Drawing::scalar py,const Drawing::SamplingOptions & sampling)166 void RSCPUOverdrawCanvasListener::DrawImage(const Drawing::Image& image, const Drawing::scalar px,
167     const Drawing::scalar py, const Drawing::SamplingOptions& sampling)
168 {
169     DrawRect(Drawing::Rect(px, py, image.GetWidth() + px, image.GetHeight() + py));
170 }
171 
DrawImageRect(const Drawing::Image & image,const Drawing::Rect & src,const Drawing::Rect & dst,const Drawing::SamplingOptions & sampling,Drawing::SrcRectConstraint constraint)172 void RSCPUOverdrawCanvasListener::DrawImageRect(const Drawing::Image& image, const Drawing::Rect& src,
173     const Drawing::Rect& dst, const Drawing::SamplingOptions& sampling, Drawing::SrcRectConstraint constraint)
174 {
175     DrawRect(dst);
176 }
177 
DrawImageRect(const Drawing::Image & image,const Drawing::Rect & dst,const Drawing::SamplingOptions & sampling)178 void RSCPUOverdrawCanvasListener::DrawImageRect(
179     const Drawing::Image& image, const Drawing::Rect& dst, const Drawing::SamplingOptions& sampling)
180 {
181     DrawRect(dst);
182 }
183 
DrawPicture(const Drawing::Picture & picture)184 void RSCPUOverdrawCanvasListener::DrawPicture(const Drawing::Picture& picture)
185 {
186     // need know picture rect region
187 }
188 
Clear(Drawing::ColorQuad color)189 void RSCPUOverdrawCanvasListener::Clear(Drawing::ColorQuad color)
190 {
191     // need know canvas rect region
192 }
193 
AppendRegion(Drawing::Path & path)194 void RSCPUOverdrawCanvasListener::AppendRegion(Drawing::Path& path)
195 {
196     Drawing::Region target;
197     Drawing::Region drRegion;
198     path.Transform(canvas_.GetTotalMatrix());
199     drRegion.SetRect(Drawing::RectI(-1e9, -1e9, 1e9, 1e9));
200     target.SetPath(path, drRegion);
201 
202     for (size_t i = regions_.size(); i > 0; i--) {
203         if (regions_[i].IsIntersects(target)) {
204             auto regi = regions_[i];
205             regi.Op(target, Drawing::RegionOp::INTERSECT);
206             regions_[i + 1].Op(regi, Drawing::RegionOp::UNION);
207         }
208     }
209     regions_[1].Op(target, Drawing::RegionOp::UNION);
210 }
211 } // namespace Rosen
212 } // namespace OHOS