/* * This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ #include "FontAtlasFactory.hpp" #include "SdfFontAtlasGenerator.hpp" #include "BitmapFontAtlasGenerator.hpp" #include "Host/SystemFontResolver.hpp" #include "Base/Logger.hpp" #include "Host/ResourceLoader.hpp" #include namespace OpenVulkano::Scene { FontAtlasFactory FontAtlasFactory::INSTANCE = FontAtlasFactory(); // Global factory bool FontAtlasFactory::FontIdentifier::FontIdentifier::operator<(const FontIdentifier& other) const { if (atlasType < other.atlasType) return true; if (atlasType > other.atlasType) return false; if (atlasType.IsSDF()) { return font < other.font; } return std::tie(ptSize, subpixelLayout, font) < std::tie(other.ptSize, other.subpixelLayout, other.font); } FontAtlas::Ptr FontAtlasFactory::GetFontAtlasScalable(const std::string& fontIdentifier, bool msdf, const std::set& charset) const { FontIdentifier id(fontIdentifier, msdf ? FontAtlasType::MSDF : FontAtlasType::SDF); auto it = m_atlasesCache.find(id); if (it != m_atlasesCache.end()) { return it->second; } Array ovFontData = ResourceLoader::GetInstance().GetResource(fontIdentifier + ".ovfont"); if (!ovFontData.Empty()) { auto atlas = std::make_shared(ovFontData); m_atlasesCache[FontIdentifier(fontIdentifier, atlas->GetAtlasType())] = atlas; return atlas; } const auto& fontData = FindFont(fontIdentifier); if (fontData.Empty()) { Logger::DATA->warn("Could not find font {}", fontIdentifier); return nullptr; } FontAtlas::Ptr atlas; if (msdf) { MsdfFontAtlasGenerator msdfGen; msdfGen.GenerateAtlas(fontData, charset); atlas = msdfGen.GetAtlas(); } else { SdfFontAtlasGenerator sdfGen; sdfGen.GenerateAtlas(fontData, charset); atlas = sdfGen.GetAtlas(); } if (charset.empty()) m_atlasesCache.emplace(id, atlas); return atlas; } FontAtlas::Ptr FontAtlasFactory::GetFontAtlas(const std::string& fontIdentifier, float ptSize, SubpixelLayout subpixelLayout, const std::set& charset) const { FontIdentifier id(fontIdentifier, subpixelLayout ? FontAtlasType::BITMAP_SUBPIXEL : FontAtlasType::BITMAP, subpixelLayout, ptSize); auto it = m_atlasesCache.find(id); if (it != m_atlasesCache.end()) { return it->second; } const auto& fontData = FindFont(fontIdentifier); if (fontData.Empty()) { Logger::DATA->warn("Could not find font {}", fontIdentifier); return nullptr; } FontPixelSizeConfig cfg(ptSize); BitmapFontAtlasGenerator bitmapGen(cfg, subpixelLayout); bitmapGen.GenerateAtlas(fontData, charset); if (charset.empty()) m_atlasesCache.emplace(id, bitmapGen.GetAtlas()); return bitmapGen.GetAtlas(); } Array FontAtlasFactory::FindFont(const std::string& fontIdentifier) const { Array resource = ResourceLoader::GetInstance().GetResource(fontIdentifier); if (resource.Empty()) { if (!std::filesystem::exists(fontIdentifier)) { if (!m_allowSystemFonts) { return {}; } return Utils::ReadFile(SystemFontResolver::GetSystemFontPath(fontIdentifier), true); } return Utils::ReadFile(fontIdentifier); } return resource; } }