しろもじメモランダム

文字についてあれこれと。

フォントまわりのツールの探し方

Twitter 上でとある鍵アカ氏が「このツール知らなかった! 使ってみたらべんり! 楽しい!」的なことをつぶやいていました。フォントの世界にはお役立ちツールがいろいろとあるのですが、日本語での情報が少ないこともあり、とっかかりが難しいかもしれません。そこでこの記事では、「ツールを探すならまずはここから」という定番の情報源を3つ紹介しておきます。

1. awesome-typography

github.com

フォント関連のさまざまなツールがリストアップされたリンク集です。ツールだけでなく、オープンソースのフォントや、フォント関連のドキュメントなども一緒に挙げられています。

プログラミング言語別に並んでおり、ごく簡単な説明もついていますので、「この言語でうまいことあれをやってくれるツールないかなー?」というときには真っ先にチェックすべきページです。

2. 技術カンファレンスの動画

フォント関係のカンファレンスというと ATypI が有名ですが、TYPO LabsRobothon のように、技術的側面に特化したカンファレンスも開催されています。定番ツールから尖ったツールまで、作者の解説や実演デモをじっくり見ることができます。以下のように動画が公開されており、カンファレンスに行かずとも視聴できるのが嬉しいところです。

3. TypeDrawers

TypeDrawers は、書体制作やレタリング、タイポグラフィに関する掲示板です。プロの書体デザイナーや開発者が多く、活発な議論がなされています。いくつかのカテゴリーに分かれていますが、ツールの話題を探すのであれば、下の2つがメインになるでしょう。

いろいろなスレッドが立ちますので、全部追いかけようとすると大変かもしれませんが、最新の動向や界隈の評判などをチェックすることができます。フォント界の Stack Overflow のような存在です。アカウント登録をして、やりとりに参加するのも良いかもしれません。

その先へ

以上、3つのソースをさらっと紹介しました。気になるツールや愛用のツールが出てきたら、そのツールのリポジトリ/フォーラムを覗いたり、作者の Twitter をフォローしたりすると、芋づる式に世界が広がっていきます。巨人の肩の上に乗って満喫しましょう。

追記:OpenType の仕様に興味が出てきたら以下の記事もどうぞ。

タイププロジェクト株式会社を退職しました

2018年7月10日付けでタイププロジェクト株式会社を退職しました。

大学在学中の2012年8月からタイププロジェクトの仕事をするようになり、その後タイプエンジニア(フォントエンジニア)として2015年4月に入社しました。あわせると、6年近くにわたってお世話になったことになります。

タイププロジェクトがコンパクトなチームだったこともあり、製品版フォントのプロダクション、フォーマット変換やカスタマイズ、内製ツールの開発、制作ワークフローの自動化・省力化、イントラの管理などなど、とにかくいろいろなことに携わることができました。仕事を始めた当初はほとんど何もわかっていなかったのですが*1、おかげさまで随分いろいろなことができるようになり、自信もつきました。フォントへの興味がますます深まったのは、言うまでもありません。

タイププロジェクトに参加するまであまり想像していなかったのですが、実際の仕事では、タイプデザイナーなど他のメンバーとのコミュニケーションが頻繁に発生します。「こういう機能がほしい」「こんな感じならできるけど」とやりとりしながら開発を進めていく過程は、なかなか楽しいものでした。まわりの方が協力的で、この点において恵まれた環境だったと感じます。

ちなみに、明日からは別の会社にフロントエンドエンジニアとして入社します。文字関係の仕事ではありません。エンジニアとしてあらためて基礎固めを行い、実践的なチーム開発のスキルを身につけることができれば、と考えています。

仕事としては文字から離れることになりますが、あいかわらず興味は尽きませんので、これからもこのまま趣味として続けていきたいと思います。今後ともどうぞよろしくお願いいたします。

*1:Python を身に着けたのも実はこのときです。

Python パッケージとして再構成された AFDKO 2.7 がリリース

AFDKO の新バージョン 2.7.0 が先週リリースされました。AFDKO は、フォント開発のための Adobeコマンドラインツール集です。

github.com

Python パッケージ化

今回の大きな変更点は、AFDKO の中身がひとつの Python パッケージへと、がらっと再構成された点です。

The AFDKO has been restructured so that it can be installed as a Python package. It now depends on the user's Python interpreter, and no longer contains its own Python interpreter.

https://github.com/adobe-type-tools/afdko/tree/2.7.0#major-changes

すでに PyPIafdko パッケージがアップロードされていますので、普段の Python パッケージと同じく、以下のコマンドでインストールすることができます。

$ pip install afdko

