1a3e0fd82Sopenharmony_ci/*
2a3e0fd82Sopenharmony_ci * Copyright (c) 2020-2022 Huawei Device Co., Ltd.
3a3e0fd82Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License");
4a3e0fd82Sopenharmony_ci * you may not use this file except in compliance with the License.
5a3e0fd82Sopenharmony_ci * You may obtain a copy of the License at
6a3e0fd82Sopenharmony_ci *
7a3e0fd82Sopenharmony_ci *     http://www.apache.org/licenses/LICENSE-2.0
8a3e0fd82Sopenharmony_ci *
9a3e0fd82Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software
10a3e0fd82Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS,
11a3e0fd82Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12a3e0fd82Sopenharmony_ci * See the License for the specific language governing permissions and
13a3e0fd82Sopenharmony_ci * limitations under the License.
14a3e0fd82Sopenharmony_ci */
15a3e0fd82Sopenharmony_ci
16a3e0fd82Sopenharmony_ci#include "font/ui_font.h"
17a3e0fd82Sopenharmony_ci#include "common/text.h"
18a3e0fd82Sopenharmony_ci#include "font/ui_font_cache.h"
19a3e0fd82Sopenharmony_ci#include "font/font_ram_allocator.h"
20a3e0fd82Sopenharmony_ci#if defined(ENABLE_VECTOR_FONT) && ENABLE_VECTOR_FONT
21a3e0fd82Sopenharmony_ci#include "font/ui_font_vector.h"
22a3e0fd82Sopenharmony_ci#endif
23a3e0fd82Sopenharmony_ci#if defined(ENABLE_BITMAP_FONT) && ENABLE_BITMAP_FONT
24a3e0fd82Sopenharmony_ci#include "font/ui_font_bitmap.h"
25a3e0fd82Sopenharmony_ci#endif
26a3e0fd82Sopenharmony_ci#include "graphic_config.h"
27a3e0fd82Sopenharmony_ci#if defined(ENABLE_MULTI_FONT) && ENABLE_MULTI_FONT
28a3e0fd82Sopenharmony_ci#include "font/ui_multi_font_manager.h"
29a3e0fd82Sopenharmony_ci#endif
30a3e0fd82Sopenharmony_ci
31a3e0fd82Sopenharmony_cinamespace OHOS {
32a3e0fd82Sopenharmony_cibool UIFont::setFontAllocFlag_ = false;
33a3e0fd82Sopenharmony_ciUIFont::UIFont() : instance_(nullptr), defaultInstance_(nullptr) {}
34a3e0fd82Sopenharmony_ci
35a3e0fd82Sopenharmony_ciUIFont::~UIFont() {}
36a3e0fd82Sopenharmony_ci
37a3e0fd82Sopenharmony_ciUIFont* UIFont::GetInstance()
38a3e0fd82Sopenharmony_ci{
39a3e0fd82Sopenharmony_ci    static UIFont instance;
40a3e0fd82Sopenharmony_ci#if defined(ENABLE_BITMAP_FONT) && ENABLE_BITMAP_FONT
41a3e0fd82Sopenharmony_ci    if (instance.instance_ == nullptr) {
42a3e0fd82Sopenharmony_ci        instance.defaultInstance_ = new UIFontBitmap();
43a3e0fd82Sopenharmony_ci        instance.instance_ = instance.defaultInstance_;
44a3e0fd82Sopenharmony_ci        setFontAllocFlag_ = true;
45a3e0fd82Sopenharmony_ci    }
46a3e0fd82Sopenharmony_ci#endif
47a3e0fd82Sopenharmony_ci#if defined(ENABLE_VECTOR_FONT) && ENABLE_VECTOR_FONT
48a3e0fd82Sopenharmony_ci    if (instance.instance_ == nullptr) {
49a3e0fd82Sopenharmony_ci        instance.defaultInstance_ = new UIFontVector();
50a3e0fd82Sopenharmony_ci        instance.instance_ = instance.defaultInstance_;
51a3e0fd82Sopenharmony_ci        setFontAllocFlag_ = true;
52a3e0fd82Sopenharmony_ci    }
53a3e0fd82Sopenharmony_ci#endif
54a3e0fd82Sopenharmony_ci    return &instance;
55a3e0fd82Sopenharmony_ci}
56a3e0fd82Sopenharmony_ci
57a3e0fd82Sopenharmony_civoid UIFont::SetFont(BaseFont* font)
58a3e0fd82Sopenharmony_ci{
59a3e0fd82Sopenharmony_ci    if (font != nullptr) {
60a3e0fd82Sopenharmony_ci        if (defaultInstance_ != nullptr && setFontAllocFlag_) {
61a3e0fd82Sopenharmony_ci            delete defaultInstance_;
62a3e0fd82Sopenharmony_ci            defaultInstance_ = nullptr;
63a3e0fd82Sopenharmony_ci            setFontAllocFlag_ = false;
64a3e0fd82Sopenharmony_ci        }
65a3e0fd82Sopenharmony_ci        defaultInstance_ = font;
66a3e0fd82Sopenharmony_ci        instance_ = font;
67a3e0fd82Sopenharmony_ci    }
68a3e0fd82Sopenharmony_ci}
69a3e0fd82Sopenharmony_ci
70a3e0fd82Sopenharmony_ciBaseFont* UIFont::GetFont()
71a3e0fd82Sopenharmony_ci{
72a3e0fd82Sopenharmony_ci    return instance_;
73a3e0fd82Sopenharmony_ci}
74a3e0fd82Sopenharmony_ci
75a3e0fd82Sopenharmony_ci#if (defined(ENABLE_MIX_FONT) && (ENABLE_MIX_FONT == 1))
76a3e0fd82Sopenharmony_civoid UIFont::SetBitmapFont(BaseFont* font)
77a3e0fd82Sopenharmony_ci{
78a3e0fd82Sopenharmony_ci    if (font == nullptr) {
79a3e0fd82Sopenharmony_ci        return;
80a3e0fd82Sopenharmony_ci    }
81a3e0fd82Sopenharmony_ci    GetBitmapInstance()->SetFont(font);
82a3e0fd82Sopenharmony_ci}
83a3e0fd82Sopenharmony_ci
84a3e0fd82Sopenharmony_ciUIFont* UIFont::GetBitmapInstance()
85a3e0fd82Sopenharmony_ci{
86a3e0fd82Sopenharmony_ci    static UIFont instance;
87a3e0fd82Sopenharmony_ci    if (instance.instance_ == nullptr) {
88a3e0fd82Sopenharmony_ci        instance.defaultInstance_ = new UIFontBitmap();
89a3e0fd82Sopenharmony_ci        instance.instance_ = instance.defaultInstance_;
90a3e0fd82Sopenharmony_ci        setFontAllocFlag_ = true;
91a3e0fd82Sopenharmony_ci    }
92a3e0fd82Sopenharmony_ci    return &instance;
93a3e0fd82Sopenharmony_ci}
94a3e0fd82Sopenharmony_ci#endif
95a3e0fd82Sopenharmony_ci
96a3e0fd82Sopenharmony_civoid UIFont::SetFontFileOffset(uint32_t offset)
97a3e0fd82Sopenharmony_ci{
98a3e0fd82Sopenharmony_ci#if (defined(ENABLE_MIX_FONT) && (ENABLE_MIX_FONT == 1))
99a3e0fd82Sopenharmony_ci    GetBitmapInstance()->GetFont()->SetFontFileOffset(offset);
100a3e0fd82Sopenharmony_ci#else
101a3e0fd82Sopenharmony_ci    instance_->SetFontFileOffset(offset);
102a3e0fd82Sopenharmony_ci#endif
103a3e0fd82Sopenharmony_ci}
104a3e0fd82Sopenharmony_ci
105a3e0fd82Sopenharmony_ciint8_t UIFont::SetCurrentLangId(uint8_t langId)
106a3e0fd82Sopenharmony_ci{
107a3e0fd82Sopenharmony_ci#if (defined(ENABLE_MIX_FONT) && (ENABLE_MIX_FONT == 1))
108a3e0fd82Sopenharmony_ci    return GetBitmapInstance()->GetFont()->SetCurrentLangId(langId);
109a3e0fd82Sopenharmony_ci#else
110a3e0fd82Sopenharmony_ci    return instance_->SetCurrentLangId(langId);
111a3e0fd82Sopenharmony_ci#endif
112a3e0fd82Sopenharmony_ci}
113a3e0fd82Sopenharmony_ci
114a3e0fd82Sopenharmony_ciuint8_t UIFont::GetCurrentLangId() const
115a3e0fd82Sopenharmony_ci{
116a3e0fd82Sopenharmony_ci#if (defined(ENABLE_MIX_FONT) && (ENABLE_MIX_FONT == 1))
117a3e0fd82Sopenharmony_ci    return GetBitmapInstance()->GetFont()->GetCurrentLangId();
118a3e0fd82Sopenharmony_ci#else
119a3e0fd82Sopenharmony_ci    return instance_->GetCurrentLangId();
120a3e0fd82Sopenharmony_ci#endif
121a3e0fd82Sopenharmony_ci}
122a3e0fd82Sopenharmony_ci
123a3e0fd82Sopenharmony_ciint8_t  UIFont::SetFontPath(const char* path, BaseFont::FontType type)
124a3e0fd82Sopenharmony_ci{
125a3e0fd82Sopenharmony_ci#if (defined(ENABLE_MIX_FONT) && (ENABLE_MIX_FONT == 1))
126a3e0fd82Sopenharmony_ci    if (type == BaseFont::FontType::VECTOR_FONT) {
127a3e0fd82Sopenharmony_ci        return instance_->SetFontPath(path, type);
128a3e0fd82Sopenharmony_ci    }
129a3e0fd82Sopenharmony_ci    return GetBitmapInstance()->GetFont()->SetFontPath(path, type);
130a3e0fd82Sopenharmony_ci#else
131a3e0fd82Sopenharmony_ci    return instance_->SetFontPath(path, type);
132a3e0fd82Sopenharmony_ci#endif
133a3e0fd82Sopenharmony_ci}
134a3e0fd82Sopenharmony_ci
135a3e0fd82Sopenharmony_ciint8_t UIFont::GetTextUtf8(uint16_t textId, uint8_t** utf8Addr, uint16_t& utf8Len) const
136a3e0fd82Sopenharmony_ci{
137a3e0fd82Sopenharmony_ci#if (defined(ENABLE_MIX_FONT) && (ENABLE_MIX_FONT == 1))
138a3e0fd82Sopenharmony_ci    return GetBitmapInstance()->GetFont()->GetTextUtf8(textId, utf8Addr, utf8Len);
139a3e0fd82Sopenharmony_ci#else
140a3e0fd82Sopenharmony_ci    return instance_->GetTextUtf8(textId, utf8Addr, utf8Len);
141a3e0fd82Sopenharmony_ci#endif
142a3e0fd82Sopenharmony_ci}
143a3e0fd82Sopenharmony_ci
144a3e0fd82Sopenharmony_ciint8_t UIFont::GetTextParam(uint16_t textId, UITextLanguageTextParam& param) const
145a3e0fd82Sopenharmony_ci{
146a3e0fd82Sopenharmony_ci#if (defined(ENABLE_MIX_FONT) && (ENABLE_MIX_FONT == 1))
147a3e0fd82Sopenharmony_ci    return GetBitmapInstance()->GetFont()->GetTextParam(textId, param);
148a3e0fd82Sopenharmony_ci#else
149a3e0fd82Sopenharmony_ci    return instance_->GetTextParam(textId, param);
150a3e0fd82Sopenharmony_ci#endif
151a3e0fd82Sopenharmony_ci}
152a3e0fd82Sopenharmony_ci
153a3e0fd82Sopenharmony_ciint8_t UIFont::GetWildCardStaticStr(uint16_t textId,
154a3e0fd82Sopenharmony_ci                                    UITextWildcardStaticType type,
155a3e0fd82Sopenharmony_ci                                    uint8_t** strAddr,
156a3e0fd82Sopenharmony_ci                                    uint16_t& strLen) const
157a3e0fd82Sopenharmony_ci{
158a3e0fd82Sopenharmony_ci#if (defined(ENABLE_MIX_FONT) && (ENABLE_MIX_FONT == 1))
159a3e0fd82Sopenharmony_ci    return GetBitmapInstance()->GetFont()->GetWildCardStaticStr(textId, type, strAddr, strLen);
160a3e0fd82Sopenharmony_ci#else
161a3e0fd82Sopenharmony_ci    return instance_->GetWildCardStaticStr(textId, type, strAddr, strLen);
162a3e0fd82Sopenharmony_ci#endif
163a3e0fd82Sopenharmony_ci}
164a3e0fd82Sopenharmony_ci
165a3e0fd82Sopenharmony_ciint8_t UIFont::GetCodePoints(uint16_t textId, uint32_t** codePoints, uint16_t& codePointsNum) const
166a3e0fd82Sopenharmony_ci{
167a3e0fd82Sopenharmony_ci#if (defined(ENABLE_MIX_FONT) && (ENABLE_MIX_FONT == 1))
168a3e0fd82Sopenharmony_ci    return GetBitmapInstance()->GetFont()->GetCodePoints(textId, codePoints, codePointsNum);
169a3e0fd82Sopenharmony_ci#else
170a3e0fd82Sopenharmony_ci    return instance_->GetCodePoints(textId, codePoints, codePointsNum);
171a3e0fd82Sopenharmony_ci#endif
172a3e0fd82Sopenharmony_ci}
173a3e0fd82Sopenharmony_ci
174a3e0fd82Sopenharmony_ciuint8_t* UIFont::GetBitmap(uint32_t unicode, GlyphNode& glyphNode, uint16_t fontId, uint8_t fontSize,
175a3e0fd82Sopenharmony_ci                           uint8_t shapingFont)
176a3e0fd82Sopenharmony_ci{
177a3e0fd82Sopenharmony_ci    uint8_t* bitmap = nullptr;
178a3e0fd82Sopenharmony_ci#if ENABLE_MULTI_FONT
179a3e0fd82Sopenharmony_ci    // shaping font is in search list, search shaping font first
180a3e0fd82Sopenharmony_ci    if (shapingFont > 1) {
181a3e0fd82Sopenharmony_ci        bitmap = instance_->GetBitmap(unicode, glyphNode, shapingFont, fontSize);
182a3e0fd82Sopenharmony_ci        if (bitmap != nullptr) {
183a3e0fd82Sopenharmony_ci            return bitmap;
184a3e0fd82Sopenharmony_ci        }
185a3e0fd82Sopenharmony_ci    }
186a3e0fd82Sopenharmony_ci#endif
187a3e0fd82Sopenharmony_ci    bitmap = instance_->GetBitmap(unicode, glyphNode, fontId, fontSize);
188a3e0fd82Sopenharmony_ci    if (bitmap != nullptr) {
189a3e0fd82Sopenharmony_ci        return bitmap;
190a3e0fd82Sopenharmony_ci    }
191a3e0fd82Sopenharmony_ci#if ENABLE_MULTI_FONT
192a3e0fd82Sopenharmony_ci    uint16_t* searchLists = nullptr;
193a3e0fd82Sopenharmony_ci    int32_t listSize = UIMultiFontManager::GetInstance()->GetSearchFontList(fontId, &searchLists);
194a3e0fd82Sopenharmony_ci    int32_t currentIndex = 0;
195a3e0fd82Sopenharmony_ci    if ((searchLists == nullptr) || (listSize == 0)) {
196a3e0fd82Sopenharmony_ci        return nullptr;
197a3e0fd82Sopenharmony_ci    }
198a3e0fd82Sopenharmony_ci    do {
199a3e0fd82Sopenharmony_ci        bitmap = instance_->GetBitmap(unicode, glyphNode, searchLists[currentIndex], fontSize);
200a3e0fd82Sopenharmony_ci        if (bitmap != nullptr) {
201a3e0fd82Sopenharmony_ci            return bitmap;
202a3e0fd82Sopenharmony_ci        }
203a3e0fd82Sopenharmony_ci        // switch to next search List
204a3e0fd82Sopenharmony_ci        currentIndex++;
205a3e0fd82Sopenharmony_ci    } while ((currentIndex < listSize) && (searchLists != nullptr));
206a3e0fd82Sopenharmony_ci#endif
207a3e0fd82Sopenharmony_ci    return nullptr;
208a3e0fd82Sopenharmony_ci}
209a3e0fd82Sopenharmony_ci
210a3e0fd82Sopenharmony_ciint8_t UIFont::GetGlyphNode(uint32_t unicode, GlyphNode& glyphNode, uint16_t fontId, uint8_t fontSize)
211a3e0fd82Sopenharmony_ci{
212a3e0fd82Sopenharmony_ci    int8_t result = instance_->GetGlyphNode(unicode, glyphNode, fontId, fontSize);
213a3e0fd82Sopenharmony_ci    if (result == RET_VALUE_OK) {
214a3e0fd82Sopenharmony_ci        return result;
215a3e0fd82Sopenharmony_ci    }
216a3e0fd82Sopenharmony_ci
217a3e0fd82Sopenharmony_ci#if defined(ENABLE_MULTI_FONT) && ENABLE_MULTI_FONT
218a3e0fd82Sopenharmony_ci    uint16_t* searchLists = nullptr;
219a3e0fd82Sopenharmony_ci    int32_t listSize = UIMultiFontManager::GetInstance()->GetSearchFontList(fontId, &searchLists);
220a3e0fd82Sopenharmony_ci    if ((searchLists == nullptr) || (listSize == 0)) {
221a3e0fd82Sopenharmony_ci        return INVALID_RET_VALUE;
222a3e0fd82Sopenharmony_ci    }
223a3e0fd82Sopenharmony_ci    int32_t currentIndex = 0;
224a3e0fd82Sopenharmony_ci    do {
225a3e0fd82Sopenharmony_ci        result = instance_->GetGlyphNode(unicode, glyphNode, searchLists[currentIndex], fontSize);
226a3e0fd82Sopenharmony_ci        if (result == RET_VALUE_OK) {
227a3e0fd82Sopenharmony_ci            return result;
228a3e0fd82Sopenharmony_ci        }
229a3e0fd82Sopenharmony_ci        currentIndex++;
230a3e0fd82Sopenharmony_ci    } while ((currentIndex < listSize) && (searchLists != nullptr));
231a3e0fd82Sopenharmony_ci#endif
232a3e0fd82Sopenharmony_ci    return INVALID_RET_VALUE;
233a3e0fd82Sopenharmony_ci}
234a3e0fd82Sopenharmony_ci
235a3e0fd82Sopenharmony_ciuint16_t UIFont::GetWidth(uint32_t unicode, uint16_t fontId, uint8_t fontSize, uint8_t shapingId)
236a3e0fd82Sopenharmony_ci{
237a3e0fd82Sopenharmony_ci    int16_t result;
238a3e0fd82Sopenharmony_ci#if ENABLE_MULTI_FONT
239a3e0fd82Sopenharmony_ci    if (shapingId > 1) {
240a3e0fd82Sopenharmony_ci        result = instance_->GetWidth(unicode, shapingId, fontSize);
241a3e0fd82Sopenharmony_ci        if (result >= 0) {
242a3e0fd82Sopenharmony_ci            return result;
243a3e0fd82Sopenharmony_ci        }
244a3e0fd82Sopenharmony_ci    }
245a3e0fd82Sopenharmony_ci#endif
246a3e0fd82Sopenharmony_ci    result = instance_->GetWidth(unicode, fontId, fontSize);
247a3e0fd82Sopenharmony_ci    if (result >= 0) {
248a3e0fd82Sopenharmony_ci        return result;
249a3e0fd82Sopenharmony_ci    }
250a3e0fd82Sopenharmony_ci
251a3e0fd82Sopenharmony_ci#if ENABLE_MULTI_FONT
252a3e0fd82Sopenharmony_ci    uint16_t* searchLists = nullptr;
253a3e0fd82Sopenharmony_ci    int32_t listSize = UIMultiFontManager::GetInstance()->GetSearchFontList(fontId, &searchLists);
254a3e0fd82Sopenharmony_ci    if ((searchLists == nullptr) || (listSize == 0)) {
255a3e0fd82Sopenharmony_ci        return 0;
256a3e0fd82Sopenharmony_ci    }
257a3e0fd82Sopenharmony_ci    int32_t currentIndex = 0;
258a3e0fd82Sopenharmony_ci    do {
259a3e0fd82Sopenharmony_ci        result = instance_->GetWidth(unicode, searchLists[currentIndex], fontSize);
260a3e0fd82Sopenharmony_ci        if (result >= 0) {
261a3e0fd82Sopenharmony_ci            return result;
262a3e0fd82Sopenharmony_ci        }
263a3e0fd82Sopenharmony_ci        currentIndex++;
264a3e0fd82Sopenharmony_ci    } while ((currentIndex < listSize) && (searchLists != nullptr));
265a3e0fd82Sopenharmony_ci#endif
266a3e0fd82Sopenharmony_ci    return 0;
267a3e0fd82Sopenharmony_ci}
268a3e0fd82Sopenharmony_ci
269a3e0fd82Sopenharmony_ciuint16_t UIFont::GetLineMaxHeight(const char* text, uint16_t lineLength, uint16_t fontId, uint8_t fontSize,
270a3e0fd82Sopenharmony_ci                                  uint16_t letterIndex, SpannableString* spannableString)
271a3e0fd82Sopenharmony_ci{
272a3e0fd82Sopenharmony_ci    return instance_->GetLineMaxHeight(text, lineLength, fontId, fontSize, letterIndex, spannableString);
273a3e0fd82Sopenharmony_ci}
274a3e0fd82Sopenharmony_ci} // namespace OHOS
275