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