従来(2.5 まで)の AFDKO は、スクリプトやバイナリ等が Python インタプリタとともに ZIP で固められて配布されており、AFDKO 中の Python スクリプトは、必ずこのインタプリタを使って実行されるようになっていました。また、これを実現するためにインストール方法やパスの管理が独自のものになっており、少々扱いづらい面がありました。

Python パッケージへの再構成作業は2017年末ごろからスタートし、ベータ期間(2.6 がこれに相当)を経て、今回の 2.7.0 をもってめでたく正式リリースとなったようです。この Python パッケージ化によって、以下のようなメリットが享受できそうです。

  • インストール/アンインストール/更新が、おなじみの pip で行えるようになる
  • バージョンの固定や切り替えが容易になる
  • 他の Python パッケージと組み合わせて使いやすくなる
  • パッケージのビルド方法やテスト方法が整備・明文化される

AFDKO 開発の盛り上がり

AFDKO の開発は、Adobe のエンジニアが中心となって進められていますが、昨年まではあまり活発には見えませんでした。バリアブルフォントへの対応などは進められていたようですが、発展著しい fontTools などと比べてしまうと、地味な印象がありました。また、AFDKO には

  • コードの可読性が低い
  • テストがほどんどない
  • 古い C のコードが多い
  • バグ報告やプルリクエストがなかなか対応されない
  • バグがあっても自分では直しにくい
  • Python 2

などのつらい面も多々あり、個人的にはここ数年、fontTools の方を利用する機会が圧倒的に多くなっていました。

しかしながら、昨秋ごろから開発が加速し、現在に至るまで活発な状態が続いています。

内容としては、コードのリファクタリングやテスト・CIの整備といった基礎的な部分の改善が大きくなっており、前述の Python パッケージ化も、その流れの中で実施されたように見えます。Python 3 をサポートするための作業も始まり、明るい未来が見えてきた感じがします。

期待を込めつつ、これからも引き続き AFDKO の動きに注目していこうと思います。

fontTools のペンを使ってグリフのアウトラインを取得する

先日 Twitter で、「グリフのアウトラインの座標列を取りたいんだけど」「それ pen protocol でできるよ!」というやりとりをしました。この記事では、pen protocol に対応したペンでアウトラインを取得する方法について、具体的に解説してみます。

pen protocol とペン

さて、そもそも pen protocol とは何でしょう? 今回はプロトコルの詳細には触れず、概観だけ説明します。

フォント界隈では Python が共通言語になっています。しかし、グリフを表すためのオブジェクトは、フォントエディタ(Glyphs, RoboFont, FontLab, ...)やライブラリ(fontTools, ufoLib, defcon, fontParts, ...)ごとにそれぞれ独自に定義されています。ざっくり言ってしまうと、「どんなグリフオブジェクトであれ、共通のインターフェイスでアウトラインを読み書きできると楽だよね」「SVG や PDF やいろんな描画 API にも対応したいよね」というのが pen protocol の発想です。pen protocol によってグリフからアウトラインを得たり、アウトラインを描いたりするためのオブジェクトをペン(pen)と呼びます。

pen protocol が広まった結果、現在までにいろいろなペンが実装されてきました。以下にいくつか例を挙げますが、これ以外にも存在しています。

なお、pen protocol には segment pen protocolpoint pen protocol の2系統があり、前者に対応したペンは HogePen、後者は HogePointPen のようなクラス名になっているのが通例です。この記事では、前者 segment pen protocol のペンをとり上げます*1

フォントを読み込んでグリフを準備する

以下、環境は Python 3.6.3, fontTools 3.20.1 です。fontTools は $ pip install fonttools でインストールできます。

ペンのことは一旦あと回しにして、まずはフォントファイルを読み込みます。今回は例として、源ノ角ゴシック Regular SourceHanSans-Regular.otf を使いました。

from fontTools.ttLib import TTFont
font = TTFont('SourceHanSans-Regular.otf')

次に、glyphSet と呼ばれる辞書様オブジェクトと、cmap(文字コードとグリフ名の対応)を取得しておきます。後者に関しては、従来 cmap テーブル font['cmap'] からサブテーブルを選んで辿っていく必要がありましたが、最近追加されたお手軽便利メソッド getBestCmap() でいい感じに取得できます。

glyph_set = font.getGlyphSet()  # {グリフ名: グリフ} っぽいオブジェクト
cmap = font.getBestCmap()       # {Unicode: グリフ名}

これらを使って、文字 char に対応したグリフオブジェクトを返す関数を作ります。

def get_glyph(glyph_set, cmap, char):
    glyph_name = cmap[ord(char)]
    return glyph_set[glyph_name]

