Initial font work

This commit is contained in:
2026-05-05 23:18:50 +10:00
parent fd0ebb8d40
commit 3e8b472f74
20 changed files with 873 additions and 84 deletions

View File

@@ -67,6 +67,11 @@ bool ParseShaderParameterType(const std::string& typeName, ShaderParameterType&
type = ShaderParameterType::Enum;
return true;
}
if (typeName == "text")
{
type = ShaderParameterType::Text;
return true;
}
return false;
}
@@ -283,6 +288,49 @@ bool ParseTextureAssets(const JsonValue& manifestJson, ShaderPackage& shaderPack
return true;
}
bool ParseFontAssets(const JsonValue& manifestJson, ShaderPackage& shaderPackage, const std::filesystem::path& manifestPath, std::string& error)
{
const JsonValue* fontsValue = nullptr;
if (!OptionalArrayField(manifestJson, "fonts", fontsValue, manifestPath, error))
return false;
if (!fontsValue)
return true;
for (const JsonValue& fontJson : fontsValue->asArray())
{
if (!fontJson.isObject())
{
error = "Shader font entry must be an object in: " + ManifestPathMessage(manifestPath);
return false;
}
std::string fontId;
std::string fontPath;
if (!RequireNonEmptyStringField(fontJson, "id", fontId, manifestPath, error) ||
!RequireNonEmptyStringField(fontJson, "path", fontPath, manifestPath, error))
{
error = "Shader font is missing required 'id' or 'path' in: " + ManifestPathMessage(manifestPath);
return false;
}
if (!ValidateShaderIdentifier(fontId, "fonts[].id", manifestPath, error))
return false;
ShaderFontAsset fontAsset;
fontAsset.id = fontId;
fontAsset.path = shaderPackage.directoryPath / fontPath;
if (!std::filesystem::exists(fontAsset.path))
{
error = "Shader font asset not found for package " + shaderPackage.id + ": " + fontAsset.path.string();
return false;
}
fontAsset.writeTime = std::filesystem::last_write_time(fontAsset.path);
shaderPackage.fontAssets.push_back(fontAsset);
}
return true;
}
bool ParseTemporalSettings(const JsonValue& manifestJson, ShaderPackage& shaderPackage, unsigned maxTemporalHistoryFrames, const std::filesystem::path& manifestPath, std::string& error)
{
const JsonValue* temporalValue = nullptr;
@@ -365,6 +413,17 @@ bool ParseParameterDefault(const JsonValue& parameterJson, ShaderParameterDefini
return true;
}
if (definition.type == ShaderParameterType::Text)
{
if (!defaultValue->isString())
{
error = "Text parameter default must be a string for: " + definition.id;
return false;
}
definition.defaultTextValue = defaultValue->asString();
return true;
}
return NumberListFromJsonValue(*defaultValue, definition.defaultNumbers, "default", manifestPath, error);
}
@@ -447,6 +506,30 @@ bool ParseParameterDefinition(const JsonValue& parameterJson, ShaderParameterDef
return false;
}
if (definition.type == ShaderParameterType::Text)
{
if (const JsonValue* fontValue = parameterJson.find("font"))
{
if (!fontValue->isString())
{
error = "Text parameter 'font' must be a string for: " + definition.id;
return false;
}
definition.fontId = fontValue->asString();
if (!definition.fontId.empty() && !ValidateShaderIdentifier(definition.fontId, "parameters[].font", manifestPath, error))
return false;
}
if (const JsonValue* maxLengthValue = parameterJson.find("maxLength"))
{
if (!maxLengthValue->isNumber() || maxLengthValue->asNumber() < 1.0 || maxLengthValue->asNumber() > 256.0)
{
error = "Text parameter 'maxLength' must be a number from 1 to 256 for: " + definition.id;
return false;
}
definition.maxLength = static_cast<unsigned>(maxLengthValue->asNumber());
}
}
if (definition.type == ShaderParameterType::Enum)
return ParseParameterOptions(parameterJson, definition, manifestPath, error);
@@ -544,6 +627,7 @@ bool ShaderPackageRegistry::ParseManifest(const std::filesystem::path& manifestP
shaderPackage.manifestWriteTime = std::filesystem::last_write_time(shaderPackage.manifestPath);
return ParseTextureAssets(manifestJson, shaderPackage, manifestPath, error) &&
ParseFontAssets(manifestJson, shaderPackage, manifestPath, error) &&
ParseTemporalSettings(manifestJson, shaderPackage, mMaxTemporalHistoryFrames, manifestPath, error) &&
ParseParameterDefinitions(manifestJson, shaderPackage, manifestPath, error);
}