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 "foundation/multimedia/image_framework/frameworks/kits/cj/include/pixel_map_impl.h"
17 #include "bridge/cj_frontend/interfaces/cj_ffi/cj_richeditor_controller_ffi.h"
18 #include "bridge/cj_frontend/interfaces/cj_ffi/utils.h"
19 #include "bridge/common/utils/utils.h"
20 
21 using namespace OHOS::Ace;
22 using namespace OHOS::FFI;
23 using namespace OHOS::Ace::Framework;
24 
25 namespace {
26 
27 const int64_t SUB_FLAG = 2;
28 
29 std::vector<FontStyle> FONTSTYLE_TYPES = {
30     FontStyle::NORMAL, FontStyle::ITALIC
31 };
32 
33 std::vector<TextDecoration> TEXTDECORATION_TYPES = {
34     TextDecoration::NONE,
35     TextDecoration::UNDERLINE,
36     TextDecoration::OVERLINE,
37     TextDecoration::LINE_THROUGH
38 };
39 
40 std::vector<TextAlign> TEXT_ALIGNS = {
41     TextAlign::START,
42     TextAlign::CENTER,
43     TextAlign::END,
44     TextAlign::LEFT,
45     TextAlign::RIGHT,
46     TextAlign::JUSTIFY
47 };
48 
49 std::vector<VerticalAlign> VERTICAL_ALIGNS = {
50     VerticalAlign::TOP,
51     VerticalAlign::CENTER,
52     VerticalAlign::BOTTOM,
53     VerticalAlign::BASELINE
54 };
55 
56 std::vector<ImageFit> IMAGEFIT_TYPES = {
57     ImageFit::FILL,
58     ImageFit::CONTAIN,
59     ImageFit::COVER,
60     ImageFit::NONE,
61     ImageFit::SCALE_DOWN,
62     ImageFit::FITWIDTH
63 };
64 
65 std::vector<MarginType> MARGIN_TYPES = {
66     MarginType::NONE,
67     MarginType::MARGIN_LENGTH,
68     MarginType::MARGIN_PLACEHOLDER
69 };
70 }
71 
72 namespace OHOS::Ace::Framework {
ParseTextStyleResult(const TextStyleResult & textStyle,NativeRichEditorTextStyleResult & nativeTextStyle)73 void NativeRichEditorController::ParseTextStyleResult(
74     const TextStyleResult& textStyle, NativeRichEditorTextStyleResult& nativeTextStyle)
75 {
76     nativeTextStyle.fontColor = textStyle.fontColor.c_str();
77     nativeTextStyle.fontSize = textStyle.fontSize;
78     nativeTextStyle.fontStyle = textStyle.fontStyle;
79     nativeTextStyle.fontWeight = textStyle.fontWeight;
80     nativeTextStyle.fontFamily = textStyle.fontFamily.c_str();
81     NativeTextDecorationResult decoration;
82     decoration.type = textStyle.decorationType;
83     decoration.color = textStyle.decorationColor.c_str();
84     nativeTextStyle.decoration = decoration;
85 }
86 
ParseRichEditorTextSpanResult(const ResultObject & spanObject,NativeRichEditorTextSpanResult & nativeTextResult)87 void NativeRichEditorController::ParseRichEditorTextSpanResult(
88     const ResultObject& spanObject, NativeRichEditorTextSpanResult& nativeTextResult)
89 {
90     NativeRichEditorSpanPosition spanPosition;
91     spanPosition.spanIndex = spanObject.spanPosition.spanIndex;
92     spanPosition.spanStart = spanObject.spanPosition.spanRange[0];
93     spanPosition.spanEnd = spanObject.spanPosition.spanRange[1];
94     NativeRichEditorTextStyleResult nativeTextStyle;
95     ParseTextStyleResult(spanObject.textStyle, nativeTextStyle);
96 
97     nativeTextResult.textStyle = nativeTextStyle;
98     nativeTextResult.offsetInSpanStart = spanObject.offsetInSpan[0];
99     nativeTextResult.offsetInSpanEnd = spanObject.offsetInSpan[1];
100     nativeTextResult.spanPosition = spanPosition;
101     auto len = spanObject.valueString.size() + 1;
102     char* cString = static_cast<char*>(malloc(sizeof(char) * len));
103     if (cString == nullptr) {
104         LOGE("ParseRichEditorTextSpanResult error, malloc cString failed");
105         return;
106     }
107     std::char_traits<char>::copy(cString, spanObject.valueString.c_str(), len);
108     nativeTextResult.value = cString;
109 }
110 
ParseRichEditorImageSpanResult(const ResultObject & spanObject,NativeRichEditorImageSpanResult & nativeImageResult)111 void NativeRichEditorController::ParseRichEditorImageSpanResult(
112     const ResultObject& spanObject, NativeRichEditorImageSpanResult& nativeImageResult)
113 {
114     nativeImageResult.width = spanObject.imageStyle.size[0];
115     nativeImageResult.height = spanObject.imageStyle.size[1];
116     nativeImageResult.verticalAlign = spanObject.imageStyle.verticalAlign;
117     nativeImageResult.objectFit = spanObject.imageStyle.objectFit;
118 }
119 
ParseRichEditorAbstractTextSpanResult(const NG::RichEditorAbstractSpanResult & spanObject,NativeRichEditorTextSpanResult & nativeTextResult)120 void NativeRichEditorController::ParseRichEditorAbstractTextSpanResult(
121     const NG::RichEditorAbstractSpanResult& spanObject, NativeRichEditorTextSpanResult& nativeTextResult)
122 {
123     NativeRichEditorSpanPosition spanPosition;
124     spanPosition.spanIndex = spanObject.GetSpanIndex();
125     spanPosition.spanStart = spanObject.GetSpanRangeStart();
126     spanPosition.spanEnd = spanObject.GetSpanRangeEnd();
127     NativeRichEditorTextStyleResult nativeTextStyle;
128     nativeTextStyle.fontColor = spanObject.GetFontColor().c_str();
129     nativeTextStyle.fontSize = spanObject.GetFontSize();
130     nativeTextStyle.fontStyle = static_cast<int32_t>(spanObject.GetFontStyle());
131     nativeTextStyle.fontWeight = spanObject.GetFontWeight();
132     nativeTextStyle.fontFamily = spanObject.GetFontFamily().c_str();
133     NativeTextDecorationResult decoration;
134     decoration.type = static_cast<int32_t>(spanObject.GetTextDecoration());
135     decoration.color = spanObject.GetColor().c_str();
136     nativeTextStyle.decoration = decoration;
137 
138     nativeTextResult.textStyle = nativeTextStyle;
139     nativeTextResult.offsetInSpanStart = spanObject.OffsetInSpan();
140     nativeTextResult.offsetInSpanEnd = spanObject.OffsetInSpan() + spanObject.GetEraseLength();
141     nativeTextResult.spanPosition = spanPosition;
142     nativeTextResult.value = spanObject.GetValue().c_str();
143 }
144 
ParseRichEditorAbstractImageSpanResult(const NG::RichEditorAbstractSpanResult & spanObject,NativeRichEditorImageSpanResult & nativeImageResult)145 void NativeRichEditorController::ParseRichEditorAbstractImageSpanResult(
146     const NG::RichEditorAbstractSpanResult& spanObject, NativeRichEditorImageSpanResult& nativeImageResult)
147 {
148     nativeImageResult.width = spanObject.GetSizeWidth();
149     nativeImageResult.height = spanObject.GetSizeHeight();
150     nativeImageResult.verticalAlign = static_cast<int32_t>(spanObject.GetVerticalAlign());
151     nativeImageResult.objectFit = static_cast<int32_t>(spanObject.GetObjectFit());
152 }
153 
NativeRichEditorController()154 NativeRichEditorController::NativeRichEditorController() : FFIData()
155 {
156     LOGI("Native TextAreaController constructed: %{public}" PRId64, GetID());
157 }
158 
GetCaretOffset()159 int32_t NativeRichEditorController::GetCaretOffset()
160 {
161     auto controller = controller_.Upgrade();
162     int32_t caretOffset = -1;
163     if (controller) {
164         caretOffset = controller->GetCaretOffset();
165     }
166     return caretOffset;
167 }
168 
SetCaretOffset(int32_t value)169 bool NativeRichEditorController::SetCaretOffset(int32_t value)
170 {
171     auto controller = controller_.Upgrade();
172     int32_t caretPosition = value;
173     bool success = false;
174 
175     if (controller) {
176         success = controller->SetCaretOffset(caretPosition);
177     }
178     return success;
179 }
180 
AddTextSpan(std::string value,NativeRichEditorTextSpanOptions params)181 int32_t NativeRichEditorController::AddTextSpan(std::string value, NativeRichEditorTextSpanOptions params)
182 {
183     TextSpanOptions options;
184     options.value = value;
185     options.offset = params.offset;
186 
187     auto pipelineContext = PipelineBase::GetCurrentContext();
188     if (!pipelineContext) {
189         return -1;
190     }
191     auto theme = pipelineContext->GetTheme<TextTheme>();
192     TextStyle style = theme ? theme->GetTextStyle() : TextStyle();
193 
194     ParseTextStyle(params.style, style);
195     options.style = style;
196 
197     int32_t spanIndex = 0;
198     auto controller = controller_.Upgrade();
199     auto richEditorController = AceType::DynamicCast<RichEditorControllerBase>(controller);
200     if (richEditorController) {
201         spanIndex = richEditorController->AddTextSpan(options);
202     }
203     return spanIndex;
204 }
205 
ParseTextStyle(const NativeRichEditorTextStyle & nativeStyle,TextStyle & style)206 void NativeRichEditorController::ParseTextStyle(const NativeRichEditorTextStyle& nativeStyle, TextStyle& style)
207 {
208     if (!Utils::CheckParamsValid(nativeStyle.fontStyle, FONTSTYLE_TYPES.size())) {
209         LOGE("AddTextSpan error, invalid value for fontStyle");
210     }
211 
212     if (!Utils::CheckParamsValid(nativeStyle.decoration.type, TEXTDECORATION_TYPES.size())) {
213         LOGE("AddTextSpan error, invalid value for fontStyle");
214     }
215 
216     auto fontColor = Color(nativeStyle.fontColor);
217     style.SetTextColor(fontColor);
218     updateSpanStyle_.updateTextColor = fontColor;
219     auto size = CalcDimension(nativeStyle.fontSize, static_cast<DimensionUnit>(nativeStyle.fontSizeUnit));
220     style.SetFontSize(size);
221     updateSpanStyle_.updateFontSize = size;
222     style.SetFontStyle(FONTSTYLE_TYPES[nativeStyle.fontStyle]);
223     updateSpanStyle_.updateItalicFontStyle = FONTSTYLE_TYPES[nativeStyle.fontStyle];
224     auto fontWeight = ConvertStrToFontWeight(nativeStyle.fontWeight);
225     style.SetFontWeight(fontWeight);
226     updateSpanStyle_.updateFontWeight = fontWeight;
227     auto fontFamily = ConvertStrToFontFamilies(nativeStyle.fontFamily);
228     style.SetFontFamilies(fontFamily);
229     updateSpanStyle_.updateFontFamily = fontFamily;
230     style.SetTextDecoration(TEXTDECORATION_TYPES[nativeStyle.decoration.type]);
231     updateSpanStyle_.updateTextDecoration = TEXTDECORATION_TYPES[nativeStyle.decoration.type];
232     auto decorationColor = Color(nativeStyle.decoration.color);
233     style.SetTextDecorationColor(decorationColor);
234     updateSpanStyle_.updateTextDecorationColor = decorationColor;
235 }
236 
AddImageSpan(std::string value,NativeRichEditorImageSpanOptions params)237 int32_t NativeRichEditorController::AddImageSpan(std::string value, NativeRichEditorImageSpanOptions params)
238 {
239     int32_t spanIndex = 0;
240     ImageSpanOptions options;
241     auto context = PipelineBase::GetCurrentContext();
242     bool isCard = context->IsFormRender();
243     std::string image = value;
244     std::string bundleName;
245     std::string moduleName;
246     if (isCard) {
247         SrcType srcType = ImageSourceInfo::ResolveURIType(image);
248         bool notSupport =
249             (srcType == SrcType::NETWORK || srcType == SrcType::FILE || srcType == SrcType::DATA_ABILITY);
250         if (notSupport) {
251             image.clear();
252         }
253     }
254     options.image = image;
255     options.bundleName = bundleName;
256     options.moduleName = moduleName;
257 
258     std::string assetSrc = options.image.value();
259     SrcType srcType = ImageSourceInfo::ResolveURIType(assetSrc);
260     if (assetSrc[0] == '/') {
261         assetSrc = assetSrc.substr(1); // get the asset src without '/'.
262     } else if (assetSrc[0] == '.' && assetSrc.size() > SUB_FLAG && assetSrc[1] == '/') {
263         assetSrc = assetSrc.substr(2); // get the asset src without './'.
264     }
265     if (srcType == SrcType::ASSET) {
266         auto pipelineContext = PipelineBase::GetCurrentContext();
267         CHECK_NULL_RETURN(pipelineContext, -1);
268         auto assetManager = pipelineContext->GetAssetManager();
269         CHECK_NULL_RETURN(assetManager, -1);
270         auto assetData = assetManager->GetAsset(assetSrc);
271         CHECK_NULL_RETURN(assetData, -1);
272     }
273 
274     options.offset = params.offset;
275     ImageSpanAttribute imageStyle;
276     ParseImageSpanStyle(params.imageStyle, imageStyle);
277     options.imageAttribute = imageStyle;
278     auto controller = controller_.Upgrade();
279     auto richEditorController = AceType::DynamicCast<RichEditorControllerBase>(controller);
280     if (richEditorController) {
281         spanIndex = richEditorController->AddImageSpan(options);
282     }
283     return spanIndex;
284 }
285 
ParseImageSpanStyle(const NativeRichEditorImageSpanStyle & nativeStyle,ImageSpanAttribute & imageStyle)286 void NativeRichEditorController::ParseImageSpanStyle(
287     const NativeRichEditorImageSpanStyle& nativeStyle, ImageSpanAttribute& imageStyle)
288 {
289     if (nativeStyle.width.hasValue && nativeStyle.height.hasValue) {
290         ImageSpanSize imageSize;
291 
292         auto imageSpanWidth = CalcDimension(
293             nativeStyle.width.value,
294             static_cast<DimensionUnit>(nativeStyle.width.unit)
295         );
296         imageSize.width = imageSpanWidth;
297         updateSpanStyle_.updateImageWidth = imageSpanWidth;
298 
299         auto imageSpanHeight = CalcDimension(
300             nativeStyle.height.value,
301             static_cast<DimensionUnit>(nativeStyle.height.unit)
302         );
303         imageSize.height = imageSpanHeight;
304         updateSpanStyle_.updateImageHeight = imageSpanHeight;
305 
306         imageStyle.size = imageSize;
307     }
308 
309     auto align = VERTICAL_ALIGNS[nativeStyle.verticalAlign];
310     imageStyle.verticalAlign = align;
311     updateSpanStyle_.updateImageVerticalAlign = align;
312 
313     auto fit = IMAGEFIT_TYPES[nativeStyle.objectFit];
314     imageStyle.objectFit = fit;
315     updateSpanStyle_.updateImageFit = fit;
316 }
317 
DeleteSpans(int32_t start,int32_t end)318 void NativeRichEditorController::DeleteSpans(int32_t start, int32_t end)
319 {
320     RangeOptions options;
321 
322     options.start = start;
323     options.end = end;
324 
325     auto controller = controller_.Upgrade();
326     auto richEditorController = AceType::DynamicCast<RichEditorControllerBase>(controller);
327     if (richEditorController) {
328         richEditorController->DeleteSpans(options);
329     }
330 }
331 
DeleteAllSpans()332 void NativeRichEditorController::DeleteAllSpans()
333 {
334     RangeOptions options;
335 
336     auto controller = controller_.Upgrade();
337     auto richEditorController = AceType::DynamicCast<RichEditorControllerBase>(controller);
338     if (richEditorController) {
339         richEditorController->DeleteSpans(options);
340     }
341 }
342 
CloseSelectionMenu()343 void NativeRichEditorController::CloseSelectionMenu()
344 {
345     auto controller = controller_.Upgrade();
346     if (controller) {
347         controller->CloseSelectionMenu();
348     }
349 }
350 
UpdateSpanStyleText(int32_t start,int32_t end,NativeRichEditorTextStyle style)351 void NativeRichEditorController::UpdateSpanStyleText(
352     int32_t start, int32_t end, NativeRichEditorTextStyle style)
353 {
354     ContainerScope scope(instanceId_ < 0 ? Container::CurrentId() : instanceId_);
355 
356     if (start < 0) {
357         start = 0;
358     }
359     if (end < 0) {
360         end = INT_MAX;
361     }
362     if (start > end) {
363         start = 0;
364         end = INT_MAX;
365     }
366     auto pipelineContext = PipelineBase::GetCurrentContext();
367     CHECK_NULL_VOID(pipelineContext);
368     auto theme = pipelineContext->GetTheme<TextTheme>();
369     TextStyle textStyle = theme ? theme->GetTextStyle() : TextStyle();
370     ImageSpanAttribute imageStyle;
371 
372     ParseTextStyle(style, textStyle);
373 
374     auto controller = controller_.Upgrade();
375     auto richEditorController = AceType::DynamicCast<RichEditorControllerBase>(controller);
376     CHECK_NULL_VOID(richEditorController);
377     richEditorController->SetUpdateSpanStyle(updateSpanStyle_);
378     richEditorController->UpdateSpanStyle(start, end, textStyle, imageStyle);
379 }
380 
UpdateSpanStyleImage(int32_t start,int32_t end,NativeRichEditorImageSpanStyle style)381 void NativeRichEditorController::UpdateSpanStyleImage(
382     int32_t start, int32_t end, NativeRichEditorImageSpanStyle style)
383 {
384     auto pipelineContext = PipelineBase::GetCurrentContext();
385     if (!pipelineContext) {
386         return;
387     }
388     auto theme = pipelineContext->GetTheme<TextTheme>();
389     TextStyle textStyle = theme ? theme->GetTextStyle() : TextStyle();
390     ImageSpanAttribute imageStyle;
391 
392     ParseImageSpanStyle(style, imageStyle);
393 
394     auto controller = controller_.Upgrade();
395     auto richEditorController = AceType::DynamicCast<RichEditorControllerBase>(controller);
396     CHECK_NULL_VOID(richEditorController);
397     richEditorController->SetUpdateSpanStyle(updateSpanStyle_);
398     richEditorController->UpdateSpanStyle(start, end, textStyle, imageStyle);
399 }
400 
NativeRichEditorSpanResultListFree(int64_t size,NativeRichEditorSpanResult * src)401 static void NativeRichEditorSpanResultListFree(int64_t size, NativeRichEditorSpanResult* src)
402 {
403     if (!src) {
404         return;
405     }
406     for (int64_t i = 0; i < size; i++) {
407         if (src[i].textResult.value) {
408             delete src[i].textResult.value;
409         }
410     }
411     delete[] src;
412 }
413 
GetSpans(int32_t start,int32_t end)414 NativeRichEditorSpanResultList NativeRichEditorController::GetSpans(int32_t start, int32_t end)
415 {
416     NativeRichEditorSpanResultList result;
417     auto controller = controller_.Upgrade();
418     auto richEditorController = AceType::DynamicCast<RichEditorControllerBase>(controller);
419     if (richEditorController) {
420         LOGI("RichEditor GetSpans, start: %{public}d", start);
421         LOGI("RichEditor GetSpans, end: %{public}d", end);
422 
423         SelectionInfo selectionInfo = richEditorController->GetSpansInfo(start, end);
424         const std::list<ResultObject>& spanObjectList = selectionInfo.GetSelection().resultObjects;
425         if (spanObjectList.size() == 0) {
426             return result;
427         }
428         auto spans = new NativeRichEditorSpanResult[spanObjectList.size()];
429         size_t idx = 0;
430         for (const ResultObject& spanObject : spanObjectList) {
431             NativeRichEditorSpanResult current;
432             if (spanObject.type == SelectSpanType::TYPESPAN) {
433                 current.isText = true;
434                 NativeRichEditorTextSpanResult textResult;
435                 ParseRichEditorTextSpanResult(spanObject, textResult);
436                 current.textResult = textResult;
437             } else {
438                 current.isText = false;
439                 NativeRichEditorImageSpanResult imageResult;
440                 ParseRichEditorImageSpanResult(spanObject, imageResult);
441                 current.imageResult = imageResult;
442             }
443             spans[idx] = current;
444             idx ++;
445         }
446         result.array = spans;
447         result.size = static_cast<int64_t>(spanObjectList.size());
448         result.free = NativeRichEditorSpanResultListFree;
449         LOGI("FfiOHOSAceFrameworkRichEditorOnSelect parse success");
450     }
451     return result;
452 }
453 
UpdateParagraphStyle(int32_t start,int32_t end,NativeRichEditorParagraphStyle params)454 void NativeRichEditorController::UpdateParagraphStyle(
455     int32_t start, int32_t end, NativeRichEditorParagraphStyle params)
456 {
457     struct UpdateParagraphStyle style;
458     style.textAlign = TEXT_ALIGNS[params.textAlign];
459 
460     auto type = MARGIN_TYPES[params.marginType];
461     switch (type) {
462         case MarginType::NONE:
463             break;
464         case MarginType::MARGIN_LENGTH:
465             {
466                 style.leadingMargin = std::make_optional<NG::LeadingMargin>();
467                 Dimension resWidth(params.margin, static_cast<DimensionUnit>(params.marginUnit));
468                 auto widthCalc = CalcDimension(resWidth.ConvertToPx());
469                 auto heightCalc = CalcDimension(0.0);
470                 style.leadingMargin->size = NG::LeadingMarginSize(widthCalc, heightCalc);
471                 break;
472             }
473         case MarginType::MARGIN_PLACEHOLDER:
474             {
475                 auto placeholder = params.placeholder;
476                 style.leadingMargin = std::make_optional<NG::LeadingMargin>();
477 #if defined(PIXEL_MAP_SUPPORTED)
478                 auto nativePixelMap = FFIData::GetData<Media::PixelMapImpl>(placeholder.pixelMap);
479                 if (nativePixelMap == nullptr) {
480                     return;
481                 }
482                 auto pixelMap = nativePixelMap->GetRealPixelMap();
483                 style.leadingMargin->pixmap = PixelMap::CreatePixelMap(&pixelMap);
484 #endif
485                 Dimension width(placeholder.width, static_cast<DimensionUnit>(placeholder.widthUnit));
486                 Dimension height(placeholder.height, static_cast<DimensionUnit>(placeholder.heightUnit));
487                 auto widthCalc = CalcDimension(width.ConvertToPx());
488                 auto heightCalc = CalcDimension(height.ConvertToPx());
489                 style.leadingMargin->size = NG::LeadingMarginSize(widthCalc, heightCalc);
490                 break;
491             }
492         default:
493             break;
494     }
495     auto controller = controller_.Upgrade();
496     auto richEditorController = AceType::DynamicCast<RichEditorControllerBase>(controller);
497     if (richEditorController) {
498         richEditorController->UpdateParagraphStyle(start, end, style);
499     }
500 }
501 
502 }
503 
504 extern "C" {
FfiOHOSAceFrameworkRichEditorControllerCtor()505 int64_t FfiOHOSAceFrameworkRichEditorControllerCtor()
506 {
507     auto controller = FFIData::Create<NativeRichEditorController>();
508     if (controller == nullptr) {
509         return FFI_ERROR_CODE;
510     }
511     return controller->GetID();
512 }
513 
FfiOHOSAceFrameworkRichEditorControllerGetCaretOffset(int64_t controllerId)514 int64_t FfiOHOSAceFrameworkRichEditorControllerGetCaretOffset(int64_t controllerId)
515 {
516     auto nativeController = FFIData::GetData<NativeRichEditorController>(controllerId);
517     if (nativeController != nullptr) {
518         return nativeController->GetCaretOffset();
519     } else {
520         LOGE("RichEditor: invalid richEditorController id");
521         return -1;
522     }
523 }
524 
FfiOHOSAceFrameworkRichEditorControllerSetCaretOffset(int64_t controllerId,int64_t value)525 bool FfiOHOSAceFrameworkRichEditorControllerSetCaretOffset(int64_t controllerId, int64_t value)
526 {
527     auto nativeController = FFIData::GetData<NativeRichEditorController>(controllerId);
528     if (nativeController != nullptr) {
529         return nativeController->SetCaretOffset(value);
530     } else {
531         LOGE("RichEditor: invalid richEditorController id");
532         return false;
533     }
534 }
535 
FfiOHOSAceFrameworkRichEditorControllerAddTextSpan(int64_t controllerId,const char * value,NativeRichEditorTextSpanOptions params)536 int32_t FfiOHOSAceFrameworkRichEditorControllerAddTextSpan(
537     int64_t controllerId, const char* value, NativeRichEditorTextSpanOptions params)
538 {
539     auto nativeController = FFIData::GetData<NativeRichEditorController>(controllerId);
540     if (nativeController != nullptr) {
541         return nativeController->AddTextSpan(value, params);
542     } else {
543         LOGE("RichEditor: invalid richEditorController id");
544         return 0;
545     }
546 }
547 
FfiOHOSAceFrameworkRichEditorControllerAddImageSpan(int64_t controllerId,const char * value,NativeRichEditorImageSpanOptions params)548 int32_t FfiOHOSAceFrameworkRichEditorControllerAddImageSpan(
549     int64_t controllerId, const char* value, NativeRichEditorImageSpanOptions params)
550 {
551     auto nativeController = FFIData::GetData<NativeRichEditorController>(controllerId);
552     if (nativeController != nullptr) {
553         return nativeController->AddImageSpan(value, params);
554     } else {
555         LOGE("RichEditor: invalid richEditorController id");
556         return 0;
557     }
558 }
559 
FfiOHOSAceFrameworkRichEditorControllerDeleteSpans(int64_t controllerId,int32_t start,int32_t end)560 void FfiOHOSAceFrameworkRichEditorControllerDeleteSpans(int64_t controllerId, int32_t start,  int32_t end)
561 {
562     auto nativeController = FFIData::GetData<NativeRichEditorController>(controllerId);
563     if (nativeController != nullptr) {
564         return nativeController->DeleteSpans(start, end);
565     } else {
566         LOGE("RichEditor: invalid richEditorController id");
567     }
568 }
569 
FfiOHOSAceFrameworkRichEditorControllerDeleteAllSpans(int64_t controllerId)570 void FfiOHOSAceFrameworkRichEditorControllerDeleteAllSpans(int64_t controllerId)
571 {
572     auto nativeController = FFIData::GetData<NativeRichEditorController>(controllerId);
573     if (nativeController != nullptr) {
574         return nativeController->DeleteAllSpans();
575     } else {
576         LOGE("RichEditor: invalid richEditorController id");
577     }
578 }
579 
FfiOHOSAceFrameworkRichEditorControllerCloseSelectionMenu(int64_t controllerId)580 void FfiOHOSAceFrameworkRichEditorControllerCloseSelectionMenu(int64_t controllerId)
581 {
582     auto nativeController = FFIData::GetData<NativeRichEditorController>(controllerId);
583     if (nativeController != nullptr) {
584         nativeController->CloseSelectionMenu();
585     } else {
586         LOGE("RichEditor: invalid richEditorController id");
587     }
588 }
589 
FfiOHOSAceFrameworkRichEditorControllerUpdateSpanStyleText(int64_t controllerId,int32_t start,int32_t end,NativeRichEditorTextStyle params)590 void FfiOHOSAceFrameworkRichEditorControllerUpdateSpanStyleText(
591     int64_t controllerId, int32_t start, int32_t end, NativeRichEditorTextStyle params)
592 {
593     auto nativeController = FFIData::GetData<NativeRichEditorController>(controllerId);
594     if (nativeController != nullptr) {
595         nativeController->UpdateSpanStyleText(start, end, params);
596     } else {
597         LOGE("RichEditor: invalid richEditorController id");
598     }
599 }
600 
FfiOHOSAceFrameworkRichEditorControllerUpdateSpanStyleImage(int64_t controllerId,int32_t start,int32_t end,NativeRichEditorImageSpanStyle params)601 void FfiOHOSAceFrameworkRichEditorControllerUpdateSpanStyleImage(
602     int64_t controllerId, int32_t start, int32_t end, NativeRichEditorImageSpanStyle params)
603 {
604     auto nativeController = FFIData::GetData<NativeRichEditorController>(controllerId);
605     if (nativeController != nullptr) {
606         nativeController->UpdateSpanStyleImage(start, end, params);
607     } else {
608         LOGE("RichEditor: invalid richEditorController id");
609     }
610 }
611 
FfiOHOSAceFrameworkRichEditorControllerGetSpans(int64_t controllerId,int32_t start,int32_t end)612 NativeRichEditorSpanResultList FfiOHOSAceFrameworkRichEditorControllerGetSpans(
613     int64_t controllerId, int32_t start, int32_t end)
614 {
615     NativeRichEditorSpanResultList result;
616     auto nativeController = FFIData::GetData<NativeRichEditorController>(controllerId);
617     if (nativeController != nullptr) {
618         result = nativeController->GetSpans(start, end);
619     } else {
620         LOGE("RichEditor: invalid richEditorController id");
621     }
622     return result;
623 }
624 
FfiOHOSAceFrameworkRichEditorControllerUpdateParagraphStyle(int64_t controllerId,int32_t start,int32_t end,NativeRichEditorParagraphStyle params)625 void FfiOHOSAceFrameworkRichEditorControllerUpdateParagraphStyle(
626     int64_t controllerId, int32_t start, int32_t end, NativeRichEditorParagraphStyle params)
627 {
628     auto nativeController = FFIData::GetData<NativeRichEditorController>(controllerId);
629     if (nativeController != nullptr) {
630         nativeController->UpdateParagraphStyle(start, end, params);
631     } else {
632         LOGE("RichEditor: invalid richEditorController id");
633     }
634 }
635 }