rust - 创建全局字体缓存
问题描述
我正在使用rustybuzz和wasm-bindgen在 HTML5 画布上排版文本。我想创建一个由String
s 索引的全局字体缓存,这样我就可以加载和解析字体文件一次,然后多次重用它们(提示关于全局变量如何不好的评论......如果有人有更好的方法来做这个,请告诉我)。具体来说,我想要一些HashMap<String, rustybuzz::Face>
我可以在任何地方访问的变体。然后,我想向register_font
JavaScript 端公开一个函数,以便可以加载ArrayBuffers
,例如:
#[wasm_bindgen]
pub fn register_font(name: &str, font_data: &[u8]) {
MY_FONT_CACHE_SOMEHOW.insert(
name.to_string(),
rustybuzz::Face::from_slice(&font_data, 0).unwrap()
);
}
而且,为了完成,我想要一个内部get_font
函数来检索:
fn get_font(name: &String) -> rustybuzz::Face {
MY_FONT_CACHE_SOMEHOW.get(name).unwrap()
}
我知道我有可变生命周期的问题,我只是不知道如何解决它们。该rustybuzz::Face
结构仅引用其内部数据,它不拥有它。wasm-bindgen
不支持将函数上的传入ArrayBuffer
/标记为,这似乎是主要问题之一。但我对这整个生锈的事情很陌生。任何人都知道如何做到这一点(或更好的方法来做到这一点)?[u8]
register_font
'static
解决方案
如果您只添加到哈希表并且从不删除,您可以复制和泄漏 font_data 以使其成为静态:
#[wasm_bindgen]
pub fn register_font(name: &str, font_data: &[u8]) {
let font_data: &'static [u8] = font_data.to_owned().leak();
//...
}
如果您希望能够从缓存中删除字体,则必须将font_data
和保持Face
在一起。这就是臭名昭著的问题self-referential type
。
您可以采用不安全的方式并保留指向动态分配*const [u8]
类型的指针,或者您可以使用许多试图解决此问题的 crate 之一。
目前我最喜欢的是ouroboros
:它会是这样的(未经测试):
#[self_referencing]
struct MyFace {
font_data: Vec<u8>,
#[borrows(font_data)]
face: Face<'this>,
}
#[wasm_bindgen]
pub fn register_font(name: &str, font_data: &[u8]) {
let face = MyFaceBuilder {
font_data: font_data.to_owned(),
face_builder: |font_data: &[u8]| Face::from_slice(font_data).unwrap(),
}.build();
MY_FONT_CACHE_SOMEHOW.insert(
name.to_string(),
face,
);
}
推荐阅读
- deep-learning - 在哪里可以找到基于深度学习的预测模型
- npm - 将 NPM 包发布到 Azure Artifacts,但在安装时出现此错误
- openbmc - 使用 Romulus 的 IPMI 工具
- c - for循环条件递增
- javascript - Vue - 安装后访问子组件默认道具
- python - 如何将图像的轮廓保存为另一张图像?
- python - 如何创建使用 pybind 创建的 python 包?
- react-native - 如何使用酶玩笑在本机反应中编写导航堆栈的单元测试用例?
- python - 使用 Django-q 的 Django 计划任务
- google-sheets - 谷歌电子表格 - If() SUM