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