例として、文字 "L" に対応するグリフオブジェクトを、 L としておきましょう。

L = get_glyph(glyph_set, cmap, 'L')

これでグリフの準備はできました。

RecordingPen でアウトラインの内容を得る

さて、アウトラインの内容を取得するためには、fontTools に同梱されている RecordingPen というペンを使います。まずはペンのインスタンスを作成します。

from fontTools.pens.recordingPen import RecordingPen
recording_pen = RecordingPen()

次に、このペンをグリフ上で動かします。pen protocol に対応したグリフオブジェクトは draw() メソッドを持っていますので、これにペンを渡して実行します。先ほどの "L" のグリフ L を使ってみましょう。

L.draw(recording_pen)

ペンで "draw" と言われると、どこかに描く・書き込むのかと思ってしまいがちですが、ここではグリフのアウトラインを「なぞる」行為のことだと捉えてください。この RecordingPen では value 属性になぞった結果が入っていますので、見てみましょう。

print(recording_pen.value)
[('moveTo', ((100, 0),)),
 ('lineTo', ((513, 0),)),
 ('lineTo', ((513, 79),)),
 ('lineTo', ((193, 79),)),
 ('lineTo', ((193, 733),)),
 ('lineTo', ((100, 733),)),
 ('closePath', ())]

目的どおりアウトラインの内容が出てきました。"L" の左下の点からスタートし、反時計回りにパスが構成されているのが分かります。

もうひとつ、"い" のグリフで試してみるとこうなります。

い = get_glyph(glyph_set, cmap, 'い')
recording_pen = RecordingPen()
い.draw(recording_pen)
print(recording_pen.value)
[('moveTo', ((226, 696),)),
 ('lineTo', ((130, 698),)),
 ('curveTo', ((135, 674), (136, 633), (136, 610))),
 ('curveTo', ((136, 552), (137, 432), (147, 346))),
 ('curveTo', ((174, 89), (264, -4), (357, -4))),
 ('curveTo', ((425, -4), (486, 53), (545, 221))),
 ('lineTo', ((482, 293),)),
 ('curveTo', ((456, 193), (410, 91), (359, 91))),
 ('curveTo', ((289, 91), (241, 200), (225, 366))),
 ('curveTo', ((218, 447), (217, 538), (218, 600))),
 ('curveTo', ((219, 626), (222, 672), (226, 696))),
 ('closePath', ()),
 ('moveTo', ((742, 669),)),
 ('lineTo', ((664, 642),)),
 ('curveTo', ((758, 526), (818, 330), (835, 152))),
 ('lineTo', ((916, 184),)),
 ('curveTo', ((902, 351), (831, 554), (742, 669))),
 ('closePath', ())]

曲線を中心とした、2つのパスで構成されています。

SVGPathPen を利用してSVGを作成する

今度は応用として、SVGPathPen というペンを使ってみましょう。このペンは、SVGパスデータ文字列を組み立ててくれます。SVGPathPen のコンストラクタは引数に glyphSet をとりますので、最初の方で用意した glyph_set を渡します。

from fontTools.pens.svgPathPen import SVGPathPen
svg_path_pen = SVGPathPen(glyph_set)

グリフ L をなぞった後、getCommands() メソッドでパスデータ文字列を取得します。

L.draw(svg_path_pen)
print(svg_path_pen.getCommands())
M100 0H513V79H193V733H100Z

パスデータ文字列が表示されました。左下の点 100 0 からスタートし、水平線 H と垂直線 V でパスが構成されています。

以下のようにガワを手書きして、独立したSVGファイルを作ります。

<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1000 1000">
    <path d="M100 0H513V79H193V733H100Z"/>
</svg>

このSVGファイルをブラウザで表示してみると、こんな感じです。

一応「L」のグリフが表示できました。が、上下逆さです。OpenType の座標系では y 軸が上方向に延びていますが、SVG では下方向に延びているため、そのままだと上下がひっくり返ってしまいます。transform 属性で上下を逆にし、viewBox 属性も調整しましょう。

<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 -1000 1000 1000">
    <path d="M100 0H513V79H193V733H100Z" transform="scale(1, -1)"/>
</svg>

これで正立しました。

最後に、もうちょっといい感じのSVGファイルを生成する関数を定義してみます。

from textwrap import dedent

