1 /*
2  * Copyright (c) 2024 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_buffer.h"
17 
18 #include <algorithm>
19 
20 #include "face_data.h"
21 #include "font_manager.h"
22 
23 FONT_BEGIN_NAMESPACE()
FontBuffer(FontManager* fontMgr, const uint64_t hash, BASE_NS::array_view<const uint8_t> bytes)24 FontBuffer::FontBuffer(FontManager* fontMgr, const uint64_t hash, BASE_NS::array_view<const uint8_t> bytes)
25     : hash_(hash), bytes_(bytes.data(), bytes.data() + bytes.size()),
26       fontManager(BASE_NS::refcnt_ptr<FontManager>(fontMgr))
27 {}
28 
~FontBuffer()29 FontBuffer::~FontBuffer()
30 {
31     fontManager->Gc(hash_, this);
32 }
33 
CreateFace(long index)34 std::shared_ptr<FaceData> FontBuffer::CreateFace(long index)
35 {
36     {
37         std::shared_lock readerLock(mutex_);
38 
39         for (const auto& faceData : faces_) {
40             if (auto fromWeak = faceData.lock(); fromWeak && fromWeak->face_->face_index == index) {
41                 return fromWeak;
42             }
43         }
44     }
45     std::lock_guard writerLock(mutex_);
46 
47     for (const auto& faceData : faces_) {
48         if (auto fromWeak = faceData.lock(); fromWeak && fromWeak->face_->face_index == index) {
49             return fromWeak;
50         }
51     }
52 
53     auto ftFace = fontManager->OpenFtFace(bytes_, index);
54     if (!ftFace) {
55         return nullptr;
56     }
57 
58     auto face = std::make_shared<FaceData>(shared_from_this(), ftFace);
59 
60     faces_.push_back(face);
61     CORE_LOG_N("create FaceData %p", this);
62     return face;
63 }
64 
Gc()65 void FontBuffer::Gc()
66 {
67     std::lock_guard writerLock(mutex_);
68     faces_.erase(
69         std::remove_if(faces_.begin(), faces_.end(), [](const std::weak_ptr<FaceData>& ptr) { return ptr.expired(); }),
70         faces_.cend());
71 }
72 FONT_END_NAMESPACE()
73