25std::string extensionOf(
const std::string &path) {
26 const auto pos = path.find_last_of(
'.');
27 if (
pos == std::string::npos)
return {};
28 std::string ext = path.substr(
pos);
29 for (
char &
c : ext)
c = static_cast<char>(std::tolower(static_cast<unsigned char>(
c)));
33bool isFontPath(
const std::string &path) {
34 const std::string ext = extensionOf(path);
35 return ext ==
".ttf" || ext ==
".otf" || ext ==
".ttc";
38int queryInt(
const std::string &key,
const std::string &
name,
int fallback) {
39 const auto q = key.find(
'?');
40 if (q == std::string::npos)
return fallback;
42 std::string rest = key.substr(q + 1);
44 while (
pos < rest.size()) {
45 const size_t amp = rest.find(
'&',
pos);
46 const std::string pair =
47 rest.substr(
pos, amp == std::string::npos ? std::string::npos : amp -
pos);
48 const auto eq = pair.find(
'=');
49 if (eq != std::string::npos && pair.substr(0, eq) ==
name)
50 return std::atoi(pair.c_str() + eq + 1);
51 if (amp == std::string::npos)
break;
59 const char *reloadKind()
const override {
return "font"; }
61 bool handlesPath(
const std::string &normPath)
const override {
67 if (!isFontPath(path))
return nullptr;
68 const int size = queryInt(key,
"size", 16);
70 auto *fs = filesystem::Filesystem::create();
71 if (!fs)
return nullptr;
72 std::unique_ptr<filesystem::FileData> fd(fs->read(path));
73 if (!fd || fd->getData() ==
nullptr || fd->getSize() == 0)
74 throw eve::Exception(
"Could not read font file: %s", path.c_str());
76 auto *mod = Font::create();
78 return mod->newFontData(fd.get(), size);
84 static FontLoader loader;
static std::string pathOfKey(const std::string &key)
The path part of a cache key (everything before the first '?').
Resource is a game object that is managed by the ResourceManager. It can be loaded from a file or gen...