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 "font/ui_font_bitmap.h"
17
18 #include "font/ui_font_adaptor.h"
19 #include "font/ui_font_builder.h"
20 #include "gfx_utils/file.h"
21 #include "gfx_utils/graphic_log.h"
22 #include "graphic_config.h"
23 #if ENABLE_MULTI_FONT
24 #include "font/ui_multi_font_manager.h"
25 #endif
26 #if ENABLE_SHAPING
27 #include "font/ui_text_shaping.h"
28 #endif
29
30 namespace OHOS {
UIFontBitmap()31 UIFontBitmap::UIFontBitmap() : offset_(0), dynamicFont_(), dynamicFontRamUsed_(0), dynamicFontFd_(-1)
32 {
33 SetBaseFontId(UIFontBuilder::GetInstance()->GetBitmapFontIdMax());
34 bitmapCache_ = nullptr;
35 bitmapRamUsed_ = FONT_BITMAP_CACHE_SIZE;
36 }
37
~UIFontBitmap()38 UIFontBitmap::~UIFontBitmap()
39 {
40 if (dynamicFontFd_ >= 0) {
41 close(dynamicFontFd_);
42 }
43 if (bitmapCache_ != nullptr) {
44 delete bitmapCache_;
45 bitmapCache_ = nullptr;
46 }
47 }
48
IsVectorFont() const49 bool UIFontBitmap::IsVectorFont() const
50 {
51 return false;
52 }
53
GetShapingFontId(char * text,uint8_t & ttfId,uint32_t & script,uint8_t fontId,uint8_t size) const54 uint8_t UIFontBitmap::GetShapingFontId(char* text, uint8_t& ttfId, uint32_t& script, uint8_t fontId, uint8_t size) const
55 {
56 #if ENABLE_MULTI_FONT
57 return UIMultiFontManager::GetInstance()->GetShapingFontId(text, fontId, ttfId, script);
58 #else
59 UITextLanguageFontParam* fontParam = UIFontBuilder::GetInstance()->GetTextLangFontsTable(fontId);
60 if (fontParam == nullptr) {
61 return 0;
62 }
63 ttfId = fontParam->ttfId;
64 return fontParam->shaping;
65 #endif
66 }
67
GetFontWeight(uint8_t fontId)68 uint8_t UIFontBitmap::GetFontWeight(uint8_t fontId)
69 {
70 UITextLanguageFontParam* fontParam = UIFontBuilder::GetInstance()->GetTextLangFontsTable(fontId);
71 if (fontParam == nullptr) {
72 GRAPHIC_LOGE("UIFontBitmap::GetFontWeigh invalid fontId");
73 return 0;
74 }
75 return fontParam->fontWeight;
76 }
77
SetFontPath(const char * dpath,const char * spath)78 int8_t UIFontBitmap::SetFontPath(const char* dpath, const char* spath)
79 {
80 if (dpath == nullptr) {
81 GRAPHIC_LOGE("UIFontBitmap::SetFontPath invalid parameter");
82 return INVALID_RET_VALUE;
83 }
84 #ifdef _WIN32
85 dynamicFontFd_ = open(dpath, O_RDONLY | O_BINARY);
86 #else
87 dynamicFontFd_ = open(dpath, O_RDONLY);
88 #endif
89 if (dynamicFontFd_ < 0) {
90 GRAPHIC_LOGE("UIFontBitmap::SetFontPath file Open failed");
91 return INVALID_RET_VALUE;
92 }
93 dynamicFont_.SetRamBuffer(GetRamAddr());
94 int32_t ret = dynamicFont_.SetFile(dynamicFontFd_, offset_);
95 if (ret == INVALID_RET_VALUE) {
96 GRAPHIC_LOGE("GlyphsManager::SetFile failed");
97 close(dynamicFontFd_);
98 dynamicFontFd_ = -1;
99 return ret;
100 }
101 dynamicFontRamUsed_ = dynamicFont_.GetRamUsedLen();
102 return RET_VALUE_OK;
103 }
104
SetCurrentFontId(uint8_t fontId,uint8_t size)105 int8_t UIFontBitmap::SetCurrentFontId(uint8_t fontId, uint8_t size)
106 {
107 int8_t ret = SetDynamicFontId(fontId);
108 if (ret == RET_VALUE_OK) {
109 SetBaseFontId(fontId);
110 }
111 return ret;
112 }
113
GetHeight()114 uint16_t UIFontBitmap::GetHeight()
115 {
116 int16_t ret = dynamicFont_.SetCurrentFontId(GetBaseFontId());
117 if (ret == INVALID_RET_VALUE) {
118 return ret;
119 }
120 return dynamicFont_.GetFontHeight();
121 }
122
GetFontId(const char * ttfName,uint8_t size) const123 uint8_t UIFontBitmap::GetFontId(const char* ttfName, uint8_t size) const
124 {
125 if (ttfName == nullptr) {
126 return UIFontBuilder::GetInstance()->GetBitmapFontIdMax();
127 }
128 uint8_t id;
129 for (id = 0; id < UIFontBuilder::GetInstance()->GetBitmapFontIdMax(); ++id) {
130 UITextLanguageFontParam* fontParam = UIFontBuilder::GetInstance()->GetTextLangFontsTable(id);
131 if (fontParam != nullptr) {
132 if ((fontParam->size == size) && (strncmp(fontParam->ttfName, ttfName, TTF_NAME_LEN_MAX) == 0)) {
133 break;
134 }
135 }
136 }
137 return id;
138 }
139
GetWidth(uint32_t unicode,uint8_t fontId)140 int16_t UIFontBitmap::GetWidth(uint32_t unicode, uint8_t fontId)
141 {
142 return GetWidthInFontId(unicode, fontId);
143 }
144
GetBitmap(uint32_t unicode,GlyphNode & glyphNode,uint8_t fontId)145 uint8_t* UIFontBitmap::GetBitmap(uint32_t unicode, GlyphNode& glyphNode, uint8_t fontId)
146 {
147 return SearchInFont(unicode, glyphNode, fontId);
148 }
149
GetCurrentFontHeader(FontHeader & fontHeader)150 int8_t UIFontBitmap::GetCurrentFontHeader(FontHeader& fontHeader)
151 {
152 int8_t ret = dynamicFont_.SetCurrentFontId(GetBaseFontId());
153 if (ret == INVALID_RET_VALUE) {
154 return ret;
155 }
156 const FontHeader* header = dynamicFont_.GetCurrentFontHeader();
157 if (header != nullptr) {
158 fontHeader = *header;
159 return RET_VALUE_OK;
160 }
161 return INVALID_RET_VALUE;
162 }
163
GetGlyphNode(uint32_t unicode,GlyphNode & glyphNode)164 int8_t UIFontBitmap::GetGlyphNode(uint32_t unicode, GlyphNode& glyphNode)
165 {
166 int8_t ret = dynamicFont_.SetCurrentFontId(GetBaseFontId());
167 if (ret == INVALID_RET_VALUE) {
168 return ret;
169 }
170 const GlyphNode* node = dynamicFont_.GetGlyphNode(unicode);
171 if (node != nullptr) {
172 glyphNode = *node;
173 return RET_VALUE_OK;
174 }
175 GRAPHIC_LOGE("UIFontBitmap::GetGlyphNode get glyphNode failed");
176 return INVALID_RET_VALUE;
177 }
178
GetFontVersion(char * dVersion,uint8_t dLen,char * sVersion,uint8_t sLen) const179 int8_t UIFontBitmap::GetFontVersion(char* dVersion, uint8_t dLen, char* sVersion, uint8_t sLen) const
180 {
181 return dynamicFont_.GetFontVersion(dVersion, dLen);
182 }
183
SetCurrentLangId(uint8_t langId)184 int8_t UIFontBitmap::SetCurrentLangId(uint8_t langId)
185 {
186 if (bitmapCache_ == nullptr) {
187 uint8_t* bitmapCacheAddr = reinterpret_cast<uint8_t*>(GetRamAddr() + dynamicFontRamUsed_);
188 bitmapCache_ = new UIFontCache(bitmapCacheAddr, bitmapRamUsed_);
189 }
190 uint32_t total = dynamicFontRamUsed_ + bitmapRamUsed_;
191 return (total <= GetRamLen()) ? RET_VALUE_OK : INVALID_RET_VALUE;
192 }
193
GetFontInfo(uint8_t fontId) const194 UITextLanguageFontParam* UIFontBitmap::GetFontInfo(uint8_t fontId) const
195 {
196 return UIFontBuilder::GetInstance()->GetTextLangFontsTable(fontId);
197 }
198
GetBitmapRamUsed()199 uint32_t UIFontBitmap::GetBitmapRamUsed()
200 {
201 return bitmapRamUsed_;
202 }
203
GetDynamicFontRamUsed()204 uint32_t UIFontBitmap::GetDynamicFontRamUsed()
205 {
206 return dynamicFontRamUsed_;
207 }
208
GetRamUsedLen(uint32_t textManagerRamUsed,uint32_t langFontRamUsed)209 uint32_t UIFontBitmap::GetRamUsedLen(uint32_t textManagerRamUsed, uint32_t langFontRamUsed)
210 {
211 if (bitmapCache_ == nullptr) {
212 uint8_t* bitmapCacheAddr = reinterpret_cast<uint8_t*>(GetRamAddr() + dynamicFontRamUsed_ + textManagerRamUsed);
213 bitmapCache_ = new UIFontCache(bitmapCacheAddr, bitmapRamUsed_);
214 }
215 return dynamicFontRamUsed_ + textManagerRamUsed + bitmapRamUsed_ + langFontRamUsed;
216 }
217
GetDynamicFontBitmap(uint32_t unicode,uint8_t * bitmap,uint8_t fontId)218 int8_t UIFontBitmap::GetDynamicFontBitmap(uint32_t unicode, uint8_t* bitmap, uint8_t fontId)
219 {
220 int16_t ret = dynamicFont_.SetCurrentFontId(fontId);
221 if (ret == INVALID_RET_VALUE) {
222 return ret;
223 }
224 return dynamicFont_.GetBitmap(unicode, bitmap, fontId);
225 }
226
GetCacheBitmap(uint8_t fontId,uint32_t unicode)227 uint8_t* UIFontBitmap::GetCacheBitmap(uint8_t fontId, uint32_t unicode)
228 {
229 if (bitmapCache_ != nullptr) {
230 return bitmapCache_->GetBitmap(fontId, unicode);
231 }
232 GRAPHIC_LOGE("UIFontBitmap::GetCacheBitmap invalid bitmapCache");
233 return nullptr;
234 }
235
GetCacheSpace(uint8_t fontId,uint32_t unicode,uint32_t size)236 uint8_t* UIFontBitmap::GetCacheSpace(uint8_t fontId, uint32_t unicode, uint32_t size)
237 {
238 if (bitmapCache_ != nullptr) {
239 return bitmapCache_->GetSpace(fontId, unicode, size);
240 }
241 GRAPHIC_LOGE("UIFontBitmap::GetCacheSpace invalid bitmapCache");
242 return nullptr;
243 }
244
PutCacheSpace(uint8_t * addr)245 void UIFontBitmap::PutCacheSpace(uint8_t* addr)
246 {
247 if (bitmapCache_ != nullptr) {
248 bitmapCache_->PutSpace(addr);
249 }
250 GRAPHIC_LOGE("UIFontBitmap::PutCacheSpace invalid bitmapCache");
251 }
252
SetDynamicFontId(uint8_t fontId)253 int8_t UIFontBitmap::SetDynamicFontId(uint8_t fontId)
254 {
255 return dynamicFont_.SetCurrentFontId(fontId);
256 }
257
GetDynamicFontWidth(uint32_t unicode,uint8_t fontId)258 int16_t UIFontBitmap::GetDynamicFontWidth(uint32_t unicode, uint8_t fontId)
259 {
260 int16_t ret = dynamicFont_.SetCurrentFontId(fontId);
261 if (ret == INVALID_RET_VALUE) {
262 return ret;
263 }
264 return dynamicFont_.GetFontWidth(unicode);
265 }
266
SearchInFont(uint32_t unicode,GlyphNode & glyphNode,uint8_t fontId)267 uint8_t* UIFontBitmap::SearchInFont(uint32_t unicode, GlyphNode& glyphNode, uint8_t fontId)
268 {
269 if (bitmapCache_ == nullptr) {
270 return nullptr;
271 }
272 if (!UIFontAdaptor::IsSameTTFId(fontId, unicode)) {
273 GRAPHIC_LOGE("UIFontBitmap::GetWidthInFontId fontId and unicode not match");
274 return nullptr;
275 }
276 if (fontId != GetBaseFontId()) {
277 SetCurrentFontId(fontId);
278 }
279 int8_t ret = GetGlyphNode(unicode, glyphNode);
280 if (ret != RET_VALUE_OK) {
281 return nullptr;
282 }
283 uint8_t* bitmap = bitmapCache_->GetBitmap(fontId, unicode);
284 if (bitmap != nullptr) {
285 if (glyphNode.dataFlag == glyphNode.fontId && fontId == glyphNode.fontId) {
286 return bitmap;
287 } else {
288 GRAPHIC_LOGE("DataFlag of bitmap node not equal to fontId.");
289 }
290 }
291 if (glyphNode.kernOff <= glyphNode.dataOff) {
292 return nullptr;
293 }
294 uint32_t bitmapSize = glyphNode.kernOff - glyphNode.dataOff;
295 if (bitmap == nullptr) {
296 bitmap = bitmapCache_->GetSpace(fontId, unicode, bitmapSize);
297 }
298 ret = dynamicFont_.GetBitmap(unicode, bitmap, fontId);
299 if (ret == RET_VALUE_OK) {
300 return bitmap;
301 }
302 bitmapCache_->PutSpace(bitmap);
303 return nullptr;
304 }
305
GetWidthInFontId(uint32_t unicode,uint8_t fontId)306 int16_t UIFontBitmap::GetWidthInFontId(uint32_t unicode, uint8_t fontId)
307 {
308 if (!UIFontAdaptor::IsSameTTFId(fontId, unicode)) {
309 GRAPHIC_LOGE("UIFontBitmap::GetWidthInFontId fontId and unicode not match");
310 return INVALID_RET_VALUE;
311 }
312 if (fontId != GetBaseFontId()) {
313 SetCurrentFontId(fontId);
314 }
315 return GetDynamicFontWidth(unicode, GetBaseFontId());
316 }
317
SetFontFileOffset(uint32_t offset)318 void UIFontBitmap::SetFontFileOffset(uint32_t offset)
319 {
320 offset_ = offset;
321 }
322 } // namespace OHOS
323