18bf80f4bSopenharmony_ci/*
28bf80f4bSopenharmony_ci * Copyright (c) 2024 Huawei Device Co., Ltd.
38bf80f4bSopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License");
48bf80f4bSopenharmony_ci * you may not use this file except in compliance with the License.
58bf80f4bSopenharmony_ci * You may obtain a copy of the License at
68bf80f4bSopenharmony_ci *
78bf80f4bSopenharmony_ci *     http://www.apache.org/licenses/LICENSE-2.0
88bf80f4bSopenharmony_ci *
98bf80f4bSopenharmony_ci * Unless required by applicable law or agreed to in writing, software
108bf80f4bSopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS,
118bf80f4bSopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
128bf80f4bSopenharmony_ci * See the License for the specific language governing permissions and
138bf80f4bSopenharmony_ci * limitations under the License.
148bf80f4bSopenharmony_ci */
158bf80f4bSopenharmony_ci
168bf80f4bSopenharmony_ci#include "font_buffer.h"
178bf80f4bSopenharmony_ci
188bf80f4bSopenharmony_ci#include <algorithm>
198bf80f4bSopenharmony_ci
208bf80f4bSopenharmony_ci#include "face_data.h"
218bf80f4bSopenharmony_ci#include "font_manager.h"
228bf80f4bSopenharmony_ci
238bf80f4bSopenharmony_ciFONT_BEGIN_NAMESPACE()
248bf80f4bSopenharmony_ciFontBuffer::FontBuffer(FontManager* fontMgr, const uint64_t hash, BASE_NS::array_view<const uint8_t> bytes)
258bf80f4bSopenharmony_ci    : hash_(hash), bytes_(bytes.data(), bytes.data() + bytes.size()),
268bf80f4bSopenharmony_ci      fontManager(BASE_NS::refcnt_ptr<FontManager>(fontMgr))
278bf80f4bSopenharmony_ci{}
288bf80f4bSopenharmony_ci
298bf80f4bSopenharmony_ciFontBuffer::~FontBuffer()
308bf80f4bSopenharmony_ci{
318bf80f4bSopenharmony_ci    fontManager->Gc(hash_, this);
328bf80f4bSopenharmony_ci}
338bf80f4bSopenharmony_ci
348bf80f4bSopenharmony_cistd::shared_ptr<FaceData> FontBuffer::CreateFace(long index)
358bf80f4bSopenharmony_ci{
368bf80f4bSopenharmony_ci    {
378bf80f4bSopenharmony_ci        std::shared_lock readerLock(mutex_);
388bf80f4bSopenharmony_ci
398bf80f4bSopenharmony_ci        for (const auto& faceData : faces_) {
408bf80f4bSopenharmony_ci            if (auto fromWeak = faceData.lock(); fromWeak && fromWeak->face_->face_index == index) {
418bf80f4bSopenharmony_ci                return fromWeak;
428bf80f4bSopenharmony_ci            }
438bf80f4bSopenharmony_ci        }
448bf80f4bSopenharmony_ci    }
458bf80f4bSopenharmony_ci    std::lock_guard writerLock(mutex_);
468bf80f4bSopenharmony_ci
478bf80f4bSopenharmony_ci    for (const auto& faceData : faces_) {
488bf80f4bSopenharmony_ci        if (auto fromWeak = faceData.lock(); fromWeak && fromWeak->face_->face_index == index) {
498bf80f4bSopenharmony_ci            return fromWeak;
508bf80f4bSopenharmony_ci        }
518bf80f4bSopenharmony_ci    }
528bf80f4bSopenharmony_ci
538bf80f4bSopenharmony_ci    auto ftFace = fontManager->OpenFtFace(bytes_, index);
548bf80f4bSopenharmony_ci    if (!ftFace) {
558bf80f4bSopenharmony_ci        return nullptr;
568bf80f4bSopenharmony_ci    }
578bf80f4bSopenharmony_ci
588bf80f4bSopenharmony_ci    auto face = std::make_shared<FaceData>(shared_from_this(), ftFace);
598bf80f4bSopenharmony_ci
608bf80f4bSopenharmony_ci    faces_.push_back(face);
618bf80f4bSopenharmony_ci    CORE_LOG_N("create FaceData %p", this);
628bf80f4bSopenharmony_ci    return face;
638bf80f4bSopenharmony_ci}
648bf80f4bSopenharmony_ci
658bf80f4bSopenharmony_civoid FontBuffer::Gc()
668bf80f4bSopenharmony_ci{
678bf80f4bSopenharmony_ci    std::lock_guard writerLock(mutex_);
688bf80f4bSopenharmony_ci    faces_.erase(
698bf80f4bSopenharmony_ci        std::remove_if(faces_.begin(), faces_.end(), [](const std::weak_ptr<FaceData>& ptr) { return ptr.expired(); }),
708bf80f4bSopenharmony_ci        faces_.cend());
718bf80f4bSopenharmony_ci}
728bf80f4bSopenharmony_ciFONT_END_NAMESPACE()
73