Files
o3de/Gems/AtomLyIntegration/AtomFont/Code/Source/FFontXML_Internal.h
T
Esteban Papp 1f9b284de2 Merge branch 'development' into cmake/SPEC-7179
Signed-off-by: Esteban Papp <81431996+amznestebanpapp@users.noreply.github.com>

# Conflicts:
#	Code/Editor/Plugins/ComponentEntityEditorPlugin/ComponentEntityEditorPlugin_precompiled.h
#	Code/Editor/Plugins/EditorCommon/EditorCommon_precompiled.h
#	Code/Editor/Plugins/EditorCommon/stdafx.cpp
#	Code/Editor/Plugins/FFMPEGPlugin/FFMPEGPlugin_precompiled.h
#	Code/Editor/Plugins/PerforcePlugin/PerforcePlugin_precompiled.h
#	Code/Editor/Plugins/ProjectSettingsTool/ProjectSettingsTool_precompiled.h
#	Code/Framework/AzToolsFramework/AzToolsFramework/AzToolsFramework_precompiled.h
#	Code/Tools/AssetProcessor/native/precompiled.h
#	Code/Tools/Standalone/StandaloneTools_precompiled.h
#	Gems/AssetMemoryAnalyzer/Code/Source/AssetMemoryAnalyzer_precompiled.h
#	Gems/Atom/Asset/ImageProcessingAtom/Code/Source/ImageProcessing_precompiled.h
#	Gems/Atom/RHI/DX12/Code/Source/RHI/Atom_RHI_DX12_precompiled.h
#	Gems/Atom/RHI/Metal/Code/Include/Platform/Mac/Atom_RHI_Metal_precompiled_Platform.h
#	Gems/Atom/RHI/Metal/Code/Include/Platform/iOS/Atom_RHI_Metal_precompiled_Platform.h
#	Gems/Atom/RHI/Metal/Code/Source/Atom_RHI_Metal_precompiled.h
#	Gems/Atom/RHI/Metal/Code/atom_rhi_metal_common_files.cmake
#	Gems/Atom/RHI/Null/Code/Source/Atom_RHI_Null_precompiled.h
#	Gems/Atom/RHI/Null/Code/atom_rhi_null_common_files.cmake
#	Gems/Atom/RHI/Vulkan/Code/Include/Platform/Android/Atom_RHI_Vulkan_precompiled_Platform.h
#	Gems/Atom/RHI/Vulkan/Code/Include/Platform/Linux/Atom_RHI_Vulkan_precompiled_Platform.h
#	Gems/Atom/RHI/Vulkan/Code/Include/Platform/Mac/Atom_RHI_Vulkan_precompiled_Platform.h
#	Gems/Atom/RHI/Vulkan/Code/Include/Platform/Windows/Atom_RHI_Vulkan_precompiled_Platform.h
#	Gems/Atom/RHI/Vulkan/Code/Source/Atom_RHI_Vulkan_precompiled.h
#	Gems/Atom/RHI/Vulkan/Code/Source/RHI/SwapChain.cpp
#	Gems/Atom/RHI/Vulkan/Code/atom_rhi_vulkan_common_files.cmake
#	Gems/AtomLyIntegration/AtomFont/Code/Include/AtomLyIntegration/AtomFont/AtomFont_precompiled.h
#	Gems/Blast/Code/Source/StdAfx.cpp
#	Gems/Camera/Code/Source/Camera_precompiled.h
#	Gems/EMotionFX/Code/Source/EMotionFX_precompiled.h
#	Gems/FastNoise/Code/Source/FastNoise_precompiled.h
#	Gems/Gestures/Code/Source/Gestures_precompiled.h
#	Gems/GradientSignal/Code/Source/GradientSignal_precompiled.h
#	Gems/GraphCanvas/Code/precompiled.h
#	Gems/ImGui/Code/Source/ImGui_precompiled.h
#	Gems/InAppPurchases/Code/Source/InAppPurchases_precompiled.h
#	Gems/LmbrCentral/Code/Source/LmbrCentral_precompiled.h
#	Gems/LmbrCentral/Code/Tests/ShapeGeometryUtilTest.cpp
#	Gems/LyShine/Code/Editor/UiCanvasEditor_precompiled.h
#	Gems/LyShine/Code/Source/Animation/LyShine_precompiled.h
#	Gems/LyShine/Code/Source/LyShine_precompiled.h
#	Gems/LyShineExamples/Code/Source/LyShineExamples_precompiled.h
#	Gems/Maestro/Code/Source/Cinematics/Maestro_precompiled.h
#	Gems/Maestro/Code/Source/Maestro_precompiled.h
#	Gems/MessagePopup/Code/Source/MessagePopup_precompiled.h
#	Gems/Metastream/Code/Source/Metastream_precompiled.h
#	Gems/Microphone/Code/Source/Microphone_precompiled.h
#	Gems/Multiplayer/Code/Source/Multiplayer_precompiled.h
#	Gems/PhysX/Code/NumericalMethods/Source/NumericalMethods_precompiled.h
#	Gems/PhysX/Code/Source/PhysXUnsupported_precompiled.h
#	Gems/PhysX/Code/Source/PhysX_precompiled.h
#	Gems/PhysX/Code/physx_unsupported_files.cmake
#	Gems/PhysXDebug/Code/Source/PhysXDebugUnsupported_precompiled.h
#	Gems/PhysXDebug/Code/Source/PhysXDebug_precompiled.h
#	Gems/ScriptCanvas/Code/Editor/precompiled.h
#	Gems/ScriptCanvas/Code/Source/precompiled.h
#	Gems/ScriptCanvasDeveloper/Code/Source/precompiled.h
#	Gems/ScriptCanvasPhysics/Code/Source/ScriptCanvasPhysics_precompiled.h
#	Gems/ScriptEvents/Code/Source/precompiled.h
#	Gems/ScriptEvents/Code/Tests/Editor/EditorTests.cpp
#	Gems/ScriptedEntityTweener/Code/Source/ScriptedEntityTweener_precompiled.h
#	Gems/SliceFavorites/Code/Source/SliceFavorites_precompiled.h
#	Gems/StartingPointCamera/Code/Source/StartingPointCamera_precompiled.h
#	Gems/StartingPointInput/Code/Source/StartingPointInput_precompiled.h
#	Gems/StartingPointMovement/Code/Source/StartingPointMovement_precompiled.h
#	Gems/SurfaceData/Code/Source/SurfaceData_precompiled.h
#	Gems/TextureAtlas/Code/Source/TextureAtlas_precompiled.h
#	Gems/TickBusOrderViewer/Code/Source/TickBusOrderViewer_precompiled.h
#	Gems/Twitch/Code/Source/Twitch_precompiled.h
#	Gems/VirtualGamepad/Code/Source/VirtualGamepad_precompiled.h
#	Gems/WhiteBox/Code/Source/WhiteBoxUnsupported_precompiled.h
#	Gems/WhiteBox/Code/Source/WhiteBox_precompiled.h
2021-07-16 15:42:37 -07:00

