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