Canvasで日本語を縦書きする方法(SS名刺メーカー)

SS名刺メーカーではCanvasという技術を使用して画像と文字を合成しています。HTML5から導入された要素で、javascriptを使ってさまざまな図形描画が可能です。

Canvasにはテキストの入力機能もあるのですが、縦書きは実装されていません。縦に文字を並べるのにはどうすればいいか、色々調べてみて、参考にしたのはこちらのコードです。

https://gist.github.com/aya-eiya/1721182

この「 2_howToWriteVerticallyToCanvas.html」をベースにしています。

ざっくり解説すると、文字列を1字ずつバラバラに分割して、1字描画するごとに文字サイズぶん座標を下にずらす、改行のときは頭に戻って1行ぶん左にずらす、という手順です。なんだか活版印刷かタイプライターみたいですよね。

しかし、これだけではきれいな縦書きにはなりません。日本語フォントは横書きと縦書きで、字形やマス目の中の位置が違うんですね。わかりやすいのはかぎ括弧や句読点ですが、ひらがなも横書きと縦書きで微妙にバランスが違ってきます。
縦書き用スタイルシートやワープロソフトなどでは、縦書きを指定することでフォントのデータから縦書き用の字形をひっぱってくるんですが、そもそもCanvasには縦書き機能がありません。どうやったら縦書き用の字形を指定できるだろう……と調べていて、行き着いたのが「フォントのサブセット化」でした。

日本語フォントファイルには膨大な数の漢字が収録されていますが、実際に使用される漢字はその一部であることがほとんどです。Web上で特定のフォントで表記するためには「Webフォント」という技術で、サーバー上にあるフォントファイルを読み込ませて描画するのですが、フォントファイルが大きすぎると文字が表示されるまでに時間がかかりすぎてしまいます。なるべく高速にフォントを表示するため、よく使う文字に限定したフォントファイルに再構成することを、フォントのサブセット化と言います。

さてここでポイントなのですが、フリーソフト「サブセットフォントメーカー(https://opentype.jp/subsetfontmk.htm)」でフォントをサブセット化する際、縦書きと横書きのどちらかを選ばなければいけません。――そう! つまり、このサブセットフォントメーカーを使えば、縦書き用と横書き用、それぞれのフォントファイルを用意できちゃうんですね。

これに気がついたときはめっちゃ自画自賛しました。だって、検索した限りどこにも情報がないんですよ、Canvasの縦書きに縦書きグリフを使う方法。かぎ括弧を回転させたり句読点の位置を調整して擬似的な縦書きを実現する方法止まりで。(まあ、単に需要がないんだと思いますが……)

実際のコードはこっちにざっくりまとめてみました。
https://qiita.com/you_fuzuki/items/c444a2d6d6be94fa8419

フォントのサブセット化、つまり文字の取捨選択にもまた悩みが色々あったのですが、それはまた別の記事にて。




おひねり投げてくださったら嬉しいです