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_bitmap.h"
17a3e0fd82Sopenharmony_ci
18a3e0fd82Sopenharmony_ci#include "draw/draw_utils.h"
19a3e0fd82Sopenharmony_ci#include "font/font_ram_allocator.h"
20a3e0fd82Sopenharmony_ci#include "font/ui_font.h"
21a3e0fd82Sopenharmony_ci#include "font/ui_font_adaptor.h"
22a3e0fd82Sopenharmony_ci#include "font/ui_font_builder.h"
23a3e0fd82Sopenharmony_ci#include "gfx_utils/file.h"
24a3e0fd82Sopenharmony_ci#include "gfx_utils/graphic_log.h"
25a3e0fd82Sopenharmony_ci#include "graphic_config.h"
26a3e0fd82Sopenharmony_ci#if defined(ENABLE_MULTI_FONT) && ENABLE_MULTI_FONT
27a3e0fd82Sopenharmony_ci#include "font/ui_multi_font_manager.h"
28a3e0fd82Sopenharmony_ci#endif
29a3e0fd82Sopenharmony_ci#if defined(ENABLE_SHAPING) && ENABLE_SHAPING
30a3e0fd82Sopenharmony_ci#include "font/ui_text_shaping.h"
31a3e0fd82Sopenharmony_ci#endif
32a3e0fd82Sopenharmony_ci#include "font/ui_font_cache_manager.h"
33a3e0fd82Sopenharmony_ci
34a3e0fd82Sopenharmony_cinamespace OHOS {
35a3e0fd82Sopenharmony_ciUIFontBitmap::UIFontBitmap() : offset_(0), dynamicFont_() {}
36a3e0fd82Sopenharmony_ci
37a3e0fd82Sopenharmony_ciUIFontBitmap::~UIFontBitmap()
38a3e0fd82Sopenharmony_ci{
39a3e0fd82Sopenharmony_ci    CloseFontFd();
40a3e0fd82Sopenharmony_ci}
41a3e0fd82Sopenharmony_ci
42a3e0fd82Sopenharmony_civoid UIFontBitmap::CloseFontFd()
43a3e0fd82Sopenharmony_ci{
44a3e0fd82Sopenharmony_ci    for (uint16_t i = 0; i < dynamicFontFd_.Size(); i++) {
45a3e0fd82Sopenharmony_ci        if (dynamicFontFd_[i] >= 0) {
46a3e0fd82Sopenharmony_ci            close(dynamicFontFd_[i]);
47a3e0fd82Sopenharmony_ci            dynamicFontFd_[i] = -1;
48a3e0fd82Sopenharmony_ci        }
49a3e0fd82Sopenharmony_ci    }
50a3e0fd82Sopenharmony_ci}
51a3e0fd82Sopenharmony_ci
52a3e0fd82Sopenharmony_cibool UIFontBitmap::IsVectorFont() const
53a3e0fd82Sopenharmony_ci{
54a3e0fd82Sopenharmony_ci    return false;
55a3e0fd82Sopenharmony_ci}
56a3e0fd82Sopenharmony_ci
57a3e0fd82Sopenharmony_ciuint16_t
58a3e0fd82Sopenharmony_ci    UIFontBitmap::GetShapingFontId(char* text, uint8_t& ttfId, uint32_t& script, uint16_t fontId, uint8_t size) const
59a3e0fd82Sopenharmony_ci{
60a3e0fd82Sopenharmony_ci#if defined(ENABLE_MULTI_FONT) && ENABLE_MULTI_FONT
61a3e0fd82Sopenharmony_ci    return UIMultiFontManager::GetInstance()->GetShapingFontId(text, fontId, ttfId, script);
62a3e0fd82Sopenharmony_ci#else
63a3e0fd82Sopenharmony_ci    UITextLanguageFontParam* fontParam = UIFontBuilder::GetInstance()->GetTextLangFontsTable(fontId);
64a3e0fd82Sopenharmony_ci    if (fontParam == nullptr) {
65a3e0fd82Sopenharmony_ci        return 0;
66a3e0fd82Sopenharmony_ci    }
67a3e0fd82Sopenharmony_ci    ttfId = fontParam->ttfId;
68a3e0fd82Sopenharmony_ci    return fontParam->shaping;
69a3e0fd82Sopenharmony_ci#endif
70a3e0fd82Sopenharmony_ci}
71a3e0fd82Sopenharmony_ci
72a3e0fd82Sopenharmony_ciuint8_t UIFontBitmap::GetFontWeight(uint16_t fontId)
73a3e0fd82Sopenharmony_ci{
74a3e0fd82Sopenharmony_ci    UITextLanguageFontParam* fontParam = UIFontBuilder::GetInstance()->GetTextLangFontsTable(fontId);
75a3e0fd82Sopenharmony_ci    if (fontParam == nullptr) {
76a3e0fd82Sopenharmony_ci        GRAPHIC_LOGE("UIFontBitmap::GetFontWeigh invalid fontId");
77a3e0fd82Sopenharmony_ci        return 0;
78a3e0fd82Sopenharmony_ci    }
79a3e0fd82Sopenharmony_ci    return fontParam->fontWeight;
80a3e0fd82Sopenharmony_ci}
81a3e0fd82Sopenharmony_ci
82a3e0fd82Sopenharmony_ciint8_t UIFontBitmap::SetFontPath(const char* path, FontType type)
83a3e0fd82Sopenharmony_ci{
84a3e0fd82Sopenharmony_ci    if ((path == nullptr) || (type != DYNAMIC_FONT)) {
85a3e0fd82Sopenharmony_ci        GRAPHIC_LOGE("UIFontBitmap::SetFontPath invalid parameter");
86a3e0fd82Sopenharmony_ci        return INVALID_RET_VALUE;
87a3e0fd82Sopenharmony_ci    }
88a3e0fd82Sopenharmony_ci#ifdef _WIN32
89a3e0fd82Sopenharmony_ci    int32_t fontFd = open(path, O_RDONLY | O_BINARY);
90a3e0fd82Sopenharmony_ci#else
91a3e0fd82Sopenharmony_ci    int32_t fontFd = open(path, O_RDONLY);
92a3e0fd82Sopenharmony_ci#endif
93a3e0fd82Sopenharmony_ci    if (fontFd < 0) {
94a3e0fd82Sopenharmony_ci        GRAPHIC_LOGE("UIFontBitmap::SetFontPath file Open failed");
95a3e0fd82Sopenharmony_ci        return INVALID_RET_VALUE;
96a3e0fd82Sopenharmony_ci    }
97a3e0fd82Sopenharmony_ci
98a3e0fd82Sopenharmony_ci    int32_t ret = dynamicFont_.SetFile(path, fontFd, offset_, GlyphCacheType::CACHE_TYPE_DYNAMIC);
99a3e0fd82Sopenharmony_ci    if (ret == INVALID_RET_VALUE) {
100a3e0fd82Sopenharmony_ci        GRAPHIC_LOGE("GlyphsManager::SetFile failed");
101a3e0fd82Sopenharmony_ci        close(fontFd);
102a3e0fd82Sopenharmony_ci        return ret;
103a3e0fd82Sopenharmony_ci    }
104a3e0fd82Sopenharmony_ci    dynamicFontFd_.PushBack(fontFd);
105a3e0fd82Sopenharmony_ci    return RET_VALUE_OK;
106a3e0fd82Sopenharmony_ci}
107a3e0fd82Sopenharmony_ci
108a3e0fd82Sopenharmony_ciuint16_t UIFontBitmap::GetHeight(uint16_t fontId, uint8_t fontSize)
109a3e0fd82Sopenharmony_ci{
110a3e0fd82Sopenharmony_ci    return dynamicFont_.GetFontHeight(fontId);
111a3e0fd82Sopenharmony_ci}
112a3e0fd82Sopenharmony_ci
113a3e0fd82Sopenharmony_ciuint16_t UIFontBitmap::GetFontId(const char* ttfName, uint8_t size) const
114a3e0fd82Sopenharmony_ci{
115a3e0fd82Sopenharmony_ci    UIFontBuilder* fontBuilder = UIFontBuilder::GetInstance();
116a3e0fd82Sopenharmony_ci    if (ttfName == nullptr) {
117a3e0fd82Sopenharmony_ci        return fontBuilder->GetBitmapFontIdMax();
118a3e0fd82Sopenharmony_ci    }
119a3e0fd82Sopenharmony_ci    uint16_t id;
120a3e0fd82Sopenharmony_ci    for (id = 0; id < fontBuilder->GetBitmapFontIdMax(); ++id) {
121a3e0fd82Sopenharmony_ci        UITextLanguageFontParam* fontParam = fontBuilder->GetTextLangFontsTable(id);
122a3e0fd82Sopenharmony_ci        if (fontParam != nullptr) {
123a3e0fd82Sopenharmony_ci            if ((fontParam->size == size) && (strncmp(fontParam->ttfName, ttfName, TTF_NAME_LEN_MAX) == 0)) {
124a3e0fd82Sopenharmony_ci                break;
125a3e0fd82Sopenharmony_ci            }
126a3e0fd82Sopenharmony_ci        }
127a3e0fd82Sopenharmony_ci    }
128a3e0fd82Sopenharmony_ci    return id;
129a3e0fd82Sopenharmony_ci}
130a3e0fd82Sopenharmony_ci
131a3e0fd82Sopenharmony_ciint16_t UIFontBitmap::GetWidth(uint32_t unicode, uint16_t fontId, uint8_t fontSize)
132a3e0fd82Sopenharmony_ci{
133a3e0fd82Sopenharmony_ci    return GetWidthInFontId(unicode, fontId);
134a3e0fd82Sopenharmony_ci}
135a3e0fd82Sopenharmony_ci
136a3e0fd82Sopenharmony_ciuint8_t* UIFontBitmap::GetBitmap(uint32_t unicode, GlyphNode& glyphNode, uint16_t fontId, uint8_t fontSize)
137a3e0fd82Sopenharmony_ci{
138a3e0fd82Sopenharmony_ci    return SearchInFont(unicode, glyphNode, fontId);
139a3e0fd82Sopenharmony_ci}
140a3e0fd82Sopenharmony_ci
141a3e0fd82Sopenharmony_cibool UIFontBitmap::IsEmojiFont(uint16_t fontId)
142a3e0fd82Sopenharmony_ci{
143a3e0fd82Sopenharmony_ci    return false;
144a3e0fd82Sopenharmony_ci}
145a3e0fd82Sopenharmony_ci
146a3e0fd82Sopenharmony_ciint8_t UIFontBitmap::GetFontHeader(FontHeader& fontHeader, uint16_t fontId, uint8_t fontSize)
147a3e0fd82Sopenharmony_ci{
148a3e0fd82Sopenharmony_ci    const FontHeader* header = dynamicFont_.GetFontHeader(fontId);
149a3e0fd82Sopenharmony_ci    if (header != nullptr) {
150a3e0fd82Sopenharmony_ci        fontHeader = *header;
151a3e0fd82Sopenharmony_ci        return RET_VALUE_OK;
152a3e0fd82Sopenharmony_ci    }
153a3e0fd82Sopenharmony_ci    return INVALID_RET_VALUE;
154a3e0fd82Sopenharmony_ci}
155a3e0fd82Sopenharmony_ci
156a3e0fd82Sopenharmony_ci#if defined(ENABLE_MULTI_FONT) && ENABLE_MULTI_FONT
157a3e0fd82Sopenharmony_ciint8_t UIFontBitmap::GetMultiGlyphNode(uint32_t unicode, GlyphNode& glyphNode, uint16_t fontId)
158a3e0fd82Sopenharmony_ci{
159a3e0fd82Sopenharmony_ci    int8_t ret = GetGlyphNode(unicode, glyphNode, fontId);
160a3e0fd82Sopenharmony_ci    if (ret == RET_VALUE_OK) {
161a3e0fd82Sopenharmony_ci        return ret;
162a3e0fd82Sopenharmony_ci    }
163a3e0fd82Sopenharmony_ci
164a3e0fd82Sopenharmony_ci    uint16_t* searchLists = nullptr;
165a3e0fd82Sopenharmony_ci    int8_t listSize = UIMultiFontManager::GetInstance()->GetSearchFontList(fontId, &searchLists);
166a3e0fd82Sopenharmony_ci    int8_t currentIndex = 0;
167a3e0fd82Sopenharmony_ci    if ((searchLists == nullptr) || (listSize == 0)) {
168a3e0fd82Sopenharmony_ci        return INVALID_RET_VALUE;
169a3e0fd82Sopenharmony_ci    }
170a3e0fd82Sopenharmony_ci    do {
171a3e0fd82Sopenharmony_ci        ret = GetGlyphNode(unicode, glyphNode, searchLists[currentIndex]);
172a3e0fd82Sopenharmony_ci        if (ret != INVALID_RET_VALUE) {
173a3e0fd82Sopenharmony_ci            return ret;
174a3e0fd82Sopenharmony_ci        }
175a3e0fd82Sopenharmony_ci        // switch to next search List
176a3e0fd82Sopenharmony_ci        currentIndex++;
177a3e0fd82Sopenharmony_ci    } while ((currentIndex < listSize) && (searchLists != nullptr));
178a3e0fd82Sopenharmony_ci    return INVALID_RET_VALUE;
179a3e0fd82Sopenharmony_ci}
180a3e0fd82Sopenharmony_ci#endif
181a3e0fd82Sopenharmony_ci
182a3e0fd82Sopenharmony_ciint8_t UIFontBitmap::GetGlyphNode(uint32_t unicode, GlyphNode& glyphNode, uint16_t fontId, uint8_t fontSize)
183a3e0fd82Sopenharmony_ci{
184a3e0fd82Sopenharmony_ci    const GlyphNode* node = dynamicFont_.GetGlyphNode(unicode, fontId);
185a3e0fd82Sopenharmony_ci    if (node != nullptr) {
186a3e0fd82Sopenharmony_ci        glyphNode = *node;
187a3e0fd82Sopenharmony_ci        return RET_VALUE_OK;
188a3e0fd82Sopenharmony_ci    }
189a3e0fd82Sopenharmony_ci    GRAPHIC_LOGE("UIFontBitmap::GetGlyphNode get glyphNode failed");
190a3e0fd82Sopenharmony_ci    return INVALID_RET_VALUE;
191a3e0fd82Sopenharmony_ci}
192a3e0fd82Sopenharmony_ci
193a3e0fd82Sopenharmony_ciint8_t UIFontBitmap::GetGlyphNodeFromFile(uint32_t unicode, GlyphNode& glyphNode, uint16_t fontId)
194a3e0fd82Sopenharmony_ci{
195a3e0fd82Sopenharmony_ci    const GlyphNode* node = dynamicFont_.GetGlyphNodeFromFiles(unicode, fontId);
196a3e0fd82Sopenharmony_ci    if (node != nullptr) {
197a3e0fd82Sopenharmony_ci        glyphNode = *node;
198a3e0fd82Sopenharmony_ci        return RET_VALUE_OK;
199a3e0fd82Sopenharmony_ci    }
200a3e0fd82Sopenharmony_ci    return INVALID_RET_VALUE;
201a3e0fd82Sopenharmony_ci}
202a3e0fd82Sopenharmony_ci
203a3e0fd82Sopenharmony_ciint8_t UIFontBitmap::GetFontVersion(FontType type, const char* path, char* version, uint8_t len)
204a3e0fd82Sopenharmony_ci{
205a3e0fd82Sopenharmony_ci    if (type != DYNAMIC_FONT) {
206a3e0fd82Sopenharmony_ci        return INVALID_RET_VALUE;
207a3e0fd82Sopenharmony_ci    }
208a3e0fd82Sopenharmony_ci    return dynamicFont_.GetFontVersion(path, version, len);
209a3e0fd82Sopenharmony_ci}
210a3e0fd82Sopenharmony_ci
211a3e0fd82Sopenharmony_ciint8_t UIFontBitmap::SetCurrentLangId(uint8_t langId)
212a3e0fd82Sopenharmony_ci{
213a3e0fd82Sopenharmony_ci    GRAPHIC_LOGE("UIFontBitmap::SetCurrentLangId start");
214a3e0fd82Sopenharmony_ci    UIFontCacheManager* fontCacheManager = UIFontCacheManager::GetInstance();
215a3e0fd82Sopenharmony_ci
216a3e0fd82Sopenharmony_ci    if (fontCacheManager->GlyphsCacheInit() != RET_VALUE_OK) {
217a3e0fd82Sopenharmony_ci        GRAPHIC_LOGE("UIFontCacheManager::GlyphsCacheInit init failed");
218a3e0fd82Sopenharmony_ci        return INVALID_RET_VALUE;
219a3e0fd82Sopenharmony_ci    }
220a3e0fd82Sopenharmony_ci
221a3e0fd82Sopenharmony_ci    fontCacheManager->BitmapCacheInit();
222a3e0fd82Sopenharmony_ci    return RET_VALUE_OK;
223a3e0fd82Sopenharmony_ci}
224a3e0fd82Sopenharmony_ci
225a3e0fd82Sopenharmony_ciUITextLanguageFontParam* UIFontBitmap::GetFontInfo(uint16_t fontId) const
226a3e0fd82Sopenharmony_ci{
227a3e0fd82Sopenharmony_ci    return UIFontBuilder::GetInstance()->GetTextLangFontsTable(fontId);
228a3e0fd82Sopenharmony_ci}
229a3e0fd82Sopenharmony_ci
230a3e0fd82Sopenharmony_ciint8_t UIFontBitmap::GetDynamicFontBitmap(uint32_t unicode, BufferInfo& bufInfo, uint16_t fontId)
231a3e0fd82Sopenharmony_ci{
232a3e0fd82Sopenharmony_ci    return dynamicFont_.GetBitmap(unicode, bufInfo, fontId);
233a3e0fd82Sopenharmony_ci}
234a3e0fd82Sopenharmony_ci
235a3e0fd82Sopenharmony_ciuint8_t* UIFontBitmap::GetCacheBitmap(uint16_t fontId, uint32_t unicode)
236a3e0fd82Sopenharmony_ci{
237a3e0fd82Sopenharmony_ci    TextStyle textStyle = TEXT_STYLE_NORMAL;
238a3e0fd82Sopenharmony_ci    return UIFontCacheManager::GetInstance()->GetBitmap(fontId, unicode, textStyle);
239a3e0fd82Sopenharmony_ci}
240a3e0fd82Sopenharmony_ci
241a3e0fd82Sopenharmony_civoid UIFontBitmap::PutCacheSpace(uint8_t* addr)
242a3e0fd82Sopenharmony_ci{
243a3e0fd82Sopenharmony_ci    UIFontCacheManager::GetInstance()->PutSpace(addr);
244a3e0fd82Sopenharmony_ci}
245a3e0fd82Sopenharmony_ci
246a3e0fd82Sopenharmony_ciint16_t UIFontBitmap::GetDynamicFontWidth(uint32_t unicode, uint16_t fontId)
247a3e0fd82Sopenharmony_ci{
248a3e0fd82Sopenharmony_ci    return dynamicFont_.GetFontWidth(unicode, fontId);
249a3e0fd82Sopenharmony_ci}
250a3e0fd82Sopenharmony_ci
251a3e0fd82Sopenharmony_ciuint8_t* UIFontBitmap::SearchInFont(uint32_t unicode, GlyphNode& glyphNode, uint16_t fontId)
252a3e0fd82Sopenharmony_ci{
253a3e0fd82Sopenharmony_ci    GraphicLockGuard guard(lock_);
254a3e0fd82Sopenharmony_ci    UIFontCacheManager* fontCacheManager =  UIFontCacheManager::GetInstance();
255a3e0fd82Sopenharmony_ci    if (fontCacheManager->GetBitmapCache() == nullptr) {
256a3e0fd82Sopenharmony_ci        return nullptr;
257a3e0fd82Sopenharmony_ci    }
258a3e0fd82Sopenharmony_ci    if (!UIFontAdaptor::IsSameTTFId(fontId, unicode)) {
259a3e0fd82Sopenharmony_ci        GRAPHIC_LOGE("UIFontBitmap::SearchInFont fontId and unicode not match");
260a3e0fd82Sopenharmony_ci        return nullptr;
261a3e0fd82Sopenharmony_ci    }
262a3e0fd82Sopenharmony_ci    int8_t ret = GetGlyphNode(unicode, glyphNode, fontId);
263a3e0fd82Sopenharmony_ci    if (ret != RET_VALUE_OK) {
264a3e0fd82Sopenharmony_ci        return nullptr;
265a3e0fd82Sopenharmony_ci    }
266a3e0fd82Sopenharmony_ci    TextStyle textStyle = TEXT_STYLE_NORMAL;
267a3e0fd82Sopenharmony_ci    uint8_t* bitmap = fontCacheManager->GetBitmap(fontId, unicode, textStyle);
268a3e0fd82Sopenharmony_ci    if (bitmap != nullptr) {
269a3e0fd82Sopenharmony_ci        if (glyphNode.dataFlag == glyphNode.fontId && fontId == glyphNode.fontId) {
270a3e0fd82Sopenharmony_ci            return bitmap;
271a3e0fd82Sopenharmony_ci        } else {
272a3e0fd82Sopenharmony_ci            GRAPHIC_LOGE("DataFlag of bitmap node not equal to fontId.");
273a3e0fd82Sopenharmony_ci        }
274a3e0fd82Sopenharmony_ci    }
275a3e0fd82Sopenharmony_ci    if (glyphNode.kernOff <= glyphNode.dataOff) {
276a3e0fd82Sopenharmony_ci        return nullptr;
277a3e0fd82Sopenharmony_ci    }
278a3e0fd82Sopenharmony_ci    ColorMode mode = UIFont::GetInstance()->GetColorType(fontId);
279a3e0fd82Sopenharmony_ci    BufferInfo bufInfo = UIFontAllocator::GetCacheBuffer(fontId, unicode, mode, glyphNode, false, textStyle);
280a3e0fd82Sopenharmony_ci    ret = dynamicFont_.GetBitmap(unicode, bufInfo, fontId);
281a3e0fd82Sopenharmony_ci    if (ret == RET_VALUE_OK) {
282a3e0fd82Sopenharmony_ci        return reinterpret_cast<uint8_t*>(bufInfo.virAddr);
283a3e0fd82Sopenharmony_ci    }
284a3e0fd82Sopenharmony_ci    PutCacheSpace(reinterpret_cast<uint8_t*>(bufInfo.virAddr));
285a3e0fd82Sopenharmony_ci    return nullptr;
286a3e0fd82Sopenharmony_ci}
287a3e0fd82Sopenharmony_ci
288a3e0fd82Sopenharmony_ciint16_t UIFontBitmap::GetWidthInFontId(uint32_t unicode, uint16_t fontId)
289a3e0fd82Sopenharmony_ci{
290a3e0fd82Sopenharmony_ci    if (!UIFontAdaptor::IsSameTTFId(fontId, unicode)) {
291a3e0fd82Sopenharmony_ci        GRAPHIC_LOGE("UIFontBitmap::GetWidthInFontId fontId and unicode not match");
292a3e0fd82Sopenharmony_ci        return INVALID_RET_VALUE;
293a3e0fd82Sopenharmony_ci    }
294a3e0fd82Sopenharmony_ci    return GetDynamicFontWidth(unicode, fontId);
295a3e0fd82Sopenharmony_ci}
296a3e0fd82Sopenharmony_ci
297a3e0fd82Sopenharmony_civoid UIFontBitmap::SetFontFileOffset(uint32_t offset)
298a3e0fd82Sopenharmony_ci{
299a3e0fd82Sopenharmony_ci    offset_ = offset;
300a3e0fd82Sopenharmony_ci}
301a3e0fd82Sopenharmony_ci
302a3e0fd82Sopenharmony_ciuint16_t UIFontBitmap::GetOffsetPosY(const char* text,
303a3e0fd82Sopenharmony_ci                                     uint16_t lineLength,
304a3e0fd82Sopenharmony_ci                                     bool& isEmoijLarge,
305a3e0fd82Sopenharmony_ci                                     uint16_t fontId,
306a3e0fd82Sopenharmony_ci                                     uint8_t fontSize)
307a3e0fd82Sopenharmony_ci{
308a3e0fd82Sopenharmony_ci    uint32_t i = 0;
309a3e0fd82Sopenharmony_ci    uint16_t textNum = 0;
310a3e0fd82Sopenharmony_ci    uint16_t emojiNum = 0;
311a3e0fd82Sopenharmony_ci
312a3e0fd82Sopenharmony_ci    uint16_t loopNum = 0;
313a3e0fd82Sopenharmony_ci    GlyphNode glyphNode;
314a3e0fd82Sopenharmony_ci    GlyphNode emoijMaxNode = {};
315a3e0fd82Sopenharmony_ci    uint8_t maxFontSie = fontSize;
316a3e0fd82Sopenharmony_ci    while (i < lineLength) {
317a3e0fd82Sopenharmony_ci        uint32_t unicode = TypedText::GetUTF8Next(text, i, i);
318a3e0fd82Sopenharmony_ci#if defined(ENABLE_MULTI_FONT) && ENABLE_MULTI_FONT
319a3e0fd82Sopenharmony_ci        uint8_t ret = GetMultiGlyphNode(unicode, glyphNode, fontId);
320a3e0fd82Sopenharmony_ci#else
321a3e0fd82Sopenharmony_ci        uint8_t ret = GetGlyphNode(unicode, glyphNode, fontId, fontSize);
322a3e0fd82Sopenharmony_ci#endif
323a3e0fd82Sopenharmony_ci        if (ret == RET_VALUE_OK) {
324a3e0fd82Sopenharmony_ci            uint8_t weight = GetFontWeight(glyphNode.fontId);
325a3e0fd82Sopenharmony_ci            if (weight >= 16) { // 16: bit rgb565 rgba8888
326a3e0fd82Sopenharmony_ci                emoijMaxNode = glyphNode.rows > emoijMaxNode.rows ? glyphNode : emoijMaxNode;
327a3e0fd82Sopenharmony_ci                emojiNum++;
328a3e0fd82Sopenharmony_ci            } else {
329a3e0fd82Sopenharmony_ci                textNum++;
330a3e0fd82Sopenharmony_ci            }
331a3e0fd82Sopenharmony_ci            loopNum++;
332a3e0fd82Sopenharmony_ci        }
333a3e0fd82Sopenharmony_ci    }
334a3e0fd82Sopenharmony_ci    // The number of emoji is the same as the number of cycles, indicating that this line is all emoji
335a3e0fd82Sopenharmony_ci    // The number of words is the same as the number of cycles, which means that this line is all words
336a3e0fd82Sopenharmony_ci    if ((emojiNum == loopNum) || (textNum == loopNum)) {
337a3e0fd82Sopenharmony_ci        isEmoijLarge = true;
338a3e0fd82Sopenharmony_ci        return 0;
339a3e0fd82Sopenharmony_ci    }
340a3e0fd82Sopenharmony_ci    isEmoijLarge = emoijMaxNode.rows > maxFontSie;
341a3e0fd82Sopenharmony_ci    uint16_t offset = 0;
342a3e0fd82Sopenharmony_ci    if (isEmoijLarge) {
343a3e0fd82Sopenharmony_ci        // If the emoji is higher than the text
344a3e0fd82Sopenharmony_ci        if (emoijMaxNode.top >= maxFontSie) {
345a3e0fd82Sopenharmony_ci            offset = emoijMaxNode.top - maxFontSie;
346a3e0fd82Sopenharmony_ci        }
347a3e0fd82Sopenharmony_ci    } else {
348a3e0fd82Sopenharmony_ci        // If text are higher than emoji
349a3e0fd82Sopenharmony_ci        if (maxFontSie >= emoijMaxNode.rows) {
350a3e0fd82Sopenharmony_ci            // should top - ros.
351a3e0fd82Sopenharmony_ci            offset = maxFontSie - emoijMaxNode.rows;
352a3e0fd82Sopenharmony_ci        }
353a3e0fd82Sopenharmony_ci    }
354a3e0fd82Sopenharmony_ci    return offset;
355a3e0fd82Sopenharmony_ci}
356a3e0fd82Sopenharmony_ci
357a3e0fd82Sopenharmony_ciuint16_t UIFontBitmap::GetLineMaxHeight(const char* text,
358a3e0fd82Sopenharmony_ci                                        uint16_t lineLength,
359a3e0fd82Sopenharmony_ci                                        uint16_t fontId,
360a3e0fd82Sopenharmony_ci                                        uint8_t fontSize,
361a3e0fd82Sopenharmony_ci                                        uint16_t& letterIndex,
362a3e0fd82Sopenharmony_ci                                        SpannableString* spannableString)
363a3e0fd82Sopenharmony_ci{
364a3e0fd82Sopenharmony_ci    uint16_t maxHeight = GetHeight(fontId, fontSize);
365a3e0fd82Sopenharmony_ci    if (spannableString == nullptr) {
366a3e0fd82Sopenharmony_ci        return maxHeight;
367a3e0fd82Sopenharmony_ci    }
368a3e0fd82Sopenharmony_ci
369a3e0fd82Sopenharmony_ci    uint32_t i = 0;
370a3e0fd82Sopenharmony_ci    while (i < lineLength) {
371a3e0fd82Sopenharmony_ci        TypedText::GetUTF8Next(text, i, i);
372a3e0fd82Sopenharmony_ci        if (spannableString != nullptr && spannableString->GetSpannable(letterIndex)) {
373a3e0fd82Sopenharmony_ci            int16_t spannableHeight = 0;
374a3e0fd82Sopenharmony_ci            spannableString->GetFontHeight(letterIndex, spannableHeight, fontId, fontSize);
375a3e0fd82Sopenharmony_ci            uint16_t tempHeight = static_cast<uint16_t>(spannableHeight);
376a3e0fd82Sopenharmony_ci            maxHeight = tempHeight > maxHeight ? tempHeight : maxHeight;
377a3e0fd82Sopenharmony_ci        }
378a3e0fd82Sopenharmony_ci        letterIndex++;
379a3e0fd82Sopenharmony_ci        if (i > 0 && ((text[i - 1] == '\r') || (text[i - 1] == '\n'))) {
380a3e0fd82Sopenharmony_ci            break;
381a3e0fd82Sopenharmony_ci        }
382a3e0fd82Sopenharmony_ci    }
383a3e0fd82Sopenharmony_ci
384a3e0fd82Sopenharmony_ci    return maxHeight;
385a3e0fd82Sopenharmony_ci}
386a3e0fd82Sopenharmony_ci
387a3e0fd82Sopenharmony_civoid UIFontBitmap::SetPsramMemory(uintptr_t psramAddr, uint32_t psramLen)
388a3e0fd82Sopenharmony_ci{
389a3e0fd82Sopenharmony_ci    BaseFont::SetPsramMemory(psramAddr, psramLen);
390a3e0fd82Sopenharmony_ci    FontRamAllocator::GetInstance().SetRamAddr(psramAddr, psramLen);
391a3e0fd82Sopenharmony_ci}
392a3e0fd82Sopenharmony_ci} // namespace OHOS
393