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
GetLetterSpacing()236 const Dimension& GetLetterSpacing() const
237 {
238 return letterSpacing_;
239 }
240
SetLetterSpacing(const Dimension & letterSpacing)241 void SetLetterSpacing(const Dimension& letterSpacing)
242 {
243 letterSpacing_ = letterSpacing;
244 }
245
GetAdaptTextSize()246 bool GetAdaptTextSize() const
247 {
248 return adaptTextSize_;
249 }
250
251 void SetAdaptTextSize(
252 const Dimension& maxFontSize, const Dimension& minFontSize, const Dimension& fontSizeStep = 1.0_px);
253
GetAdaptHeight()254 bool GetAdaptHeight() const
255 {
256 return adaptHeight_;
257 }
258
SetAdaptHeight(bool adaptHeight)259 void SetAdaptHeight(bool adaptHeight)
260 {
261 adaptHeight_ = adaptHeight;
262 }
263
DisableAdaptTextSize()264 void DisableAdaptTextSize()
265 {
266 adaptTextSize_ = false;
267 }
268
GetMaxLines()269 uint32_t GetMaxLines() const
270 {
271 return maxLines_;
272 }
273
SetMaxLines(uint32_t maxLines)274 void SetMaxLines(uint32_t maxLines)
275 {
276 maxLines_ = maxLines;
277 }
278
SetPreferFontSizes(const std::vector<Dimension> & preferFontSizes)279 void SetPreferFontSizes(const std::vector<Dimension>& preferFontSizes)
280 {
281 preferFontSizes_ = preferFontSizes;
282 adaptTextSize_ = true;
283 }
284
GetPreferFontSizes()285 const std::vector<Dimension>& GetPreferFontSizes() const
286 {
287 return preferFontSizes_;
288 }
289
290 // Must use with SetAdaptMinFontSize and SetAdaptMaxFontSize.
SetAdaptFontSizeStep(const Dimension & adaptTextSizeStep)291 void SetAdaptFontSizeStep(const Dimension& adaptTextSizeStep)
292 {
293 adaptFontSizeStep_ = adaptTextSizeStep;
294 }
295 // Must use with SetAdaptMaxFontSize.
SetAdaptMinFontSize(const Dimension & adaptMinFontSize)296 void SetAdaptMinFontSize(const Dimension& adaptMinFontSize)
297 {
298 adaptMinFontSize_ = adaptMinFontSize;
299 adaptTextSize_ = true;
300 }
301 // Must use with SetAdaptMinFontSize.
SetAdaptMaxFontSize(const Dimension & adaptMaxFontSize)302 void SetAdaptMaxFontSize(const Dimension& adaptMaxFontSize)
303 {
304 adaptMaxFontSize_ = adaptMaxFontSize;
305 adaptTextSize_ = true;
306 }
307
GetAdaptFontSizeStep()308 const Dimension& GetAdaptFontSizeStep() const
309 {
310 return adaptFontSizeStep_;
311 }
312
GetAdaptMinFontSize()313 const Dimension& GetAdaptMinFontSize() const
314 {
315 return adaptMinFontSize_;
316 }
317
GetAdaptMaxFontSize()318 const Dimension& GetAdaptMaxFontSize() const
319 {
320 return adaptMaxFontSize_;
321 }
322
GetPreferTextSizeGroups()323 const std::vector<TextSizeGroup>& GetPreferTextSizeGroups() const
324 {
325 return preferTextSizeGroups_;
326 }
SetPreferTextSizeGroups(const std::vector<TextSizeGroup> & preferTextSizeGroups)327 void SetPreferTextSizeGroups(const std::vector<TextSizeGroup>& preferTextSizeGroups)
328 {
329 preferTextSizeGroups_ = preferTextSizeGroups;
330 adaptTextSize_ = true;
331 }
332
IsAllowScale()333 bool IsAllowScale() const
334 {
335 return allowScale_;
336 }
337
SetAllowScale(bool allowScale)338 void SetAllowScale(bool allowScale)
339 {
340 allowScale_ = allowScale;
341 }
342
GetTextOverflow()343 TextOverflow GetTextOverflow() const
344 {
345 return textOverflow_;
346 }
SetTextOverflow(TextOverflow textOverflow)347 void SetTextOverflow(TextOverflow textOverflow)
348 {
349 textOverflow_ = textOverflow;
350 }
GetTextAlign()351 TextAlign GetTextAlign() const
352 {
353 return textAlign_;
354 }
SetTextAlign(TextAlign textAlign)355 void SetTextAlign(TextAlign textAlign)
356 {
357 textAlign_ = textAlign;
358 }
SetTextVerticalAlign(VerticalAlign verticalAlign)359 void SetTextVerticalAlign(VerticalAlign verticalAlign)
360 {
361 verticalAlign_ = verticalAlign;
362 }
363
GetTextVerticalAlign()364 VerticalAlign GetTextVerticalAlign() const
365 {
366 return verticalAlign_;
367 }
368
GetWordBreak()369 WordBreak GetWordBreak() const
370 {
371 return wordBreak_;
372 }
373
SetWordBreak(WordBreak wordBreak)374 void SetWordBreak(WordBreak wordBreak)
375 {
376 wordBreak_ = wordBreak;
377 }
378
GetTextCase()379 TextCase GetTextCase() const
380 {
381 return textCase_;
382 }
383
SetTextCase(TextCase textCase)384 void SetTextCase(TextCase textCase)
385 {
386 textCase_ = textCase;
387 }
388
GetTextShadows()389 const std::vector<Shadow>& GetTextShadows() const
390 {
391 return textShadows_;
392 }
393
SetTextShadows(std::vector<Shadow> && textShadows)394 void SetTextShadows(std::vector<Shadow>&& textShadows)
395 {
396 textShadows_ = textShadows;
397 }
398
SetShadow(Shadow & shadow)399 void SetShadow(Shadow &shadow)
400 {
401 textShadows_.emplace_back(shadow);
402 }
403
404 private:
405 std::vector<std::string> fontFamilies_;
406 std::unordered_map<std::string, int32_t> fontFeatures_;
407 std::vector<Dimension> preferFontSizes_;
408 std::vector<TextSizeGroup> preferTextSizeGroups_;
409 // use 14px for normal font size.
410 Dimension fontSize_ { 14, DimensionUnit::PX };
411 Dimension adaptMinFontSize_;
412 Dimension adaptMaxFontSize_;
413 Dimension adaptFontSizeStep_;
414 Dimension lineHeight_;
415 bool hasHeightOverride_ = false;
416 FontWeight fontWeight_ { FontWeight::NORMAL };
417 FontStyle fontStyle_ { FontStyle::NORMAL };
418 TextBaseline textBaseline_ { TextBaseline::ALPHABETIC };
419 Dimension baselineOffset_;
420 TextOverflow textOverflow_ { TextOverflow::CLIP };
421 VerticalAlign verticalAlign_ { VerticalAlign::NONE };
422 TextAlign textAlign_ { TextAlign::START };
423 Color textColor_ { Color::BLACK };
424 Color textDecorationColor_ { Color::TRANSPARENT };
425 TextDecoration textDecoration_ { TextDecoration::NONE };
426 std::vector<Shadow> textShadows_;
427 WhiteSpace whiteSpace_{ WhiteSpace::PRE };
428 Dimension wordSpacing_;
429 Dimension textIndent_ { 0.0f, DimensionUnit::PX };
430 Dimension letterSpacing_;
431 uint32_t maxLines_ = UINT32_MAX;
432 bool adaptTextSize_ = false;
433 bool adaptHeight_ = false; // whether adjust text size with height.
434 bool allowScale_ = true;
435 WordBreak wordBreak_ { WordBreak::BREAK_WORD };
436 TextCase textCase_ { TextCase::NORMAL };
437 };
438
439 namespace StringUtils {
440
StringToFontWeight(const std::string & weight)441 inline FontWeight StringToFontWeight(const std::string& weight)
442 {
443 static const LinearMapNode<FontWeight> fontWeightTable[] = {
444 { "100", FontWeight::W100 },
445 { "200", FontWeight::W200 },
446 { "300", FontWeight::W300 },
447 { "400", FontWeight::W400 },
448 { "500", FontWeight::W500 },
449 { "600", FontWeight::W600 },
450 { "700", FontWeight::W700 },
451 { "800", FontWeight::W800 },
452 { "900", FontWeight::W900 },
453 { "bold", FontWeight::BOLD },
454 { "bolder", FontWeight::BOLDER },
455 { "lighter", FontWeight::LIGHTER },
456 { "medium", FontWeight::MEDIUM },
457 { "regular", FontWeight::REGULAR },
458 };
459 auto weightIter = BinarySearchFindIndex(fontWeightTable, ArraySize(fontWeightTable), weight.c_str());
460 return weightIter != -1 ? fontWeightTable[weightIter].value : FontWeight::NORMAL;
461 }
462
StringToWordBreak(const std::string & wordBreak)463 inline WordBreak StringToWordBreak(const std::string& wordBreak)
464 {
465 static const LinearMapNode<WordBreak> wordBreakTable[] = {
466 { "break-all", WordBreak::BREAK_ALL },
467 { "break-word", WordBreak::BREAK_WORD },
468 { "normal", WordBreak::NORMAL },
469 };
470 auto wordBreakIter = BinarySearchFindIndex(wordBreakTable, ArraySize(wordBreakTable), wordBreak.c_str());
471 return wordBreakIter != -1 ? wordBreakTable[wordBreakIter].value : WordBreak::BREAK_WORD;
472 }
473
474 } // namespace StringUtils
475 } // namespace OHOS::Ace
476
477 #endif // FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_BASE_PROPERTIES_TEXT_STYLE_H
478