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 #ifndef FOUNDATION_ACE_FRAMEWORKS_CORE_TEXT_ACE_TEXT_EMOJI_PROCESSOR_H 17 #define FOUNDATION_ACE_FRAMEWORKS_CORE_TEXT_ACE_TEXT_EMOJI_PROCESSOR_H 18 19 #include "base/utils/string_utils.h" 20 21 namespace OHOS::Ace { 22 enum class EmojiRelation { NO_EMOJI, IN_EMOJI, BEFORE_EMOJI, AFTER_EMOJI, MIDDLE_EMOJI }; 23 24 struct TextEmojiSubStringRange { 25 int startIndex; 26 int endIndex; 27 }; 28 29 class TextEmojiProcessor { 30 public: 31 // static functions 32 /* 33 * Delete characters from the content string according to the startIndex and length. 34 * startIndex: The UTF-16 start index. 35 * For backward delete, it's the end index + 1, for forward delete, it's the start index. 36 * Example: content = "abcde"; 37 * For backward at end, the startIndex is 5. For forward at start, the startIndex is 0. 38 * length: The number of characters to delete. 39 * Note: An emoji may have multiple bytes, but it's considered as ONE character. 40 * content: The content string to delete. 41 * isBackward: Whether the delete action is backward. 42 * return deleted UTF-16 bytes length. 43 * Why UTF-16? TextSelectController->GetCaretIndex() returns UTF-16 index. 44 */ 45 static int32_t Delete(int32_t startIndex, int32_t length, std::string& content, bool isBackward); 46 static bool IsEmoji(uint32_t codePoint); 47 static bool IsEmojiModifierBase(uint32_t codePoint); 48 static bool IsVariationSelector(uint32_t codePoint); 49 static bool IsRegionalIndicatorSymbol(uint32_t codePoint); 50 static bool IsEmojiModifier(uint32_t codePoint); 51 static bool IsTagSpec(uint32_t codePoint); 52 static bool IsKeycapBase(uint32_t codePoint); 53 static bool IsIndexInEmoji(int32_t index, const std::string& content, int32_t& startIndex, int32_t& endIndex); 54 static EmojiRelation GetIndexRelationToEmoji(int32_t index, 55 const std::string& content, int32_t& startIndex, int32_t& endIndex); 56 static bool IsIndexBeforeOrInEmoji(int32_t index, const std::string& content); 57 static bool IsIndexAfterOrInEmoji(int32_t index, const std::string& content); 58 static bool IsIndexBeforeOrInEmoji(int32_t index, const std::string& content, 59 int32_t& startIndex, int32_t& endIndex); 60 static bool IsIndexAfterOrInEmoji(int32_t index, const std::string& content, 61 int32_t& startIndex, int32_t& endIndex); 62 static std::wstring SubWstring(int32_t index, int32_t length, 63 const std::wstring& content, bool includeHalf = false); 64 static TextEmojiSubStringRange CalSubWstringRange(int32_t index, int32_t length, 65 const std::wstring& content, bool includeHalf); 66 static int32_t GetCharacterNum(const std::string& content); 67 static std::string ConvertU8stringUnpairedSurrogates(const std::string& value); 68 69 private: 70 static void OnBeginState(uint32_t codePoint, int& state, int& deleteCount, bool isBackward); 71 static void OnRISState(uint32_t codePoint, int& state, int& deleteCount, bool isBackward); 72 static void OnCRLFState(uint32_t codePoint, int& state, int& deleteCount, bool isBackward); 73 static void OnZWJState(uint32_t codePoint, int& state, int& deleteCount, int& lastVSCount, bool isBackward); 74 static void OnVSState(uint32_t codePoint, int& state, int& deleteCount, bool isBackward); 75 static void OnKeyCapState(uint32_t codePoint, int& state, int& deleteCount, int& lastVSCount, bool isBackward); 76 static void OnEMState(uint32_t codePoint, int& state, int& deleteCount, int& lastVSCount, bool isBackward); 77 static void OnEmojiState(uint32_t codePoint, int& state, int& deleteCount, bool isBackward); 78 static void OnForwardSecondState(uint32_t codePoint, int& state, int& deleteCount); 79 static void OnTagQueueState(uint32_t codePoint, int& state, int& deleteCount, bool isBackward); 80 static bool BackwardDelete(std::u32string& u32Content); 81 static bool ForwardDelete(std::u32string& u32Content); 82 static bool HandleDeleteAction(std::u32string& u32Content, int32_t deleteCount, bool isBackward); 83 static int32_t GetEmojiLengthBackward(std::u32string& u32Content, 84 int32_t& startIndex, const std::u16string& u16Content); 85 static int32_t GetEmojiLengthForward(std::u32string& u32Content, 86 int32_t& startIndex, const std::u16string& u16Content); 87 static int32_t GetEmojiLengthU16Forward(std::u32string& u32Content, 88 int32_t& startIndex, const std::u16string& u16Content); 89 static int32_t GetEmojiLengthAtEnd(const std::u32string& u32Content, bool isCountNonEmoji); 90 static int32_t GetEmojiLengthAtFront(const std::u32string& u32Content, bool isCountNonEmoji); 91 static std::u16string U32ToU16string(const std::u32string& u32str); 92 }; 93 94 } // namespace OHOS::Ace 95 96 #endif // FOUNDATION_ACE_FRAMEWORKS_CORE_TEXT_ACE_TEXT_EMOJI_PROCESSOR_H 97