1 /*
2  * Copyright (c) 2024 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/pattern/text/span_model_ng.h"
17 #include "core/components_ng/render/drawing.h"
18 
19 namespace OHOS::Ace::NG {
20 
21 #ifdef USE_GRAPHIC_TEXT_GINE
22 
23 #define UPDATE_SPAN_FONT_STYLE_ITEM(item, name, value) (item)->fontStyle->Update##name(value)
24 
25 #define UPDATE_SPAN_TEXT_LINE_STYLE_ITEM(item, name, value) (item)->textLineStyle->Update##name(value)
26 
CreateSpanItem(ArkUI_SpanItem * item)27 RefPtr<SpanItem> SpanModelNG::CreateSpanItem(ArkUI_SpanItem* item)
28 {
29     if (!item) {
30         return nullptr;
31     }
32     if (item->placeholder) {
33         auto* drawingPlaceholder = reinterpret_cast<Rosen::PlaceholderSpan*>(item->placeholder);
34         auto placeholder = AceType::MakeRefPtr<PlaceholderSpanItem>();
35         placeholder->run_.width = drawingPlaceholder->width;
36         placeholder->run_.height = drawingPlaceholder->height;
37         placeholder->run_.alignment = static_cast<PlaceholderAlignment>(drawingPlaceholder->alignment);
38         placeholder->run_.baseline = static_cast<TextBaseline>(drawingPlaceholder->baseline);
39         placeholder->run_.baseline_offset = drawingPlaceholder->baselineOffset;
40         return placeholder;
41     }
42     auto spanItem = AceType::MakeRefPtr<SpanItem>();
43     spanItem->content = item->content;
44     auto* textStyle = reinterpret_cast<RSTextStyle*>(item->textStyle);
45     if (!textStyle) {
46         return spanItem;
47     }
48     spanItem->fontStyle = std::make_unique<FontStyle>();
49     spanItem->textLineStyle = std::make_unique<TextLineStyle>();
50     UPDATE_SPAN_FONT_STYLE_ITEM(spanItem, FontSize, Dimension(textStyle->fontSize));
51     UPDATE_SPAN_FONT_STYLE_ITEM(spanItem, TextColor,
52         Color::FromARGB(textStyle->color.GetAlpha(), textStyle->color.GetRed(), textStyle->color.GetGreen(),
53             textStyle->color.GetBlue()));
54     UPDATE_SPAN_FONT_STYLE_ITEM(spanItem, ItalicFontStyle, static_cast<Ace::FontStyle>(textStyle->fontStyle));
55     UPDATE_SPAN_FONT_STYLE_ITEM(spanItem, FontWeight, static_cast<FontWeight>(textStyle->fontWeight));
56     UPDATE_SPAN_FONT_STYLE_ITEM(spanItem, FontFamily, textStyle->fontFamilies);
57     auto decoration = TextDecoration::INHERIT;
58     switch (textStyle->decoration) {
59         case Rosen::NONE:
60             decoration = TextDecoration::NONE;
61             break;
62         case Rosen::UNDERLINE:
63             decoration = TextDecoration::UNDERLINE;
64             break;
65         case Rosen::OVERLINE:
66             decoration = TextDecoration::OVERLINE;
67             break;
68         case Rosen::LINE_THROUGH:
69             decoration = TextDecoration::LINE_THROUGH;
70             break;
71             break;
72     }
73     UPDATE_SPAN_FONT_STYLE_ITEM(spanItem, TextDecoration, decoration);
74     UPDATE_SPAN_FONT_STYLE_ITEM(
75         spanItem, TextDecorationStyle, static_cast<TextDecorationStyle>(textStyle->decorationStyle));
76     UPDATE_SPAN_FONT_STYLE_ITEM(spanItem, TextDecorationColor,
77         Color::FromARGB(textStyle->decorationColor.GetAlpha(), textStyle->decorationColor.GetRed(),
78             textStyle->decorationColor.GetGreen(), textStyle->decorationColor.GetBlue()));
79     const auto& fontFeatures = textStyle->fontFeatures.GetFontFeatures();
80     FONT_FEATURES_LIST list;
81     for (const auto& item : fontFeatures) {
82         list.emplace_back(item.first, item.second);
83     }
84     UPDATE_SPAN_FONT_STYLE_ITEM(spanItem, FontFeature, list);
85     std::vector<Shadow> shadows;
86     shadows.reserve(textStyle->shadows.size());
87     for (const auto& shadow : textStyle->shadows) {
88         shadows.emplace_back(shadow.blurRadius, 0, Offset { shadow.offset.GetX(), shadow.offset.GetY() },
89             Color::FromARGB(
90                 shadow.color.GetAlpha(), shadow.color.GetRed(), shadow.color.GetGreen(), shadow.color.GetBlue()));
91     }
92     UPDATE_SPAN_FONT_STYLE_ITEM(spanItem, TextShadow, shadows);
93     UPDATE_SPAN_FONT_STYLE_ITEM(spanItem, LetterSpacing, Dimension(textStyle->letterSpacing));
94     UPDATE_SPAN_TEXT_LINE_STYLE_ITEM(spanItem, TextBaseline, static_cast<TextBaseline>(textStyle->baseline));
95     UPDATE_SPAN_TEXT_LINE_STYLE_ITEM(spanItem, BaselineOffset, Dimension(textStyle->baseLineShift));
96     UPDATE_SPAN_TEXT_LINE_STYLE_ITEM(spanItem, EllipsisMode, static_cast<EllipsisMode>(textStyle->ellipsisModal));
97     return spanItem;
98 }
99 
CreateParagraphStyle(ArkUI_StyledString * styledString)100 ParagraphStyle SpanModelNG::CreateParagraphStyle(ArkUI_StyledString* styledString)
101 {
102     auto typoStyle = reinterpret_cast<Rosen::TypographyStyle*>(styledString->paragraphStyle);
103     TextDirection textDirection;
104     switch (typoStyle->textDirection) {
105         case Rosen::TextDirection::RTL:
106             textDirection = TextDirection::RTL;
107             break;
108         case Rosen::TextDirection::LTR:
109             textDirection = TextDirection::LTR;
110             break;
111         default:
112             textDirection = TextDirection::LTR;
113             break;
114     }
115     TextAlign textAlign;
116     switch (typoStyle->textAlign) {
117         case Rosen::TextAlign::LEFT:
118             textAlign = TextAlign::LEFT;
119             break;
120         case Rosen::TextAlign::RIGHT:
121             textAlign = TextAlign::RIGHT;
122             break;
123         case Rosen::TextAlign::CENTER:
124             textAlign = TextAlign::CENTER;
125             break;
126         case Rosen::TextAlign::JUSTIFY:
127             textAlign = TextAlign::JUSTIFY;
128             break;
129         case Rosen::TextAlign::START:
130             textAlign = TextAlign::START;
131             break;
132         case Rosen::TextAlign::END:
133             textAlign = TextAlign::END;
134             break;
135         default:
136             textAlign = TextAlign::START;
137             break;
138     }
139     std::u16string ELLIPSIS = u"\u2026";
140     ParagraphStyle style = { .direction = textDirection,
141         .align = textAlign,
142         .maxLines = typoStyle->maxLines,
143         .fontLocale = typoStyle->locale,
144         .wordBreak = static_cast<WordBreak>(typoStyle->wordBreakType),
145         .ellipsisMode = static_cast<EllipsisMode>(typoStyle->ellipsisModal),
146         .lineBreakStrategy = static_cast<LineBreakStrategy>(typoStyle->breakStrategy),
147         .textOverflow = typoStyle->ellipsis == ELLIPSIS ? TextOverflow::ELLIPSIS : TextOverflow::CLIP };
148     return style;
149 }
150 #endif
151 
152 } // namespace OHOS::Ace::NG