• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2025 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/style_string/js_text_layout.h"
17 
18 #include <unordered_set>
19 
20 #if !defined(PREVIEW) && defined (OHOS_STANDARD_SYSTEM)
21 #include "paragraph_napi/js_paragraph.h"
22 #include "core/components_ng/render/adapter/txt_paragraph.h"
23 #endif
24 
25 #include "base/utils/utils.h"
26 #include "bridge/common/utils/engine_helper.h"
27 #include "bridge/common/utils/utils.h"
28 #include "bridge/declarative_frontend/jsview/js_utils.h"
29 #include "bridge/declarative_frontend/engine/js_converter.h"
30 #include "bridge/declarative_frontend/engine/functions/js_function.h"
31 #include "bridge/declarative_frontend/jsview/js_view_abstract.h"
32 #include "bridge/declarative_frontend/style_string/js_span_object.h"
33 #include "bridge/declarative_frontend/style_string/js_span_string.h"
34 
35 #include "core/common/ace_engine.h"
36 #include "core/common/container.h"
37 #include "core/common/container_scope.h"
38 #include "core/components_ng/pattern/text/span/mutable_span_string.h"
39 #include "core/components_ng/pattern/text/span/span_object.h"
40 
41 
42 namespace OHOS::Ace::Framework {
43 namespace {
44 constexpr int32_t CONST_NUM_SIX = 6;
45 constexpr int32_t CONST_NUM_MINUS_TWO = -2;
46 #if !defined(PREVIEW) && defined(OHOS_PLATFORM)
47 constexpr int32_t CONST_NUM_TWO = 2;
48 #endif
49 } // namespace
50 
ParseLengthMetrics(const JSRef<JSObject> & obj)51 CalcDimension JSTextLayout::ParseLengthMetrics(const JSRef<JSObject>& obj)
52 {
53     CalcDimension size;
54     auto value = 0.0;
55     auto valueObj = obj->GetProperty("value");
56     if (!valueObj->IsNull() && valueObj->IsNumber()) {
57         value = valueObj->ToNumber<float>();
58     }
59     auto unit = DimensionUnit::VP;
60     auto unitObj = obj->GetProperty("unit");
61     if (!unitObj->IsNull() && unitObj->IsNumber()) {
62         auto unitNum = unitObj->ToNumber<int32_t>();
63         if (unitNum >= CONST_NUM_MINUS_TWO && unitNum <= CONST_NUM_SIX) {
64             unit = static_cast<DimensionUnit>(unitNum);
65         }
66     }
67     if (value >= 0 && unit != DimensionUnit::PERCENT) {
68         size = CalcDimension(value, unit);
69     }
70     return size;
71 }
72 
GetParagraphs(const JSCallbackInfo & info)73 void JSTextLayout::GetParagraphs(const JSCallbackInfo& info)
74 {
75 #if !defined(PREVIEW) && defined(OHOS_PLATFORM)
76     if (info.Length() > CONST_NUM_TWO || !info[0]->IsObject()) {
77         JSException::Throw(ERROR_CODE_PARAM_INVALID, "%s", "Input parameter check failed.");
78         return;
79     }
80     auto* spanString = JSRef<JSObject>::Cast(info[0])->Unwrap<JSSpanString>();
81     if (!spanString || !spanString->GetController()) {
82         JSException::Throw(ERROR_CODE_PARAM_INVALID, "%s", "Invalid styled string.");
83         return;
84     }
85     auto spanStringController = spanString->GetController();
86 
87     std::optional<double> constraintWidth;
88     if (info.Length() == CONST_NUM_TWO && info[1]->IsObject()) {
89         auto paramObject = JSRef<JSObject>::Cast(info[1]);
90         if (paramObject->HasProperty("constraintWidth")) {
91             auto constraintWidthJSVal = paramObject->GetProperty("constraintWidth");
92             if (!constraintWidthJSVal->IsNull() && constraintWidthJSVal->IsObject()) {
93                 constraintWidth = ParseLengthMetrics(constraintWidthJSVal).ConvertToPx();
94             }
95         }
96     }
97     auto engine = EngineHelper::GetCurrentEngineSafely();
98     CHECK_NULL_VOID(engine);
99     NativeEngine* nativeEngine = engine->GetNativeEngine();
100     CHECK_NULL_VOID(nativeEngine);
101     napi_env env = reinterpret_cast<napi_env>(nativeEngine);
102     ScopeRAII scope(env);
103 
104     auto paraVec = SpanString::GetLayoutInfo(spanStringController, constraintWidth);
105     JSRef<JSArray> paragraphJSArray = JSRef<JSArray>::New();
106     uint32_t idx = 0;
107     for (auto para : paraVec) {
108         auto paragraph = AceType::DynamicCast<NG::TxtParagraph>(para);
109         if (!paragraph) {
110             continue;
111         }
112         auto jsParagraph = OHOS::Rosen::JsParagraph::CreateJsTypography(env,
113             paragraph->GetParagraphUniquePtr());
114         JsiRef<JsiValue> jsParagraphVal = JsConverter::ConvertNapiValueToJsVal(jsParagraph);
115         if (!jsParagraphVal->IsObject()) {
116             continue;
117         }
118         paragraphJSArray->SetValueAt(idx++, JSRef<JSObject>::Cast(jsParagraphVal));
119     }
120     info.SetReturnValue(JSRef<JSVal>::Cast(paragraphJSArray));
121 #else
122     JSRef<JSArray> paragraphJSArray = JSRef<JSArray>::New();
123     info.SetReturnValue(JSRef<JSVal>::Cast(paragraphJSArray));
124 #endif
125 }
126 
JSBind(BindingTarget globalObj)127 void JSTextLayout::JSBind(BindingTarget globalObj)
128 {
129     JSClass<JSTextLayout>::Declare("TextLayout");
130     JSClass<JSTextLayout>::StaticMethod("getParagraphs", &JSTextLayout::GetParagraphs);
131     JSClass<JSTextLayout>::Bind(globalObj, JSTextLayout::Constructor, JSTextLayout::Destructor);
132 }
133 } // namespace OHOS::Ace::Framework