• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2025 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_COMPONENTS_NG_PATTERNS_RICH_EDITOR_PARAGRAPH_MANAGER_H
17 #define FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_PATTERNS_RICH_EDITOR_PARAGRAPH_MANAGER_H
18 
19 #include "core/components_ng/pattern/rich_editor/paragraph_manager.h"
20 
21 namespace OHOS::Ace::NG {
22 
23 class RichEditorParagraphManager : public ParagraphManager {
24     DECLARE_ACE_TYPE(RichEditorParagraphManager, ParagraphManager);
25 
26 public:
AddParagraph(ParagraphInfo && info)27     void AddParagraph(ParagraphInfo&& info)
28     {
29         paragraphs_.emplace_back(std::move(info));
30         hasPosyRange = false;
31     }
32 
SetParagraphs(const std::vector<ParagraphInfo> & paragraphs)33     void SetParagraphs(const std::vector<ParagraphInfo>& paragraphs)
34     {
35         paragraphs_ = paragraphs;
36         hasPosyRange = false;
37     }
38 
Reset()39     void Reset()
40     {
41         paragraphs_.clear();
42         hasPosyRange = false;
43     }
44 
GetHeight()45     float GetHeight()
46     {
47         ACE_SCOPED_TRACE("RichEditorParagraphManager::GetHeight");
48         if (paragraphs_.empty()) {
49             return 0.0f;
50         }
51         if (!hasPosyRange) {
52             CalPosyRange();
53         }
54         return paragraphs_.back().bottomPos;
55     }
56 
CalPosyRange()57     void CalPosyRange()
58     {
59         CHECK_NULL_VOID(!hasPosyRange);
60         ACE_SCOPED_TRACE("RichEditorParagraphManager::CalPosyRange");
61         float cumHeight = 0;
62         for (auto& paragraphInfo : paragraphs_) {
63             paragraphInfo.topPos = cumHeight;
64             cumHeight += paragraphInfo.paragraph->GetHeight();
65             paragraphInfo.bottomPos = cumHeight;
66         }
67         hasPosyRange = true;
68     }
69 
70     std::vector<RectF> GetRects(int32_t start, int32_t end,
71             RectHeightPolicy rectHeightPolicy = RectHeightPolicy::COVER_LINE) const override
72     {
73         std::vector<RectF> res;
74         float y = 0.0f;
75         float paragraphSpacing = 0.0f;
76         bool isConsiderSpacing = false;
77         for (auto&& info : paragraphs_) {
78             std::vector<RectF> rects;
79             CHECK_NULL_BREAK(info.start <= end);
80             if (info.end <= start) {
81                 y += info.paragraph->GetHeight();
82                 continue;
83             }
84             auto relativeStart = (start < info.start) ? 0 : start - info.start;
85             if (rectHeightPolicy == RectHeightPolicy::COVER_TEXT) {
86                 info.paragraph->GetTightRectsForRange(relativeStart, end - info.start, rects);
87             } else {
88                 info.paragraph->GetRectsForRange(relativeStart, end - info.start, rects);
89             }
90             if (!rects.empty() && !NearZero(paragraphSpacing) && isConsiderSpacing) {
91                 auto firstRect = rects.front();
92                 for (auto&& rect : rects) {
93                     CHECK_NULL_CONTINUE(NearEqual(firstRect.Top(), rect.Top()));
94                     rect.SetHeight(rect.Height() + paragraphSpacing);
95                     rect.SetTop(rect.Top() - paragraphSpacing);
96                 }
97             }
98             for (auto&& rect : rects) {
99                 rect.SetTop(rect.Top() + y);
100             }
101             res.insert(res.end(), rects.begin(), rects.end());
102             paragraphSpacing = (rects.empty() && (info.end - info.start == 1)) ? 0.0f :
103                 info.paragraphStyle.paragraphSpacing.ConvertToPx();
104             if (info.start <= start && info.end > start) {
105                 isConsiderSpacing = true;
106             }
107             y += info.paragraph->GetHeight();
108         }
109         return res;
110     }
111 
112 private:
113     bool hasPosyRange = false;
114 };
115 } // namespace OHOS::Ace::NG
116 #endif
117