• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 #include "core/components/common/layout/constants.h"
19 #include "core/components/common/properties/text_style.h"
20 
21 namespace OHOS::Ace {
22 namespace {
23 constexpr uint8_t UINT32_LEFT_SHIFT_24 = 24;
24 constexpr uint8_t UINT32_LEFT_SHIFT_16 = 16;
25 constexpr uint8_t UINT32_LEFT_SHIFT_8 = 8;
26 } // namespace
ToRSColor(const Color & color)27 RSColor ToRSColor(const Color& color)
28 {
29     return RSColor(color.GetRed(), color.GetGreen(), color.GetBlue(), color.GetAlpha());
30 }
31 
ToRSColor(const LinearColor & color)32 RSColor ToRSColor(const LinearColor& color)
33 {
34     return RSColor(
35         (static_cast<uint32_t>(std::clamp<int16_t>(color.GetAlpha(), 0, UINT8_MAX)) << UINT32_LEFT_SHIFT_24) |
36         (static_cast<uint32_t>(std::clamp<int16_t>(color.GetRed(), 0, UINT8_MAX)) << UINT32_LEFT_SHIFT_16) |
37         (static_cast<uint32_t>(std::clamp<int16_t>(color.GetGreen(), 0, UINT8_MAX)) << UINT32_LEFT_SHIFT_8) |
38         (static_cast<uint32_t>(std::clamp<int16_t>(color.GetBlue(), 0, UINT8_MAX))));
39 }
40 
ToRSRect(const NG::RectF & rect)41 RSRect ToRSRect(const NG::RectF& rect)
42 {
43     return RSRect(rect.Left(), rect.Top(), rect.Right(), rect.Bottom());
44 }
45 
ToRSPoint(const NG::PointF & point)46 RSPoint ToRSPoint(const NG::PointF& point)
47 {
48     return RSPoint(point.GetX(), point.GetY());
49 }
50 
ToRSCapStyle(const LineCap & lineCap)51 RSPen::CapStyle ToRSCapStyle(const LineCap& lineCap)
52 {
53     RSPen::CapStyle capStyle;
54     switch (lineCap) {
55         case LineCap::SQUARE:
56             capStyle = RSPen::CapStyle::SQUARE_CAP;
57             break;
58         case LineCap::ROUND:
59             capStyle = RSPen::CapStyle::ROUND_CAP;
60             break;
61         default:
62             capStyle = RSPen::CapStyle::FLAT_CAP;
63             break;
64     }
65     return capStyle;
66 }
67 
ToRSTextDirection(const TextDirection & txtDir)68 RSTextDirection ToRSTextDirection(const TextDirection& txtDir)
69 {
70     RSTextDirection rsTxtDir = RSTextDirection::LTR;
71     if (txtDir == TextDirection::LTR) {
72         rsTxtDir = RSTextDirection::LTR;
73     } else if (txtDir == TextDirection::RTL) {
74         rsTxtDir = RSTextDirection::RTL;
75     }
76     return rsTxtDir;
77 }
78 
ToRSTextAlign(const TextAlign & align)79 RSTextAlign ToRSTextAlign(const TextAlign& align)
80 {
81     // should keep enum same with rosen.
82     return static_cast<RSTextAlign>(align);
83 }
84 
ToRSFontWeight(FontWeight fontWeight)85 RSFontWeight ToRSFontWeight(FontWeight fontWeight)
86 {
87     RSFontWeight rsFontWeight = RSFontWeight::W400;
88     switch (fontWeight) {
89         case FontWeight::W100:
90         case FontWeight::LIGHTER:
91             rsFontWeight = RSFontWeight::W100;
92             break;
93         case FontWeight::W200:
94             rsFontWeight = RSFontWeight::W200;
95             break;
96         case FontWeight::W300:
97             rsFontWeight = RSFontWeight::W300;
98             break;
99         case FontWeight::W400:
100         case FontWeight::NORMAL:
101         case FontWeight::REGULAR:
102             rsFontWeight = RSFontWeight::W400;
103             break;
104         case FontWeight::W500:
105         case FontWeight::MEDIUM:
106             rsFontWeight = RSFontWeight::W500;
107             break;
108         case FontWeight::W600:
109             rsFontWeight = RSFontWeight::W600;
110             break;
111         case FontWeight::W700:
112         case FontWeight::BOLD:
113             rsFontWeight = RSFontWeight::W700;
114             break;
115         case FontWeight::W800:
116             rsFontWeight = RSFontWeight::W800;
117             break;
118         case FontWeight::W900:
119         case FontWeight::BOLDER:
120             rsFontWeight = RSFontWeight::W900;
121             break;
122         default:
123             rsFontWeight = RSFontWeight::W400;
124             break;
125     }
126     return rsFontWeight;
127 }
128 
ToRSWordBreakType(const WordBreak & wordBreak)129 RSWordBreakType ToRSWordBreakType(const WordBreak& wordBreak)
130 {
131     // should keep enum same with rosen.
132     return static_cast<RSWordBreakType>(wordBreak);
133 }
134 
ToRSTextDecoration(TextDecoration textDecoration)135 RSTextDecoration ToRSTextDecoration(TextDecoration textDecoration)
136 {
137     RSTextDecoration rsTextDecoration = RSTextDecoration::NONE;
138     switch (textDecoration) {
139         case TextDecoration::OVERLINE:
140             rsTextDecoration = RSTextDecoration::OVERLINE;
141             break;
142         case TextDecoration::LINE_THROUGH:
143             rsTextDecoration = RSTextDecoration::LINETHROUGH;
144             break;
145         case TextDecoration::UNDERLINE:
146             rsTextDecoration = RSTextDecoration::UNDERLINE;
147             break;
148         default:
149             rsTextDecoration = RSTextDecoration::NONE;
150             break;
151     }
152     return rsTextDecoration;
153 }
154 
ToRSTextStyle(const RefPtr<PipelineBase> & context,const TextStyle & textStyle)155 RSTextStyle ToRSTextStyle(const RefPtr<PipelineBase>& context, const TextStyle& textStyle)
156 {
157     RSTextStyle rsTextStyle;
158     rsTextStyle.color_ = ToRSColor(textStyle.GetTextColor());
159     rsTextStyle.decoration_ = ToRSTextDecoration(textStyle.GetTextDecoration());
160     rsTextStyle.decorationColor_ = ToRSColor(textStyle.GetTextDecorationColor());
161     // TODO: convert fontFamily and other styles.
162 
163     // TODO: convert missing textBaseline
164     rsTextStyle.fontWeight_ = ToRSFontWeight(textStyle.GetFontWeight());
165     rsTextStyle.fontStyle_ = static_cast<RSFontStyle>(textStyle.GetFontStyle());
166     rsTextStyle.textBaseline_ = static_cast<RSTextBaseline>(textStyle.GetTextBaseline());
167     rsTextStyle.fontFamilies_ = textStyle.GetFontFamilies();
168     if (textStyle.GetTextOverflow() == TextOverflow::ELLIPSIS) {
169         rsTextStyle.ellipsis_ = StringUtils::Str8ToStr16(StringUtils::ELLIPSIS);
170     }
171     if (context) {
172         rsTextStyle.fontSize_ = context->NormalizeToPx(textStyle.GetFontSize());
173         if (textStyle.IsAllowScale() || textStyle.GetFontSize().Unit() == DimensionUnit::FP) {
174             rsTextStyle.fontSize_ = context->NormalizeToPx(textStyle.GetFontSize() * context->GetFontScale());
175         }
176     } else {
177         rsTextStyle.fontSize_ = textStyle.GetFontSize().Value();
178     }
179     if (context) {
180         rsTextStyle.letterSpacing_ = context->NormalizeToPx(textStyle.GetLetterSpacing());
181     }
182     if (textStyle.GetWordSpacing().Unit() == DimensionUnit::PERCENT) {
183         rsTextStyle.wordSpacing_ = textStyle.GetWordSpacing().Value() * rsTextStyle.fontSize_;
184     } else {
185         if (context) {
186             rsTextStyle.wordSpacing_ = context->NormalizeToPx(textStyle.GetWordSpacing());
187         } else {
188             rsTextStyle.wordSpacing_ = textStyle.GetWordSpacing().Value();
189         }
190     }
191 
192     if (textStyle.GetLineHeight().Unit() == DimensionUnit::PERCENT) {
193         rsTextStyle.hasHeightOverride_ = true;
194         rsTextStyle.height_ = textStyle.GetLineHeight().Value();
195     } else {
196         double fontSize = rsTextStyle.fontSize_;
197         double lineHeight = textStyle.GetLineHeight().Value();
198         if (context) {
199             lineHeight = context->NormalizeToPx(textStyle.GetLineHeight());
200         }
201         rsTextStyle.hasHeightOverride_ = textStyle.HasHeightOverride();
202         if (!NearEqual(lineHeight, fontSize) && (lineHeight > 0.0) && (!NearZero(fontSize))) {
203             rsTextStyle.height_ = lineHeight / fontSize;
204         } else {
205             LOGD("use default text style height value.");
206             rsTextStyle.height_ = 1;
207             static const int32_t BEGIN_VERSION = 6;
208             auto isBeginVersion = context && context->GetMinPlatformVersion() >= BEGIN_VERSION;
209             if (NearZero(lineHeight) || (!isBeginVersion && NearEqual(lineHeight, fontSize))) {
210                 rsTextStyle.hasHeightOverride_ = false;
211             }
212         }
213     }
214     return rsTextStyle;
215 }
216 } // namespace OHOS::Ace
217