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