1 /*
2  * Copyright (c) 2020-2022 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.h"
17 #include "common/text.h"
18 #include "font/ui_font_cache.h"
19 #include "font/font_ram_allocator.h"
20 #if defined(ENABLE_VECTOR_FONT) && ENABLE_VECTOR_FONT
21 #include "font/ui_font_vector.h"
22 #endif
23 #if defined(ENABLE_BITMAP_FONT) && ENABLE_BITMAP_FONT
24 #include "font/ui_font_bitmap.h"
25 #endif
26 #include "graphic_config.h"
27 #if defined(ENABLE_MULTI_FONT) && ENABLE_MULTI_FONT
28 #include "font/ui_multi_font_manager.h"
29 #endif
30 
31 namespace OHOS {
32 bool UIFont::setFontAllocFlag_ = false;
UIFont()33 UIFont::UIFont() : instance_(nullptr), defaultInstance_(nullptr) {}
34 
~UIFont()35 UIFont::~UIFont() {}
36 
GetInstance()37 UIFont* UIFont::GetInstance()
38 {
39     static UIFont instance;
40 #if defined(ENABLE_BITMAP_FONT) && ENABLE_BITMAP_FONT
41     if (instance.instance_ == nullptr) {
42         instance.defaultInstance_ = new UIFontBitmap();
43         instance.instance_ = instance.defaultInstance_;
44         setFontAllocFlag_ = true;
45     }
46 #endif
47 #if defined(ENABLE_VECTOR_FONT) && ENABLE_VECTOR_FONT
48     if (instance.instance_ == nullptr) {
49         instance.defaultInstance_ = new UIFontVector();
50         instance.instance_ = instance.defaultInstance_;
51         setFontAllocFlag_ = true;
52     }
53 #endif
54     return &instance;
55 }
56 
SetFont(BaseFont * font)57 void UIFont::SetFont(BaseFont* font)
58 {
59     if (font != nullptr) {
60         if (defaultInstance_ != nullptr && setFontAllocFlag_) {
61             delete defaultInstance_;
62             defaultInstance_ = nullptr;
63             setFontAllocFlag_ = false;
64         }
65         defaultInstance_ = font;
66         instance_ = font;
67     }
68 }
69 
GetFont()70 BaseFont* UIFont::GetFont()
71 {
72     return instance_;
73 }
74 
75 #if (defined(ENABLE_MIX_FONT) && (ENABLE_MIX_FONT == 1))
SetBitmapFont(BaseFont * font)76 void UIFont::SetBitmapFont(BaseFont* font)
77 {
78     if (font == nullptr) {
79         return;
80     }
81     GetBitmapInstance()->SetFont(font);
82 }
83 
GetBitmapInstance()84 UIFont* UIFont::GetBitmapInstance()
85 {
86     static UIFont instance;
87     if (instance.instance_ == nullptr) {
88         instance.defaultInstance_ = new UIFontBitmap();
89         instance.instance_ = instance.defaultInstance_;
90         setFontAllocFlag_ = true;
91     }
92     return &instance;
93 }
94 #endif
95 
SetFontFileOffset(uint32_t offset)96 void UIFont::SetFontFileOffset(uint32_t offset)
97 {
98 #if (defined(ENABLE_MIX_FONT) && (ENABLE_MIX_FONT == 1))
99     GetBitmapInstance()->GetFont()->SetFontFileOffset(offset);
100 #else
101     instance_->SetFontFileOffset(offset);
102 #endif
103 }
104 
SetCurrentLangId(uint8_t langId)105 int8_t UIFont::SetCurrentLangId(uint8_t langId)
106 {
107 #if (defined(ENABLE_MIX_FONT) && (ENABLE_MIX_FONT == 1))
108     return GetBitmapInstance()->GetFont()->SetCurrentLangId(langId);
109 #else
110     return instance_->SetCurrentLangId(langId);
111 #endif
112 }
113 
GetCurrentLangId() const114 uint8_t UIFont::GetCurrentLangId() const
115 {
116 #if (defined(ENABLE_MIX_FONT) && (ENABLE_MIX_FONT == 1))
117     return GetBitmapInstance()->GetFont()->GetCurrentLangId();
118 #else
119     return instance_->GetCurrentLangId();
120 #endif
121 }
122 
SetFontPath(const char * path,BaseFont::FontType type)123 int8_t  UIFont::SetFontPath(const char* path, BaseFont::FontType type)
124 {
125 #if (defined(ENABLE_MIX_FONT) && (ENABLE_MIX_FONT == 1))
126     if (type == BaseFont::FontType::VECTOR_FONT) {
127         return instance_->SetFontPath(path, type);
128     }
129     return GetBitmapInstance()->GetFont()->SetFontPath(path, type);
130 #else
131     return instance_->SetFontPath(path, type);
132 #endif
133 }
134 
GetTextUtf8(uint16_t textId,uint8_t ** utf8Addr,uint16_t & utf8Len) const135 int8_t UIFont::GetTextUtf8(uint16_t textId, uint8_t** utf8Addr, uint16_t& utf8Len) const
136 {
137 #if (defined(ENABLE_MIX_FONT) && (ENABLE_MIX_FONT == 1))
138     return GetBitmapInstance()->GetFont()->GetTextUtf8(textId, utf8Addr, utf8Len);
139 #else
140     return instance_->GetTextUtf8(textId, utf8Addr, utf8Len);
141 #endif
142 }
143 
GetTextParam(uint16_t textId,UITextLanguageTextParam & param) const144 int8_t UIFont::GetTextParam(uint16_t textId, UITextLanguageTextParam& param) const
145 {
146 #if (defined(ENABLE_MIX_FONT) && (ENABLE_MIX_FONT == 1))
147     return GetBitmapInstance()->GetFont()->GetTextParam(textId, param);
148 #else
149     return instance_->GetTextParam(textId, param);
150 #endif
151 }
152 
GetWildCardStaticStr(uint16_t textId,UITextWildcardStaticType type,uint8_t ** strAddr,uint16_t & strLen) const153 int8_t UIFont::GetWildCardStaticStr(uint16_t textId,
154                                     UITextWildcardStaticType type,
155                                     uint8_t** strAddr,
156                                     uint16_t& strLen) const
157 {
158 #if (defined(ENABLE_MIX_FONT) && (ENABLE_MIX_FONT == 1))
159     return GetBitmapInstance()->GetFont()->GetWildCardStaticStr(textId, type, strAddr, strLen);
160 #else
161     return instance_->GetWildCardStaticStr(textId, type, strAddr, strLen);
162 #endif
163 }
164 
GetCodePoints(uint16_t textId,uint32_t ** codePoints,uint16_t & codePointsNum) const165 int8_t UIFont::GetCodePoints(uint16_t textId, uint32_t** codePoints, uint16_t& codePointsNum) const
166 {
167 #if (defined(ENABLE_MIX_FONT) && (ENABLE_MIX_FONT == 1))
168     return GetBitmapInstance()->GetFont()->GetCodePoints(textId, codePoints, codePointsNum);
169 #else
170     return instance_->GetCodePoints(textId, codePoints, codePointsNum);
171 #endif
172 }
173 
GetBitmap(uint32_t unicode,GlyphNode & glyphNode,uint16_t fontId,uint8_t fontSize,uint8_t shapingFont)174 uint8_t* UIFont::GetBitmap(uint32_t unicode, GlyphNode& glyphNode, uint16_t fontId, uint8_t fontSize,
175                            uint8_t shapingFont)
176 {
177     uint8_t* bitmap = nullptr;
178 #if ENABLE_MULTI_FONT
179     // shaping font is in search list, search shaping font first
180     if (shapingFont > 1) {
181         bitmap = instance_->GetBitmap(unicode, glyphNode, shapingFont, fontSize);
182         if (bitmap != nullptr) {
183             return bitmap;
184         }
185     }
186 #endif
187     bitmap = instance_->GetBitmap(unicode, glyphNode, fontId, fontSize);
188     if (bitmap != nullptr) {
189         return bitmap;
190     }
191 #if ENABLE_MULTI_FONT
192     uint16_t* searchLists = nullptr;
193     int32_t listSize = UIMultiFontManager::GetInstance()->GetSearchFontList(fontId, &searchLists);
194     int32_t currentIndex = 0;
195     if ((searchLists == nullptr) || (listSize == 0)) {
196         return nullptr;
197     }
198     do {
199         bitmap = instance_->GetBitmap(unicode, glyphNode, searchLists[currentIndex], fontSize);
200         if (bitmap != nullptr) {
201             return bitmap;
202         }
203         // switch to next search List
204         currentIndex++;
205     } while ((currentIndex < listSize) && (searchLists != nullptr));
206 #endif
207     return nullptr;
208 }
209 
GetGlyphNode(uint32_t unicode,GlyphNode & glyphNode,uint16_t fontId,uint8_t fontSize)210 int8_t UIFont::GetGlyphNode(uint32_t unicode, GlyphNode& glyphNode, uint16_t fontId, uint8_t fontSize)
211 {
212     int8_t result = instance_->GetGlyphNode(unicode, glyphNode, fontId, fontSize);
213     if (result == RET_VALUE_OK) {
214         return result;
215     }
216 
217 #if defined(ENABLE_MULTI_FONT) && ENABLE_MULTI_FONT
218     uint16_t* searchLists = nullptr;
219     int32_t listSize = UIMultiFontManager::GetInstance()->GetSearchFontList(fontId, &searchLists);
220     if ((searchLists == nullptr) || (listSize == 0)) {
221         return INVALID_RET_VALUE;
222     }
223     int32_t currentIndex = 0;
224     do {
225         result = instance_->GetGlyphNode(unicode, glyphNode, searchLists[currentIndex], fontSize);
226         if (result == RET_VALUE_OK) {
227             return result;
228         }
229         currentIndex++;
230     } while ((currentIndex < listSize) && (searchLists != nullptr));
231 #endif
232     return INVALID_RET_VALUE;
233 }
234 
GetWidth(uint32_t unicode,uint16_t fontId,uint8_t fontSize,uint8_t shapingId)235 uint16_t UIFont::GetWidth(uint32_t unicode, uint16_t fontId, uint8_t fontSize, uint8_t shapingId)
236 {
237     int16_t result;
238 #if ENABLE_MULTI_FONT
239     if (shapingId > 1) {
240         result = instance_->GetWidth(unicode, shapingId, fontSize);
241         if (result >= 0) {
242             return result;
243         }
244     }
245 #endif
246     result = instance_->GetWidth(unicode, fontId, fontSize);
247     if (result >= 0) {
248         return result;
249     }
250 
251 #if ENABLE_MULTI_FONT
252     uint16_t* searchLists = nullptr;
253     int32_t listSize = UIMultiFontManager::GetInstance()->GetSearchFontList(fontId, &searchLists);
254     if ((searchLists == nullptr) || (listSize == 0)) {
255         return 0;
256     }
257     int32_t currentIndex = 0;
258     do {
259         result = instance_->GetWidth(unicode, searchLists[currentIndex], fontSize);
260         if (result >= 0) {
261             return result;
262         }
263         currentIndex++;
264     } while ((currentIndex < listSize) && (searchLists != nullptr));
265 #endif
266     return 0;
267 }
268 
GetLineMaxHeight(const char * text,uint16_t lineLength,uint16_t fontId,uint8_t fontSize,uint16_t letterIndex,SpannableString * spannableString)269 uint16_t UIFont::GetLineMaxHeight(const char* text, uint16_t lineLength, uint16_t fontId, uint8_t fontSize,
270                                   uint16_t letterIndex, SpannableString* spannableString)
271 {
272     return instance_->GetLineMaxHeight(text, lineLength, fontId, fontSize, letterIndex, spannableString);
273 }
274 } // namespace OHOS
275