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