diff --git a/Code/CryEngine/CMakeLists.txt b/Code/CryEngine/CMakeLists.txt index 38fcbf4a27..96f6427268 100644 --- a/Code/CryEngine/CMakeLists.txt +++ b/Code/CryEngine/CMakeLists.txt @@ -10,5 +10,4 @@ # add_subdirectory(CryCommon) -add_subdirectory(CryFont) add_subdirectory(CrySystem) diff --git a/Code/CryEngine/CryCommon/CryFontBus.h b/Code/CryEngine/CryCommon/CryFontBus.h deleted file mode 100644 index 9922193f42..0000000000 --- a/Code/CryEngine/CryCommon/CryFontBus.h +++ /dev/null @@ -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 - -#include - -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; - -} diff --git a/Code/CryEngine/CryFont/CMakeLists.txt b/Code/CryEngine/CryFont/CMakeLists.txt deleted file mode 100644 index 9e2f29f7b6..0000000000 --- a/Code/CryEngine/CryFont/CMakeLists.txt +++ /dev/null @@ -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 -) diff --git a/Code/CryEngine/CryFont/CryFont.cpp b/Code/CryEngine/CryFont/CryFont.cpp deleted file mode 100644 index ab39a0fa4d..0000000000 --- a/Code/CryEngine/CryFont/CryFont.cpp +++ /dev/null @@ -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 -#include - -// 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 tag of - //! an enclosing definition: - //! - //! - //! - //! - //! - //! - //! - //! - //! - 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: - //! - //! - //! - //! - //! - //! - //! - //! - //! - //! - //! - //! - //! - //! - //! - //! - //! - //! - //! - //! - //! - 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 m_fontTagsXml; //!< List of child 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; - } - - // - 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; - } - } - - // - 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; - } - } - - // - 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 "); - 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 fontFamilyFilenames; - AZStd::list 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(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(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> insertPair(loweredFilename, fontFamily); - auto iterPosition = m_fontFamilies.insert(insertPair).first; - m_fontFamilyReverseLookup[fontFamily.get()] = iterPosition; - - // Then, by Font Family name - AZStd::pair> 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 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 - diff --git a/Code/CryEngine/CryFont/CryFont.def b/Code/CryEngine/CryFont/CryFont.def deleted file mode 100644 index 43bfe0b13d..0000000000 --- a/Code/CryEngine/CryFont/CryFont.def +++ /dev/null @@ -1,3 +0,0 @@ -EXPORTS - ModuleInitISystem @2 - CryModuleGetMemoryInfo @8 diff --git a/Code/CryEngine/CryFont/CryFont.h b/Code/CryEngine/CryFont/CryFont.h deleted file mode 100644 index 726818f5a7..0000000000 --- a/Code/CryEngine/CryFont/CryFont.h +++ /dev/null @@ -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 -#include -#include -#include - -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 FontMap; - typedef FontMap::iterator FontMapItor; - typedef FontMap::const_iterator FontMapConstItor; - - typedef AZStd::map> FontFamilyMap; - typedef AZStd::map 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; // m_persistedFontFamilies; //!< Stores persisted fonts (if "persist font families" is enabled) - -}; - -#endif - -#endif // CRYINCLUDE_CRYFONT_CRYFONT_H diff --git a/Code/CryEngine/CryFont/CryFont.rc b/Code/CryEngine/CryFont/CryFont.rc deleted file mode 100644 index 5730d0a537..0000000000 --- a/Code/CryEngine/CryFont/CryFont.rc +++ /dev/null @@ -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 - diff --git a/Code/CryEngine/CryFont/CryFont_precompiled.cpp b/Code/CryEngine/CryFont/CryFont_precompiled.cpp deleted file mode 100644 index 235fe8e053..0000000000 --- a/Code/CryEngine/CryFont/CryFont_precompiled.cpp +++ /dev/null @@ -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" diff --git a/Code/CryEngine/CryFont/CryFont_precompiled.h b/Code/CryEngine/CryFont/CryFont_precompiled.h deleted file mode 100644 index e37845aa35..0000000000 --- a/Code/CryEngine/CryFont/CryFont_precompiled.h +++ /dev/null @@ -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 - -#define CRYFONT_EXPORTS - -#include - -#include - -#include -#include -#include -#include - -#define USE_NULLFONT - -#if defined(DEDICATED_SERVER) -#define USE_NULLFONT_ALWAYS 1 -#endif - diff --git a/Code/CryEngine/CryFont/FBitmap.h b/Code/CryEngine/CryFont/FBitmap.h deleted file mode 100644 index 93f5505726..0000000000 --- a/Code/CryEngine/CryFont/FBitmap.h +++ /dev/null @@ -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 diff --git a/Code/CryEngine/CryFont/FFont.cpp b/Code/CryEngine/CryFont/FFont.cpp deleted file mode 100644 index c028a0827e..0000000000 --- a/Code/CryEngine/CryFont/FFont.cpp +++ /dev/null @@ -1,1550 +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. - - -#include "CryFont_precompiled.h" - -#if !defined(USE_NULLFONT_ALWAYS) - -#include "FFont.h" -#include "CryFont.h" -#include "FontTexture.h" -#include "UnicodeIterator.h" - -#include -#include - -static ColorB ColorTable[10] = -{ - ColorB(0x00, 0x00, 0x00), // black - ColorB(0xff, 0xff, 0xff), // white - ColorB(0x00, 0x00, 0xff), // blue - ColorB(0x00, 0xff, 0x00), // green - ColorB(0xff, 0x00, 0x00), // red - ColorB(0x00, 0xff, 0xff), // cyan - ColorB(0xff, 0xff, 0x00), // yellow - ColorB(0xff, 0x00, 0xff), // purple - ColorB(0xff, 0x80, 0x00), // orange - ColorB(0x8f, 0x8f, 0x8f), // grey -}; - -static const int TabCharCount = 4; -static const size_t MsgBufferSize = 1024; -static const size_t MaxDrawVBQuads = 128; - -CFFont::CFFont(ISystem* pSystem, CCryFont* pCryFont, const char* pFontName) - : m_name(pFontName) - , m_curPath("") - , m_pFontTexture(0) - , m_fontBufferSize(0) - , m_pFontBuffer(0) - , m_texID(-1) - , m_textureVersion(0) - , m_pSystem(pSystem) - , m_pCryFont(pCryFont) - , m_fontTexDirty(false) - , m_effects() - , m_pDrawVB(0) - , m_nRefCount(0) - , m_monospacedFont(false) -{ - assert(m_name.c_str()); - assert(m_pSystem); - assert(m_pCryFont); - - // create default effect - SEffect* pEffect = AddEffect("default"); - pEffect->AddPass(); - - m_pDrawVB = new SVF_P3F_C4B_T2F[MaxDrawVBQuads * 6]; - - AddRef(); -} - -CFFont::~CFFont() -{ - // The font should already be unregistered through a call to - // CFFont::Release() at this point. - CRY_ASSERT(m_pCryFont == nullptr); - - Free(); - - SAFE_DELETE_ARRAY(m_pDrawVB); -} - -int32 CFFont::AddRef() -{ - int32 nRef = CryInterlockedIncrement(&m_nRefCount); - return nRef; -} - -int32 CFFont::Release() -{ - if (m_nRefCount > 0) - { - int32 nRef = CryInterlockedDecrement(&m_nRefCount); - if (nRef < 0) - { - CryFatalError("CBaseResource::Release() called more than once!"); - } - - if (nRef <= 0) - { - if (m_pCryFont) - { - AZStd::lock_guard locker(m_fontMutex); - - // Unregister font so no one can increase it's ref count while it is queued for deletion - m_pCryFont->UnregisterFont(m_name); - m_pCryFont = nullptr; - } - - if (gEnv->pRenderer) - { - gEnv->pRenderer->DeleteFont(this); - } - return 0; - } - return nRef; - } - return 0; -} - -// Load a font from a TTF file -bool CFFont::Load(const char* pFontFilePath, unsigned int width, unsigned int height, unsigned int widthNumSlots, unsigned int heightNumSlots, unsigned int flags, float sizeRatio) -{ - if (!pFontFilePath) - { - return false; - } - - Free(); - - auto pPak = gEnv->pCryPak; - - string fullFile; - if (pPak->IsAbsPath(pFontFilePath)) - { - fullFile = pFontFilePath; - } - else - { - fullFile = m_curPath + pFontFilePath; - } - - int iSmoothMethod = (flags & TTFFLAG_SMOOTH_MASK) >> TTFFLAG_SMOOTH_SHIFT; - int iSmoothAmount = (flags & TTFFLAG_SMOOTH_AMOUNT_MASK) >> TTFFLAG_SMOOTH_AMOUNT_SHIFT; - - AZ::IO::HandleType fileHandle = pPak->FOpen(fullFile.c_str(), "rb"); - if (fileHandle == AZ::IO::InvalidHandle) - { - return false; - } - - size_t fileSize = pPak->FGetSize(fileHandle); - if (!fileSize) - { - pPak->FClose(fileHandle); - return false; - } - - unsigned char* pBuffer = new unsigned char[fileSize]; - if (!pPak->FReadRaw(pBuffer, fileSize, 1, fileHandle)) - { - pPak->FClose(fileHandle); - delete [] pBuffer; - return false; - } - - pPak->FClose(fileHandle); - - if (!m_pFontTexture) - { - m_pFontTexture = new CFontTexture(); - } - - if (!m_pFontTexture || !m_pFontTexture->CreateFromMemory(pBuffer, (int)fileSize, width, height, iSmoothMethod, iSmoothAmount, widthNumSlots, heightNumSlots, sizeRatio)) - { - delete [] pBuffer; - return false; - } - - m_monospacedFont = m_pFontTexture->GetMonospaced(); - m_pFontBuffer = pBuffer; - m_fontBufferSize = fileSize; - m_fontTexDirty = false; - m_sizeRatio = sizeRatio; - - InitCache(); - - return true; -} - - -void CFFont::Free() -{ - IRenderer* pRenderer = gEnv->pRenderer; - if (m_texID >= 0 && pRenderer) - { - pRenderer->RemoveTexture(m_texID); - m_texID = -1; - m_textureVersion = 0; - } - - delete m_pFontTexture; - m_pFontTexture = 0; - - delete [] m_pFontBuffer; - m_pFontBuffer = 0; -} - -void CFFont::DrawString(float x, float y, const char* pStr, const bool asciiMultiLine, const STextDrawContext& ctx) -{ - IF (!pStr, 0) - { - return; - } - - DrawStringUInternal(x, y, 1.0f, pStr, asciiMultiLine, ctx); -} - -void CFFont::DrawString(float x, float y, float z, const char* pStr, const bool asciiMultiLine, const STextDrawContext& ctx) -{ - IF (!pStr, 0) - { - return; - } - - DrawStringUInternal(x, y, z, pStr, asciiMultiLine, ctx); -} - -void CFFont::DrawStringUInternal(float x, float y, float z, const char* pStr, const bool asciiMultiLine, const STextDrawContext& ctx) -{ - IF (!pStr || !m_pFontTexture || ctx.m_fxIdx >= m_effects.size() || m_effects[ctx.m_fxIdx].m_passes.empty(), 0) - { - return; - } - - AZStd::lock_guard locker(m_fontMutex); - - IRenderer* pRenderer = gEnv->pRenderer; - AZ_Assert(pRenderer, "gEnv->pRenderer is NULL"); - - pRenderer->DrawStringU(this, x, y, z, pStr, asciiMultiLine, ctx); -} - -ILINE uint32 COLCONV(uint32 clr) -{ - return ((clr & 0xff00ff00) | ((clr & 0xff0000) >> 16) | ((clr & 0xff) << 16)); -} - -void CFFont::RenderCallback(float x, float y, float z, const char* pStr, const bool asciiMultiLine, const STextDrawContext& ctx) -{ - AZStd::lock_guard locker(m_fontMutex); - - const size_t fxSize = m_effects.size(); - - IF (fxSize && m_texID == -1 && !InitTexture(), 0) - { - return; - } - - // if the font is about to be deleted then m_pCryFont can be nullptr - if (!m_pCryFont) - { - return; - } - - SVF_P3F_C4B_T2F* pVertex = m_pDrawVB; - size_t vbOffset = 0; - - bool isFontRenderStateSet = false; - TransformationMatrices backupSceneMatrices; - IRenderer* pRenderer = gEnv->pRenderer; - AZ_Assert(pRenderer, "gEnv->pRenderer is NULL"); - - int baseState = ctx.m_baseState; - bool overrideViewProjMatrices = ctx.m_overrideViewProjMatrices; - int texId = m_texID; - - // Local function to share code needed when we render the vertex buffer so far - AZStd::function RenderVB = [&pVertex, &vbOffset, pRenderer] - { - gEnv->pRenderer->DrawDynVB(pVertex, 0, vbOffset, 0, prtTriangleList); - vbOffset = 0; - }; - - // Local function that is passed into CreateQuadsForText as the AddQuad function - AddFunction AddQuad = [&pVertex, &vbOffset, RenderVB] - (const Vec3& v0, const Vec3& v1, const Vec3& v2, const Vec3& v3, const Vec2& tc0, const Vec2& tc1, const Vec2& tc2, const Vec2& tc3, uint32 packedColor) - { - // define char quad - pVertex[vbOffset].xyz = v0; - pVertex[vbOffset].color.dcolor = packedColor; - pVertex[vbOffset].st = tc0; - - pVertex[vbOffset + 1].xyz = v1; - pVertex[vbOffset + 1].color.dcolor = packedColor; - pVertex[vbOffset + 1].st = tc1; - - pVertex[vbOffset + 2].xyz = v2; - pVertex[vbOffset + 2].color.dcolor = packedColor; - pVertex[vbOffset + 2].st = tc2; - - pVertex[vbOffset + 3].xyz = v2; - pVertex[vbOffset + 3].color.dcolor = packedColor; - pVertex[vbOffset + 3].st = tc2; - - pVertex[vbOffset + 4].xyz = v3; - pVertex[vbOffset + 4].color.dcolor = packedColor; - pVertex[vbOffset + 4].st = tc3; - - pVertex[vbOffset + 5].xyz = v0; - pVertex[vbOffset + 5].color.dcolor = packedColor; - pVertex[vbOffset + 5].st = tc0; - - vbOffset += 6; - - if (vbOffset >= MaxDrawVBQuads * 6) - { - RenderVB(); - } - }; - - // Local function that is passed into CreateQuadsForText as the BeginPass function - BeginPassFunction BeginPass = [&pVertex, &vbOffset, &isFontRenderStateSet, &backupSceneMatrices, texId, pRenderer, baseState, RenderVB, overrideViewProjMatrices] - (const SRenderingPass* pPass) - { - // We don't want to set this state before the call to CreateQuadsForText since that calls Prepare, - // which is needed before FontSetTexture - if (!isFontRenderStateSet) - { - pRenderer->FontSetTexture(texId, FILTER_TRILINEAR); - pRenderer->FontSetRenderingState(overrideViewProjMatrices, backupSceneMatrices); - gEnv->pRenderer->FontSetBlending(pPass->m_blendSrc, pPass->m_blendDest, baseState); - isFontRenderStateSet = true; - } - - if (vbOffset > 0) - { - RenderVB(); - } - - gEnv->pRenderer->FontSetBlending(pPass->m_blendSrc, pPass->m_blendDest, baseState); - }; - - CreateQuadsForText(x, y, z, pStr, asciiMultiLine, ctx, AddQuad, BeginPass); - - if (vbOffset > 0) - { - RenderVB(); - } - - // restore the old states - if (isFontRenderStateSet) - { - pRenderer->FontRestoreRenderingState(overrideViewProjMatrices, backupSceneMatrices); - } -} - -Vec2 CFFont::GetTextSize(const char* pStr, const bool asciiMultiLine, const STextDrawContext& ctx) -{ - IF (!pStr, 0) - { - return Vec2(0.0f, 0.0f); - } - - return GetTextSizeUInternal(pStr, asciiMultiLine, ctx); -} - -Vec2 CFFont::GetTextSizeUInternal(const char* pStr, const bool asciiMultiLine, const STextDrawContext& ctx) -{ - const size_t fxSize = m_effects.size(); - - IF (!pStr || !m_pFontTexture || !fxSize, 0) - { - return Vec2(0, 0); - } - - AZStd::lock_guard locker(m_fontMutex); - - Prepare(pStr, false, ctx.m_requestSize); - - IRenderer* pRenderer = gEnv->pRenderer; - AZ_Assert(pRenderer, "gEnv->pRenderer is NULL"); - - // This is the "logical" size of the font (in pixels). The actual size of - // the glyphs in the font texture may have additional scaling applied or - // could have been re-rendered at a different size. - Vec2 size = ctx.m_size; - if (ctx.m_sizeIn800x600) - { - pRenderer->ScaleCoord(size.x, size.y); - } - - // This scaling takes into account the logical size of the font relative - // to any additional scaling applied (such as from "size ratio"). - const TextScaleInfoInternal scaleInfo(CalculateScaleInternal(ctx)); - - float maxW = 0; - float maxH = 0; - - const size_t fxIdx = ctx.m_fxIdx < fxSize ? ctx.m_fxIdx : 0; - const SEffect& fx = m_effects[fxIdx]; - - for (size_t i = 0, numPasses = fx.m_passes.size(); i < numPasses; ++i) - { - const SRenderingPass* pPass = &fx.m_passes[numPasses - i - 1]; - - // gather pass data - Vec2 offset = pPass->m_posOffset; - - float charX = offset.x; - float charY = offset.y + size.y; - - if (charY > maxH) - { - maxH = charY; - } - - // parse the string, ignoring control characters - uint32_t nextCh = 0; - Unicode::CIterator pChar(pStr); - while (uint32_t ch = *pChar) - { - ++pChar; - nextCh = *pChar; - switch (ch) - { - case '\\': - { - if (*pChar != 'n' || !asciiMultiLine) - { - break; - } - - ++pChar; - } - case '\n': - { - if (charX > maxW) - { - maxW = charX; - } - - charX = offset.x; - charY += size.y; - - if (charY > maxH) - { - maxH = charY; - } - - continue; - } - break; - case '\r': - { - if (charX > maxW) - { - maxW = charX; - } - - charX = offset.x; - continue; - } - break; - case '\t': - { - if (ctx.m_proportional) - { - charX += TabCharCount * size.x * FONT_SPACE_SIZE; - } - else - { - charX += TabCharCount * size.x * ctx.m_widthScale; - } - continue; - } - break; - case '$': - { - if (ctx.m_processSpecialChars) - { - if (*pChar == '$') - { - ++pChar; - } - else if (isdigit(*pChar)) - { - ++pChar; - continue; - } - else if (*pChar == 'O' || *pChar == 'o') - { - ++pChar; - continue; - } - } - } - break; - default: - break; - } - - const bool rerenderGlyphs = m_sizeBehavior == SizeBehavior::Rerender; - const Vec2i requestSize = rerenderGlyphs ? ctx.m_requestSize : CCryFont::defaultGlyphSize; - int horizontalAdvance = m_pFontTexture->GetHorizontalAdvance(ch, requestSize); - float advance; - - if (ctx.m_proportional) - { - advance = horizontalAdvance * scaleInfo.scale.x; - } - else - { - advance = size.x * ctx.m_widthScale; - } - - // Adjust "advance" here for kerning purposes - Vec2 kerningOffset(Vec2_Zero); - if (ctx.m_kerningEnabled && nextCh) - { - kerningOffset = m_pFontTexture->GetKerning(ch, nextCh) * scaleInfo.scale.x; - } - - // Adjust char width with tracking only if there is a next character - if (nextCh) - { - charX += ctx.m_tracking; - } - - charX += advance + kerningOffset.x; - } - - if (charX > maxW) - { - maxW = charX; - } - } - - return Vec2(maxW, maxH); -} - -uint32 CFFont::GetNumQuadsForText(const char* pStr, const bool asciiMultiLine, const STextDrawContext& ctx) -{ - uint32 numQuads = 0; - - const size_t fxSize = m_effects.size(); - const size_t fxIdx = ctx.m_fxIdx < fxSize ? ctx.m_fxIdx : 0; - const SEffect& fx = m_effects[fxIdx]; - - for (size_t j = 0, numPasses = fx.m_passes.size(); j < numPasses; ++j) - { - size_t i = numPasses - j - 1; - bool drawFrame = ctx.m_framed && i == numPasses - 1; - - if (drawFrame) - { - ++numQuads; - } - - uint32_t nextCh = 0; - Unicode::CIterator pChar(pStr); - while (uint32_t ch = *pChar) - { - ++pChar; - nextCh = *pChar; - - switch (ch) - { - case '\\': - { - if (*pChar != 'n' || !asciiMultiLine) - { - break; - } - ++pChar; - } - case '\n': - { - continue; - } - break; - case '\r': - { - continue; - } - break; - case '\t': - { - continue; - } - break; - case '$': - { - if (ctx.m_processSpecialChars) - { - if (*pChar == '$') - { - ++pChar; - } - else if (isdigit(*pChar)) - { - ++pChar; - continue; - } - else if (*pChar == 'O' || *pChar == 'o') - { - ++pChar; - continue; - } - } - } - break; - default: - break; - } - - ++numQuads; - } - } - - return numQuads; -} - -uint32 CFFont::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) -{ - AZStd::lock_guard locker(m_fontMutex); - - uint32 numQuadsWritten = 0; - - const size_t fxSize = m_effects.size(); - IF (fxSize && m_texID == -1 && !InitTexture(), 0) - { - return numQuadsWritten; - } - - // if the font is about to be deleted then m_pCryFont can be nullptr - if (!m_pCryFont) - { - return numQuadsWritten; - } - - SVF_P2F_C4B_T2F_F4B* pVertex = verts; - uint16* pIndex = indices; - size_t vbOffset = 0; - size_t ibOffset = 0; - - // Local function that is passed into CreateQuadsForText as the AddQuad function - AddFunction AddQuad = [&pVertex, &pIndex, &vbOffset, &ibOffset, maxQuads, &numQuadsWritten] - (const Vec3& v0, const Vec3& v1, const Vec3& v2, const Vec3& v3, const Vec2& tc0, const Vec2& tc1, const Vec2& tc2, const Vec2& tc3, uint32 packedColor) - { - Vec2 xy0(v0); - Vec2 xy1(v1); - Vec2 xy2(v2); - Vec2 xy3(v3); - - AZ_Assert(vbOffset + 3 < maxQuads * 4, "Vertex buffer overflow"); - AZ_Assert(ibOffset + 5 < maxQuads * 6, "Index buffer overflow"); - - // This should never happen but for safety make sure we never write off end of buffers (should hit asserts above if this is the case) - if (numQuadsWritten < maxQuads) - { - // define char quad - pVertex[vbOffset].xy = xy0; - pVertex[vbOffset].color.dcolor = packedColor; - pVertex[vbOffset].st = tc0; - pVertex[vbOffset].texIndex = 0; - pVertex[vbOffset].texHasColorChannel = 0; - pVertex[vbOffset].texIndex2 = 0; - pVertex[vbOffset].pad = 0; - - pVertex[vbOffset + 1].xy = xy1; - pVertex[vbOffset + 1].color.dcolor = packedColor; - pVertex[vbOffset + 1].st = tc1; - pVertex[vbOffset + 1].texIndex = 0; - pVertex[vbOffset + 1].texHasColorChannel = 0; - pVertex[vbOffset + 1].texIndex2 = 0; - pVertex[vbOffset + 1].pad = 0; - - pVertex[vbOffset + 2].xy = xy2; - pVertex[vbOffset + 2].color.dcolor = packedColor; - pVertex[vbOffset + 2].st = tc2; - pVertex[vbOffset + 2].texIndex = 0; - pVertex[vbOffset + 2].texHasColorChannel = 0; - pVertex[vbOffset + 2].texIndex2 = 0; - pVertex[vbOffset + 2].pad = 0; - - pVertex[vbOffset + 3].xy = xy3; - pVertex[vbOffset + 3].color.dcolor = packedColor; - pVertex[vbOffset + 3].st = tc3; - pVertex[vbOffset + 3].texIndex = 0; - pVertex[vbOffset + 3].texHasColorChannel = 0; - pVertex[vbOffset + 3].texIndex2 = 0; - pVertex[vbOffset + 3].pad = 0; - - pIndex[ibOffset] = vbOffset; - pIndex[ibOffset + 1] = vbOffset + 1; - pIndex[ibOffset + 2] = vbOffset + 2; - pIndex[ibOffset + 3] = vbOffset + 2; - pIndex[ibOffset + 4] = vbOffset + 3; - pIndex[ibOffset + 5] = vbOffset + 0; - - vbOffset += 4; - ibOffset += 6; - - ++numQuadsWritten; - } - }; - - // Local function that is passed into CreateQuadsForText as the BeginPass function - BeginPassFunction BeginPass = [] - (const SRenderingPass* /* pPass */) - { - }; - - - CreateQuadsForText(x, y, z, pStr, asciiMultiLine, ctx, AddQuad, BeginPass); - - return numQuadsWritten; -} - -int CFFont::GetFontTextureId() -{ - if (m_texID == -1 && !InitTexture()) - { - return -1; - } - - return m_texID; -} - -uint32 CFFont::GetFontTextureVersion() -{ - return m_textureVersion; -} - -void CFFont::CreateQuadsForText(float x, float y, float z, const char* pStr, const bool asciiMultiLine, const STextDrawContext& ctx, - AddFunction AddQuad, BeginPassFunction BeginPass) -{ - const size_t fxSize = m_effects.size(); - - Prepare(pStr, true, ctx.m_requestSize); - - const size_t fxIdx = ctx.m_fxIdx < fxSize ? ctx.m_fxIdx : 0; - const SEffect& fx = m_effects[fxIdx]; - - bool isRGB = m_pCryFont->RndPropIsRGBA(); - - float halfTexelShift = m_pCryFont->RndPropHalfTexelOffset(); - - bool passZeroColorOverridden = ctx.IsColorOverridden(); - - uint32 alphaBlend = passZeroColorOverridden ? ctx.m_colorOverride.a : fx.m_passes[0].m_color.a; - if (alphaBlend > 128) - { - ++alphaBlend; // 0..256 for proper blending - } - IRenderer* pRenderer = gEnv->pRenderer; - AZ_Assert(pRenderer, "gEnv->pRenderer is NULL"); - - // This is the "logical" size of the font (in pixels). The actual size of - // the glyphs in the font texture may have additional scaling applied or - // could have been re-rendered at a different size. - Vec2 size = ctx.m_size; - if (ctx.m_sizeIn800x600) - { - pRenderer->ScaleCoord(size.x, size.y); - } - - // This scaling takes into account the logical size of the font relative - // to any additional scaling applied (such as from "size ratio"). - const TextScaleInfoInternal scaleInfo(CalculateScaleInternal(ctx)); - - Vec2 baseXY = Vec2(x, y); // in pixels - if (ctx.m_sizeIn800x600) - { - pRenderer->ScaleCoord(baseXY.x, baseXY.y); - } - - // Apply overscan border - const int flags = ctx.GetFlags(); - if ((flags & eDrawText_2D) && !(flags & eDrawText_IgnoreOverscan)) - { - Vec2 overscanBorder = Vec2(0.0f, 0.0f); - pRenderer->EF_Query(EFQ_OverscanBorders, overscanBorder); - - const float screenWidth = (float)pRenderer->GetOverlayWidth(); - const float screenHeight = (float)pRenderer->GetOverlayHeight(); - Vec2 overscanBorderOffset = ZERO; - if (!(flags & eDrawText_Center)) - { - overscanBorderOffset.x = (overscanBorder.x * screenWidth); - } - if (!(flags & eDrawText_CenterV)) - { - overscanBorderOffset.y = (overscanBorder.y * screenHeight); - } - if (flags & eDrawText_Right) - { - overscanBorderOffset.x = -overscanBorderOffset.x; - } - if (flags & eDrawText_Bottom) - { - overscanBorderOffset.y = -overscanBorderOffset.y; - } - baseXY += overscanBorderOffset; - } - - // snap for pixel perfect rendering (better quality for text) - if (ctx.m_pixelAligned) - { - baseXY.x = floor(baseXY.x); - baseXY.y = floor(baseXY.y); - - // for smaller fonts (half res or less) it's better to average multiple pixels (we don't miss lines) - if (scaleInfo.scale.x < 0.9f) - { - baseXY.x += 0.5f; // try to average two columns (for exact half res) - } - if (scaleInfo.scale.y < 0.9f) - { - baseXY.y += 0.25f; // hand tweaked value to get a good result with tiny font (640x480 underscore in console) - } - } - - for (size_t j = 0, numPasses = fx.m_passes.size(); j < numPasses; ++j) - { - size_t i = numPasses - j - 1; - - const SRenderingPass* pPass = &fx.m_passes[i]; - - if (!i) - { - alphaBlend = 256; - } - - ColorB passColor = !i && passZeroColorOverridden ? ctx.m_colorOverride : fx.m_passes[i].m_color; - - // gather pass data - Vec2 offset = pPass->m_posOffset; // in pixels - - float charX = baseXY.x + offset.x; // in pixels - float charY = baseXY.y + offset.y; // in pixels - - ColorB color = passColor; - - bool drawFrame = ctx.m_framed && i == numPasses - 1; - - BeginPass(pPass); - - if (drawFrame) - { - ColorB tempColor(255, 255, 255, 255); - uint32 frameColor = tempColor.pack_abgr8888(); - if (!isRGB) - { - frameColor = COLCONV(frameColor); - } - - Vec2 textSize = GetTextSizeUInternal(pStr, asciiMultiLine, ctx); - - float x0 = baseXY.x - 12; - float y0 = baseXY.y - 6; - float x1 = baseXY.x + textSize.x + 12; - float y1 = baseXY.y + textSize.y + 6; - - bool culled = false; - IF (ctx.m_clippingEnabled, 0) - { - float clipX = ctx.m_clipX; - float clipY = ctx.m_clipY; - float clipR = ctx.m_clipX + ctx.m_clipWidth; - float clipB = ctx.m_clipY + ctx.m_clipHeight; - - if ((x0 >= clipR) || (y0 >= clipB) || (x1 < clipX) || (y1 < clipY)) - { - culled = true; - } - - x0 = max(clipX, x0); - y0 = max(clipY, y0); - x1 = min(clipR, x1); - y1 = min(clipB, y1); - - //if (!culled && ((x1 - x0 <= 0.0f) || (y1 - y0 <= 0.0f))) - // culled = true; - } - - IF (!culled, 1) - { - Vec3 v0(x0, y0, z); - Vec3 v2(x1, y1, z); - Vec3 v1(v2.x, v0.y, v0.z); // to avoid float->half conversion - Vec3 v3(v0.x, v2.y, v0.z); // to avoid float->half conversion - - if (ctx.m_drawTextFlags & eDrawText_UseTransform) - { - v0 = ctx.m_transform * v0; - v2 = ctx.m_transform * v2; - v1 = ctx.m_transform * v1; - v3 = ctx.m_transform * v3; - } - - Vec2 gradientUvMin, gradientUvMax; - GetGradientTextureCoord(gradientUvMin.x, gradientUvMin.y, gradientUvMax.x, gradientUvMax.y); - - // define the frame quad - Vec2 uv(gradientUvMin.x, gradientUvMax.y); - AddQuad(v0, v1, v2, v3, uv, uv, uv, uv, frameColor); - } - } - - // parse the string, ignoring control characters - uint32_t nextCh = 0; - Unicode::CIterator pChar(pStr); - while (uint32_t ch = *pChar) - { - ++pChar; - nextCh = *pChar; - - switch (ch) - { - case '\\': - { - if (*pChar != 'n' || !asciiMultiLine) - { - break; - } - ++pChar; - } - case '\n': - { - charX = baseXY.x + offset.x; - charY += size.y; - continue; - } - break; - case '\r': - { - charX = baseXY.x + offset.x; - continue; - } - break; - case '\t': - { - if (ctx.m_proportional) - { - charX += TabCharCount * size.x * FONT_SPACE_SIZE; - } - else - { - charX += TabCharCount * size.x * ctx.m_widthScale; - } - continue; - } - break; - case '$': - { - if (ctx.m_processSpecialChars) - { - if (*pChar == '$') - { - ++pChar; - } - else if (isdigit(*pChar)) - { - if (!i) - { - int colorIndex = (*pChar) - '0'; - ColorB newColor = ColorTable[colorIndex]; - color.r = newColor.r; - color.g = newColor.g; - color.b = newColor.b; - // Leave alpha at original value! - } - ++pChar; - continue; - } - else if (*pChar == 'O' || *pChar == 'o') - { - if (!i) - { - color = passColor; - } - ++pChar; - continue; - } - } - } - break; - default: - break; - } - - // get texture coordinates - float texCoord[4]; - - int charOffsetX, charOffsetY; // in font texels - int charSizeX, charSizeY; // in font texels - const bool rerenderGlyphs = m_sizeBehavior == SizeBehavior::Rerender; - const Vec2i requestSize = rerenderGlyphs ? ctx.m_requestSize : CCryFont::defaultGlyphSize; - m_pFontTexture->GetTextureCoord(m_pFontTexture->GetCharSlot(ch, requestSize), texCoord, charSizeX, charSizeY, charOffsetX, charOffsetY, requestSize); - - int horizontalAdvance = m_pFontTexture->GetHorizontalAdvance(ch, requestSize); - float advance; - - if (ctx.m_proportional) - { - advance = horizontalAdvance * scaleInfo.scale.x; - } - else - { - advance = size.x * ctx.m_widthScale; - } - - Vec2 kerningOffset(Vec2_Zero); - if (ctx.m_kerningEnabled && nextCh) - { - kerningOffset = m_pFontTexture->GetKerning(ch, nextCh) * scaleInfo.scale.x; - } - - float trackingOffset = 0.0f; - if (nextCh) - { - trackingOffset = ctx.m_tracking; - } - - float px = charX + charOffsetX * scaleInfo.scale.x; // in pixels - float py = charY + charOffsetY * scaleInfo.scale.y; // in pixels - float pr = px + charSizeX * scaleInfo.scale.x; - float pb = py + charSizeY * scaleInfo.scale.y; - - // compute clipping - float newX = px; // in pixels - float newY = py; // in pixels - float newR = pr; // in pixels - float newB = pb; // in pixels - - if (ctx.m_clippingEnabled) - { - float clipX = ctx.m_clipX; - float clipY = ctx.m_clipY; - float clipR = ctx.m_clipX + ctx.m_clipWidth; - float clipB = ctx.m_clipY + ctx.m_clipHeight; - - // clip non visible - if ((px >= clipR) || (py >= clipB) || (pr < clipX) || (pb < clipY)) - { - charX += advance + kerningOffset.x + trackingOffset; - continue; - } - // clip partially visible - else - { - float width = horizontalAdvance * scaleInfo.rcpCellWidth; - if ((width <= 0.0f) || (size.y <= 0.0f)) - { - charX += advance + kerningOffset.x + trackingOffset; - continue; - } - - // clip the image to the scissor rect - newX = max(clipX, px); - newY = max(clipY, py); - newR = min(clipR, pr); - newB = min(clipB, pb); - - float rcpWidth = 1.0f / width; - float rcpHeight = 1.0f / size.y; - - float texW = texCoord[2] - texCoord[0]; - float texH = texCoord[3] - texCoord[1]; - - // clip horizontal - texCoord[0] = texCoord[0] + texW * (newX - px) * rcpWidth; - texCoord[2] = texCoord[2] + texW * (newR - pr) * rcpWidth; - - // clip vertical - texCoord[1] = texCoord[1] + texH * (newY - py) * rcpHeight; - texCoord[3] = texCoord[3] + texH * (newB - pb) * rcpHeight; - } - } - - newX += halfTexelShift; - newY += halfTexelShift; - newR += halfTexelShift; - newB += halfTexelShift; - - //int offset = vbLen * 6; - - Vec3 v0(newX, newY, z); - Vec3 v2(newR, newB, z); - Vec3 v1(v2.x, v0.y, v0.z); // to avoid float->half conversion - Vec3 v3(v0.x, v2.y, v0.z); // to avoid float->half conversion - - Vec2 tc0(texCoord[0], texCoord[1]); - Vec2 tc2(texCoord[2], texCoord[3]); - Vec2 tc1(tc2.x, tc0.y); // to avoid float->half conversion - Vec2 tc3(tc0.x, tc2.y); // to avoid float->half conversion - - uint32 packedColor = 0; - { - ColorB tempColor = color; - tempColor.a = ((uint32) tempColor.a * alphaBlend) >> 8; - packedColor = tempColor.pack_abgr8888(); - - if (!isRGB) - { - packedColor = COLCONV(packedColor); - } - } - - if (ctx.m_drawTextFlags & eDrawText_UseTransform) - { - v0 = ctx.m_transform * v0; - v2 = ctx.m_transform * v2; - v1 = ctx.m_transform * v1; - v3 = ctx.m_transform * v3; - } - - AddQuad(v0, v1, v2, v3, tc0, tc1, tc2, tc3, packedColor); - - charX += advance + kerningOffset.x + trackingOffset; - } - } -} - -CFFont::TextScaleInfoInternal CFFont::CalculateScaleInternal(const STextDrawContext& ctx) const -{ - Vec2 size = GetRestoredFontSize(ctx); // in pixel - - IRenderer* pRenderer = gEnv->pRenderer; - AZ_Assert(pRenderer, "gEnv->pRenderer is NULL"); - - if (ctx.m_sizeIn800x600) - { - pRenderer->ScaleCoord(size.x, size.y); - } - - float rcpCellWidth; - Vec2 scale; - - int fontTextureCellWidth = GetFontTexture()->GetCellWidth(); - int fontTextureCellHeight = GetFontTexture()->GetCellHeight(); - - if (ctx.m_proportional) - { - rcpCellWidth = (1.0f / static_cast(fontTextureCellWidth)) * size.x; - scale = Vec2(rcpCellWidth * ctx.m_widthScale, size.y / static_cast(fontTextureCellHeight)); - } - else - { - rcpCellWidth = size.x / 16.0f; - scale = Vec2(rcpCellWidth * ctx.m_widthScale, size.y * ctx.m_widthScale / 16.0f); - } - - return TextScaleInfoInternal(scale, rcpCellWidth); -} - -size_t CFFont::GetTextLength(const char* pStr, const bool asciiMultiLine) const -{ - size_t len = 0; - - // parse the string, ignoring control characters - const char* pChar = pStr; - while (char ch = *pChar++) - { - if ((ch & 0xC0) == 0x80) - { - continue; // Skip UTF-8 continuation bytes, we count only the first byte of a code-point - } - switch (ch) - { - case '\\': - { - if (*pChar != 'n' || !asciiMultiLine) - { - break; - } - ++pChar; - } - case '\n': - case '\r': - case '\t': - { - continue; - } - break; - case '$': - { - if (*pChar == '$') - { - ++pChar; - } - else if (*pChar) - { - ++pChar; - continue; - } - } - break; - default: - break; - } - ++len; - } - - return len; -} - -void CFFont::WrapText(string& result, float maxWidth, const char* pStr, const STextDrawContext& ctx) -{ - result = pStr; - - if (ctx.m_sizeIn800x600) - { - maxWidth = gEnv->pRenderer->ScaleCoordX(maxWidth); - } - - Vec2 strSize = GetTextSizeUInternal(result.c_str(), true, ctx); - - if (strSize.x <= maxWidth) - { - return; - } - - // Assume a given string has multiple lines of text if it's height is - // greater than the height of its font. - const bool multiLine = strSize.y > GetRestoredFontSize(ctx).y; - - int lastSpace = -1; - const char* pLastSpace = NULL; - float lastSpaceWidth = 0.0f; - - float curCharWidth = 0.0f; - float curLineWidth = 0.0f; - float biggestLineWidth = 0.0f; - float widthSum = 0.0f; - - int curChar = 0; - Unicode::CIterator pChar(result.c_str()); - while (uint32_t ch = *pChar) - { - // Dollar sign escape codes. The following scenarios can happen with dollar signs embedded in a string. - // The following character is... - // 1. ... a digit, 'O' or 'o' which indicates a color code. Both characters a skipped in the width calculation. - // 2. ... another dollar sign. Only 1 dollar sign is skipped in the width calculation. - // 3. ... anything else. The dollar sign is processed in the width calculation. - if (ctx.m_processSpecialChars && ch == '$') - { - ++pChar; - char nextChar = *pChar; - - if (isdigit(nextChar) || nextChar == 'O' || nextChar == 'o') - { - ++pChar; - continue; - } - else if (nextChar != '$') - { - --pChar; - } - } - - // get char width and sum it to the line width - // Note: This is not unicode compatible, since char-width depends on surrounding context (ie, combining diacritics etc) - char codepoint[5]; - Unicode::Convert(codepoint, ch); - curCharWidth = GetTextSizeUInternal(codepoint, true, ctx).x; - - // keep track of spaces - // they are good for splitting the string - if (ch == ' ') - { - lastSpace = curChar; - lastSpaceWidth = curLineWidth + curCharWidth; - pLastSpace = pChar.GetPosition(); - assert(*pLastSpace == ' '); - } - - bool prevCharWasNewline = false; - const bool notFirstChar = pChar.GetPosition() != result.c_str(); - if (*pChar && notFirstChar) - { - const char* pPrevCharStr = pChar.GetPosition() - 1; - prevCharWasNewline = pPrevCharStr[0] == '\n'; - } - - // if line exceed allowed width, split it - if (prevCharWasNewline || (curLineWidth + curCharWidth >= maxWidth && (*pChar))) - { - if (prevCharWasNewline) - { - // Reset the current line width to account for newline - curLineWidth = curCharWidth; - widthSum += curLineWidth; - } - else if ((lastSpace > 0) && ((curChar - lastSpace) < 16) && (curChar - lastSpace >= 0)) // 16 is the default threshold - { - *(char*)pLastSpace = '\n'; // This is safe inside UTF-8 because space is single-byte codepoint - - if (lastSpaceWidth > biggestLineWidth) - { - biggestLineWidth = lastSpaceWidth; - } - - curLineWidth = curLineWidth - lastSpaceWidth + curCharWidth; - widthSum += curLineWidth; - } - else - { - const char* pBuf = pChar.GetPosition(); - size_t bytesProcessed = pBuf - result.c_str(); - result.insert(bytesProcessed, '\n'); // Insert the newline, this invalidates the iterator - pBuf = result.c_str() + bytesProcessed; // In case reallocation occurs, we ensure we are inside the new buffer - assert(*pBuf == '\n'); - pChar.SetPosition(pBuf); // pChar once again points inside the target string, at the current character - assert(*pChar == ch); - ++pChar; - ++curChar; - - if (curLineWidth > biggestLineWidth) - { - biggestLineWidth = curLineWidth; - } - - widthSum += curLineWidth; - curLineWidth = curCharWidth; - } - - // if we don't need any more line breaks, then just stop, but for - // multiple lines we can't assume that there aren't any more - // strings to wrap, so continue - if (strSize.x - widthSum <= maxWidth && !multiLine) - { - break; - } - - lastSpaceWidth = 0; - lastSpace = 0; - } - else - { - curLineWidth += curCharWidth; - } - - ++curChar; - ++pChar; - } -} - -void CFFont::GetMemoryUsage (ICrySizer* pSizer) const -{ - pSizer->AddObject(m_name); - pSizer->AddObject(m_curPath); - pSizer->AddObject(m_pFontTexture); - pSizer->AddObject(m_pFontBuffer, m_fontBufferSize); - pSizer->AddObject(m_effects); - pSizer->AddObject(m_pDrawVB, sizeof(SVF_P3F_C4B_T2F) * MaxDrawVBQuads * 6); -} - -void CFFont::GetGradientTextureCoord(float& minU, float& minV, float& maxU, float& maxV) const -{ - const CTextureSlot* pSlot = m_pFontTexture->GetGradientSlot(); - assert(pSlot); - - float invWidth = 1.0f / (float) m_pFontTexture->GetWidth(); - float invHeight = 1.0f / (float) m_pFontTexture->GetHeight(); - - // deflate by one pixel to avoid bilinear filtering on the borders - minU = pSlot->vTexCoord[0] + invWidth; - minV = pSlot->vTexCoord[1] + invHeight; - maxU = pSlot->vTexCoord[0] + (pSlot->iCharWidth - 1) * invWidth; - maxV = pSlot->vTexCoord[1] + (pSlot->iCharHeight - 1) * invHeight; -} - -unsigned int CFFont::GetEffectId(const char* pEffectName) const -{ - if (pEffectName) - { - for (size_t i = 0, numEffects = m_effects.size(); i < numEffects; ++i) - { - if (!strcmp(m_effects[i].m_name.c_str(), pEffectName)) - { - return i; - } - } - } - - return 0; -} - -unsigned int CFFont::GetNumEffects() const -{ - return m_effects.size(); -} - -const char* CFFont::GetEffectName(unsigned int effectId) const -{ - return (effectId < m_effects.size()) ? m_effects[effectId].m_name.c_str() : nullptr; -} - -Vec2 CFFont::GetMaxEffectOffset(unsigned int effectId) const -{ - Vec2 maxOffset(0.0f, 0.0f); - - if (effectId < m_effects.size()) - { - const SEffect& fx = m_effects[effectId]; - - for (size_t i = 0, numPasses = fx.m_passes.size(); i < numPasses; ++i) - { - const SRenderingPass* pPass = &fx.m_passes[numPasses - i - 1]; - - // gather pass data - Vec2 offset = pPass->m_posOffset; - - if (maxOffset.x < offset.x) - { - maxOffset.x = offset.x; - } - - if (maxOffset.y < offset.y) - { - maxOffset.y = offset.y; - } - } - } - - return maxOffset; -} - -bool CFFont::DoesEffectHaveTransparency(unsigned int effectId) const -{ - const size_t fxSize = m_effects.size(); - const size_t fxIdx = effectId < fxSize ? effectId : 0; - const SEffect& fx = m_effects[fxIdx]; - - for (auto& pass : fx.m_passes) - { - // if the alpha is not 255 then there is transparency - if (pass.m_color.a != 255) - { - return true; - } - } - - return false; -} - -void CFFont::AddCharsToFontTexture(const char* pChars, int glyphSizeX, int glyphSizeY) -{ - AZStd::lock_guard locker(m_fontMutex); - Vec2i glyphSize(glyphSizeX, glyphSizeY); - Prepare(pChars, false, glyphSize); -} - -Vec2 CFFont::GetKerning(uint32_t leftGlyph, uint32_t rightGlyph, const STextDrawContext& ctx) const -{ - const TextScaleInfoInternal scaleInfo(CalculateScaleInternal(ctx)); - return m_pFontTexture->GetKerning(leftGlyph, rightGlyph) * scaleInfo.scale.x; -} - -float CFFont::GetAscender(const STextDrawContext& ctx) const -{ - return (ctx.m_size.y * m_pFontTexture->GetAscenderToHeightRatio()); -} - -float CFFont::GetBaseline(const STextDrawContext& ctx) const -{ - const TextScaleInfoInternal scaleInfo(CalculateScaleInternal(ctx)); - // Calculate baseline the same way as the font renderer which uses the glyph height * size ratio. - // Adding 1 because FontTexture always adds 1 to the char height in GetTextureCoord - return (round(m_pFontTexture->GetCellHeight() * GetSizeRatio()) + 1.0f) * scaleInfo.scale.y; -} - -bool CFFont::InitTexture() -{ - m_texID = gEnv->pRenderer->FontCreateTexture(m_pFontTexture->GetWidth(), m_pFontTexture->GetHeight(), (uint8*)m_pFontTexture->GetBuffer(), eTF_A8, IRenderer::FontCreateTextureGenMipsDefaultValue, m_name.c_str()); - m_textureVersion = 0; - return m_texID >= 0; -} - -bool CFFont::InitCache() -{ - m_pFontTexture->CreateGradientSlot(); - - // precache (not required but for faster printout later) - const char first = ' '; - const char last = '~'; - char buf[last - first + 2]; - char* p = buf; - - // precache all [normal] printable characters to the string (missing ones are updated on demand) - for (int i = first; i <= last; ++i) - { - *p++ = i; - } - *p = 0; - - Prepare(buf, false); - - return true; -} - -CFFont::SEffect* CFFont::AddEffect(const char* pEffectName) -{ - m_effects.push_back(SEffect(pEffectName)); - return &m_effects[m_effects.size() - 1]; -} - -CFFont::SEffect* CFFont::GetDefaultEffect() -{ - return &m_effects[0]; -} - -void CFFont::Prepare(const char* pStr, bool updateTexture, const Vec2i& glyphSize) -{ - const bool rerenderGlyphs = m_sizeBehavior == SizeBehavior::Rerender; - const Vec2i usedGlyphSize = rerenderGlyphs ? glyphSize : CCryFont::defaultGlyphSize; - bool texUpdateNeeded = m_pFontTexture->PreCacheString(pStr, nullptr, m_sizeRatio, usedGlyphSize, m_fontHintParams) == 1 || m_fontTexDirty; - if (updateTexture && texUpdateNeeded && m_texID >= 0) - { - gEnv->pRenderer->FontUpdateTexture(m_texID, 0, 0, m_pFontTexture->GetWidth(), m_pFontTexture->GetHeight(), (unsigned char*)m_pFontTexture->GetBuffer()); - m_fontTexDirty = false; - ++m_textureVersion; - - // Let any listeners know that the font texture has changed - EBUS_EVENT(FontNotificationBus, OnFontTextureUpdated, this); - } - else - { - m_fontTexDirty = texUpdateNeeded; - } -} - -Vec2 CFFont::GetRestoredFontSize(const STextDrawContext& ctx) const -{ - // Calculate the scale that we need to apply to the text size to ensure - // it's on-screen size is the same regardless of the slot scaling needed - // to fit the glyphs of the font within the font texture slots. - float restoringScale = IFFontConstants::defaultSizeRatio / m_sizeRatio; - return Vec2(ctx.m_size.x * restoringScale, ctx.m_size.y * restoringScale); -} - -#endif - diff --git a/Code/CryEngine/CryFont/FFont.h b/Code/CryEngine/CryFont/FFont.h deleted file mode 100644 index c2eddd7b1d..0000000000 --- a/Code/CryEngine/CryFont/FFont.h +++ /dev/null @@ -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 -#include -#include -#include -#include "CryFont.h" - -#include - -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 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 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; - using BeginPassFunction = AZStd::function; - - //! 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 diff --git a/Code/CryEngine/CryFont/FFontXML.cpp b/Code/CryEngine/CryFont/FFontXML.cpp deleted file mode 100644 index 1fdd84994e..0000000000 --- a/Code/CryEngine/CryFont/FFontXML.cpp +++ /dev/null @@ -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 -#include - -#if defined(WIN32) || defined(WIN64) -# include -# include -#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(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 - diff --git a/Code/CryEngine/CryFont/FontRenderer.cpp b/Code/CryEngine/CryFont/FontRenderer.cpp deleted file mode 100644 index 2cf160896b..0000000000 --- a/Code/CryEngine/CryFont/FontRenderer.cpp +++ /dev/null @@ -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 -#include -#include - -#include - -// 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(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 "" - 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(textureSlotBufferWidth, m_pGlyph->bitmap.width); - const int bufferMaxIterHeight = AZStd::GetMin(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(kerningOffsets.x / fractionalPixelUnits), azlossy_cast(kerningOffsets.y / fractionalPixelUnits)); -} - -float CFontRenderer::GetAscenderToHeightRatio() -{ - return (static_cast(m_pFace->ascender) / static_cast(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) diff --git a/Code/CryEngine/CryFont/FontRenderer.h b/Code/CryEngine/CryFont/FontRenderer.h deleted file mode 100644 index aca26a1e04..0000000000 --- a/Code/CryEngine/CryFont/FontRenderer.h +++ /dev/null @@ -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 -#pragma push_macro("generic") -#define generic GenericFromFreeTypeLibrary -#include -#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) diff --git a/Code/CryEngine/CryFont/FontTexture.cpp b/Code/CryEngine/CryFont/FontTexture.cpp deleted file mode 100644 index 8db7484d59..0000000000 --- a/Code/CryEngine/CryFont/FontTexture.cpp +++ /dev/null @@ -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 - -#ifdef WIN32 -#define WIN32_LEAN_AND_MEAN -#include -#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 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(1.0f, GetRequestSizeWidthScale(glyphSize)); - const float requestSizeHeightScale = AZ::GetMin(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(pSlot->iCharWidth * invRequestSizeWidthScale); - int iChHeight = static_cast(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(pSlot->iCharOffsetX * invRequestSizeWidthScale); - iCharOffsetY = static_cast(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(rSlot.iHoriAdvance * AZ::GetMax(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(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(iWidth + 1, m_iCellWidth); - const int blitHeight = AZ::GetMin(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) diff --git a/Code/CryEngine/CryFont/FontTexture.h b/Code/CryEngine/CryFont/FontTexture.h deleted file mode 100644 index 45d0403f47..0000000000 --- a/Code/CryEngine/CryFont/FontTexture.h +++ /dev/null @@ -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 CTextureSlotList; -typedef std::vector::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 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 Int32Pair; - typedef AZStd::pair Int32PairU32Pair; - ResultType operator()(const ArgumentType& value) const - { - // Utiliize existing hash function for pairs of ints - AZStd::hash 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 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 diff --git a/Code/CryEngine/CryFont/GlyphBitmap.cpp b/Code/CryEngine/CryFont/GlyphBitmap.cpp deleted file mode 100644 index 8ae893c317..0000000000 --- a/Code/CryEngine/CryFont/GlyphBitmap.cpp +++ /dev/null @@ -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 - - -//------------------------------------------------------------------------------------------------- -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 -//------------------------------------------------------------------------------------------------- diff --git a/Code/CryEngine/CryFont/GlyphBitmap.h b/Code/CryEngine/CryFont/GlyphBitmap.h deleted file mode 100644 index 3d04a36cf7..0000000000 --- a/Code/CryEngine/CryFont/GlyphBitmap.h +++ /dev/null @@ -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 diff --git a/Code/CryEngine/CryFont/GlyphCache.cpp b/Code/CryEngine/CryFont/GlyphCache.cpp deleted file mode 100644 index 96949009df..0000000000 --- a/Code/CryEngine/CryFont/GlyphCache.cpp +++ /dev/null @@ -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(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) diff --git a/Code/CryEngine/CryFont/GlyphCache.h b/Code/CryEngine/CryFont/GlyphCache.h deleted file mode 100644 index c0cc1db555..0000000000 --- a/Code/CryEngine/CryFont/GlyphCache.h +++ /dev/null @@ -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 -#include "GlyphBitmap.h" -#include "FontRenderer.h" -#include "CryFont.h" -#include - -//! 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 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 Int32Pair; - typedef AZStd::pair Int32PairU32Pair; - ResultType operator()(const ArgumentType& value) const - { - AZStd::hash 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 CCacheTable; - -typedef std::vector CCacheSlotList; -typedef std::vector::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 diff --git a/Code/CryEngine/CryFont/ICryFont.cpp b/Code/CryEngine/CryFont/ICryFont.cpp deleted file mode 100644 index dfbaf65335..0000000000 --- a/Code/CryEngine/CryFont/ICryFont.cpp +++ /dev/null @@ -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 -#include -#include - -#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() -{ -}; diff --git a/Code/CryEngine/CryFont/NullFont.cpp b/Code/CryEngine/CryFont/NullFont.cpp deleted file mode 100644 index bddca1bbed..0000000000 --- a/Code/CryEngine/CryFont/NullFont.cpp +++ /dev/null @@ -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 diff --git a/Code/CryEngine/CryFont/NullFont.h b/Code/CryEngine/CryFont/NullFont.h deleted file mode 100644 index 94fceeb9b0..0000000000 --- a/Code/CryEngine/CryFont/NullFont.h +++ /dev/null @@ -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 - -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 diff --git a/Code/CryEngine/CryFont/Platform/Linux/platform_linux.cmake b/Code/CryEngine/CryFont/Platform/Linux/platform_linux.cmake deleted file mode 100644 index bafe20e506..0000000000 --- a/Code/CryEngine/CryFont/Platform/Linux/platform_linux.cmake +++ /dev/null @@ -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 diff --git a/Code/CryEngine/CryFont/cryfont_files.cmake b/Code/CryEngine/CryFont/cryfont_files.cmake deleted file mode 100644 index f46a5b5b44..0000000000 --- a/Code/CryEngine/CryFont/cryfont_files.cmake +++ /dev/null @@ -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 -) diff --git a/Code/CryEngine/CryFont/resource.h b/Code/CryEngine/CryFont/resource.h deleted file mode 100644 index ed88839421..0000000000 --- a/Code/CryEngine/CryFont/resource.h +++ /dev/null @@ -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 diff --git a/Code/CryEngine/CrySystem/CMakeLists.txt b/Code/CryEngine/CrySystem/CMakeLists.txt index e7816cc1cd..1a5593e5d8 100644 --- a/Code/CryEngine/CrySystem/CMakeLists.txt +++ b/Code/CryEngine/CrySystem/CMakeLists.txt @@ -90,8 +90,6 @@ ly_add_target( AZ::AzCore Legacy::CryCommon Legacy::CryCommon.EngineSettings.Static - RUNTIME_DEPENDENCIES - Legacy::CryFont ) ################################################################################ diff --git a/Code/CryEngine/CrySystem/System.h b/Code/CryEngine/CrySystem/System.h index 47fdb362e9..e4fcc82552 100644 --- a/Code/CryEngine/CrySystem/System.h +++ b/Code/CryEngine/CrySystem/System.h @@ -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); diff --git a/Code/CryEngine/CrySystem/SystemInit.cpp b/Code/CryEngine/CrySystem/SystemInit.cpp index fcbf0b8215..d293f9ca80 100644 --- a/Code/CryEngine/CrySystem/SystemInit.cpp +++ b/Code/CryEngine/CrySystem/SystemInit.cpp @@ -43,8 +43,6 @@ #include #include -#include "CryFontBus.h" - #include #include @@ -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::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::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(maxWidth) / static_cast(displayWidth); - displayWidth *= widthScaleFactor; - displayHeight *= widthScaleFactor; - } - - const int maxHeight = m_rMaxHeight->GetIVal(); - if (maxHeight > 0 && maxHeight < displayHeight) - { - const float heightScaleFactor = static_cast(maxHeight) / static_cast(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(&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(); #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; -} diff --git a/Code/LauncherUnified/launcher_generator.cmake b/Code/LauncherUnified/launcher_generator.cmake index 08ddd538fc..28429729e1 100644 --- a/Code/LauncherUnified/launcher_generator.cmake +++ b/Code/LauncherUnified/launcher_generator.cmake @@ -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() diff --git a/Code/Sandbox/Editor/Platform/Mac/editor_mac.cmake b/Code/Sandbox/Editor/Platform/Mac/editor_mac.cmake index 484974745d..62523369e7 100644 --- a/Code/Sandbox/Editor/Platform/Mac/editor_mac.cmake +++ b/Code/Sandbox/Editor/Platform/Mac/editor_mac.cmake @@ -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 diff --git a/Code/Tools/AssetProcessor/Platform/Mac/assetprocessor_mac.cmake b/Code/Tools/AssetProcessor/Platform/Mac/assetprocessor_mac.cmake index e065f9a1a2..be1e85d370 100644 --- a/Code/Tools/AssetProcessor/Platform/Mac/assetprocessor_mac.cmake +++ b/Code/Tools/AssetProcessor/Platform/Mac/assetprocessor_mac.cmake @@ -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 diff --git a/Gems/AtomLyIntegration/AtomFont/Code/Source/AtomFontSystemComponent.cpp b/Gems/AtomLyIntegration/AtomFont/Code/Source/AtomFontSystemComponent.cpp index b1275b5b3b..dec52234bb 100644 --- a/Gems/AtomLyIntegration/AtomFont/Code/Source/AtomFontSystemComponent.cpp +++ b/Gems/AtomLyIntegration/AtomFont/Code/Source/AtomFontSystemComponent.cpp @@ -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) diff --git a/Gems/AtomLyIntegration/AtomFont/Code/Source/AtomFontSystemComponent.h b/Gems/AtomLyIntegration/AtomFont/Code/Source/AtomFontSystemComponent.h index 23ce20c307..05e30661f2 100644 --- a/Gems/AtomLyIntegration/AtomFont/Code/Source/AtomFontSystemComponent.h +++ b/Gems/AtomLyIntegration/AtomFont/Code/Source/AtomFontSystemComponent.h @@ -13,7 +13,6 @@ #include -#include #include 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; //////////////////////////////////////////////////////////////////////// };