Initial font work
This commit is contained in:
@@ -133,6 +133,7 @@ std::string ShaderParameterTypeToString(ShaderParameterType type)
|
||||
case ShaderParameterType::Color: return "color";
|
||||
case ShaderParameterType::Boolean: return "bool";
|
||||
case ShaderParameterType::Enum: return "enum";
|
||||
case ShaderParameterType::Text: return "text";
|
||||
}
|
||||
return "unknown";
|
||||
}
|
||||
@@ -179,6 +180,11 @@ bool ParseShaderParameterType(const std::string& typeName, ShaderParameterType&
|
||||
type = ShaderParameterType::Enum;
|
||||
return true;
|
||||
}
|
||||
if (typeName == "text")
|
||||
{
|
||||
type = ShaderParameterType::Text;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -200,6 +206,24 @@ bool TextureAssetsEqual(const std::vector<ShaderTextureAsset>& left, const std::
|
||||
return true;
|
||||
}
|
||||
|
||||
bool FontAssetsEqual(const std::vector<ShaderFontAsset>& left, const std::vector<ShaderFontAsset>& right)
|
||||
{
|
||||
if (left.size() != right.size())
|
||||
return false;
|
||||
|
||||
for (std::size_t index = 0; index < left.size(); ++index)
|
||||
{
|
||||
if (left[index].id != right[index].id ||
|
||||
left[index].path != right[index].path ||
|
||||
left[index].writeTime != right[index].writeTime)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
std::string ManifestPathMessage(const std::filesystem::path& manifestPath)
|
||||
{
|
||||
return manifestPath.string();
|
||||
@@ -379,6 +403,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;
|
||||
@@ -461,6 +528,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);
|
||||
}
|
||||
|
||||
@@ -543,6 +621,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);
|
||||
|
||||
@@ -693,7 +795,8 @@ bool RuntimeHost::PollFileChanges(bool& registryChanged, bool& reloadRequested,
|
||||
}
|
||||
if (previous->second.shaderWriteTime != item.second.shaderWriteTime ||
|
||||
previous->second.manifestWriteTime != item.second.manifestWriteTime ||
|
||||
!TextureAssetsEqual(previous->second.textureAssets, item.second.textureAssets))
|
||||
!TextureAssetsEqual(previous->second.textureAssets, item.second.textureAssets) ||
|
||||
!FontAssetsEqual(previous->second.fontAssets, item.second.fontAssets))
|
||||
{
|
||||
registryChanged = true;
|
||||
break;
|
||||
@@ -714,7 +817,8 @@ bool RuntimeHost::PollFileChanges(bool& registryChanged, bool& reloadRequested,
|
||||
if (previous->second.first != active->second.shaderWriteTime ||
|
||||
previous->second.second != active->second.manifestWriteTime ||
|
||||
(previousPackage != previousPackages.end() &&
|
||||
!TextureAssetsEqual(previousPackage->second.textureAssets, active->second.textureAssets)))
|
||||
(!TextureAssetsEqual(previousPackage->second.textureAssets, active->second.textureAssets) ||
|
||||
!FontAssetsEqual(previousPackage->second.fontAssets, active->second.fontAssets))))
|
||||
{
|
||||
mReloadRequested = true;
|
||||
}
|
||||
@@ -1143,6 +1247,7 @@ std::vector<RuntimeRenderState> RuntimeHost::GetLayerRenderStates(unsigned outpu
|
||||
state.outputHeight = outputHeight;
|
||||
state.parameterDefinitions = shaderIt->second.parameters;
|
||||
state.textureAssets = shaderIt->second.textureAssets;
|
||||
state.fontAssets = shaderIt->second.fontAssets;
|
||||
state.isTemporal = shaderIt->second.temporal.enabled;
|
||||
state.temporalHistorySource = shaderIt->second.temporal.historySource;
|
||||
state.requestedTemporalHistoryLength = shaderIt->second.temporal.requestedHistoryLength;
|
||||
@@ -1447,6 +1552,7 @@ bool RuntimeHost::ParseShaderManifest(const std::filesystem::path& manifestPath,
|
||||
shaderPackage.manifestWriteTime = std::filesystem::last_write_time(shaderPackage.manifestPath);
|
||||
|
||||
return ParseTextureAssets(manifestJson, shaderPackage, manifestPath, error) &&
|
||||
ParseFontAssets(manifestJson, shaderPackage, manifestPath, error) &&
|
||||
ParseTemporalSettings(manifestJson, shaderPackage, mConfig.maxTemporalHistoryFrames, manifestPath, error) &&
|
||||
ParseParameterDefinitions(manifestJson, shaderPackage, manifestPath, error);
|
||||
}
|
||||
@@ -1692,6 +1798,12 @@ JsonValue RuntimeHost::SerializeLayerStackLocked() const
|
||||
}
|
||||
parameter.set("options", options);
|
||||
}
|
||||
if (definition.type == ShaderParameterType::Text)
|
||||
{
|
||||
parameter.set("maxLength", JsonValue(static_cast<double>(definition.maxLength)));
|
||||
if (!definition.fontId.empty())
|
||||
parameter.set("font", JsonValue(definition.fontId));
|
||||
}
|
||||
|
||||
ShaderParameterValue value = DefaultValueForDefinition(definition);
|
||||
auto valueIt = layer.parameterValues.find(definition.id);
|
||||
@@ -1830,6 +1942,8 @@ JsonValue RuntimeHost::SerializeParameterValue(const ShaderParameterDefinition&
|
||||
return JsonValue(value.booleanValue);
|
||||
case ShaderParameterType::Enum:
|
||||
return JsonValue(value.enumValue);
|
||||
case ShaderParameterType::Text:
|
||||
return JsonValue(value.textValue);
|
||||
case ShaderParameterType::Float:
|
||||
return JsonValue(value.numberValues.empty() ? 0.0 : value.numberValues.front());
|
||||
case ShaderParameterType::Vec2:
|
||||
|
||||
Reference in New Issue
Block a user