1 /*
2  * Copyright (c) 2022 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 "core/components_ng/render/paint_wrapper.h"
17 
18 #include "core/components_ng/base/frame_node.h"
19 #include "core/components_ng/render/node_paint_method.h"
20 
21 namespace OHOS::Ace::NG {
22 
PaintWrapper(WeakPtr<RenderContext> renderContext,RefPtr<GeometryNode> geometryNode,RefPtr<PaintProperty> layoutProperty,RefPtr<ExtensionHandler> handler)23 PaintWrapper::PaintWrapper(WeakPtr<RenderContext> renderContext, RefPtr<GeometryNode> geometryNode,
24     RefPtr<PaintProperty> layoutProperty, RefPtr<ExtensionHandler> handler)
25     : renderContext_(std::move(renderContext)), geometryNode_(std::move(geometryNode)),
26       paintProperty_(std::move(layoutProperty)), extensionHandler_(std::move(handler))
27 {}
28 
29 PaintWrapper::~PaintWrapper() = default;
30 
SetNodePaintMethod(const RefPtr<NodePaintMethod> & nodePaintImpl)31 void PaintWrapper::SetNodePaintMethod(const RefPtr<NodePaintMethod>& nodePaintImpl)
32 {
33     nodePaintImpl_ = nodePaintImpl;
34     CHECK_NULL_VOID(nodePaintImpl_);
35     auto renderContext = renderContext_.Upgrade();
36     CHECK_NULL_VOID(renderContext);
37     auto contentModifier = AceType::DynamicCast<ContentModifier>(nodePaintImpl_->GetContentModifier(this));
38     if (contentModifier) {
39         if (extensionHandler_) {
40             contentModifier->SetExtensionHandler(AceType::RawPtr(extensionHandler_));
41         }
42         renderContext->FlushContentModifier(contentModifier);
43     }
44     auto overlayModifier = AceType::DynamicCast<OverlayModifier>(nodePaintImpl_->GetOverlayModifier(this));
45     if (overlayModifier) {
46         if (extensionHandler_) {
47             overlayModifier->SetExtensionHandler(AceType::RawPtr(extensionHandler_));
48         }
49         renderContext->FlushOverlayModifier(overlayModifier);
50     }
51     auto foregroundModifier = AceType::DynamicCast<ForegroundModifier>(nodePaintImpl_->GetForegroundModifier(this));
52     if (foregroundModifier) {
53         if (extensionHandler_) {
54             foregroundModifier->SetExtensionHandler(AceType::RawPtr(extensionHandler_));
55         }
56         renderContext->FlushForegroundModifier(foregroundModifier);
57     }
58 }
59 
FlushOverlayModifier()60 void PaintWrapper::FlushOverlayModifier()
61 {
62     CHECK_NULL_VOID(nodePaintImpl_);
63     auto overlayModifier = nodePaintImpl_->GetOverlayModifier(this);
64     CHECK_NULL_VOID(overlayModifier);
65     auto renderContext = renderContext_.Upgrade();
66     CHECK_NULL_VOID(renderContext);
67     renderContext->FlushOverlayModifier(overlayModifier);
68 }
69 
FlushContentModifier()70 void PaintWrapper::FlushContentModifier()
71 {
72     CHECK_NULL_VOID(nodePaintImpl_);
73     auto contentModifier = nodePaintImpl_->GetContentModifier(this);
74     CHECK_NULL_VOID(contentModifier);
75     auto renderContext = renderContext_.Upgrade();
76     CHECK_NULL_VOID(renderContext);
77     renderContext->FlushContentModifier(contentModifier);
78 }
79 
FlushRender()80 void PaintWrapper::FlushRender()
81 {
82     auto renderContext = renderContext_.Upgrade();
83     CHECK_NULL_VOID(renderContext);
84 
85     auto contentModifier =
86         DynamicCast<ContentModifier>(nodePaintImpl_ ? nodePaintImpl_->GetContentModifier(this) : nullptr);
87     if (contentModifier) {
88         nodePaintImpl_->UpdateContentModifier(this);
89         if (extensionHandler_) {
90             extensionHandler_->InvalidateRender();
91         }
92     }
93 
94     auto overlayModifier = nodePaintImpl_ ? nodePaintImpl_->GetOverlayModifier(this) : nullptr;
95     if (overlayModifier) {
96         nodePaintImpl_->UpdateOverlayModifier(this);
97         if (extensionHandler_) {
98             extensionHandler_->OverlayRender();
99         }
100     }
101 
102     auto foregroundModifier = nodePaintImpl_ ? nodePaintImpl_->GetForegroundModifier(this) : nullptr;
103     if (foregroundModifier) {
104         nodePaintImpl_->UpdateForegroundModifier(this);
105         if (extensionHandler_) {
106             extensionHandler_->ForegroundRender();
107         }
108     }
109 
110     renderContext->StartRecording();
111 
112     auto contentDraw = nodePaintImpl_ ? nodePaintImpl_->GetContentDrawFunction(this) : nullptr;
113     auto foregroundDraw = nodePaintImpl_ ? nodePaintImpl_->GetForegroundDrawFunction(this) : nullptr;
114     auto overlayDraw = nodePaintImpl_ ? nodePaintImpl_->GetOverlayDrawFunction(this) : nullptr;
115 
116     if (extensionHandler_) {
117         auto layoutSize = GetGeometryNode()->GetFrameSize();
118         auto width = layoutSize.Width();
119         auto height = layoutSize.Height();
120         if (!contentModifier) {
121             if (contentDraw) {
122                 extensionHandler_->SetInnerDrawImpl([contentDraw = std::move(contentDraw)](
123                                                         DrawingContext& context) { contentDraw(context.canvas); });
124             }
125             renderContext->FlushContentDrawFunction(
126                 [extensionHandler = RawPtr(extensionHandler_), width, height](RSCanvas& canvas) {
127                     DrawingContext context = { canvas, width, height };
128                     extensionHandler->Draw(context);
129                 });
130         }
131         if (!foregroundModifier) {
132             if (foregroundDraw) {
133                 extensionHandler_->SetInnerForegroundDrawImpl(
134                     [foregroundDraw = std::move(foregroundDraw)](
135                         DrawingContext& context) { foregroundDraw(context.canvas); });
136             }
137             renderContext->FlushForegroundDrawFunction(
138                 [extensionHandler = RawPtr(extensionHandler_), width, height](RSCanvas& canvas) {
139                     DrawingContext context = { canvas, width, height };
140                     extensionHandler->ForegroundDraw(context);
141                 });
142         }
143         if (!overlayModifier) {
144             if (overlayDraw) {
145                 extensionHandler_->SetInnerOverlayDrawImpl(
146                     [overlayDraw = std::move(overlayDraw)](
147                         DrawingContext& context) { overlayDraw(context.canvas); });
148             }
149             renderContext->FlushOverlayDrawFunction(
150                 [extensionHandler = RawPtr(extensionHandler_), width, height](RSCanvas& canvas) {
151                     DrawingContext context = { canvas, width, height };
152                     extensionHandler->OverlayDraw(context);
153                 });
154         }
155     } else {
156         if (contentDraw && !contentModifier) {
157             renderContext->FlushContentDrawFunction(std::move(contentDraw));
158         }
159         if (foregroundDraw && !foregroundModifier) {
160             renderContext->FlushForegroundDrawFunction(std::move(foregroundDraw));
161         }
162         if (overlayDraw && !overlayModifier) {
163             renderContext->FlushOverlayDrawFunction(std::move(overlayDraw));
164         }
165     }
166 
167     if (renderContext->GetAccessibilityFocus().value_or(false)) {
168         renderContext->PaintAccessibilityFocus();
169     }
170 
171     renderContext->StopRecordingIfNeeded();
172 }
173 } // namespace OHOS::Ace::NG
174