Files
OpenVulkano/openVulkanoCpp/Scene/Text/FontAtlasFactory.cpp

117 lines
3.4 KiB
C++

/*
* 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 <utility>
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<uint32_t>& 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<char> ovFontData = ResourceLoader::GetInstance().GetResource(fontIdentifier + ".ovfont");
if (!ovFontData.Empty())
{
auto atlas = std::make_shared<FontAtlas>(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<uint32_t>& 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<char> FontAtlasFactory::FindFont(const std::string& fontIdentifier) const
{
Array<char> 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;
}
}