Remove CryFont and initialization functions related to the legacy renderer. (#485)

- Remove CryFont and initialization functions related to the legacy renderer.
- Remove some references to Code/Tools/RC from mac CMake scripts.
This commit is contained in:
bosnichd
2021-04-30 15:02:11 -06:00
committed by GitHub
parent 59811cb3a8
commit a7c6638064
35 changed files with 30 additions and 6822 deletions
-1
View File
@@ -10,5 +10,4 @@
#
add_subdirectory(CryCommon)
add_subdirectory(CryFont)
add_subdirectory(CrySystem)
-35
View File
@@ -1,35 +0,0 @@
/*
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
* its licensors.
*
* For complete copyright and license terms please see the LICENSE at the root of this
* distribution (the "License"). All use of this software is governed by the License,
* or, if provided, by the license below or the license accompanying this file. Do not
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*/
#pragma once
#include <AzCore/EBus/EBus.h>
#include <CryCommon/ISystem.h>
namespace AZ
{
/*!
* Signal LY to create an ICryFont
*/
class CryFontCreationRequests
: public AZ::EBusTraits
{
public:
using MutexType = AZStd::recursive_mutex;
static const AZ::EBusHandlerPolicy HandlerPolicy = AZ::EBusHandlerPolicy::Single;
static const AZ::EBusAddressPolicy AddressPolicy = AZ::EBusAddressPolicy::Single;
virtual bool CreateCryFont([[maybe_unused]] SSystemGlobalEnvironment& env, [[maybe_unused]] const SSystemInitParams& initParams) {return false;} //! return false to fall back to default CryFont initialization
};
using CryFontCreationRequestBus = AZ::EBus<CryFontCreationRequests>;
}
-24
View File
@@ -1,24 +0,0 @@
#
# All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
# its licensors.
#
# For complete copyright and license terms please see the LICENSE at the root of this
# distribution (the "License"). All use of this software is governed by the License,
# or, if provided, by the license below or the license accompanying this file. Do not
# remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
#
ly_add_target(
NAME CryFont ${PAL_TRAIT_MONOLITHIC_DRIVEN_LIBRARY_TYPE}
NAMESPACE Legacy
FILES_CMAKE
cryfont_files.cmake
INCLUDE_DIRECTORIES
PRIVATE
.
BUILD_DEPENDENCIES
PRIVATE
3rdParty::freetype
Legacy::CryCommon
)
-845
View File
@@ -1,845 +0,0 @@
/*
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
* its licensors.
*
* For complete copyright and license terms please see the LICENSE at the root of this
* distribution (the "License"). All use of this software is governed by the License,
* or, if provided, by the license below or the license accompanying this file. Do not
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
*/
// Original file Copyright Crytek GMBH or its affiliates, used under license.
// Description : CCryFont class.
#include "CryFont_precompiled.h"
#if !defined(USE_NULLFONT_ALWAYS)
#include "CryFont.h"
#include "CryPath.h"
#include "FFont.h"
#include "FontTexture.h"
#include "FontRenderer.h"
#include "ILocalizationManager.h"
#include <AzCore/std/string/conversions.h>
#include <AzFramework/Archive/IArchive.h>
// Static member definitions
const Vec2i CCryFont::defaultGlyphSize = Vec2i(ICryFont::defaultGlyphSizeX, ICryFont::defaultGlyphSizeY);
#if !defined(_RELEASE)
static void DumpFontTexture(IConsoleCmdArgs* pArgs)
{
if (pArgs->GetArgCount() != 2)
{
return;
}
const char* pFontName = pArgs->GetArg(1);
if (pFontName && *pFontName && *pFontName != '0')
{
string fontFile("@devroot@/");
fontFile += pFontName;
fontFile += ".bmp";
CFFont* pFont = (CFFont*) gEnv->pCryFont->GetFont(pFontName);
if (pFont)
{
pFont->GetFontTexture()->WriteToFile(fontFile.c_str());
gEnv->pLog->LogWithType(IMiniLog::eInputResponse, "Dumped \"%s\" texture to \"%s\"!", pFontName, fontFile.c_str());
}
}
}
static void DumpFontNames([[maybe_unused]] IConsoleCmdArgs* pArgs)
{
string names = gEnv->pCryFont->GetLoadedFontNames();
gEnv->pLog->LogWithType(IMiniLog::eInputResponse, "Currently loaded fonts: %s", names.c_str());
}
static void ReloadFonts([[maybe_unused]] IConsoleCmdArgs* pArgs)
{
gEnv->pCryFont->ReloadAllFonts();
}
#endif
namespace
{
//! Stores paths to styled font assets for a given set of languages
//! This struct stores the XML data contained within the <font> tag of
//! an enclosing <fontfamily> definition:
//!
//! <fontfamily name="FontFamilyName">
//! <font lang="Language1, Language2">
//! <file path="regular.font" />
//! <file path="bold.font" tags="b" />
//! <file path="italic.font" tags="i" />
//! <file path="bolditalic.font" tags="b,i" />
//! </font>
//! </fontfamily>
struct FontTagXml
{
//! \return True if all font asset paths are non-empty, false otherwise
bool IsValid() const
{
// Note that "lang" can be empty
return !m_fontFilename.empty()
&& !m_boldFontFilename.empty()
&& !m_italicFontFilename.empty()
&& !m_boldItalicFontFilename.empty();
}
string m_lang; //!< Stores a comma-separated list of languages this collection of fonts applies to.
//!< If this is an empty string, it implies that these set of fonts will be applied
//!< by default (when a language is being used but no fonts in the font family are
//!< mapped to that language).
string m_fontFilename; //!< Font used when no styling is applied.
string m_boldFontFilename; //!< Bold-styled font
string m_italicFontFilename; //!< Italic-styled font
string m_boldItalicFontFilename; //!< Bold-italic-styled font
};
//! Stores parsed font family XML data.
//! This struct contains the name of the font family and a list of font
//! file XML data for all the language-specific mappings of this
//! font family.
//!
//! Example XML:
//!
//! <fontfamily name="FontFamilyName">
//! <font>
//! <file path="regular.font" />
//! <file path="bold.font" tags="b" />
//! <file path="italic.font" tags="i" />
//! <file path="bolditalic.font" tags="b,i" />
//! </font>
//! <font lang="korean">
//! <file path="../korean/korean-regular.font" />
//! <file path="../korean/korean-italic.font" tags="b" />
//! <file path="../korean/korean-bold.font" tags="i" />
//! <file path="../korean/korean-bolditalic.font" tags="b,i" />
//! </font>
//! <font lang="chinesesimplified">
//! <file path="../chinesesimplified/chinesesimplified-regular.font" />
//! <file path="../chinesesimplified/chinesesimplified-bold.font" tags="b" />
//! <file path="../chinesesimplified/chinesesimplified-italic.font" tags="i" />
//! <file path="../chinesesimplified/chinesesimplified-bolditalic.font" tags="b,i" />
//! </font>
//! </fontfamily>
struct FontFamilyTagXml
{
//! Returns true if all font file fields were parsed, false otherwise.
bool IsValid() const
{
for (const FontTagXml& fontTagXml : m_fontTagsXml)
{
if (!fontTagXml.IsValid())
{
return false;
}
}
// Every font family must have a name
return !m_fontFamilyName.empty();
}
string m_fontFamilyName; //!< Value of the "name" font-family tag attribute
AZStd::list<FontTagXml> m_fontTagsXml; //!< List of child <font> tag data.
};
//! Returns true if the XML tree was traversed successfully, false otherwise.
//!
//! Note that, if this function returns true, it simply means that there were
//! no unexpected structure issues with the given XML tree, it doesn't
//! necessarily mean that all the required fields were parsed.
bool ParseFontFamilyXml(const XmlNodeRef& node, FontFamilyTagXml& xmlData)
{
if (!node)
{
return false;
}
// <fontfamily>
if (AZStd::string(node->getTag()) == "fontfamily")
{
const int numAttributes = node->getNumAttributes();
if (numAttributes <= 0)
{
// Expecting at least one attribute
return false;
}
string name;
for (int i = 0, count = node->getNumAttributes(); i < count; ++i)
{
const char* key = "";
const char* value = "";
if (node->getAttributeByIndex(i, &key, &value))
{
if (string(key) == "name")
{
name = value;
}
else
{
// Unexpected font tag attribute
return false;
}
}
}
name.Trim();
if (!name.empty())
{
xmlData.m_fontFamilyName = name;
}
else
{
// Font family must have a name
return false;
}
}
// <font>
if (AZStd::string(node->getTag()) == "font")
{
xmlData.m_fontTagsXml.push_back(FontTagXml());
string lang;
for (int i = 0, count = node->getNumAttributes(); i < count; ++i)
{
const char* key = "";
const char* value = "";
if (node->getAttributeByIndex(i, &key, &value))
{
if (string(key) == "lang")
{
lang = value;
}
else
{
// Unexpected font tag attribute
return false;
}
}
}
lang.Trim();
if (!lang.empty())
{
xmlData.m_fontTagsXml.back().m_lang = lang;
}
}
// <file>
else if (AZStd::string(node->getTag()) == "file")
{
const int numAttributes = node->getNumAttributes();
if (numAttributes <= 0)
{
// Expecting at least one attribute
return false;
}
string path;
string tags;
for (int i = 0, count = node->getNumAttributes(); i < count; ++i)
{
const char* key = "";
const char* value = "";
if (node->getAttributeByIndex(i, &key, &value))
{
if (string(key) == "path")
{
path = value;
}
else if (string(key) == "tags")
{
tags = value;
}
else
{
// Unexpected font tag attribute
return false;
}
}
}
tags.Trim();
if (tags.empty())
{
xmlData.m_fontTagsXml.back().m_fontFilename = path;
}
else if (tags == "b")
{
xmlData.m_fontTagsXml.back().m_boldFontFilename = path;
}
else if (tags == "i")
{
xmlData.m_fontTagsXml.back().m_italicFontFilename = path;
}
else
{
// We'll just assume any other tag indicates bold italic
xmlData.m_fontTagsXml.back().m_boldItalicFontFilename = path;
}
}
for (int i = 0, count = node->getChildCount(); i < count; ++i)
{
XmlNodeRef child = node->getChild(i);
if (!ParseFontFamilyXml(child, xmlData))
{
return false;
}
}
return true;
}
//! Only attempt XML file load if file exists.
//! There are use-cases where the XML path is not fully known (such as
//! when referencing font family names from font family XML files), and
//! attempting to load the XML files directly via ISystem() methods can
//! produce a lot of warning noise.
XmlNodeRef SafeLoadXmlFromFile(const string& xmlPath)
{
if (gEnv->pCryPak->IsFileExist(xmlPath.c_str()))
{
return GetISystem()->LoadXmlFromFile(xmlPath.c_str());
}
return XmlNodeRef();
}
}
CCryFont::CCryFont(ISystem* pSystem)
: m_pSystem(pSystem)
, m_fonts()
, m_rndPropIsRGBA(false)
, m_rndPropHalfTexelOffset(0.5f)
{
assert(m_pSystem);
CryLogAlways("Using FreeType %d.%d.%d", FREETYPE_MAJOR, FREETYPE_MINOR, FREETYPE_PATCH);
// Persist fonts for application lifetime to prevent unnecessary work
REGISTER_CVAR(r_persistFontFamilies, r_persistFontFamilies, VF_NULL, "Persist loaded font families for lifetime of application.");
#if !defined(_RELEASE)
REGISTER_COMMAND("r_DumpFontTexture", DumpFontTexture, 0,
"Dumps the specified font's texture to a bitmap file\n"
"Use r_DumpFontTexture to get the loaded font names\n"
"Usage: r_DumpFontTexture <fontname>");
REGISTER_COMMAND("r_DumpFontNames", DumpFontNames, 0,
"Logs a list of fonts currently loaded");
REGISTER_COMMAND("r_ReloadFonts", ReloadFonts, VF_NULL,
"Reload all fonts");
#endif
}
CCryFont::~CCryFont()
{
// Persist fonts for application lifetime to prevent unnecessary work
m_persistedFontFamilies.clear();
for (FontMapItor it = m_fonts.begin(), itEnd = m_fonts.end(); it != itEnd; )
{
CFFont* pFont = it->second;
++it; // iterate as Release() below will remove font from the map
SAFE_RELEASE(pFont);
}
}
void CCryFont::Release()
{
delete this;
}
IFFont* CCryFont::NewFont(const char* pFontName)
{
string name = pFontName;
name.MakeLower();
FontMapItor it = m_fonts.find(CONST_TEMP_STRING(name.c_str()));
if (it != m_fonts.end())
{
return it->second;
}
CFFont* pFont = new CFFont(m_pSystem, this, name.c_str());
m_fonts.insert(FontMapItor::value_type(name, pFont));
return pFont;
}
IFFont* CCryFont::GetFont(const char* pFontName) const
{
FontMapConstItor it = m_fonts.find(CONST_TEMP_STRING(string(pFontName).MakeLower()));
return it != m_fonts.end() ? it->second : 0;
}
FontFamilyPtr CCryFont::LoadFontFamily(const char* pFontFamilyName)
{
FontFamilyPtr fontFamily(nullptr);
string fontFamilyPath;
string fontFamilyFullPath;
XmlNodeRef root = LoadFontFamilyXml(pFontFamilyName, fontFamilyPath, fontFamilyFullPath);
if (root)
{
FontFamilyTagXml xmlData;
const bool parseSuccess = ParseFontFamilyXml(root, xmlData);
if (parseSuccess && xmlData.IsValid())
{
const char* currentLanguage = gEnv->pSystem->GetLocalizationManager()->GetLanguage();
FontTagXml* defaultFont = nullptr;
FontTagXml* langSpecificFont = nullptr;
// Note that we don't break out of this for-loop early because we
// want to find both the default font family and the
// language-specific font family. We prefer the lang-specific
// family but will fall back on the default if it doesn't exist.
for (FontTagXml& fontTagXml : xmlData.m_fontTagsXml)
{
if (fontTagXml.m_lang.empty())
{
defaultFont = &fontTagXml;
}
else
{
int searchPos = 0;
string langToken;
// "lang" font-tag attribute could be comma-separated
while (!(langToken = fontTagXml.m_lang.Tokenize(",", searchPos)).empty())
{
if (langToken.Trim() == currentLanguage)
{
langSpecificFont = &fontTagXml;
break;
}
}
}
}
if (langSpecificFont || defaultFont)
{
// Prefer lang-specific font-family over default, if it exists
FontTagXml* fontTagXml = langSpecificFont ? langSpecificFont : defaultFont;
// Pre-pend font family's path to make font family XML paths
// relative to font family file
fontTagXml->m_fontFilename = fontFamilyPath + fontTagXml->m_fontFilename;
fontTagXml->m_boldFontFilename = fontFamilyPath + fontTagXml->m_boldFontFilename;
fontTagXml->m_italicFontFilename = fontFamilyPath + fontTagXml->m_italicFontFilename;
fontTagXml->m_boldItalicFontFilename = fontFamilyPath + fontTagXml->m_boldItalicFontFilename;
IFFont* normal = LoadFont(fontTagXml->m_fontFilename.c_str());
IFFont* bold = LoadFont(fontTagXml->m_boldFontFilename.c_str());
IFFont* italic = LoadFont(fontTagXml->m_italicFontFilename.c_str());
IFFont* boldItalic = LoadFont(fontTagXml->m_boldItalicFontFilename.c_str());
// Only continue if all fonts were created successfully
if (normal && bold && italic && boldItalic)
{
fontFamily.reset(new FontFamily(),
[this](FontFamily* pFontFamily)
{
ReleaseFontFamily(pFontFamily);
});
// Map the font family name both by path and by name defined
// within the Font Family XML itself. This allows font
// families to also be referenced simply by name.
if (!AddFontFamilyToMaps(fontFamilyFullPath, xmlData.m_fontFamilyName, fontFamily))
{
SAFE_RELEASE(normal);
SAFE_RELEASE(bold);
SAFE_RELEASE(italic);
SAFE_RELEASE(boldItalic);
return nullptr;
}
fontFamily->familyName = xmlData.m_fontFamilyName;
fontFamily->normal = normal;
fontFamily->bold = bold;
fontFamily->italic = italic;
fontFamily->boldItalic = boldItalic;
}
else
{
SAFE_RELEASE(normal);
SAFE_RELEASE(bold);
SAFE_RELEASE(italic);
SAFE_RELEASE(boldItalic);
}
}
}
}
if (!fontFamily)
{
// Unable to load font family XML, so load font normally and associate
// it with a font family
IFFont* pFont = LoadFont(pFontFamilyName);
if (pFont)
{
// Create a font family from a single font by assigning all the
// font family stylings to the same font
fontFamily.reset(new FontFamily(),
[this](FontFamily* pFontFamily)
{
ReleaseFontFamily(pFontFamily);
});
// Use filepath as familyName so font loading/unloading doesn't break with duplicate file names
fontFamily->familyName = pFontFamilyName;
if (!AddFontFamilyToMaps(pFontFamilyName, fontFamily->familyName, fontFamily))
{
SAFE_RELEASE(pFont);
return nullptr;
}
// Assign all stylings to the same font
fontFamily->normal = pFont;
fontFamily->bold = pFont;
fontFamily->italic = pFont;
fontFamily->boldItalic = pFont;
// The other three stylings need to have their ref count
// incremented (even though in this particular case its all the
// same font) because when ReleaseFontFamily executes all fonts
// in the family will be (corresondingly) Release'd.
fontFamily->bold->AddRef();
fontFamily->italic->AddRef();
fontFamily->boldItalic->AddRef();
}
}
// Persist fonts for application lifetime to prevent unnecessary work
if (r_persistFontFamilies > 0)
{
m_persistedFontFamilies.emplace_back(FontFamilyPtr(fontFamily));
}
return fontFamily;
}
FontFamilyPtr CCryFont::GetFontFamily(const char* pFontFamilyName)
{
FontFamilyPtr fontFamily = nullptr;
// The given string could either be: a font family name (defined in font
// family XML), a file path (for regular fonts mapped as font families),
// or just the filename of a font itself. Fonts are mapped by font family
// name or by filepath, so attempt lookup using the map first since it's
// the fastest.
string loweredName = string(pFontFamilyName).Trim().MakeLower();
auto it = m_fontFamilies.find(PathUtil::MakeGamePath(loweredName).c_str());
if (it != m_fontFamilies.end())
{
fontFamily = FontFamilyPtr(it->second);
}
else
{
// Iterate through all fonts, returning the first match where simply
// the filename of a font could be a match. This case will likely be
// hit when text markup references a font that doesn't belong to a
// font family.
for (const auto& fontFamilyIter : m_fontFamilies)
{
const AZStd::string& mappedFontFamilyName = fontFamilyIter.first;
string mappedFilenameNoExtension = PathUtil::GetFileName(mappedFontFamilyName.c_str());
string searchStringFilenameNoExtension = PathUtil::GetFileName(loweredName);
if (mappedFilenameNoExtension == searchStringFilenameNoExtension)
{
fontFamily = FontFamilyPtr(fontFamilyIter.second);
break;
}
}
}
return fontFamily;
}
void CCryFont::AddCharsToFontTextures(FontFamilyPtr pFontFamily, const char* pChars, int glyphSizeX, int glyphSizeY)
{
pFontFamily->normal->AddCharsToFontTexture(pChars, glyphSizeX, glyphSizeY);
pFontFamily->bold->AddCharsToFontTexture(pChars, glyphSizeX, glyphSizeY);
pFontFamily->italic->AddCharsToFontTexture(pChars, glyphSizeX, glyphSizeY);
pFontFamily->boldItalic->AddCharsToFontTexture(pChars, glyphSizeX, glyphSizeY);
}
void CCryFont::SetRendererProperties(IRenderer* pRenderer)
{
if (pRenderer)
{
m_rndPropIsRGBA = (pRenderer->GetFeatures() & RFT_RGBA) != 0;
m_rndPropHalfTexelOffset = 0.0f;
}
}
void CCryFont::GetMemoryUsage(ICrySizer* pSizer) const
{
if (!pSizer->Add(*this))
{
return;
}
pSizer->AddObject(m_fonts);
}
string CCryFont::GetLoadedFontNames() const
{
string ret;
for (FontMapConstItor it = m_fonts.begin(), itEnd = m_fonts.end(); it != itEnd; ++it)
{
CFFont* pFont = it->second;
if (pFont)
{
if (!ret.empty())
{
ret += ",";
}
ret += pFont->GetName();
}
}
return ret;
}
void CCryFont::OnLanguageChanged()
{
ReloadAllFonts();
EBUS_EVENT(LanguageChangeNotificationBus, LanguageChanged);
}
void CCryFont::ReloadAllFonts()
{
// Persist fonts for application lifetime to prevent unnecessary work
m_persistedFontFamilies.clear();
AZStd::list<AZStd::string> fontFamilyFilenames;
AZStd::list<FontFamily*> fontFamilyWeakPtrs;
// Iterate through all currently loaded font families
for (auto it : m_fontFamilyReverseLookup)
{
fontFamilyWeakPtrs.push_back(it.first);
fontFamilyFilenames.push_back(it.second->first);
}
// Release font-family resources and unmap them
for (auto fontFamily : fontFamilyWeakPtrs)
{
ReleaseFontFamily(fontFamily);
}
// Reload the font families
for (auto familyFilename : fontFamilyFilenames)
{
LoadFontFamily(familyFilename.c_str());
}
// All UI text components need to reload their font assets (both in-game
// and in-editor).
EBUS_EVENT(FontNotificationBus, OnFontsReloaded);
}
void CCryFont::UnregisterFont(const char* pFontName)
{
FontMapItor it = m_fonts.find(CONST_TEMP_STRING(pFontName));
#if defined(AZ_ENABLE_TRACING)
IFFont* fontPtr = it->second;
#endif
if (it != m_fonts.end())
{
m_fonts.erase(it);
}
#if defined(AZ_ENABLE_TRACING)
// Make sure the font being released isn't currently in use by a font family.
// If it is, the FontFamily will have a dangling pointer and will cause a
// crash when the FontFamily eventually gets released.
for (auto reverseMapEntry : m_fontFamilyReverseLookup)
{
FontFamily* fontFamily = reverseMapEntry.first;
AZ_Assert(fontFamily->normal != fontPtr,
"The following font is being freed but still in use by a FontFamily: %s",
pFontName);
AZ_Assert(fontFamily->italic != fontPtr,
"The following font is being freed but still in use by a FontFamily: %s",
pFontName);
AZ_Assert(fontFamily->bold != fontPtr,
"The following font is being freed but still in use by a FontFamily: %s",
pFontName);
AZ_Assert(fontFamily->boldItalic != fontPtr,
"The following font is being freed but still in use by a FontFamily: %s",
pFontName);
}
#endif
}
IFFont* CCryFont::LoadFont(const char* pFontName)
{
string fontName = pFontName;
fontName.MakeLower();
IFFont* font = GetFont(fontName);
if (font)
{
font->AddRef(); // use existing loaded font
}
else
{
// attempt to create and load a new font, use the font pathname as the font name
font = NewFont(fontName);
if (!font)
{
string errorMsg = "Error creating a new font named ";
errorMsg += fontName;
errorMsg += ".";
CryWarning(VALIDATOR_MODULE_SYSTEM, VALIDATOR_ERROR, errorMsg.c_str());
}
else
{
// creating font adds one to its refcount so no need for AddRef here
if (!font->Load(fontName))
{
string errorMsg = "Error loading a font from ";
errorMsg += fontName;
errorMsg += ".";
CryWarning(VALIDATOR_MODULE_SYSTEM, VALIDATOR_ERROR, errorMsg);
font->Release();
font = nullptr;
}
}
}
return font;
}
void CCryFont::ReleaseFontFamily(FontFamily* pFontFamily)
{
// Ensure that Font Family was mapped prior to destruction
const bool isMapped = m_fontFamilyReverseLookup.find(pFontFamily) != m_fontFamilyReverseLookup.end();
if (!isMapped)
{
return;
}
// Note that the FontFamily is mapped both by filename and by "family name"
auto it = m_fontFamilyReverseLookup[pFontFamily];
m_fontFamilies.erase(it);
string familyName(pFontFamily->familyName);
m_fontFamilies.erase(familyName.MakeLower().c_str());
// Reverse lookup is used to avoid needing to store filename path with
// the font family, so we need to remove that entry also.
m_fontFamilyReverseLookup.erase(pFontFamily);
SAFE_RELEASE(pFontFamily->normal);
SAFE_RELEASE(pFontFamily->bold);
SAFE_RELEASE(pFontFamily->italic);
SAFE_RELEASE(pFontFamily->boldItalic);
}
bool CCryFont::AddFontFamilyToMaps(const char* pFontFamilyFilename, const char* pFontFamilyName, FontFamilyPtr fontFamily)
{
if (!pFontFamilyFilename || !pFontFamilyName || !fontFamily.get())
{
return false;
}
// We don't support "updating" mapped values.
AZStd::string loweredFilename(PathUtil::MakeGamePath(string(pFontFamilyFilename)).c_str());
AZStd::to_lower<AZStd::string::iterator>(loweredFilename.begin(), loweredFilename.end());
if (m_fontFamilies.find(loweredFilename) != m_fontFamilies.end())
{
string warnMsg;
warnMsg.Format("Couldn't load Font Family '%s': already loaded", pFontFamilyFilename);
CryWarning(VALIDATOR_MODULE_SYSTEM, VALIDATOR_WARNING, warnMsg.c_str());
return false;
}
// Similarly, we don't support Font Family XMLs that have the same font
// family name (we assume all Font Family names are unique).
AZStd::string loweredFontFamilyName(pFontFamilyName);
AZStd::to_lower<AZStd::string::iterator>(loweredFontFamilyName.begin(), loweredFontFamilyName.end());
if (m_fontFamilies.find(loweredFontFamilyName) != m_fontFamilies.end())
{
string warnMsg;
warnMsg.Format("Couldn't load Font Family '%s': already loaded", pFontFamilyName);
CryWarning(VALIDATOR_MODULE_SYSTEM, VALIDATOR_WARNING, warnMsg.c_str());
return false;
}
// First, insert by filename
AZStd::pair<AZStd::string, AZStd::weak_ptr<FontFamily>> insertPair(loweredFilename, fontFamily);
auto iterPosition = m_fontFamilies.insert(insertPair).first;
m_fontFamilyReverseLookup[fontFamily.get()] = iterPosition;
// Then, by Font Family name
AZStd::pair<AZStd::string, AZStd::weak_ptr<FontFamily>> nameInsertPair(loweredFontFamilyName, fontFamily);
m_fontFamilies.insert(nameInsertPair);
return true;
}
XmlNodeRef CCryFont::LoadFontFamilyXml(const char* pFontFamilyName, string& outputDirectory, string& outputFullPath)
{
outputFullPath = pFontFamilyName;
outputDirectory = PathUtil::GetPath(pFontFamilyName);
XmlNodeRef root = SafeLoadXmlFromFile(outputFullPath);
// When parsing a <font> tag in markup, only the font name is given and
// not a path, so we try to build a "best guess" path from the name.
if (!root)
{
string fileNoExtension(PathUtil::GetFileName(pFontFamilyName));
string fileExtension(PathUtil::GetExt(pFontFamilyName));
if (fileExtension.empty())
{
fileExtension = ".fontfamily";
}
// Try: "fonts/fontName.fontfamily"
outputDirectory = string("fonts/");
outputFullPath = outputDirectory + fileNoExtension + fileExtension;
root = SafeLoadXmlFromFile(outputFullPath);
// Finally, try: "fonts/fontName/fontName.fontfamily"
if (!root)
{
outputDirectory = string("fonts/") + fileNoExtension + "/";
outputFullPath = outputDirectory + fileNoExtension + fileExtension;
root = SafeLoadXmlFromFile(outputFullPath);
}
}
return root;
}
#endif
-3
View File
@@ -1,3 +0,0 @@
EXPORTS
ModuleInitISystem @2
CryModuleGetMemoryInfo @8
-108
View File
@@ -1,108 +0,0 @@
/*
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
* its licensors.
*
* For complete copyright and license terms please see the LICENSE at the root of this
* distribution (the "License"). All use of this software is governed by the License,
* or, if provided, by the license below or the license accompanying this file. Do not
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
*/
// Original file Copyright Crytek GMBH or its affiliates, used under license.
#ifndef CRYINCLUDE_CRYFONT_CRYFONT_H
#define CRYINCLUDE_CRYFONT_CRYFONT_H
#pragma once
#if !defined(USE_NULLFONT_ALWAYS)
#include <IXml.h>
#include <AzCore/std/containers/map.h>
#include <AzCore/std/smart_ptr/weak_ptr.h>
#include <map>
class CFFont;
class CCryFont
: public ICryFont
{
friend class CFFont;
public:
static const Vec2i defaultGlyphSize; //!< Default glyph size indicates that glyphs in the font texture
//!< should be rendered at the maximum resolution supported by
//!< the font texture's glyph cell/slot configuration (configured
//!< via font XML).
public:
CCryFont(ISystem* pSystem);
virtual ~CCryFont();
virtual void Release();
virtual IFFont* NewFont(const char* pFontName);
virtual IFFont* GetFont(const char* pFontName) const;
virtual FontFamilyPtr LoadFontFamily(const char* pFontFamilyName) override;
virtual FontFamilyPtr GetFontFamily(const char* pFontFamilyName) override;
virtual void AddCharsToFontTextures(FontFamilyPtr pFontFamily, const char* pChars, int glyphSizeX = ICryFont::defaultGlyphSizeX, int glyphSizeY = ICryFont::defaultGlyphSizeY) override;
virtual void SetRendererProperties(IRenderer* pRenderer);
virtual void GetMemoryUsage(ICrySizer* pSizer) const;
virtual string GetLoadedFontNames() const;
virtual void OnLanguageChanged() override;
virtual void ReloadAllFonts() override;
public:
void UnregisterFont(const char* pFontName);
bool RndPropIsRGBA() const { return m_rndPropIsRGBA; }
float RndPropHalfTexelOffset() const { return m_rndPropHalfTexelOffset; }
private:
typedef std::map<string, CFFont*> FontMap;
typedef FontMap::iterator FontMapItor;
typedef FontMap::const_iterator FontMapConstItor;
typedef AZStd::map<AZStd::string, AZStd::weak_ptr<FontFamily>> FontFamilyMap;
typedef AZStd::map<FontFamily*, FontFamilyMap::iterator> FontFamilyReverseLookupMap;
private:
//! Convenience method for loading fonts
IFFont* LoadFont(const char* fontName);
//! Called when final FontFamily shared_ptr is destroyed; do not call directly.
void ReleaseFontFamily(FontFamily* pFontFamily);
//! Adds new entries into both font family maps for the given font family
//!
//! Note that it's not possible to update Font Family mappings with this
//! method. The only way to do that would be to release the font family
//! and re-load it with the new values.
//!
//! \return True only if the Font Family was added to the maps, false for all other cases (such as
//! when the font family is already mapped).
bool AddFontFamilyToMaps(const char* pFontFamilyFilename, const char* pFontFamilyName, FontFamilyPtr fontFamily);
//! Internal method that (possibly) makes several attempts at locating and loading a given font family XML.
//! \param pFontFamilyName The name of the font family, or path to a font family file.
//! \param outputDirectory Path to loaded font family (no filename), may need resolving with PathUtil::MakeGamePath.
//! \param outputFullPath Full path to loaded font family, may need resolving with PathUtil::MakeGamePath.
XmlNodeRef LoadFontFamilyXml(const char* pFontFamilyName, string& outputDirectory, string& outputFullPath);
private:
FontMap m_fonts;
FontFamilyMap m_fontFamilies; //!< Map font family names to weak ptrs so we can construct shared_ptrs but not keep a ref ourselves.
FontFamilyReverseLookupMap m_fontFamilyReverseLookup; //<! FontFamily pointer reverse-lookup for quick removal
ISystem* m_pSystem;
bool m_rndPropIsRGBA;
float m_rndPropHalfTexelOffset;
int r_persistFontFamilies = 1; //!< Persist fonts for application lifetime to prevent unnecessary work; enabled by default.
AZStd::vector<FontFamilyPtr> m_persistedFontFamilies; //!< Stores persisted fonts (if "persist font families" is enabled)
};
#endif
#endif // CRYINCLUDE_CRYFONT_CRYFONT_H
-111
View File
@@ -1,111 +0,0 @@
// Microsoft Visual C++ generated resource script.
//
#include "resource.h"
#define APSTUDIO_READONLY_SYMBOLS
/////////////////////////////////////////////////////////////////////////////
//
// Generated from the TEXTINCLUDE 2 resource.
//
#include "winres.h"
/////////////////////////////////////////////////////////////////////////////
#undef APSTUDIO_READONLY_SYMBOLS
/////////////////////////////////////////////////////////////////////////////
// Russian resources
#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_RUS)
#ifdef _WIN32
LANGUAGE LANG_RUSSIAN, SUBLANG_DEFAULT
#pragma code_page(1251)
#endif //_WIN32
#ifdef APSTUDIO_INVOKED
/////////////////////////////////////////////////////////////////////////////
//
// TEXTINCLUDE
//
1 TEXTINCLUDE
BEGIN
"resource.h\0"
END
2 TEXTINCLUDE
BEGIN
"#include ""winres.h""\r\n"
"\0"
END
3 TEXTINCLUDE
BEGIN
"\r\n"
"\0"
END
#endif // APSTUDIO_INVOKED
#endif // Russian resources
/////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////
// German (Germany) resources
#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_DEU)
#ifdef _WIN32
LANGUAGE LANG_GERMAN, SUBLANG_GERMAN
#pragma code_page(1252)
#endif //_WIN32
/////////////////////////////////////////////////////////////////////////////
//
// Version
//
VS_VERSION_INFO VERSIONINFO
FILEVERSION 1,0,0,1
PRODUCTVERSION 1,0,0,1
FILEFLAGSMASK 0x17L
#ifdef _DEBUG
FILEFLAGS 0x1L
#else
FILEFLAGS 0x0L
#endif
FILEOS 0x4L
FILETYPE 0x2L
FILESUBTYPE 0x0L
BEGIN
BLOCK "StringFileInfo"
BEGIN
BLOCK "000904b0"
BEGIN
VALUE "CompanyName", "Amazon.com, Inc."
VALUE "FileVersion", "1, 0, 0, 1"
VALUE "LegalCopyright", "Portions of this file Copyright (c) Amazon.com, Inc. or its affiliates. All Rights Reserved. Original file Copyright (c) Crytek GMBH. Used under license by Amazon.com, Inc. and its affiliates."
VALUE "ProductName", "Lumberyard"
VALUE "ProductVersion", "1, 0, 0, 1"
END
END
BLOCK "VarFileInfo"
BEGIN
VALUE "Translation", 0x9, 1200
END
END
#endif // German (Germany) resources
/////////////////////////////////////////////////////////////////////////////
#ifndef APSTUDIO_INVOKED
/////////////////////////////////////////////////////////////////////////////
//
// Generated from the TEXTINCLUDE 3 resource.
//
/////////////////////////////////////////////////////////////////////////////
#endif // not APSTUDIO_INVOKED
@@ -1,14 +0,0 @@
/*
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
* its licensors.
*
* For complete copyright and license terms please see the LICENSE at the root of this
* distribution (the "License"). All use of this software is governed by the License,
* or, if provided, by the license below or the license accompanying this file. Do not
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
*/
// Original file Copyright Crytek GMBH or its affiliates, used under license.
#include "CryFont_precompiled.h"
@@ -1,34 +0,0 @@
/*
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
* its licensors.
*
* For complete copyright and license terms please see the LICENSE at the root of this
* distribution (the "License"). All use of this software is governed by the License,
* or, if provided, by the license below or the license accompanying this file. Do not
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
*/
// Original file Copyright Crytek GMBH or its affiliates, used under license.
#pragma once
#include <vector>
#define CRYFONT_EXPORTS
#include <platform.h>
#include <IFont.h>
#include <ILog.h>
#include <IConsole.h>
#include <IRenderer.h>
#include <CrySizer.h>
#define USE_NULLFONT
#if defined(DEDICATED_SERVER)
#define USE_NULLFONT_ALWAYS 1
#endif
-74
View File
@@ -1,74 +0,0 @@
/*
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
* its licensors.
*
* For complete copyright and license terms please see the LICENSE at the root of this
* distribution (the "License"). All use of this software is governed by the License,
* or, if provided, by the license below or the license accompanying this file. Do not
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
*/
// Original file Copyright Crytek GMBH or its affiliates, used under license.
#pragma once
#ifndef CRYINCLUDE_CRYFONT_FBITMAP_H
#define CRYINCLUDE_CRYFONT_FBITMAP_H
class CFBitmap
{
public:
CFBitmap();
~CFBitmap();
int Blur(int iIterations);
int Scale(float fScaleX, float fScaleY);
int BlitFrom(CFBitmap* pSrc, int iSX, int iSY, int iDX, int iDY, int iW, int iH);
int BlitTo(CFBitmap* pDst, int iDX, int iDY, int iSX, int iSY, int iW, int iH);
int Create(int iWidth, int iHeight);
int Release();
int SaveBitmap(const string& szFileName);
int Get32Bpp(unsigned int** pBuffer)
{
(*pBuffer) = new unsigned int[m_iWidth * m_iHeight];
if (!(*pBuffer))
{
return 0;
}
int iDataSize = m_iWidth * m_iHeight;
for (int i = 0; i < iDataSize; i++)
{
(*pBuffer)[i] = (m_pData[i] << 24) | (m_pData[i] << 16) | (m_pData[i] << 8) | (m_pData[i]);
}
return 1;
}
int GetWidth() { return m_iWidth; }
int GetHeight() { return m_iHeight; }
void SetRenderData(void* pRenderData) { m_pIRenderData = pRenderData; };
void* GetRenderData() { return m_pIRenderData; };
void GetMemoryUsage (class ICrySizer* pSizer);
unsigned char* GetData() { return m_pData; }
public:
int m_iWidth;
int m_iHeight;
unsigned char* m_pData;
void* m_pIRenderData;
};
#endif // CRYINCLUDE_CRYFONT_FBITMAP_H
File diff suppressed because it is too large Load Diff
-234
View File
@@ -1,234 +0,0 @@
/*
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
* its licensors.
*
* For complete copyright and license terms please see the LICENSE at the root of this
* distribution (the "License"). All use of this software is governed by the License,
* or, if provided, by the license below or the license accompanying this file. Do not
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
*/
// Original file Copyright Crytek GMBH or its affiliates, used under license.
// Description : Font class.
#ifndef CRYINCLUDE_CRYFONT_FFONT_H
#define CRYINCLUDE_CRYFONT_FFONT_H
#pragma once
#if !defined(USE_NULLFONT_ALWAYS)
#include <vector>
#include <Cry_Math.h>
#include <Cry_Color.h>
#include <CryString.h>
#include "CryFont.h"
#include <AzCore/std/parallel/mutex.h>
struct ISystem;
class CFontTexture;
class CFFont
: public IFFont
, public IFFont_RenderProxy
{
public:
//! Determines how characters of different sizes should be handled during render.
enum class SizeBehavior
{
Scale, //!< Default behavior; glyphs rendered at different sizes are rendered on scaled geometry
Rerender //!< Similar to Scale, but the glyph in the font texture is re-rendered to match the target
//!< size, as long as the size isn't greater than the maximum glyph/slot resolution as
//!< configured for the font texture in the font XML.
};
//! The hinting visual algorithm to be used (when hinting is enabled)
enum class HintStyle
{
Normal, //!< Default hinting behavior provided by font renderer
Light //!< Produces fuzzier glyphs but more accurately tracks glyph shape
};
//! Chooses whether hinting info should be obtained from the font, turned off entirely, or automatically generated
enum class HintBehavior
{
Default, //!< Obtain hinting data from font itself
AutoHint, //!< Procedurally derive hinting information from glyph
NoHinting, //!< Disable hinting entirely
};
//! Simple struct used to communicate font hinting parameters to font renderer.
struct FontHintParams
{
FontHintParams() : hintStyle(HintStyle::Normal), hintBehavior(HintBehavior::Default) { }
HintStyle hintStyle;
HintBehavior hintBehavior;
};
struct SRenderingPass
{
ColorB m_color;
Vec2 m_posOffset;
int m_blendSrc;
int m_blendDest;
SRenderingPass()
: m_color(255, 255, 255, 255)
, m_posOffset(0, 0)
, m_blendSrc(GS_BLSRC_SRCALPHA)
, m_blendDest(GS_BLDST_ONEMINUSSRCALPHA)
{
}
void GetMemoryUsage([[maybe_unused]] ICrySizer* pSizer) const {}
};
struct SEffect
{
string m_name;
std::vector<SRenderingPass> m_passes;
SEffect(const char* name)
: m_name(name)
{
assert(name);
}
SRenderingPass* AddPass()
{
m_passes.push_back(SRenderingPass());
return &m_passes[m_passes.size() - 1];
}
void ClearPasses()
{
m_passes.resize(0);
}
void GetMemoryUsage(ICrySizer* pSizer) const
{
pSizer->AddObject(m_name);
pSizer->AddObject(m_passes);
}
};
typedef std::vector<SEffect> Effects;
typedef Effects::iterator EffectsIt;
public:
virtual int32 AddRef() override;
virtual int32 Release() override;
virtual bool Load(const char* pFontFilePath, unsigned int width, unsigned int height, unsigned int widthNumSlots, unsigned int heightNumSlots, unsigned int flags, float sizeRatio);
virtual bool Load(const char* pXMLFile);
virtual void Free();
virtual void DrawString(float x, float y, const char* pStr, const bool asciiMultiLine, const STextDrawContext& ctx);
virtual void DrawString(float x, float y, float z, const char* pStr, const bool asciiMultiLine, const STextDrawContext& ctx);
virtual Vec2 GetTextSize(const char* pStr, const bool asciiMultiLine, const STextDrawContext& ctx);
virtual size_t GetTextLength(const char* pStr, const bool asciiMultiLine) const;
virtual void WrapText(string& result, float maxWidth, const char* pStr, const STextDrawContext& ctx);
virtual void GetMemoryUsage(ICrySizer* pSizer) const;
virtual void GetGradientTextureCoord(float& minU, float& minV, float& maxU, float& maxV) const;
virtual unsigned int GetEffectId(const char* pEffectName) const;
virtual unsigned int GetNumEffects() const;
virtual const char* GetEffectName(unsigned int effectId) const;
virtual Vec2 GetMaxEffectOffset(unsigned int effectId) const;
virtual bool DoesEffectHaveTransparency(unsigned int effectId) const;
virtual void AddCharsToFontTexture(const char* pChars, int glyphSizeX = ICryFont::defaultGlyphSizeX, int glyphSizeY = ICryFont::defaultGlyphSizeY) override;
virtual Vec2 GetKerning(uint32_t leftGlyph, uint32_t rightGlyph, const STextDrawContext& ctx) const override;
virtual float GetAscender(const STextDrawContext& ctx) const override;
virtual float GetBaseline(const STextDrawContext& ctx) const override;
virtual uint32 GetNumQuadsForText(const char* pStr, const bool asciiMultiLine, const STextDrawContext& ctx);
virtual uint32 WriteTextQuadsToBuffers(SVF_P2F_C4B_T2F_F4B* verts, uint16* indices, uint32 maxQuads, float x, float y, float z, const char* pStr, const bool asciiMultiLine, const STextDrawContext& ctx);
virtual int GetFontTextureId();
virtual uint32 GetFontTextureVersion();
virtual float GetSizeRatio() const override { return m_sizeRatio; }
public:
virtual void RenderCallback(float x, float y, float z, const char* pStr, const bool asciiMultiLine, const STextDrawContext& ctx);
public:
CFFont(ISystem* pSystem, CCryFont* pCryFont, const char* pFontName);
bool InitTexture();
bool InitCache();
CFontTexture* GetFontTexture() const { return m_pFontTexture; }
const string& GetName() const { return m_name; }
SEffect* AddEffect(const char* pEffectName);
SEffect* GetDefaultEffect();
private:
virtual ~CFFont();
void Prepare(const char* pStr, bool updateTexture, const Vec2i& glyphSize = CCryFont::defaultGlyphSize);
void DrawStringUInternal(float x, float y, float z, const char* pStr, const bool asciiMultiLine, const STextDrawContext& ctx);
Vec2 GetTextSizeUInternal(const char* pStr, const bool asciiMultiLine, const STextDrawContext& ctx);
using AddFunction = AZStd::function<void(const Vec3&, const Vec3&, const Vec3&, const Vec3&, const Vec2&, const Vec2&, const Vec2&, const Vec2&, uint32)>;
using BeginPassFunction = AZStd::function<void(const SRenderingPass* pPass)>;
//! This function is used by both RenderCallback and WriteTextQuadsToBuffers
//! To do this is takes two function pointers that implement the appropriate AddQuad and BeginPass behavior
void CreateQuadsForText(float x, float y, float z, const char* pStr, const bool asciiMultiLine, const STextDrawContext& ctx,
AddFunction AddQuad, BeginPassFunction BeginPass);
struct TextScaleInfoInternal
{
TextScaleInfoInternal(const Vec2& _scale, float _rcpCellWidth)
: scale(_scale), rcpCellWidth(_rcpCellWidth) { }
Vec2 scale;
float rcpCellWidth;
};
TextScaleInfoInternal CalculateScaleInternal(const STextDrawContext& ctx) const;
Vec2 GetRestoredFontSize(const STextDrawContext& ctx) const;
private:
string m_name;
string m_curPath;
CFontTexture* m_pFontTexture;
size_t m_fontBufferSize;
unsigned char* m_pFontBuffer;
int m_texID;
uint32 m_textureVersion;
ISystem* m_pSystem;
AZStd::recursive_mutex m_fontMutex; //!< Controls access between main and render threads. It's common for one thread
//!< to add un-cached glyphs to the font texture while another is accessing the
//!< font texture.
CCryFont* m_pCryFont;
bool m_fontTexDirty;
Effects m_effects;
SVF_P3F_C4B_T2F* m_pDrawVB;
volatile int32 m_nRefCount;
bool m_monospacedFont; //!< True if this font is fixed/monospaced, false otherwise (obtained from FreeType)
float m_sizeRatio = IFFontConstants::defaultSizeRatio;
SizeBehavior m_sizeBehavior = SizeBehavior::Scale; //!< Changes how glyphs rendered at different sizes are rendered.
FontHintParams m_fontHintParams; //!< How the font should be hinted when its loaded and rendered to the font texture
};
#endif
#endif // CRYINCLUDE_CRYFONT_FFONT_H
-448
View File
@@ -1,448 +0,0 @@
/*
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
* its licensors.
*
* For complete copyright and license terms please see the LICENSE at the root of this
* distribution (the "License"). All use of this software is governed by the License,
* or, if provided, by the license below or the license accompanying this file. Do not
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
*/
// Original file Copyright Crytek GMBH or its affiliates, used under license.
// Description : XML parsing to load a font.
#include "CryFont_precompiled.h"
#if !defined(USE_NULLFONT_ALWAYS)
#include "FFont.h"
#include "FontTexture.h"
#include <Cry_Math.h>
#include <CryPath.h>
#if defined(WIN32) || defined(WIN64)
# include <shlobj.h>
# include <StringUtils.h>
#endif
//////////////////////////////////////////////////////////////////////////
// Xml parser implementation
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
};
static 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;
}
class CXmlFontShader
{
public:
CXmlFontShader(CFFont* pFont)
{
m_pFont = pFont;
m_nElement = ELEMENT_UNKNOWN;
m_pEffect = NULL;
m_pPass = NULL;
m_FontTexSize.set(0, 0);
static const int defaultSlotWidthSize = 16;
static const int defaultSlotHeightSize = 8;
m_SlotSizes.set(defaultSlotWidthSize, defaultSlotHeightSize);
m_FontSmoothAmount = 0;
m_FontSmoothMethod = FONT_SMOOTH_NONE;
}
~CXmlFontShader()
{
}
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:
// 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_pFont->Load(m_strFontPath.c_str(), m_FontTexSize.x, m_FontTexSize.y, m_SlotSizes.x, m_SlotSizes.y, TTFFLAG_CREATE(m_FontSmoothMethod, m_FontSmoothAmount), m_SizeRatio);
#if defined(WIN32) || defined(WIN64)
if (!fontLoaded)
{
TCHAR sysFontPath[MAX_PATH];
if (SUCCEEDED(SHGetFolderPath(0, CSIDL_FONTS, 0, SHGFP_TYPE_DEFAULT, sysFontPath)))
{
const char* pFontPath = m_strFontPath.c_str();
const char* pFontName = CryStringUtils::FindFileNameInPath(pFontPath);
string newFontPath(sysFontPath);
newFontPath += "/";
newFontPath += pFontName;
m_pFont->Load(newFontPath, m_FontTexSize.x, m_FontTexSize.y, m_SlotSizes.x, m_SlotSizes.y, TTFFLAG_CREATE(m_FontSmoothMethod, m_FontSmoothAmount), m_SizeRatio);
}
}
#endif
}
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_pPass = NULL;
m_nElement = ELEMENT_PASS;
if (m_pEffect)
{
m_pPass = m_pEffect->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")
{
if (value == "blur")
{
m_FontSmoothMethod = FONT_SMOOTH_BLUR;
}
else if (value == "supersample")
{
m_FontSmoothMethod = FONT_SMOOTH_SUPERSAMPLE;
}
else if (value == "none")
{
m_FontSmoothMethod = FONT_SMOOTH_NONE;
}
}
else if (name == "smooth_amount")
{
m_FontSmoothAmount = (long)atof(value.c_str());
}
break;
case ELEMENT_EFFECT:
if (name == "name")
{
if (value == "default")
{
m_pEffect = m_pFont->GetDefaultEffect();
m_pEffect->ClearPasses();
}
else
{
m_pEffect = m_pFont->AddEffect(value.c_str());
}
}
break;
case ELEMENT_EFFECTFILE:
if (name == "path")
{
m_strFontEffectPath = value;
}
break;
case ELEMENT_PASS_COLOR:
if (!m_pPass)
{
break;
}
if (name == "r")
{
m_pPass->m_color.r = (uint8)((float)atof(value.c_str()) * 255.0f);
}
else if (name == "g")
{
m_pPass->m_color.g = (uint8)((float)atof(value.c_str()) * 255.0f);
}
else if (name == "b")
{
m_pPass->m_color.b = (uint8)((float)atof(value.c_str()) * 255.0f);
}
else if (name == "a")
{
m_pPass->m_color.a = (uint8)((float)atof(value.c_str()) * 255.0f);
}
break;
case ELEMENT_PASS_POSOFFSET:
if (!m_pPass)
{
break;
}
if (name == "x")
{
m_pPass->m_posOffset.x = (float)atoi(value.c_str());
}
else if (name == "y")
{
m_pPass->m_posOffset.y = (float)atoi(value.c_str());
}
break;
case ELEMENT_PASS_BLEND:
if (!m_pPass)
{
break;
}
if (name == "src")
{
m_pPass->m_blendSrc = GetBlendModeFromString(value, false);
}
else if (name == "dst")
{
m_pPass->m_blendDest = GetBlendModeFromString(value, true);
}
else if (name == "type")
{
if (value == "modulate")
{
m_pPass->m_blendSrc = GS_BLSRC_SRCALPHA;
m_pPass->m_blendDest = GS_BLDST_ONEMINUSSRCALPHA;
}
else if (value == "additive")
{
m_pPass->m_blendSrc = GS_BLSRC_SRCALPHA;
m_pPass->m_blendDest = GS_BLDST_ONE;
}
}
break;
default:
case ELEMENT_UNKNOWN:
break;
}
}
public:
CFFont* m_pFont;
unsigned long m_nElement;
CFFont::SEffect* m_pEffect;
CFFont::SRenderingPass* m_pPass;
string m_strFontPath;
string m_strFontEffectPath;
vector2l m_FontTexSize;
Vec2i m_SlotSizes;
float m_SizeRatio = IFFontConstants::defaultSizeRatio;
int m_FontSmoothMethod;
int m_FontSmoothAmount;
};
//////////////////////////////////////////////////////////////////////////
// Main loading function
bool CFFont::Load(const char* pXMLFile)
{
m_curPath = "";
if (pXMLFile)
{
m_curPath = PathUtil::GetPath(pXMLFile);
}
XmlNodeRef root = GetISystem()->LoadXmlFromFile(pXMLFile);
if (!root)
{
return false;
}
CXmlFontShader xmlfs(this);
xmlfs.ScanXmlNodesRecursively(root);
// if this was not a valid font XML file then return false
if (!m_pFontTexture || !m_pFontBuffer)
{
return false;
}
// if there was a font effect file then parse that for effects
if (!xmlfs.m_strFontEffectPath.empty())
{
XmlNodeRef fontEffectRoot = GetISystem()->LoadXmlFromFile(xmlfs.m_strFontEffectPath.c_str());
if (!fontEffectRoot)
{
AZ_Warning("Font", false, "Error parsing font file %s, 'effectfile' pathname %s could not be found.",
pXMLFile, xmlfs.m_strFontEffectPath.c_str());
return false;
}
if (m_effects.size() > 1 || (m_effects.size() == 1 && (m_effects[0].m_name != "default" || m_effects[0].m_passes.size() > 1)))
{
AZ_Warning("Font", false, "Error parsing font file %s, 'effectfile' and 'effect' cannot both be used in the same font file.",
pXMLFile);
m_effects.clear();
}
// parse the font effects file, adding to this font object
CXmlFontShader xmlfsEffect(this);
xmlfsEffect.ScanXmlNodesRecursively(fontEffectRoot);
}
return true;
}
#endif
-398
View File
@@ -1,398 +0,0 @@
/*
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
* its licensors.
*
* For complete copyright and license terms please see the LICENSE at the root of this
* distribution (the "License"). All use of this software is governed by the License,
* or, if provided, by the license below or the license accompanying this file. Do not
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
*/
// Original file Copyright Crytek GMBH or its affiliates, used under license.
//
// Purpose:
// - Render a glyph outline into a bitmap using FreeType 2
#include "CryFont_precompiled.h"
#if !defined(USE_NULLFONT_ALWAYS)
#include "FontRenderer.h"
#include <freetype/ftoutln.h>
#include <freetype/ftglyph.h>
#include <freetype/ftimage.h>
#include <AzCore/Casting/lossy_cast.h>
// Sizes are defined in in 26.6 fixed float format (TT_F26Dot6), where
// 1 unit is 1/64 of a pixel.
static const int fractionalPixelUnits = 64;
namespace
{
FT_Int32 GetLoadFlags(CFFont::HintBehavior hintBehavior)
{
switch (hintBehavior)
{
case CFFont::HintBehavior::NoHinting:
{
return FT_LOAD_NO_HINTING;
break;
}
case CFFont::HintBehavior::AutoHint:
{
return FT_LOAD_FORCE_AUTOHINT;
break;
}
}
return FT_LOAD_DEFAULT;
}
FT_Int32 GetLoadTarget(CFFont::HintStyle hintStyle)
{
if (hintStyle == CFFont::HintStyle::Light)
{
return FT_LOAD_TARGET_LIGHT;
}
return FT_LOAD_TARGET_NORMAL;
}
FT_Render_Mode GetRenderMode(CFFont::HintStyle hintStyle)
{
// We use the hint style to drive the render mode also. These should
// usually be correlated with each other for best results, even though
// they could technically be different.
if (hintStyle == CFFont::HintStyle::Light)
{
return FT_RENDER_MODE_LIGHT;
}
return FT_RENDER_MODE_NORMAL;
}
}
//-------------------------------------------------------------------------------------------------
CFontRenderer::CFontRenderer()
: m_pLibrary(0)
, m_pFace(0)
, m_pGlyph(0)
, m_fSizeRatio(IFFontConstants::defaultSizeRatio)
, m_pEncoding(FONT_ENCODING_UNICODE)
, m_iGlyphBitmapWidth(0)
, m_iGlyphBitmapHeight(0)
{
}
//-------------------------------------------------------------------------------------------------
CFontRenderer::~CFontRenderer()
{
FT_Done_Face(m_pFace);
;
FT_Done_FreeType(m_pLibrary);
m_pFace = NULL;
m_pLibrary = NULL;
}
//-------------------------------------------------------------------------------------------------
int CFontRenderer::LoadFromFile(const string& szFileName)
{
int iError = FT_Init_FreeType(&m_pLibrary);
if (iError)
{
return 0;
}
if (m_pFace)
{
FT_Done_Face(m_pFace);
m_pFace = 0;
}
iError = FT_New_Face(m_pLibrary, szFileName.c_str(), 0, &m_pFace);
if (iError)
{
return 0;
}
SetEncoding(FONT_ENCODING_UNICODE);
return 1;
}
//-------------------------------------------------------------------------------------------------
int CFontRenderer::LoadFromMemory(unsigned char* pBuffer, int iBufferSize)
{
int iError = FT_Init_FreeType(&m_pLibrary);
if (iError)
{
return 0;
}
if (m_pFace)
{
FT_Done_Face(m_pFace);
m_pFace = 0;
}
iError = FT_New_Memory_Face(m_pLibrary, pBuffer, iBufferSize, 0, &m_pFace);
if (iError)
{
return 0;
}
SetEncoding(FONT_ENCODING_UNICODE);
return 1;
}
//-------------------------------------------------------------------------------------------------
int CFontRenderer::Release()
{
FT_Done_Face(m_pFace);
;
FT_Done_FreeType(m_pLibrary);
m_pFace = NULL;
m_pLibrary = NULL;
return 1;
}
//-------------------------------------------------------------------------------------------------
int CFontRenderer::SetGlyphBitmapSize(int iWidth, int iHeight, float sizeRatio)
{
m_iGlyphBitmapWidth = iWidth;
m_iGlyphBitmapHeight = iHeight;
// Assign the given scale for texture slots as long as its positive
m_fSizeRatio = sizeRatio > 0.0f ? sizeRatio : m_fSizeRatio;
FT_Set_Pixel_Sizes(m_pFace, (int)(m_iGlyphBitmapWidth * m_fSizeRatio), (int)(m_iGlyphBitmapHeight * m_fSizeRatio));
return 1;
}
//-------------------------------------------------------------------------------------------------
int CFontRenderer::GetGlyphBitmapSize(int* pWidth, int* pHeight)
{
if (pWidth)
{
*pWidth = m_iGlyphBitmapWidth;
}
if (pHeight)
{
*pHeight = m_iGlyphBitmapHeight;
}
return 1;
}
//-------------------------------------------------------------------------------------------------
int CFontRenderer::SetEncoding(FT_Encoding pEncoding)
{
if (FT_Select_Charmap(m_pFace, pEncoding))
{
return 0;
}
return 1;
}
//-------------------------------------------------------------------------------------------------
//-------------------------------------------------------------------------------------------------
int CFontRenderer::GetGlyph(CGlyphBitmap* pGlyphBitmap, int* iHoriAdvance, uint8* iGlyphWidth, uint8* iGlyphHeight, AZ::s32& iCharOffsetX, AZ::s32& iCharOffsetY, int iX, int iY, int iCharCode, const CFFont::FontHintParams& fontHintParams)
{
FT_Int32 loadFlags = GetLoadFlags(fontHintParams.hintBehavior);
loadFlags |= GetLoadTarget(fontHintParams.hintStyle);
int iError = FT_Load_Char(m_pFace, iCharCode, loadFlags);
if (iError)
{
return 0;
}
FT_Render_Mode renderMode = GetRenderMode(fontHintParams.hintStyle);
m_pGlyph = m_pFace->glyph;
iError = FT_Render_Glyph(m_pGlyph, renderMode);
if (iError)
{
return 0;
}
if (iHoriAdvance)
{
*iHoriAdvance = m_pGlyph->metrics.horiAdvance / fractionalPixelUnits;
}
if (iGlyphWidth)
{
*iGlyphWidth = m_pGlyph->bitmap.width;
}
if (iGlyphHeight)
{
*iGlyphHeight = m_pGlyph->bitmap.rows;
}
unsigned char* pBuffer = pGlyphBitmap->GetBuffer();
AZ_Assert(pBuffer, "CGlyphBitmap: bad buffer");
uint32 dwGlyphWidth = pGlyphBitmap->GetWidth();
iCharOffsetX = m_pGlyph->bitmap_left;
iCharOffsetY = (static_cast<AZ::s32>(round(m_iGlyphBitmapHeight * m_fSizeRatio)) - m_pGlyph->bitmap_top);
const int textureSlotBufferWidth = pGlyphBitmap->GetWidth();
const int textureSlotBufferHeight = pGlyphBitmap->GetHeight();
// might happen if font characters are too big or cache dimenstions in font.xml is too small "<font path="VeraMono.ttf" w="320" h="368"/>"
const bool charWidthFits = iX + m_pGlyph->bitmap.width <= textureSlotBufferWidth;
const bool charHeightFits = iY + m_pGlyph->bitmap.rows <= textureSlotBufferHeight;
const bool charFitsInSlot = charWidthFits && charHeightFits;
AZ_Error("Font", charFitsInSlot, "Character code %d doesn't fit in font texture; check 'sizeRatio' attribute in font XML or adjust this character's sizing in the font.", iCharCode);
// Since we might be re-rendering/overwriting a glyph that already exists
// in the font texture, clear the contents of this particular slot so no
// artifacts of the previous glyph remain.
pGlyphBitmap->Clear();
// Restrict iteration to smallest of either the texture slot or glyph
// bitmap buffer ranges
const int bufferMaxIterWidth = AZStd::GetMin<int>(textureSlotBufferWidth, m_pGlyph->bitmap.width);
const int bufferMaxIterHeight = AZStd::GetMin<int>(textureSlotBufferHeight, m_pGlyph->bitmap.rows);
for (int i = 0; i < bufferMaxIterHeight; i++)
{
int iNewY = i + iY;
for (int j = 0; j < bufferMaxIterWidth; j++)
{
unsigned char cColor = m_pGlyph->bitmap.buffer[(i * m_pGlyph->bitmap.width) + j];
int iOffset = iNewY * dwGlyphWidth + iX + j;
if (iOffset >= (int)dwGlyphWidth * m_iGlyphBitmapHeight)
{
continue;
}
pBuffer[iOffset] = cColor;
// pBuffer[iOffset] = cColor/2+32; // debug - visualize character in a block
}
}
return 1;
}
int CFontRenderer::GetGlyphScaled([[maybe_unused]] CGlyphBitmap* pGlyphBitmap, [[maybe_unused]] int* iGlyphWidth, [[maybe_unused]] int* iGlyphHeight, [[maybe_unused]] int iX, [[maybe_unused]] int iY, [[maybe_unused]] float fScaleX, [[maybe_unused]] float fScaleY, [[maybe_unused]] int iCharCode)
{
return 1;
}
Vec2 CFontRenderer::GetKerning(uint32_t leftGlyph, uint32_t rightGlyph)
{
FT_Vector kerningOffsets;
kerningOffsets.x = kerningOffsets.y = 0;
if (FT_HAS_KERNING(m_pFace))
{
const FT_UInt leftGlyphIndex = FT_Get_Char_Index(m_pFace, leftGlyph);
const FT_UInt rightGlyphIndex = FT_Get_Char_Index(m_pFace, rightGlyph);
[[maybe_unused]] FT_Error ftError = FT_Get_Kerning(m_pFace, leftGlyphIndex, rightGlyphIndex, FT_KERNING_DEFAULT, &kerningOffsets);
#if !defined(_RELEASE)
if (0 != ftError)
{
string warnMsg;
warnMsg.Format("FT_Get_Kerning returned %d", ftError);
CryWarning(VALIDATOR_MODULE_SYSTEM, VALIDATOR_WARNING, warnMsg.c_str());
}
#endif
}
return Vec2(azlossy_cast<float>(kerningOffsets.x / fractionalPixelUnits), azlossy_cast<float>(kerningOffsets.y / fractionalPixelUnits));
}
float CFontRenderer::GetAscenderToHeightRatio()
{
return (static_cast<float>(m_pFace->ascender) / static_cast<float>(m_pFace->height));
}
//-------------------------------------------------------------------------------------------------
/*
int CFontRenderer::FT_GetIndex(int iCharCode)
{
if (iCharCode < 256)
{
int iIndex = 0;
int iUnicode;
// try unicode
for (int i = 0; i < m_pFace->num_charmaps; i++)
{
if ((m_pFace->charmaps[i]->platform_id == 3) && (m_pFace->charmaps[i]->encoding_id == 1))
{
iUnicode = i;
FT_Set_Charmap(m_pFace, m_pFace->charmaps[i]);
iIndex = FT_Get_Char_Index(m_pFace, iCharCode);
// not unicode, try ascii
if (iIndex == 0)
{
for (int i = 0; i < m_pFace->num_charmaps; i++)
{
if ((m_pFace->charmaps[i]->platform_id == 0) && (m_pFace->charmaps[i]->encoding_id == 0))
{
FT_Set_Charmap(m_pFace, m_pFace->charmaps[i]);
iIndex = FT_Get_Char_Index(m_pFace, iCharCode);
// not ascii either, reuse unicode default "missing char"
if (iIndex == 0)
{
FT_Set_Charmap(m_pFace, m_pFace->charmaps[iUnicode]);
return FT_Get_Char_Index(m_pFace, iCharCode);
}
}
}
}
return iIndex;
}
}
return 0;
}
else
{
for (int i = 0; i < m_pFace->num_charmaps; i++)
{
if ((m_pFace->charmaps[i]->platform_id == 3) && (m_pFace->charmaps[i]->encoding_id == 1))
{
FT_Set_Charmap(m_pFace, m_pFace->charmaps[i]);
return FT_Get_Char_Index(m_pFace, iCharCode);
}
}
return 0;
}
return 0;
}
*/
#endif // #if !defined(USE_NULLFONT_ALWAYS)
-113
View File
@@ -1,113 +0,0 @@
/*
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
* its licensors.
*
* For complete copyright and license terms please see the LICENSE at the root of this
* distribution (the "License"). All use of this software is governed by the License,
* or, if provided, by the license below or the license accompanying this file. Do not
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
*/
// Original file Copyright Crytek GMBH or its affiliates, used under license.
// Description : Render a glyph outline into a bitmap using FreeType 2
#if !defined(USE_NULLFONT_ALWAYS)
#ifndef CRYINCLUDE_CRYFONT_FONTRENDERER_H
#define CRYINCLUDE_CRYFONT_FONTRENDERER_H
#pragma once
#include "GlyphBitmap.h"
#include "FFont.h"
#include <ft2build.h>
#pragma push_macro("generic")
#define generic GenericFromFreeTypeLibrary
#include <freetype/freetype.h>
#undef generic
#pragma pop_macro("generic")
// Corresponds to the Unicode character set. This value covers all versions of the Unicode repertoire,
// including ASCII and Latin-1. Most fonts include a Unicode charmap, but not all of them.
#define FONT_ENCODING_UNICODE (FT_ENCODING_UNICODE)
// Corresponds to the Microsoft Symbol encoding, used to encode mathematical symbols in the 32..255 character code range.
// For more information, see `http://www.ceviz.net/symbol.htm'.
#define FONT_ENCODING_SYMBOL (FT_ENCODING_MS_SYMBOL)
// Corresponds to Microsoft's Japanese SJIS encoding.
// More info at `http://langsupport.japanreference.com/encoding.shtml'. See note on multi-byte encodings below.
#define FONT_ENCODING_SJIS (FT_ENCODING_MS_SJIS)
// Corresponds to the encoding system for Simplified Chinese, as used in China. Only found in some TrueType fonts.
#define FONT_ENCODING_GB2312 (FT_ENCODING_MS_GB2312)
// Corresponds to the encoding system for Traditional Chinese, as used in Taiwan and Hong Kong. Only found in some TrueType fonts.
#define FONT_ENCODING_BIG5 (FT_ENCODING_MS_BIG5)
// Corresponds to the Korean encoding system known as Wansung.
// This is a Microsoft encoding that is only found in some TrueType fonts.
// For more information, see `http://www.microsoft.com/typography/unicode/949.txt'.
#define FONT_ENCODING_WANSUNG (FT_ENCODING_MS_WANSUNG)
// The Korean standard character set (KS C-5601-1992), which corresponds to Windows code page 1361.
// This character set includes all possible Hangeul character combinations. Only found on some rare TrueType fonts.
#define FONT_ENCODING_JOHAB (FT_ENCODING_MS_JOHAB)
//------------------------------------------------------------------------------------
class CFontRenderer
{
public:
CFontRenderer();
~CFontRenderer();
int LoadFromFile(const string& szFileName);
int LoadFromMemory(unsigned char* pBuffer, int iBufferSize);
int Release();
int SetGlyphBitmapSize(int iWidth, int iHeight, float sizeRatio);
int GetGlyphBitmapSize(int* pWidth, int* pHeight);
int SetSizeRatio(float fSizeRatio) { m_fSizeRatio = fSizeRatio; return 1; };
float GetSizeRatio() { return m_fSizeRatio; };
int SetEncoding(FT_Encoding pEncoding);
FT_Encoding GetEncoding() { return m_pEncoding; };
//! Populates the given pGlyphBitmap's buffer from the FreeType bitmap buffer
//! \param iCharCode Used as a character index to retrieve the FreeType glyph and it's associated bitmap buffer for the character
//! \param pGlyphBitmap The FreeType glyph buffer is essentially copied into this CGlyphBitmap buffer
int GetGlyph(CGlyphBitmap* pGlyphBitmap, int* iHoriAdvance, uint8* iGlyphWidth, uint8* iGlyphHeight, AZ::s32& iCharOffsetX, AZ::s32& iCharOffsetY, int iX, int iY, int iCharCode, const CFFont::FontHintParams& glyphFlags = CFFont::FontHintParams());
int GetGlyphScaled(CGlyphBitmap* pGlyphBitmap, int* iGlyphWidth, int* iGlyphHeight, int iX, int iY, float fScaleX, float fScaleY, int iCharCode);
void GetMemoryUsage([[maybe_unused]] ICrySizer* pSizer) const {}
bool GetMonospaced() const { return FT_IS_FIXED_WIDTH(m_pFace) != 0; }
Vec2 GetKerning(uint32_t leftGlyph, uint32_t rightGlyph);
float GetAscenderToHeightRatio();
private:
FT_Library m_pLibrary;
FT_Face m_pFace;
FT_GlyphSlot m_pGlyph;
float m_fSizeRatio;
FT_Encoding m_pEncoding;
int m_iGlyphBitmapWidth;
int m_iGlyphBitmapHeight;
};
#endif // CRYINCLUDE_CRYFONT_FONTRENDERER_H
#endif // #if !defined(USE_NULLFONT_ALWAYS)
-633
View File
@@ -1,633 +0,0 @@
/*
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
* its licensors.
*
* For complete copyright and license terms please see the LICENSE at the root of this
* distribution (the "License"). All use of this software is governed by the License,
* or, if provided, by the license below or the license accompanying this file. Do not
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
*/
// Original file Copyright Crytek GMBH or its affiliates, used under license.
// Purpose:
// - Create and update a texture with the most recently used glyphs
#include "CryFont_precompiled.h"
#if !defined(USE_NULLFONT_ALWAYS)
#include "FontTexture.h"
#include "UnicodeIterator.h"
#include <AzCore/IO/FileIO.h>
#ifdef WIN32
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#undef GetCharWidth
#endif
//-------------------------------------------------------------------------------------------------
CFontTexture::CFontTexture()
: m_wSlotUsage(1)
, m_iWidth(0)
, m_iHeight(0)
, m_fInvWidth(0.0f)
, m_fInvHeight(0.0f)
, m_iCellWidth(0)
, m_iCellHeight(0)
, m_fTextureCellWidth(0)
, m_fTextureCellHeight(0)
, m_iWidthCellCount(0)
, m_iHeightCellCount(0)
, m_nTextureSlotCount(0)
, m_pBuffer(0)
, m_iSmoothMethod(FONT_SMOOTH_NONE)
, m_iSmoothAmount(FONT_SMOOTH_AMOUNT_NONE)
{
}
//-------------------------------------------------------------------------------------------------
CFontTexture::~CFontTexture()
{
Release();
}
//-------------------------------------------------------------------------------------------------
int CFontTexture::CreateFromFile(const string& szFileName, int iWidth, int iHeight, int iSmoothMethod, int iSmoothAmount, int iWidthCellCount, int iHeightCellCount)
{
if (!m_pGlyphCache.LoadFontFromFile(szFileName))
{
Release();
return 0;
}
if (!Create(iWidth, iHeight, iSmoothMethod, iSmoothAmount, iWidthCellCount, iHeightCellCount))
{
return 0;
}
return 1;
}
//-------------------------------------------------------------------------------------------------
int CFontTexture::CreateFromMemory(unsigned char* pFileData, int iDataSize, int iWidth, int iHeight, int iSmoothMethod, int iSmoothAmount, int iWidthCellCount, int iHeightCellCount, float sizeRatio)
{
if (!m_pGlyphCache.LoadFontFromMemory(pFileData, iDataSize))
{
Release();
return 0;
}
if (!Create(iWidth, iHeight, iSmoothMethod, iSmoothAmount, iWidthCellCount, iHeightCellCount, sizeRatio))
{
return 0;
}
return 1;
}
//-------------------------------------------------------------------------------------------------
int CFontTexture::Create(int iWidth, int iHeight, int iSmoothMethod, int iSmoothAmount, int iWidthCellCount, int iHeightCellCount, float sizeRatio)
{
m_pBuffer = new FONT_TEXTURE_TYPE[iWidth * iHeight];
if (!m_pBuffer)
{
return 0;
}
memset(m_pBuffer, 0, iWidth * iHeight * sizeof(FONT_TEXTURE_TYPE));
if (!(iWidthCellCount * iHeightCellCount))
{
return 0;
}
m_iWidth = iWidth;
m_iHeight = iHeight;
m_fInvWidth = 1.0f / (float)iWidth;
m_fInvHeight = 1.0f / (float)iHeight;
m_iWidthCellCount = iWidthCellCount;
m_iHeightCellCount = iHeightCellCount;
m_nTextureSlotCount = m_iWidthCellCount * m_iHeightCellCount;
m_iSmoothMethod = iSmoothMethod;
m_iSmoothAmount = iSmoothAmount;
m_iCellWidth = m_iWidth / m_iWidthCellCount;
m_iCellHeight = m_iHeight / m_iHeightCellCount;
m_fTextureCellWidth = m_iCellWidth * m_fInvWidth;
m_fTextureCellHeight = m_iCellHeight * m_fInvHeight;
if (!m_pGlyphCache.Create(FONT_GLYPH_CACHE_SIZE, m_iCellWidth, m_iCellHeight, iSmoothMethod, iSmoothAmount, sizeRatio))
{
Release();
return 0;
}
if (!CreateSlotList(m_nTextureSlotCount))
{
Release();
return 0;
}
return 1;
}
//-------------------------------------------------------------------------------------------------
int CFontTexture::Release()
{
delete[] m_pBuffer;
m_pBuffer = 0;
ReleaseSlotList();
m_pSlotTable.clear();
m_pGlyphCache.Release();
m_iWidthCellCount = 0;
m_iHeightCellCount = 0;
m_nTextureSlotCount = 0;
m_iWidth = 0;
m_iHeight = 0;
m_fInvWidth = 0.0f;
m_fInvHeight = 0.0f;
m_iCellWidth = 0;
m_iCellHeight = 0;
m_iSmoothMethod = 0;
m_iSmoothAmount = 0;
m_fTextureCellWidth = 0.0f;
m_fTextureCellHeight = 0.0f;
m_wSlotUsage = 1;
return 1;
}
//-------------------------------------------------------------------------------------------------
uint32 CFontTexture::GetSlotChar(int iSlot) const
{
return m_pSlotList[iSlot]->cCurrentChar;
}
//-------------------------------------------------------------------------------------------------
CTextureSlot* CFontTexture::GetCharSlot(uint32 cChar, const Vec2i& glyphSize)
{
CryFont::FontTexture::CTextureSlotKey slotKey = GetTextureSlotKey(cChar, glyphSize);
CTextureSlotTableItor pItor = m_pSlotTable.find(slotKey);
if (pItor != m_pSlotTable.end())
{
return pItor->second;
}
return 0;
}
//-------------------------------------------------------------------------------------------------
CTextureSlot* CFontTexture::GetLRUSlot()
{
uint16 wMaxSlotAge = 0;
CTextureSlot* pLRUSlot = 0;
CTextureSlot* pSlot;
CTextureSlotListItor pItor = m_pSlotList.begin();
while (pItor != m_pSlotList.end())
{
pSlot = *pItor;
if (pSlot->wSlotUsage == 0)
{
return pSlot;
}
else
{
uint16 slotAge = m_wSlotUsage - pSlot->wSlotUsage;
if (slotAge > wMaxSlotAge)
{
pLRUSlot = pSlot;
wMaxSlotAge = slotAge;
}
}
++pItor;
}
return pLRUSlot;
}
//-------------------------------------------------------------------------------------------------
CTextureSlot* CFontTexture::GetMRUSlot()
{
uint16 wMinSlotAge = 0xFFFF;
CTextureSlot* pMRUSlot = 0;
CTextureSlot* pSlot;
CTextureSlotListItor pItor = m_pSlotList.begin();
while (pItor != m_pSlotList.end())
{
pSlot = *pItor;
if (pSlot->wSlotUsage != 0)
{
uint16 slotAge = m_wSlotUsage - pSlot->wSlotUsage;
if (slotAge > wMinSlotAge)
{
pMRUSlot = pSlot;
wMinSlotAge = slotAge;
}
}
++pItor;
}
return pMRUSlot;
}
//-------------------------------------------------------------------------------------------------
int CFontTexture::PreCacheString(const char* szString, int* pUpdated, float sizeRatio, const Vec2i& glyphSize, const CFFont::FontHintParams& fontHintParams)
{
Vec2i clampedGlyphSize = ClampGlyphSize(glyphSize, m_iCellWidth, m_iCellHeight);
uint16 wSlotUsage = m_wSlotUsage++;
int iUpdated = 0;
uint32 cChar;
for (Unicode::CIterator<const char*, false> it(szString); *it; ++it)
{
cChar = *it;
CTextureSlot* pSlot = GetCharSlot(cChar, clampedGlyphSize);
if (!pSlot)
{
pSlot = GetLRUSlot();
if (!pSlot)
{
return 0;
}
if (!UpdateSlot(pSlot->iTextureSlot, wSlotUsage, cChar, sizeRatio, clampedGlyphSize, fontHintParams))
{
return 0;
}
++iUpdated;
}
else
{
pSlot->wSlotUsage = wSlotUsage;
}
}
if (pUpdated)
{
*pUpdated = iUpdated;
}
if (iUpdated)
{
return 1;
}
return 2;
}
//-------------------------------------------------------------------------------------------------
void CFontTexture::GetTextureCoord(CTextureSlot* pSlot, float texCoords[4],
int& iCharSizeX, int& iCharSizeY, int& iCharOffsetX, int& iCharOffsetY,
const Vec2i& glyphSize) const
{
if (!pSlot)
{
return; // expected behavior
}
// Re-rendered glyphs are stored at smaller sizes than glyphs rendered at
// the (maximum) font texture slot resolution. We scale the returned width
// and height of the (actual) rendered glyph sizes so its transparent to
// callers that the glyph is actually smaller (from being re-rendered).
const float requestSizeWidthScale = AZ::GetMin<float>(1.0f, GetRequestSizeWidthScale(glyphSize));
const float requestSizeHeightScale = AZ::GetMin<float>(1.0f, GetRequestSizeHeightScale(glyphSize));
const float invRequestSizeWidthScale = 1.0f / requestSizeWidthScale;
const float invRequestSizeHeightScale = 1.0f / requestSizeHeightScale;
// The inverse scale grows as the glyph size decreases. Once the glyph size
// reaches the font texture's max slot dimensions, we cap width/height scale
// since the text draw context will apply normal (as opposed to re-rendered)
// scaling.
int iChWidth = static_cast<int>(pSlot->iCharWidth * invRequestSizeWidthScale);
int iChHeight = static_cast<int>(pSlot->iCharHeight * invRequestSizeHeightScale);
float slotCoord0 = pSlot->vTexCoord[0];
float slotCoord1 = pSlot->vTexCoord[1];
texCoords[0] = slotCoord0 - m_fInvWidth; // extra pixel for nicer bilinear filter
texCoords[1] = slotCoord1 - m_fInvHeight; // extra pixel for nicer bilinear filter
// UV coordinates also must be scaled relative to the re-rendered glyph size
// as well. Width scale must be capped at 1.0f since glyph can't grow
// beyond the slot's resolution.
texCoords[2] = slotCoord0 + (((float)iChWidth * m_fInvWidth) * requestSizeWidthScale);
texCoords[3] = slotCoord1 + (((float)iChHeight * m_fInvHeight) * requestSizeHeightScale);
iCharSizeX = iChWidth + 1; // extra pixel for nicer bilinear filter
iCharSizeY = iChHeight + 1; // extra pixel for nicer bilinear filter
// Offsets are scaled accordingly when the rendered glyph size is smaller
// than the glyph/slot dimensions, but otherwise we expect the text draw
// context to apply scaling beyond that.
iCharOffsetX = static_cast<int>(pSlot->iCharOffsetX * invRequestSizeWidthScale);
iCharOffsetY = static_cast<int>(pSlot->iCharOffsetY * invRequestSizeHeightScale);
}
//-------------------------------------------------------------------------------------------------
int CFontTexture::GetCharacterWidth(uint32 cChar) const
{
CTextureSlotTableItorConst pItor = m_pSlotTable.find(GetTextureSlotKey(cChar));
if (pItor == m_pSlotTable.end())
{
return 0;
}
const CTextureSlot& rSlot = *pItor->second;
// For proportional fonts, add one pixel of spacing for aesthetic reasons
int proportionalOffset = GetMonospaced() ? 0 : 1;
return rSlot.iCharWidth + proportionalOffset;
}
//-------------------------------------------------------------------------------------------------
int CFontTexture::GetHorizontalAdvance(uint32 cChar, const Vec2i& glyphSize) const
{
CTextureSlotTableItorConst pItor = m_pSlotTable.find(GetTextureSlotKey(cChar, glyphSize));
if (pItor == m_pSlotTable.end())
{
return 0;
}
const CTextureSlot& rSlot = *pItor->second;
// Re-rendered glyphs are stored at smaller sizes than glyphs rendered at
// the (maximum) font texture slot resolution. We scale the returned width
// and height of the (actual) rendered glyph sizes so its transparent to
// callers that the glyph is actually smaller (from being re-rendered).
const float requestSizeWidthScale = GetRequestSizeWidthScale(glyphSize);
const float invRequestSizeWidthScale = 1.0f / requestSizeWidthScale;
// Only multiply by 1.0f when glyphsize is greater than cell width because we assume that callers
// will use the font draw text context to scale the value appropriately.
return static_cast<int>(rSlot.iHoriAdvance * AZ::GetMax<float>(1.0f, invRequestSizeWidthScale));
}
//-------------------------------------------------------------------------------------------------
/*
int CFontTexture::GetCharHeightByChar(wchar_t cChar)
{
CTextureSlotTableItor pItor = m_pSlotTable.find(cChar);
if (pItor != m_pSlotTable.end())
{
return pItor->second->iCharHeight;
}
return 0;
}
*/
//-------------------------------------------------------------------------------------------------
int CFontTexture::WriteToFile([[maybe_unused]] const string& szFileName)
{
#ifdef WIN32
AZ::IO::FileIOStream outputFile(szFileName.c_str(), AZ::IO::OpenMode::ModeWrite | AZ::IO::OpenMode::ModeBinary);
if (!outputFile.IsOpen())
{
return 0;
}
BITMAPFILEHEADER pHeader;
BITMAPINFOHEADER pInfoHeader;
memset(&pHeader, 0, sizeof(BITMAPFILEHEADER));
memset(&pInfoHeader, 0, sizeof(BITMAPINFOHEADER));
pHeader.bfType = 0x4D42;
pHeader.bfSize = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER) + m_iWidth * m_iHeight * 3;
pHeader.bfOffBits = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER);
pInfoHeader.biSize = sizeof(BITMAPINFOHEADER);
pInfoHeader.biWidth = m_iWidth;
pInfoHeader.biHeight = m_iHeight;
pInfoHeader.biPlanes = 1;
pInfoHeader.biBitCount = 24;
pInfoHeader.biCompression = 0;
pInfoHeader.biSizeImage = m_iWidth * m_iHeight * 3;
outputFile.Write(sizeof(BITMAPFILEHEADER), &pHeader);
outputFile.Write(sizeof(BITMAPINFOHEADER), &pInfoHeader);
unsigned char cRGB[3];
for (int i = m_iHeight - 1; i >= 0; i--)
{
for (int j = 0; j < m_iWidth; j++)
{
cRGB[0] = m_pBuffer[(i * m_iWidth) + j];
cRGB[1] = *cRGB;
cRGB[2] = *cRGB;
outputFile.Write(3, cRGB);
}
}
#endif
return 1;
}
//-------------------------------------------------------------------------------------------------
Vec2 CFontTexture::GetKerning(uint32_t leftGlyph, uint32_t rightGlyph)
{
return m_pGlyphCache.GetKerning(leftGlyph, rightGlyph);
}
//-------------------------------------------------------------------------------------------------
float CFontTexture::GetAscenderToHeightRatio()
{
return m_pGlyphCache.GetAscenderToHeightRatio();
}
//-------------------------------------------------------------------------------------------------
int CFontTexture::CreateSlotList(int iListSize)
{
int y, x;
for (int i = 0; i < iListSize; i++)
{
CTextureSlot* pTextureSlot = new CTextureSlot;
if (!pTextureSlot)
{
return 0;
}
pTextureSlot->iTextureSlot = i;
pTextureSlot->Reset();
y = i / m_iWidthCellCount;
x = i % m_iWidthCellCount;
pTextureSlot->vTexCoord[0] = (float)(x * m_fTextureCellWidth) + (0.5f / (float)m_iWidth);
pTextureSlot->vTexCoord[1] = (float)(y * m_fTextureCellHeight) + (0.5f / (float)m_iHeight);
m_pSlotList.push_back(pTextureSlot);
}
return 1;
}
//-------------------------------------------------------------------------------------------------
int CFontTexture::ReleaseSlotList()
{
CTextureSlotListItor pItor = m_pSlotList.begin();
while (pItor != m_pSlotList.end())
{
delete (*pItor);
pItor = m_pSlotList.erase(pItor);
}
return 1;
}
//-------------------------------------------------------------------------------------------------
int CFontTexture::UpdateSlot(int iSlot, uint16 wSlotUsage, uint32 cChar, float sizeRatio, const Vec2i& glyphSize, const CFFont::FontHintParams& fontHintParams)
{
CTextureSlot* pSlot = m_pSlotList[iSlot];
if (!pSlot)
{
return 0;
}
CTextureSlotTableItor pItor = m_pSlotTable.find(GetTextureSlotKey(pSlot->cCurrentChar, pSlot->glyphSize));
if (pItor != m_pSlotTable.end())
{
m_pSlotTable.erase(pItor);
}
m_pSlotTable.insert(AZStd::pair<CryFont::FontTexture::CTextureSlotKey, CTextureSlot*>(GetTextureSlotKey(cChar, glyphSize), pSlot));
pSlot->glyphSize = glyphSize;
pSlot->wSlotUsage = wSlotUsage;
pSlot->cCurrentChar = cChar;
int iWidth = 0;
int iHeight = 0;
// blit the char glyph into the texture
int x = pSlot->iTextureSlot % m_iWidthCellCount;
int y = pSlot->iTextureSlot / m_iWidthCellCount;
CGlyphBitmap* pGlyphBitmap;
if (glyphSize.x > 0 && glyphSize.y > 0)
{
m_pGlyphCache.SetGlyphBitmapSize(glyphSize.x, glyphSize.y, sizeRatio);
}
if (!m_pGlyphCache.GetGlyph(&pGlyphBitmap, &pSlot->iHoriAdvance, &iWidth, &iHeight, pSlot->iCharOffsetX, pSlot->iCharOffsetY, cChar, glyphSize, fontHintParams))
{
return 0;
}
pSlot->iCharWidth = iWidth;
pSlot->iCharHeight = iHeight;
// Add a pixel along width and height to avoid artifacts being rendered
// from a previous glyph in this slot due to bilinear filtering. The source
// glyph bitmap buffer is presumed to be cleared prior to FreeType rendering
// to the bitmap.
const int blitWidth = AZ::GetMin<int>(iWidth + 1, m_iCellWidth);
const int blitHeight = AZ::GetMin<int>(iHeight + 1, m_iCellHeight);
pGlyphBitmap->BlitTo8(m_pBuffer, 0, 0,
blitWidth, blitHeight, x * m_iCellWidth, y * m_iCellHeight, m_iWidth);
return 1;
}
//-------------------------------------------------------------------------------------------------
void CFontTexture::CreateGradientSlot()
{
CTextureSlot* pSlot = GetGradientSlot();
assert(pSlot->cCurrentChar == (uint32)~0); // 0 needs to be unused spot
pSlot->Reset();
pSlot->iCharWidth = m_iCellWidth - 2;
pSlot->iCharHeight = m_iCellHeight - 2;
pSlot->SetNotReusable();
int x = pSlot->iTextureSlot % m_iWidthCellCount;
int y = pSlot->iTextureSlot / m_iWidthCellCount;
assert(sizeof(*m_pBuffer) == sizeof(uint8));
uint8* pBuffer = &m_pBuffer[x * m_iCellWidth + y * m_iCellHeight * m_iWidth];
for (uint32 dwY = 0; dwY < pSlot->iCharHeight; ++dwY)
{
for (uint32 dwX = 0; dwX < pSlot->iCharWidth; ++dwX)
{
pBuffer[dwX + dwY * m_iWidth] = dwY * 255 / (pSlot->iCharHeight - 1);
}
}
}
//-------------------------------------------------------------------------------------------------
CTextureSlot* CFontTexture::GetGradientSlot()
{
return m_pSlotList[0];
}
//-------------------------------------------------------------------------------------------------
CryFont::FontTexture::CTextureSlotKey CFontTexture::GetTextureSlotKey(uint32 cChar, const Vec2i& glyphSize) const
{
const Vec2i clampedGlyphSize(ClampGlyphSize(glyphSize, m_iCellWidth, m_iCellHeight));
return CryFont::FontTexture::CTextureSlotKey(clampedGlyphSize, cChar);
}
Vec2i CFontTexture::ClampGlyphSize(const Vec2i& glyphSize, int cellWidth, int cellHeight)
{
const Vec2i maxCellDimensions(cellWidth, cellHeight);
Vec2i clampedGlyphSize(glyphSize);
const bool hasZeroDimension = glyphSize.x == 0 || glyphSize.y == 0;
const bool isDefaultSize = glyphSize == CCryFont::defaultGlyphSize;
const bool exceedsDimensions = glyphSize.x > cellWidth || glyphSize.y > cellHeight;
const bool useMaxCellDimension = hasZeroDimension || isDefaultSize || exceedsDimensions;
if (useMaxCellDimension)
{
clampedGlyphSize = maxCellDimensions;
}
return clampedGlyphSize;
}
#endif // #if !defined(USE_NULLFONT_ALWAYS)
-301
View File
@@ -1,301 +0,0 @@
/*
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
* its licensors.
*
* For complete copyright and license terms please see the LICENSE at the root of this
* distribution (the "License"). All use of this software is governed by the License,
* or, if provided, by the license below or the license accompanying this file. Do not
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
*/
// Original file Copyright Crytek GMBH or its affiliates, used under license.
#ifndef CRYINCLUDE_CRYFONT_FONTTEXTURE_H
#define CRYINCLUDE_CRYFONT_FONTTEXTURE_H
#pragma once
#if !defined(USE_NULLFONT_ALWAYS)
#include "GlyphCache.h"
#include "GlyphBitmap.h"
#include "CryFont.h"
#include "FFont.h"
typedef uint8 FONT_TEXTURE_TYPE;
// the number of slots in the glyph cache
// each slot ocupies ((glyph_bitmap_width * glyph_bitmap_height) + 24) bytes
#define FONT_GLYPH_CACHE_SIZE (1)
// the glyph spacing in font texels between characters in proportional font mode (more correct would be to take the value in the character)
#define FONT_GLYPH_PROP_SPACING (1)
// the size of a rendered space, this value gets multiplied by the default characted width
#define FONT_SPACE_SIZE (0.5f)
// don't draw this char (used to avoid drawing color codes)
#define FONT_NOT_DRAWABLE_CHAR (0xffff)
// smoothing methods
#define FONT_SMOOTH_NONE 0
#define FONT_SMOOTH_BLUR 1
#define FONT_SMOOTH_SUPERSAMPLE 2
// smoothing amounts
#define FONT_SMOOTH_AMOUNT_NONE 0
#define FONT_SMOOTH_AMOUNT_2X 1
#define FONT_SMOOTH_AMOUNT_4X 2
//! Stores glyph meta-data read from the font (FreeType).
//!
//! \sa CCacheSlot
typedef struct CTextureSlot
{
Vec2i glyphSize = CCryFont::defaultGlyphSize; //!< Size of the rendered glyph stored in the font texture
uint16 wSlotUsage; //!< For LRU strategy, 0xffff is never released
uint32 cCurrentChar; //!< ~0 if not used for characters
int iTextureSlot;
int iHoriAdvance; //!< Advance width. See FT_Glyph_Metrics::horiAdvance.
float vTexCoord[2]; //!< Character position in the texture (not yet half texel corrected)
uint8 iCharWidth; //!< Glyph width (in pixel)
uint8 iCharHeight; //!< Glyph height (in pixel)
AZ::s32 iCharOffsetX; //!< Glyph's left-side bearing (in pixels). See FT_GlyphSlotRec::bitmap_left.
AZ::s32 iCharOffsetY; //!< Glyph's top bearing (in pixels). See FT_GlyphSlotRec::bitmap_top.
void Reset()
{
wSlotUsage = 0;
cCurrentChar = ~0;
iHoriAdvance = 0;
iCharWidth = 0;
iCharHeight = 0;
iCharOffsetX = 0;
iCharOffsetY = 0;
}
void SetNotReusable()
{
wSlotUsage = 0xffff;
}
void GetMemoryUsage([[maybe_unused]] ICrySizer* pSizer) const {}
} CTextureSlot;
typedef std::vector<CTextureSlot*> CTextureSlotList;
typedef std::vector<CTextureSlot*>::iterator CTextureSlotListItor;
namespace CryFont
{
namespace FontTexture
{
//! Height and width pair for glyph size mapping
typedef Vec2i CGlyphSizeType;
//! Pair for mapping a height and width size to a UTF32 character/glyph
typedef AZStd::pair<CGlyphSizeType, uint32> CTextureSlotKey;
//! Hasher for texture slot table keys (glyphsize-char code pair)
//!
//! Instead of creating our own custom hash, the types are broken down to their
//! native types (ints) and passed to existing hashes that handle those types.
struct HashTextureSlotTableKey
{
typedef CTextureSlotKey ArgumentType;
typedef AZStd::size_t ResultType;
typedef AZStd::pair<int32, int32> Int32Pair;
typedef AZStd::pair<Int32Pair, uint32> Int32PairU32Pair;
ResultType operator()(const ArgumentType& value) const
{
// Utiliize existing hash function for pairs of ints
AZStd::hash<Int32PairU32Pair> pairHash;
return pairHash(Int32PairU32Pair(Int32Pair(value.first.x, value.first.y), value.second));
}
};
}
}
//! Maps size-speicifc UTF32 glyphs to their corresponding texture slots
typedef AZStd::unordered_map<CryFont::FontTexture::CTextureSlotKey, CTextureSlot*, CryFont::FontTexture::HashTextureSlotTableKey> CTextureSlotTable;
typedef CTextureSlotTable::iterator CTextureSlotTableItor;
typedef CTextureSlotTable::const_iterator CTextureSlotTableItorConst;
#ifdef WIN64
#undef GetCharWidth
#undef GetCharHeight
#endif
//! Stores the glyphs of a font within a single texture.
//!
//! The texture resolution is configurable, as is the number of slots within
//! the texture.
//!
//! A texture slot contains a single glyph within the font and are uniform
//! size throughout the font texture (each slot occupies the same size
//! regardless of the size of a glyph being stored, so a '.' occupies the
//! same amount of space as a 'W', for example).
//!
//! Font glyph buffers are read from FreeType and copied into the texture.
//!
//! \sa CTextureSlot, CFontRenderer
class CFontTexture
{
public:
CFontTexture();
~CFontTexture();
int CreateFromFile(const string& szFileName, int iWidth, int iHeight, int iSmoothMethod, int iSmoothAmount, int iWidthCharCount = 16, int iHeightCharCount = 16);
//! Default texture slot width/height is 16x8 slots, allowing for 128 glyphs to be stored in the font texture. This was
//! previously 16x16, allowing 256 glyphs to be stored. For reference, there are 95 printable ASCII characters, so by
//! reducing the number of slots, the height of the font texture can be halved (for some nice memory savings). We may
//! want to make this configurable in the font XML (especially for languages with a large number of printable chars).
int CreateFromMemory(unsigned char* pFileData, int iDataSize, int iWidth, int iHeight, int iSmoothMethod, int iSmoothAmount, int iWidthCharCount, int iHeightCharCount, float sizeRatio);
int Create(int iWidth, int iHeight, int iSmoothMethod, int iSmoothAmount, int iWidthCharCount = 16, int iHeightCharCount = 16, float sizeRatio = IFFontConstants::defaultSizeRatio);
int Release();
int SetEncoding(FT_Encoding pEncoding) { return m_pGlyphCache.SetEncoding(pEncoding); }
FT_Encoding GetEncoding() { return m_pGlyphCache.GetEncoding(); }
int GetCellWidth() { return m_iCellWidth; }
int GetCellHeight() { return m_iCellHeight; }
int GetWidth() { return m_iWidth; }
int GetHeight() { return m_iHeight; }
int GetWidthCellCount() { return m_iWidthCellCount; }
int GetHeightCellCount() { return m_iHeightCellCount; }
float GetTextureCellWidth() { return m_fTextureCellWidth; }
float GetTextureCellHeight() { return m_fTextureCellHeight; }
FONT_TEXTURE_TYPE* GetBuffer() { return m_pBuffer; }
uint32 GetSlotChar(int iSlot) const;
CTextureSlot* GetCharSlot(uint32 cChar, const Vec2i& glyphSize = CCryFont::defaultGlyphSize);
CTextureSlot* GetGradientSlot();
CTextureSlot* GetLRUSlot();
CTextureSlot* GetMRUSlot();
//! Returns 1 if texture updated, returns 2 if texture not updated, returns 0 on error
//! \param szString A string of glyphs (UTF8) to added to the font texture (if they don't already exist in the font texture)
//! \param pUpdated is the number of slots updated
//! \param sizeRatio A sizing scale that gets applied to all glyphs sizes before they are stored in the font texture.
//! \param glyphSize The resolution to render the glyphs in szString at.
//! \param glyphFlags Controls hinting behavior for glyphs rendered to the font texture.
int PreCacheString(const char* szString, int* pUpdated = 0, float sizeRatio = IFFontConstants::defaultSizeRatio, const Vec2i& glyphSize = CCryFont::defaultGlyphSize, const CFFont::FontHintParams& glyphFlags = CFFont::FontHintParams());
// Arguments:
// pSlot - function does nothing if this pointer is 0
void GetTextureCoord(CTextureSlot * pSlot, float texCoords[4], int& iCharSizeX, int& iCharSizeY, int& iCharOffsetX, int& iCharOffsetY, const Vec2i& glyphSize = CCryFont::defaultGlyphSize) const;
int GetCharacterWidth(uint32 cChar) const;
//! Gets the horizontal advance for the given glyph/char.
//! \param cChar The glyph (UTF32) to get the horizontal advance for.
//! \param glyphSize The rendered size of the glyph to get the advance for (the same glyph could be stored in the font texture at multiple sizes).
int GetHorizontalAdvance(uint32 cChar, const Vec2i& glyphSize = CCryFont::defaultGlyphSize) const;
// int GetCharHeightByChar(wchar_t cChar);
// useful for special feature rendering interleaved with fonts (e.g. box behind the text)
void CreateGradientSlot();
int WriteToFile(const string& szFileName);
void GetMemoryUsage(ICrySizer* pSizer) const
{
pSizer->AddObject(this, sizeof(*this));
pSizer->AddObject(m_pGlyphCache);
pSizer->AddObject(m_pSlotList);
//pSizer->AddContainer(m_pSlotTable);
pSizer->AddObject(m_pBuffer, m_iWidth * m_iHeight * sizeof(FONT_TEXTURE_TYPE));
}
bool GetMonospaced() const { return m_pGlyphCache.GetMonospaced(); }
Vec2 GetKerning(uint32_t leftGlyph, uint32_t rightGlyph);
float GetAscenderToHeightRatio();
public: // ---------------------------------------------------------------
//! Clamps the given glyph size to the given max cell width and height dimensions.
static Vec2i ClampGlyphSize(const Vec2i& glyphSize, int cellWidth, int cellHeight);
private: // ---------------------------------------------------------------
int CreateSlotList(int iListSize);
int ReleaseSlotList();
//! Updates the given font texture slot with the given glyph (UTF8) with the given parameters. If the glyph doesn't
//! exist in the font texture at the given size, then the glyph will be rendered to the font texture with the given
//! parameters.
//! \param iSlot Index of the texture slot to update within the slot list.
//! \param wSlotUsage Used for LRU strategy to determine how many times a glyph is referenced for retention within the font texture (before eviction).
//! \param cChar UTF32 glyph to store within the slot.
//! \param sizeRatio A sizing scale that should be applied to the glyph before being stored within the font texture.
//! \param glyphSize The size of the glyph to be rendered at within the font texture.
//! \param glyphFlags Specifies hinting behavior that should be applied to the glyph when rendered to the font texture.
int UpdateSlot(int iSlot, uint16 wSlotUsage, uint32 cChar, float sizeRatio, const Vec2i& glyphSize = CCryFont::defaultGlyphSize, const CFFont::FontHintParams& glyphFlags = CFFont::FontHintParams());
CryFont::FontTexture::CTextureSlotKey GetTextureSlotKey(uint32 cChar, const Vec2i& glyphSize = CCryFont::defaultGlyphSize) const;
//! Calculates scaling info that should be applied when the rendered glyph size doesn't match the maximum glyph slot resolution.
//!
//! Glyphs can be re-rendered to glyph slots at smaller resolutions for pixel-perfect resolution (rather than applying a scale
//! to glyphs rendered at larger sizes). These scaling values allow clients of the font texture to use the glyphs without regard
//! to whether the glyphs have been re-rendered or not.
float GetRequestSizeWidthScale(const Vec2i& glyphSize) const
{
const int cellWidth = m_iCellWidth == 0 ? 1 : m_iCellWidth;
const float invCellWidth = 1.0f / cellWidth;
return glyphSize.x > 0 ? glyphSize.x * invCellWidth : 1.0f;
}
//! Calculates scaling info that should be applied when the rendered glyph size doesn't match the maximum glyph slot resolution.
//!
//! Glyphs can be re-rendered to glyph slots at smaller resolutions for pixel-perfect resolution (rather than applying a scale
//! to glyphs rendered at larger sizes). These scaling values allow clients of the font texture to use the glyphs without regard
//! to whether the glyphs have been re-rendered or not.
float GetRequestSizeHeightScale(const Vec2i& glyphSize) const
{
const int cellHeight = m_iCellHeight == 0 ? 1 : m_iCellHeight;
const float invCellHeight = 1.0f / cellHeight;
return glyphSize.y > 0 ? glyphSize.y * invCellHeight : 1.0f;
}
// --------------------------------
int m_iWidth; // whole texture cache width
int m_iHeight; // whole texture cache height
float m_fInvWidth;
float m_fInvHeight;
int m_iCellWidth;
int m_iCellHeight;
float m_fTextureCellWidth;
float m_fTextureCellHeight;
int m_iWidthCellCount;
int m_iHeightCellCount;
int m_nTextureSlotCount;
int m_iSmoothMethod;
int m_iSmoothAmount;
CGlyphCache m_pGlyphCache;
CTextureSlotList m_pSlotList;
CTextureSlotTable m_pSlotTable;
FONT_TEXTURE_TYPE* m_pBuffer; // [y*iWidth * x] x=0..iWidth-1, y=0..iHeight-1
uint16 m_wSlotUsage;
};
#endif // #if !defined(USE_NULLFONT_ALWAYS)
#endif // CRYINCLUDE_CRYFONT_FONTTEXTURE_H
-396
View File
@@ -1,396 +0,0 @@
/*
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
* its licensors.
*
* For complete copyright and license terms please see the LICENSE at the root of this
* distribution (the "License"). All use of this software is governed by the License,
* or, if provided, by the license below or the license accompanying this file. Do not
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
*/
// Original file Copyright Crytek GMBH or its affiliates, used under license.
// Purpose:
// - Hold a glyph bitmap and blit it to the main texture
#include "CryFont_precompiled.h"
#include "GlyphBitmap.h"
#include <math.h>
//-------------------------------------------------------------------------------------------------
CGlyphBitmap::CGlyphBitmap()
: m_iWidth(0)
, m_iHeight(0)
, m_pBuffer(0)
{
}
//-------------------------------------------------------------------------------------------------
CGlyphBitmap::~CGlyphBitmap()
{
Release();
}
//-------------------------------------------------------------------------------------------------
int CGlyphBitmap::Create(int iWidth, int iHeight)
{
Release();
m_pBuffer = new unsigned char[iWidth * iHeight];
if (!m_pBuffer)
{
return 0;
}
m_iWidth = iWidth;
m_iHeight = iHeight;
return 1;
}
//-------------------------------------------------------------------------------------------------
int CGlyphBitmap::Release()
{
if (m_pBuffer)
{
delete[] m_pBuffer;
}
m_pBuffer = 0;
m_iWidth = m_iHeight = 0;
return 1;
}
//-------------------------------------------------------------------------------------------------
int CGlyphBitmap::Blur(int iIterations)
{
int cSum;
int yOffset;
int yupOffset;
int ydownOffset;
for (int i = 0; i < iIterations; i++)
{
for (int y = 0; y < m_iHeight; y++)
{
yOffset = y * m_iWidth;
if (y - 1 >= 0)
{
yupOffset = (y - 1) * m_iWidth;
}
else
{
yupOffset = (y) * m_iWidth;
}
if (y + 1 < m_iHeight)
{
ydownOffset = (y + 1) * m_iWidth;
}
else
{
ydownOffset = (y) * m_iWidth;
}
for (int x = 0; x < m_iWidth; x++)
{
cSum = m_pBuffer[yupOffset + x] + m_pBuffer[ydownOffset + x];
if (x - 1 >= 0)
{
cSum += m_pBuffer[yOffset + x - 1];
}
else
{
cSum += m_pBuffer[yOffset + x];
}
if (x + 1 < m_iWidth)
{
cSum += m_pBuffer[yOffset + x + 1];
}
else
{
cSum += m_pBuffer[yOffset + x];
}
m_pBuffer[yOffset + x] = cSum >> 2;
}
}
}
return 1;
}
//-------------------------------------------------------------------------------------------------
int CGlyphBitmap::Scale(float fScaleX, float fScaleY)
{
int iNewWidth = (int)(m_iWidth * fScaleX);
int iNewHeight = (int)(m_iHeight * fScaleY);
unsigned char* pNewBuffer = new unsigned char[iNewWidth * iNewHeight];
if (!pNewBuffer)
{
return 0;
}
float xFactor = m_iWidth / (float)iNewWidth;
float yFactor = m_iHeight / (float)iNewHeight;
float xFractioned, yFractioned, xFraction, yFraction, oneMinusX, oneMinusY, fR0, fR1;
int xCeil, yCeil, xFloor, yFloor, yNewOffset;
unsigned char c0, c1, c2, c3;
for (int y = 0; y < iNewHeight; ++y)
{
yFractioned = y * yFactor;
yFloor = (int)floor_tpl(yFractioned);
yCeil = yFloor + 1;
if (yCeil >= m_iHeight)
{
yCeil = yFloor;
}
yFraction = yFractioned - yFloor;
oneMinusY = 1.0f - yFraction;
yNewOffset = y * iNewWidth;
for (int x = 0; x < iNewWidth; ++x)
{
xFractioned = x * xFactor;
xFloor = (int)floor_tpl(xFractioned);
xCeil = xFloor + 1;
if (xCeil >= m_iWidth)
{
xCeil = xFloor;
}
xFraction = xFractioned - xFloor;
oneMinusX = 1.0f - xFraction;
c0 = m_pBuffer[yFloor * m_iWidth + xFloor];
c1 = m_pBuffer[yFloor * m_iWidth + xCeil];
c2 = m_pBuffer[yCeil * m_iWidth + xFloor];
c3 = m_pBuffer[yCeil * m_iWidth + xCeil];
fR0 = (oneMinusX * c0 + xFraction * c1);
fR1 = (oneMinusX * c2 + xFraction * c3);
pNewBuffer[yNewOffset + x] = (unsigned char)((oneMinusY * fR0) + (yFraction * fR1));
}
}
m_iWidth = iNewWidth;
m_iHeight = iNewHeight;
delete[] m_pBuffer;
m_pBuffer = pNewBuffer;
return 1;
}
//-------------------------------------------------------------------------------------------------
int CGlyphBitmap::Clear()
{
memset(m_pBuffer, 0, m_iWidth * m_iHeight);
return 1;
}
//-------------------------------------------------------------------------------------------------
int CGlyphBitmap::BlitTo8(unsigned char* pBuffer, int iSrcX, int iSrcY, int iSrcWidth, int iSrcHeight, int iDestX, int iDestY, int iDestWidth)
{
int ySrcOffset, yDestOffset;
for (int y = 0; y < iSrcHeight; y++)
{
ySrcOffset = (iSrcY + y) * m_iWidth;
yDestOffset = (iDestY + y) * iDestWidth;
for (int x = 0; x < iSrcWidth; x++)
{
pBuffer[yDestOffset + iDestX + x] = m_pBuffer[ySrcOffset + iSrcX + x];
}
}
return 1;
}
//-------------------------------------------------------------------------------------------------
int CGlyphBitmap::BlitTo32(unsigned int* pBuffer, int iSrcX, int iSrcY, int iSrcWidth, int iSrcHeight, int iDestX, int iDestY, int iDestWidth)
{
int ySrcOffset, yDestOffset;
char cColor;
for (int y = 0; y < iSrcHeight; y++)
{
ySrcOffset = (iSrcY + y) * m_iWidth;
yDestOffset = (iDestY + y) * iDestWidth;
for (int x = 0; x < iSrcWidth; x++)
{
cColor = m_pBuffer[ySrcOffset + iSrcX + x];
pBuffer[yDestOffset + iDestX + x] = (cColor << 24) | (255 << 16) | (255 << 8) | 255;
}
}
return 1;
}
//-------------------------------------------------------------------------------------------------
int CGlyphBitmap::BlitScaledTo8(unsigned char* pBuffer, [[maybe_unused]] int iSrcX, int iSrcY, int iSrcWidth, int iSrcHeight, int iDestX, [[maybe_unused]] int iDestY, int iDestWidth, int iDestHeight, int iDestBufferWidth)
{
int iNewWidth = (int)iDestWidth;
int iNewHeight = (int)iDestHeight;
unsigned char* pNewBuffer = pBuffer;
float xFactor = iSrcWidth / (float)iNewWidth;
float yFactor = iSrcHeight / (float)iNewHeight;
float xFractioned, yFractioned, xFraction, yFraction, oneMinusX, oneMinusY, fR0, fR1;
int xCeil, yCeil, xFloor, yFloor, yNewOffset;
unsigned char c0, c1, c2, c3;
for (int y = 0; y < iNewHeight; ++y)
{
yFractioned = y * yFactor;
yFloor = (int)floor_tpl(yFractioned);
yCeil = yFloor + 1;
yFraction = yFractioned - yFloor;
oneMinusY = 1.0f - yFraction;
yNewOffset = y * iDestBufferWidth;
yFloor += iSrcY;
yCeil += iSrcY;
if (yCeil >= m_iHeight)
{
yCeil = yFloor;
}
for (int x = 0; x < iNewWidth; ++x)
{
xFractioned = x * xFactor;
xFloor = (int)floor_tpl(xFractioned);
xCeil = xFloor + 1;
xFraction = xFractioned - xFloor;
oneMinusX = 1.0f - xFraction;
xFloor += iSrcY;
xCeil += iSrcY;
if (xCeil >= m_iWidth)
{
xCeil = xFloor;
}
c0 = m_pBuffer[yFloor * m_iWidth + xFloor];
c1 = m_pBuffer[yFloor * m_iWidth + xCeil];
c2 = m_pBuffer[yCeil * m_iWidth + xFloor];
c3 = m_pBuffer[yCeil * m_iWidth + xCeil];
fR0 = (oneMinusX * c0 + xFraction * c1);
fR1 = (oneMinusX * c2 + xFraction * c3);
pNewBuffer[yNewOffset + x + iDestX] = (unsigned char)((oneMinusY * fR0) + (yFraction * fR1));
}
}
return 1;
}
#if defined(__GNUC__)
#if __GNUC__ >= 4 && __GNUC__MINOR__ < 7
#pragma GCC diagnostic ignored "-Woverflow"
#endif
#endif
//-------------------------------------------------------------------------------------------------
int CGlyphBitmap::BlitScaledTo32(unsigned char* pBuffer, [[maybe_unused]] int iSrcX, int iSrcY, int iSrcWidth, int iSrcHeight, int iDestX, [[maybe_unused]] int iDestY, int iDestWidth, int iDestHeight, int iDestBufferWidth)
{
int iNewWidth = (int)iDestWidth;
int iNewHeight = (int)iDestHeight;
unsigned char* pNewBuffer = pBuffer;
float xFactor = iSrcWidth / (float)iNewWidth;
float yFactor = iSrcHeight / (float)iNewHeight;
float xFractioned, yFractioned, xFraction, yFraction, oneMinusX, oneMinusY, fR0, fR1;
int xCeil, yCeil, xFloor, yFloor, yNewOffset;
unsigned char c0, c1, c2, c3, cColor;
for (int y = 0; y < iNewHeight; ++y)
{
yFractioned = y * yFactor;
yFloor = (int)floor_tpl(yFractioned);
yCeil = yFloor + 1;
yFraction = yFractioned - yFloor;
oneMinusY = 1.0f - yFraction;
yNewOffset = y * iDestBufferWidth;
yFloor += iSrcY;
yCeil += iSrcY;
if (yCeil >= m_iHeight)
{
yCeil = yFloor;
}
for (int x = 0; x < iNewWidth; ++x)
{
xFractioned = x * xFactor;
xFloor = (int)floor_tpl(xFractioned);
xCeil = xFloor + 1;
xFraction = xFractioned - xFloor;
oneMinusX = 1.0f - xFraction;
xFloor += iSrcY;
xCeil += iSrcY;
if (xCeil >= m_iWidth)
{
xCeil = xFloor;
}
c0 = m_pBuffer[yFloor * m_iWidth + xFloor];
c1 = m_pBuffer[yFloor * m_iWidth + xCeil];
c2 = m_pBuffer[yCeil * m_iWidth + xFloor];
c3 = m_pBuffer[yCeil * m_iWidth + xCeil];
fR0 = (oneMinusX * c0 + xFraction * c1);
fR1 = (oneMinusX * c2 + xFraction * c3);
cColor = (unsigned char)((oneMinusY * fR0) + (yFraction * fR1));
pNewBuffer[yNewOffset + x + iDestX] = 0xffffff | (cColor << 24);
}
}
return 1;
}
#if defined(__GNUC__)
#if __GNUC__ >= 4 && __GNUC__MINOR__ < 7
#pragma GCC diagnostic error "-Woverflow"
#endif
#endif
//-------------------------------------------------------------------------------------------------
-59
View File
@@ -1,59 +0,0 @@
/*
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
* its licensors.
*
* For complete copyright and license terms please see the LICENSE at the root of this
* distribution (the "License"). All use of this software is governed by the License,
* or, if provided, by the license below or the license accompanying this file. Do not
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
*/
// Original file Copyright Crytek GMBH or its affiliates, used under license.
// Purpose : Hold a glyph bitmap and blit it to the main texture
#ifndef CRYINCLUDE_CRYFONT_GLYPHBITMAP_H
#define CRYINCLUDE_CRYFONT_GLYPHBITMAP_H
#pragma once
class CGlyphBitmap
{
public:
CGlyphBitmap();
~CGlyphBitmap();
int Create(int iWidth, int iHeight);
int Release();
unsigned char* GetBuffer() { return m_pBuffer; };
int Blur(int iIterations);
int Scale(float fScaleX, float fScaleY);
int Clear();
int BlitTo8(unsigned char* pBuffer, int iSrcX, int iSrcY, int iSrcWidth, int iSrcHeight, int iDestX, int iDestY, int iDestWidth);
int BlitTo32(unsigned int* pBuffer, int iSrcX, int iSrcY, int iSrcWidth, int iSrcHeight, int iDestX, int iDestY, int iDestWidth);
int BlitScaledTo8(unsigned char* pBuffer, int iSrcX, int iSrcY, int iSrcWidth, int iSrcHeight, int iDestX, int iDestY, int iDestWidth, int iDestHeight, int iDestBufferWidth);
int BlitScaledTo32(unsigned char* pBuffer, int iSrcX, int iSrcY, int iSrcWidth, int iSrcHeight, int iDestX, int iDestY, int iDestWidth, int iDestHeight, int iDestBufferWidth);
int GetWidth() { return m_iWidth; }
int GetHeight() { return m_iHeight; }
void GetMemoryUsage(ICrySizer* pSizer) const
{
pSizer->AddObject(m_pBuffer, m_iWidth * m_iHeight);
}
private:
unsigned char* m_pBuffer;
int m_iWidth;
int m_iHeight;
};
#endif // CRYINCLUDE_CRYFONT_GLYPHBITMAP_H
-433
View File
@@ -1,433 +0,0 @@
/*
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
* its licensors.
*
* For complete copyright and license terms please see the LICENSE at the root of this
* distribution (the "License"). All use of this software is governed by the License,
* or, if provided, by the license below or the license accompanying this file. Do not
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
*/
// Original file Copyright Crytek GMBH or its affiliates, used under license.
// Purpose:
// - Manage and cache glyphs, retrieving them from the renderer as needed
#include "CryFont_precompiled.h"
#if !defined(USE_NULLFONT_ALWAYS)
#include "GlyphCache.h"
#include "FontTexture.h"
//-------------------------------------------------------------------------------------------------
CGlyphCache::CGlyphCache()
: m_dwUsage(1)
, m_iGlyphBitmapWidth(0)
, m_iGlyphBitmapHeight(0)
, m_pScaleBitmap(0)
{
m_pCacheTable.clear();
m_pSlotList.clear();
}
//-------------------------------------------------------------------------------------------------
CGlyphCache::~CGlyphCache()
{
}
//-------------------------------------------------------------------------------------------------
int CGlyphCache::Create(int iCacheSize, int iGlyphBitmapWidth, int iGlyphBitmapHeight, int iSmoothMethod, int iSmoothAmount, float sizeRatio)
{
m_iSmoothMethod = iSmoothMethod;
m_iSmoothAmount = iSmoothAmount;
m_iGlyphBitmapWidth = iGlyphBitmapWidth;
m_iGlyphBitmapHeight = iGlyphBitmapHeight;
if (!CreateSlotList(iCacheSize))
{
ReleaseSlotList();
return 0;
}
int iScaledGlyphWidth = 0;
int iScaledGlyphHeight = 0;
switch (m_iSmoothMethod)
{
case FONT_SMOOTH_SUPERSAMPLE:
{
switch (m_iSmoothAmount)
{
case FONT_SMOOTH_AMOUNT_2X:
iScaledGlyphWidth = m_iGlyphBitmapWidth << 1;
iScaledGlyphHeight = m_iGlyphBitmapHeight << 1;
break;
case FONT_SMOOTH_AMOUNT_4X:
iScaledGlyphWidth = m_iGlyphBitmapWidth << 2;
iScaledGlyphHeight = m_iGlyphBitmapHeight << 2;
break;
}
}
break;
}
if (iScaledGlyphWidth)
{
m_pScaleBitmap = new CGlyphBitmap;
if (!m_pScaleBitmap)
{
Release();
return 0;
}
if (!m_pScaleBitmap->Create(iScaledGlyphWidth, iScaledGlyphHeight))
{
Release();
return 0;
}
m_pFontRenderer.SetGlyphBitmapSize(iScaledGlyphWidth, iScaledGlyphHeight, sizeRatio);
}
else
{
m_pFontRenderer.SetGlyphBitmapSize(m_iGlyphBitmapWidth, m_iGlyphBitmapHeight, sizeRatio);
}
return 1;
}
//-------------------------------------------------------------------------------------------------
int CGlyphCache::Release()
{
ReleaseSlotList();
m_pCacheTable.clear();
if (m_pScaleBitmap)
{
m_pScaleBitmap->Release();
delete m_pScaleBitmap;
m_pScaleBitmap = 0;
}
m_iGlyphBitmapWidth = 0;
m_iGlyphBitmapHeight = 0;
return 1;
}
//-------------------------------------------------------------------------------------------------
int CGlyphCache::LoadFontFromFile(const string& szFileName)
{
return m_pFontRenderer.LoadFromFile(szFileName);
}
//-------------------------------------------------------------------------------------------------
int CGlyphCache::LoadFontFromMemory(unsigned char* pFileBuffer, int iDataSize)
{
return m_pFontRenderer.LoadFromMemory(pFileBuffer, iDataSize);
}
//-------------------------------------------------------------------------------------------------
int CGlyphCache::ReleaseFont()
{
m_pFontRenderer.Release();
return 1;
}
//-------------------------------------------------------------------------------------------------
int CGlyphCache::GetGlyphBitmapSize(int* pWidth, int* pHeight)
{
if (pWidth)
{
*pWidth = m_iGlyphBitmapWidth;
}
if (pHeight)
{
*pHeight = m_iGlyphBitmapWidth;
}
return 1;
}
//-------------------------------------------------------------------------------------------------
void CGlyphCache::SetGlyphBitmapSize(int width, int height, float sizeRatio)
{
m_pFontRenderer.SetGlyphBitmapSize(width, height, sizeRatio);
}
//-------------------------------------------------------------------------------------------------
int CGlyphCache::PreCacheGlyph(uint32 cChar, const Vec2i& glyphSize, const CFFont::FontHintParams& fontHintParams)
{
CCacheTable::iterator pItor = m_pCacheTable.find(GetCacheSlotKey(cChar, glyphSize));
if (pItor != m_pCacheTable.end())
{
pItor->second->dwUsage = m_dwUsage;
return 1;
}
CCacheSlot* pSlot = GetLRUSlot();
if (!pSlot)
{
return 0;
}
if (pSlot->dwUsage > 0)
{
UnCacheGlyph(pSlot->cCurrentChar, pSlot->glyphSize);
}
if (m_pScaleBitmap)
{
int iOffsetMult = 1;
switch (m_iSmoothAmount)
{
case FONT_SMOOTH_AMOUNT_2X:
iOffsetMult = 2;
break;
case FONT_SMOOTH_AMOUNT_4X:
iOffsetMult = 4;
break;
}
m_pScaleBitmap->Clear();
if (!m_pFontRenderer.GetGlyph(m_pScaleBitmap, &pSlot->iHoriAdvance, &pSlot->iCharWidth, &pSlot->iCharHeight, pSlot->iCharOffsetX, pSlot->iCharOffsetY, 0, 0, cChar, fontHintParams))
{
return 0;
}
pSlot->iCharWidth >>= iOffsetMult >> 1;
pSlot->iCharHeight >>= iOffsetMult >> 1;
m_pScaleBitmap->BlitScaledTo8(pSlot->pGlyphBitmap.GetBuffer(), 0, 0, m_pScaleBitmap->GetWidth(), m_pScaleBitmap->GetHeight(), 0, 0, pSlot->pGlyphBitmap.GetWidth(), pSlot->pGlyphBitmap.GetHeight(), pSlot->pGlyphBitmap.GetWidth());
}
else
{
if (!m_pFontRenderer.GetGlyph(&pSlot->pGlyphBitmap, &pSlot->iHoriAdvance, &pSlot->iCharWidth, &pSlot->iCharHeight, pSlot->iCharOffsetX, pSlot->iCharOffsetY, 0, 0, cChar, fontHintParams))
{
return 0;
}
}
if (m_iSmoothMethod == FONT_SMOOTH_BLUR)
{
pSlot->pGlyphBitmap.Blur(m_iSmoothAmount);
}
pSlot->dwUsage = m_dwUsage;
pSlot->cCurrentChar = cChar;
pSlot->glyphSize = glyphSize;
m_pCacheTable.insert(AZStd::pair<CryFont::GlyphCache::CCacheTableKey, CCacheSlot*>(GetCacheSlotKey(cChar, glyphSize), pSlot));
return 1;
}
int CGlyphCache::UnCacheGlyph(uint32 cChar, const Vec2i& glyphSize)
{
CCacheTable::iterator pItor = m_pCacheTable.find(GetCacheSlotKey(cChar, glyphSize));
if (pItor != m_pCacheTable.end())
{
CCacheSlot* pSlot = pItor->second;
pSlot->Reset();
m_pCacheTable.erase(pItor);
return 1;
}
return 0;
}
//-------------------------------------------------------------------------------------------------
int CGlyphCache::GlyphCached(uint32 cChar, const Vec2i& glyphSize)
{
return (m_pCacheTable.find(GetCacheSlotKey(cChar, glyphSize)) != m_pCacheTable.end());
}
//-------------------------------------------------------------------------------------------------
CCacheSlot* CGlyphCache::GetLRUSlot()
{
unsigned int dwMinUsage = 0xffffffff;
CCacheSlot* pLRUSlot = 0;
CCacheSlot* pSlot;
CCacheSlotListItor pItor = m_pSlotList.begin();
while (pItor != m_pSlotList.end())
{
pSlot = *pItor;
if (pSlot->dwUsage == 0)
{
return pSlot;
}
else
{
if (pSlot->dwUsage < dwMinUsage)
{
pLRUSlot = pSlot;
dwMinUsage = pSlot->dwUsage;
}
}
pItor++;
}
return pLRUSlot;
}
//-------------------------------------------------------------------------------------------------
CCacheSlot* CGlyphCache::GetMRUSlot()
{
unsigned int dwMaxUsage = 0;
CCacheSlot* pMRUSlot = 0;
CCacheSlot* pSlot;
CCacheSlotListItor pItor = m_pSlotList.begin();
while (pItor != m_pSlotList.end())
{
pSlot = *pItor;
if (pSlot->dwUsage != 0)
{
if (pSlot->dwUsage > dwMaxUsage)
{
pMRUSlot = pSlot;
dwMaxUsage = pSlot->dwUsage;
}
}
pItor++;
}
return pMRUSlot;
}
//-------------------------------------------------------------------------------------------------
int CGlyphCache::GetGlyph(CGlyphBitmap** pGlyph, int* piHoriAdvance, int* piWidth, int* piHeight, AZ::s32& iCharOffsetX, AZ::s32& iCharOffsetY, uint32 cChar, const Vec2i& glyphSize, const CFFont::FontHintParams& fontHintParams)
{
CCacheTable::iterator pItor = m_pCacheTable.find(GetCacheSlotKey(cChar, glyphSize));
if (pItor == m_pCacheTable.end())
{
if (!PreCacheGlyph(cChar, glyphSize, fontHintParams))
{
return 0;
}
}
pItor = m_pCacheTable.find(GetCacheSlotKey(cChar, glyphSize));
pItor->second->dwUsage = m_dwUsage++;
(*pGlyph) = &pItor->second->pGlyphBitmap;
if (piHoriAdvance)
{
*piHoriAdvance = pItor->second->iHoriAdvance;
}
if (piWidth)
{
*piWidth = pItor->second->iCharWidth;
}
if (piHeight)
{
*piHeight = pItor->second->iCharHeight;
}
iCharOffsetX = pItor->second->iCharOffsetX;
iCharOffsetY = pItor->second->iCharOffsetY;
return 1;
}
//-------------------------------------------------------------------------------------------------
Vec2 CGlyphCache::GetKerning(uint32_t leftGlyph, uint32_t rightGlyph)
{
return m_pFontRenderer.GetKerning(leftGlyph, rightGlyph);
}
//-------------------------------------------------------------------------------------------------
float CGlyphCache::GetAscenderToHeightRatio()
{
return m_pFontRenderer.GetAscenderToHeightRatio();
}
//-------------------------------------------------------------------------------------------------
int CGlyphCache::CreateSlotList(int iListSize)
{
for (int i = 0; i < iListSize; i++)
{
CCacheSlot* pCacheSlot = new CCacheSlot;
if (!pCacheSlot)
{
return 0;
}
if (!pCacheSlot->pGlyphBitmap.Create(m_iGlyphBitmapWidth, m_iGlyphBitmapHeight))
{
delete pCacheSlot;
return 0;
}
pCacheSlot->Reset();
pCacheSlot->iCacheSlot = i;
m_pSlotList.push_back(pCacheSlot);
}
return 1;
}
//-------------------------------------------------------------------------------------------------
int CGlyphCache::ReleaseSlotList()
{
CCacheSlotListItor pItor = m_pSlotList.begin();
while (pItor != m_pSlotList.end())
{
(*pItor)->pGlyphBitmap.Release();
delete (*pItor);
pItor = m_pSlotList.erase(pItor);
}
return 1;
}
//-------------------------------------------------------------------------------------------------
CryFont::GlyphCache::CCacheTableKey CGlyphCache::GetCacheSlotKey(uint32 cChar, const Vec2i& glyphSize) const
{
const Vec2i clampedGlyphSize = CFontTexture::ClampGlyphSize(glyphSize, m_iGlyphBitmapWidth, m_iGlyphBitmapHeight);
return CryFont::GlyphCache::CCacheTableKey(clampedGlyphSize, cChar);
}
#endif // #if !defined(USE_NULLFONT_ALWAYS)
-200
View File
@@ -1,200 +0,0 @@
/*
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
* its licensors.
*
* For complete copyright and license terms please see the LICENSE at the root of this
* distribution (the "License"). All use of this software is governed by the License,
* or, if provided, by the license below or the license accompanying this file. Do not
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
*/
// Original file Copyright Crytek GMBH or its affiliates, used under license.
// Purpose:
// - Manage and cache glyphs, retrieving them from the renderer as needed
#ifndef CRYINCLUDE_CRYFONT_GLYPHCACHE_H
#define CRYINCLUDE_CRYFONT_GLYPHCACHE_H
#pragma once
#if !defined(USE_NULLFONT_ALWAYS)
#include <vector>
#include "GlyphBitmap.h"
#include "FontRenderer.h"
#include "CryFont.h"
#include <StlUtils.h>
//! Glyph cache slots store the bitmap buffer and glyph metadata from FreeType.
//!
//! This bitmap buffer is eventually copied to a CFontTexture texture buffer.
//! A glyph cache slot bitmap buffer only holds a single glyph, whereas the
//! CFontTexture stores multiple glyphs in a grid (row/col) format.
typedef struct CCacheSlot
{
Vec2i glyphSize = CCryFont::defaultGlyphSize; //!< The render resolution of the glyph in the glyph bitmap
unsigned int dwUsage;
int iCacheSlot;
int iHoriAdvance; //!< Advance width. See FT_Glyph_Metrics::horiAdvance.
uint32 cCurrentChar;
uint8 iCharWidth; //!< Glyph width (in pixel)
uint8 iCharHeight; //!< Glyph height (in pixel)
AZ::s32 iCharOffsetX; //!< Glyph's left-side bearing (in pixels). See FT_GlyphSlotRec::bitmap_left.
AZ::s32 iCharOffsetY; //!< Glyph's top bearing (in pixels). See FT_GlyphSlotRec::bitmap_top.
CGlyphBitmap pGlyphBitmap; //!< Contains a buffer storing a copy of the glyph from FreeType
void Reset()
{
dwUsage = 0;
cCurrentChar = ~0;
iCharWidth = 0;
iCharHeight = 0;
iCharOffsetX = 0;
iCharOffsetY = 0;
pGlyphBitmap.Clear();
}
void GetMemoryUsage(ICrySizer* pSizer) const
{
pSizer->AddObject(this, sizeof(*this));
pSizer->AddObject(pGlyphBitmap);
}
} CCacheSlot;
namespace CryFont
{
namespace GlyphCache
{
//! Height and width pair for glyph size mapping
typedef Vec2i CCacheTableGlyphSizeType;
//! Pair for mapping a height and width size to a UTF32 character/glyph
typedef AZStd::pair<CCacheTableGlyphSizeType, uint32> CCacheTableKey;
//! Hasher for glyph cache table keys (glyphsize-char code pair)
//!
//! Instead of creating our own custom hash, the types are broken down to their
//! native types (ints) and passed to existing hashes that handle those types.
struct HashGlyphCacheTableKey
{
typedef CCacheTableKey ArgumentType;
typedef AZStd::size_t ResultType;
typedef AZStd::pair<int32, int32> Int32Pair;
typedef AZStd::pair<Int32Pair, uint32> Int32PairU32Pair;
ResultType operator()(const ArgumentType& value) const
{
AZStd::hash<Int32PairU32Pair> pairHash;
return pairHash(Int32PairU32Pair(Int32Pair(value.first.x, value.first.y), value.second));
}
};
}
}
//! Maps size-speicifc UTF32 glyphs to their corresponding cache slots
typedef AZStd::unordered_map<CryFont::GlyphCache::CCacheTableKey, CCacheSlot*, CryFont::GlyphCache::HashGlyphCacheTableKey> CCacheTable;
typedef std::vector<CCacheSlot*> CCacheSlotList;
typedef std::vector<CCacheSlot*>::iterator CCacheSlotListItor;
#ifdef WIN64
#undef GetCharWidth
#undef GetCharHeight
#endif
//! The glyph cache maps UTF32 codepoints to their corresponding FreeType data.
//!
//! This cache is used to associate font glyph info (read from FreeType) with
//! UTF32 codepoints. Ultimately the glyph info will be read into a font texture
//! (CFontTexture) to avoid future FreeType lookups.
//!
//! If a CFontTexture is missing a glyph that is currently stored in the glyph
//! cache, the cached data can be returned instead of having to be rendered from
//! FreeType again.
//!
//! \sa CFontTexture
class CGlyphCache
{
public:
CGlyphCache();
~CGlyphCache();
int Create(int iCacheSize, int iGlyphBitmapWidth, int iGlyphBitmapHeight, int iSmoothMethod, int iSmoothAmount, float sizeRatio);
int Release();
int LoadFontFromFile(const string& szFileName);
int LoadFontFromMemory(unsigned char* pFileBuffer, int iDataSize);
int ReleaseFont();
int SetEncoding(FT_Encoding pEncoding) { return m_pFontRenderer.SetEncoding(pEncoding); };
FT_Encoding GetEncoding() { return m_pFontRenderer.GetEncoding(); };
int GetGlyphBitmapSize(int* pWidth, int* pHeight);
void SetGlyphBitmapSize(int width, int height, float sizeRatio);
int PreCacheGlyph(uint32 cChar, const Vec2i& glyphSize = CCryFont::defaultGlyphSize, const CFFont::FontHintParams& glyphFlags = CFFont::FontHintParams());
int UnCacheGlyph(uint32 cChar, const Vec2i& glyphSize = CCryFont::defaultGlyphSize);
int GlyphCached(uint32 cChar, const Vec2i& glyphSize = CCryFont::defaultGlyphSize);
CCacheSlot* GetLRUSlot();
CCacheSlot* GetMRUSlot();
//! Obtains glyph information for the given UTF32 codepoint.
//! This information is obtained from a CCacheSlot that corresponds to
//! the given codepoint. If the codepoint doesn't exist within the cache
//! table (m_pCacheTable), then the information is obtain from FreeType
//! directly via CFontRenderer.
//!
//! Ultimately the glyph bitmap is copied into a font texture
//! (CFontTexture). Once the glyph is copied into the font texture then
//! the font texture is referenced directly rather than relying on the
//! glyph cache or FreeType.
//!
//! \sa CFontRenderer::GetGlyph, CFontTexture::UpdateSlot
int GetGlyph(CGlyphBitmap** pGlyph, int* piHoriAdvance, int* piWidth, int* piHeight, AZ::s32& iCharOffsetX, AZ::s32& iCharOffsetY, uint32 cChar, const Vec2i& glyphSize = CCryFont::defaultGlyphSize, const CFFont::FontHintParams& glyphFlags = CFFont::FontHintParams());
void GetMemoryUsage(ICrySizer* pSizer) const
{
pSizer->AddObject(m_pSlotList);
//pSizer->AddContainer(m_pCacheTable);
pSizer->AddObject(m_pScaleBitmap);
pSizer->AddObject(m_pFontRenderer);
}
bool GetMonospaced() const { return m_pFontRenderer.GetMonospaced(); }
Vec2 GetKerning(uint32_t leftGlyph, uint32_t rightGlyph);
float GetAscenderToHeightRatio();
private:
//! Returns a key for the cache table where the given char is mapped at the given size.
CryFont::GlyphCache::CCacheTableKey GetCacheSlotKey(uint32 cChar, const Vec2i& glyphSize = CCryFont::defaultGlyphSize) const;
int CreateSlotList(int iListSize);
int ReleaseSlotList();
CCacheSlotList m_pSlotList;
CCacheTable m_pCacheTable;
int m_iGlyphBitmapWidth;
int m_iGlyphBitmapHeight;
int m_iSmoothMethod;
int m_iSmoothAmount;
CGlyphBitmap* m_pScaleBitmap;
CFontRenderer m_pFontRenderer;
unsigned int m_dwUsage;
};
#endif // #if !defined(USE_NULLFONT_ALWAYS)
#endif // CRYINCLUDE_CRYFONT_GLYPHCACHE_H
-104
View File
@@ -1,104 +0,0 @@
/*
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
* its licensors.
*
* For complete copyright and license terms please see the LICENSE at the root of this
* distribution (the "License"). All use of this software is governed by the License,
* or, if provided, by the license below or the license accompanying this file. Do not
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
*/
// Original file Copyright Crytek GMBH or its affiliates, used under license.
// Description : Create the font interface.
#include "CryFont_precompiled.h"
#include <IEngineModule.h>
#include <CryExtension/ICryFactory.h>
#include <CryExtension/Impl/ClassWeaver.h>
#include "CryFont.h"
#if defined(USE_NULLFONT)
#include "NullFont.h"
#endif
//////////////////////////////////////////////////////////////////////////
struct CSystemEventListner_Font
: public ISystemEventListener
{
public:
virtual void OnSystemEvent(ESystemEvent event, [[maybe_unused]] UINT_PTR wparam, [[maybe_unused]] UINT_PTR lparam)
{
switch (event)
{
case ESYSTEM_EVENT_LEVEL_POST_UNLOAD:
{
STLALLOCATOR_CLEANUP;
break;
}
}
}
};
static CSystemEventListner_Font g_system_event_listener_font;
///////////////////////////////////////////////
extern "C" ICryFont * CreateCryFontInterface(ISystem * pSystem)
{
ModuleInitISystem(pSystem, "CryFont");
if (gEnv->IsDedicated())
{
#if defined(USE_NULLFONT)
return new CCryNullFont();
#else
// The NULL font implementation must be present for all platforms
// supporting running as a pure dedicated server.
pSystem->GetILog()->LogError("Missing NULL font implementation for dedicated server");
return NULL;
#endif
}
else
{
#if defined(USE_NULLFONT) && defined(USE_NULLFONT_ALWAYS)
return new CCryNullFont();
#else
pSystem->GetISystemEventDispatcher()->RegisterListener(&g_system_event_listener_font);
return new CCryFont(pSystem);
#endif
}
}
//////////////////////////////////////////////////////////////////////////
class CEngineModule_CryFont
: public IEngineModule
{
CRYINTERFACE_SIMPLE(IEngineModule)
CRYGENERATE_SINGLETONCLASS(CEngineModule_CryFont, "EngineModule_CryFont", 0x6758643f43214957, 0x9b920d898d31f434)
//////////////////////////////////////////////////////////////////////////
virtual const char* GetName() const {
return "CryFont";
};
virtual const char* GetCategory() const { return "CryEngine"; };
//////////////////////////////////////////////////////////////////////////
virtual bool Initialize(SSystemGlobalEnvironment& env, [[maybe_unused]] const SSystemInitParams& initParams)
{
ISystem* pSystem = env.pSystem;
env.pCryFont = CreateCryFontInterface(pSystem);
return env.pCryFont != 0;
}
};
CRYREGISTER_SINGLETON_CLASS(CEngineModule_CryFont)
CEngineModule_CryFont::CEngineModule_CryFont()
{
};
CEngineModule_CryFont::~CEngineModule_CryFont()
{
};
-24
View File
@@ -1,24 +0,0 @@
/*
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
* its licensors.
*
* For complete copyright and license terms please see the LICENSE at the root of this
* distribution (the "License"). All use of this software is governed by the License,
* or, if provided, by the license below or the license accompanying this file. Do not
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
*/
// Original file Copyright Crytek GMBH or its affiliates, used under license.
// Description : Dummy font implementation (dedicated server)
#include "CryFont_precompiled.h"
#if defined(USE_NULLFONT)
#include "NullFont.h"
CNullFont CCryNullFont::ms_nullFont;
#endif // USE_NULLFONT
-98
View File
@@ -1,98 +0,0 @@
/*
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
* its licensors.
*
* For complete copyright and license terms please see the LICENSE at the root of this
* distribution (the "License"). All use of this software is governed by the License,
* or, if provided, by the license below or the license accompanying this file. Do not
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
*/
// Original file Copyright Crytek GMBH or its affiliates, used under license.
// Description : Dummy font implementation (dedicated server)
#ifndef CRYINCLUDE_CRYFONT_NULLFONT_H
#define CRYINCLUDE_CRYFONT_NULLFONT_H
#pragma once
#if defined(USE_NULLFONT)
#include <IFont.h>
class CNullFont
: public IFFont
{
public:
CNullFont() {}
virtual ~CNullFont() {}
virtual int32 AddRef() { return 0; };
virtual int32 Release() { return 0; };
virtual bool Load([[maybe_unused]] const char* pFontFilePath, [[maybe_unused]] unsigned int width, [[maybe_unused]] unsigned int height, [[maybe_unused]] unsigned int widthNumSlots, [[maybe_unused]] unsigned int heightNumSlots, [[maybe_unused]] unsigned int flags, [[maybe_unused]] float sizeRatio) { return true; }
virtual bool Load([[maybe_unused]] const char* pXMLFile) { return true; }
virtual void Free() {}
virtual void DrawString([[maybe_unused]] float x, [[maybe_unused]] float y, [[maybe_unused]] const char* pStr, [[maybe_unused]] const bool asciiMultiLine, [[maybe_unused]] const STextDrawContext& ctx) {}
virtual void DrawString([[maybe_unused]] float x, [[maybe_unused]] float y, [[maybe_unused]] float z, [[maybe_unused]] const char* pStr, [[maybe_unused]] const bool asciiMultiLine, [[maybe_unused]] const STextDrawContext& ctx) {}
virtual void DrawStringW([[maybe_unused]] float x, [[maybe_unused]] float y, [[maybe_unused]] const wchar_t* pStr, [[maybe_unused]] const bool asciiMultiLine, [[maybe_unused]] const STextDrawContext& ctx) {}
virtual void DrawStringW([[maybe_unused]] float x, [[maybe_unused]] float y, [[maybe_unused]] float z, [[maybe_unused]] const wchar_t* pStr, [[maybe_unused]] const bool asciiMultiLine, [[maybe_unused]] const STextDrawContext& ctx) {}
virtual Vec2 GetTextSize([[maybe_unused]] const char* pStr, [[maybe_unused]] const bool asciiMultiLine, [[maybe_unused]] const STextDrawContext& ctx) { return Vec2(0.0f, 0.0f); }
virtual Vec2 GetTextSizeW([[maybe_unused]] const wchar_t* pStr, [[maybe_unused]] const bool asciiMultiLine, [[maybe_unused]] const STextDrawContext& ctx) { return Vec2(0.0f, 0.0f); }
virtual size_t GetTextLength([[maybe_unused]] const char* pStr, [[maybe_unused]] const bool asciiMultiLine) const { return 0; }
virtual size_t GetTextLengthW([[maybe_unused]] const wchar_t* pStr, [[maybe_unused]] const bool asciiMultiLine) const { return 0; }
virtual void WrapText(string& result, [[maybe_unused]] float maxWidth, const char* pStr, [[maybe_unused]] const STextDrawContext& ctx) { result = pStr; }
virtual void WrapTextW(wstring& result, [[maybe_unused]] float maxWidth, const wchar_t* pStr, [[maybe_unused]] const STextDrawContext& ctx) { result = pStr; }
virtual void GetMemoryUsage([[maybe_unused]] ICrySizer* pSizer) const {}
virtual void GetGradientTextureCoord([[maybe_unused]] float& minU, [[maybe_unused]] float& minV, [[maybe_unused]] float& maxU, [[maybe_unused]] float& maxV) const {}
virtual unsigned int GetEffectId([[maybe_unused]] const char* pEffectName) const { return 0; }
virtual unsigned int GetNumEffects() const { return 0; }
virtual const char* GetEffectName([[maybe_unused]] unsigned int effectId) const { return nullptr; }
virtual Vec2 GetMaxEffectOffset([[maybe_unused]] unsigned int effectId) const { return Vec2(); }
virtual bool DoesEffectHaveTransparency([[maybe_unused]] unsigned int effectId) const { return false; }
virtual void AddCharsToFontTexture([[maybe_unused]] const char* pChars, [[maybe_unused]] int glyphSizeX, [[maybe_unused]] int glyphSizeY) override {}
virtual Vec2 GetKerning([[maybe_unused]] uint32_t leftGlyph, [[maybe_unused]] uint32_t rightGlyph, [[maybe_unused]] const STextDrawContext& ctx) const override { return Vec2(); }
virtual float GetAscender([[maybe_unused]] const STextDrawContext& ctx) const override { return 0.0f; }
virtual float GetBaseline([[maybe_unused]] const STextDrawContext& ctx) const override { return 0.0f; }
virtual float GetSizeRatio() const override { return IFFontConstants::defaultSizeRatio; }
virtual uint32 GetNumQuadsForText([[maybe_unused]] const char* pStr, [[maybe_unused]] const bool asciiMultiLine, [[maybe_unused]] const STextDrawContext& ctx) { return 0; }
virtual uint32 WriteTextQuadsToBuffers([[maybe_unused]] SVF_P2F_C4B_T2F_F4B* verts, [[maybe_unused]] uint16* indices, [[maybe_unused]] uint32 maxQuads, [[maybe_unused]] float x, [[maybe_unused]] float y, [[maybe_unused]] float z, [[maybe_unused]] const char* pStr, [[maybe_unused]] const bool asciiMultiLine, [[maybe_unused]] const STextDrawContext& ctx) { return 0; }
virtual int GetFontTextureId() { return -1; }
virtual uint32 GetFontTextureVersion() { return 0; }
};
class CCryNullFont
: public ICryFont
{
public:
virtual void Release() {}
virtual IFFont* NewFont([[maybe_unused]] const char* pFontName) { return &ms_nullFont; }
virtual IFFont* GetFont([[maybe_unused]] const char* pFontName) const { return &ms_nullFont; }
virtual FontFamilyPtr LoadFontFamily([[maybe_unused]] const char* pFontFamilyName) override { CRY_ASSERT(false); return nullptr; }
virtual FontFamilyPtr GetFontFamily([[maybe_unused]] const char* pFontFamilyName) override { CRY_ASSERT(false); return nullptr; }
virtual void AddCharsToFontTextures(FontFamilyPtr pFontFamily, [[maybe_unused]] const char* pChars, [[maybe_unused]] int glyphSizeX, [[maybe_unused]] int glyphSizeY) override {};
virtual void SetRendererProperties([[maybe_unused]] IRenderer* pRenderer) {}
virtual void GetMemoryUsage([[maybe_unused]] ICrySizer* pSizer) const {}
virtual string GetLoadedFontNames() const { return ""; }
virtual void OnLanguageChanged() override { }
virtual void ReloadAllFonts() override { }
private:
static CNullFont ms_nullFont;
};
#endif // USE_NULLFONT
#endif // CRYINCLUDE_CRYFONT_NULLFONT_H
@@ -1,16 +0,0 @@
#
# All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
# its licensors.
#
# For complete copyright and license terms please see the LICENSE at the root of this
# distribution (the "License"). All use of this software is governed by the License,
# or, if provided, by the license below or the license accompanying this file. Do not
# remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
#
# Platform specific cmake file for configuring target compiler/link properties
# based on the active platform
# NOTE: functions in cmake are global, therefore adding functions to this file
# is being avoided to prevent overriding functions declared in other targets platfrom
# specific cmake files
@@ -1,33 +0,0 @@
#
# All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
# its licensors.
#
# For complete copyright and license terms please see the LICENSE at the root of this
# distribution (the "License"). All use of this software is governed by the License,
# or, if provided, by the license below or the license accompanying this file. Do not
# remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
#
set(FILES
CryFont.cpp
FFont.cpp
FFontXML.cpp
FontRenderer.cpp
FontTexture.cpp
GlyphBitmap.cpp
GlyphCache.cpp
ICryFont.cpp
NullFont.cpp
CryFont.h
FBitmap.h
FFont.h
FontRenderer.h
FontTexture.h
GlyphBitmap.h
GlyphCache.h
NullFont.h
resource.h
CryFont_precompiled.h
CryFont_precompiled.cpp
)
-25
View File
@@ -1,25 +0,0 @@
/*
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
* its licensors.
*
* For complete copyright and license terms please see the LICENSE at the root of this
* distribution (the "License"). All use of this software is governed by the License,
* or, if provided, by the license below or the license accompanying this file. Do not
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
*/
// Original file Copyright Crytek GMBH or its affiliates, used under license.
#define VS_VERSION_INFO 1
// Next default values for new objects
//
#ifdef APSTUDIO_INVOKED
#ifndef APSTUDIO_READONLY_SYMBOLS
#define _APS_NEXT_RESOURCE_VALUE 101
#define _APS_NEXT_COMMAND_VALUE 40001
#define _APS_NEXT_CONTROL_VALUE 1001
#define _APS_NEXT_SYMED_VALUE 101
#endif
#endif
-2
View File
@@ -90,8 +90,6 @@ ly_add_target(
AZ::AzCore
Legacy::CryCommon
Legacy::CryCommon.EngineSettings.Static
RUNTIME_DEPENDENCIES
Legacy::CryFont
)
################################################################################
-9
View File
@@ -676,17 +676,11 @@ private:
//! @name Initialization routines
//@{
bool InitConsole();
bool InitRenderer(WIN_HINSTANCE hinst, WIN_HWND hwnd, const SSystemInitParams& initParams);
bool InitFont(const SSystemInitParams& initParams);
bool InitFileSystem();
bool InitFileSystem_LoadEngineFolders(const SSystemInitParams& initParams);
bool InitStreamEngine();
bool Init3DEngine(const SSystemInitParams& initParams);
bool InitAudioSystem(const SSystemInitParams& initParams);
bool InitShine(const SSystemInitParams& initParams);
bool OpenRenderLibrary(int type, const SSystemInitParams& initParams);
bool OpenRenderLibrary(const char* t_rend, const SSystemInitParams& initParams);
//@}
@@ -738,9 +732,6 @@ private:
bool GetWinGameFolder(char* szMyDocumentsPath, int maxPathSize);
#endif
//! \brief Initializes the given IFFont member variable with the given name (internal use only).
bool LoadFontInternal(IFFont*& font, const string& fontName);
public:
void EnableFloatExceptions(int type);
+1 -465
View File
@@ -43,8 +43,6 @@
#include <StringUtils.h>
#include <IThreadManager.h>
#include "CryFontBus.h"
#include <AzFramework/Input/Devices/Mouse/InputDeviceMouse.h>
#include <AzFramework/IO/LocalFileIO.h>
@@ -247,24 +245,6 @@ CUNIXConsole* pUnixConsole;
#define LOCALIZATION_TRANSLATIONS_LIST_FILE_NAME "Libs/Localization/localization.xml"
#define LOAD_LEGACY_RENDERER_FOR_EDITOR false // If you set this to true you must also set 'ed_useAtomNativeViewport' to false (see /Code/Sandbox/Editor/ViewManager.cpp)
#define LOAD_LEGACY_RENDERER_FOR_LAUNCHER false
//////////////////////////////////////////////////////////////////////////
// Where possible, these are defaults used to initialize cvars
// System.cfg can then be used to override them
// This includes the Game DLL, although it is loaded elsewhere
#define DLL_FONT "CryFont"
#define DLL_3DENGINE "Cry3DEngine"
#define DLL_RENDERER_DX9 "CryRenderD3D9"
#define DLL_RENDERER_DX11 "CryRenderD3D11"
#define DLL_RENDERER_DX12 "CryRenderD3D12"
#define DLL_RENDERER_METAL "CryRenderMetal"
#define DLL_RENDERER_GL "CryRenderGL"
#define DLL_RENDERER_NULL "CryRenderNULL"
#define DLL_SHINE "LyShine"
//////////////////////////////////////////////////////////////////////////
#if defined(WIN32) || defined(LINUX) || defined(APPLE)
# define DLL_MODULE_INIT_ISYSTEM "ModuleInitISystem"
@@ -1079,58 +1059,6 @@ void CSystem::ShutdownModuleLibraries()
#endif // !defined(AZ_MONOLITHIC_BUILD)
}
//////////////////////////////////////////////////////////////////////////
bool CSystem::OpenRenderLibrary([[maybe_unused]] const char* t_rend, const SSystemInitParams& initParams)
{
LOADING_TIME_PROFILE_SECTION(GetISystem());
#if defined(AZ_RESTRICTED_PLATFORM)
#define AZ_RESTRICTED_SECTION SYSTEMINIT_CPP_SECTION_6
#include AZ_RESTRICTED_FILE(SystemInit_cpp)
#endif
#if defined(AZ_RESTRICTED_SECTION_IMPLEMENTED)
#undef AZ_RESTRICTED_SECTION_IMPLEMENTED
#else
if (gEnv->IsDedicated())
{
return OpenRenderLibrary(R_NULL_RENDERER, initParams);
}
if (AZ::Interface<AzFramework::AtomActiveInterface>::Get())
{
return OpenRenderLibrary(R_DX11_RENDERER, initParams);
}
else if (azstricmp(t_rend, "DX9") == 0)
{
return OpenRenderLibrary(R_DX9_RENDERER, initParams);
}
else if (azstricmp(t_rend, "DX11") == 0)
{
return OpenRenderLibrary(R_DX11_RENDERER, initParams);
}
else if (azstricmp(t_rend, "DX12") == 0)
{
return OpenRenderLibrary(R_DX12_RENDERER, initParams);
}
else if (azstricmp(t_rend, "GL") == 0)
{
return OpenRenderLibrary(R_GL_RENDERER, initParams);
}
else if (azstricmp(t_rend, "METAL") == 0)
{
return OpenRenderLibrary(R_METAL_RENDERER, initParams);
}
else if (azstricmp(t_rend, "NULL") == 0)
{
return OpenRenderLibrary(R_NULL_RENDERER, initParams);
}
AZ_Assert(false, "Unknown renderer type: %s", t_rend);
return false;
#endif
}
/////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////
@@ -1220,126 +1148,6 @@ wstring GetErrorStringUnsupportedGPU(const char* gpuName, unsigned int gpuVendor
}
#endif
bool CSystem::OpenRenderLibrary(int type, const SSystemInitParams& initParams)
{
LOADING_TIME_PROFILE_SECTION;
#if defined(WIN32) || defined(WIN64)
if (!gEnv->IsDedicated())
{
unsigned int gpuVendorId = 0, gpuDeviceId = 0, totVidMem = 0;
char gpuName[256];
Win32SysInspect::DXFeatureLevel featureLevel = Win32SysInspect::DXFL_Undefined;
Win32SysInspect::GetGPUInfo(gpuName, sizeof(gpuName), gpuVendorId, gpuDeviceId, totVidMem, featureLevel);
if (m_env.IsEditor())
{
#if defined(EXTERNAL_CRASH_REPORTING)
CrashHandler::CrashHandlerBase::AddAnnotation("dx.feature.level", Win32SysInspect::GetFeatureLevelAsString(featureLevel));
CrashHandler::CrashHandlerBase::AddAnnotation("gpu.name", gpuName);
CrashHandler::CrashHandlerBase::AddAnnotation("gpu.vendorId", std::to_string(gpuVendorId));
CrashHandler::CrashHandlerBase::AddAnnotation("gpu.deviceId", std::to_string(gpuDeviceId));
CrashHandler::CrashHandlerBase::AddAnnotation("gpu.memory", std::to_string(totVidMem));
#endif
}
else
{
if (featureLevel < Win32SysInspect::DXFL_11_0)
{
const char logMsgFmt[] ("Unsupported GPU configuration!\n- %s (vendor = 0x%.4x, device = 0x%.4x)\n- Dedicated video memory: %d MB\n- Feature level: %s\n");
AZ_Printf(AZ_TRACE_SYSTEM_WINDOW, logMsgFmt, gpuName, gpuVendorId, gpuDeviceId, totVidMem >> 20, GetFeatureLevelAsString(featureLevel));
#if !defined(_RELEASE)
const bool allowPrompts = m_env.pSystem->GetICmdLine()->FindArg(eCLAT_Pre, "noprompt") == 0;
#else
const bool allowPrompts = true;
#endif // !defined(_RELEASE)
if (allowPrompts)
{
AZ_Printf(AZ_TRACE_SYSTEM_WINDOW, "Asking user if they wish to continue...");
const int mbRes = MessageBoxW(0, GetErrorStringUnsupportedGPU(gpuName, gpuVendorId, gpuDeviceId).c_str(), L"Open 3D Engine", MB_ICONWARNING | MB_OKCANCEL | MB_DEFBUTTON2 | MB_DEFAULT_DESKTOP_ONLY);
if (mbRes == IDCANCEL)
{
AZ_Printf(AZ_TRACE_SYSTEM_WINDOW, "User chose to cancel startup due to unsupported GPU.");
return false;
}
}
else
{
#if !defined(_RELEASE)
const bool obeyGPUCheck = m_env.pSystem->GetICmdLine()->FindArg(eCLAT_Pre, "anygpu") == 0;
#else
const bool obeyGPUCheck = true;
#endif // !defined(_RELEASE)
if (obeyGPUCheck)
{
AZ_Printf(AZ_TRACE_SYSTEM_WINDOW, "No prompts allowed and unsupported GPU check active. Treating unsupported GPU as error and exiting.");
return false;
}
}
AZ_Printf(AZ_TRACE_SYSTEM_WINDOW, "User chose to continue despite unsupported GPU!");
}
}
}
#endif
#if defined(AZ_RESTRICTED_PLATFORM)
#define AZ_RESTRICTED_SECTION SYSTEMINIT_CPP_SECTION_7
#include AZ_RESTRICTED_FILE(SystemInit_cpp)
#endif
if (gEnv->IsDedicated())
{
type = R_NULL_RENDERER;
}
const char* libname = "";
if (AZ::Interface<AzFramework::AtomActiveInterface>::Get())
{
libname = DLL_RENDERER_NULL;
}
else if (type == R_DX9_RENDERER)
{
libname = DLL_RENDERER_DX9;
}
else if (type == R_DX11_RENDERER)
{
libname = DLL_RENDERER_DX11;
}
else if (type == R_DX12_RENDERER)
{
libname = DLL_RENDERER_DX12;
}
else if (type == R_NULL_RENDERER)
{
libname = DLL_RENDERER_NULL;
}
else if (type == R_GL_RENDERER)
{
libname = DLL_RENDERER_GL;
}
else if (type == R_METAL_RENDERER)
{
libname = DLL_RENDERER_METAL;
}
else
{
AZ_Assert(false, "Renderer did not initialize correctly; no valid renderer specified.");
return false;
}
if (!InitializeEngineModule(libname, "EngineModule_CryRenderer", initParams))
{
return false;
}
if (!m_env.pRenderer)
{
AZ_Assert(false, "Renderer did not initialize correctly; it could not be found in the system environment.");
return false;
}
return true;
}
/////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////
bool CSystem::InitConsole()
@@ -1391,123 +1199,6 @@ ICVar* CSystem::attachVariable (const char* szVarName, int* pContainer, const ch
return pVar;
}
/////////////////////////////////////////////////////////////////////////////////
bool CSystem::InitRenderer(WIN_HINSTANCE hinst, WIN_HWND hwnd, const SSystemInitParams& initParams)
{
LOADING_TIME_PROFILE_SECTION(GetISystem());
if (m_pUserCallback)
{
m_pUserCallback->OnInitProgress("Initializing Renderer...");
}
if (m_bEditor)
{
m_env.pConsole->GetCVar("r_Width");
// save current screen width/height/bpp, so they can be restored on shutdown
m_iWidth = m_env.pConsole->GetCVar("r_Width")->GetIVal();
m_iHeight = m_env.pConsole->GetCVar("r_Height")->GetIVal();
m_iColorBits = m_env.pConsole->GetCVar("r_ColorBits")->GetIVal();
}
if (!OpenRenderLibrary(m_rDriver->GetString(), initParams))
{
return false;
}
#if defined(AZ_PLATFORM_IOS) || defined(AZ_PLATFORM_ANDROID)
if (m_rWidthAndHeightAsFractionOfScreenSize->GetFlags() & VF_WASINCONFIG)
{
int displayWidth = 0;
int displayHeight = 0;
if (GetPrimaryPhysicalDisplayDimensions(displayWidth, displayHeight))
{
// Ideally we would probably want to clamp this at the source,
// but I don't believe cvars support specifying a valid range.
float scaleFactor = 1.0f;
if(IsTablet())
{
scaleFactor = AZ::GetClamp(m_rTabletWidthAndHeightAsFractionOfScreenSize->GetFVal(), 0.1f, 1.0f);
}
else
{
scaleFactor = AZ::GetClamp(m_rWidthAndHeightAsFractionOfScreenSize->GetFVal(), 0.1f, 1.0f);
}
displayWidth *= scaleFactor;
displayHeight *= scaleFactor;
const int maxWidth = m_rMaxWidth->GetIVal();
if (maxWidth > 0 && maxWidth < displayWidth)
{
const float widthScaleFactor = static_cast<float>(maxWidth) / static_cast<float>(displayWidth);
displayWidth *= widthScaleFactor;
displayHeight *= widthScaleFactor;
}
const int maxHeight = m_rMaxHeight->GetIVal();
if (maxHeight > 0 && maxHeight < displayHeight)
{
const float heightScaleFactor = static_cast<float>(maxHeight) / static_cast<float>(displayHeight);
displayWidth *= heightScaleFactor;
displayHeight *= heightScaleFactor;
}
m_rWidth->Set(displayWidth);
m_rHeight->Set(displayHeight);
}
}
#endif // defined(AZ_PLATFORM_IOS) || defined(AZ_PLATFORM_ANDROID)
if (m_env.pRenderer)
{
// This is crucial as textures suffix are hard coded to context and we need to initialize
// the texture semantics to look it up.
m_env.pRenderer->InitTexturesSemantics();
#ifdef WIN32
SCustomRenderInitArgs args;
args.appStartedFromMediaCenter = strstr(initParams.szSystemCmdLine, "ReLaunchMediaCenter") != 0;
m_hWnd = m_env.pRenderer->Init(0, 0, m_rWidth->GetIVal(), m_rHeight->GetIVal(), m_rColorBits->GetIVal(), m_rDepthBits->GetIVal(), m_rStencilBits->GetIVal(), m_rFullscreen->GetIVal() ? true : false, initParams.bEditor, hinst, hwnd, false, &args, initParams.bShaderCacheGen);
//Timur, Not very clean code, we need to push new hwnd value to the system init params, so other modules can used when initializing.
(const_cast<SSystemInitParams*>(&initParams))->hWnd = m_hWnd;
bool retVal = (initParams.bShaderCacheGen || m_hWnd != 0);
AZ_Assert(retVal, "Renderer failed to initialize correctly.");
return retVal;
#else // WIN32
WIN_HWND h = m_env.pRenderer->Init(0, 0, m_rWidth->GetIVal(), m_rHeight->GetIVal(), m_rColorBits->GetIVal(), m_rDepthBits->GetIVal(), m_rStencilBits->GetIVal(), m_rFullscreen->GetIVal() ? true : false, initParams.bEditor, hinst, hwnd, false, nullptr, initParams.bShaderCacheGen);
#if (defined(LINUX) && !defined(AZ_PLATFORM_ANDROID))
return true;
#define AZ_RESTRICTED_SECTION_IMPLEMENTED
#elif defined(AZ_RESTRICTED_PLATFORM)
#define AZ_RESTRICTED_SECTION SYSTEMINIT_CPP_SECTION_8
#include AZ_RESTRICTED_FILE(SystemInit_cpp)
#endif
#if defined(AZ_RESTRICTED_SECTION_IMPLEMENTED)
#undef AZ_RESTRICTED_SECTION_IMPLEMENTED
#else
bool retVal = (initParams.bShaderCacheGen || h != 0);
if (retVal)
{
return true;
}
AZ_Assert(false, "Renderer failed to initialize correctly.");
return false;
#endif
#endif
}
return true;
}
/////////////////////////////////////////////////////////////////////////////////
bool CSystem::InitFileSystem()
{
@@ -1662,68 +1353,6 @@ bool CSystem::InitStreamEngine()
return true;
}
/////////////////////////////////////////////////////////////////////////////////
bool CSystem::InitFont(const SSystemInitParams& initParams)
{
LOADING_TIME_PROFILE_SECTION(GetISystem());
bool fontInited = false;
AZ::CryFontCreationRequestBus::BroadcastResult(fontInited, &AZ::CryFontCreationRequests::CreateCryFont, m_env, initParams);
if (!fontInited && !InitializeEngineModule(DLL_FONT, "EngineModule_CryFont", initParams))
{
return false;
}
if (!m_env.pCryFont)
{
AZ_Assert(false, "Font System did not initialize correctly; it could not be found in the system environment");
return false;
}
if (gEnv->IsDedicated())
{
return true;
}
if (!LoadFontInternal(m_pIFont, "default"))
{
return false;
}
if (!LoadFontInternal(m_pIFontUi, "default-ui"))
{
return false;
}
return true;
}
//////////////////////////////////////////////////////////////////////////
bool CSystem::Init3DEngine(const SSystemInitParams& initParams)
{
LOADING_TIME_PROFILE_SECTION(GetISystem());
if (!InitializeEngineModule(DLL_3DENGINE, "EngineModule_Cry3DEngine", initParams))
{
return false;
}
if (!m_env.p3DEngine)
{
AZ_Assert(false, "3D Engine did not initialize correctly; it could not be found in the system environment");
return false;
}
if (!m_env.p3DEngine->Init())
{
return false;
}
m_pProcess = m_env.p3DEngine;
m_pProcess->SetFlags(PROC_3DENGINE);
return true;
}
//////////////////////////////////////////////////////////////////////////
bool CSystem::InitAudioSystem(const SSystemInitParams& initParams)
{
@@ -2785,42 +2414,6 @@ AZ_POP_DISABLE_WARNING
}
InlineInitializationProcessing("CSystem::Init InitLocalizations");
//////////////////////////////////////////////////////////////////////////
// RENDERER
//////////////////////////////////////////////////////////////////////////
const bool loadLegacyRenderer = gEnv->IsEditor() ?
LOAD_LEGACY_RENDERER_FOR_EDITOR :
LOAD_LEGACY_RENDERER_FOR_LAUNCHER;
if (loadLegacyRenderer && !startupParams.bSkipRenderer)
{
AZ_Assert(CryMemory::IsHeapValid(), "CryMemory must be valid before initializing renderer.");
AZ_Printf(AZ_TRACE_SYSTEM_WINDOW, "Renderer initialization");
if (!InitRenderer(m_hInst, m_hWnd, startupParams))
{
return false;
}
AZ_Assert(CryMemory::IsHeapValid(), "CryMemory must be valid after initializing renderer.");
if (m_env.pRenderer)
{
bool bMultiGPUEnabled = false;
m_env.pRenderer->EF_Query(EFQ_MultiGPUEnabled, bMultiGPUEnabled);
if (bMultiGPUEnabled)
{
LoadConfiguration("mgpu.cfg");
}
}
InlineInitializationProcessing("CSystem::Init InitRenderer");
if (m_env.pCryFont)
{
m_env.pCryFont->SetRendererProperties(m_env.pRenderer);
}
AZ_Assert(m_env.pRenderer || startupParams.bSkipRenderer, "The renderer did not initialize correctly.");
}
#if !defined(AZ_RELEASE_BUILD) && defined(AZ_PLATFORM_ANDROID)
m_thermalInfoHandler = AZStd::make_unique<ThermalInfoAndroidHandler>();
#endif
@@ -2928,24 +2521,10 @@ AZ_POP_DISABLE_WARNING
}
}
//////////////////////////////////////////////////////////////////////////
// FONT
//////////////////////////////////////////////////////////////////////////
if (!startupParams.bSkipFont)
{
AZ_Printf(AZ_TRACE_SYSTEM_WINDOW, "Font initialization");
if (!InitFont(startupParams))
{
return false;
}
}
InlineInitializationProcessing("CSystem::Init InitFonts");
// The last update to the loading screen message was 'Initializing CryFont...'
// Compiling the default system textures can be the lengthiest portion of
// editor initialization, so it is useful to inform users that they are waiting on
// the necessary default textures to compile, and that they are not waiting on CryFont.
// the necessary default textures to compile.
if (m_pUserCallback)
{
m_pUserCallback->OnInitProgress("First time asset processing - may take a minute...");
@@ -3040,28 +2619,6 @@ AZ_POP_DISABLE_WARNING
return false;
}
//////////////////////////////////////////////////////////////////////////
// Init 3d engine
//////////////////////////////////////////////////////////////////////////
if (loadLegacyRenderer && !startupParams.bSkipRenderer && !startupParams.bShaderCacheGen)
{
AZ_Printf(AZ_TRACE_SYSTEM_WINDOW, "Initializing 3D Engine");
INDENT_LOG_DURING_SCOPE();
if (!Init3DEngine(startupParams))
{
return false;
}
// try flush to keep renderer busy
if (m_env.pRenderer)
{
m_env.pRenderer->TryFlush();
}
InlineInitializationProcessing("CSystem::Init Init3DEngine");
}
//////////////////////////////////////////////////////////////////////////
// SERVICE NETWORK
//////////////////////////////////////////////////////////////////////////
@@ -4223,24 +3780,3 @@ void CSystem::SetAssertVisible(bool bAssertVisble)
{
m_bIsAsserting = bAssertVisble;
}
bool CSystem::LoadFontInternal(IFFont*& font, const string& fontName)
{
font = m_env.pCryFont->NewFont(fontName);
if (!font)
{
AZ_Assert(false, "Could not instantiate the default font.");
return false;
}
//////////////////////////////////////////////////////////////////////////
string szFontPath = "Fonts/" + fontName + ".font";
if (!font->Load(szFontPath.c_str()))
{
AZ_Error(AZ_TRACE_SYSTEM_WINDOW, false, "Could not load font: %s. Make sure the program is running from the correct working directory.", szFontPath.c_str());
return false;
}
return true;
}
@@ -66,7 +66,6 @@ foreach(project_name project_path IN ZIP_LISTS LY_PROJECTS_TARGET_NAME LY_PROJEC
set(game_build_dependencies
${game_gem_dependencies}
Legacy::CrySystem
Legacy::CryFont
)
if(PAL_TRAIT_BUILD_SERVER_SUPPORTED)
@@ -95,7 +94,6 @@ foreach(project_name project_path IN ZIP_LISTS LY_PROJECTS_TARGET_NAME LY_PROJEC
set(server_build_dependencies
${game_gem_dependencies}
Legacy::CrySystem
Legacy::CryFont
)
endif()
@@ -103,7 +101,6 @@ foreach(project_name project_path IN ZIP_LISTS LY_PROJECTS_TARGET_NAME LY_PROJEC
set(game_runtime_dependencies
Legacy::CrySystem
Legacy::CryFont
)
endif()
@@ -9,13 +9,6 @@
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
#
ly_add_bundle_resources(
TARGET Editor
FILES
${CMAKE_SOURCE_DIR}/Code/Tools/RC/Config/rc/xmlfilter.txt
${CMAKE_SOURCE_DIR}/Code/Tools/RC/Config/rc/rc.ini
)
# Set resources directory for app icons
target_sources(Editor PRIVATE ${CMAKE_CURRENT_LIST_DIR}/Images.xcassets)
set_target_properties(Editor PROPERTIES
@@ -9,13 +9,6 @@
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
#
ly_add_bundle_resources(
TARGET AssetProcessor
FILES
${CMAKE_SOURCE_DIR}/Code/Tools/RC/Config/rc/xmlfilter.txt
${CMAKE_SOURCE_DIR}/Code/Tools/RC/Config/rc/rc.ini
)
# Set resources directory for app icons
target_sources(AssetProcessor PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/Platform/Mac/Images.xcassets)
set_target_properties(AssetProcessor PROPERTIES
@@ -65,27 +65,38 @@ namespace AZ
void AtomFontSystemComponent::Activate()
{
AZ::CryFontCreationRequestBus::Handler::BusConnect();
CrySystemEventBus::Handler::BusConnect();
}
void AtomFontSystemComponent::Deactivate()
{
AZ::CryFontCreationRequestBus::Handler::BusDisconnect();
CrySystemEventBus::Handler::BusDisconnect();
}
bool AtomFontSystemComponent::CreateCryFont(SSystemGlobalEnvironment& env, [[maybe_unused]] const SSystemInitParams& initParams)
void LoadFont(ICryFont& cryFont, const AZStd::string& fontName)
{
IFFont* font = cryFont.NewFont(fontName.c_str());
AZ_Assert(font, "Could not instantiate font: %s", fontName.c_str());
const AZStd::string fontPath = "Fonts/" + fontName + ".font";
if (!font->Load(fontPath.c_str()))
{
AZ_Error("AtomFont", false, "Could not load font: %s", fontPath.c_str());
}
}
void AtomFontSystemComponent::OnCrySystemInitialized(ISystem& system, const SSystemInitParams&)
{
ISystem* system = env.pSystem;
#if !defined(AZ_MONOLITHIC_BUILD)
// When module is linked dynamically, we must set our gEnv pointer.
// When module is linked statically, we'll share the application's gEnv pointer.
gEnv = system->GetGlobalEnvironment();
gEnv = system.GetGlobalEnvironment();
#endif
if (env.IsDedicated())
if (gEnv->IsDedicated())
{
#if defined(USE_NULLFONT)
env.pCryFont = new AtomNullFont();
gEnv->pCryFont = new AtomNullFont();
#else
// The NULL font implementation must be present for all platforms
// supporting running as a pure dedicated server.
@@ -96,12 +107,17 @@ namespace AZ
else
{
#if defined(USE_NULLFONT) && defined(USE_NULLFONT_ALWAYS)
env.pCryFont = new AtomNullFont();
gEnv->pCryFont = new AtomNullFont();
#else
env.pCryFont = new AtomFont(system);
gEnv->pCryFont = new AtomFont(&system);
#endif
}
return env.pCryFont != 0;
if (gEnv->pCryFont)
{
LoadFont(*gEnv->pCryFont, "default");
LoadFont(*gEnv->pCryFont, "default-ui");
}
}
void AtomFontSystemComponent::OnCrySystemShutdown([[maybe_unused]] ISystem& system)
@@ -13,7 +13,6 @@
#include <AzCore/Component/Component.h>
#include <CryCommon/CryFontBus.h>
#include <CryCommon/CrySystemBus.h>
namespace AZ
@@ -22,7 +21,6 @@ namespace AZ
{
class AtomFontSystemComponent
: public AZ::Component
, private AZ::CryFontCreationRequestBus::Handler
, private CrySystemEventBus::Handler
{
public:
@@ -43,12 +41,12 @@ namespace AZ
////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////
// CryFontCreationBus
bool CreateCryFont(SSystemGlobalEnvironment& env, const SSystemInitParams& initParams) override;
// CrySystemEventBus
void OnCrySystemInitialized(ISystem& system, const SSystemInitParams& initParams);
////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////
// CryFontCreationBus
// CrySystemEventBus
void OnCrySystemShutdown(ISystem& system) override;
////////////////////////////////////////////////////////////////////////
};