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