• 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 <algorithm>
17 #include <codecvt>
18 #include <cstdint>
19 
20 #include "ani_common.h"
21 #include "ani_font_collection.h"
22 #include "ani_paragraph.h"
23 #include "ani_paragraph_builder.h"
24 #include "ani_paragraph_style_converter.h"
25 #include "ani_text_style_converter.h"
26 #include "ani_text_utils.h"
27 #include "font_collection.h"
28 #include "text_style.h"
29 #include "utils/text_log.h"
30 
31 namespace OHOS::Text::ANI {
32 using namespace OHOS::Rosen;
Constructor(ani_env * env,ani_object object,ani_object paragraphStyle,ani_object fontCollection)33 void AniParagraphBuilder::Constructor(
34     ani_env* env, ani_object object, ani_object paragraphStyle, ani_object fontCollection)
35 {
36     std::unique_ptr<TypographyStyle> typographyStyleNative =
37         AniParagraphStyleConverter::ParseParagraphStyleToNative(env, paragraphStyle);
38     if (typographyStyleNative == nullptr) {
39         TEXT_LOGE("Failed to parse typographyStyle");
40         AniTextUtils::ThrowBusinessError(env, TextErrorCode::ERROR_INVALID_PARAM, "Invalid params.");
41         return;
42     }
43 
44     AniFontCollection* aniFontCollection = AniTextUtils::GetNativeFromObj<AniFontCollection>(env, fontCollection);
45     if (aniFontCollection == nullptr) {
46         TEXT_LOGE("FontCollection is null");
47         AniTextUtils::ThrowBusinessError(env, TextErrorCode::ERROR_INVALID_PARAM, "Invalid params.");
48         return;
49     }
50     std::shared_ptr<FontCollection> fontCollectionNative = aniFontCollection->GetFontCollection();
51     if (fontCollectionNative == nullptr) {
52         TEXT_LOGE("Failed to get font collection");
53         AniTextUtils::ThrowBusinessError(env, TextErrorCode::ERROR_INVALID_PARAM, "Invalid params.");
54         return;
55     }
56 
57     std::unique_ptr<TypographyCreate> typographyCreateNative =
58         TypographyCreate::Create(*typographyStyleNative, fontCollectionNative);
59     if (typographyCreateNative == nullptr) {
60         TEXT_LOGE("Failed to create typography creator");
61         AniTextUtils::ThrowBusinessError(env, TextErrorCode::ERROR_INVALID_PARAM, "TypographyCreate create error.");
62         return;
63     }
64 
65     TypographyCreate* typographyCreate = typographyCreateNative.release();
66     ani_status ret = env->Object_SetFieldByName_Long(object, NATIVE_OBJ, reinterpret_cast<ani_long>(typographyCreate));
67     if (ret != ANI_OK) {
68         TEXT_LOGE("Failed to create ani ParagraphBuilder obj");
69         delete typographyCreate;
70         typographyCreate = nullptr;
71         AniTextUtils::ThrowBusinessError(env, TextErrorCode::ERROR_INVALID_PARAM, "AniParagraphBuilder create error.");
72         return;
73     }
74 }
75 
AniInit(ani_vm * vm,uint32_t * result)76 ani_status AniParagraphBuilder::AniInit(ani_vm* vm, uint32_t* result)
77 {
78     ani_env* env;
79     ani_status ret = vm->GetEnv(ANI_VERSION_1, &env);
80     if (ret != ANI_OK) {
81         TEXT_LOGE("null env, ret %{public}d", ret);
82         return ANI_NOT_FOUND;
83     }
84 
85     ani_class cls = nullptr;
86     ret = env->FindClass(ANI_CLASS_PARAGRAPH_BUILDER, &cls);
87     if (ret != ANI_OK) {
88         TEXT_LOGE("Failed to  find class, ret %{public}d", ret);
89         return ANI_NOT_FOUND;
90     }
91 
92     std::string ctorSignature =
93         std::string(ANI_INTERFACE_PARAGRAPH_STYLE) + std::string(ANI_CLASS_FONT_COLLECTION) + ":V";
94     std::string pushStyleSignature = std::string(ANI_INTERFACE_TEXT_STYLE) + ":V";
95     std::string buildStyleSignature = ":" + std::string(ANI_CLASS_PARAGRAPH);
96     std::array methods = {
97         ani_native_function{"constructorNative", ctorSignature.c_str(), reinterpret_cast<void*>(Constructor)},
98         ani_native_function{"pushStyle", pushStyleSignature.c_str(), reinterpret_cast<void*>(PushStyle)},
99         ani_native_function{"popStyle", ":V", reinterpret_cast<void*>(PopStyle)},
100         ani_native_function{"addText", "Lstd/core/String;:V", reinterpret_cast<void*>(AddText)},
101         ani_native_function{"build", buildStyleSignature.c_str(), reinterpret_cast<void*>(Build)},
102     };
103 
104     ret = env->Class_BindNativeMethods(cls, methods.data(), methods.size());
105     if (ret != ANI_OK) {
106         TEXT_LOGE("Failed to bind methods, ret %{public}d", ret);
107         return ANI_NOT_FOUND;
108     }
109     return ANI_OK;
110 }
111 
PushStyle(ani_env * env,ani_object object,ani_object textStyle)112 void AniParagraphBuilder::PushStyle(ani_env* env, ani_object object, ani_object textStyle)
113 {
114     TypographyCreate* typographyCreate = AniTextUtils::GetNativeFromObj<TypographyCreate>(env, object);
115     if (typographyCreate == nullptr) {
116         TEXT_LOGE("ParagraphBuilder is null");
117         AniTextUtils::ThrowBusinessError(env, TextErrorCode::ERROR_INVALID_PARAM, "Invalid params.");
118         return;
119     }
120     TextStyle textStyleNative;
121     ani_status status = AniTextStyleConverter::ParseTextStyleToNative(env, textStyle, textStyleNative);
122     if (status == ANI_OK) {
123         typographyCreate->PushStyle(textStyleNative);
124     }
125 }
126 
PopStyle(ani_env * env,ani_object object)127 void AniParagraphBuilder::PopStyle(ani_env* env, ani_object object)
128 {
129     TypographyCreate* typographyCreate = AniTextUtils::GetNativeFromObj<TypographyCreate>(env, object);
130     if (typographyCreate == nullptr) {
131         TEXT_LOGE("ParagraphBuilder is null");
132         AniTextUtils::ThrowBusinessError(env, TextErrorCode::ERROR_INVALID_PARAM, "Invalid params.");
133         return;
134     }
135 
136     typographyCreate->PopStyle();
137 }
138 
AddText(ani_env * env,ani_object object,ani_string text)139 void AniParagraphBuilder::AddText(ani_env* env, ani_object object, ani_string text)
140 {
141     std::u16string textStr;
142     ani_status status = AniTextUtils::AniToStdStringUtf16(env, text, textStr);
143     if (status != ANI_OK) {
144         AniTextUtils::ThrowBusinessError(env, TextErrorCode::ERROR_INVALID_PARAM, "Fail get utf16.");
145         return;
146     }
147     TypographyCreate* typographyCreate = AniTextUtils::GetNativeFromObj<TypographyCreate>(env, object);
148     if (typographyCreate == nullptr) {
149         TEXT_LOGE("ParagraphBuilder is null");
150         AniTextUtils::ThrowBusinessError(env, TextErrorCode::ERROR_INVALID_PARAM, "Invalid params.");
151         return;
152     }
153     typographyCreate->AppendText(textStr);
154 }
155 
Build(ani_env * env,ani_object object)156 ani_object AniParagraphBuilder::Build(ani_env* env, ani_object object)
157 {
158     TypographyCreate* typographyCreate = AniTextUtils::GetNativeFromObj<TypographyCreate>(env, object);
159     if (typographyCreate == nullptr) {
160         TEXT_LOGE("ParagraphBuilder is null");
161         AniTextUtils::ThrowBusinessError(env, TextErrorCode::ERROR_INVALID_PARAM, "Invalid params.");
162         return AniTextUtils::CreateAniUndefined(env);
163     }
164     std::unique_ptr<OHOS::Rosen::Typography> typography = typographyCreate->CreateTypography();
165     return AniParagraph::SetTypography(env, typography);
166 }
167 } // namespace OHOS::Text::ANI