1 /*
2 * Copyright (c) 2021 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 #ifndef FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_BASE_PROPERTIES_TEXT_STYLE_H
17 #define FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_BASE_PROPERTIES_TEXT_STYLE_H
18
19 #include <string>
20 #include <unordered_map>
21 #include <vector>
22
23 #include "base/geometry/dimension.h"
24 #include "base/utils/linear_map.h"
25 #include "core/components/common/layout/constants.h"
26 #include "core/components/common/properties/color.h"
27 #include "core/components/common/properties/shadow.h"
28 #include "core/pipeline/base/render_component.h"
29
30 namespace OHOS::Ace {
31
32 // The normal weight is W400, the larger the number after W, the thicker the font will be.
33 // BOLD is equal to W700 and NORMAL is equal to W400, lighter is W100, BOLDER is W900.
34 enum class FontWeight {
35 W100 = 0,
36 W200,
37 W300,
38 W400,
39 W500,
40 W600,
41 W700,
42 W800,
43 W900,
44 BOLD,
45 NORMAL,
46 BOLDER,
47 LIGHTER,
48 MEDIUM,
49 REGULAR,
50 };
51
52 enum class FontStyle {
53 NORMAL,
54 ITALIC,
55 };
56
57 enum class TextBaseline {
58 ALPHABETIC,
59 IDEOGRAPHIC,
60 TOP,
61 BOTTOM,
62 MIDDLE,
63 HANGING,
64 };
65
66 enum class TextCase {
67 NORMAL = 0,
68 LOWERCASE,
69 UPPERCASE,
70 };
71
72 enum class WordBreak { NORMAL = 0, BREAK_ALL, BREAK_WORD };
73
74 struct TextSizeGroup {
75 Dimension fontSize = 14.0_px;
76 uint32_t maxLines = INT32_MAX;
77 TextOverflow textOverflow = TextOverflow::CLIP;
78 };
79
80 class ACE_EXPORT TextStyle final {
81 public:
82 TextStyle() = default;
83 TextStyle(const std::vector<std::string>& fontFamilies, double fontSize, FontWeight fontWeight, FontStyle fontStyle,
84 const Color& textColor);
85 ~TextStyle() = default;
86
87 bool operator==(const TextStyle& rhs) const;
88 bool operator!=(const TextStyle& rhs) const;
89
GetTextBaseline()90 TextBaseline GetTextBaseline() const
91 {
92 return textBaseline_;
93 }
94
GetBaselineOffset()95 const Dimension& GetBaselineOffset() const
96 {
97 return baselineOffset_;
98 }
99
SetBaselineOffset(const Dimension & baselineOffset)100 void SetBaselineOffset(const Dimension& baselineOffset)
101 {
102 baselineOffset_ = baselineOffset;
103 }
104
SetTextBaseline(TextBaseline baseline)105 void SetTextBaseline(TextBaseline baseline)
106 {
107 textBaseline_ = baseline;
108 }
109
SetTextDecoration(TextDecoration textDecoration)110 void SetTextDecoration(TextDecoration textDecoration)
111 {
112 textDecoration_ = textDecoration;
113 }
114
GetFontStyle()115 FontStyle GetFontStyle() const
116 {
117 return fontStyle_;
118 }
119
SetFontStyle(FontStyle fontStyle)120 void SetFontStyle(FontStyle fontStyle)
121 {
122 fontStyle_ = fontStyle;
123 }
124
GetFontSize()125 const Dimension& GetFontSize() const
126 {
127 return fontSize_;
128 }
129
GetWhiteSpace()130 WhiteSpace GetWhiteSpace() const
131 {
132 return whiteSpace_;
133 }
134
SetWhiteSpace(WhiteSpace whiteSpace)135 void SetWhiteSpace(WhiteSpace whiteSpace)
136 {
137 whiteSpace_ = whiteSpace;
138 }
139
SetFontSize(const Dimension & fontSize)140 void SetFontSize(const Dimension& fontSize)
141 {
142 fontSize_ = fontSize;
143 }
144
GetFontWeight()145 FontWeight GetFontWeight() const
146 {
147 return fontWeight_;
148 }
149
SetFontWeight(FontWeight fontWeight)150 void SetFontWeight(FontWeight fontWeight)
151 {
152 fontWeight_ = fontWeight;
153 }
154
GetTextColor()155 const Color& GetTextColor() const
156 {
157 return textColor_;
158 }
159
SetTextColor(const Color & textColor)160 void SetTextColor(const Color& textColor)
161 {
162 textColor_ = textColor;
163 }
164
GetTextDecoration()165 TextDecoration GetTextDecoration() const
166 {
167 return textDecoration_;
168 }
169
GetWordSpacing()170 const Dimension& GetWordSpacing() const
171 {
172 return wordSpacing_;
173 }
174
SetWordSpacing(const Dimension & wordSpacing)175 void SetWordSpacing(const Dimension& wordSpacing)
176 {
177 wordSpacing_ = wordSpacing;
178 }
179
GetTextDecorationColor()180 const Color& GetTextDecorationColor() const
181 {
182 return textDecorationColor_;
183 }
184
SetTextDecorationColor(const Color & textDecorationColor)185 void SetTextDecorationColor(const Color& textDecorationColor)
186 {
187 textDecorationColor_ = textDecorationColor;
188 }
189
GetFontFamilies()190 const std::vector<std::string>& GetFontFamilies() const
191 {
192 return fontFamilies_;
193 }
194
SetFontFamilies(const std::vector<std::string> & fontFamilies)195 void SetFontFamilies(const std::vector<std::string>& fontFamilies)
196 {
197 fontFamilies_ = fontFamilies;
198 }
199
GetTextIndent()200 Dimension GetTextIndent() const
201 {
202 return textIndent_;
203 }
204
SetTextIndent(const Dimension & textIndent)205 void SetTextIndent(const Dimension& textIndent)
206 {
207 textIndent_ = textIndent;
208 }
209
GetFontFeatures()210 const std::unordered_map<std::string, int32_t>& GetFontFeatures() const
211 {
212 return fontFeatures_;
213 }
214
SetFontFeatures(const std::unordered_map<std::string,int32_t> & fontFeatures)215 void SetFontFeatures(const std::unordered_map<std::string, int32_t>& fontFeatures)
216 {
217 fontFeatures_ = fontFeatures;
218 }
219
GetLineHeight()220 const Dimension& GetLineHeight() const
221 {
222 return lineHeight_;
223 }
224
225 void SetLineHeight(const Dimension& lineHeight, bool hasHeightOverride = true)
226 {
227 lineHeight_ = lineHeight;
228 hasHeightOverride_ = hasHeightOverride;
229 }
230
HasHeightOverride()231 bool HasHeightOverride() const
232 {
233 return hasHeightOverride_;
234 }
235
GetShadow()236 const Shadow& GetShadow() const
237 {
238 return shadow_;
239 }
240
SetShadow(const Shadow & shadow)241 void SetShadow(const Shadow& shadow)
242 {
243 shadow_ = shadow;
244 }
245
GetLetterSpacing()246 const Dimension& GetLetterSpacing() const
247 {
248 return letterSpacing_;
249 }
250
SetLetterSpacing(const Dimension & letterSpacing)251 void SetLetterSpacing(const Dimension& letterSpacing)
252 {
253 letterSpacing_ = letterSpacing;
254 }
255
GetAdaptTextSize()256 bool GetAdaptTextSize() const
257 {
258 return adaptTextSize_;
259 }
260
261 void SetAdaptTextSize(
262 const Dimension& maxFontSize, const Dimension& minFontSize, const Dimension& fontSizeStep = 1.0_px);
263
GetAdaptHeight()264 bool GetAdaptHeight() const
265 {
266 return adaptHeight_;
267 }
268
SetAdaptHeight(bool adaptHeight)269 void SetAdaptHeight(bool adaptHeight)
270 {
271 adaptHeight_ = adaptHeight;
272 }
273
DisableAdaptTextSize()274 void DisableAdaptTextSize()
275 {
276 adaptTextSize_ = false;
277 }
278
GetMaxLines()279 uint32_t GetMaxLines() const
280 {
281 return maxLines_;
282 }
283
SetMaxLines(uint32_t maxLines)284 void SetMaxLines(uint32_t maxLines)
285 {
286 maxLines_ = maxLines;
287 }
288
SetPreferFontSizes(const std::vector<Dimension> & preferFontSizes)289 void SetPreferFontSizes(const std::vector<Dimension>& preferFontSizes)
290 {
291 preferFontSizes_ = preferFontSizes;
292 adaptTextSize_ = true;
293 }
294
GetPreferFontSizes()295 const std::vector<Dimension>& GetPreferFontSizes() const
296 {
297 return preferFontSizes_;
298 }
299
300 // Must use with SetAdaptMinFontSize and SetAdaptMaxFontSize.
SetAdaptFontSizeStep(const Dimension & adaptTextSizeStep)301 void SetAdaptFontSizeStep(const Dimension& adaptTextSizeStep)
302 {
303 adaptFontSizeStep_ = adaptTextSizeStep;
304 }
305 // Must use with SetAdaptMaxFontSize.
SetAdaptMinFontSize(const Dimension & adaptMinFontSize)306 void SetAdaptMinFontSize(const Dimension& adaptMinFontSize)
307 {
308 adaptMinFontSize_ = adaptMinFontSize;
309 adaptTextSize_ = true;
310 }
311 // Must use with SetAdaptMinFontSize.
SetAdaptMaxFontSize(const Dimension & adaptMaxFontSize)312 void SetAdaptMaxFontSize(const Dimension& adaptMaxFontSize)
313 {
314 adaptMaxFontSize_ = adaptMaxFontSize;
315 adaptTextSize_ = true;
316 }
317
GetAdaptFontSizeStep()318 const Dimension& GetAdaptFontSizeStep() const
319 {
320 return adaptFontSizeStep_;
321 }
322
GetAdaptMinFontSize()323 const Dimension& GetAdaptMinFontSize() const
324 {
325 return adaptMinFontSize_;
326 }
327
GetAdaptMaxFontSize()328 const Dimension& GetAdaptMaxFontSize() const
329 {
330 return adaptMaxFontSize_;
331 }
332
GetPreferTextSizeGroups()333 const std::vector<TextSizeGroup>& GetPreferTextSizeGroups() const
334 {
335 return preferTextSizeGroups_;
336 }
SetPreferTextSizeGroups(const std::vector<TextSizeGroup> & preferTextSizeGroups)337 void SetPreferTextSizeGroups(const std::vector<TextSizeGroup>& preferTextSizeGroups)
338 {
339 preferTextSizeGroups_ = preferTextSizeGroups;
340 adaptTextSize_ = true;
341 }
342
IsAllowScale()343 bool IsAllowScale() const
344 {
345 return allowScale_;
346 }
347
SetAllowScale(bool allowScale)348 void SetAllowScale(bool allowScale)
349 {
350 allowScale_ = allowScale;
351 }
352
GetTextOverflow()353 TextOverflow GetTextOverflow() const
354 {
355 return textOverflow_;
356 }
SetTextOverflow(TextOverflow textOverflow)357 void SetTextOverflow(TextOverflow textOverflow)
358 {
359 textOverflow_ = textOverflow;
360 }
GetTextAlign()361 TextAlign GetTextAlign() const
362 {
363 return textAlign_;
364 }
SetTextAlign(TextAlign textAlign)365 void SetTextAlign(TextAlign textAlign)
366 {
367 textAlign_ = textAlign;
368 }
SetTextVerticalAlign(VerticalAlign verticalAlign)369 void SetTextVerticalAlign(VerticalAlign verticalAlign)
370 {
371 verticalAlign_ = verticalAlign;
372 }
373
GetTextVerticalAlign()374 VerticalAlign GetTextVerticalAlign() const
375 {
376 return verticalAlign_;
377 }
378
GetWordBreak()379 WordBreak GetWordBreak() const
380 {
381 return wordBreak_;
382 }
383
SetWordBreak(WordBreak wordBreak)384 void SetWordBreak(WordBreak wordBreak)
385 {
386 wordBreak_ = wordBreak;
387 }
388
GetTextCase()389 TextCase GetTextCase() const
390 {
391 return textCase_;
392 }
393
SetTextCase(TextCase textCase)394 void SetTextCase(TextCase textCase)
395 {
396 textCase_ = textCase;
397 }
398
399 private:
400 std::vector<std::string> fontFamilies_;
401 std::unordered_map<std::string, int32_t> fontFeatures_;
402 std::vector<Dimension> preferFontSizes_;
403 std::vector<TextSizeGroup> preferTextSizeGroups_;
404 // use 14px for normal font size.
405 Dimension fontSize_ { 14, DimensionUnit::PX };
406 Dimension adaptMinFontSize_;
407 Dimension adaptMaxFontSize_;
408 Dimension adaptFontSizeStep_;
409 Dimension lineHeight_;
410 bool hasHeightOverride_ = false;
411 FontWeight fontWeight_ { FontWeight::NORMAL };
412 FontStyle fontStyle_ { FontStyle::NORMAL };
413 TextBaseline textBaseline_ { TextBaseline::ALPHABETIC };
414 Dimension baselineOffset_;
415 TextOverflow textOverflow_ { TextOverflow::CLIP };
416 VerticalAlign verticalAlign_ { VerticalAlign::NONE };
417 TextAlign textAlign_ { TextAlign::START };
418 Color textColor_ { Color::BLACK };
419 Color textDecorationColor_ { Color::TRANSPARENT };
420 TextDecoration textDecoration_ { TextDecoration::NONE };
421 Shadow shadow_;
422 WhiteSpace whiteSpace_{ WhiteSpace::PRE };
423 Dimension wordSpacing_;
424 Dimension textIndent_ { 0.0f, DimensionUnit::PX };
425 Dimension letterSpacing_;
426 uint32_t maxLines_ = UINT32_MAX;
427 bool adaptTextSize_ = false;
428 bool adaptHeight_ = false; // whether adjust text size with height.
429 bool allowScale_ = true;
430 WordBreak wordBreak_ { WordBreak::BREAK_WORD };
431 TextCase textCase_ { TextCase::NORMAL };
432 };
433
434 namespace StringUtils {
435
StringToFontWeight(const std::string & weight)436 inline FontWeight StringToFontWeight(const std::string& weight)
437 {
438 static const LinearMapNode<FontWeight> fontWeightTable[] = {
439 { "100", FontWeight::W100 },
440 { "200", FontWeight::W200 },
441 { "300", FontWeight::W300 },
442 { "400", FontWeight::W400 },
443 { "500", FontWeight::W500 },
444 { "600", FontWeight::W600 },
445 { "700", FontWeight::W700 },
446 { "800", FontWeight::W800 },
447 { "900", FontWeight::W900 },
448 { "bold", FontWeight::BOLD },
449 { "bolder", FontWeight::BOLDER },
450 { "lighter", FontWeight::LIGHTER },
451 { "medium", FontWeight::MEDIUM },
452 { "regular", FontWeight::REGULAR },
453 };
454 auto weightIter = BinarySearchFindIndex(fontWeightTable, ArraySize(fontWeightTable), weight.c_str());
455 return weightIter != -1 ? fontWeightTable[weightIter].value : FontWeight::NORMAL;
456 }
457
StringToWordBreak(const std::string & wordBreak)458 inline WordBreak StringToWordBreak(const std::string& wordBreak)
459 {
460 static const LinearMapNode<WordBreak> wordBreakTable[] = {
461 { "break-all", WordBreak::BREAK_ALL },
462 { "break-word", WordBreak::BREAK_WORD },
463 { "normal", WordBreak::NORMAL },
464 };
465 auto wordBreakIter = BinarySearchFindIndex(wordBreakTable, ArraySize(wordBreakTable), wordBreak.c_str());
466 return wordBreakIter != -1 ? wordBreakTable[wordBreakIter].value : WordBreak::BREAK_WORD;
467 }
468
469 } // namespace StringUtils
470 } // namespace OHOS::Ace
471
472 #endif // FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_BASE_PROPERTIES_TEXT_STYLE_H
473