1a3e0fd82Sopenharmony_ci/*
2a3e0fd82Sopenharmony_ci * Copyright (c) 2020-2021 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_manager.h"
17a3e0fd82Sopenharmony_ci#include "font/ui_font_builder.h"
18a3e0fd82Sopenharmony_ci#include "font/ui_font_cache_manager.h"
19a3e0fd82Sopenharmony_ci#include "gfx_utils/file.h"
20a3e0fd82Sopenharmony_ci#include "gfx_utils/graphic_log.h"
21a3e0fd82Sopenharmony_ci#include "securec.h"
22a3e0fd82Sopenharmony_ci
23a3e0fd82Sopenharmony_cinamespace OHOS {
24a3e0fd82Sopenharmony_ciGlyphsManager::GlyphsManager() : fileType_(0) {}
25a3e0fd82Sopenharmony_ci
26a3e0fd82Sopenharmony_ciGlyphsManager::~GlyphsManager()
27a3e0fd82Sopenharmony_ci{
28a3e0fd82Sopenharmony_ci    for (uint16_t i = 0; i < glyphsFiles_.Size(); i++) {
29a3e0fd82Sopenharmony_ci        delete glyphsFiles_[i];
30a3e0fd82Sopenharmony_ci        glyphsFiles_[i] = nullptr;
31a3e0fd82Sopenharmony_ci    }
32a3e0fd82Sopenharmony_ci}
33a3e0fd82Sopenharmony_ci
34a3e0fd82Sopenharmony_ciint8_t GlyphsManager::SetFile(const char* fontName, int32_t fp, uint32_t start, uint16_t fileType)
35a3e0fd82Sopenharmony_ci{
36a3e0fd82Sopenharmony_ci    for (uint16_t i = 0; i < glyphsFiles_.Size(); i++) {
37a3e0fd82Sopenharmony_ci        if (glyphsFiles_[i]->IsSameFile(fontName)) {
38a3e0fd82Sopenharmony_ci            GRAPHIC_LOGE("GlyphsManager::SetFile font name repeat");
39a3e0fd82Sopenharmony_ci            return INVALID_RET_VALUE;
40a3e0fd82Sopenharmony_ci        }
41a3e0fd82Sopenharmony_ci    }
42a3e0fd82Sopenharmony_ci
43a3e0fd82Sopenharmony_ci    GlyphsFile* instance = new GlyphsFile();
44a3e0fd82Sopenharmony_ci    if (instance == nullptr) {
45a3e0fd82Sopenharmony_ci        GRAPHIC_LOGE("GlyphsManager::SetFile new failed");
46a3e0fd82Sopenharmony_ci        return INVALID_RET_VALUE;
47a3e0fd82Sopenharmony_ci    }
48a3e0fd82Sopenharmony_ci
49a3e0fd82Sopenharmony_ci    if (instance->SetFile(fontName, fp, start) != RET_VALUE_OK) {
50a3e0fd82Sopenharmony_ci        delete instance;
51a3e0fd82Sopenharmony_ci        instance = nullptr;
52a3e0fd82Sopenharmony_ci        GRAPHIC_LOGE("GlyphsManager::SetFile() instance->SetFile() failed");
53a3e0fd82Sopenharmony_ci        return INVALID_RET_VALUE;
54a3e0fd82Sopenharmony_ci    }
55a3e0fd82Sopenharmony_ci
56a3e0fd82Sopenharmony_ci    glyphsFiles_.PushBack(instance);
57a3e0fd82Sopenharmony_ci    fileType_ = fileType;
58a3e0fd82Sopenharmony_ci    return RET_VALUE_OK;
59a3e0fd82Sopenharmony_ci}
60a3e0fd82Sopenharmony_ci
61a3e0fd82Sopenharmony_ciint8_t GlyphsManager::GetFontVersion(const char* fontName, char* version, uint8_t len)
62a3e0fd82Sopenharmony_ci{
63a3e0fd82Sopenharmony_ci    for (uint16_t i = 0; i < glyphsFiles_.Size(); i++) {
64a3e0fd82Sopenharmony_ci        if (glyphsFiles_[i]->GetFontVersion(fontName, version, len) == RET_VALUE_OK) {
65a3e0fd82Sopenharmony_ci            return RET_VALUE_OK;
66a3e0fd82Sopenharmony_ci        }
67a3e0fd82Sopenharmony_ci    }
68a3e0fd82Sopenharmony_ci    return INVALID_RET_VALUE;
69a3e0fd82Sopenharmony_ci}
70a3e0fd82Sopenharmony_ci
71a3e0fd82Sopenharmony_ciconst FontHeader* GlyphsManager::GetFontHeader(uint16_t fontId)
72a3e0fd82Sopenharmony_ci{
73a3e0fd82Sopenharmony_ci    for (uint16_t i = 0; i < glyphsFiles_.Size(); i++) {
74a3e0fd82Sopenharmony_ci        const FontHeader* tmp = glyphsFiles_[i]->GetFontHeader(fontId);
75a3e0fd82Sopenharmony_ci        if (tmp != nullptr) {
76a3e0fd82Sopenharmony_ci            return tmp;
77a3e0fd82Sopenharmony_ci        }
78a3e0fd82Sopenharmony_ci    }
79a3e0fd82Sopenharmony_ci
80a3e0fd82Sopenharmony_ci    return nullptr;
81a3e0fd82Sopenharmony_ci}
82a3e0fd82Sopenharmony_ci
83a3e0fd82Sopenharmony_ciconst GlyphNode* GlyphsManager::GetGlyphNodeFromFiles(uint32_t unicode, uint16_t fontId)
84a3e0fd82Sopenharmony_ci{
85a3e0fd82Sopenharmony_ci    int8_t ret = INVALID_RET_VALUE;
86a3e0fd82Sopenharmony_ci    GlyphNode nodeInfo;
87a3e0fd82Sopenharmony_ci    for (uint16_t i = 0; i < glyphsFiles_.Size(); i++) {
88a3e0fd82Sopenharmony_ci        ret = glyphsFiles_[i]->GetNodeFromFile(unicode, fontId, nodeInfo);
89a3e0fd82Sopenharmony_ci        if (ret == RET_VALUE_OK) {
90a3e0fd82Sopenharmony_ci            nodeInfo.fontId = fontId;
91a3e0fd82Sopenharmony_ci            break;
92a3e0fd82Sopenharmony_ci        }
93a3e0fd82Sopenharmony_ci    }
94a3e0fd82Sopenharmony_ci
95a3e0fd82Sopenharmony_ci    if (ret != RET_VALUE_OK) {
96a3e0fd82Sopenharmony_ci        return nullptr;
97a3e0fd82Sopenharmony_ci    }
98a3e0fd82Sopenharmony_ci
99a3e0fd82Sopenharmony_ci    GlyphCacheNode* cacheNode = UIFontCacheManager::GetInstance()->GetNodeCacheSpace(unicode, fontId);
100a3e0fd82Sopenharmony_ci    if (cacheNode == nullptr) {
101a3e0fd82Sopenharmony_ci        return nullptr;
102a3e0fd82Sopenharmony_ci    }
103a3e0fd82Sopenharmony_ci    cacheNode->node = nodeInfo;
104a3e0fd82Sopenharmony_ci    cacheNode->cacheType = fileType_;
105a3e0fd82Sopenharmony_ci
106a3e0fd82Sopenharmony_ci    return &(cacheNode->node);
107a3e0fd82Sopenharmony_ci}
108a3e0fd82Sopenharmony_ci
109a3e0fd82Sopenharmony_ciconst GlyphNode* GlyphsManager::GetGlyphNode(uint32_t unicode, uint16_t fontId)
110a3e0fd82Sopenharmony_ci{
111a3e0fd82Sopenharmony_ci    GlyphCacheNode* cacheNode =
112a3e0fd82Sopenharmony_ci        UIFontCacheManager::GetInstance()->GetNodeFromCache(unicode, fontId, GlyphCacheType::CACHE_TYPE_NONE);
113a3e0fd82Sopenharmony_ci    if (cacheNode != nullptr) {
114a3e0fd82Sopenharmony_ci        return &(cacheNode->node);
115a3e0fd82Sopenharmony_ci    }
116a3e0fd82Sopenharmony_ci
117a3e0fd82Sopenharmony_ci    const GlyphNode* node = const_cast<GlyphNode*>(GetGlyphNodeFromFiles(unicode, fontId));
118a3e0fd82Sopenharmony_ci    if (node != nullptr) {
119a3e0fd82Sopenharmony_ci        return node;
120a3e0fd82Sopenharmony_ci    }
121a3e0fd82Sopenharmony_ci    return nullptr;
122a3e0fd82Sopenharmony_ci}
123a3e0fd82Sopenharmony_ci
124a3e0fd82Sopenharmony_ciint16_t GlyphsManager::GetFontHeight(uint16_t fontId)
125a3e0fd82Sopenharmony_ci{
126a3e0fd82Sopenharmony_ci    for (uint16_t i = 0; i < glyphsFiles_.Size(); i++) {
127a3e0fd82Sopenharmony_ci        int16_t height = glyphsFiles_[i]->GetFontHeight(fontId);
128a3e0fd82Sopenharmony_ci        if (height != INVALID_RET_VALUE) {
129a3e0fd82Sopenharmony_ci            return height;
130a3e0fd82Sopenharmony_ci        }
131a3e0fd82Sopenharmony_ci    }
132a3e0fd82Sopenharmony_ci
133a3e0fd82Sopenharmony_ci    return INVALID_RET_VALUE;
134a3e0fd82Sopenharmony_ci}
135a3e0fd82Sopenharmony_ci
136a3e0fd82Sopenharmony_ciint16_t GlyphsManager::GetFontWidth(uint32_t unicode, uint16_t fontId)
137a3e0fd82Sopenharmony_ci{
138a3e0fd82Sopenharmony_ci    const GlyphNode* node = GetGlyphNode(unicode, fontId);
139a3e0fd82Sopenharmony_ci    if (node == nullptr) {
140a3e0fd82Sopenharmony_ci        return INVALID_RET_VALUE;
141a3e0fd82Sopenharmony_ci    }
142a3e0fd82Sopenharmony_ci    return node->advance;
143a3e0fd82Sopenharmony_ci}
144a3e0fd82Sopenharmony_ci
145a3e0fd82Sopenharmony_ciint8_t GlyphsManager::GetBitmap(uint32_t unicode, BufferInfo& bufInfo, uint16_t fontId)
146a3e0fd82Sopenharmony_ci{
147a3e0fd82Sopenharmony_ci    GlyphCacheNode* cacheNode = UIFontCacheManager::GetInstance()->GetNodeFromCache(unicode, fontId, fileType_);
148a3e0fd82Sopenharmony_ci    if (cacheNode != nullptr && cacheNode->cacheType == fileType_) {
149a3e0fd82Sopenharmony_ci        for (uint16_t i = 0; i < glyphsFiles_.Size(); i++) {
150a3e0fd82Sopenharmony_ci            int8_t ret = glyphsFiles_[i]->GetBitmap(cacheNode->node, bufInfo);
151a3e0fd82Sopenharmony_ci            if (ret == RET_VALUE_OK) {
152a3e0fd82Sopenharmony_ci                return RET_VALUE_OK;
153a3e0fd82Sopenharmony_ci            }
154a3e0fd82Sopenharmony_ci        }
155a3e0fd82Sopenharmony_ci    }
156a3e0fd82Sopenharmony_ci
157a3e0fd82Sopenharmony_ci    GlyphNode* node = const_cast<GlyphNode*>(GetGlyphNodeFromFiles(unicode, fontId));
158a3e0fd82Sopenharmony_ci    if (node == nullptr) {
159a3e0fd82Sopenharmony_ci        GRAPHIC_LOGE("GlyphsManager::GetBitmap node not found");
160a3e0fd82Sopenharmony_ci        return INVALID_RET_VALUE;
161a3e0fd82Sopenharmony_ci    }
162a3e0fd82Sopenharmony_ci
163a3e0fd82Sopenharmony_ci    for (uint16_t i = 0; i < glyphsFiles_.Size(); i++) {
164a3e0fd82Sopenharmony_ci        int8_t ret = glyphsFiles_[i]->GetBitmap(*node, bufInfo);
165a3e0fd82Sopenharmony_ci        if (ret == RET_VALUE_OK) {
166a3e0fd82Sopenharmony_ci            return RET_VALUE_OK;
167a3e0fd82Sopenharmony_ci        }
168a3e0fd82Sopenharmony_ci    }
169a3e0fd82Sopenharmony_ci    return INVALID_RET_VALUE;
170a3e0fd82Sopenharmony_ci}
171a3e0fd82Sopenharmony_ci} // namespace OHOS
172