404 lines
12 KiB
C++

/*
* Copyright (c) Contributors to the Open 3D Engine Project.
* For complete copyright and license terms please see the LICENSE at the root of this distribution.
*
* SPDX-License-Identifier: Apache-2.0 OR MIT
*
*/
#pragma once
#if !defined(USE_NULLFONT_ALWAYS)
#include <AtomLyIntegration/AtomFont/FFont.h>
#include <AtomLyIntegration/AtomFont/FontTexture.h>
#include <CryCommon/Cry_Math.h>
#include <CryCommon/CryPath.h>
#include <AzCore/PlatformIncl.h>
//////////////////////////////////////////////////////////////////////////
// Xml parser implementation
namespace AtomFontInternal
{
enum
{
ELEMENT_UNKNOWN = 0,
ELEMENT_FONT = 1,
ELEMENT_EFFECT = 2,
ELEMENT_EFFECTFILE = 3,
ELEMENT_PASS = 4,
ELEMENT_PASS_COLOR = 5,
ELEMENT_PASS_POSOFFSET = 12,
ELEMENT_PASS_BLEND = 14
};
inline int GetBlendModeFromString(const string& str, bool dst)
{
int blend = GS_BLSRC_ONE;
if (str == "zero")
{
blend = dst ? GS_BLDST_ZERO : GS_BLSRC_ZERO;
}
else if (str == "one")
{
blend = dst ? GS_BLDST_ONE : GS_BLSRC_ONE;
}
else if (str == "srcalpha" ||
str == "src_alpha")
{
blend = dst ? GS_BLDST_SRCALPHA : GS_BLSRC_SRCALPHA;
}
else if (str == "invsrcalpha" ||
str == "inv_src_alpha")
{
blend = dst ? GS_BLDST_ONEMINUSSRCALPHA : GS_BLSRC_ONEMINUSSRCALPHA;
}
else if (str == "dstalpha" ||
str == "dst_alpha")
{
blend = dst ? GS_BLDST_DSTALPHA : GS_BLSRC_DSTALPHA;
}
else if (str == "invdstalpha" ||
str == "inv_dst_alpha")
{
blend = dst ? GS_BLDST_ONEMINUSDSTALPHA : GS_BLSRC_ONEMINUSDSTALPHA;
}
else if (str == "dstcolor" ||
str == "dst_color")
{
blend = GS_BLSRC_DSTCOL;
}
else if (str == "srccolor" ||
str == "src_color")
{
blend = GS_BLDST_SRCCOL;
}
else if (str == "invdstcolor" ||
str == "inv_dst_color")
{
blend = GS_BLSRC_ONEMINUSDSTCOL;
}
else if (str == "invsrccolor" ||
str == "inv_src_color")
{
blend = GS_BLDST_ONEMINUSSRCCOL;
}
return blend;
}
inline int CreateTTFFontFlag(AZ::FontSmoothMethod smoothMethod, AZ::FontSmoothAmount smoothAmount)
{
return (
((static_cast<int>(smoothMethod) << TTFFLAG_SMOOTH_SHIFT) & TTFFLAG_SMOOTH_MASK) |
((static_cast<int>(smoothAmount) << TTFFLAG_SMOOTH_AMOUNT_SHIFT) & TTFFLAG_SMOOTH_AMOUNT_MASK)
);
}
inline AZ::FontSmoothMethod TranslateSmoothMethod(const string& value)
{
AZ::FontSmoothMethod smoothMethod = AZ::FontSmoothMethod::None;
if (value == "blur")
{
smoothMethod = AZ::FontSmoothMethod::Blur;
}
else if (value == "supersample")
{
smoothMethod = AZ::FontSmoothMethod::SuperSample;
}
return smoothMethod;
}
inline AZ::FontSmoothAmount TranslateSmoothAmount(int value)
{
AZ::FontSmoothAmount smoothAmount = AZ::FontSmoothAmount::None;
if (value == 1)
{
smoothAmount = AZ::FontSmoothAmount::x2;
}
else if (value > 1)
{
smoothAmount = AZ::FontSmoothAmount::x4;
}
return smoothAmount;
}
class XmlFontShader
{
static const int DefaultSlotWidthSize = 16;
static const int DefaultSlotHeightSize = 8;
public:
XmlFontShader(AZ::FFont* font)
: m_font(font)
, m_nElement(ELEMENT_UNKNOWN)
, m_slotSizes(DefaultSlotWidthSize, DefaultSlotHeightSize)
, m_effect(NULL)
, m_pass(NULL)
, m_FontTexSize(0, 0)
, m_FontSmoothAmount(AZ::FontSmoothAmount::None)
, m_FontSmoothMethod(AZ::FontSmoothMethod::None)
{
}
~XmlFontShader()
{
}
void ScanXmlNodesRecursively(XmlNodeRef node)
{
if (!node)
{
return;
}
FoundElement(node->getTag());
for (int i = 0, count = node->getNumAttributes(); i < count; ++i)
{
const char* key = "";
const char* value = "";
if (node->getAttributeByIndex(i, &key, &value))
{
FoundAttribute(key, value);
}
}
for (int i = 0, count = node->getChildCount(); i < count; ++i)
{
XmlNodeRef child = node->getChild(i);
ScanXmlNodesRecursively(child);
}
}
private:
void FoundElementImpl();
// notify methods
void FoundElement(const string& name)
{
//MessageBox(NULL, string("[" + name + "]").c_str(), "FoundElement", MB_OK);
// process the previous element
switch (m_nElement)
{
case ELEMENT_FONT:
{
if (!m_FontTexSize.x || !m_FontTexSize.y)
{
m_FontTexSize.set(512, 512);
}
bool fontLoaded = m_font->Load(m_strFontPath.c_str(), m_FontTexSize.x, m_FontTexSize.y, m_slotSizes.x, m_slotSizes.y, CreateTTFFontFlag(m_FontSmoothMethod, m_FontSmoothAmount), m_SizeRatio);
if (!fontLoaded)
{
FoundElementImpl();
}
}
break;
default:
break;
}
// Translate the m_nElement name to a define
if (name == "font")
{
m_nElement = ELEMENT_FONT;
}
else if (name == "effect")
{
m_nElement = ELEMENT_EFFECT;
}
else if (name == "effectfile")
{
m_nElement = ELEMENT_EFFECTFILE;
}
else if (name == "pass")
{
m_pass = NULL;
m_nElement = ELEMENT_PASS;
if (m_effect)
{
m_pass = m_effect->AddPass();
}
}
else if (name == "color")
{
m_nElement = ELEMENT_PASS_COLOR;
}
else if (name == "pos" ||
name == "offset")
{
m_nElement = ELEMENT_PASS_POSOFFSET;
}
else if (name == "blend" ||
name == "blending")
{
m_nElement = ELEMENT_PASS_BLEND;
}
else
{
m_nElement = ELEMENT_UNKNOWN;
}
}
void FoundAttribute(const string& name, const string& value)
{
//MessageBox(NULL, string(name + "\n" + value).c_str(), "FoundAttribute", MB_OK);
switch (m_nElement)
{
case ELEMENT_FONT:
if (name == "path")
{
m_strFontPath = value;
}
else if (name == "w")
{
m_FontTexSize.x = (long)atof(value.c_str());
}
else if (name == "h")
{
m_FontTexSize.y = (long)atof(value.c_str());
}
else if (name == "widthslots")
{
m_slotSizes.x = (int)atoi(value.c_str());
}
else if (name == "heightslots")
{
m_slotSizes.y = (int)atoi(value.c_str());
}
else if (name == "sizeratio")
{
m_SizeRatio = static_cast<float>(atof(value.c_str()));
}
else if (name == "smooth")
{
m_FontSmoothMethod = TranslateSmoothMethod(value);
}
else if (name == "smooth_amount")
{
m_FontSmoothAmount = TranslateSmoothAmount((int)atof(value.c_str()));
}
break;
case ELEMENT_EFFECT:
if (name == "name")
{
if (value == "default")
{
m_effect = m_font->GetDefaultEffect();
m_effect->ClearPasses();
}
else
{
m_effect = m_font->AddEffect(value.c_str());
}
}
break;
case ELEMENT_EFFECTFILE:
if (name == "path")
{
m_strFontEffectPath = value;
}
break;
case ELEMENT_PASS_COLOR:
if (!m_pass)
{
break;
}
if (name == "r")
{
m_pass->m_color.r = (uint8_t)((float)atof(value.c_str()) * 255.0f);
}
else if (name == "g")
{
m_pass->m_color.g = (uint8_t)((float)atof(value.c_str()) * 255.0f);
}
else if (name == "b")
{
m_pass->m_color.b = (uint8_t)((float)atof(value.c_str()) * 255.0f);
}
else if (name == "a")
{
m_pass->m_color.a = (uint8_t)((float)atof(value.c_str()) * 255.0f);
}
break;
case ELEMENT_PASS_POSOFFSET:
if (!m_pass)
{
break;
}
if (name == "x")
{
m_pass->m_posOffset.x = (float)atoi(value.c_str());
}
else if (name == "y")
{
m_pass->m_posOffset.y = (float)atoi(value.c_str());
}
break;
case ELEMENT_PASS_BLEND:
if (!m_pass)
{
break;
}
if (name == "src")
{
m_pass->m_blendSrc = GetBlendModeFromString(value, false);
}
else if (name == "dst")
{
m_pass->m_blendDest = GetBlendModeFromString(value, true);
}
else if (name == "type")
{
if (value == "modulate")
{
m_pass->m_blendSrc = GS_BLSRC_SRCALPHA;
m_pass->m_blendDest = GS_BLDST_ONEMINUSSRCALPHA;
}
else if (value == "additive")
{
m_pass->m_blendSrc = GS_BLSRC_SRCALPHA;
m_pass->m_blendDest = GS_BLDST_ONE;
}
}
break;
default:
case ELEMENT_UNKNOWN:
break;
}
}
public:
AZ::FFont* m_font;
unsigned long m_nElement;
AZ::FFont::FontEffect* m_effect;
AZ::FFont::FontRenderingPass* m_pass;
string m_strFontPath;
string m_strFontEffectPath;
vector2l m_FontTexSize;
AZ::AtomFont::GlyphSize m_slotSizes;
float m_SizeRatio = IFFontConstants::defaultSizeRatio;
AZ::FontSmoothMethod m_FontSmoothMethod;
AZ::FontSmoothAmount m_FontSmoothAmount;
};
}
#endif