特定の文字が指定されたスタイルのフォントで表示されているのか、システムのデフォルトのフォントで表示されているのかをチェックするツールをまとめようとしています。私の最終的な目標は、少なくとも最新の(IE8 +を読む)ブラウザーで、特定のフォントでリガチャーがサポートされているかどうかを確認できるようにすることです。
同じ合字(この場合はst)を表示する2つのキャンバスがあります。それらのキャンバスをデータに変換し、それらを比較して、文字が一致するかどうかを確認します。
Arial(ほとんどのフォントと同様)には合字がないため、デフォルトのセリフフォントにフォールバックします。ここが奇妙なところです。同じフォントを表示していますが、2つのキャンバスには同じデータがありません。
なんで?キャンバス上のそれらの位置は完全に同じではないからです。フォントの相対的な高さの違いに関係していると思います(一方はもう一方より少し高いですが、フォントごとに異なります)。違いは1ピクセルか2ピクセルのようで、フォントごとに異なります。
これをどのように解決することができますか?私の現在の唯一のアイデアは、フォントの高さを測定し、それに応じてその位置を調整する方法を見つけることですが、残念ながら、それを行う方法がわかりません。2つの画像を同一にするために私が取るかもしれない他のアプローチはありますか?
以下のコードを見ることができます。両方のキャンバスが正常に初期化され、要素の本体に追加されているため、何が起こっているかを視覚的に確認できます(ただし、実際に作業しているスクリプトでは必要ありません)。初期化とコンテキストはすべて正常に機能しているため、削除しました。
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;
}