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_cache.h"
17a3e0fd82Sopenharmony_ci#include <cstddef>
18a3e0fd82Sopenharmony_ci#if defined(ENABLE_VECTOR_FONT) && ENABLE_VECTOR_FONT
19a3e0fd82Sopenharmony_ci#include "gfx_utils/style.h"
20a3e0fd82Sopenharmony_ci
21a3e0fd82Sopenharmony_ci#endif
22a3e0fd82Sopenharmony_cinamespace OHOS {
23a3e0fd82Sopenharmony_ciUIFontCache::UIFontCache(uint8_t* ram, uint32_t size)
24a3e0fd82Sopenharmony_ci{
25a3e0fd82Sopenharmony_ci    if (ram == nullptr) {
26a3e0fd82Sopenharmony_ci        return;
27a3e0fd82Sopenharmony_ci    }
28a3e0fd82Sopenharmony_ci    allocator_.SetRamAddr(ram, size);
29a3e0fd82Sopenharmony_ci    allocator_.SetMinChunkSize(FONT_CACHE_MIN_SIZE + sizeof(Bitmap));
30a3e0fd82Sopenharmony_ci
31a3e0fd82Sopenharmony_ci    uint32_t hashTableSize = sizeof(ListHead) * FONT_CACHE_HASH_NR;
32a3e0fd82Sopenharmony_ci    hashTable_ = reinterpret_cast<ListHead*>(allocator_.Allocate(hashTableSize));
33a3e0fd82Sopenharmony_ci    for (uint8_t i = 0; i < FONT_CACHE_HASH_NR; i++) {
34a3e0fd82Sopenharmony_ci        ListInit(hashTable_ + i);
35a3e0fd82Sopenharmony_ci    }
36a3e0fd82Sopenharmony_ci
37a3e0fd82Sopenharmony_ci    ListInit(&lruList_);
38a3e0fd82Sopenharmony_ci}
39a3e0fd82Sopenharmony_ci
40a3e0fd82Sopenharmony_ciUIFontCache::~UIFontCache() {}
41a3e0fd82Sopenharmony_ci
42a3e0fd82Sopenharmony_civoid UIFontCache::UpdateLru(Bitmap* bitmap)
43a3e0fd82Sopenharmony_ci{
44a3e0fd82Sopenharmony_ci    ListDel(&bitmap->lruHead);
45a3e0fd82Sopenharmony_ci    ListInit(&bitmap->lruHead);
46a3e0fd82Sopenharmony_ci    ListAdd(&bitmap->lruHead, &lruList_);
47a3e0fd82Sopenharmony_ci}
48a3e0fd82Sopenharmony_ci
49a3e0fd82Sopenharmony_ciuint8_t* UIFontCache::GetSpace(uint16_t fontId, uint32_t unicode, uint32_t size, TextStyle textStyle)
50a3e0fd82Sopenharmony_ci{
51a3e0fd82Sopenharmony_ci    Bitmap* bitmap = nullptr;
52a3e0fd82Sopenharmony_ci
53a3e0fd82Sopenharmony_ci    uint32_t allocSize = sizeof(Bitmap) + size;
54a3e0fd82Sopenharmony_ci    while (bitmap == nullptr) {
55a3e0fd82Sopenharmony_ci        bitmap = reinterpret_cast<Bitmap*>(allocator_.Allocate(allocSize));
56a3e0fd82Sopenharmony_ci        if (bitmap == nullptr) {
57a3e0fd82Sopenharmony_ci            // nothing to free, return null
58a3e0fd82Sopenharmony_ci            if ((lruList_.prev == &lruList_) && (lruList_.next == &lruList_)) {
59a3e0fd82Sopenharmony_ci                return nullptr;
60a3e0fd82Sopenharmony_ci            }
61a3e0fd82Sopenharmony_ci            Bitmap* toFree = reinterpret_cast<struct Bitmap *>(reinterpret_cast<uint8_t *>(lruList_.prev) -
62a3e0fd82Sopenharmony_ci                offsetof(struct Bitmap, lruHead));
63a3e0fd82Sopenharmony_ci            ListDel(&toFree->hashHead);
64a3e0fd82Sopenharmony_ci            ListDel(&toFree->lruHead);
65a3e0fd82Sopenharmony_ci            allocator_.Free(toFree);
66a3e0fd82Sopenharmony_ci        }
67a3e0fd82Sopenharmony_ci    }
68a3e0fd82Sopenharmony_ci
69a3e0fd82Sopenharmony_ci    ListInit(&bitmap->hashHead);
70a3e0fd82Sopenharmony_ci    ListInit(&bitmap->lruHead);
71a3e0fd82Sopenharmony_ci    ListAdd(&bitmap->hashHead, hashTable_ + unicode % FONT_CACHE_HASH_NR);
72a3e0fd82Sopenharmony_ci    ListAdd(&bitmap->lruHead, &lruList_);
73a3e0fd82Sopenharmony_ci
74a3e0fd82Sopenharmony_ci    bitmap->fontId = fontId;
75a3e0fd82Sopenharmony_ci    bitmap->unicode = unicode;
76a3e0fd82Sopenharmony_ci#if defined(ENABLE_TEXT_STYLE) && ENABLE_TEXT_STYLE
77a3e0fd82Sopenharmony_ci    bitmap->textStyle = textStyle;
78a3e0fd82Sopenharmony_ci#endif
79a3e0fd82Sopenharmony_ci
80a3e0fd82Sopenharmony_ci    return reinterpret_cast<uint8_t*>(bitmap->data);
81a3e0fd82Sopenharmony_ci}
82a3e0fd82Sopenharmony_ci
83a3e0fd82Sopenharmony_civoid UIFontCache::PutSpace(uint8_t* addr)
84a3e0fd82Sopenharmony_ci{
85a3e0fd82Sopenharmony_ci    if (addr == nullptr) {
86a3e0fd82Sopenharmony_ci        return;
87a3e0fd82Sopenharmony_ci    }
88a3e0fd82Sopenharmony_ci    Bitmap* bitmap = reinterpret_cast<Bitmap*>(addr - sizeof(Bitmap));
89a3e0fd82Sopenharmony_ci
90a3e0fd82Sopenharmony_ci    ListDel(&bitmap->hashHead);
91a3e0fd82Sopenharmony_ci    ListDel(&bitmap->lruHead);
92a3e0fd82Sopenharmony_ci
93a3e0fd82Sopenharmony_ci    allocator_.Free(bitmap);
94a3e0fd82Sopenharmony_ci}
95a3e0fd82Sopenharmony_ci
96a3e0fd82Sopenharmony_ciuint8_t* UIFontCache::GetBitmap(uint16_t fontKey, uint32_t unicode, TextStyle textStyle)
97a3e0fd82Sopenharmony_ci{
98a3e0fd82Sopenharmony_ci    Bitmap* bitmap = nullptr;
99a3e0fd82Sopenharmony_ci    ListHead* head = hashTable_ + unicode % FONT_CACHE_HASH_NR;
100a3e0fd82Sopenharmony_ci    for (ListHead* node = head->next; node != head; node = node->next) {
101a3e0fd82Sopenharmony_ci        bitmap = reinterpret_cast<struct Bitmap*>(reinterpret_cast<uint8_t*>(node) - offsetof(struct Bitmap, hashHead));
102a3e0fd82Sopenharmony_ci        if ((bitmap->fontId == fontKey) &&
103a3e0fd82Sopenharmony_ci#if defined(ENABLE_TEXT_STYLE) && ENABLE_TEXT_STYLE
104a3e0fd82Sopenharmony_ci            (bitmap->textStyle == textStyle) &&
105a3e0fd82Sopenharmony_ci#endif
106a3e0fd82Sopenharmony_ci            (bitmap->unicode == unicode)) {
107a3e0fd82Sopenharmony_ci            UpdateLru(bitmap);
108a3e0fd82Sopenharmony_ci            return reinterpret_cast<uint8_t*>(bitmap->data);
109a3e0fd82Sopenharmony_ci        }
110a3e0fd82Sopenharmony_ci    }
111a3e0fd82Sopenharmony_ci
112a3e0fd82Sopenharmony_ci    return nullptr;
113a3e0fd82Sopenharmony_ci}
114a3e0fd82Sopenharmony_ci} // namespace OHOS
115