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