1/*
2 * Copyright (c) 2020-2022 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 *     http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16#include "font/ui_font_cache.h"
17#include <cstddef>
18#if defined(ENABLE_VECTOR_FONT) && ENABLE_VECTOR_FONT
19#include "gfx_utils/style.h"
20
21#endif
22namespace OHOS {
23UIFontCache::UIFontCache(uint8_t* ram, uint32_t size)
24{
25    if (ram == nullptr) {
26        return;
27    }
28    allocator_.SetRamAddr(ram, size);
29    allocator_.SetMinChunkSize(FONT_CACHE_MIN_SIZE + sizeof(Bitmap));
30
31    uint32_t hashTableSize = sizeof(ListHead) * FONT_CACHE_HASH_NR;
32    hashTable_ = reinterpret_cast<ListHead*>(allocator_.Allocate(hashTableSize));
33    for (uint8_t i = 0; i < FONT_CACHE_HASH_NR; i++) {
34        ListInit(hashTable_ + i);
35    }
36
37    ListInit(&lruList_);
38}
39
40UIFontCache::~UIFontCache() {}
41
42void UIFontCache::UpdateLru(Bitmap* bitmap)
43{
44    ListDel(&bitmap->lruHead);
45    ListInit(&bitmap->lruHead);
46    ListAdd(&bitmap->lruHead, &lruList_);
47}
48
49uint8_t* UIFontCache::GetSpace(uint16_t fontId, uint32_t unicode, uint32_t size, TextStyle textStyle)
50{
51    Bitmap* bitmap = nullptr;
52
53    uint32_t allocSize = sizeof(Bitmap) + size;
54    while (bitmap == nullptr) {
55        bitmap = reinterpret_cast<Bitmap*>(allocator_.Allocate(allocSize));
56        if (bitmap == nullptr) {
57            // nothing to free, return null
58            if ((lruList_.prev == &lruList_) && (lruList_.next == &lruList_)) {
59                return nullptr;
60            }
61            Bitmap* toFree = reinterpret_cast<struct Bitmap *>(reinterpret_cast<uint8_t *>(lruList_.prev) -
62                offsetof(struct Bitmap, lruHead));
63            ListDel(&toFree->hashHead);
64            ListDel(&toFree->lruHead);
65            allocator_.Free(toFree);
66        }
67    }
68
69    ListInit(&bitmap->hashHead);
70    ListInit(&bitmap->lruHead);
71    ListAdd(&bitmap->hashHead, hashTable_ + unicode % FONT_CACHE_HASH_NR);
72    ListAdd(&bitmap->lruHead, &lruList_);
73
74    bitmap->fontId = fontId;
75    bitmap->unicode = unicode;
76#if defined(ENABLE_TEXT_STYLE) && ENABLE_TEXT_STYLE
77    bitmap->textStyle = textStyle;
78#endif
79
80    return reinterpret_cast<uint8_t*>(bitmap->data);
81}
82
83void UIFontCache::PutSpace(uint8_t* addr)
84{
85    if (addr == nullptr) {
86        return;
87    }
88    Bitmap* bitmap = reinterpret_cast<Bitmap*>(addr - sizeof(Bitmap));
89
90    ListDel(&bitmap->hashHead);
91    ListDel(&bitmap->lruHead);
92
93    allocator_.Free(bitmap);
94}
95
96uint8_t* UIFontCache::GetBitmap(uint16_t fontKey, uint32_t unicode, TextStyle textStyle)
97{
98    Bitmap* bitmap = nullptr;
99    ListHead* head = hashTable_ + unicode % FONT_CACHE_HASH_NR;
100    for (ListHead* node = head->next; node != head; node = node->next) {
101        bitmap = reinterpret_cast<struct Bitmap*>(reinterpret_cast<uint8_t*>(node) - offsetof(struct Bitmap, hashHead));
102        if ((bitmap->fontId == fontKey) &&
103#if defined(ENABLE_TEXT_STYLE) && ENABLE_TEXT_STYLE
104            (bitmap->textStyle == textStyle) &&
105#endif
106            (bitmap->unicode == unicode)) {
107            UpdateLru(bitmap);
108            return reinterpret_cast<uint8_t*>(bitmap->data);
109        }
110    }
111
112    return nullptr;
113}
114} // namespace OHOS
115