1 /*
2  * Copyright (c) 2022-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 #ifndef FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_RENDER_ADAPTER_TXT_PARAGRAPH_H
17 #define FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_RENDER_ADAPTER_TXT_PARAGRAPH_H
18 
19 #ifndef USE_GRAPHIC_TEXT_GINE
20 #include "txt/font_collection.h"
21 #include "txt/paragraph_builder.h"
22 #include "txt/paragraph_txt.h"
23 #else
24 #include "core/components_ng/render/adapter/rosen_render_context.h"
25 #include "core/components_ng/render/drawing.h"
26 #endif
27 
28 #include "base/utils/noncopyable.h"
29 #include "core/components/common/properties/text_layout_info.h"
30 #include "core/components_ng/render/paragraph.h"
31 
32 namespace OHOS::Ace::NG {
33 
34 // Paragraph is interface for drawing text and text paragraph.
35 class TxtParagraph : public Paragraph {
DECLARE_ACE_TYPE(NG::TxtParagraph,NG::Paragraph)36     DECLARE_ACE_TYPE(NG::TxtParagraph, NG::Paragraph)
37 
38 public:
39 #ifndef USE_GRAPHIC_TEXT_GINE
40     TxtParagraph(const ParagraphStyle& paraStyle, std::shared_ptr<txt::FontCollection> fontCollection)
41         : paraStyle_(paraStyle), fontCollection_(std::move(fontCollection))
42     {}
43 
TxtParagraph(void * paragraph)44     TxtParagraph(void* paragraph) : hasExternalParagraph_(true)
45     {}
46 
SetParagraphSymbolAnimation(const RefPtr<FrameNode> & frameNode)47     void SetParagraphSymbolAnimation(const RefPtr<FrameNode>& frameNode) override
48     {}
49 #else
50     TxtParagraph(const ParagraphStyle& paraStyle, std::shared_ptr<RSFontCollection> fontCollection)
51         : paraStyle_(paraStyle), fontCollection_(std::move(fontCollection))
52     {}
53 
54     TxtParagraph(void* paragraph)
55     {
56         hasExternalParagraph_ = true;
57         externalParagraph_ = reinterpret_cast<RSParagraph*>(paragraph);
58     }
59 
60     void SetParagraphSymbolAnimation(const RefPtr<FrameNode>& frameNode) override
61     {
62         auto context = AceType::DynamicCast<NG::RosenRenderContext>(frameNode->GetRenderContext());
63         auto rsNode = context->GetRSNode();
64         rsSymbolAnimation_ = RSSymbolAnimation();
65         rsSymbolAnimation_.SetNode(rsNode);
66 
67         std::function<bool(
68             const std::shared_ptr< RSSymbolAnimationConfig>& symbolAnimationConfig)>
69             scaleCallback = std::bind(&RSSymbolAnimation::SetSymbolAnimation,
70             rsSymbolAnimation_,
71             std::placeholders::_1);
72 
73         SetAnimation(scaleCallback);
74     }
75 
76     void SetAnimation(
77         std::function<bool(
78             const std::shared_ptr<Rosen::TextEngine::SymbolAnimationConfig>&)>& animationFunc)
79     {
80         if (animationFunc == nullptr) {
81             TAG_LOGE(AceLogTag::ACE_TEXT_FIELD, "HmSymbol txt_paragraph::SetAnimation failed ");
82         } else {
83             auto paragraph = GetParagraph();
84             CHECK_NULL_VOID(paragraph);
85             paragraph->SetAnimation(animationFunc);
86             TAG_LOGD(AceLogTag::ACE_TEXT_FIELD, "HmSymbol txt_paragraph::SetAnimation success ");
87         }
88     }
89 #endif
90     ~TxtParagraph() override;
91 
92     // whether the paragraph has been build
93     bool IsValid() override;
94 
95     // interfaces for build text paragraph
96     void PushStyle(const TextStyle& style) override;
97     void PopStyle() override;
98 
99     void AddText(const std::u16string& text) override;
100     void AddSymbol(const uint32_t& symbolId) override;
101     int32_t AddPlaceholder(const PlaceholderRun& span) override;
102     void Build() override;
103     void Reset() override;
104 
105     // interfaces for layout
106     void Layout(float width) override;
107     float GetHeight() override;
108     float GetTextWidth() override;
109     size_t GetLineCount() override;
110     float GetMaxIntrinsicWidth() override;
111     bool DidExceedMaxLines() override;
112     float GetLongestLine() override;
113     float GetLongestLineWithIndent() override;
114     float GetMaxWidth() override;
115     float GetAlphabeticBaseline() override;
116     float GetCharacterWidth(int32_t index) override;
117 
118     // interfaces for painting
119     void Paint(RSCanvas& canvas, float x, float y) override;
120 #ifndef USE_ROSEN_DRAWING
121     void Paint(SkCanvas* skCanvas, float x, float y) override;
122 #endif
123 
124     // interfaces for calculate the the specified paragraph position
125     int32_t GetGlyphIndexByCoordinate(const Offset& offset, bool isSelectionPos = false) override;
126     PositionWithAffinity GetGlyphPositionAtCoordinate(const Offset& offset) override;
127     void AdjustIndexForward(const Offset& offset, bool compareOffset, int32_t& index);
128     void GetRectsForRange(int32_t start, int32_t end, std::vector<RectF>& selectedRects) override;
129     void GetTightRectsForRange(int32_t start, int32_t end, std::vector<RectF>& selectedRects) override;
130     void GetRectsForPlaceholders(std::vector<RectF>& selectedRects) override;
131     bool ComputeOffsetForCaretDownstream(int32_t extent, CaretMetricsF& result, bool needLineHighest = true) override;
132     bool ComputeOffsetForCaretUpstream(int32_t extent, CaretMetricsF& result, bool needLineHighest = true) override;
133     bool CalcCaretMetricsByPosition(int32_t extent, CaretMetricsF& caretCaretMetric, TextAffinity textAffinity,
134         bool needLineHighest = true) override;
135     bool CalcCaretMetricsByPosition(int32_t extent, CaretMetricsF& caretCaretMetric, const OffsetF& lastTouchOffset,
136         TextAffinity& textAffinity) override;
137     void SetIndents(const std::vector<float>& indents) override;
138     bool GetWordBoundary(int32_t offset, int32_t& start, int32_t& end) override;
139     std::u16string GetParagraphText() override;
140     const ParagraphStyle& GetParagraphStyle() const override;
empty()141     bool empty() const
142     {
143         return GetParagraphLength() == 0;
144     }
145     LineMetrics GetLineMetricsByRectF(RectF& rect) override;
146     TextLineMetrics GetLineMetrics(size_t lineNumber) override;
147     RectF GetPaintRegion(float x, float y) override;
148     void SetRunMetrics(RunMetrics& runMetrics, const OHOS::Rosen::RunMetrics& runMetricsRes);
149     bool GetLineMetricsByCoordinate(const Offset& offset, LineMetrics& lineMetrics) override;
150     void UpdateColor(size_t from, size_t to, const Color& color) override;
151     void TxtGetRectsForRange(int32_t start, int32_t end,
152         RectHeightStyle heightStyle, RectWidthStyle widthStyle,
153         std::vector<RectF>& selectedRects, std::vector<TextDirection>& textDirections) override;
154 
155 private:
156     void CreateBuilder();
157     bool CalCulateAndCheckPreIsPlaceholder(int32_t index, int32_t& extent);
GetParagraphLength()158     inline size_t GetParagraphLength() const
159     {
160         return text_.length() + placeholderCnt_;
161     }
162     float MakeEmptyOffsetX();
163     bool HandleCaretWhenEmpty(CaretMetricsF& result);
164     void HandleTextAlign(CaretMetricsF& result, TextAlign align);
165     void HandleLeadingMargin(CaretMetricsF& result, LeadingMargin leadingMargin);
166     void GetRectsForRangeInner(int32_t start, int32_t end, std::vector<RectF>& selectedRects,
167         RectHeightPolicy rectHeightPolicy = RectHeightPolicy::COVER_LINE);
168     int32_t AdjustIndexForEmoji(int32_t index);
169     bool IsIndexInEmoji(int32_t index, int32_t& emojiStart, int32_t& emojiEnd);
170     void CalculateLeadingMarginOffest(float& x, float& y);
171 
172     ParagraphStyle paraStyle_;
173 #ifndef USE_GRAPHIC_TEXT_GINE
174     txt::Paragraph* GetParagraph();
175     std::unique_ptr<txt::Paragraph> paragraph_;
176     std::unique_ptr<txt::ParagraphBuilder> builder_;
177     std::shared_ptr<txt::FontCollection> fontCollection_;
178 #else
179     RSParagraph* GetParagraph();
180     Rosen::RSSymbolAnimation rsSymbolAnimation_;
181     std::unique_ptr<RSParagraph> paragraph_;
182     RSParagraph* externalParagraph_ = nullptr;
183     std::unique_ptr<RSParagraphBuilder> builder_;
184     std::shared_ptr<RSFontCollection> fontCollection_;
185 #endif
186     std::u16string text_;
187     int32_t placeholderCnt_ = 0;
188     TextAlign textAlign_ = TextAlign::START;
189     static uint32_t destructCount;
190     std::list<size_t> placeholderPosition_;
191     bool hasExternalParagraph_ = false;
192 
193     ACE_DISALLOW_COPY_AND_MOVE(TxtParagraph);
194 };
195 
196 } // namespace OHOS::Ace::NG
197 
198 #endif // FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_RENDER_ADAPTER_TXT_PARAGRAPH_H
199