1 /*
2 * Copyright (c) 2023 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 "core/components_ng/pattern/rich_editor/rich_editor_paint_method.h"
17
18 #include "core/components_ng/pattern/rich_editor/paragraph_manager.h"
19 #include "core/components_ng/pattern/rich_editor/rich_editor_overlay_modifier.h"
20 #include "core/components_ng/pattern/rich_editor/rich_editor_pattern.h"
21 #include "core/components_ng/pattern/text/text_content_modifier.h"
22 #include "core/components_ng/pattern/text/text_overlay_modifier.h"
23
24 namespace OHOS::Ace::NG {
RichEditorPaintMethod(const WeakPtr<Pattern> & pattern,const ParagraphManager * pManager,float baselineOffset,const RefPtr<TextContentModifier> & contentMod,const RefPtr<TextOverlayModifier> & overlayMod)25 RichEditorPaintMethod::RichEditorPaintMethod(const WeakPtr<Pattern>& pattern, const ParagraphManager* pManager,
26 float baselineOffset, const RefPtr<TextContentModifier>& contentMod,
27 const RefPtr<TextOverlayModifier>& overlayMod)
28 : TextPaintMethod(pattern, baselineOffset, contentMod, overlayMod),
29 pManager_(pManager)
30 {}
31
UpdateOverlayModifier(PaintWrapper * paintWrapper)32 void RichEditorPaintMethod::UpdateOverlayModifier(PaintWrapper* paintWrapper)
33 {
34 TextPaintMethod::UpdateOverlayModifier(paintWrapper);
35 auto richEditorPattern = DynamicCast<RichEditorPattern>(GetPattern().Upgrade());
36 CHECK_NULL_VOID(richEditorPattern);
37 auto overlayMod = DynamicCast<RichEditorOverlayModifier>(GetOverlayModifier(paintWrapper));
38 overlayMod->SetPrintOffset(richEditorPattern->GetTextRect().GetOffset());
39 overlayMod->SetTextHeight(richEditorPattern->GetTextRect().Height());
40 overlayMod->SetScrollOffset(richEditorPattern->GetScrollOffset());
41 SetPreviewTextDecoration(paintWrapper);
42 if (!richEditorPattern->HasFocus()) {
43 overlayMod->UpdateScrollBar(paintWrapper);
44 overlayMod->SetCaretVisible(false);
45 const auto& selection = richEditorPattern->GetTextSelector();
46 if (richEditorPattern->GetTextContentLength() > 0 && selection.GetTextStart() != selection.GetTextEnd()) {
47 overlayMod->SetSelectedRects(pManager_->GetRects(selection.GetTextStart(), selection.GetTextEnd()));
48 }
49 return;
50 }
51 auto caretVisible = richEditorPattern->GetCaretVisible();
52 overlayMod->SetShowSelect(richEditorPattern->GetShowSelect());
53 overlayMod->SetCaretVisible(caretVisible);
54 overlayMod->SetCaretColor(richEditorPattern->GetCaretColor().GetValue());
55 overlayMod->SetSelectedBackgroundColor(richEditorPattern->GetSelectedBackgroundColor().GetValue());
56 constexpr float CARET_WIDTH = 2.0f;
57 overlayMod->SetCaretWidth(static_cast<float>(Dimension(CARET_WIDTH, DimensionUnit::VP).ConvertToPx()));
58 SetCaretOffsetAndHeight(paintWrapper);
59 std::vector<RectF> selectedRects;
60 const auto& selection = richEditorPattern->GetTextSelector();
61 if (richEditorPattern->GetTextContentLength() > 0 && selection.GetTextStart() != selection.GetTextEnd()) {
62 selectedRects = pManager_->GetRects(selection.GetTextStart(), selection.GetTextEnd());
63 }
64 auto contentRect = richEditorPattern->GetTextContentRect();
65 overlayMod->SetContentRect(contentRect);
66 overlayMod->SetSelectedRects(selectedRects);
67 auto frameSize = paintWrapper->GetGeometryNode()->GetFrameSize();
68 overlayMod->SetFrameSize(frameSize);
69 overlayMod->UpdateScrollBar(paintWrapper);
70 overlayMod->SetIsClip(false);
71 }
72
SetPreviewTextDecoration(PaintWrapper * paintWrapper)73 void RichEditorPaintMethod::SetPreviewTextDecoration(PaintWrapper* paintWrapper)
74 {
75 auto richEditorPattern = DynamicCast<RichEditorPattern>(GetPattern().Upgrade());
76 CHECK_NULL_VOID(richEditorPattern);
77 auto overlayMod = DynamicCast<RichEditorOverlayModifier>(GetOverlayModifier(paintWrapper));
78 CHECK_NULL_VOID(overlayMod);
79 overlayMod->SetPreviewTextDecorationColor(richEditorPattern->GetPreviewTextDecorationColor());
80 overlayMod->SetPreviewTextUnderlineWidth(richEditorPattern->GetPreviewTextUnderlineWidth());
81 overlayMod->SetShowPreviewTextDecoration(richEditorPattern->IsPreviewTextInputting());
82 overlayMod->SetPreviewTextStyle(richEditorPattern->GetPreviewTextStyle());
83 }
84
SetCaretOffsetAndHeight(PaintWrapper * paintWrapper)85 void RichEditorPaintMethod::SetCaretOffsetAndHeight(PaintWrapper* paintWrapper)
86 {
87 auto richEditorPattern = DynamicCast<RichEditorPattern>(GetPattern().Upgrade());
88 CHECK_NULL_VOID(richEditorPattern);
89 auto overlayMod = DynamicCast<RichEditorOverlayModifier>(GetOverlayModifier(paintWrapper));
90 CHECK_NULL_VOID(overlayMod);
91 CHECK_NULL_VOID(!richEditorPattern->IsMoveCaretAnywhere()); // Avoid to reset caret offset
92 auto [caretOffset, caretHeight] = richEditorPattern->CalculateCaretOffsetAndHeight();
93 auto lastOffset = overlayMod->GetCaretOffset();
94 auto lastCaretY = lastOffset.GetY() + overlayMod->GetCaretHeight() - richEditorPattern->GetLastTextRect().GetY();
95 auto curCaretY = caretOffset.GetY() + caretHeight - richEditorPattern->GetTextRect().GetY();
96 overlayMod->SetCaretOffsetAndHeight(caretOffset, caretHeight);
97 if (richEditorPattern->IsTriggerAvoidOnCaretAvoidMode() || !NearEqual(lastCaretY, curCaretY) ||
98 !NearEqual(lastOffset.GetX(), caretOffset.GetX())) {
99 richEditorPattern->NotifyCaretChange();
100 richEditorPattern->ResetTriggerAvoidFlagOnCaretChange();
101 }
102 richEditorPattern->ChangeLastRichTextRect();
103 }
104
UpdateContentModifier(PaintWrapper * paintWrapper)105 void RichEditorPaintMethod::UpdateContentModifier(PaintWrapper* paintWrapper)
106 {
107 auto contentMod = DynamicCast<RichEditorContentModifier>(GetContentModifier(paintWrapper));
108 CHECK_NULL_VOID(contentMod);
109 TextPaintMethod::UpdateContentModifier(paintWrapper);
110 auto richEditorPattern = DynamicCast<RichEditorPattern>(GetPattern().Upgrade());
111 CHECK_NULL_VOID(richEditorPattern);
112 auto richtTextOffset = richEditorPattern->GetTextRect().GetOffset();
113 contentMod->SetRichTextRectX(richtTextOffset.GetX());
114 contentMod->SetRichTextRectY(richtTextOffset.GetY());
115
116 const auto& geometryNode = paintWrapper->GetGeometryNode();
117 auto frameSize = geometryNode->GetPaddingSize();
118 OffsetF paddingOffset = geometryNode->GetPaddingOffset() - geometryNode->GetFrameOffset();
119 contentMod->SetClipOffset(paddingOffset);
120 contentMod->SetClipSize(frameSize);
121 }
122 } // namespace OHOS::Ace::NG
123