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 #include "convert.h"
17 
18 #include "txt/paint_record.h"
19 
20 namespace OHOS {
21 namespace Rosen {
22 namespace AdapterTxt {
23 const std::string WGHT_AXIS = "wght";
24 constexpr float FONT_WEIGHT_MULTIPLE = 100.0;
25 
Convert(const std::shared_ptr<OHOS::Rosen::FontCollection> & fontCollection)26 std::shared_ptr<OHOS::Rosen::AdapterTxt::FontCollection> Convert(
27     const std::shared_ptr<OHOS::Rosen::FontCollection>& fontCollection)
28 {
29     return std::static_pointer_cast<OHOS::Rosen::AdapterTxt::FontCollection>(fontCollection);
30 }
31 
Convert(const SPText::PositionWithAffinity & pos)32 IndexAndAffinity Convert(const SPText::PositionWithAffinity& pos)
33 {
34     return { pos.position, static_cast<Affinity>(pos.affinity) };
35 }
36 
Convert(const SPText::Range<size_t> & range)37 Boundary Convert(const SPText::Range<size_t>& range)
38 {
39     return { range.start, range.end };
40 }
41 
Convert(const SPText::TextBox & box)42 TextRect Convert(const SPText::TextBox& box)
43 {
44     Drawing::RectF rect(box.rect.fLeft, box.rect.fTop, box.rect.fRight, box.rect.fBottom);
45     return { rect, static_cast<TextDirection>(box.direction) };
46 }
47 
Convert(const TextRectHeightStyle & style)48 SPText::RectHeightStyle Convert(const TextRectHeightStyle& style)
49 {
50     return static_cast<SPText::RectHeightStyle>(style);
51 }
52 
Convert(const TextRectWidthStyle & style)53 SPText::RectWidthStyle Convert(const TextRectWidthStyle& style)
54 {
55     return static_cast<SPText::RectWidthStyle>(style);
56 }
57 
Convert(const TypographyStyle & style)58 SPText::ParagraphStyle Convert(const TypographyStyle& style)
59 {
60     return {
61         .fontWeight = static_cast<SPText::FontWeight>(style.fontWeight),
62         .fontWidth = static_cast<SPText::FontWidth>(style.fontWidth),
63         .fontStyle = static_cast<SPText::FontStyle>(style.fontStyle),
64         .wordBreakType = static_cast<SPText::WordBreakType>(style.wordBreakType),
65         .fontFamily = style.fontFamily,
66         .fontSize = style.fontSize,
67         .height = style.heightScale,
68         .heightOverride = style.heightOnly,
69         .strutEnabled = style.useLineStyle,
70         .strutFontWeight = static_cast<SPText::FontWeight>(style.lineStyleFontWeight),
71         .strutFontWidth = static_cast<SPText::FontWidth>(style.lineStyleFontWidth),
72         .strutFontStyle = static_cast<SPText::FontStyle>(style.lineStyleFontStyle),
73         .strutFontFamilies = style.lineStyleFontFamilies,
74         .strutFontSize = style.lineStyleFontSize,
75         .strutHeight = style.lineStyleHeightScale,
76         .strutHeightOverride = style.lineStyleHeightOnly,
77         .strutHalfLeading = style.lineStyleHalfLeading,
78         .strutLeading = style.lineStyleSpacingScale,
79         .forceStrutHeight = style.lineStyleOnly,
80         .textAlign = static_cast<SPText::TextAlign>(style.textAlign),
81         .textDirection = static_cast<SPText::TextDirection>(style.textDirection),
82         .ellipsisModal = static_cast<SPText::EllipsisModal>(style.ellipsisModal),
83         .maxLines = style.maxLines,
84         .ellipsis = style.ellipsis,
85         .locale = style.locale,
86         .textSplitRatio = style.textSplitRatio,
87         .textOverflower = style.Ellipsized(),
88         .spTextStyle = Convert(style.insideTextStyle),
89         .customSpTextStyle = style.customTextStyle,
90         .textHeightBehavior = static_cast<SPText::TextHeightBehavior>(style.textHeightBehavior),
91         .hintingIsOn = style.hintingIsOn,
92         .breakStrategy = static_cast<SPText::BreakStrategy>(style.breakStrategy),
93     };
94 }
95 
Convert(const PlaceholderSpan & run)96 SPText::PlaceholderRun Convert(const PlaceholderSpan& run)
97 {
98     return {
99         run.width,
100         run.height,
101         static_cast<SPText::PlaceholderAlignment>(run.alignment),
102         static_cast<SPText::TextBaseline>(run.baseline),
103         run.baselineOffset,
104     };
105 }
106 
RemoveQuotes(const std::string & str)107 static std::string RemoveQuotes(const std::string& str)
108 {
109     if (str.empty() || str.front() != '\"' || str.back() != '\"') {
110         return str;
111     }
112     const int start = 1; // The starting position of string.
113     const int end = static_cast<int>(str.size()) - 2; // End position of string.
114     return str.substr(start, end); // Remove quotation marks from both ends.
115 }
116 
CopyTextStyleSymbol(const TextStyle & style,SPText::TextStyle & textStyle)117 void CopyTextStyleSymbol(const TextStyle& style, SPText::TextStyle& textStyle)
118 {
119     textStyle.symbol.SetRenderColor(style.symbol.GetRenderColor());
120     textStyle.symbol.SetRenderMode(style.symbol.GetRenderMode());
121     textStyle.symbol.SetSymbolEffect(style.symbol.GetEffectStrategy());
122     textStyle.symbol.SetAnimationMode(style.symbol.GetAnimationMode());
123     textStyle.symbol.SetRepeatCount(style.symbol.GetRepeatCount());
124     textStyle.symbol.SetAnimationStart(style.symbol.GetAnimationStart());
125     textStyle.symbol.SetCommonSubType(style.symbol.GetCommonSubType());
126     for (auto [tag, value] : style.symbol.GetVisualMap()) {
127         textStyle.fontFeatures.SetFeature(RemoveQuotes(tag), value);
128     }
129 }
130 
SplitTextStyleConvert(SPText::TextStyle & textStyle,const TextStyle & style)131 void SplitTextStyleConvert(SPText::TextStyle& textStyle, const TextStyle& style)
132 {
133     if (style.isSymbolGlyph) {
134         CopyTextStyleSymbol(style, textStyle);
135     }
136     if (style.backgroundBrush.has_value() || style.backgroundPen.has_value()) {
137         textStyle.background = SPText::PaintRecord(style.backgroundBrush, style.backgroundPen);
138     }
139     if (style.foregroundBrush.has_value() || style.foregroundPen.has_value()) {
140         textStyle.foreground = SPText::PaintRecord(style.foregroundBrush, style.foregroundPen);
141     }
142 
143     for (const auto& [color, offset, radius] : style.shadows) {
144         auto shadowColor = SkColorSetARGB(color.GetAlpha(), color.GetRed(), color.GetGreen(), color.GetBlue());
145         auto shadowOffset = SkPoint::Make(offset.GetX(), offset.GetY());
146         textStyle.textShadows.emplace_back(shadowColor, shadowOffset, radius);
147     }
148 
149     for (const auto& [tag, value] : style.fontFeatures.GetFontFeatures()) {
150         textStyle.fontFeatures.SetFeature(RemoveQuotes(tag), value);
151     }
152 
153     if (!style.fontVariations.GetAxisValues().empty()) {
154         for (const auto& [axis, value] : style.fontVariations.GetAxisValues()) {
155             textStyle.fontVariations.SetAxisValue(axis, value);
156         }
157     } else {
158         textStyle.fontVariations.SetAxisValue(WGHT_AXIS,
159             (static_cast<float>(style.fontWeight) + 1.0) * FONT_WEIGHT_MULTIPLE);
160     }
161 }
162 
Convert(const TextStyle & style)163 SPText::TextStyle Convert(const TextStyle& style)
164 {
165     SPText::TextStyle textStyle;
166     textStyle.color = style.color.CastToColorQuad();
167     textStyle.decoration = static_cast<SPText::TextDecoration>(style.decoration);
168     auto decorationColor = SkColorSetARGB(style.decorationColor.GetAlpha(), style.decorationColor.GetRed(),
169         style.decorationColor.GetGreen(), style.decorationColor.GetBlue());
170     textStyle.decorationColor = decorationColor;
171     textStyle.decorationStyle = static_cast<SPText::TextDecorationStyle>(style.decorationStyle);
172     textStyle.decorationThicknessMultiplier = style.decorationThicknessScale;
173     textStyle.fontWeight = static_cast<SPText::FontWeight>(style.fontWeight);
174     textStyle.fontWidth = static_cast<SPText::FontWidth>(style.fontWidth);
175     textStyle.fontStyle = static_cast<SPText::FontStyle>(style.fontStyle);
176     textStyle.baseline = static_cast<SPText::TextBaseline>(style.baseline);
177     textStyle.halfLeading = style.halfLeading;
178     textStyle.fontFamilies = style.fontFamilies;
179     textStyle.fontSize = style.fontSize;
180     textStyle.letterSpacing = style.letterSpacing;
181     textStyle.wordSpacing = style.wordSpacing;
182     textStyle.height = style.heightScale;
183     textStyle.heightOverride = style.heightOnly;
184     textStyle.locale = style.locale;
185     textStyle.backgroundRect = { style.backgroundRect.color, style.backgroundRect.leftTopRadius,
186         style.backgroundRect.rightTopRadius, style.backgroundRect.rightBottomRadius,
187         style.backgroundRect.leftBottomRadius };
188     textStyle.styleId = style.styleId;
189     textStyle.isSymbolGlyph = style.isSymbolGlyph;
190     textStyle.baseLineShift = style.baseLineShift;
191     textStyle.isPlaceholder = style.isPlaceholder;
192     SplitTextStyleConvert(textStyle, style);
193 
194     return textStyle;
195 }
196 
CopyTextStyleSymbol(const SPText::TextStyle & style,TextStyle & textStyle)197 void CopyTextStyleSymbol(const SPText::TextStyle& style, TextStyle& textStyle)
198 {
199     textStyle.symbol.SetRenderColor(style.symbol.GetRenderColor());
200     textStyle.symbol.SetRenderMode(style.symbol.GetRenderMode());
201     textStyle.symbol.SetSymbolEffect(style.symbol.GetEffectStrategy());
202     textStyle.symbol.SetAnimationMode(style.symbol.GetAnimationMode());
203     textStyle.symbol.SetRepeatCount(style.symbol.GetRepeatCount());
204     textStyle.symbol.SetAnimationStart(style.symbol.GetAnimationStart());
205     textStyle.symbol.SetCommonSubType(style.symbol.GetCommonSubType());
206 }
207 
SplitTextStyleConvert(TextStyle & textStyle,const SPText::TextStyle & style)208 void SplitTextStyleConvert(TextStyle& textStyle, const SPText::TextStyle& style)
209 {
210     if (style.isSymbolGlyph) {
211         CopyTextStyleSymbol(style, textStyle);
212     }
213 
214     if (style.background.has_value()) {
215         textStyle.backgroundBrush = style.background->brush;
216         textStyle.backgroundPen = style.background->pen;
217     }
218 
219     if (style.foreground.has_value()) {
220         textStyle.foregroundBrush = style.foreground->brush;
221         textStyle.foregroundPen = style.foreground->pen;
222     }
223 
224     for (const auto& [color, offset, radius] : style.textShadows) {
225         Drawing::Color shadowColor;
226         shadowColor.SetColorQuad(color);
227         Drawing::Point shadowOffset(offset.x(), offset.y());
228         textStyle.shadows.emplace_back(shadowColor, shadowOffset, radius);
229     }
230 
231     for (const auto& [tag, value] : style.fontFeatures.GetFontFeatures()) {
232         textStyle.fontFeatures.SetFeature(RemoveQuotes(tag), value);
233     }
234 
235     if (!style.fontVariations.GetAxisValues().empty()) {
236         for (const auto& [axis, value] : style.fontVariations.GetAxisValues()) {
237             textStyle.fontVariations.SetAxisValue(axis, value);
238         }
239     }
240 }
241 
Convert(const SPText::TextStyle & style)242 TextStyle Convert(const SPText::TextStyle& style)
243 {
244     TextStyle textStyle;
245     textStyle.color.SetColorQuad(style.color);
246     textStyle.decoration = static_cast<TextDecoration>(style.decoration);
247     textStyle.decorationColor.SetColorQuad(style.decorationColor);
248     textStyle.decorationStyle = static_cast<TextDecorationStyle>(style.decorationStyle);
249     textStyle.decorationThicknessScale = style.decorationThicknessMultiplier;
250     textStyle.fontWeight = static_cast<FontWeight>(style.fontWeight);
251     textStyle.fontWidth = static_cast<FontWidth>(style.fontWidth);
252     textStyle.fontStyle = static_cast<FontStyle>(style.fontStyle);
253     textStyle.baseline = static_cast<TextBaseline>(style.baseline);
254 
255     textStyle.halfLeading = style.halfLeading;
256     textStyle.fontFamilies = style.fontFamilies;
257     textStyle.fontSize = style.fontSize;
258     textStyle.letterSpacing = style.letterSpacing;
259     textStyle.wordSpacing = style.wordSpacing;
260     textStyle.heightScale = style.height;
261     textStyle.heightOnly = style.heightOverride;
262     textStyle.locale = style.locale;
263     textStyle.backgroundRect = { style.backgroundRect.color, style.backgroundRect.leftTopRadius,
264         style.backgroundRect.rightTopRadius, style.backgroundRect.rightBottomRadius,
265         style.backgroundRect.leftBottomRadius };
266     textStyle.styleId = style.styleId;
267     textStyle.isSymbolGlyph = style.isSymbolGlyph;
268     textStyle.baseLineShift = style.baseLineShift;
269     textStyle.isPlaceholder = style.isPlaceholder;
270     SplitTextStyleConvert(textStyle, style);
271 
272     return textStyle;
273 }
274 } // namespace AdapterTxt
275 } // namespace Rosen
276 } // namespace OHOS
277