def save_as_svg(font, char, output_path):
    '''TTFont オブジェクトを受け取り、指定した文字のグリフを SVG として保存する'''
    
    glyph_set = font.getGlyphSet()
    cmap = font.getBestCmap()
    
    # グリフのアウトラインを SVGPathPen でなぞる
    glyph = get_glyph(glyph_set, cmap, char)
    svg_path_pen = SVGPathPen(glyph_set)
    glyph.draw(svg_path_pen)

    # メトリクスを取得
    ascender = font['OS/2'].sTypoAscender
    descender = font['OS/2'].sTypoDescender
    width = glyph.width
    height = ascender - descender
    
    content = dedent(f'''\
        <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 {-ascender} {width} {height}">
            <g transform="scale(1, -1)">
                <!-- ボディの枠 -->
                <rect x="0" y="{descender}" width="{width}" height="{height}"
                    stroke="cyan" fill="none"/>
                <!-- グリフ座標系の原点 -->
                <circle cx="0" cy="0" r="5" fill="blue"/>
                <!-- グリフのアウトライン -->
                <path d="{svg_path_pen.getCommands()}"/>
            </g>
        </svg>
    ''')
    
    with open(output_path, 'w') as f:
        f.write(content)

"L" と "い" で実行してみます。

save_as_svg(font, 'L', 'L.svg')
save_as_svg(font, 'い', 'い.svg')

こんな感じの SVG ファイルができました。めでたしめでたし。

おわりに

この記事では pen protocol の概要を説明し、ペンを使ってアウトラインを取得したり、SVG として表示する方法について見てきました。一方、今回触れなかった話題としては、

  • pen protocol の詳細とペンの定義方法
  • グリフへの書き込み
  • ペンを利用したアウトラインの加工
  • さまざまなペンの紹介

などがあります。これらに関しては、またいずれ気が向いたときに記事を書くかもしれません。

なお、今回のファイルは以下のリポジトリにまとめておきました。どうぞご利用ください。

github.com

*1:若干紛らわしいのですが、segment pen protocol は単に pen protocol と呼ばれることがあります。

TTXによるフォントのチラ見をちょっといい感じにする設定

github.com

仕事場/プライベート問わずに大活躍の fontTools ですが、その中でも頻出なのが「フォントファイルを TTX でダンプして中身をチラ見したい」という場面です。

$ ttx -o out.ttx [オプション] font.otf
$ less out.ttx

つい最近まで、上のようにしてごく普通に中身を見ていたのですが、何度もやっているといい加減めんどくさくなってきます。そこで、.zshrc(適宜 .bashrc などに読み替えてください)に簡単なシェル関数を定義してみました。

tl() {
    ttx -q -o - $* | source-highlight -s xml -f esc | less
}

関数名はなんでもいいのですが、ttxless なので短く tl にしておきました。途中の source-highlightGNU Source-highlight というシンタックスハイライトの定番ツールです。こうしておけば、

$ tl [オプション] font.otf

とするだけでちょっといい感じに中身がチラ見できるようになります。べんり。

f:id:mashabow:20170111232302g:plain

OpenType の仕様策定の議論をのぞくには

OpenType は1997年に MicrosoftAdobe が策定したフォントフォーマットで、現在のデファクトスタンダードになっています*1。仕様は Microsoft のサイトで公開されており、興味があればだれでもすぐに読むことができます。

この OpenType の仕様はときたま改定されており、今のところは2015年3月に発表された v1.7 が最新バーションです。

ところで、この仕様の改定はどこで議論されているんでしょう? UCS/Unicode や各種 Web 標準などは策定プロセスがオープンになっていますが、OpenType の仕様はどこで議論が進んでいるのか、ぱっと見ただけではよくわかりません。日本語の情報もほとんど見つかりません。というわけで、この記事でその一端を紹介したいと思います。

OpenType メーリングリスト

実は、Microsoft のサイトにこのメーリングリスト(ML)の案内がちゃんと載っています。

An e-mail based discussion forum has been set up specifically to help people working on the development of OpenType fonts and associated technologies.

載っているのですが、indx.co.uk という馴染みのないドメインだったり、登録前に ML のアーカイブが見れなかったり、ページのフッタに This page was last updated 9 August 2004. と書いてあったりと、登録に躊躇してしまう要素が満載です。

が、これでも現役でちゃんと生きている公式 ML です。to help people working on the development of OpenType fonts and associated technologies と書かれていてスコープが少しぼんやりとしていますが、OpenType の仕様に関する話題が現在中心になっています。

この ML へ登録するためには、subscribe-opentype@indx.co.uk にメールを送ります*2。このとき空メールではだめで、メールの本文が必要です。自己紹介や「登録したいんだけど」みたいなことを1, 2文書いておけば大丈夫なはずです。ML 管理者の承認が降りれば、数日後に通知のメールが来ますので、これで登録完了です。過去のアーカイブは、ML 登録完了後にこのページからたどれます。ただしシステムが古いようで、使い勝手は残念な感じです。

