1 /* 2 * Copyright (c) 2024 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_PATTERN_TEXT_MULTIPLE_PARAGRAPH_LAYOUT_ALGORITHM_H 17 #define FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_PATTERN_TEXT_MULTIPLE_PARAGRAPH_LAYOUT_ALGORITHM_H 18 19 #include <list> 20 #include <optional> 21 #include <string> 22 #include <unordered_map> 23 #include <utility> 24 25 #include "base/memory/referenced.h" 26 #include "core/components_ng/base/frame_node.h" 27 #include "core/components_ng/layout/box_layout_algorithm.h" 28 #include "core/components_ng/layout/layout_wrapper.h" 29 #include "core/components_ng/pattern/rich_editor/paragraph_manager.h" 30 #include "core/components_ng/pattern/text/span_node.h" 31 #include "core/components_ng/pattern/text/text_content_modifier.h" 32 #include "core/components_ng/pattern/text/text_layout_property.h" 33 #include "core/components_ng/pattern/text/text_styles.h" 34 35 namespace OHOS::Ace::NG { 36 // TextLayoutAlgorithm acts as the underlying text layout. 37 class ACE_EXPORT MultipleParagraphLayoutAlgorithm : public BoxLayoutAlgorithm { 38 DECLARE_ACE_TYPE(MultipleParagraphLayoutAlgorithm, BoxLayoutAlgorithm); 39 40 public: 41 MultipleParagraphLayoutAlgorithm() = default; 42 ~MultipleParagraphLayoutAlgorithm() override = default; 43 44 void Measure(LayoutWrapper* layoutWrapper) override; 45 void Layout(LayoutWrapper* layoutWrapper) override; GetBaselineOffset()46 virtual float GetBaselineOffset() const 47 { 48 return 0.0f; 49 } 50 51 static SizeF GetMaxMeasureSize(const LayoutConstraintF& contentConstraint); 52 RefPtr<Paragraph> GetSingleParagraph() const; 53 54 protected: 55 void GetSpanParagraphStyle(LayoutWrapper* layoutWrapper, const RefPtr<SpanItem>& spanItem, ParagraphStyle& pStyle); 56 virtual ParagraphStyle GetParagraphStyle( 57 const TextStyle& textStyle, const std::string& content, LayoutWrapper* layoutWrapper) const; 58 virtual bool CreateParagraph( 59 const TextStyle& textStyle, std::string content, LayoutWrapper* layoutWrapper, double maxWidth = 0.0) = 0; HandleEmptyParagraph(RefPtr<Paragraph> paragraph,const std::list<RefPtr<SpanItem>> & spanGroup)60 virtual void HandleEmptyParagraph(RefPtr<Paragraph> paragraph, const std::list<RefPtr<SpanItem>>& spanGroup) {} GetParagraphStyleSpanItem(const std::list<RefPtr<SpanItem>> & spanGroup)61 virtual RefPtr<SpanItem> GetParagraphStyleSpanItem(const std::list<RefPtr<SpanItem>>& spanGroup) 62 { 63 CHECK_NULL_RETURN(!spanGroup.empty(), nullptr); 64 return spanGroup.front(); 65 } 66 67 void ApplyIndent(ParagraphStyle& paragraphStyle, const RefPtr<Paragraph>& paragraph, double width, 68 const TextStyle& textStyle); 69 void ConstructTextStyles( 70 const LayoutConstraintF& contentConstraint, LayoutWrapper* layoutWrapper, TextStyle& textStyle); 71 bool ParagraphReLayout(const LayoutConstraintF& contentConstraint); 72 bool UpdateParagraphBySpan(LayoutWrapper* layoutWrapper, ParagraphStyle paraStyle, double maxWidth, 73 const TextStyle& textStyle); 74 OffsetF SetContentOffset(LayoutWrapper* layoutWrapper); SpansToString()75 std::string SpansToString() 76 { 77 std::stringstream ss; 78 for (auto& list : spans_) { 79 ss << "["; 80 for_each(list.begin(), list.end(), [&ss](RefPtr<SpanItem>& item) { 81 ss << "[" << item->interval.first << "," << item->interval.second << ":" 82 << StringUtils::RestoreEscape(item->content) << "], "; 83 }); 84 ss << "], "; 85 } 86 return ss.str(); 87 } 88 GetParagraphs()89 std::list<ParagraphManager::ParagraphInfo> GetParagraphs() 90 { 91 std::list<ParagraphManager::ParagraphInfo> paragraphInfo; 92 if (paragraphManager_) { 93 paragraphInfo = paragraphManager_->GetParagraphs(); 94 } 95 return paragraphInfo; 96 } 97 98 std::vector<std::list<RefPtr<SpanItem>>> spans_; 99 RefPtr<ParagraphManager> paragraphManager_; 100 std::optional<TextStyle> textStyle_; 101 float baselineOffset_ = 0.0f; 102 float shadowOffset_ = 0.0f; 103 bool spanStringHasMaxLines_ = false; 104 bool isSpanStringMode_ = false; 105 bool isMarquee_ = false; 106 107 private: 108 virtual OffsetF GetContentOffset(LayoutWrapper* layoutWrapper) = 0; GetShadowOffset(const std::list<RefPtr<SpanItem>> & group)109 virtual float GetShadowOffset(const std::list<RefPtr<SpanItem>>& group) 110 { 111 return 0.0f; 112 } 113 static TextDirection GetTextDirection(const std::string& content, LayoutWrapper* layoutWrapper); 114 static TextDirection GetTextDirectionByContent(const std::string& content); 115 116 void UpdateSymbolSpanEffect( 117 RefPtr<FrameNode>& frameNode, const RefPtr<Paragraph>& paragraph, const std::list<RefPtr<SpanItem>>& spans); 118 void FontRegisterCallback(const RefPtr<FrameNode>& frameNode, const TextStyle& textStyle); 119 void UpdateTextColorIfForeground(const RefPtr<FrameNode>& frameNode, TextStyle& textStyle); 120 void SetPropertyToModifier(const RefPtr<TextLayoutProperty>& layoutProperty, 121 const RefPtr<TextContentModifier>& modifier, const TextStyle& textStyle); 122 void SetDecorationPropertyToModifier(const RefPtr<TextLayoutProperty>& layoutProperty, 123 const RefPtr<TextContentModifier>& modifier, const TextStyle& textStyle); 124 void SetFontSizePropertyToModifier(const RefPtr<TextLayoutProperty>& layoutProperty, 125 const RefPtr<TextContentModifier>&, const TextStyle& textStyle); 126 127 void AddImageToParagraph(RefPtr<ImageSpanItem>& imageSpanItem, const RefPtr<LayoutWrapper>& iterItem, 128 const LayoutConstraintF& layoutConstrain, const RefPtr<Paragraph>& paragraph, int32_t& spanTextLength, 129 const TextStyle& textStyle); 130 void AddPlaceHolderToParagraph(RefPtr<PlaceholderSpanItem>& placeholderSpanItem, 131 const RefPtr<LayoutWrapper>& layoutWrapper, const LayoutConstraintF& layoutConstrain, 132 const RefPtr<Paragraph>& paragraph, int32_t& spanTextLength); 133 void UpdateParagraphByCustomSpan(RefPtr<CustomSpanItem>& customSpanItem, LayoutWrapper* layoutWrapper, 134 const RefPtr<Paragraph>& paragraph, int32_t& spanTextLength, CustomSpanPlaceholderInfo& customSpanPlaceholder); 135 136 void AddSymbolSpanToParagraph(const RefPtr<SpanItem>& child, int32_t& spanTextLength, 137 const RefPtr<FrameNode>& frameNode, const RefPtr<Paragraph>& paragraph); 138 void AddTextSpanToParagraph(const RefPtr<SpanItem>& child, int32_t& spanTextLength, 139 const RefPtr<FrameNode>& frameNode, const RefPtr<Paragraph>& paragraph); 140 141 void GetChildrenPlaceholderIndex(std::vector<int32_t>& placeholderIndex); 142 143 int32_t preParagraphsPlaceholderCount_ = 0; 144 int32_t currentParagraphPlaceholderCount_ = 0; 145 146 float paragraphFontSize_ = 0.0f; 147 148 ACE_DISALLOW_COPY_AND_MOVE(MultipleParagraphLayoutAlgorithm); 149 }; 150 } // namespace OHOS::Ace::NG 151 152 #endif // FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_PATTERN_TEXT_MULTIPLE_PARAGRAPH_LAYOUT_ALGORITHM_H 153