テキストとフォントファイルを与えると、テキストの形をsvgで表現した出力が出てくる夢を見たことがありますよね?
作りました。
$ text2svg "Hello, World\!" --font="/Library/Fonts/Times New Roman.ttf" > test.svg $ open test.svg -a /Applications/Google\ Chrome.app
な感じで試すことができます。
freetypeを使っているのでこちらのインストールが事前に必要です。
$ brew install freetype
svgでは、<text>
タグで文字を表現するのが普通ですが、表現したいフォントが決まっている場合フォントファイルのダウンロードを必要とします。
テキストの外形をsvgのpathにして<path>
タグで表現することができれば、
サーバーでsvgファイルを生成してクライアントにフォントファイルをダウンロードさせること無しに文字を表現できます。
文字の並びやtext-align、改行やkerningにも自前で対応していて、
imagemagickなどで画像化した場合と遜色ない文字並びで扱うことができます。
(上がtext2svgで作ったsvg、下がimagemagickで作ったpng画像)
実装
freetypeのAPIをffi経由で呼ぶgemも作りました。
freetypeはフォントファイルを扱うCのライブラリーで、文字の外形pathやbitmap化なんかができます。
https://ja.wikipedia.org/wiki/FreeType
ffiはCと他言語の間をとりもつやつ。
https://ja.wikipedia.org/wiki/Foreign_function_interface
TrueTypeだけならttfunkを使えばなんとか外形を取ることができますが、
.otf
なPostScriptフォントに対応していません。
freetypeであればTrueTypeとPostScriptフォント両方の形式を同じAPIで扱うことができます。
今回はじめてffiで書いてみたけど、 コンパイル無しで(ffiはコンパイルいる)CのAPIが呼べるのはよさげでした。
しかしながらStructの構成は自動でできてくれたらなあという感じ。
ffiは初めてなのでまだまだ至らぬ点もあるのかもしれないです。
ちなみにテストはRubyKaigiのLTで話したrgotを使っています。 メソッド一つづつテストするというよりは、ストーリー仕立てでテストするのに向いている気がする。
注意
フォントのSVGを公開してもいいかどうかはフォントの規約に依存します。 作成したSVGを公開する際は、フォントの規約にご注意ください。