1 /*
2 * Copyright (c) 2021-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 "bridge/declarative_frontend/jsview/canvas/js_canvas.h"
17
18 #include "base/log/ace_scoring_log.h"
19 #include "bridge/common/utils/engine_helper.h"
20 #include "bridge/declarative_frontend/jsview/js_utils.h"
21 #include "bridge/declarative_frontend/jsview/canvas/js_rendering_context_base.h"
22 #include "bridge/declarative_frontend/jsview/models/canvas/canvas_model_impl.h"
23 #include "core/common/container.h"
24 #include "core/components_ng/base/view_stack_model.h"
25 #include "core/components_ng/base/view_stack_processor.h"
26 #include "core/components_ng/pattern/canvas/canvas_model_ng.h"
27
28 namespace OHOS::Ace {
GetInstance()29 CanvasModel* CanvasModel::GetInstance()
30 {
31 #ifdef NG_BUILD
32 static NG::CanvasModelNG instance;
33 return &instance;
34 #else
35 if (Container::IsCurrentUseNewPipeline()) {
36 static NG::CanvasModelNG instance;
37 return &instance;
38 } else {
39 static Framework::CanvasModelImpl instance;
40 return &instance;
41 }
42 #endif
43 }
44 } // namespace OHOS::Ace
45 namespace OHOS::Ace::Framework {
46
Create(const JSCallbackInfo & info)47 void JSCanvas::Create(const JSCallbackInfo& info)
48 {
49 auto pattern = CanvasModel::GetInstance()->Create();
50 CHECK_NULL_VOID(pattern);
51 if (info[0]->IsUndefined()) {
52 CanvasModel::GetInstance()->DetachRenderContext();
53 } else if (info[0]->IsObject()) {
54 JSRenderingContextBase* jsContext = JSRef<JSObject>::Cast(info[0])->Unwrap<JSRenderingContextBase>();
55 if (jsContext) {
56 jsContext->SetInstanceId(Container::CurrentId());
57 jsContext->SetCanvasPattern(pattern);
58 jsContext->SetAntiAlias();
59 jsContext->SetDensity();
60 }
61 }
62
63 if (info.Length() > 1) {
64 auto options = info[1];
65 if (!options->IsObject()) {
66 return;
67 }
68 auto engine = EngineHelper::GetCurrentEngine();
69 CHECK_NULL_VOID(engine);
70 NativeEngine* nativeEngine = engine->GetNativeEngine();
71 CHECK_NULL_VOID(nativeEngine);
72 panda::Local<JsiValue> value = options.Get().GetLocalHandle();
73 JSValueWrapper valueWrapper = value;
74 ScopeRAII scope(reinterpret_cast<napi_env>(nativeEngine));
75 napi_value optionsValue = nativeEngine->ValueToNapiValue(valueWrapper);
76 CanvasModel::GetInstance()->SetImageAIOptions(optionsValue);
77 }
78 }
79
JSBind(BindingTarget globalObj)80 void JSCanvas::JSBind(BindingTarget globalObj)
81 {
82 JSClass<JSCanvas>::Declare("Canvas");
83 MethodOptions opt = MethodOptions::NONE;
84 JSClass<JSCanvas>::StaticMethod("create", &JSCanvas::Create, opt);
85 JSClass<JSCanvas>::StaticMethod("onReady", &JSCanvas::OnReady);
86 JSClass<JSCanvas>::StaticMethod("onAttach", &JSInteractableView::JsOnAttach);
87 JSClass<JSCanvas>::StaticMethod("onAppear", &JSInteractableView::JsOnAppear);
88 JSClass<JSCanvas>::StaticMethod("onDetach", &JSInteractableView::JsOnDetach);
89 JSClass<JSCanvas>::StaticMethod("onDisAppear", &JSInteractableView::JsOnDisAppear);
90 JSClass<JSCanvas>::StaticMethod("onTouch", &JSInteractableView::JsOnTouch);
91 JSClass<JSCanvas>::StaticMethod("onHover", &JSInteractableView::JsOnHover);
92 JSClass<JSCanvas>::StaticMethod("onKeyEvent", &JSInteractableView::JsOnKey);
93 JSClass<JSCanvas>::StaticMethod("onDeleteEvent", &JSInteractableView::JsOnDelete);
94 JSClass<JSCanvas>::StaticMethod("onClick", &JSInteractableView::JsOnClick);
95 JSClass<JSCanvas>::StaticMethod("enableAnalyzer", &JSCanvas::EnableAnalyzer);
96 JSClass<JSCanvas>::InheritAndBind<JSViewAbstract>(globalObj);
97 }
98
OnReady(const JSCallbackInfo & info)99 void JSCanvas::OnReady(const JSCallbackInfo& info)
100 {
101 if (info.Length() < 1 || !info[0]->IsFunction()) {
102 return;
103 }
104
105 RefPtr<JsFunction> jsFunc = AceType::MakeRefPtr<JsFunction>(JSRef<JSObject>(), JSRef<JSFunc>::Cast(info[0]));
106 if (Container::IsCurrentUsePartialUpdate()) {
107 auto targetNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
108 auto readyEvent = [execCtx = info.GetExecutionContext(), func = std::move(jsFunc), node = targetNode]() {
109 JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
110 ACE_SCORING_EVENT("Canvas.onReady");
111 PipelineContext::SetCallBackNode(node);
112 func->Execute();
113 };
114 CanvasModel::GetInstance()->SetOnReady(std::move(readyEvent));
115 } else {
116 auto targetNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
117 auto readyEvent = [execCtx = info.GetExecutionContext(), func = std::move(jsFunc), node = targetNode](
118 uint32_t accountableCanvasElement) {
119 JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
120 ACE_SCORING_EVENT("Canvas.onReady");
121 PipelineContext::SetCallBackNode(node);
122 func->Execute();
123 };
124 CanvasModel::GetInstance()->SetOnReady(std::move(readyEvent));
125 }
126 }
127
EnableAnalyzer(bool enable)128 void JSCanvas::EnableAnalyzer(bool enable)
129 {
130 CanvasModel::GetInstance()->EnableAnalyzer(enable);
131 }
132 } // namespace OHOS::Ace::Framework
133