なお、この ML から配信されるメールは、件名の頭に [OpenType] がついています。

mpeg-OTspec メーリングリスト

世の中には ISO/IEC 14496-22 Open Font Format (OFF) という規格があります。といっても OpenType と中身は同じ…というか、OpenType をそのまま公的な国際規格にしたのがこの OFF です。デジュール標準というやつです。ISO が規格票を無料で公開しており、以下のページからPDFのダウンロードが可能です。ちなみに、ISO/IEC 14496-22:2015 が OpenType v1.7 に対応します。

そして、この規格について議論するための ML が米 Yahoo! Groups に用意されています。これが mpeg-OTspec ML です。

こちらの ML は mpeg-otspec-subscribe@yahoogroups.com に空メールを送信するだけですぐに参加できるので、OpenType ML と比べるととっつきやすいかもしれません。過去のアーカイブや添付ファイルの閲覧には米 Yahoo! のアカウントが必要になりますので、アカウントを持っていなければ作っておきましょう。

なお、この ML から配信されるメールは、件名の頭に [mpeg-OTspec] がついています。

ちなみに、mpeg-OTspec ML の近年の流量は以下のとおりで、話題があるときとないときでムラがあります。これは OpenType ML の方も同様です。

f:id:mashabow:20160621000505p:plain

また、両 ML 間では転送やクロスポストが多く、両方とも登録していると若干カオスです。

おまけ

最後におまけとして、以下のリポジトリを紹介しておきます。位置づけがまだよくわかりませんが、OpenType レイアウトに関する追加仕様のドラフトのようです。

github.com

*1:ややこしいので詳細は省きますが、今どきの TrueType は OpenType に含まれます。また、Web フォントで使われる WOFF は、ざっくり言えば OpenType を zlib 圧縮したものです。

*2:一時期は opentype-migration-sub@indx.co.uk というアドレスだったようです(参考)。

二号明朝活字書体見本(明治26年)

TL;DR

東京築地活版製造所『二号明朝活字書体見本』(明治26年/1893年)の画像を Flickr で公開しました。

二号明朝活字書体見本

PDF 版がほしい方は下のページから。

いきさつ

先月末、Twitter でこんなやりとりをしていました。

この『二号明朝活字書体見本 全』というのは、2年半ほど前にたまたま運良く入手した活字見本帳です。自分の本棚に古い見本帳があるというのは、もちろん飛び上がるほど嬉しいわけですが、それをそのまましまっておくのもどうももったいない。どうせなら、文字に興味を持ったいろいろな人に見てもらいたい*1。……などということを以前から考えていました。

そんな中でこのやりとりがあり、チャンスだと思って(ずうずうしくも)撮影をお願いしてみました。この内田(@uakira2)さんは以前、築地五号の見本帳のスキャンや、『光をかかぐる人々』の撮影をされています。ありがたいことに、今回快く撮影を引き受けてくださり、こうして『二号明朝活字書体見本 全』の画像を公開することができました。下の Filckr アルバムで全ページ閲覧できますので、どうぞご覧ください。表紙を含めて画像は88枚あります。

二号明朝活字書体見本

いつものように PDF 版も用意してあります。

見本帳概観

二号明朝活字書体見本_16

この見本帳の8割以上は、漢字のページで占められています。字種数はまだ数えていませんが、総数見本帳だけあってさまざまな字種が載っています。その分、整ったデザインの活字(頻出する漢字)から、その場しのぎっぽいバランス悪い活字(あまり出てこない漢字)まで、クオリティもさまざまです。

二号明朝活字書体見本_76

部首順に並んだ漢字が終わると、次は分合活字(この見本帳では「分合文字」とよぶ)のページに移ります。横幅が1/3, 2/3の2種類の活字があり、この両者を偏旁として組み合わせ、漢字1字を組み立てるようになっています。

二号明朝活字書体見本_81

その次はかな類が続きます。カタカナ・ひらがなともに、非常に洗練された細身のデザインです。上のツイートにあるように、自分の Twitter のヘッダ画像にはこのひらがな部分の写真を使っていますが、プロフィールページを開くたびについつい見とれてしまいます。

あとは記号類が少し並んで終わりです。全84ページ。奥付は以下のようになっています。

明治廿六年六月六日印刷
明治廿六年六月十日出版

   日本東京市京橋區築地二丁目拾七番地
     印刷者  曲田 成
     印刷所  東京築地活版製造所

というわけで、どうぞご活用ください。

*1:というかそもそも自分自身、ほかの人が持っている見本帳をいろいろ見たくてしょうがなかった