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