0

有什么方法可以判断何时应用 @font-face 规则?我正在创建使用数据的@font-face 规则:使用 JavaScript 中的同步 XMLHttpRequest 请求的字体文件中的 URI,然后立即使用该字体将文本写入画布元素。问题是它在前几毫秒绘制文本时实际上并没有使用字体。我目前的解决方案是通过发送同步 XMLHttpRequest 来阻止执行几毫秒,这是一个糟糕的解决方案。

我不能让它异步,因为它是为了在 Processing.js 中实现Processing同步loadFont()功能。

我希望解决方案不检查字符的尺寸,因为不能保证字体具有某个字符,并且它的尺寸与当前字体的相同字符不同。

4

2 回答 2

1

即使您不喜欢尺寸检查,这也是Modernizr @font-face特征检测的工作方式,并且可能是最好的方法:

Modernizr 使用 data: URI 嵌入了一个微小的字体字形。在此,单“。” 性格被创造出来;然后将其应用于一个临时元素,该元素的 innerHTML 设置为 '........' 并测量其宽度,首先使用基本衬线字体,然后应用自定义字体。如果宽度不同,我们就知道浏览器渲染了我们提供的新字体数据。

于 2010-12-06T16:14:53.113 回答
1

简短的回答:浏览器还不够好,无法让我们在不实际使用字体并验证它的情况下测试“已加载并准备好使用”。

长答案: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 导致它无法使用一帧或多帧)

于 2012-10-07T02:46:16.610 回答