javascript - 比较 HTML5 Canvas 中的两种字体

标签 javascript html canvas fonts ligature

我正在尝试组装一个工具来检查给定字符是以指定样式字体还是以系统默认字体显示。我的最终目标是至少在现代(阅读:IE8+)浏览器中能够检查给定字体是否支持连字。

我有两个 Canvas 显示相同的连字(在本例中为 st)。我将这些 Canvas 转换为数据并比较它们以查看字符是否匹配。

Arial(与大多数字体一样)没有 st 连字,因此它会退回到默认的衬线字体。这就是奇怪的地方:虽然它们显示相同的字体,但两个 Canvas 没有相同的数据

为什么?因为它们在 Canvas 上的位置并不完全相同。我猜这与字体的不同相对高度有关(一个比另一个略高,尽管字体因字体而异)。差异似乎只有一两个像素,并且因字体而异。

如何解决这个问题?我目前唯一的想法是找到一种方法来测量字体的高度并相应地调整其位置,但不幸的是我不知道该怎么做。我是否可以采取其他方法使两张图片完全相同?

你可以看到下面的代码。两个 Canvas 都已成功初始化并附加到元素的主体,因此我可以直观地看到发生了什么(尽管在我正在处理的实际脚本中这不是必需的)。我已经删除了初始化和上下文,因为它们都工作得很好。

function checkLig() {

   lig = 'fb06'   // this is the unicode for the st ligature

   canvas0.width = 250;
   canvas0.height = 50;
   context0.fillStyle = 'rgb(0, 0, 0)';
   context0.textBaseline = 'top';
   context0.font = 'normal normal normal 40px Arial';
   context0.fillText(String.fromCharCode(parseInt(lig, 16)), 0, 0);
   var print0 = context0.getImageData(0, 0, 720, 50).data;

   canvas1.width = 250;
   canvas1.height = 50;
   context1.fillStyle = 'rgb(0, 0, 0)';
   context1.textBaseline = 'top';
   context1.font = 'normal normal normal 40px serif';
   context1.fillText(String.fromCharCode(parseInt(lig, 16)), 0, 0);
   var print1 = context1.getImageData(0, 0, 720, 50).data;

   var i = 0, same = true, len = 720 * 50 * 4;
   while (i < len && same === true) {
      if (print0[i] !== print1[i]) {
         same = false;
      }
      else {
         i++;
      }
   }

   return same;
}

最佳答案

所以我正确地理解了这个问题,问题是一个 Canvas 指定了 Arial(但回落到 Serif),另一个是 Serif,当你进行像素匹配时,它不匹配,因为其中一个有轻微的偏移量?

一个建议是从每个 Canvas 上抓取一个引用像素并比较两个引用像素的位置以获得偏移量。然后将该偏移量计入您的比较循环。

例如,在这种情况下,您可以通过从一个 Canvas 的左上角开始检查像素并向下扫描该列来获取引用像素,当您到达底部时,返回到下一列的顶部并向下扫描。

一旦您碰到一个不是背景颜色的像素,请记录该位置并将其用作您的引用像素。那应该是你字体的边缘。 对下一个 Canvas 执行相同操作,然后比较两个引用像素的位置以获得偏移量。在比较循环中考虑该偏移量。

希望我对问题的理解是正确的,希望对您有所帮助!

关于javascript - 比较 HTML5 Canvas 中的两种字体,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7844491/

相关文章:

javascript 动态生成的表与 onclick 事件无法正常工作

javascript - 将事件处理程序附加到 DOM 元素

javascript - Processing.js 不允许在 Firefox 中绑定(bind)外部 javascript

php - 如何将动态生成的图像保存到数据库

javascript - HTML5 Canvas 和鼠标事件问题

javascript - Internet Explorer 10 - jQuery 单击选择选项不起作用

javascript - 如何在不使用任何 Javascript 框架的情况下实现 MV* 架构?

javascript - 使用javascript调整html5 Canvas 大小(未达到预期结果)

javascript - 当鼠标悬停在另一个元素上时,使用 jQuery 为一个元素分配一个类

java - 将数组列表中的文本放在单独的行中