diff options
author | smfontes <smf@fontes.us> | 2023-03-14 13:11:15 -0400 |
---|---|---|
committer | smfontes <smf@fontes.us> | 2023-06-15 15:40:42 -0400 |
commit | 645650bd94bb24a9b4cb473028b044a43f45fa5d (patch) | |
tree | 7eb1c19cb173fd2a03562db9021e33d7ace696aa | |
parent | db30b9712e80c4fdead1cb235afdbeaeacd611c8 (diff) |
Look for <fontset> definitions in xml files in /fonts directory
Modified SettingOptionsSkinFontsFiller in addons/Skin.cpp to get the names of available fontsets from any xml files in the skin's /fonts directory, along with from the Font.xml file. Created new method in unamed namespace, GetFontsetsFromFile, to look for the names of fontsets in an xml file.
Modified LoadFonts in guilib/GUIFontManager to look for fontset definitions from any xml file in the skin's /fonts directory along with from the Font.xml file. Created new private method, LoadFontsFromFile, to load fonts from an xml file.
-rw-r--r-- | xbmc/addons/Skin.cpp | 80 | ||||
-rw-r--r-- | xbmc/guilib/GUIFontManager.cpp | 89 | ||||
-rw-r--r-- | xbmc/guilib/GUIFontManager.h | 3 |
3 files changed, 104 insertions, 68 deletions
diff --git a/xbmc/addons/Skin.cpp b/xbmc/addons/Skin.cpp index 4450a90860..220e77383d 100644 --- a/xbmc/addons/Skin.cpp +++ b/xbmc/addons/Skin.cpp @@ -488,6 +488,42 @@ void CSkinInfo::SettingOptionsSkinColorsFiller(const SettingConstPtr& setting, } } +namespace +{ +void GetFontsetsFromFile(const std::string& fontsetFilePath, + std::vector<StringSettingOption>& list, + const std::string& settingValue, + bool* currentValueSet) +{ + CXBMCTinyXML xmlDoc; + if (xmlDoc.LoadFile(fontsetFilePath)) + { + TiXmlElement* rootElement = xmlDoc.RootElement(); + g_SkinInfo->ResolveIncludes(rootElement); + if (rootElement && (rootElement->ValueStr() == "fonts")) + { + const TiXmlElement* fontsetElement = rootElement->FirstChildElement("fontset"); + while (fontsetElement) + { + const char* idAttr = fontsetElement->Attribute("id"); + const char* idLocAttr = fontsetElement->Attribute("idloc"); + if (idAttr) + { + if (idLocAttr) + list.emplace_back(g_localizeStrings.Get(atoi(idLocAttr)), idAttr); + else + list.emplace_back(idAttr, idAttr); + + if (StringUtils::EqualsNoCase(idAttr, settingValue)) + *currentValueSet = true; + } + fontsetElement = fontsetElement->NextSiblingElement("fontset"); + } + } + } +} +} // unnamed namespace + void CSkinInfo::SettingOptionsSkinFontsFiller(const SettingConstPtr& setting, std::vector<StringSettingOption>& list, std::string& current, @@ -496,44 +532,24 @@ void CSkinInfo::SettingOptionsSkinFontsFiller(const SettingConstPtr& setting, if (!g_SkinInfo) return; - std::string settingValue = std::static_pointer_cast<const CSettingString>(setting)->GetValue(); + const std::string settingValue = + std::static_pointer_cast<const CSettingString>(setting)->GetValue(); bool currentValueSet = false; - std::string strPath = g_SkinInfo->GetSkinPath("Font.xml"); - - CXBMCTinyXML xmlDoc; - if (!xmlDoc.LoadFile(strPath)) - { - CLog::Log(LOGERROR, "FillInSkinFonts: Couldn't load {}", strPath); - return; - } - - const TiXmlElement* pRootElement = xmlDoc.RootElement(); - if (!pRootElement || pRootElement->ValueStr() != "fonts") - { - CLog::Log(LOGERROR, "FillInSkinFonts: file {} doesn't start with <fonts>", strPath); - return; - } - const TiXmlElement *pChild = pRootElement->FirstChildElement("fontset"); - while (pChild) - { - const char* idAttr = pChild->Attribute("id"); - const char* idLocAttr = pChild->Attribute("idloc"); - if (idAttr != nullptr) - { - if (idLocAttr) - list.emplace_back(g_localizeStrings.Get(atoi(idLocAttr)), idAttr); - else - list.emplace_back(idAttr, idAttr); + // Look for fontsets that are defined in the skin's Font.xml file + const std::string fontsetFilePath = g_SkinInfo->GetSkinPath("Font.xml"); + GetFontsetsFromFile(fontsetFilePath, list, settingValue, ¤tValueSet); - if (StringUtils::EqualsNoCase(idAttr, settingValue)) - currentValueSet = true; - } - pChild = pChild->NextSiblingElement("fontset"); - } + // Look for additional fontsets that are defined in .xml files in the skin's fonts directory + CFileItemList xmlFileItems; + CDirectory::GetDirectory(CSpecialProtocol::TranslatePath("special://skin/fonts"), xmlFileItems, + ".xml", DIR_FLAG_DEFAULTS); + for (int i = 0; i < xmlFileItems.Size(); i++) + GetFontsetsFromFile(xmlFileItems[i]->GetPath(), list, settingValue, ¤tValueSet); if (list.empty()) { // Since no fontset is defined, there is no selection of a fontset, so disable the component + CLog::LogF(LOGERROR, "No fontsets found"); list.emplace_back(g_localizeStrings.Get(13278), ""); current = ""; currentValueSet = true; diff --git a/xbmc/guilib/GUIFontManager.cpp b/xbmc/guilib/GUIFontManager.cpp index 9cd25b2a8b..cf90147b01 100644 --- a/xbmc/guilib/GUIFontManager.cpp +++ b/xbmc/guilib/GUIFontManager.cpp @@ -15,6 +15,7 @@ #include "addons/FontResource.h" #include "addons/Skin.h" #include "addons/addoninfo/AddonType.h" +#include "filesystem/SpecialProtocol.h" #include "windowing/GraphicContext.h" #include <mutex> @@ -42,10 +43,7 @@ #include <algorithm> #include <set> -#ifdef TARGET_POSIX -#include "filesystem/SpecialProtocol.h" -#endif - +using namespace XFILE; using namespace ADDON; namespace @@ -420,50 +418,69 @@ void GUIFontManager::Clear() #endif } -void GUIFontManager::LoadFonts(const std::string& fontSet) +bool GUIFontManager::LoadFontsFromFile(const std::string& fontsetFilePath, + const std::string& fontSet, + std::string& firstFontset) { - // Get the file to load fonts from: - const std::string filePath = g_SkinInfo->GetSkinPath("Font.xml", &m_skinResolution); - CLog::LogF(LOGINFO, "Loading fonts from '{}'", filePath); - CXBMCTinyXML xmlDoc; - if (!LoadXMLData(filePath, xmlDoc)) - return; - - TiXmlElement* pRootElement = xmlDoc.RootElement(); - // Resolve includes in Font.xml - g_SkinInfo->ResolveIncludes(pRootElement); - // take note of the first font available in case we can't load the one specified - std::string firstFont; - const TiXmlElement* pChild = pRootElement->FirstChildElement("fontset"); - while (pChild) + if (LoadXMLData(fontsetFilePath, xmlDoc)) { - const char* idAttr = pChild->Attribute("id"); - if (idAttr) + TiXmlElement* rootElement = xmlDoc.RootElement(); + g_SkinInfo->ResolveIncludes(rootElement); + const TiXmlElement* fontsetElement = rootElement->FirstChildElement("fontset"); + while (fontsetElement) { - if (firstFont.empty()) - firstFont = idAttr; - - if (StringUtils::EqualsNoCase(fontSet, idAttr)) + const char* idAttr = fontsetElement->Attribute("id"); + if (idAttr) { - LoadFonts(pChild->FirstChild("font")); - return; + // Take note of the first fontset available in case we can't load the fontset requested + if (firstFontset.empty()) + firstFontset = idAttr; + + if (StringUtils::EqualsNoCase(fontSet, idAttr)) + { + // Found the requested fontset, so load the fonts and return + CLog::LogF(LOGINFO, "Loading <fontset> with name '{}' from '{}'", fontSet, + fontsetFilePath); + LoadFonts(fontsetElement->FirstChild("font")); + return true; + } } + fontsetElement = fontsetElement->NextSiblingElement("fontset"); } - pChild = pChild->NextSiblingElement("fontset"); } + return false; +} + +void GUIFontManager::LoadFonts(const std::string& fontSet) +{ + std::string firstFontset; + // Try to load the fontset from Font.xml + const std::string fontsetFilePath = g_SkinInfo->GetSkinPath("Font.xml", &m_skinResolution); + if (LoadFontsFromFile(fontsetFilePath, fontSet, firstFontset)) + return; + + // If we got here, then the requested fontset was not found in the skin's Font.xml file + // Look at additional fontsets that are defined in .xml files in the skin's fonts directory + CFileItemList xmlFileItems; + CDirectory::GetDirectory(CSpecialProtocol::TranslatePath("special://skin/fonts"), xmlFileItems, + ".xml", DIR_FLAG_BYPASS_CACHE); + for (int i = 0; i < xmlFileItems.Size(); i++) + if (LoadFontsFromFile(xmlFileItems[i]->GetPath(), fontSet, firstFontset)) + return; - // no fontset was loaded, try the first - if (!firstFont.empty()) + // Requested fontset was not found, try the first + if (!firstFontset.empty()) { - CLog::Log(LOGWARNING, - "GUIFontManager::{}: File doesn't have <fontset> with name '{}', defaulting to first " - "fontset", - __func__, fontSet); - LoadFonts(firstFont); + CLog::LogF(LOGWARNING, + "Fontset with name '{}' was not found, " + "defaulting to first fontset '{}' ", + fontSet, firstFontset); + LoadFonts(firstFontset); } else - CLog::LogF(LOGERROR, "File '{}' doesn't have a valid <fontset>", filePath); + CLog::LogF(LOGERROR, "No valid <fontset> found in '{}' or in xml files in fonts directory", + fontsetFilePath); } void GUIFontManager::LoadFonts(const TiXmlNode* fontNode) diff --git a/xbmc/guilib/GUIFontManager.h b/xbmc/guilib/GUIFontManager.h index 5923517059..16924a7cbd 100644 --- a/xbmc/guilib/GUIFontManager.h +++ b/xbmc/guilib/GUIFontManager.h @@ -127,6 +127,9 @@ protected: private: void LoadUserFonts(); + bool LoadFontsFromFile(const std::string& fontsetFilePath, + const std::string& fontSet, + std::string& firstFontset); mutable CCriticalSection m_critSection; std::vector<FontMetadata> m_userFontsCache; |