• 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 "draw/draw_label.h"
17 #include <cstdio>
18 #include "common/typed_text.h"
19 #include "draw/draw_utils.h"
20 #include "engines/gfx/gfx_engine_manager.h"
21 #include "font/ui_font.h"
22 #include "font/ui_font_header.h"
23 #include "gfx_utils/graphic_log.h"
24 
25 namespace OHOS {
DrawTextOneLine(BufferInfo & gfxDstBuffer,const LabelLineInfo & labelLine)26 void DrawLabel::DrawTextOneLine(BufferInfo& gfxDstBuffer, const LabelLineInfo& labelLine)
27 {
28     if (labelLine.text == nullptr) {
29         return;
30     }
31     UIFont* fontEngine = UIFont::GetInstance();
32     if (labelLine.direct == TEXT_DIRECT_RTL) {
33         labelLine.pos.x -= labelLine.offset.x;
34     } else {
35         labelLine.pos.x += labelLine.offset.x;
36     }
37 
38     uint32_t i = 0;
39     uint32_t letter;
40     uint16_t letterWidth;
41     while (i < labelLine.lineLength) {
42         letter = TypedText::GetUTF8Next(labelLine.text, i, i);
43 
44         LabelLetterInfo letterInfo{labelLine.pos,
45                                    labelLine.mask,
46                                    labelLine.style.textColor_,
47                                    labelLine.opaScale,
48                                    0,
49                                    0,
50                                    letter,
51                                    labelLine.direct,
52                                    labelLine.fontId,
53                                    0,
54                                    labelLine.fontSize,
55                                    labelLine.baseLine};
56         DrawUtils::GetInstance()->DrawLetter(gfxDstBuffer, letterInfo);
57         letterWidth = fontEngine->GetWidth(letter, 0);
58         if (labelLine.direct == TEXT_DIRECT_RTL) {
59             labelLine.pos.x -= (letterWidth + labelLine.style.letterSpace_);
60         } else {
61             labelLine.pos.x += (letterWidth + labelLine.style.letterSpace_);
62         }
63     }
64 }
65 
DrawArcText(BufferInfo & gfxDstBuffer,const Rect & mask,const char * text,const Point & arcCenter,uint8_t fontId,const UIArcLabel::ArcTextInfo arcTextInfo,UIArcLabel::TextOrientation orientation,const Style & style,OpacityType opaScale)66 void DrawLabel::DrawArcText(BufferInfo& gfxDstBuffer,
67                             const Rect& mask,
68                             const char* text,
69                             const Point& arcCenter,
70                             uint8_t fontId,
71                             const UIArcLabel::ArcTextInfo arcTextInfo,
72                             UIArcLabel::TextOrientation orientation,
73                             const Style& style,
74                             OpacityType opaScale)
75 {
76     if ((text == nullptr) || (arcTextInfo.lineStart == arcTextInfo.lineEnd) || (arcTextInfo.radius == 0)) {
77         GRAPHIC_LOGE("DrawLabel::DrawArcText invalid parameter\n");
78         return;
79     }
80     OpacityType opa = DrawUtils::GetMixOpacity(opaScale, style.textOpa_);
81     if (opa == OPA_TRANSPARENT) {
82         return;
83     }
84     uint16_t letterWidth;
85     uint16_t letterHeight = UIFont::GetInstance()->GetHeight();
86     uint32_t i = arcTextInfo.lineStart;
87     float angle = arcTextInfo.startAngle;
88     float posX;
89     float posY;
90     float rotateAngle;
91 
92     bool orientationFlag = (orientation == UIArcLabel::TextOrientation::INSIDE);
93     bool directFlag = (arcTextInfo.direct == TEXT_DIRECT_LTR);
94     bool xorFlag = !((orientationFlag && directFlag) || (!orientationFlag && !directFlag));
95 
96     while (i < arcTextInfo.lineEnd) {
97         uint32_t tmp = i;
98         uint32_t letter = TypedText::GetUTF8Next(text, tmp, i);
99         if (letter == 0) {
100             continue;
101         }
102         if ((letter == '\r') || (letter == '\n')) {
103             break;
104         }
105         letterWidth = UIFont::GetInstance()->GetWidth(letter, 0);
106         if ((tmp == arcTextInfo.lineStart) && xorFlag) {
107             angle += TypedText::GetAngleForArcLen(static_cast<float>(letterWidth), letterHeight, arcTextInfo.radius,
108                                                   arcTextInfo.direct, orientation);
109         }
110         uint16_t arcLen = letterWidth + style.letterSpace_;
111         if (arcLen == 0) {
112             continue;
113         }
114         float incrementAngle = TypedText::GetAngleForArcLen(static_cast<float>(arcLen), letterHeight,
115                                                             arcTextInfo.radius, arcTextInfo.direct, orientation);
116 
117         rotateAngle = (orientation == UIArcLabel::TextOrientation::INSIDE) ? angle : (angle - SEMICIRCLE_IN_DEGREE);
118 
119         // 2: half
120         float fineTuningAngle = incrementAngle * (static_cast<float>(letterWidth) / (2 * arcLen));
121         rotateAngle += (xorFlag ? -fineTuningAngle : fineTuningAngle);
122         TypedText::GetArcLetterPos(arcCenter, arcTextInfo.radius, angle, posX, posY);
123         angle += incrementAngle;
124 
125         DrawLetterWithRotate(gfxDstBuffer, mask, fontId, letter, Point { MATH_ROUND(posX), MATH_ROUND(posY) },
126                              static_cast<int16_t>(rotateAngle), style.textColor_, opaScale);
127     }
128 }
129 
DrawLetterWithRotate(BufferInfo & gfxDstBuffer,const Rect & mask,uint8_t fontId,uint32_t letter,const Point & pos,int16_t rotateAngle,const ColorType & color,OpacityType opaScale)130 void DrawLabel::DrawLetterWithRotate(BufferInfo& gfxDstBuffer,
131                                      const Rect& mask,
132                                      uint8_t fontId,
133                                      uint32_t letter,
134                                      const Point& pos,
135                                      int16_t rotateAngle,
136                                      const ColorType& color,
137                                      OpacityType opaScale)
138 {
139     UIFont* fontEngine = UIFont::GetInstance();
140     FontHeader head;
141     GlyphNode node;
142     if (fontEngine->GetCurrentFontHeader(head) != 0) {
143         return;
144     }
145 
146     const uint8_t* fontMap = fontEngine->GetBitmap(letter, node, 0);
147     if (fontMap == nullptr) {
148         return;
149     }
150     uint8_t fontWeight = fontEngine->GetFontWeight(fontId);
151     ColorMode colorMode;
152     switch (fontWeight) {
153         case FONT_WEIGHT_1:
154             colorMode = A1;
155             break;
156         case FONT_WEIGHT_2:
157             colorMode = A2;
158             break;
159         case FONT_WEIGHT_4:
160             colorMode = A4;
161             break;
162         case FONT_WEIGHT_8:
163             colorMode = A8;
164             break;
165         default:
166             return;
167     }
168     Rect rectLetter;
169     rectLetter.SetPosition(pos.x + node.left, pos.y + head.ascender - node.top);
170     rectLetter.Resize(node.cols, node.rows);
171     TransformMap transMap(rectLetter);
172     transMap.Rotate(rotateAngle, Vector2<float>(-node.left, node.top - head.ascender));
173     TransformDataInfo letterTranDataInfo = {ImageHeader{colorMode, 0, 0, 0, node.cols, node.rows}, fontMap, fontWeight,
174                                             BlurLevel::LEVEL0, TransformAlgorithm::BILINEAR};
175     BaseGfxEngine::GetInstance()->DrawTransform(gfxDstBuffer, mask, Point { 0, 0 }, color, opaScale, transMap,
176                                                 letterTranDataInfo);
177 }
178 } // namespace OHOS
179