1a3e0fd82Sopenharmony_ci/*
2a3e0fd82Sopenharmony_ci * Copyright (c) 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/glyphs_file.h"
17a3e0fd82Sopenharmony_ci#include "draw/draw_utils.h"
18a3e0fd82Sopenharmony_ci#include "font/font_ram_allocator.h"
19a3e0fd82Sopenharmony_ci#include "font/ui_font_builder.h"
20a3e0fd82Sopenharmony_ci#include "gfx_utils/file.h"
21a3e0fd82Sopenharmony_ci#include "gfx_utils/graphic_log.h"
22a3e0fd82Sopenharmony_ci#include "securec.h"
23a3e0fd82Sopenharmony_ci
24a3e0fd82Sopenharmony_cinamespace OHOS {
25a3e0fd82Sopenharmony_ciGlyphsFile::GlyphsFile()
26a3e0fd82Sopenharmony_ci    : binHeader_{{0}},
27a3e0fd82Sopenharmony_ci      start_(0),
28a3e0fd82Sopenharmony_ci      fontHeaderSectionStart_(0),
29a3e0fd82Sopenharmony_ci      fontIndexSectionStart_(0),
30a3e0fd82Sopenharmony_ci      glyphNodeSectionStart_(0),
31a3e0fd82Sopenharmony_ci      bitMapSectionStart_(0),
32a3e0fd82Sopenharmony_ci      fontHeaderCache_(nullptr),
33a3e0fd82Sopenharmony_ci      indexCache_(nullptr),
34a3e0fd82Sopenharmony_ci      fontName_(nullptr),
35a3e0fd82Sopenharmony_ci      fp_(-1),
36a3e0fd82Sopenharmony_ci      isFileSet_(false),
37a3e0fd82Sopenharmony_ci      fontNum_(0)
38a3e0fd82Sopenharmony_ci{
39a3e0fd82Sopenharmony_ci}
40a3e0fd82Sopenharmony_ciGlyphsFile::~GlyphsFile()
41a3e0fd82Sopenharmony_ci{
42a3e0fd82Sopenharmony_ci    if (fontName_) {
43a3e0fd82Sopenharmony_ci        UIFree(fontName_);
44a3e0fd82Sopenharmony_ci        fontName_ = nullptr;
45a3e0fd82Sopenharmony_ci    }
46a3e0fd82Sopenharmony_ci}
47a3e0fd82Sopenharmony_ci
48a3e0fd82Sopenharmony_ciint8_t GlyphsFile::CacheInit()
49a3e0fd82Sopenharmony_ci{
50a3e0fd82Sopenharmony_ci    uint32_t size = 0;
51a3e0fd82Sopenharmony_ci    for (int32_t i = 0; i < fontNum_; i++) {
52a3e0fd82Sopenharmony_ci        size += fontHeaderCache_[i].indexLen;
53a3e0fd82Sopenharmony_ci    }
54a3e0fd82Sopenharmony_ci
55a3e0fd82Sopenharmony_ci    indexCache_ = reinterpret_cast<uint8_t*>(FontRamAllocator::GetInstance().Allocate(size));
56a3e0fd82Sopenharmony_ci    if (indexCache_ == nullptr) {
57a3e0fd82Sopenharmony_ci        GRAPHIC_LOGE("GlyphsFile::CacheInit Allocate failed");
58a3e0fd82Sopenharmony_ci        return INVALID_RET_VALUE;
59a3e0fd82Sopenharmony_ci    }
60a3e0fd82Sopenharmony_ci
61a3e0fd82Sopenharmony_ci    int32_t ret = read(fp_, indexCache_, size);
62a3e0fd82Sopenharmony_ci    if (ret != static_cast<int32_t>(size)) {
63a3e0fd82Sopenharmony_ci        GRAPHIC_LOGE("GlyphsFile::CacheInit read failed");
64a3e0fd82Sopenharmony_ci        return INVALID_RET_VALUE;
65a3e0fd82Sopenharmony_ci    }
66a3e0fd82Sopenharmony_ci
67a3e0fd82Sopenharmony_ci    return RET_VALUE_OK;
68a3e0fd82Sopenharmony_ci}
69a3e0fd82Sopenharmony_ci
70a3e0fd82Sopenharmony_ciint8_t GlyphsFile::GetNodeFromFile(uint32_t unicode, uint16_t fontId, GlyphNode& node)
71a3e0fd82Sopenharmony_ci{
72a3e0fd82Sopenharmony_ci    uint16_t idx = 0;
73a3e0fd82Sopenharmony_ci    uint32_t offset;
74a3e0fd82Sopenharmony_ci    GlyphInfo glyphInfo;
75a3e0fd82Sopenharmony_ci    int8_t result = GetGlyphInfo(fontId, glyphInfo);
76a3e0fd82Sopenharmony_ci    if (result != RET_VALUE_OK) {
77a3e0fd82Sopenharmony_ci        return INVALID_RET_VALUE;
78a3e0fd82Sopenharmony_ci    }
79a3e0fd82Sopenharmony_ci    for (int32_t i = RADIX_SHIFT_START; i >= 0; i -= RADIX_TREE_BITS) {
80a3e0fd82Sopenharmony_ci        offset = idx * sizeof(IndexNode);
81a3e0fd82Sopenharmony_ci        uint8_t key = static_cast<uint8_t>((unicode >> static_cast<uint8_t>(i)) & RADIX_TREE_MASK);
82a3e0fd82Sopenharmony_ci        offset += key * sizeof(uint16_t);
83a3e0fd82Sopenharmony_ci        idx = *(reinterpret_cast<uint16_t*>(glyphInfo.indexCache + offset));
84a3e0fd82Sopenharmony_ci        if (idx == 0) {
85a3e0fd82Sopenharmony_ci            return INVALID_RET_VALUE;
86a3e0fd82Sopenharmony_ci        }
87a3e0fd82Sopenharmony_ci    }
88a3e0fd82Sopenharmony_ci
89a3e0fd82Sopenharmony_ci    offset = glyphInfo.glyphNodeSectionStart + (idx - 1) * sizeof(GlyphNode);
90a3e0fd82Sopenharmony_ci    int32_t ret = lseek(fp_, offset, SEEK_SET);
91a3e0fd82Sopenharmony_ci    if (ret != static_cast<int32_t>(offset)) {
92a3e0fd82Sopenharmony_ci        GRAPHIC_LOGE("GlyphsFile::GetNodeFromFile lseek failed");
93a3e0fd82Sopenharmony_ci        return INVALID_RET_VALUE;
94a3e0fd82Sopenharmony_ci    }
95a3e0fd82Sopenharmony_ci
96a3e0fd82Sopenharmony_ci    ret = read(fp_, &node, sizeof(GlyphNode));
97a3e0fd82Sopenharmony_ci    if (ret < 0) {
98a3e0fd82Sopenharmony_ci        GRAPHIC_LOGE("GlyphsFile::GetNodeFromFile read failed");
99a3e0fd82Sopenharmony_ci        return INVALID_RET_VALUE;
100a3e0fd82Sopenharmony_ci    }
101a3e0fd82Sopenharmony_ci
102a3e0fd82Sopenharmony_ci    return RET_VALUE_OK;
103a3e0fd82Sopenharmony_ci}
104a3e0fd82Sopenharmony_ci
105a3e0fd82Sopenharmony_civoid GlyphsFile::SetFontName(const char* fontName)
106a3e0fd82Sopenharmony_ci{
107a3e0fd82Sopenharmony_ci    if (fontName_ != nullptr) {
108a3e0fd82Sopenharmony_ci        return;
109a3e0fd82Sopenharmony_ci    }
110a3e0fd82Sopenharmony_ci
111a3e0fd82Sopenharmony_ci    if (fontName == nullptr) {
112a3e0fd82Sopenharmony_ci        GRAPHIC_LOGE("GlyphsFile::SetFontName invalid parameters");
113a3e0fd82Sopenharmony_ci        return;
114a3e0fd82Sopenharmony_ci    }
115a3e0fd82Sopenharmony_ci
116a3e0fd82Sopenharmony_ci    uint32_t nameLen = strlen(fontName);
117a3e0fd82Sopenharmony_ci    if (nameLen > FONT_NAME_LEN_MAX) {
118a3e0fd82Sopenharmony_ci        nameLen = FONT_NAME_LEN_MAX;
119a3e0fd82Sopenharmony_ci    } else if (nameLen == 0) {
120a3e0fd82Sopenharmony_ci        return;
121a3e0fd82Sopenharmony_ci    }
122a3e0fd82Sopenharmony_ci
123a3e0fd82Sopenharmony_ci    fontName_ = static_cast<char*>(UIMalloc(++nameLen));
124a3e0fd82Sopenharmony_ci    if (fontName_ == nullptr) {
125a3e0fd82Sopenharmony_ci        return;
126a3e0fd82Sopenharmony_ci    }
127a3e0fd82Sopenharmony_ci    if (memcpy_s(fontName_, nameLen, fontName, nameLen) != EOK) {
128a3e0fd82Sopenharmony_ci        UIFree(fontName_);
129a3e0fd82Sopenharmony_ci        fontName_ = nullptr;
130a3e0fd82Sopenharmony_ci    }
131a3e0fd82Sopenharmony_ci}
132a3e0fd82Sopenharmony_ci
133a3e0fd82Sopenharmony_ciint8_t GlyphsFile::SetFile(const char* fontName, int32_t fp, uint32_t start)
134a3e0fd82Sopenharmony_ci{
135a3e0fd82Sopenharmony_ci    SetFontName(fontName);
136a3e0fd82Sopenharmony_ci    fp_ = fp;
137a3e0fd82Sopenharmony_ci    start_ = start;
138a3e0fd82Sopenharmony_ci    int32_t ret = lseek(fp_, start_, SEEK_SET);
139a3e0fd82Sopenharmony_ci    if (ret < 0) {
140a3e0fd82Sopenharmony_ci        GRAPHIC_LOGE("GlyphsFile::SetFile lseek failed");
141a3e0fd82Sopenharmony_ci        return INVALID_RET_VALUE;
142a3e0fd82Sopenharmony_ci    }
143a3e0fd82Sopenharmony_ci    ret = read(fp_, &binHeader_, sizeof(binHeader_));
144a3e0fd82Sopenharmony_ci    if (ret != sizeof(binHeader_)) {
145a3e0fd82Sopenharmony_ci        GRAPHIC_LOGE("GlyphsFile::SetFile read failed");
146a3e0fd82Sopenharmony_ci        return INVALID_RET_VALUE;
147a3e0fd82Sopenharmony_ci    }
148a3e0fd82Sopenharmony_ci    if (strncmp(binHeader_.fontMagic, FONT_MAGIC_NUMBER, FONT_MAGIC_NUM_LEN) != 0) {
149a3e0fd82Sopenharmony_ci        return INVALID_RET_VALUE;
150a3e0fd82Sopenharmony_ci    }
151a3e0fd82Sopenharmony_ci    if (binHeader_.fontNum > UIFontBuilder::GetInstance()->GetBitmapFontIdMax()) {
152a3e0fd82Sopenharmony_ci        GRAPHIC_LOGE("GlyphsFile::SetFile data error, fontNum need less than max fontId");
153a3e0fd82Sopenharmony_ci        return INVALID_RET_VALUE;
154a3e0fd82Sopenharmony_ci    }
155a3e0fd82Sopenharmony_ci
156a3e0fd82Sopenharmony_ci    fontNum_ = binHeader_.fontNum;
157a3e0fd82Sopenharmony_ci    fontHeaderSectionStart_ = start_ + sizeof(binHeader_);
158a3e0fd82Sopenharmony_ci    uint32_t size = sizeof(FontHeader) * fontNum_;
159a3e0fd82Sopenharmony_ci    fontIndexSectionStart_ = fontHeaderSectionStart_ + size;
160a3e0fd82Sopenharmony_ci
161a3e0fd82Sopenharmony_ci    fontHeaderCache_ = reinterpret_cast<FontHeader*>(FontRamAllocator::GetInstance().Allocate(size));
162a3e0fd82Sopenharmony_ci    if (fontHeaderCache_ == nullptr) {
163a3e0fd82Sopenharmony_ci        GRAPHIC_LOGE("GlyphsFile::SetFile allocate font header cache failed");
164a3e0fd82Sopenharmony_ci        return INVALID_RET_VALUE;
165a3e0fd82Sopenharmony_ci    }
166a3e0fd82Sopenharmony_ci
167a3e0fd82Sopenharmony_ci    ret = read(fp_, fontHeaderCache_, size);
168a3e0fd82Sopenharmony_ci    if (ret != static_cast<int32_t>(size)) {
169a3e0fd82Sopenharmony_ci        GRAPHIC_LOGE("GlyphsFile::SetFile read failed");
170a3e0fd82Sopenharmony_ci        return INVALID_RET_VALUE;
171a3e0fd82Sopenharmony_ci    }
172a3e0fd82Sopenharmony_ci
173a3e0fd82Sopenharmony_ci    FontHeader* last = fontHeaderCache_ + fontNum_ - 1;
174a3e0fd82Sopenharmony_ci    size = last->indexOffset + last->indexLen;
175a3e0fd82Sopenharmony_ci    glyphNodeSectionStart_ = fontIndexSectionStart_ + size;
176a3e0fd82Sopenharmony_ci
177a3e0fd82Sopenharmony_ci    size = 0;
178a3e0fd82Sopenharmony_ci    for (uint32_t i = 0; i < fontNum_; i++) {
179a3e0fd82Sopenharmony_ci        size += fontHeaderCache_[i].glyphNum * sizeof(GlyphNode);
180a3e0fd82Sopenharmony_ci    }
181a3e0fd82Sopenharmony_ci    bitMapSectionStart_ = glyphNodeSectionStart_ + size;
182a3e0fd82Sopenharmony_ci    ret = CacheInit();
183a3e0fd82Sopenharmony_ci    if (ret == RET_VALUE_OK) {
184a3e0fd82Sopenharmony_ci        isFileSet_ = true;
185a3e0fd82Sopenharmony_ci    }
186a3e0fd82Sopenharmony_ci
187a3e0fd82Sopenharmony_ci    return ret;
188a3e0fd82Sopenharmony_ci}
189a3e0fd82Sopenharmony_ci
190a3e0fd82Sopenharmony_cibool GlyphsFile::IsSameFile(const char* fontName)
191a3e0fd82Sopenharmony_ci{
192a3e0fd82Sopenharmony_ci    if ((fontName_ == nullptr) || (fontName == nullptr)) {
193a3e0fd82Sopenharmony_ci        return false;
194a3e0fd82Sopenharmony_ci    }
195a3e0fd82Sopenharmony_ci
196a3e0fd82Sopenharmony_ci    uint32_t Offset = 0;
197a3e0fd82Sopenharmony_ci    uint32_t nameLen = strlen(fontName);
198a3e0fd82Sopenharmony_ci    if (nameLen > FONT_NAME_LEN_MAX) {
199a3e0fd82Sopenharmony_ci        Offset = nameLen - FONT_NAME_LEN_MAX;
200a3e0fd82Sopenharmony_ci    }
201a3e0fd82Sopenharmony_ci    return (strcmp(fontName_, fontName + Offset) == 0);
202a3e0fd82Sopenharmony_ci}
203a3e0fd82Sopenharmony_ci
204a3e0fd82Sopenharmony_ciint8_t GlyphsFile::GetGlyphInfo(uint16_t fontId, GlyphInfo& glyphInfo)
205a3e0fd82Sopenharmony_ci{
206a3e0fd82Sopenharmony_ci    uint16_t fontIdx = 0;
207a3e0fd82Sopenharmony_ci    UIFontBuilder* fontBuilder = UIFontBuilder::GetInstance();
208a3e0fd82Sopenharmony_ci    if (fontId > fontBuilder->GetBitmapFontIdMax()) {
209a3e0fd82Sopenharmony_ci        GRAPHIC_LOGE("GlyphsFile::GetGlyphInfo fontId need less than max fontId");
210a3e0fd82Sopenharmony_ci        return INVALID_RET_VALUE;
211a3e0fd82Sopenharmony_ci    }
212a3e0fd82Sopenharmony_ci    if (!isFileSet_) {
213a3e0fd82Sopenharmony_ci        GRAPHIC_LOGE("GlyphsFile::GetGlyphInfo file not set");
214a3e0fd82Sopenharmony_ci        return INVALID_RET_VALUE;
215a3e0fd82Sopenharmony_ci    }
216a3e0fd82Sopenharmony_ci
217a3e0fd82Sopenharmony_ci    int32_t low = 0;
218a3e0fd82Sopenharmony_ci    int32_t high = binHeader_.fontNum - 1;
219a3e0fd82Sopenharmony_ci    bool found = false;
220a3e0fd82Sopenharmony_ci
221a3e0fd82Sopenharmony_ci    while (low <= high) {
222a3e0fd82Sopenharmony_ci        int32_t mid = (low + high) / 2; // 2 means half
223a3e0fd82Sopenharmony_ci        if (fontHeaderCache_[mid].fontId == fontId) {
224a3e0fd82Sopenharmony_ci            fontIdx = mid;
225a3e0fd82Sopenharmony_ci            found = true;
226a3e0fd82Sopenharmony_ci            break;
227a3e0fd82Sopenharmony_ci        } else if (fontHeaderCache_[mid].fontId > fontId) {
228a3e0fd82Sopenharmony_ci            high = mid - 1;
229a3e0fd82Sopenharmony_ci        } else if (fontHeaderCache_[mid].fontId < fontId) {
230a3e0fd82Sopenharmony_ci            low = mid + 1;
231a3e0fd82Sopenharmony_ci        }
232a3e0fd82Sopenharmony_ci    }
233a3e0fd82Sopenharmony_ci    if (!found) {
234a3e0fd82Sopenharmony_ci        glyphInfo.fontHeader = nullptr;
235a3e0fd82Sopenharmony_ci        glyphInfo.fontId = fontBuilder->GetBitmapFontIdMax();
236a3e0fd82Sopenharmony_ci        return INVALID_RET_VALUE;
237a3e0fd82Sopenharmony_ci    }
238a3e0fd82Sopenharmony_ci
239a3e0fd82Sopenharmony_ci    uint32_t size = 0;
240a3e0fd82Sopenharmony_ci    glyphInfo.fontId = fontId;
241a3e0fd82Sopenharmony_ci    glyphInfo.fontHeader = fontHeaderCache_ + fontIdx;
242a3e0fd82Sopenharmony_ci    glyphInfo.fontIndexSectionStart = fontIndexSectionStart_ + glyphInfo.fontHeader->indexOffset;
243a3e0fd82Sopenharmony_ci    for (uint32_t i = 0; i < fontIdx; i++) {
244a3e0fd82Sopenharmony_ci        size += fontHeaderCache_[i].glyphNum * sizeof(GlyphNode);
245a3e0fd82Sopenharmony_ci    }
246a3e0fd82Sopenharmony_ci    glyphInfo.glyphNodeSectionStart = glyphNodeSectionStart_ + size;
247a3e0fd82Sopenharmony_ci    glyphInfo.bitMapSectionStart = bitMapSectionStart_ + glyphInfo.fontHeader->glyphOffset;
248a3e0fd82Sopenharmony_ci    glyphInfo.indexCache = indexCache_ + glyphInfo.fontHeader->indexOffset;
249a3e0fd82Sopenharmony_ci
250a3e0fd82Sopenharmony_ci    return RET_VALUE_OK;
251a3e0fd82Sopenharmony_ci}
252a3e0fd82Sopenharmony_ci
253a3e0fd82Sopenharmony_ciint8_t GlyphsFile::GetFontVersion(const char* fontName, char* version, uint8_t len)
254a3e0fd82Sopenharmony_ci{
255a3e0fd82Sopenharmony_ci    if (!isFileSet_ || (version == nullptr) || (len > FONT_VERSION_LEN)) {
256a3e0fd82Sopenharmony_ci        GRAPHIC_LOGE("GlyphsFile::GetFontVersion invalid parameters");
257a3e0fd82Sopenharmony_ci        return INVALID_RET_VALUE;
258a3e0fd82Sopenharmony_ci    }
259a3e0fd82Sopenharmony_ci
260a3e0fd82Sopenharmony_ci    if (!IsSameFile(fontName)) {
261a3e0fd82Sopenharmony_ci        return INVALID_RET_VALUE;
262a3e0fd82Sopenharmony_ci    }
263a3e0fd82Sopenharmony_ci
264a3e0fd82Sopenharmony_ci    if (memset_s(version, len, 0, len) != EOK) {
265a3e0fd82Sopenharmony_ci        GRAPHIC_LOGE("GlyphsFile::GetFontVersion memset_s failed");
266a3e0fd82Sopenharmony_ci        return INVALID_RET_VALUE;
267a3e0fd82Sopenharmony_ci    }
268a3e0fd82Sopenharmony_ci    if (strcpy_s(version, len, binHeader_.fontVersion) != EOK) {
269a3e0fd82Sopenharmony_ci        GRAPHIC_LOGE("GlyphsFile::GetFontVersion strcpy_s failed");
270a3e0fd82Sopenharmony_ci        return INVALID_RET_VALUE;
271a3e0fd82Sopenharmony_ci    }
272a3e0fd82Sopenharmony_ci    return RET_VALUE_OK;
273a3e0fd82Sopenharmony_ci}
274a3e0fd82Sopenharmony_ci
275a3e0fd82Sopenharmony_ciconst FontHeader* GlyphsFile::GetFontHeader(uint16_t fontId)
276a3e0fd82Sopenharmony_ci{
277a3e0fd82Sopenharmony_ci    GlyphInfo glyphInfo;
278a3e0fd82Sopenharmony_ci    int8_t ret = GetGlyphInfo(fontId, glyphInfo);
279a3e0fd82Sopenharmony_ci    if (ret != RET_VALUE_OK) {
280a3e0fd82Sopenharmony_ci        return nullptr;
281a3e0fd82Sopenharmony_ci    }
282a3e0fd82Sopenharmony_ci
283a3e0fd82Sopenharmony_ci    return glyphInfo.fontHeader;
284a3e0fd82Sopenharmony_ci}
285a3e0fd82Sopenharmony_ci
286a3e0fd82Sopenharmony_ciint16_t GlyphsFile::GetFontHeight(uint16_t fontId)
287a3e0fd82Sopenharmony_ci{
288a3e0fd82Sopenharmony_ci    GlyphInfo glyphInfo;
289a3e0fd82Sopenharmony_ci    int8_t ret = GetGlyphInfo(fontId, glyphInfo);
290a3e0fd82Sopenharmony_ci    if (ret != RET_VALUE_OK) {
291a3e0fd82Sopenharmony_ci        return INVALID_RET_VALUE;
292a3e0fd82Sopenharmony_ci    }
293a3e0fd82Sopenharmony_ci
294a3e0fd82Sopenharmony_ci    return glyphInfo.fontHeader->fontHeight;
295a3e0fd82Sopenharmony_ci}
296a3e0fd82Sopenharmony_ci
297a3e0fd82Sopenharmony_ciint8_t GlyphsFile::GetBitmap(GlyphNode& node, BufferInfo& bufInfo)
298a3e0fd82Sopenharmony_ci{
299a3e0fd82Sopenharmony_ci    if (bufInfo.virAddr == nullptr) {
300a3e0fd82Sopenharmony_ci        GRAPHIC_LOGE("GlyphsFile::GetBitmap invalid parameter");
301a3e0fd82Sopenharmony_ci        return INVALID_RET_VALUE;
302a3e0fd82Sopenharmony_ci    }
303a3e0fd82Sopenharmony_ci
304a3e0fd82Sopenharmony_ci    GlyphInfo glyphInfo;
305a3e0fd82Sopenharmony_ci    int8_t result = GetGlyphInfo(node.fontId, glyphInfo);
306a3e0fd82Sopenharmony_ci    if (result != RET_VALUE_OK) {
307a3e0fd82Sopenharmony_ci        return INVALID_RET_VALUE;
308a3e0fd82Sopenharmony_ci    }
309a3e0fd82Sopenharmony_ci
310a3e0fd82Sopenharmony_ci    uint32_t tmpBitMapSectionStart = glyphInfo.bitMapSectionStart;
311a3e0fd82Sopenharmony_ci    uint32_t offset = tmpBitMapSectionStart + node.dataOff;
312a3e0fd82Sopenharmony_ci    uint32_t size = node.kernOff - node.dataOff;
313a3e0fd82Sopenharmony_ci    int32_t ret = lseek(fp_, offset, SEEK_SET);
314a3e0fd82Sopenharmony_ci    if (ret != static_cast<int32_t>(offset)) {
315a3e0fd82Sopenharmony_ci        GRAPHIC_LOGE("GlyphsFile::GetBitmap lseek failed");
316a3e0fd82Sopenharmony_ci        return INVALID_RET_VALUE;
317a3e0fd82Sopenharmony_ci    }
318a3e0fd82Sopenharmony_ci
319a3e0fd82Sopenharmony_ci    int32_t readSize = read(fp_, bufInfo.virAddr, size);
320a3e0fd82Sopenharmony_ci    if (readSize != static_cast<int32_t>(size)) {
321a3e0fd82Sopenharmony_ci        GRAPHIC_LOGE("GlyphsFile::GetBitmap read failed");
322a3e0fd82Sopenharmony_ci        return INVALID_RET_VALUE;
323a3e0fd82Sopenharmony_ci    }
324a3e0fd82Sopenharmony_ci    UIFontAllocator::RearrangeBitmap(bufInfo, size, false);
325a3e0fd82Sopenharmony_ci
326a3e0fd82Sopenharmony_ci    node.dataFlag = node.fontId;
327a3e0fd82Sopenharmony_ci    return RET_VALUE_OK;
328a3e0fd82Sopenharmony_ci}
329a3e0fd82Sopenharmony_ci} // namespace OHOS
330