• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2020-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 #include "components/ui_arc_label.h"
17 
18 #include "common/typed_text.h"
19 #include "draw/draw_label.h"
20 #include "engines/gfx/gfx_engine_manager.h"
21 #include "font/ui_font.h"
22 #include "themes/theme_manager.h"
23 
24 namespace OHOS {
UIArcLabel()25 UIArcLabel::UIArcLabel()
26     : arcLabelText_(nullptr),
27       compatibilityMode_(true),
28       needRefresh_(false),
29       arcTextInfo_{0},
30       textSize_({0, 0}),
31       radius_(0),
32       startAngle_(0),
33       endAngle_(0),
34       arcCenter_({0, 0}),
35       orientation_(TextOrientation::INSIDE)
36 {
37     Theme* theme = ThemeManager::GetInstance().GetCurrent();
38     style_ = (theme != nullptr) ? &(theme->GetLabelStyle()) : &(StyleDefault::GetLabelStyle());
39 }
40 
~UIArcLabel()41 UIArcLabel::~UIArcLabel()
42 {
43     if (arcLabelText_ != nullptr) {
44         delete arcLabelText_;
45         arcLabelText_ = nullptr;
46     }
47 }
48 
SetStyle(uint8_t key,int64_t value)49 void UIArcLabel::SetStyle(uint8_t key, int64_t value)
50 {
51     UIView::SetStyle(key, value);
52     RefreshArcLabel();
53 }
54 
SetText(const char * text)55 void UIArcLabel::SetText(const char* text)
56 {
57     if (text == nullptr) {
58         return;
59     }
60     InitArcLabelText();
61     arcLabelText_->SetText(text);
62     if (arcLabelText_->IsNeedRefresh()) {
63         RefreshArcLabel();
64     }
65 }
66 
GetText() const67 const char* UIArcLabel::GetText() const
68 {
69     return (arcLabelText_ == nullptr) ? nullptr : arcLabelText_->GetText();
70 }
71 
SetAlign(UITextLanguageAlignment horizontalAlign)72 void UIArcLabel::SetAlign(UITextLanguageAlignment horizontalAlign)
73 {
74     InitArcLabelText();
75     arcLabelText_->SetAlign(horizontalAlign, TEXT_ALIGNMENT_TOP);
76     if (arcLabelText_->IsNeedRefresh()) {
77         RefreshArcLabel();
78     }
79 }
80 
GetHorAlign()81 UITextLanguageAlignment UIArcLabel::GetHorAlign()
82 {
83     InitArcLabelText();
84     return arcLabelText_->GetHorAlign();
85 }
86 
GetDirect()87 UITextLanguageDirect UIArcLabel::GetDirect()
88 {
89     InitArcLabelText();
90     return arcLabelText_->GetDirect();
91 }
92 
SetFontId(uint16_t fontId)93 void UIArcLabel::SetFontId(uint16_t fontId)
94 {
95     InitArcLabelText();
96     arcLabelText_->SetFontId(fontId);
97     if (arcLabelText_->IsNeedRefresh()) {
98         RefreshArcLabel();
99     }
100 }
101 
GetFontId()102 uint16_t UIArcLabel::GetFontId()
103 {
104     InitArcLabelText();
105     return arcLabelText_->GetFontId();
106 }
107 
SetFont(const char * name,uint8_t size)108 void UIArcLabel::SetFont(const char* name, uint8_t size)
109 {
110     if (name == nullptr) {
111         return;
112     }
113     InitArcLabelText();
114     arcLabelText_->SetFont(name, size);
115     if (arcLabelText_->IsNeedRefresh()) {
116         RefreshArcLabel();
117     }
118 }
119 
OnDraw(BufferInfo & gfxDstBuffer,const Rect & invalidatedArea)120 void UIArcLabel::OnDraw(BufferInfo& gfxDstBuffer, const Rect& invalidatedArea)
121 {
122     InitArcLabelText();
123     const char* text = arcLabelText_->GetText();
124     if ((text == nullptr) || (radius_ == 0)) {
125         return;
126     }
127     OpacityType opa = GetMixOpaScale();
128     UIView::OnDraw(gfxDstBuffer, invalidatedArea);
129     DrawArcText(gfxDstBuffer, invalidatedArea, opa, arcTextInfo_, orientation_);
130 }
131 
DrawArcText(BufferInfo & gfxDstBuffer,const Rect & mask,OpacityType opaScale,const ArcTextInfo arcTextInfo,TextOrientation orientation)132 void UIArcLabel::DrawArcText(BufferInfo& gfxDstBuffer,
133                              const Rect& mask,
134                              OpacityType opaScale,
135                              const ArcTextInfo arcTextInfo,
136                              TextOrientation orientation)
137 {
138     Point center;
139     center.x = arcTextInfo_.arcCenter.x + GetRect().GetX();
140     center.y = arcTextInfo_.arcCenter.y + GetRect().GetY();
141     DrawLabel::DrawArcText(gfxDstBuffer, mask, arcLabelText_->GetText(), center, arcLabelText_->GetFontId(),
142                            arcLabelText_->GetFontSize(), arcTextInfo,
143                            orientation, *style_, opaScale, compatibilityMode_);
144 }
145 
GetArcTextRect(const char * text,uint16_t fontId,uint8_t fontSize,const Point & arcCenter,int16_t letterSpace,TextOrientation orientation,const ArcTextInfo & arcTextInfo)146 Rect UIArcLabel::GetArcTextRect(const char* text, uint16_t fontId, uint8_t fontSize, const Point& arcCenter,
147                                 int16_t letterSpace, TextOrientation orientation, const ArcTextInfo& arcTextInfo)
148 {
149     return TypedText::GetArcTextRect(text, fontId, fontSize, arcCenter, letterSpace, orientation, arcTextInfo);
150 }
151 
RefreshArcLabel()152 void UIArcLabel::RefreshArcLabel()
153 {
154     Invalidate();
155     if (!needRefresh_) {
156         needRefresh_ = true;
157     }
158 }
159 
ReMeasure()160 void UIArcLabel::ReMeasure()
161 {
162     if (!needRefresh_) {
163         return;
164     }
165     needRefresh_ = false;
166     InitArcLabelText();
167 
168     MeasureArcTextInfo();
169     arcTextInfo_.shapingFontId = arcLabelText_->GetShapingFontId();
170     arcTextInfo_.codePoints = arcLabelText_->GetCodePoints();
171     arcTextInfo_.codePointsNum = arcLabelText_->GetCodePointNum();
172     Rect textRect =
173         GetArcTextRect(arcLabelText_->GetText(), arcLabelText_->GetFontId(), arcLabelText_->GetFontSize(),
174                        arcCenter_, style_->letterSpace_, orientation_, arcTextInfo_);
175     int16_t arcTextWidth = textRect.GetWidth();
176     int16_t arcTextHeight = textRect.GetHeight();
177 
178     if (compatibilityMode_) {
179         SetPosition(textRect.GetX(), textRect.GetY());
180         Resize(arcTextWidth, arcTextHeight);
181     }
182 
183     arcTextInfo_.arcCenter.x = arcCenter_.x - GetX() + style_->borderWidth_ + style_->paddingLeft_;
184     arcTextInfo_.arcCenter.y = arcCenter_.y - GetY() + style_->borderWidth_ + style_->paddingTop_;
185     textSize_.x = arcTextWidth;
186     textSize_.y = arcTextHeight;
187     Invalidate();
188 }
189 
GetLineEnd(int16_t maxLength)190 uint32_t UIArcLabel::GetLineEnd(int16_t maxLength)
191 {
192     const char* text = arcLabelText_->GetText();
193     if (text == nullptr) {
194         return 0;
195     }
196 
197     return TypedText::GetNextLine(&text[arcTextInfo_.lineStart], arcLabelText_->GetFontId(),
198         arcLabelText_->GetFontSize(), style_->letterSpace_, maxLength);
199 }
200 
MeasureArcTextInfo()201 void UIArcLabel::MeasureArcTextInfo()
202 {
203     const char* text = arcLabelText_->GetText();
204     if (text == nullptr) {
205         return;
206     }
207     uint16_t letterHeight = UIFont::GetInstance()->GetHeight(arcLabelText_->GetFontId(), arcLabelText_->GetFontSize());
208     if (compatibilityMode_) {
209         arcTextInfo_.radius = ((orientation_ == TextOrientation::INSIDE) ? radius_ : (radius_ - letterHeight));
210     } else {
211         arcTextInfo_.radius = radius_;
212     }
213     if (arcTextInfo_.radius == 0) {
214         return;
215     }
216 
217     uint16_t arcAngle;
218     if (startAngle_ < endAngle_) {
219         arcAngle = endAngle_ - startAngle_;
220         arcTextInfo_.direct = TEXT_DIRECT_LTR; // Clockwise
221         arcLabelText_->SetDirect(TEXT_DIRECT_LTR);
222     } else {
223         arcAngle = startAngle_ - endAngle_;
224         arcTextInfo_.direct = TEXT_DIRECT_RTL; // Counterclockwise
225         arcLabelText_->SetDirect(TEXT_DIRECT_RTL);
226     }
227     // calculate max arc length
228     float maxLength = static_cast<float>((UI_PI * radius_ * arcAngle) / SEMICIRCLE_IN_DEGREE);
229     arcTextInfo_.lineStart = 0;
230 
231     Rect rect;
232     rect.SetWidth(static_cast<int16_t>(maxLength));
233     arcLabelText_->ReMeasureTextSize(rect, *style_);
234 
235     arcTextInfo_.lineEnd = GetLineEnd(static_cast<int16_t>(maxLength));
236 
237     arcTextInfo_.startAngle = startAngle_ % CIRCLE_IN_DEGREE;
238     int16_t actLength =
239         TypedText::GetTextWidth(&text[arcTextInfo_.lineStart], arcLabelText_->GetFontId(), arcLabelText_->GetFontSize(),
240                                 arcTextInfo_.lineEnd - arcTextInfo_.lineStart, style_->letterSpace_);
241     if ((arcLabelText_->GetHorAlign() != TEXT_ALIGNMENT_LEFT) && (actLength < maxLength)) {
242         float gapLength = maxLength - actLength;
243         if (arcLabelText_->GetHorAlign() == TEXT_ALIGNMENT_CENTER) {
244             gapLength = gapLength / 2; // 2: half
245         }
246         arcTextInfo_.startAngle += TypedText::GetAngleForArcLen(gapLength, letterHeight, arcTextInfo_.radius,
247                                                                 arcTextInfo_.direct, orientation_);
248     }
249 }
250 } // namespace OHOS
251