载入中...
搜索中...
未找到
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
70 eve::Result<bool> reload(const std::string &) override { return eve::Result<bool>::success(false); }
71
72 eve::Resource *load(const std::string &key) override {
73 const std::string path = eve::ResourceManager::pathOfKey(key);
74 if (!isFontPath(path)) return nullptr;
75 const int size = queryInt(key, "size", 16);
76
77 auto *fs = filesystem::Filesystem::create();
78 if (!fs) return nullptr;
79 std::unique_ptr<filesystem::FileData> fd(fs->read(path));
80 if (!fd || fd->getData() == nullptr || fd->getSize() == 0)
81 throw eve::Exception("Could not read font file: %s", path.c_str());
82
83 auto *mod = Font::create();
84 if (!mod) throw eve::Exception("eve::font module is not loaded");
85 return mod->newFontData(fd.get(), size);
86 }
87};
88
89struct Register {
90 Register() {
91 static FontLoader loader;
92 eve::cap::addListener<eve::caps::IAssetReloader>(&loader, eve::caps::IAssetReloader::kCache);
93 }
94} g_register;
95
96} // namespace
97} // namespace eve::font
std::uint32_t key
std::array< double, 10 > q
std::int32_t c
std::string name
std::string path
Definition PlayHost.cpp:110
float size
Definition TreeMesh.cpp:156
EVENGINE_API_FOUNDATION public API.
Definition Exception.h:13
static std::string pathOfKey(const std::string &key)
The path part of a cache key (everything before the first '?').
Definition Resource.cpp:46
Resource is a game object that is managed by the ResourceManager. It can be loaded from a file or gen...
Definition Resource.h:51
Move-only operation result carrying either a value or Status.
Definition Result.h:155
static Result success(T value)
Construct a successful result owning value.
Definition Result.h:164
EVENGINE_API_FOUNDATION public API.