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_PATTERNS_TEXT_SPAN_SPAN_OBJECT_H
17 #define FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_PATTERNS_TEXT_SPAN_SPAN_OBJECT_H
18 
19 #include <string>
20 #include <utility>
21 #include <vector>
22 
23 #include "base/memory/ace_type.h"
24 #include "base/memory/referenced.h"
25 #include "core/components/common/layout/constants.h"
26 #include "core/components_ng/pattern/text/span/tlv_util.h"
27 #include "core/components_ng/pattern/text/span_node.h"
28 #include "core/components_ng/pattern/text/text_model.h"
29 #include "core/components_ng/pattern/text/text_styles.h"
30 #include "core/components_ng/pattern/text_field/text_field_model.h"
31 #include "core/components_ng/render/paragraph.h"
32 
33 namespace OHOS::Ace {
34 
35 enum class SpanType {
36     Font = 0,
37     Decoration,
38     BaselineOffset,
39     LetterSpacing,
40     TextShadow = 4,
41     LineHeight = 5,
42     BackgroundColor = 6,
43     Url = 7,
44     Gesture = 100,
45     ParagraphStyle = 200,
46     Image = 300,
47     CustomSpan = 400,
48     ExtSpan = 500
49 };
50 
51 struct SpanParagraphStyle {
52     std::optional<TextAlign> align;
53     std::optional<int32_t> maxLines;
54     std::optional<WordBreak> wordBreak;
55     std::optional<TextOverflow> textOverflow;
56     std::optional<NG::LeadingMargin> leadingMargin;
57     std::optional<Dimension> textIndent;
58 
EqualSpanParagraphStyle59     bool Equal(const SpanParagraphStyle& other) const
60     {
61         auto flag = align == other.align && maxLines == other.maxLines && wordBreak == other.wordBreak &&
62                     textOverflow == other.textOverflow && textIndent == other.textIndent;
63         if (leadingMargin.has_value() && other.leadingMargin.has_value()) {
64             flag &= leadingMargin.value().CheckLeadingMargin(other.leadingMargin.value());
65         } else if (!leadingMargin.has_value() && !other.textOverflow.has_value()) {
66             flag &= true;
67         } else {
68             flag &= false;
69         }
70         return flag;
71     }
72 };
73 
74 enum class SpanOperation {
75     ADD = 0,
76     REMOVE,
77 };
78 
79 class SpanWatcher : public virtual AceType {
80     DECLARE_ACE_TYPE(SpanWatcher, AceType);
81 
82 public:
83     virtual void UpdateSpanItems(const std::list<RefPtr<NG::SpanItem>>& spanItems) = 0;
84 };
85 
86 struct GestureStyle {
87     std::optional<GestureEventFunc> onClick;
88     std::optional<GestureEventFunc> onLongPress;
89 
IsEqualGestureStyle90     bool IsEqual(const GestureStyle& other) const
91     {
92         return false;
93     }
94 };
95 
96 class SpanBase : public virtual AceType {
97     DECLARE_ACE_TYPE(SpanBase, AceType);
98 
99 public:
100     SpanBase() = default;
SpanBase(int32_t start,int32_t end)101     SpanBase(int32_t start, int32_t end) : start_(start), end_(end) {}
102     virtual bool IsAttributesEqual(const RefPtr<SpanBase>& other) const = 0;
103     virtual RefPtr<SpanBase> GetSubSpan(int32_t start, int32_t end) = 0;
104     virtual SpanType GetSpanType() const = 0;
105     virtual void ApplyToSpanItem(const RefPtr<NG::SpanItem>& spanItem, SpanOperation operation) const = 0;
106     virtual std::string ToString() const = 0;
107 
108     int32_t GetStartIndex() const;
109     int32_t GetEndIndex() const;
110     void UpdateStartIndex(int32_t startIndex);
111     void UpdateEndIndex(int32_t endIndex);
112     int32_t GetLength() const;
113     std::optional<std::pair<int32_t, int32_t>> GetIntersectionInterval(std::pair<int32_t, int32_t> interval) const;
114 
115 private:
116     int32_t start_ = 0;
117     int32_t end_ = 0; // The interval rules are closed on the left and open on the right
118 };
119 
120 class FontSpan : public SpanBase {
121     DECLARE_ACE_TYPE(FontSpan, SpanBase);
122 
123 public:
124     FontSpan() = default;
125     explicit FontSpan(Font font);
126     FontSpan(Font font, int32_t start, int32_t end);
127     Font GetFont() const;
128     RefPtr<SpanBase> GetSubSpan(int32_t start, int32_t end) override;
129     bool IsAttributesEqual(const RefPtr<SpanBase>& other) const override;
130     SpanType GetSpanType() const override;
131     std::string ToString() const override;
132     void ApplyToSpanItem(const RefPtr<NG::SpanItem>& spanItem, SpanOperation operation) const override;
133     static RefPtr<SpanBase> CreateDefaultSpan();
134 
135 private:
136     void AddSpanStyle(const RefPtr<NG::SpanItem>& spanItem) const;
137     static void RemoveSpanStyle(const RefPtr<NG::SpanItem>& spanItem);
138 
139     Font font_;
140 };
141 
142 class DecorationSpan : public SpanBase {
143     DECLARE_ACE_TYPE(DecorationSpan, SpanBase);
144 
145 public:
146     DecorationSpan() = default;
147     explicit DecorationSpan(TextDecoration type, std::optional<Color> color, std::optional<TextDecorationStyle> style);
148     DecorationSpan(TextDecoration type, std::optional<Color> color, std::optional<TextDecorationStyle> style,
149         int32_t start, int32_t end);
150     TextDecoration GetTextDecorationType() const;
151     std::optional<Color> GetColor() const;
152     std::optional<TextDecorationStyle> GetTextDecorationStyle() const;
153     RefPtr<SpanBase> GetSubSpan(int32_t start, int32_t end) override;
154     bool IsAttributesEqual(const RefPtr<SpanBase>& other) const override;
155     SpanType GetSpanType() const override;
156     std::string ToString() const override;
157     void ApplyToSpanItem(const RefPtr<NG::SpanItem>& spanItem, SpanOperation operation) const override;
158 
159 private:
160     void AddDecorationStyle(const RefPtr<NG::SpanItem>& spanItem) const;
161     static void RemoveDecorationStyle(const RefPtr<NG::SpanItem>& spanItem);
162 
163     TextDecoration type_;
164     std::optional<Color> color_;
165     std::optional<TextDecorationStyle> style_;
166 };
167 
168 class BaselineOffsetSpan : public SpanBase {
169     DECLARE_ACE_TYPE(BaselineOffsetSpan, SpanBase);
170 
171 public:
172     BaselineOffsetSpan() = default;
173     explicit BaselineOffsetSpan(Dimension baselineOffset);
174     BaselineOffsetSpan(Dimension baselineOffset, int32_t start, int32_t end);
175     Dimension GetBaselineOffset() const;
176     RefPtr<SpanBase> GetSubSpan(int32_t start, int32_t end) override;
177     bool IsAttributesEqual(const RefPtr<SpanBase>& other) const override;
178     SpanType GetSpanType() const override;
179     std::string ToString() const override;
180     void ApplyToSpanItem(const RefPtr<NG::SpanItem>& spanItem, SpanOperation operation) const override;
181 
182 private:
183     void AddBaselineOffsetStyle(const RefPtr<NG::SpanItem>& spanItem) const;
184     static void RemoveBaselineOffsetStyle(const RefPtr<NG::SpanItem>& spanItem);
185     Dimension baselineOffset_;
186 };
187 
188 class LetterSpacingSpan : public SpanBase {
189     DECLARE_ACE_TYPE(LetterSpacingSpan, SpanBase);
190 
191 public:
192     LetterSpacingSpan() = default;
193     explicit LetterSpacingSpan(Dimension letterSpacing);
194     LetterSpacingSpan(Dimension letterSpacing, int32_t start, int32_t end);
195     Dimension GetLetterSpacing() const;
196     RefPtr<SpanBase> GetSubSpan(int32_t start, int32_t end) override;
197     bool IsAttributesEqual(const RefPtr<SpanBase>& other) const override;
198     SpanType GetSpanType() const override;
199     std::string ToString() const override;
200     void ApplyToSpanItem(const RefPtr<NG::SpanItem>& spanItem, SpanOperation operation) const override;
201 
202 private:
203     void AddLetterSpacingStyle(const RefPtr<NG::SpanItem>& spanItem) const;
204     static void RemoveLetterSpacingStyle(const RefPtr<NG::SpanItem>& spanItem);
205 
206     Dimension letterSpacing_;
207 };
208 
209 class GestureSpan : public SpanBase {
210     DECLARE_ACE_TYPE(GestureSpan, SpanBase);
211 
212 public:
213     GestureSpan() = default;
214     explicit GestureSpan(GestureStyle gestureInfo);
215     ~GestureSpan() override = default;
216     GestureSpan(GestureStyle gestureInfo, int32_t start, int32_t end);
217     GestureStyle GetGestureStyle() const;
218     RefPtr<SpanBase> GetSubSpan(int32_t start, int32_t end) override;
219     bool IsAttributesEqual(const RefPtr<SpanBase>& other) const override;
220     SpanType GetSpanType() const override;
221     std::string ToString() const override;
222     void ApplyToSpanItem(const RefPtr<NG::SpanItem>& spanItem, SpanOperation operation) const override;
223 
224 private:
225     void AddSpanStyle(const RefPtr<NG::SpanItem>& spanItem) const;
226     static void RemoveSpanStyle(const RefPtr<NG::SpanItem>& spanItem);
227 
228     GestureStyle gestureInfo_;
229 };
230 
231 class TextShadowSpan : public SpanBase {
232     DECLARE_ACE_TYPE(TextShadowSpan, SpanBase);
233 
234 public:
235     TextShadowSpan() = default;
236     explicit TextShadowSpan(std::vector<Shadow> font);
237     TextShadowSpan(std::vector<Shadow> font, int32_t start, int32_t end);
238     std::vector<Shadow> GetTextShadow() const;
239     RefPtr<SpanBase> GetSubSpan(int32_t start, int32_t end) override;
240     bool IsAttributesEqual(const RefPtr<SpanBase>& other) const override;
241     SpanType GetSpanType() const override;
242     std::string ToString() const override;
243     void ApplyToSpanItem(const RefPtr<NG::SpanItem>& spanItem, SpanOperation operation) const override;
244 
245 private:
246     void AddSpanStyle(const RefPtr<NG::SpanItem>& spanItem) const;
247     static void RemoveSpanStyle(const RefPtr<NG::SpanItem>& spanItem);
248 
249     std::optional<std::vector<Shadow>> textShadow_ = std::nullopt;
250 };
251 class BackgroundColorSpan : public SpanBase {
252     DECLARE_ACE_TYPE(BackgroundColorSpan, SpanBase);
253 public:
254     BackgroundColorSpan() = default;
255     explicit BackgroundColorSpan(std::optional<TextBackgroundStyle> textBackgroundStyle_);
256     BackgroundColorSpan(std::optional<TextBackgroundStyle> textBackgroundStyle_, int32_t start, int32_t end);
257     TextBackgroundStyle GetBackgroundColor() const;
258     void SetBackgroundColorGroupId(int32_t groupId);
259     RefPtr<SpanBase> GetSubSpan(int32_t start, int32_t end) override;
260     bool IsAttributesEqual(const RefPtr<SpanBase>& other) const override;
261     SpanType GetSpanType() const override;
262     std::string ToString() const override;
263     void ApplyToSpanItem(const RefPtr<NG::SpanItem>& spanItem, SpanOperation operation) const override;
264 private:
265     std::optional<TextBackgroundStyle> textBackgroundStyle_;
266     void AddSpanStyle(const RefPtr<NG::SpanItem>& spanItem) const;
267     static void RemoveSpanStyle(const RefPtr<NG::SpanItem>& spanItem);
268 };
269 
270 class ImageSpan : public SpanBase {
271     DECLARE_ACE_TYPE(ImageSpan, SpanBase);
272 
273 public:
274     explicit ImageSpan(const ImageSpanOptions& options);
275     ImageSpan(const ImageSpanOptions& options, int32_t position);
276     bool IsAttributesEqual(const RefPtr<SpanBase>& other) const override;
277     RefPtr<SpanBase> GetSubSpan(int32_t start, int32_t end) override;
278     SpanType GetSpanType() const override;
279     void ApplyToSpanItem(const RefPtr<NG::SpanItem>& spanItem, SpanOperation operation) const override;
280     std::string ToString() const override;
281 
282     const ImageSpanOptions& GetImageSpanOptions();
283     const std::optional<ImageSpanAttribute>& GetImageAttribute() const;
284 
285 private:
286     ImageSpanOptions imageOptions_;
287 };
288 
289 class CustomSpan : public SpanBase {
290     DECLARE_ACE_TYPE(CustomSpan, SpanBase);
291 
292 public:
293     CustomSpan();
294     explicit CustomSpan(std::optional<std::function<CustomSpanMetrics(CustomSpanMeasureInfo)>> onMeasure,
295         std::optional<std::function<void(NG::DrawingContext&, CustomSpanOptions)>> onDraw);
296 
297     explicit CustomSpan(std::optional<std::function<CustomSpanMetrics(CustomSpanMeasureInfo)>> onMeasure,
298         std::optional<std::function<void(NG::DrawingContext&, CustomSpanOptions)>> onDraw, int32_t start, int32_t end);
299     virtual ~CustomSpan() override = default;
300     RefPtr<SpanBase> GetSubSpan(int32_t start, int32_t end) override;
301     bool IsAttributesEqual(const RefPtr<SpanBase>& other) const override;
302     SpanType GetSpanType() const override;
303     void SetOnMeasure(std::function<CustomSpanMetrics(CustomSpanMeasureInfo)> onMeasure);
304     void SetOnDraw(std::function<void(NG::DrawingContext&, CustomSpanOptions)> onDraw);
305     std::optional<std::function<CustomSpanMetrics(CustomSpanMeasureInfo)>> GetOnMeasure();
306     std::optional<std::function<void(NG::DrawingContext&, CustomSpanOptions)>> GetOnDraw();
307     std::string ToString() const override;
308     void ApplyToSpanItem(const RefPtr<NG::SpanItem>& spanItem, SpanOperation operation) const override;
AddStyledString(const WeakPtr<SpanStringBase> & spanString)309     virtual void AddStyledString(const WeakPtr<SpanStringBase>& spanString) {}
RemoveStyledString(const WeakPtr<SpanStringBase> & spanString)310     virtual void RemoveStyledString(const WeakPtr<SpanStringBase>& spanString) {}
311 
312 private:
313     std::optional<std::function<CustomSpanMetrics(CustomSpanMeasureInfo)>> onMeasure_;
314     std::optional<std::function<void(NG::DrawingContext&, CustomSpanOptions)>> onDraw_;
315 };
316 
317 class ParagraphStyleSpan : public SpanBase {
318     DECLARE_ACE_TYPE(ParagraphStyleSpan, SpanBase);
319 
320 public:
321     ParagraphStyleSpan() = default;
322     explicit ParagraphStyleSpan(SpanParagraphStyle paragraphStyle);
323     ParagraphStyleSpan(SpanParagraphStyle paragraphStyle, int32_t start, int32_t end);
324     SpanParagraphStyle GetParagraphStyle() const;
325     RefPtr<SpanBase> GetSubSpan(int32_t start, int32_t end) override;
326     bool IsAttributesEqual(const RefPtr<SpanBase>& other) const override;
327     SpanType GetSpanType() const override;
328     std::string ToString() const override;
329     void ApplyToSpanItem(const RefPtr<NG::SpanItem>& spanItem, SpanOperation operation) const override;
330 
331 private:
332     void AddParagraphStyle(const RefPtr<NG::SpanItem>& spanItem) const;
333     void RemoveParagraphStyle(const RefPtr<NG::SpanItem>& spanItem) const;
334 
335     SpanParagraphStyle paragraphStyle_;
336 };
337 
338 class LineHeightSpan : public SpanBase {
339     DECLARE_ACE_TYPE(LineHeightSpan, SpanBase);
340 
341 public:
342     LineHeightSpan() = default;
343     explicit LineHeightSpan(Dimension lineHeight);
344     LineHeightSpan(Dimension lineHeight, int32_t start, int32_t end);
345     Dimension GetLineHeight() const;
346     RefPtr<SpanBase> GetSubSpan(int32_t start, int32_t end) override;
347     bool IsAttributesEqual(const RefPtr<SpanBase>& other) const override;
348     SpanType GetSpanType() const override;
349     std::string ToString() const override;
350     void ApplyToSpanItem(const RefPtr<NG::SpanItem>& spanItem, SpanOperation operation) const override;
351 
352 private:
353     void AddLineHeightStyle(const RefPtr<NG::SpanItem>& spanItem) const;
354     void RemoveLineHeightStyle(const RefPtr<NG::SpanItem>& spanItem) const;
355 
356     Dimension lineHeight_;
357 };
358 
359 class ExtSpan : public SpanBase {
360     DECLARE_ACE_TYPE(ExtSpan, SpanBase);
361 
362 public:
363     ExtSpan() = default;
364     ExtSpan(int32_t start, int32_t end);
365     RefPtr<SpanBase> GetSubSpan(int32_t start, int32_t end) override;
366     bool IsAttributesEqual(const RefPtr<SpanBase>& other) const override;
367     SpanType GetSpanType() const override;
368     std::string ToString() const override;
ApplyToSpanItem(const RefPtr<NG::SpanItem> & spanItem,SpanOperation operation)369     void ApplyToSpanItem(const RefPtr<NG::SpanItem>& spanItem, SpanOperation operation) const override {}
370 };
371 class UrlSpan : public SpanBase {
372     DECLARE_ACE_TYPE(UrlSpan, SpanBase);
373 
374 public:
375     UrlSpan() = default;
376     explicit UrlSpan(const std::string& urlAddress);
377     UrlSpan(const std::string& urlAddress, int32_t start, int32_t end);
378     std::string GetUrlSpanAddress() const;
379     RefPtr<SpanBase> GetSubSpan(int32_t start, int32_t end) override;
380     bool IsAttributesEqual(const RefPtr<SpanBase>& other) const override;
381     SpanType GetSpanType() const override;
382     std::string ToString() const override;
383     void ApplyToSpanItem(const RefPtr<NG::SpanItem>& spanItem,
384         SpanOperation operation) const override;
385 private:
386     void AddUrlStyle(const RefPtr<NG::SpanItem>& spanItem) const;
387     static void RemoveUrlStyle(const RefPtr<NG::SpanItem>& spanItem);
388     std::string urlAddress_;
389 };
390 } // namespace OHOS::Ace
391 #endif // FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_PATTERNS_TEXT_SPAN_SPAN_OBJECT_H