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 62ad9c4f21c5f0e49aeb5af06e43da0fc2406c44..676a3402ae211f8b3d2f49d5e8519ba02523eef2 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 @@ -2495,14 +2495,24 @@ void RichEditorPattern::HandleDoubleClickOrLongPress(GestureEvent& info) HandleDoubleClickOrLongPress(info, host); } +Offset RichEditorPattern::ConvertGlobalToLocalOffset(const Offset& globalOffset) +{ + auto localPoint = OffsetF(globalOffset.GetX(), globalOffset.GetY()); + selectOverlay_->RevertLocalPointWithTransform(localPoint); + return Offset(localPoint.GetX(), localPoint.GetY()); +} + void RichEditorPattern::HandleDoubleClickOrLongPress(GestureEvent& info, RefPtr host) { auto focusHub = host->GetOrCreateFocusHub(); CHECK_NULL_VOID(focusHub); isLongPress_ = true; + auto localOffset = info.GetLocalLocation(); + if (selectOverlay_->HasRenderTransform()) { + localOffset = ConvertGlobalToLocalOffset(info.GetGlobalLocation()); + } auto textPaintOffset = GetTextRect().GetOffset() - OffsetF(0.0, std::min(baselineOffset_, 0.0f)); - Offset textOffset = { info.GetLocalLocation().GetX() - textPaintOffset.GetX(), - info.GetLocalLocation().GetY() - textPaintOffset.GetY() }; + Offset textOffset = { localOffset.GetX() - textPaintOffset.GetX(), localOffset.GetY() - textPaintOffset.GetY() }; InitSelection(textOffset); auto selectEnd = std::max(textSelector_.baseOffset, textSelector_.destinationOffset); auto selectStart = std::min(textSelector_.baseOffset, textSelector_.destinationOffset); @@ -5416,7 +5426,7 @@ void RichEditorPattern::OnAreaChangedInner() CHECK_NULL_VOID(host); auto context = PipelineContext::GetCurrentContext(); CHECK_NULL_VOID(context); - auto parentGlobalOffset = host->GetPaintRectOffset() - context->GetRootRect().GetOffset(); + auto parentGlobalOffset = GetPaintRectGlobalOffset(); // offset on screen(with transformation) if (parentGlobalOffset != parentGlobalOffset_) { parentGlobalOffset_ = parentGlobalOffset; UpdateTextFieldManager(Offset(parentGlobalOffset_.GetX(), parentGlobalOffset_.GetY()), frameRect_.Height()); @@ -5455,6 +5465,9 @@ void RichEditorPattern::CalculateHandleOffsetAndShowOverlay(bool isUsingMouse) CHECK_NULL_VOID(pipeline); auto rootOffset = pipeline->GetRootRect().GetOffset(); auto offset = host->GetPaintRectOffset(); + if (selectOverlay_->HasRenderTransform()) { + offset = selectOverlay_->GetPaintOffsetWithoutTransform(); + } auto textPaintOffset = offset - OffsetF(0.0, std::min(baselineOffset_, 0.0f)); textSelector_.ReverseTextSelector(); int32_t baseOffset = std::min(textSelector_.baseOffset, GetTextContentLength()); @@ -5519,6 +5532,9 @@ bool RichEditorPattern::BetweenSelectedPosition(const Offset& globalOffset) CHECK_NULL_RETURN(host, false); auto offset = host->GetPaintRectOffset(); auto localOffset = globalOffset - Offset(offset.GetX(), offset.GetY()); + if (selectOverlay_->HasRenderTransform()) { + localOffset = ConvertGlobalToLocalOffset(globalOffset); + } auto eventHub = host->GetEventHub(); if (copyOption_ != CopyOptions::None && GreatNotEqual(textSelector_.GetTextEnd(), textSelector_.GetTextStart())) { // Determine if the pan location is in the selected area @@ -6691,6 +6707,7 @@ void RichEditorPattern::ResetDragOption() RectF RichEditorPattern::GetSelectArea() { + auto paintOffset = selectOverlay_->GetPaintOffsetWithoutTransform(); auto selectRects = paragraphs_.GetRects(textSelector_.GetTextStart(), textSelector_.GetTextEnd()); if (selectRects.empty()) { float caretHeight = 0.0f; @@ -6699,22 +6716,22 @@ RectF RichEditorPattern::GetSelectArea() caretOffset = CalculateEmptyValueCaretRect(); } auto caretWidth = Dimension(1.5f, DimensionUnit::VP).ConvertToPx(); - return RectF(caretOffset + parentGlobalOffset_, SizeF(caretWidth, caretHeight)); + return RectF(caretOffset + paintOffset, SizeF(caretWidth, caretHeight)); } auto frontRect = selectRects.front(); auto backRect = selectRects.back(); RectF res; if (GreatNotEqual(backRect.Bottom(), frontRect.Bottom())) { - res.SetRect(contentRect_.GetX() + parentGlobalOffset_.GetX(), - frontRect.GetY() + richTextRect_.GetY() + parentGlobalOffset_.GetY(), contentRect_.Width(), + res.SetRect(contentRect_.GetX() + paintOffset.GetX(), + frontRect.GetY() + richTextRect_.GetY() + paintOffset.GetY(), contentRect_.Width(), backRect.Bottom() - frontRect.Top()); } else { - res.SetRect(frontRect.GetX() + richTextRect_.GetX() + parentGlobalOffset_.GetX(), - frontRect.GetY() + richTextRect_.GetY() + parentGlobalOffset_.GetY(), backRect.Right() - frontRect.Left(), + res.SetRect(frontRect.GetX() + richTextRect_.GetX() + paintOffset.GetX(), + frontRect.GetY() + richTextRect_.GetY() + paintOffset.GetY(), backRect.Right() - frontRect.Left(), backRect.Bottom() - frontRect.Top()); } auto contentRect = contentRect_; - contentRect.SetOffset(contentRect.GetOffset() + parentGlobalOffset_); + contentRect.SetOffset(contentRect.GetOffset() + paintOffset); auto host = GetHost(); CHECK_NULL_RETURN(host, RectF(0, 0, 0, 0)); auto parent = host->GetAncestorNodeOfFrame(); @@ -7599,10 +7616,18 @@ void RichEditorPattern::AfterChangeText(RichEditorChangeValue& changeValue) } OffsetF RichEditorPattern::GetTextPaintOffset() const +{ + if (selectOverlay_->HasRenderTransform()) { + return selectOverlay_->GetPaintRectOffsetWithTransform(); + } + return GetPaintRectGlobalOffset(); +} + +OffsetF RichEditorPattern::GetPaintRectGlobalOffset() const { auto host = GetHost(); CHECK_NULL_RETURN(host, OffsetF(0.0f, 0.0f)); - auto pipeline = host->GetContext(); + auto pipeline = host->GetContextRefPtr(); CHECK_NULL_RETURN(pipeline, OffsetF(0.0f, 0.0f)); auto rootOffset = pipeline->GetRootRect().GetOffset(); auto textPaintOffset = host->GetPaintRectOffset(); 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 86e6db37af5633edf24e2a6774dce6477fd714f8..a60ed19854142862694f0d48b4d7adc779b898b2 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 @@ -668,7 +668,13 @@ public: OffsetF GetCaretOffset() const override { - return GetCaretRect().GetOffset(); + // only used in magnifier, return position of the handle that is currently moving + return movingHandleOffset_; + } + + void SetMovingHandleOffset(const OffsetF& handleOffset) + { + movingHandleOffset_ = handleOffset; } OffsetF GetParentGlobalOffset() const override @@ -687,6 +693,7 @@ public: } OffsetF GetTextPaintOffset() const override; + OffsetF GetPaintRectGlobalOffset() const; float GetCrossOverHeight() const; @@ -711,6 +718,7 @@ protected: private: friend class RichEditorSelectOverlay; RefPtr selectOverlay_; + Offset ConvertGlobalToLocalOffset(const Offset& globalOffset); void UpdateSelectMenuInfo(SelectMenuInfo& selectInfo); void HandleOnPaste() override; void HandleOnCut() override; @@ -1013,6 +1021,7 @@ private: PreviewTextRecord previewTextRecord_; float lastFontScale_ = -1; bool isCaretInContentArea_ = false; + OffsetF movingHandleOffset_; }; } // namespace OHOS::Ace::NG diff --git a/frameworks/core/components_ng/pattern/rich_editor/rich_editor_select_overlay.cpp b/frameworks/core/components_ng/pattern/rich_editor/rich_editor_select_overlay.cpp index 0e869d74bc14125e650bf707ea51fa22d2a06f20..ac1e984fdf344152c654da7b5f77e9fcedeec8dd 100644 --- a/frameworks/core/components_ng/pattern/rich_editor/rich_editor_select_overlay.cpp +++ b/frameworks/core/components_ng/pattern/rich_editor/rich_editor_select_overlay.cpp @@ -50,6 +50,10 @@ std::optional RichEditorSelectOverlay::GetFirstHandleInfo() SelectHandleInfo handleInfo; handleInfo.paintRect = pattern->textSelector_.firstHandle; handleInfo.isShow = CheckHandleVisible(handleInfo.paintRect); + + auto localPaintRect = handleInfo.paintRect; + localPaintRect.SetOffset(localPaintRect.GetOffset() - GetPaintOffsetWithoutTransform()); + SetTransformPaintInfo(handleInfo, localPaintRect); return handleInfo; } @@ -60,6 +64,10 @@ std::optional RichEditorSelectOverlay::GetSecondHandleInfo() SelectHandleInfo handleInfo; handleInfo.paintRect = pattern->textSelector_.secondHandle; handleInfo.isShow = CheckHandleVisible(handleInfo.paintRect); + + auto localPaintRect = handleInfo.paintRect; + localPaintRect.SetOffset(localPaintRect.GetOffset() - GetPaintOffsetWithoutTransform()); + SetTransformPaintInfo(handleInfo, localPaintRect); return handleInfo; } @@ -111,13 +119,27 @@ void RichEditorSelectOverlay::OnHandleMove(const RectF& handleRect, bool isFirst CHECK_NULL_VOID(!pattern->spans_.empty()); TextSelectOverlay::OnHandleMove(handleRect, isFirst); auto parentGlobalOffset = pattern->GetParentGlobalOffset(); - auto localOffset = handleRect.GetOffset() - parentGlobalOffset; + if (hasTransform_) { + parentGlobalOffset = GetPaintOffsetWithoutTransform(); + } + auto localOffset = handleRect.GetOffset() - parentGlobalOffset; // original offset + + // update moving handle offset + auto movingHandleOffset = pattern->ConvertTouchOffsetToTextOffset(Offset(localOffset.GetX(), localOffset.GetY())); + auto movingHandleOffsetF = OffsetF(movingHandleOffset.GetX(), movingHandleOffset.GetY()); + GetLocalPointWithTransform(movingHandleOffsetF); // do affine transformation + pattern->SetMovingHandleOffset(movingHandleOffsetF); + auto contentRect = pattern->GetContentRect(); auto caretRect = pattern->GetCaretRect(); float x = std::clamp(localOffset.GetX(), contentRect.Left(), contentRect.Right() - caretRect.Width()); float y = std::clamp(localOffset.GetY(), contentRect.Top(), contentRect.Bottom() - caretRect.Height()); localOffset = OffsetF(x, y); - pattern->magnifierController_->SetLocalOffset(localOffset); + + auto magnifierLocalOffset = localOffset; + GetLocalPointWithTransform(magnifierLocalOffset); // do affine transformation + pattern->magnifierController_->SetLocalOffset(magnifierLocalOffset); + if (isFirst) { pattern->textSelector_.firstHandle.SetOffset(localOffset); } else { @@ -190,7 +212,14 @@ RectF RichEditorSelectOverlay::GetSelectArea() { auto pattern = GetPattern(); CHECK_NULL_RETURN(pattern, {}); - return pattern->GetSelectArea(); + auto intersectRect = pattern->GetSelectArea(); + + if (hasTransform_) { + auto textPaintOffset = GetPaintOffsetWithoutTransform(); + intersectRect.SetOffset(intersectRect.GetOffset() - textPaintOffset); + GetGlobalRectWithTransform(intersectRect); + } + return intersectRect; } void RichEditorSelectOverlay::OnUpdateMenuInfo(SelectMenuInfo& menuInfo, SelectOverlayDirtyFlag dirtyFlag) @@ -238,7 +267,7 @@ void RichEditorSelectOverlay::OnUpdateSelectOverlayInfo(SelectOverlayInfo& selec selectInfo.menuInfo.editorType = static_cast(pattern->GetEditorType()); selectInfo.callerFrameNode = pattern->GetHost(); selectInfo.isNewAvoid = true; - selectInfo.selectArea = pattern->GetSelectArea(); + selectInfo.selectArea = GetSelectArea(); selectInfo.checkIsTouchInHostArea = [weak = AceType::WeakClaim(AceType::RawPtr(pattern))](const PointF& touchPoint) -> bool { auto pattern = weak.Upgrade(); @@ -252,6 +281,12 @@ void RichEditorSelectOverlay::OnUpdateSelectOverlayInfo(SelectOverlayInfo& selec selectInfo.recreateOverlay = requestCode == REQUEST_RECREATE; CheckEditorTypeChange(selectInfo, pattern->GetEditorType()); pattern->CopySelectionMenuParams(selectInfo, responseType); + if (hasTransform_) { + selectInfo.callerNodeInfo = { + .paintFrameRect = GetPaintRectWithTransform(), + .paintOffset = GetPaintRectOffsetWithTransform() + }; + } } void RichEditorSelectOverlay::CheckEditorTypeChange(SelectOverlayInfo& selectInfo, TextSpanType selectType) diff --git a/frameworks/core/components_ng/pattern/text/text_select_overlay.cpp b/frameworks/core/components_ng/pattern/text/text_select_overlay.cpp index 74626e37dda6c349a8ff79eebf05a0777ea06728..d456834973aaa6c69ed5e1fc87a5ee5d7089fada 100644 --- a/frameworks/core/components_ng/pattern/text/text_select_overlay.cpp +++ b/frameworks/core/components_ng/pattern/text/text_select_overlay.cpp @@ -153,7 +153,7 @@ void TextSelectOverlay::OnHandleMove(const RectF& handleRect, bool isFirst) auto renderContext = host->GetRenderContext(); CHECK_NULL_VOID(renderContext); auto contentRect = textPattern->GetTextContentRect(); - auto contentOffset = textPattern->GetTextPaintOffset() + contentRect.GetOffset(); + auto contentOffset = GetPaintOffsetWithoutTransform() + contentRect.GetOffset(); auto handleOffset = handleRect.GetOffset(); if (!selectTextUseTopHandle) { bool isUseHandleTop = (isFirst != IsHandleReverse());