1 /*
2 * Copyright (c) 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 "frameworks/bridge/declarative_frontend/jsview/js_image_span.h"
17 #include "frameworks/bridge/declarative_frontend/jsview/js_container_span.h"
18
19 #if !defined(PREVIEW)
20 #include <dlfcn.h>
21 #endif
22
23 #include "base/log/ace_scoring_log.h"
24 #include "core/components/common/layout/constants.h"
25 #include "core/components_ng/pattern/image/image_model.h"
26 #include "core/components_ng/pattern/text/image_span_view.h"
27 #include "bridge/declarative_frontend/jsview/js_view_common_def.h"
28 #include "bridge/declarative_frontend/engine/functions/js_event_function.h"
29 #include "frameworks/bridge/declarative_frontend/jsview/js_image.h"
30
31 namespace OHOS::Ace::Framework {
32 const std::vector<float> DEFAULT_COLORFILTER_MATRIX = {
33 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f,
34 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f
35 };
36
Create(const JSCallbackInfo & info)37 void JSImageSpan::Create(const JSCallbackInfo& info)
38 {
39 if (!Container::IsCurrentUseNewPipeline()) {
40 return;
41 }
42 if (info.Length() != 1) {
43 return;
44 }
45 JSImage::CreateImage(info, true);
46 NG::ImageSpanView::Create();
47 }
48
SetAlt(const JSCallbackInfo & info)49 void JSImageSpan::SetAlt(const JSCallbackInfo& info)
50 {
51 if (!Container::IsCurrentUseNewPipeline()) {
52 return;
53 }
54 if (info.Length() < 1) {
55 return;
56 }
57 JSImage::SetAlt(info);
58 }
59
SetObjectFit(const JSCallbackInfo & info)60 void JSImageSpan::SetObjectFit(const JSCallbackInfo& info)
61 {
62 if (info.Length() != 1) {
63 return;
64 }
65
66 JSRef<JSVal> args = info[0];
67 if (args->IsNumber()) {
68 auto fit = static_cast<ImageFit>(args->ToNumber<int32_t>());
69 if (fit < ImageFit::FILL || fit > ImageFit::BOTTOM_END) {
70 fit = ImageFit::COVER;
71 }
72 ImageModel::GetInstance()->SetImageFit(fit);
73 } else {
74 ImageModel::GetInstance()->SetImageFit(ImageFit::COVER);
75 }
76 }
77
SetVerticalAlign(int32_t verticalAlign)78 void JSImageSpan::SetVerticalAlign(int32_t verticalAlign)
79 {
80 auto align = static_cast<VerticalAlign>(verticalAlign);
81 if (align < VerticalAlign::TOP || align > VerticalAlign::NONE) {
82 align = VerticalAlign::BOTTOM;
83 }
84 NG::ImageSpanView::SetVerticalAlign(align);
85 }
86
SetTextBackgroundStyle(const JSCallbackInfo & info)87 void JSImageSpan::SetTextBackgroundStyle(const JSCallbackInfo& info)
88 {
89 auto textBackgroundStyle = JSContainerSpan::ParseTextBackgroundStyle(info);
90 NG::ImageSpanView::SetPlaceHolderStyle(textBackgroundStyle);
91 }
92
OnComplete(const JSCallbackInfo & args)93 void JSImageSpan::OnComplete(const JSCallbackInfo& args)
94 {
95 JSRef<JSVal> arg = args[0];
96 if (arg->IsFunction()) {
97 auto jsLoadSuccFunc = AceType::MakeRefPtr<JsEventFunction<LoadImageSuccessEvent, 1>>(
98 JSRef<JSFunc>::Cast(arg), LoadImageSuccEventToJSValue);
99
100 auto onComplete = [execCtx = args.GetExecutionContext(), func = std::move(jsLoadSuccFunc)](
101 const LoadImageSuccessEvent& info) {
102 JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
103 ACE_SCORING_EVENT("ImageSpan.onComplete");
104 func->Execute(info);
105 };
106 ImageModel::GetInstance()->SetOnComplete(std::move(onComplete));
107 }
108 }
109
OnError(const JSCallbackInfo & args)110 void JSImageSpan::OnError(const JSCallbackInfo& args)
111 {
112 JSRef<JSVal> arg = args[0];
113 if (arg->IsFunction()) {
114 auto jsLoadFailFunc = AceType::MakeRefPtr<JsEventFunction<LoadImageFailEvent, 1>>(
115 JSRef<JSFunc>::Cast(arg), LoadImageFailEventToJSValue);
116 auto onError = [execCtx = args.GetExecutionContext(), func = std::move(jsLoadFailFunc)](
117 const LoadImageFailEvent& info) {
118 JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
119 ACE_SCORING_EVENT("ImageSpan.onError");
120 func->Execute(info);
121 };
122 ImageModel::GetInstance()->SetOnError(onError);
123 }
124 }
125
SetBaselineOffset(const JSCallbackInfo & info)126 void JSImageSpan::SetBaselineOffset(const JSCallbackInfo& info)
127 {
128 if (info.Length() < 1) {
129 return;
130 }
131 NG::CalcLength value;
132 RefPtr<ResourceObject> resObj;
133 UnRegisterResource("BaselineOffset");
134 if (ConvertFromJSValueNG(info[0], value, resObj) &&
135 value.GetDimensionContainsNegative().Unit() != DimensionUnit::PERCENT) {
136 NG::ImageSpanView::SetBaselineOffset(value.GetDimensionContainsNegative());
137 if (SystemProperties::ConfigChangePerform() && resObj) {
138 RegisterResource<CalcDimension>("BaselineOffset", resObj,
139 value.GetDimensionContainsNegative());
140 }
141 return;
142 }
143 value.Reset();
144 NG::ImageSpanView::SetBaselineOffset(value.GetDimensionContainsNegative());
145 }
146
SetColorFilter(const JSCallbackInfo & info)147 void JSImageSpan::SetColorFilter(const JSCallbackInfo& info)
148 {
149 if (info.Length() != 1) {
150 ImageModel::GetInstance()->SetColorFilterMatrix(DEFAULT_COLORFILTER_MATRIX);
151 return;
152 }
153 auto tmpInfo = info[0];
154 if (!tmpInfo->IsArray() && !tmpInfo->IsObject()) {
155 ImageModel::GetInstance()->SetColorFilterMatrix(DEFAULT_COLORFILTER_MATRIX);
156 return;
157 }
158 if (tmpInfo->IsObject() && !tmpInfo->IsArray()) {
159 auto drawingColorFilter = CreateDrawingColorFilter(tmpInfo);
160 if (drawingColorFilter) {
161 ImageModel::GetInstance()->SetDrawingColorFilter(drawingColorFilter);
162 return;
163 }
164 JSColorFilter* colorFilter;
165 if (!tmpInfo->IsUndefined() && !tmpInfo->IsNull()) {
166 colorFilter = JSRef<JSObject>::Cast(tmpInfo)->Unwrap<JSColorFilter>();
167 } else {
168 ImageModel::GetInstance()->SetColorFilterMatrix(DEFAULT_COLORFILTER_MATRIX);
169 return;
170 }
171 if (colorFilter && colorFilter->GetColorFilterMatrix().size() == COLOR_FILTER_MATRIX_SIZE) {
172 ImageModel::GetInstance()->SetColorFilterMatrix(colorFilter->GetColorFilterMatrix());
173 return;
174 }
175 ImageModel::GetInstance()->SetColorFilterMatrix(DEFAULT_COLORFILTER_MATRIX);
176 return;
177 }
178 JSRef<JSArray> array = JSRef<JSArray>::Cast(tmpInfo);
179 if (array->Length() != COLOR_FILTER_MATRIX_SIZE) {
180 ImageModel::GetInstance()->SetColorFilterMatrix(DEFAULT_COLORFILTER_MATRIX);
181 return;
182 }
183 std::vector<float> colorfilter;
184 for (size_t i = 0; i < array->Length(); i++) {
185 JSRef<JSVal> value = array->GetValueAt(i);
186 if (value->IsNumber()) {
187 colorfilter.emplace_back(value->ToNumber<float>());
188 } else {
189 ImageModel::GetInstance()->SetColorFilterMatrix(DEFAULT_COLORFILTER_MATRIX);
190 return;
191 }
192 }
193 ImageModel::GetInstance()->SetColorFilterMatrix(colorfilter);
194 }
195
JSBind(BindingTarget globalObj)196 void JSImageSpan::JSBind(BindingTarget globalObj)
197 {
198 JSClass<JSImageSpan>::Declare("ImageSpan");
199 MethodOptions opt = MethodOptions::NONE;
200 JSClass<JSImageSpan>::StaticMethod("create", &JSImageSpan::Create, opt);
201 JSClass<JSImageSpan>::StaticMethod("alt", &JSImageSpan::SetAlt, opt);
202 JSClass<JSImageSpan>::StaticMethod("objectFit", &JSImageSpan::SetObjectFit);
203 JSClass<JSImageSpan>::StaticMethod("verticalAlign", &JSImageSpan::SetVerticalAlign);
204 JSClass<JSImageSpan>::StaticMethod("textBackgroundStyle", &JSImageSpan::SetTextBackgroundStyle);
205 JSClass<JSImageSpan>::StaticMethod("onComplete", &JSImageSpan::OnComplete);
206 JSClass<JSImageSpan>::StaticMethod("onError", &JSImageSpan::OnError);
207 JSClass<JSImageSpan>::StaticMethod("border", &JSImage::JsBorder);
208 JSClass<JSImageSpan>::StaticMethod("borderRadius", &JSImage::JsBorderRadius);
209 JSClass<JSImageSpan>::StaticMethod("colorFilter", &JSImageSpan::SetColorFilter, opt);
210 JSClass<JSImageSpan>::StaticMethod("baselineOffset", &JSImageSpan::SetBaselineOffset);
211 JSClass<JSImageSpan>::InheritAndBind<JSViewAbstract>(globalObj);
212 }
213 } // namespace OHOS::Ace::Framework
214