JavaScript
Electron
ElectronDay 12

Electronでフォント選択を実現する

More than 1 year has passed since last update.

Electron Advent Calendar 2015 - Qiitaの12日目ですが一日遅れでの投稿になります。

さて、Electronの記事なんですが、webviewを使ってgmail clientを書く話にしようかとも思ったのですが、あまりにもまとまらなかったのでフォント選択の話にしようかと思います。

最近はElectron製のアプリも増えてきましたが、僕は一つ不満を持っています。それはElectron自体がフォント選択ダイアログを持っていないためか、どのアプリもフォント選択機能がなく、せいぜいが直接フォント名を設定ファイルに書くという仕組みになっていることです。Atom, VSCodeなんかもそのパターンですね。

さて、システムフォントの一覧及びそのフォントの情報を取得する方法はあるでしょうか?標準ではありませんがfont-managerを使えば可能になります。

$ npm i font-manager --save

このfont-managerはOSごとにシステムのフォントインターフェースを叩いていい感じにフォント情報を取得してくれるます。今回の目的だとgetAvailableFonts()findFonts({})のどちらかを叩くことになるのですが、前者ならば全フォント、後者なら{}の中で指定した条件にマッチするフォントが配列として帰ってきます。たとえばfindFonts({monospace: true})で固定幅フォントだけをピックアップできます。

var fonts = fontManager.findFontsSync({ family: 'Arial' });

// output 

[ { path: '/Library/Fonts/Arial.ttf',
postscriptName: 'ArialMT',
family: 'Arial',
style: 'Regular',
weight: 400,
width: 5,
italic: false,
monospace: false },
{ path: '/Library/Fonts/Arial Bold.ttf',
postscriptName: 'Arial-BoldMT',
family: 'Arial',
style: 'Bold',
weight: 700,
width: 5,
italic: false,
monospace: false } ]

これは公式ページにあるサンプルコードです。APIの後ろにSyncが付いているものは同期バージョンです。通常版はコールバックを指定することになります。CSSのfont-familyには、この情報のうちfamilyもしくはpostscriptNameを指定することができます。ArialMTとArial-BoldMTを見ればわかる通り、postscriptNameにはフォントのスタイル情報が含まれています。

考え方次第ですが、フォント名の指定にスタイル情報を含めてもかまわないのであれば、postscriptNameをキーにして扱えばいいと思います。ただ、この場合、たとえばfont-weightなどの指定が無意味になったりします。あと純粋なフォントファミリーに比べてフォント名が圧倒的に増えてしまいます。

いいやり方としては、取得したフォント配列のfamilyプロパティに着目し、新しいMapを構築するとよいでしょう。そうすればフォントファミリーごとにまとまったものになります。Mapの中身は使用したい情報に応じてさらにstyleをキーにしたMapにするのも手でしょう。

実のところは、familyかせいぜいpostscriptName位しか役に立たない気もします。これ以上の情報を調べる方法はfontkitなどがありますがぱっと見た感じでは使える情報を見つけられませんでした。

フォントには、対応してる文字種(日本語いける?とか)も入ってるはずですし、システムのフォント選択では「ほげゴチック」のような日本語でのフォント名称がでてくるので、そういった情報も取得できるはずです。僕的には前者はまぁ別に興味だけの話だったのでいいんですが、せめて後者、日本語でのフォント名称は取得したかったところです。方法をご存じの方教えてください。

サンプルを erukiti/electron-font-setting-test においてあります。

Electronアプリにフォント選択機能が増えることを願っております。それではごきげんよう。