载入中...
搜索中...
未找到
FontLoader.cpp
浏览该文件的文档.
1// Loads FontData through the unified resource cache (common/Resource.h).
2//
3// The cache key carries the pixel size ("fonts/a.ttf?size=16"), so the same
4// file at two sizes is two distinct cached resources, while repeated loads at
5// one size share a single decoded face.
6
8#include "common/Capability.h"
9#include "common/Exception.h"
10#include "common/Module.h"
11#include "common/Resource.h"
12#include "filesystem/FileData.h"
14#include "font/Font.h"
15#include "font/FontData.h"
16
17#include <cctype>
18#include <cstdlib>
19#include <memory>
20#include <string>
21
22namespace eve::font {
23namespace {
24
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)));
30 return ext;
31}
32
33bool isFontPath(const std::string &path) {
34 const std::string ext = extensionOf(path);
35 return ext == ".ttf" || ext == ".otf" || ext == ".ttc";
36}
37
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;
41
42 std::string rest = key.substr(q + 1);
43 size_t pos = 0;
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;
52 pos = amp + 1;
53 }
54 return fallback;
55}
56
57class FontLoader : public eve::caps::IAssetReloader {
58public:
59 const char *reloadKind() const override { return "font"; }
60
61 bool handlesPath(const std::string &normPath) const override {
62 return isFontPath(eve::ResourceManager::pathOfKey(normPath));
63 }
64
65 eve::Resource *load(const std::string &key) override {
66 const std::string path = eve::ResourceManager::pathOfKey(key);
67 if (!isFontPath(path)) return nullptr;
68 const int size = queryInt(key, "size", 16);
69
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());
75
76 auto *mod = Font::create();
77 if (!mod) throw eve::Exception("eve::font module is not loaded");
78 return mod->newFontData(fd.get(), size);
79 }
80};
81
82struct Register {
83 Register() {
84 static FontLoader loader;
86 }
87} g_register;
88
89} // namespace
90} // namespace eve::font
uint32_t c
const char * name
Definition RockMesh.cpp:21
static std::string pathOfKey(const std::string &key)
The path part of a cache key (everything before the first '?').
Definition Resource.cpp:39
Resource is a game object that is managed by the ResourceManager. It can be loaded from a file or gen...
Definition Resource.h:35
I * query()
Definition Capability.h:77