1

特定の文字が指定されたスタイルのフォントで表示されているのか、システムのデフォルトのフォントで表示されているのかをチェックするツールをまとめようとしています。私の最終的な目標は、少なくとも最新の(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;
}
4

1 に答える 1

2

質問を正しく理解しています。問題は、1つのキャンバスがArialを指定している(ただし、Serifにフォールバックしている)ことと、もう1つがSerifであり、ピクセルマッチングを実行すると、一方がわずかにオフセットされているため、一致しませんか?

1つの提案は、各キャンバスから参照ピクセルを取得し、2つの参照ピクセルの位置を比較してオフセットを取得することです。次に、そのオフセットを比較ループに織り込みます。

たとえば、この場合、1つのキャンバスの左上隅からピクセルをチェックし始め、その列を下にスキャンし、下部に到達したら、次の列の上部に戻ってスキャンダウンすることで、参照ピクセルを取得できます。 。

背景の色ではないピクセルに当たったらすぐに、位置を記録し、それを参照ピクセルとして使用します。それがフォントの端になります。次のキャンバスでも同じことを行い、2つの参照ピクセルの位置を比較してオフセットを取得します。比較ループでは、そのオフセットを考慮に入れてください。

私が問題について正しい考えを持っていることを願っています、そしてそれが役立つことを願っています!

于 2011-10-21T12:28:33.487 に答える