简短的回答:浏览器还不够好,无法让我们在不实际使用字体并验证它的情况下测试“已加载并准备好使用”。
长答案:Pjs 带有用于字体预加载的内置字体验证器(与https://github.com/pomax/font.js相关),但正如您指出的那样,这不适用于使用 @font-face 的规则数据-uri。我建议的一种解决方法(尽管我还没有尝试过。我只是猜测它会根据我在 Processing.js 上的工作和浏览器中的字体加载工作)是使用两个 PGraphic 屏幕外缓冲区。使它们都带有黑色填充文本的白色背景,在第一个缓冲区上执行 text("X",0,0),然后在字体加载后,使用第二个缓冲区执行相同的 text("X",0, 0")。获取每个缓冲区的像素[],并进行并排比较:
boolean verifyFontLoad() {
buffer1.loadPixels();
buffer2.loadPixels();
for (int i=0; i<buffer1.pixels.length; i++) {
if (buffer1.pixels[i] != buffer2.pixels[i]) {
return false; }}
return true;
}
当您加载字体时,在某处有一个跟踪布尔值,指示字体加载状态,初始化为“false”,加载字体后,在 draw() 调用开始时
void draw() {
// code that does not rely on your font
[...]
// check state
if(!fontLoaded) { fontLoaded = verifyFontLoaded(); }
// not ready? "stop" drawing.
if(!fontLoaded) { return; }
// font ready. run code that relies on the font being ready
else {
// code that depends on your font being available goes here.
}
}
现在,至少您可以避免浏览器完成解压缩 data-uri 字体并将其加载为 @font-face 资源的前几帧,但还没有时间将其传递给 Canvas2D 渲染系统。
(此时使用字体为 DOM 元素设置样式实际上可以正常工作,实际上是将其移交给 Canvas2D 导致它无法使用一帧或多帧)