1 /*
2 * Copyright (c) 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/cj_frontend/interfaces/cj_ffi/cj_text_clock_ffi.h"
17
18 #include "cj_lambda.h"
19 #include "base/utils/string_utils.h"
20 #include "core/common/ace_application_info.h"
21 #include "bridge/cj_frontend/interfaces/cj_ffi/cj_view_abstract_ffi.h"
22 #include "bridge/cj_frontend/interfaces/cj_ffi/utils.h"
23 #include "bridge/common/utils/utils.h"
24 #include "core/components/common/properties/text_style_parser.h"
25
26
27 using namespace OHOS::Ace;
28 using namespace OHOS::FFI;
29 using namespace OHOS::Ace::Framework;
30
31 namespace OHOS::Ace::Framework {
32
33 namespace {
34 const std::vector<FontStyle> FONT_STYLES = { FontStyle::NORMAL, FontStyle::ITALIC };
35 const std::string DEFAULT_FORMAT_API_ELEVEN = "aa hh:mm:ss";
36 const std::string DEFAULT_FORMAT_API_TEN = "hms";
37 } // namespace
38
NativeTextClockController()39 NativeTextClockController::NativeTextClockController() : FFIData()
40 {
41 LOGI("Native TextAreaController constructed: %{public}" PRId64, GetID());
42 }
43
Start()44 void NativeTextClockController::Start()
45 {
46 if (controller_) {
47 controller_->Start();
48 }
49 }
50
Stop()51 void NativeTextClockController::Stop()
52 {
53 if (controller_) {
54 controller_->Stop();
55 }
56 }
57
58 namespace {
59 constexpr int32_t TWENTY_FOUR_HOUR_BASE = 24;
60 constexpr int32_t HOURS_WEST_LOWER_LIMIT = -14;
61 constexpr int32_t HOURS_WEST_UPPER_LIMIT = 12;
62 constexpr int32_t HOURS_WEST_GEOGRAPHICAL_LOWER_LIMIT = -12;
63
HoursWestIsValid_(int32_t hoursWest)64 bool HoursWestIsValid_(int32_t hoursWest)
65 {
66 if (hoursWest < HOURS_WEST_LOWER_LIMIT || hoursWest > HOURS_WEST_UPPER_LIMIT) {
67 return false;
68 }
69 if (hoursWest < HOURS_WEST_GEOGRAPHICAL_LOWER_LIMIT) {
70 hoursWest += TWENTY_FOUR_HOUR_BASE;
71 }
72 return true;
73 }
74 } // namespace
75
76 } // namespace OHOS::Ace::Framework
77
78 extern "C" {
FFICJCreateVectorNativeTextShadow(int64_t size)79 VectorNativeTextShadow FFICJCreateVectorNativeTextShadow(int64_t size)
80 {
81 LOGI("Create NativeTextShadow Vector");
82 return new std::vector<NativeTextShadow>(size);
83 }
84
FFICJVectorNativeTextShadowSetElement(VectorNativeTextShadow vec,int64_t index,NativeTextShadow textShadow)85 void FFICJVectorNativeTextShadowSetElement(
86 VectorNativeTextShadow vec, int64_t index, NativeTextShadow textShadow)
87 {
88 LOGI("NativeTextShadow Vector Set Element");
89 auto actualVec = reinterpret_cast<std::vector<NativeTextShadow>*>(vec);
90 (*actualVec)[index] = textShadow;
91 LOGI("NativeTextShadow Vector Set Element Success");
92 }
93
FFICJVectorNativeTextShadowDelete(VectorNativeTextShadow vec)94 void FFICJVectorNativeTextShadowDelete(VectorNativeTextShadow vec)
95 {
96 auto actualVec = reinterpret_cast<std::vector<NativeTextShadow>*>(vec);
97 delete actualVec;
98 }
99
FfiOHOSAceFrameworkTextClockCreateDefault(int64_t controllerId)100 void FfiOHOSAceFrameworkTextClockCreateDefault(int64_t controllerId)
101 {
102 auto textClock = TextClockModel::GetInstance()->Create();
103 TextClockModel::GetInstance()->SetHoursWest(NAN);
104
105 auto controller = FFIData::GetData<NativeTextClockController>(controllerId);
106 if (controller != nullptr) {
107 controller->SetController(textClock);
108 } else {
109 LOGE("textClockControllerId is invalid ");
110 }
111 }
112
FfiOHOSAceFrameworkTextClockCreate(int32_t timeZoneOffset,int64_t controllerId)113 void FfiOHOSAceFrameworkTextClockCreate(int32_t timeZoneOffset, int64_t controllerId)
114 {
115 auto textClock = TextClockModel::GetInstance()->Create();
116 if (HoursWestIsValid_(timeZoneOffset)) {
117 TextClockModel::GetInstance()->SetHoursWest(timeZoneOffset);
118 } else {
119 LOGE("timeZoneOffset is invalid");
120 }
121
122 auto controller = FFIData::GetData<NativeTextClockController>(controllerId);
123 if (controller != nullptr) {
124 controller->SetController(textClock);
125 } else {
126 LOGE("textClockControllerId is invalid ");
127 }
128 }
129
FfiOHOSAceFrameworkTextClockFormat(const char * value)130 void FfiOHOSAceFrameworkTextClockFormat(const char* value)
131 {
132 std::string format = static_cast<std::string>(value);
133 if (AceApplicationInfo::GetInstance().GreatOrEqualTargetAPIVersion(PlatformVersion::VERSION_ELEVEN)) {
134 if (format.length() == 0) {
135 TextClockModel::GetInstance()->SetFormat(DEFAULT_FORMAT_API_ELEVEN);
136 return;
137 }
138 } else {
139 std::regex pattern(
140 R"(^([Yy]*[_|\W\s]*[M]*[_|\W\s]*[d]*[_|\W\s]*[D]*[_|\W\s]*[Hh]*[_|\W\s]*[m]*[_|\W\s]*[s]*[_|\W\s]*[S]*)$)");
141 if (format.length() == 0 || !StringUtils::IsAscii(format) || !std::regex_match(format, pattern)) {
142 TextClockModel::GetInstance()->SetFormat(DEFAULT_FORMAT_API_TEN);
143 return;
144 }
145 }
146
147 TextClockModel::GetInstance()->SetFormat(format);
148 }
149
FfiOHOSAceFrameworkTextClockOnChange(void (* callback)(int64_t timeStamp))150 void FfiOHOSAceFrameworkTextClockOnChange(void (*callback)(int64_t timeStamp))
151 {
152 auto lambda = [lambda = CJLambda::Create(callback)](
153 const std::string& value) -> void { lambda(std::atol(value.c_str())); };
154 TextClockModel::GetInstance()->SetOnDateChange(lambda);
155 }
156
FfiOHOSAceFrameworkTextClockTextColor(uint32_t color)157 void FfiOHOSAceFrameworkTextClockTextColor(uint32_t color)
158 {
159 TextClockModel::GetInstance()->SetTextColor(Color(color));
160 }
161
FfiOHOSAceFrameworkTextClockFontSize(double size,int32_t unit)162 void FfiOHOSAceFrameworkTextClockFontSize(double size, int32_t unit)
163 {
164 CalcDimension fontSize = CalcDimension(size, DimensionUnit(unit));
165 TextClockModel::GetInstance()->SetFontSize(fontSize);
166 }
167
FfiOHOSAceFrameworkTextClockFontWeight(const char * fontWeight)168 void FfiOHOSAceFrameworkTextClockFontWeight(const char* fontWeight)
169 {
170 TextClockModel::GetInstance()->SetFontWeight(ConvertStrToFontWeight(fontWeight));
171 }
172
FfiOHOSAceFrameworkTextClockFontStyle(int32_t fontStyle)173 void FfiOHOSAceFrameworkTextClockFontStyle(int32_t fontStyle)
174 {
175 if (!Utils::CheckParamsValid(fontStyle, FONT_STYLES.size())) {
176 LOGE("invalid value for font style");
177 return;
178 }
179 TextClockModel::GetInstance()->SetItalicFontStyle(FONT_STYLES[fontStyle]);
180 }
181
FfiOHOSAceFrameworkTextClockFontFamily(const char * fontFamily)182 void FfiOHOSAceFrameworkTextClockFontFamily(const char* fontFamily)
183 {
184 std::vector<std::string> fontFamilies;
185 fontFamilies = ConvertStrToFontFamilies(fontFamily);
186 TextClockModel::GetInstance()->SetFontFamily(fontFamilies);
187 }
188
FfiOHOSAceFrameworkTextClockTextShadow(VectorStringPtr vecContent)189 void FfiOHOSAceFrameworkTextClockTextShadow(VectorStringPtr vecContent)
190 {
191 auto nativeTextShadowVec = *reinterpret_cast<std::vector<NativeTextShadow>*>(vecContent);
192
193 std::vector<Shadow> shadows(nativeTextShadowVec.size());
194 for (size_t i = 0; i < nativeTextShadowVec.size(); i++) {
195 Dimension dOffsetX(nativeTextShadowVec[i].offsetX, DimensionUnit::VP);
196 Dimension dOffsetY(nativeTextShadowVec[i].offsetY, DimensionUnit::VP);
197
198 shadows[i].SetBlurRadius(nativeTextShadowVec[i].radius);
199 shadows[i].SetOffsetX(dOffsetX.Value());
200 shadows[i].SetOffsetY(dOffsetY.Value());
201 shadows[i].SetColor(Color(nativeTextShadowVec[i].color));
202 }
203
204 TextClockModel::GetInstance()->SetTextShadow(shadows);
205 }
206
FfiOHOSAceFrameworkTextClockFontFeature(const char * fontFeature)207 void FfiOHOSAceFrameworkTextClockFontFeature(const char* fontFeature)
208 {
209 std::string fontFeatureSettings = fontFeature;
210 TextClockModel::GetInstance()->SetFontFeature(ParseFontFeatureSettings(fontFeatureSettings));
211 }
212
FfiOHOSAceFrameworkTextClockControllerCtor()213 int64_t FfiOHOSAceFrameworkTextClockControllerCtor()
214 {
215 auto controller = FFIData::Create<NativeTextClockController>();
216 if (controller == nullptr) {
217 return FFI_ERROR_CODE;
218 }
219 return controller->GetID();
220 }
221
FfiOHOSAceFrameworkTextClockControllerStart(int64_t selfID)222 void FfiOHOSAceFrameworkTextClockControllerStart(int64_t selfID)
223 {
224 auto self = FFIData::GetData<NativeTextClockController>(selfID);
225 if (self != nullptr) {
226 self->Start();
227 } else {
228 LOGE("FfiTextArea: invalid textClockController");
229 }
230 }
231
FfiOHOSAceFrameworkTextClockControllerStop(int64_t selfID)232 void FfiOHOSAceFrameworkTextClockControllerStop(int64_t selfID)
233 {
234 auto self = FFIData::GetData<NativeTextClockController>(selfID);
235 if (self != nullptr) {
236 self->Stop();
237 } else {
238 LOGE("FfiTextArea: invalid textClockController");
239 }
240 }
241 }
242