レンダリングに使われているフォントと、ブラウザで使えるフォントを取得する
「あのdiv要素は、どのフォントでレンダリングされているの?」「どのフォントがブラウザ上で利用可能なの?」といった基本的な情報が、CSS や CSS API からは(残念ながら)取得できません。
/* 実際に使われるフォントは一体どれなの? */ font: 24pt 'メイリオ', Meiryo, 'ヒラギノ角ゴ Pro W3', 'Hiragino Kaku Gothic Pro', 'MS Pゴシック', sans-serif;
ライトなユーザには不必要な情報でも、高度なWebアプリを組もうとすると、そういったレアな情報が欲しくなったりします。
仕方が無いので、いつものようにゴニョゴニョするのです。
レンダリングで使われているフォントを取得する
やり方としては…
- window.getComputedStyle(node, null).fontFamily を取得
- IE なら node.currentStyle.fontFamily
- fontFamily の値をカンマで切断し、余計な空白を除去
- <div style="font: 72pt フォント">適当な文字列</div>を用意し、幅/高さを測定
- 72ptである必要はありませんが、できるだけ大きな値を指定します。
- 幅/高さが一致するフォントが、現在レンダリングで使われているフォント
で取れます。
uu.font.js // uu.font.detect function fontdetect(node) { // @param Node: // @return String: detected font, eg: "serif" var fam = window.getComputedStyle(node, null).fontFamily, ary = uu.split.token(fam, ","), i = -1, // カンマ区切りで切断 a, b = fontmetric("72pt " + fam); // コンテントボックスのサイズを取得 while ( (v = ary[++i]) ) { a = fontmetric("72pt " + v); if (a.w === b.w && a.h === b.h) { // サイズが一致 return v; // match } } return ""; }
このフォントは使えるの? を判別する
やり方としては…
- まず、ありえないフォントを指定して、幅/高さを測定
- 次に、検査したいフォントを指定して、幅/高さを測定
- 利用可能なフォントなら幅/高さが変化するので、調べたいフォントを順番に試す
な感じです。
uu.font.js // uu.font.able function fontable(fontName) { // @param String: font name, "Arial" // @return Boolean: true is installed var a = fontmetric("72pt dummy"), b = fontmetric("72pt " + fontName); return a.w !== b.w || a.h !== b.h; } var _metricNode, // [lazy] Measure Text Metric Node _BASE_STYLE = "position:absolute;border:0 none;margin:0;padding:0;"; // uu.font.metric - measure text rect(width, height) function fontmetric(font, // @param CSSFronString: "12pt Arial" text) { // @param String(= "aABCDEFGHIJKLMm"): // @return Hash: { w, h } if (!_metricNode) { _metricNode = doc.createElement("div"); _metricNode.style.cssText = _BASE_STYLE + "top:-10000px;left:-10000px;text-align:left;visibility:hidden"; doc.body.appendChild(_metricNode); } _metricNode.style.font = font; _metricNode[uu.gecko ? "textContent" : "innerText"] = text || "aABCDEFGHIJKLMm"; return { w: _metricNode.offsetWidth, h: _metricNode.offsetHeight }; }
です。そんなに難しくありませんね。
DEMO
# Firefox, IE, Chrome に比べ Opera や Safari では使えるフォントに制限があるようです
あ
デモは Windows で見てください。