From 939df874e3959805a48b2895d2cb012e1d7fc130 Mon Sep 17 00:00:00 2001 From: xqq879988 Date: Fri, 7 Jun 2024 15:01:21 +0800 Subject: [PATCH] =?UTF-8?q?RichEditor=20=E5=BF=AB=E6=8D=B7=E9=94=AEbug?= =?UTF-8?q?=E4=BF=AE=E5=A4=8D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: xqq879988 --- .../rich_editor/rich_editor_pattern.cpp | 113 ++++++++++++++++-- .../pattern/rich_editor/rich_editor_pattern.h | 4 + 2 files changed, 109 insertions(+), 8 deletions(-) diff --git a/frameworks/core/components_ng/pattern/rich_editor/rich_editor_pattern.cpp b/frameworks/core/components_ng/pattern/rich_editor/rich_editor_pattern.cpp index d161bb5519b..d3ac352cd2a 100644 --- a/frameworks/core/components_ng/pattern/rich_editor/rich_editor_pattern.cpp +++ b/frameworks/core/components_ng/pattern/rich_editor/rich_editor_pattern.cpp @@ -1715,6 +1715,93 @@ void RichEditorPattern::UpdateSpanStyle( CloseSystemMenu(); } +std::string RichEditorPattern::GetContentBySpans() +{ + std::stringstream ss; + for (auto iter = spans_.cbegin(); iter != spans_.cend(); iter++) { + ss << (*iter)->content; + } + auto textContent = ss.str(); + return textContent; +} + +ResultObject RichEditorPattern::TextEmojiSplit(int32_t& start, int32_t end, std::string& content) +{ + ResultObject resultObject; + int32_t emojiStartIndex = 0; + int32_t emojiEndIndex = 0; + int32_t size = 2; + bool isEmoji = false; + int32_t initStart = start; + for (auto index = start; index <= end; index++) { + emojiStartIndex = 0; + emojiEndIndex = 0; + EmojiRelation indexRelationEmoji = + TextEmojiProcessor::GetIndexRelationToEmoji(index - start, content, emojiStartIndex, emojiEndIndex); + // caret position after emoji + if (indexRelationEmoji == EmojiRelation::AFTER_EMOJI || indexRelationEmoji == EmojiRelation::MIDDLE_EMOJI) { + resultObject.spanPosition.spanRange[RichEditorSpanRange::RANGESTART] = start; + resultObject.spanPosition.spanRange[RichEditorSpanRange::RANGEEND] = index - size; + resultObject.type = SelectSpanType::TYPESPAN; + start = index; + isEmoji = true; + break; + } + } + + if (!isEmoji) { + resultObject.spanPosition.spanRange[RichEditorSpanRange::RANGESTART] = start; + resultObject.spanPosition.spanRange[RichEditorSpanRange::RANGEEND] = end; + resultObject.type = SelectSpanType::TYPESPAN; + start = end; + return resultObject; + } + std::u16string u16Content = StringUtils::Str8ToStr16(content); + CHECK_NULL_RETURN(!(end - start < 0), resultObject); + std::u16string temp = u16Content.substr(start - initStart, end - start); + content = StringUtils::Str16ToStr8(temp); + return resultObject; +} + +SelectionInfo RichEditorPattern::GetEmojisBySelect(int32_t start, int32_t end) +{ + SelectionInfo selection; + std::list resultObjects; + CHECK_NULL_RETURN(textSelector_.IsValid(), selection); + + // get all content + auto selectTextContent = GetContentBySpans(); + CHECK_NULL_RETURN(!selectTextContent.empty(), selection); + std::u16string u16Content = StringUtils::Str8ToStr16(selectTextContent); + // get select content + std::u16string selectData16 = u16Content.substr(static_cast(start), static_cast(end - start)); + std::string selectData = StringUtils::Str16ToStr8(selectData16); + // set SelectionInfo start position and end position + selection.SetSelectionStart(start); + selection.SetSelectionEnd(end); + while (start != end) { + ResultObject resultObject = TextEmojiSplit(start, end, selectData); + resultObjects.emplace_back(resultObject); + } + selection.SetResultObjectList(resultObjects); + return selection; +} + +void RichEditorPattern::MixTextEmojiUpdateStyle( + int32_t start, int32_t end, TextStyle textStyle, ImageSpanAttribute imageStyle) +{ + SelectionInfo textSelectInfo = GetEmojisBySelect(start, end); + std::list textResultObjects = textSelectInfo.GetSelection().resultObjects; + for (const auto& textIter : textResultObjects) { + int32_t newStart = textIter.spanPosition.spanRange[RichEditorSpanRange::RANGESTART]; + int32_t newEnd = textIter.spanPosition.spanRange[RichEditorSpanRange::RANGEEND]; + if (newStart == newEnd) { + continue; + } + UpdateSpanStyle(newStart, newEnd, textStyle, imageStyle); + } +} + void RichEditorPattern::SetSelectSpanStyle( int32_t start, int32_t end, RefPtr& target, KeyCode code, bool isStart) { @@ -1755,7 +1842,7 @@ void RichEditorPattern::SetSelectSpanStyle( } } SetUpdateSpanStyle(updateSpanStyle); - UpdateSpanStyle(start, end, spanStyle, imageStyle); + MixTextEmojiUpdateStyle(start, end, spanStyle, imageStyle); } void RichEditorPattern::GetSelectSpansPositionInfo( @@ -1848,7 +1935,7 @@ void RichEditorPattern::UpdateSelectSpanStyle(int32_t start, int32_t end, KeyCod SetSelectSpanStyle(startPosition, endPosition, spanNode, code, false); continue; } - startPosition = spanItem->rangeStart; + startPosition = spanItem->position - StringUtils::ToWstring(spanItem->content).length(); endPosition = spanItem->position; SetSelectSpanStyle(startPosition, endPosition, spanNode, code, false); } @@ -4441,7 +4528,7 @@ bool RichEditorPattern::CursorMoveDown() auto overlayMod = DynamicCast(overlayMod_); auto caretOffsetOverlay = overlayMod->GetCaretOffset(); float textOffsetX = GetTextRect().GetX(); - float textOffsetY = GetTextRect().GetY() - caretHeightDown - minDet / 2.0; + float textOffsetY = GetTextRect().GetY() - caretHeightUp - minDet / 2.0; float textOffsetDownY = caretOffsetOverlay.GetY() - textOffsetY; textOffset = Offset(caretOffsetOverlay.GetX() - textOffsetX, textOffsetDownY); caretPositionEnd = paragraphs_.GetIndex(textOffset); @@ -8186,6 +8273,7 @@ int32_t RichEditorPattern::CalcMoveUpPos(OffsetF& caretOffsetUp, OffsetF& caretO int32_t caretPosition; float caretHeightUp = 0.0f; float caretHeightDown = 0.0f; + float lineHeightDis = 0.0f; Offset textOffset; OffsetF caretOffsetCalcUp = CalcCursorOffsetByPosition(GetCaretPosition(), caretHeightUp, false, false); @@ -8197,7 +8285,12 @@ int32_t RichEditorPattern::CalcMoveUpPos(OffsetF& caretOffsetUp, OffsetF& caretO auto overlayMod = DynamicCast(overlayMod_); auto caretOffsetOverlay = overlayMod->GetCaretOffset(); float textOffsetY = GetTextRect().GetY() + minDet / 2.0; // 2.0 Cursor one half at the center position - auto lineHeightDis = CalcLineHeightByPosition(GetCaretPosition()) - overlayMod->GetCaretHeight(); + float lineHeight = CalcLineHeightByPosition(GetCaretPosition()); + if (lineHeight == 0) { + lineHeightDis = caretHeightUp - overlayMod->GetCaretHeight(); + } else { + lineHeightDis = lineHeight - overlayMod->GetCaretHeight(); + } float textOffsetDownY = caretOffsetOverlay.GetY() - lineHeightDis - textOffsetY; textOffset = Offset(caretOffsetOverlay.GetX() - GetTextRect().GetX(), textOffsetDownY); caretPosition = paragraphs_.GetIndex(textOffset); @@ -8269,7 +8362,7 @@ bool RichEditorPattern::CursorMoveLineEndPos(OffsetF& caretOffsetUp, OffsetF& ca bool RichEditorPattern::CursorMoveLineBegin() { - CHECK_NULL_RETURN(!SelectOverlayIsOn(), false); + CloseSelectOverlay(); ResetSelection(); float caretHeightDown = 0.0f; Offset textOffset; @@ -8298,7 +8391,7 @@ bool RichEditorPattern::CursorMoveLineBegin() bool RichEditorPattern::CursorMoveLineEnd() { - CHECK_NULL_RETURN(!SelectOverlayIsOn(), false); + CloseSelectOverlay(); ResetSelection(); float caretHeight = 0.0f; auto position = CalcLineEndPosition(); @@ -8380,10 +8473,14 @@ int32_t RichEditorPattern::HandleSelectPosition(bool isForward) OffsetF caretOffset = CalcCursorOffsetByPosition(caretPosition_, caretHeight); auto minDet = paragraphs_.minParagraphFontSize.value_or(GetTextThemeFontSize()) / 2.0; if (isForward) { - CHECK_NULL_RETURN(textSelector_.SelectNothing(), textSelector_.GetTextStart()); + if (!textSelector_.SelectNothing() && textSelector_.GetTextEnd() == caretPosition_) { + return textSelector_.GetTextStart(); + } careOffsetY = caretOffset.GetY() - GetTextRect().GetY() - minDet; } else { - CHECK_NULL_RETURN(textSelector_.SelectNothing(), textSelector_.GetTextEnd()); + if (!textSelector_.SelectNothing() && textSelector_.GetTextStart() == caretPosition_) { + return textSelector_.GetTextEnd(); + } careOffsetY = caretOffset.GetY() - GetTextRect().GetY() + caretHeight + minDet / 2.0; } newPos = paragraphs_.GetIndex(Offset(caretOffset.GetX() - GetTextRect().GetX(), careOffsetY), true); diff --git a/frameworks/core/components_ng/pattern/rich_editor/rich_editor_pattern.h b/frameworks/core/components_ng/pattern/rich_editor/rich_editor_pattern.h index 5e7cbe818d7..e0dfe2681f6 100644 --- a/frameworks/core/components_ng/pattern/rich_editor/rich_editor_pattern.h +++ b/frameworks/core/components_ng/pattern/rich_editor/rich_editor_pattern.h @@ -396,6 +396,10 @@ public: void FireOnDeleteComplete(const RichEditorDeleteValue& info); void UpdateSpanStyle(int32_t start, int32_t end, const TextStyle& textStyle, const ImageSpanAttribute& imageStyle); + std::string GetContentBySpans(); + ResultObject TextEmojiSplit(int32_t& start, int32_t end, std::string& content); + SelectionInfo GetEmojisBySelect(int32_t start, int32_t end); + void MixTextEmojiUpdateStyle(int32_t start, int32_t end, TextStyle textStyle, ImageSpanAttribute imageStyle); void SetSelectSpanStyle(int32_t start, int32_t end, RefPtr& target, KeyCode code, bool isStart); void GetSelectSpansPositionInfo( int32_t start, int32_t end, SpanPositionInfo& startPositionSpanInfo, SpanPositionInfo& endPositionSpanInfo); -- Gitee