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