1 // Copyright © 2008-2021 Pioneer Developers. See AUTHORS.txt for details 2 // Licensed under the terms of the GPL v3. See licenses/GPL-3.txt 3 4 #include "FontConfig.h" 5 #include "FileSystem.h" 6 #include "JsonUtils.h" 7 #include "utils.h" 8 9 namespace Text { 10 FontConfig(const std::string & name,float scaleX,float scaleY)11 FontConfig::FontConfig(const std::string &name, float scaleX, float scaleY) 12 { 13 const std::string path("fonts/" + name + ".json"); 14 Json data = JsonUtils::LoadJsonFile(path, FileSystem::gameDataFiles); 15 if (data.is_null()) { 16 Output("couldn't read font file '%s'\n", path.c_str()); 17 abort(); 18 } 19 20 m_name = data.value("name", "unknown"); 21 m_outline = data.value("outline", false); 22 23 Json faces = data.value("faces", Json::array()); 24 for (auto &i : faces) { 25 const std::string &fontFile = i.value("fontFile", ""); 26 const int pixelWidth = 1.0f / scaleX * i.value("pixelWidth", 14); 27 const int pixelHeight = 1.0f / scaleY * i.value("pixelWidth", 14); 28 const float advanceXAdjustment = i.value("advanceXAdjustment", 0.0f); 29 30 Json ranges = i.value("ranges", Json::array()); 31 if (ranges.empty()) 32 m_faces.push_back(Face(fontFile, pixelWidth, pixelHeight, advanceXAdjustment, 0x000000, 0x1fffff)); 33 else { 34 for (auto &j : ranges) { 35 Uint32 rangeMin = 0x000000, rangeMax = 0x1fffff; 36 const std::string rangeMinStr = j[0].is_string() ? j[0] : "0x000000"; 37 const std::string rangeMaxStr = j[1].is_string() ? j[1] : "0x1fffff"; 38 sscanf(rangeMinStr.c_str(), "%x", &rangeMin); 39 sscanf(rangeMaxStr.c_str(), "%x", &rangeMax); 40 m_faces.push_back(Face(fontFile, pixelWidth, pixelHeight, advanceXAdjustment, rangeMin, rangeMax)); 41 } 42 } 43 } 44 } 45 GetFaceForCodePoint(Uint32 cp)46 const FontConfig::Face &FontConfig::GetFaceForCodePoint(Uint32 cp) 47 { 48 // XXX naive. map and custom comparator would be better 49 auto best = m_faces.end(); 50 for (auto i = m_faces.begin(); i != m_faces.end(); ++i) { 51 if (cp < (*i).rangeMin || cp > (*i).rangeMax) 52 continue; 53 if (best == m_faces.end()) { 54 best = i; 55 continue; 56 } 57 if ((*i).rangeMax - (*i).rangeMin < (*best).rangeMax - (*best).rangeMin) { 58 best = i; 59 continue; 60 } 61 } 62 return *best; 63 } 64 65 } // namespace Text 66