/* * 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 "Scene/SdfFontAtlasGenerator.hpp" #include "Scene/BitmapFontAtlasGenerator.hpp" #include "Host/SystemFontResolver.hpp" #include "Base/Logger.hpp" #include "Host/ResourceLoader.hpp" #include namespace OpenVulkano::Scene { FontAtlasFactory::FontIdentifier::FontIdentifier(const std::string& font_, const std::set& charset, SubpixelLayout subpixelLayout_, float ptSize_, FontAtlasType atlasType_) : font(font_), subpixelLayout(subpixelLayout_), ptSize(ptSize_), atlasType(atlasType_) { std::for_each(charset.begin(), charset.end(), [&](uint32_t c) { charsetHash ^= c; }); } bool FontAtlasFactory::FontIdentifier::FontIdentifier::operator<(const FontIdentifier& other) const { return std::tie(atlasType, charsetHash, ptSize, subpixelLayout, font) < std::tie(other.atlasType, other.charsetHash, other.ptSize, other.subpixelLayout, other.font); } FontAtlas::Ptr FontAtlasFactory::GetFontAtlasScalable(const std::string& fontIdentifier, bool msdf, const std::set& charset) const { const auto& fontData = FindFont(fontIdentifier); if (fontData.Empty()) { Logger::DATA->warn("Could not find font {}", fontIdentifier); return nullptr; } const std::set& setRef = (charset.empty() ? FontAtlasGeneratorBase::LoadAllGlyphs(fontData) : charset); FontIdentifier id(fontIdentifier, setRef, SubpixelLayout::UNKNOWN, 0, msdf ? FontAtlasType::MSDF : FontAtlasType::SDF); auto it = m_atlasesCache.find(id); if (it != m_atlasesCache.end()) { return it->second; } if (msdf) { MsdfFontAtlasGenerator msdfGen; msdfGen.GenerateAtlas(fontData, setRef); return m_atlasesCache.insert({ id, msdfGen.GetAtlas() }).first->second; } SdfFontAtlasGenerator sdfGen; sdfGen.GenerateAtlas(fontData, setRef); return m_atlasesCache.insert({ id, sdfGen.GetAtlas() }).first->second; } FontAtlas::Ptr FontAtlasFactory::GetFontAtlas(const std::string& fontIdentifier, float ptSize, SubpixelLayout subpixelLayout, const std::set& charset) const { const auto& fontData = FindFont(fontIdentifier); if (fontData.Empty()) { Logger::DATA->warn("Could not find font {}", fontIdentifier); return nullptr; } const std::set& setRef = (charset.empty() ? FontAtlasGeneratorBase::LoadAllGlyphs(fontData) : charset); FontIdentifier id(fontIdentifier, setRef, subpixelLayout, ptSize, subpixelLayout ? FontAtlasType::BITMAP_SUBPIXEL : FontAtlasType::BITMAP); auto it = m_atlasesCache.find(id); if (it != m_atlasesCache.end()) { return it->second; } FontPixelSizeConfig cfg(ptSize); BitmapFontAtlasGenerator bitmapGen(cfg, subpixelLayout); bitmapGen.GenerateAtlas(fontData, setRef); return m_atlasesCache.insert({ id, bitmapGen.GetAtlas() }).first->second; } Array FontAtlasFactory::FindFont(const std::string& fontIdentifier) const { try { return ResourceLoader::GetInstance().GetResource(fontIdentifier); } catch (...) { } if (!std::filesystem::exists(fontIdentifier)) { if (!m_allowSystemFonts) { return {}; } return Utils::ReadFile(SystemFontResolver::GetSystemFontPath(fontIdentifier), true); } return Utils::ReadFile(fontIdentifier); } }