#pragma once #include "ShaderTypes.h" #include #include #include #include namespace RenderCadenceCompositor { struct FontAtlasBuildConfig { std::filesystem::path repoRoot; std::filesystem::path cacheRoot; double sizePixelsPerEm = 128.0; double pixelRange = 8.0; std::string atlasType = "mtsdf"; }; struct FontAtlasBuildOutput { struct Glyph { double advance = 0.0; double planeLeft = 0.0; double planeTop = 0.0; double planeRight = 0.0; double planeBottom = 0.0; double atlasLeft = 0.0; double atlasTop = 0.0; double atlasRight = 0.0; double atlasBottom = 0.0; bool hasBounds = false; }; std::string fontId; std::filesystem::path imagePath; std::filesystem::path jsonPath; unsigned width = 0; unsigned height = 0; double ascender = -0.9; double descender = 0.25; double lineHeight = 1.2; std::vector rgbaPixels; std::map glyphsByCodepoint; }; class FontAtlasBuilder { public: explicit FontAtlasBuilder(FontAtlasBuildConfig config); bool BuildPackageFontAtlases( const ShaderPackage& shaderPackage, std::vector& outputs, std::string& error) const; bool BuildFontAtlas( const ShaderPackage& shaderPackage, const ShaderFontAsset& fontAsset, FontAtlasBuildOutput& output, std::string& error) const; static bool FindMsdfAtlasGenExecutable(const std::filesystem::path& repoRoot, std::filesystem::path& executablePath); private: std::filesystem::path PackageCacheDirectory(const ShaderPackage& shaderPackage) const; bool LoadAtlasJson(FontAtlasBuildOutput& output, std::string& error) const; bool LoadAtlasImage(FontAtlasBuildOutput& output, std::string& error) const; static std::string SanitizePathToken(const std::string& value); static bool RunProcess(const std::string& commandLine, const std::filesystem::path& workingDirectory, std::string& error); FontAtlasBuildConfig mConfig; }; }