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_HTML_TO_SPAN_H
17 #define FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_PATTERNS_TEXT_SPAN_HTML_TO_SPAN_H
18 
19 #include <list>
20 #include <string>
21 #include <unordered_map>
22 #include <variant>
23 #include <vector>
24 
25 #include "libxml/HTMLparser.h"
26 #include "libxml/HTMLtree.h"
27 #include "libxml/parser.h"
28 
29 #include "base/geometry/dimension.h"
30 #include "base/memory/ace_type.h"
31 #include "base/memory/referenced.h"
32 #include "base/utils/string_utils.h"
33 #include "base/utils/utils.h"
34 #include "core/components/common/properties/color.h"
35 #include "core/components/common/properties/text_style.h"
36 #include "core/components/text/text_theme.h"
37 #include "core/components_ng/pattern/text/span/mutable_span_string.h"
38 #include "core/components_ng/pattern/text/span/span_object.h"
39 #include "core/components_ng/pattern/text/span/span_string.h"
40 #include "core/components_ng/pattern/text/span_node.h"
41 #include "core/components_ng/pattern/text/text_model.h"
42 #include "core/components_ng/pattern/text/text_pattern.h"
43 #include "core/components_ng/pattern/text/text_styles.h"
44 
45 namespace OHOS::Ace {
46 
47 class SpanStringBase;
48 
49 class HtmlToSpan {
50 public:
HtmlToSpan()51     explicit HtmlToSpan() {};
~HtmlToSpan()52     ~HtmlToSpan() {};
53     RefPtr<MutableSpanString> ToSpanString(const std::string& html, const bool isNeedLoadPixelMap = true);
54     using Styles = std::vector<std::pair<std::string, std::string>>;
55 
56     class DecorationSpanParam {
57     public:
58         TextDecoration decorationType;
59         Color color;
60         TextDecorationStyle decorationSytle;
61     };
62     class BaseLineSpanParam {
63     public:
64         Dimension dimension;
65     };
66     class LetterSpacingSpanParam {
67     public:
68         Dimension dimension;
69     };
70     class LineHeightSpanSparam {
71     public:
72         Dimension dimension;
73     };
74     using StyleValue = std::variant<std::monostate, Font, DecorationSpanParam, BaseLineSpanParam,
75         LetterSpacingSpanParam, LineHeightSpanSparam, std::vector<Shadow>, ImageSpanOptions, SpanParagraphStyle>;
76     enum class StyleIndex {
77         STYLE_NULL = 0,
78         STYLE_FONT,
79         STYLE_DECORATION,
80         STYLE_BASELINE,
81         STYLE_LETTERSPACE,
82         STYLE_LINEHEIGHT,
83         STYLE_SHADOWS,
84         STYLE_IMAGE,
85         STYLE_PARAGRAPH,
86         STYLE_MAX
87     };
88 
89 private:
90     enum class HtmlType {
91         PARAGRAPH = 0,
92         IMAGE,
93         TEXT,
94         DEFAULT,
95     };
96 
97     struct SpanInfo {
98         HtmlType type;
99         size_t start;
100         size_t end;
101         std::vector<StyleValue> values;
102     };
103     using StyleValues = std::map<std::string, StyleValue>;
104     template<class T>
105     T* Get(StyleValue* styleValue) const;
106     Styles ParseStyleAttr(const std::string& style);
107     bool IsParagraphAttr(const std::string& key);
108     void InitParagrap(const std::string& key, const std::string& value, const std::string& index, StyleValues& values);
109     void InitFont(const std::string& key, const std::string& value, const std::string& index, StyleValues& values);
110     bool IsFontAttr(const std::string& key);
111     void InitDecoration(
112         const std::string& key, const std::string& value, const std::string& index, StyleValues& values);
113     bool IsDecorationAttr(const std::string& key);
114     template<class T>
115     void InitDimension(const std::string& key, const std::string& value, const std::string& index, StyleValues& values);
116     bool IsLetterSpacingAttr(const std::string& key);
117     void InitTextShadow(
118         const std::string& key, const std::string& value, const std::string& index, StyleValues& values);
119     bool IsTextShadowAttr(const std::string& key);
120     std::pair<std::string, double> GetUnitAndSize(const std::string& str);
121     bool IsLength(const std::string& str);
122     void InitShadow(Shadow &textShadow, std::vector<std::string> &attribute);
123     void InitLineHeight(const std::string& key, const std::string& value, StyleValues& values);
124     Dimension FromString(const std::string& str);
125     TextAlign StringToTextAlign(const std::string& value);
126     WordBreak StringToWordBreak(const std::string& value);
127     TextOverflow StringToTextOverflow(const std::string& value);
128     bool IsTextIndentAttr(const std::string& key);
129     bool IsLineHeightAttr(const std::string& key);
130     bool IsPaddingAttr(const std::string& key);
131     bool IsMarginAttr(const std::string& key);
132     bool IsBorderAttr(const std::string& key);
133     bool IsDecorationLine(const std::string& key);
134     bool IsDecorationStyle(const std::string& key);
135     void SetPaddingOption(const std::string& key, const std::string& value, ImageSpanOptions& options);
136     void SetMarginOption(const std::string& key, const std::string& value, ImageSpanOptions& options);
137     void SetBorderOption(const std::string& key, const std::string& value, ImageSpanOptions& options);
138     template<class T>
139     std::pair<bool, HtmlToSpan::StyleValue*> GetStyleValue(
140         const std::string& key, std::map<std::string, StyleValue>& values);
141     void HandleImgSpanOption(const Styles& styleMap, ImageSpanOptions& options);
142     void HandleImagePixelMap(const std::string& src, ImageSpanOptions& option);
143     void HandleImageSize(const std::string& key, const std::string& value, ImageSpanOptions& options);
144     void MakeImageSpanOptions(const std::string& key, const std::string& value, ImageSpanOptions& imgOpt);
145 
146     Color ToSpanColor(const std::string& color);
147 
148     void ToDefalutSpan(xmlNodePtr node, size_t len, size_t& pos, std::vector<SpanInfo>& spanInfos);
149     std::map<std::string, HtmlToSpan::StyleValue> ToTextSpanStyle(xmlAttrPtr curNode);
150     void AddStyleSpan(const std::string& element, SpanInfo& info);
151     void ToTextSpan(const std::string& element, xmlNodePtr node, size_t len,
152         size_t& pos, std::vector<SpanInfo>& spanInfos);
153 
154     void ToImageOptions(const std::map<std::string, std::string>& styles, ImageSpanOptions& option);
155     void ToImage(xmlNodePtr node, size_t len, size_t& pos, std::vector<SpanInfo>& spanInfos,
156         bool isProcessImageOptions = true);
157 
158     void ToParagraphStyle(const Styles& styleMap, SpanParagraphStyle& style);
159     void ToParagraphSpan(xmlNodePtr node, size_t len, size_t& pos, std::vector<SpanInfo>& spanInfos);
160 
161     void ParaseHtmlToSpanInfo(
162         xmlNodePtr node, size_t& pos, std::string& allContent, std::vector<SpanInfo>& spanInfos,
163         bool isNeedLoadPixelMap = true);
164     void ToSpan(xmlNodePtr curNode, size_t& pos, std::string& allContent, std::vector<SpanInfo>& spanInfos,
165         bool isNeedLoadPixelMap = true);
166     void PrintSpanInfos(const std::vector<SpanInfo>& spanInfos);
167     void AfterProcSpanInfos(std::vector<SpanInfo>& spanInfos);
168     bool IsValidNode(const std::string& name);
169 
170     RefPtr<SpanBase> CreateSpan(size_t index, const SpanInfo& info, StyleValue& value);
171     template<class T, class P>
172     RefPtr<SpanBase> MakeSpan(const SpanInfo& info, StyleValue& value);
173     template<class T, class P>
174     RefPtr<SpanBase> MakeDimensionSpan(const SpanInfo& info, StyleValue& value);
175     RefPtr<SpanBase> MakeDecorationSpan(const SpanInfo& info, StyleValue& value);
176     void AddImageSpans(const SpanInfo& info, RefPtr<MutableSpanString> mutableSpan);
177     void AddSpans(const SpanInfo& info, RefPtr<MutableSpanString> span);
178 
179     std::string GetHtmlContent(xmlNodePtr node);
180     RefPtr<MutableSpanString> GenerateSpans(const std::string& allContent, const std::vector<SpanInfo>& spanInfos);
181     std::vector<SpanInfo> spanInfos_;
182     static constexpr double PT_TO_PX = 1.3;
183     static constexpr double ROUND_TO_INT = 0.5;
184 };
185 } // namespace OHOS::Ace
186 
187 #endif // FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_PATTERNS_TEXT_SPAN_HTML_TO_SPAN_H