1 /*
2 * Copyright (c) 2022-2023 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 "core/components_ng/render/drawing_prop_convertor.h"
17
18 namespace OHOS::Ace {
19 namespace {
20 constexpr uint8_t UINT32_LEFT_SHIFT_24 = 24;
21 constexpr uint8_t UINT32_LEFT_SHIFT_16 = 16;
22 constexpr uint8_t UINT32_LEFT_SHIFT_8 = 8;
23 } // namespace
ToRSColor(const Color & color)24 RSColor ToRSColor(const Color& color)
25 {
26 return RSColor(color.GetRed(), color.GetGreen(), color.GetBlue(), color.GetAlpha());
27 }
28
ToRSColor(const LinearColor & color)29 RSColor ToRSColor(const LinearColor& color)
30 {
31 return RSColor(
32 (static_cast<uint32_t>(std::clamp<int16_t>(color.GetAlpha(), 0, UINT8_MAX)) << UINT32_LEFT_SHIFT_24) |
33 (static_cast<uint32_t>(std::clamp<int16_t>(color.GetRed(), 0, UINT8_MAX)) << UINT32_LEFT_SHIFT_16) |
34 (static_cast<uint32_t>(std::clamp<int16_t>(color.GetGreen(), 0, UINT8_MAX)) << UINT32_LEFT_SHIFT_8) |
35 (static_cast<uint32_t>(std::clamp<int16_t>(color.GetBlue(), 0, UINT8_MAX))));
36 }
37
ToRSRect(const NG::RectF & rect)38 RSRect ToRSRect(const NG::RectF& rect)
39 {
40 return RSRect(rect.Left(), rect.Top(), rect.Right(), rect.Bottom());
41 }
42
ToRSPoint(const NG::PointF & point)43 RSPoint ToRSPoint(const NG::PointF& point)
44 {
45 return RSPoint(point.GetX(), point.GetY());
46 }
47
ToRSCapStyle(const LineCap & lineCap)48 RSPen::CapStyle ToRSCapStyle(const LineCap& lineCap)
49 {
50 RSPen::CapStyle capStyle;
51 switch (lineCap) {
52 case LineCap::SQUARE:
53 capStyle = RSPen::CapStyle::SQUARE_CAP;
54 break;
55 case LineCap::ROUND:
56 capStyle = RSPen::CapStyle::ROUND_CAP;
57 break;
58 default:
59 capStyle = RSPen::CapStyle::FLAT_CAP;
60 break;
61 }
62 return capStyle;
63 }
64
ToRSTextDirection(const TextDirection & txtDir)65 RSTextDirection ToRSTextDirection(const TextDirection& txtDir)
66 {
67 RSTextDirection rsTxtDir = RSTextDirection::LTR;
68 if (txtDir == TextDirection::LTR) {
69 rsTxtDir = RSTextDirection::LTR;
70 } else if (txtDir == TextDirection::RTL) {
71 rsTxtDir = RSTextDirection::RTL;
72 }
73 return rsTxtDir;
74 }
75
ToRSTextAlign(const TextAlign & align)76 RSTextAlign ToRSTextAlign(const TextAlign& align)
77 {
78 // should keep enum same with rosen.
79 RSTextAlign textAlign = RSTextAlign::START;
80 switch (align) {
81 case TextAlign::LEFT:
82 textAlign = RSTextAlign::LEFT;
83 break;
84 case TextAlign::RIGHT:
85 textAlign = RSTextAlign::RIGHT;
86 break;
87 case TextAlign::CENTER:
88 textAlign = RSTextAlign::CENTER;
89 break;
90 case TextAlign::JUSTIFY:
91 textAlign = RSTextAlign::JUSTIFY;
92 break;
93 case TextAlign::START:
94 textAlign = RSTextAlign::START;
95 break;
96 case TextAlign::END:
97 textAlign = RSTextAlign::END;
98 break;
99 default:
100 textAlign = RSTextAlign::START;
101 break;
102 }
103 return textAlign;
104 }
105
ToRSFontWeight(FontWeight fontWeight)106 RSFontWeight ToRSFontWeight(FontWeight fontWeight)
107 {
108 RSFontWeight rsFontWeight = RSFontWeight::W400;
109 switch (fontWeight) {
110 case FontWeight::W100:
111 case FontWeight::LIGHTER:
112 rsFontWeight = RSFontWeight::W100;
113 break;
114 case FontWeight::W200:
115 rsFontWeight = RSFontWeight::W200;
116 break;
117 case FontWeight::W300:
118 rsFontWeight = RSFontWeight::W300;
119 break;
120 case FontWeight::W400:
121 case FontWeight::NORMAL:
122 case FontWeight::REGULAR:
123 rsFontWeight = RSFontWeight::W400;
124 break;
125 case FontWeight::W500:
126 case FontWeight::MEDIUM:
127 rsFontWeight = RSFontWeight::W500;
128 break;
129 case FontWeight::W600:
130 rsFontWeight = RSFontWeight::W600;
131 break;
132 case FontWeight::W700:
133 case FontWeight::BOLD:
134 rsFontWeight = RSFontWeight::W700;
135 break;
136 case FontWeight::W800:
137 rsFontWeight = RSFontWeight::W800;
138 break;
139 case FontWeight::W900:
140 case FontWeight::BOLDER:
141 rsFontWeight = RSFontWeight::W900;
142 break;
143 default:
144 rsFontWeight = RSFontWeight::W400;
145 break;
146 }
147 return rsFontWeight;
148 }
149
ToRSWordBreakType(const WordBreak & wordBreak)150 RSWordBreakType ToRSWordBreakType(const WordBreak& wordBreak)
151 {
152 // should keep enum same with rosen.
153 return static_cast<RSWordBreakType>(wordBreak);
154 }
155
ToRSEllipsisMode(EllipsisMode value)156 RSEllipsisMode ToRSEllipsisMode(EllipsisMode value)
157 {
158 // should keep enum same with rosen.
159 return static_cast<RSEllipsisMode>(value);
160 }
161
ToRSTextDecoration(TextDecoration textDecoration)162 RSTextDecoration ToRSTextDecoration(TextDecoration textDecoration)
163 {
164 RSTextDecoration rsTextDecoration = RSTextDecoration::NONE;
165 switch (textDecoration) {
166 case TextDecoration::OVERLINE:
167 rsTextDecoration = RSTextDecoration::OVERLINE;
168 break;
169 case TextDecoration::LINE_THROUGH:
170 #ifndef USE_GRAPHIC_TEXT_GINE
171 rsTextDecoration = RSTextDecoration::LINETHROUGH;
172 #else
173 rsTextDecoration = RSTextDecoration::LINE_THROUGH;
174 #endif
175 break;
176 case TextDecoration::UNDERLINE:
177 rsTextDecoration = RSTextDecoration::UNDERLINE;
178 break;
179 default:
180 rsTextDecoration = RSTextDecoration::NONE;
181 break;
182 }
183 return rsTextDecoration;
184 }
185
ToRSTextDecorationStyle(TextDecorationStyle textDecorationStyle)186 RSTextDecorationStyle ToRSTextDecorationStyle(TextDecorationStyle textDecorationStyle)
187 {
188 RSTextDecorationStyle rsTextDecorationStyle = RSTextDecorationStyle::SOLID;
189 switch (textDecorationStyle) {
190 case TextDecorationStyle::DOUBLE:
191 rsTextDecorationStyle = RSTextDecorationStyle::DOUBLE;
192 break;
193 case TextDecorationStyle::DOTTED:
194 rsTextDecorationStyle = RSTextDecorationStyle::DOTTED;
195 break;
196 case TextDecorationStyle::DASHED:
197 rsTextDecorationStyle = RSTextDecorationStyle::DASHED;
198 break;
199 case TextDecorationStyle::WAVY:
200 rsTextDecorationStyle = RSTextDecorationStyle::WAVY;
201 break;
202 default:
203 rsTextDecorationStyle = RSTextDecorationStyle::SOLID;
204 break;
205 }
206 return rsTextDecorationStyle;
207 }
208
ToRSTextStyle(const RefPtr<PipelineBase> & context,const TextStyle & textStyle)209 RSTextStyle ToRSTextStyle(const RefPtr<PipelineBase>& context, const TextStyle& textStyle)
210 {
211 RSTextStyle rsTextStyle;
212 #ifndef USE_GRAPHIC_TEXT_GINE
213 rsTextStyle.color_ = ToRSColor(textStyle.GetTextColor());
214 rsTextStyle.decoration_ = ToRSTextDecoration(textStyle.GetTextDecoration());
215 rsTextStyle.decorationStyle_ = ToRSTextDecorationStyle(textStyle.GetTextDecorationStyle());
216 rsTextStyle.decorationColor_ = ToRSColor(textStyle.GetTextDecorationColor());
217 #else
218 rsTextStyle.color = ToRSColor(textStyle.GetTextColor());
219 rsTextStyle.decoration = ToRSTextDecoration(textStyle.GetTextDecoration());
220 rsTextStyle.decorationColor = ToRSColor(textStyle.GetTextDecorationColor());
221 #endif
222
223 #ifndef USE_GRAPHIC_TEXT_GINE
224 rsTextStyle.fontWeight_ = ToRSFontWeight(textStyle.GetFontWeight());
225 rsTextStyle.fontStyle_ = static_cast<RSFontStyle>(textStyle.GetFontStyle());
226 rsTextStyle.textBaseline_ = static_cast<RSTextBaseline>(textStyle.GetTextBaseline());
227 rsTextStyle.fontFamilies_ = textStyle.GetFontFamilies();
228 #else
229 rsTextStyle.fontWeight = ToRSFontWeight(textStyle.GetFontWeight());
230 rsTextStyle.fontStyle = static_cast<RSFontStyle>(textStyle.GetFontStyle());
231 rsTextStyle.baseline = static_cast<RSTextBaseline>(textStyle.GetTextBaseline());
232 rsTextStyle.fontFamilies = textStyle.GetFontFamilies();
233 #endif
234 if (textStyle.GetTextOverflow() == TextOverflow::ELLIPSIS) {
235 #ifndef USE_GRAPHIC_TEXT_GINE
236 rsTextStyle.ellipsis_ = StringUtils::Str8ToStr16(StringUtils::ELLIPSIS);
237 #else
238 rsTextStyle.ellipsis = StringUtils::Str8ToStr16(StringUtils::ELLIPSIS);
239 #endif
240 }
241 if (context) {
242 #ifndef USE_GRAPHIC_TEXT_GINE
243 rsTextStyle.fontSize_ = context->NormalizeToPx(textStyle.GetFontSize());
244 #else
245 rsTextStyle.fontSize = context->NormalizeToPx(textStyle.GetFontSize());
246 #endif
247 if (textStyle.IsAllowScale() || textStyle.GetFontSize().Unit() == DimensionUnit::FP) {
248 #ifndef USE_GRAPHIC_TEXT_GINE
249 rsTextStyle.fontSize_ = context->NormalizeToPx(textStyle.GetFontSize() * context->GetFontScale());
250 #else
251 rsTextStyle.fontSize = context->NormalizeToPx(textStyle.GetFontSize() * context->GetFontScale());
252 #endif
253 }
254 } else {
255 #ifndef USE_GRAPHIC_TEXT_GINE
256 rsTextStyle.fontSize_ = textStyle.GetFontSize().Value();
257 #else
258 rsTextStyle.fontSize = textStyle.GetFontSize().Value();
259 #endif
260 }
261 if (context) {
262 #ifndef USE_GRAPHIC_TEXT_GINE
263 rsTextStyle.letterSpacing_ = context->NormalizeToPx(textStyle.GetLetterSpacing());
264 #else
265 rsTextStyle.letterSpacing = context->NormalizeToPx(textStyle.GetLetterSpacing());
266 #endif
267 }
268 if (textStyle.GetWordSpacing().Unit() == DimensionUnit::PERCENT) {
269 #ifndef USE_GRAPHIC_TEXT_GINE
270 rsTextStyle.wordSpacing_ = textStyle.GetWordSpacing().Value() * rsTextStyle.fontSize_;
271 #else
272 rsTextStyle.wordSpacing = textStyle.GetWordSpacing().Value() * rsTextStyle.fontSize;
273 #endif
274 } else {
275 if (context) {
276 #ifndef USE_GRAPHIC_TEXT_GINE
277 rsTextStyle.wordSpacing_ = context->NormalizeToPx(textStyle.GetWordSpacing());
278 #else
279 rsTextStyle.wordSpacing = context->NormalizeToPx(textStyle.GetWordSpacing());
280 #endif
281 } else {
282 #ifndef USE_GRAPHIC_TEXT_GINE
283 rsTextStyle.wordSpacing_ = textStyle.GetWordSpacing().Value();
284 #else
285 rsTextStyle.wordSpacing = textStyle.GetWordSpacing().Value();
286 #endif
287 }
288 }
289
290 if (textStyle.GetLineHeight().Unit() == DimensionUnit::PERCENT) {
291 #ifndef USE_GRAPHIC_TEXT_GINE
292 rsTextStyle.hasHeightOverride_ = true;
293 rsTextStyle.height_ = textStyle.GetLineHeight().Value();
294 #else
295 rsTextStyle.heightOnly = true;
296 rsTextStyle.heightScale = textStyle.GetLineHeight().Value();
297 #endif
298 } else {
299 #ifndef USE_GRAPHIC_TEXT_GINE
300 double fontSize = rsTextStyle.fontSize_;
301 #else
302 double fontSize = rsTextStyle.fontSize;
303 #endif
304 double lineHeight = textStyle.GetLineHeight().Value();
305 if (context) {
306 lineHeight = context->NormalizeToPx(textStyle.GetLineHeight());
307 }
308 #ifndef USE_GRAPHIC_TEXT_GINE
309 rsTextStyle.hasHeightOverride_ = textStyle.HasHeightOverride();
310 #else
311 rsTextStyle.heightOnly = textStyle.HasHeightOverride();
312 #endif
313 if (!NearEqual(lineHeight, fontSize) && (lineHeight > 0.0) && (!NearZero(fontSize))) {
314 #ifndef USE_GRAPHIC_TEXT_GINE
315 rsTextStyle.height_ = lineHeight / fontSize;
316 #else
317 rsTextStyle.heightScale = lineHeight / fontSize;
318 #endif
319 } else {
320 #ifndef USE_GRAPHIC_TEXT_GINE
321 rsTextStyle.height_ = 1;
322 #else
323 rsTextStyle.heightScale = 1;
324 #endif
325 static const int32_t BEGIN_VERSION = 6;
326 auto isBeginVersion = context && context->GetMinPlatformVersion() >= BEGIN_VERSION;
327 if (NearZero(lineHeight) || (!isBeginVersion && NearEqual(lineHeight, fontSize))) {
328 #ifndef USE_GRAPHIC_TEXT_GINE
329 rsTextStyle.hasHeightOverride_ = false;
330 #else
331 rsTextStyle.heightOnly = false;
332 #endif
333 }
334 }
335 }
336 return rsTextStyle;
337 }
338 } // namespace OHOS::Ace
339