文字をプログラムする(ligaフィーチャの話)【Jasmine System Advent Calendar 2020 Day23】

この記事は「Jasmine System Advent Calendar 2020」の23日目です。

はじめに

お初にお目にかかります。
株式会社ジャスミンシステムのKozyと申します。

今年の新卒入社1年目、自称CTO(代表役立たず役:Cho Tenokakaru Onimotsu / Chittomo Tsukaenai Ochikobore)です。

普段の業務では、デザイン、営業、動画制作、Web上でのアニメーションのコーディング、工事の進捗管理、サウナ、水風呂、外気浴などを繰り返し行ないながら、心と身体をととのえるなどしております。

本当はこの日のアドカレは「ジャスミンシステムを支えるCSS」と題して、弊社のロゴマークをHTML5+CSS3でDIVタグをいっぱい使って描画、もちろんSVGとかCANVASは禁止の縛りをつけた華麗なるCSS芸を披露しようと思っていました。

Jasmine System Logo

しかしながら、どうやら弊社のロゴは思ってた5000兆倍複雑で面倒な仕様(CSS的な意味で)になっているようでした。上野のホームサウナ「北欧」のアウフグースで鮭山さんの作る極上の熱風を浴びながら頭を捻らせても、最高の汗は滝のように出るものの実装方法のアイデアは出てこず、水風呂に入ったらその瞬間にととのってしまい、外気浴中も何も考えられないほどキマってしまったので、泣く泣く断念しました。

HTML5+CSS3ってチューリング完全っていう割にはにできないことが多すぎて、もうちょっと図形描画周りどうにかならないものかとW3Cを小一時間問い詰めたいものです。マークアップの構造や意味付けの話とか、SVGやCANVASの存在意義の話とかで論破するのはやめてください。宗教上の理由で受け付けられません。

ということで今回は、急遽内容を変更してお送りします。デザイン関連で、私の趣味である文字、その中でもコンピュータで扱う「フォント」と呼ばれる「プログラム」について少し書いてみたいと思います。駄文ですが、少々お付き合いくださいませ。

コンピュータとインターフェース

0と1が並ぶ画面

コンピュータが「0」と「1」でものを考える、というのはIT業界に身を置いたことのない方でもおおよそ聞いたことがあるのではないかと思いますが、ではここでいう「0」と「1」とは何でしょうか。これは勝手に人間が決めたもので、何もない状態を「0」、何かある状態を「1」という記号、特に文字と呼ばれるものを使って定義したものです(厳密には少し違います)。ですから、コンピュータは本来「0」とか「1」とかいう記号のことなど考える必要すらないのです。

しかし、人間がコンピュータと対話するには「インターフェース」が必要です。人間でいう口や目などのように、何かしら情報を発信したり受け取ったりして、人間と情報の交換をできるアクションを起こさなければなりません。それをしなければ、たとえコンピュータが内部でP≠NP予想やリーマン予想などのミレニアム懸賞問題を完全に証明したとしても、それを人間に伝えられず、同様に人間はそれを知ることができません。この状態のコンピュータはそこらへんにある石ころとさほど変わりないような存在と言えるでしょう。

先にも述べたように、コンピュータは0や1だけ電圧で判断すればなんでもできるのに対し、人間は音や画像、文字などにして表示してやらないと何もわかってくれません。そこの間にとてつもなく大きな壁があることはお分りいただけますでしょうか。

フォント=文字のプログラム

コンピュータで文字を扱うことは、簡単そうに見えて非常に大変なことなのです。

なんせ、文字ってやつには「形」があります。コンピュータの持っている情報を人間にもわかるような文章にするだけでなく、それを人間が「文字」と呼んでいる形に変換して画面や紙の上に表示しろと言うのですから、人類というのは図々しいことこの上ありません。

とはいえ、コンピュータは(今のところ)人類に従順なようですから、「このコードが出たら画面にこの形を出せ」と言われれば、言われた通りの形に画面を光らせてくれます。さて、その形は誰がどのように定義しているのでしょうか。

察された方やご存知の方も多いかと思いますが、この文字の「形」を定義しているのが「フォント」と呼ばれるプログラムファイルなのです。「フォント」は、言い換えれば「コードを文字の”形”に変換して画面に出力させるプログラム」と言えるでしょう。

(度々連呼している『文字の「形」』のことを、専門用語で「グリフ(Glyph)」と言います。以降「グリフ」とします。)

実際のところ

とはいえ、実際のところフォントが持っている機能はごく限られたものです。なぜならば、コードと文字の紐付けはほとんどUnicodeやJISなどの規格によって決まっていて、フォントファイルはそのコードに紐つけられた文字に対応するグリフを記録しているものであるという面がかなり強いからです。

しかしながら、文字というもの厄介なもので、一筋縄ではいかないものです(そこが面白いのですが)。フォント(厳密にはOpenTypeフォントと呼ばれる形式のもの)の多くには、フィーチャ(Feature)と呼ばれる、一種のプログラムのようなテーブルが組み込まれています。

たとえば、「vert」というフィーチャは、日本語の縦書きのときの「、」の位置や「ー(長音)」の向きなど、縦書きの時に文字の形が変化するものを定義しています。また、「liga」というフィーチャは、英語の教科書や新聞でたまに見かける「f」と「i」、「f」と「t」がくっついた文字の形などを定義できます。そのほか、簡体字や略字体を定義する「smpl」、上付き文字を定義する「sups」など、文字を組むための細かい機能が数え切れないほど存在しているのです。

今回はフィーチャの中でも、見た目でわかりやすく楽しい「liga」についてご紹介します。

特定の文字列が現れたときにグリフが変わる機能「liga」

ligaは、特定の文字列が続いた時に、それぞれの文字のグリフではなくそれらを合わせた一つのグリフを出力するフィーチャです。リガチャ(Ligature)からきており、日本語では合字などと呼んだりします。

試しに、既存のフォントのligaフィーチャを覗いてみましょう。

ここでは、大日本タイポ組合が2016年に公開した「DTAP」というフォントのligaフィーチャの中身を見ていきます。あまり実用的ではありませんがligaフィーチャを学習するのにはとても良く、興味深いフォントです。

sub A P P L E P E N by A_P_P_L_E_P_E_N.liga;
sub A p p l e P e n by A_p_p_l_e_P_e_n.liga;
sub A p p l e p e n by A_p_p_l_e_p_e_n.liga;
sub A P P L E by A_P_P_L_E.liga;
sub A p p l e by A_p_p_l_e.liga;
sub P E N P I N E A P P L E A P P L E P E N by P_E_N_P_I_N_E_A_P_P_L_E_A_P_P_L_E_P_E_N.;
sub P e n P i n e a p p l e A p p l e P e n by P_e_n_P_i_n_e_a_p_p_l_e_A_p_p_l_e_P_e_n.;
sub P e n P i n e a p p l e A p p l e p e n by P_e_n_P_i_n_e_a_p_p_l_e_A_p_p_l_e_p_e_n.;
sub P e n P i n e a p p l e a p p l e P e n by P_e_n_P_i_n_e_a_p_p_l_e_a_p_p_l_e_P_e_n.;
sub P e n P i n e a p p l e a p p l e p e n by P_e_n_P_i_n_e_a_p_p_l_e_a_p_p_l_e_p_e_n.;
sub P e n p i n e a p p l e A p p l e P e n by P_e_n_p_i_n_e_a_p_p_l_e_A_p_p_l_e_P_e_n.;
sub P e n p i n e a p p l e A p p l e p e n by P_e_n_p_i_n_e_a_p_p_l_e_A_p_p_l_e_p_e_n.;
sub P e n p i n e a p p l e a p p l e P e n by P_e_n_p_i_n_e_a_p_p_l_e_a_p_p_l_e_P_e_n.;
sub P e n p i n e a p p l e a p p l e p e n by P_e_n_p_i_n_e_a_p_p_l_e_a_p_p_l_e_p_e_n.;
sub P I N E A P P L E P E N by P_I_N_E_A_P_P_L_E_P_E_N.liga;
sub P i n e a p p l e P e n by P_i_n_e_a_p_p_l_e_P_e_n.liga;
sub P i n e a p p l e p e n by P_i_n_e_a_p_p_l_e_p_e_n.liga;
sub P I N E A P P L E by P_I_N_E_A_P_P_L_E.liga;
sub P E N by P_E_N.liga;
sub P e n by P_e_n.liga;
sub a p p l e P e n by a_p_p_l_e_P_e_n.liga;
sub a p p l e p e n by a_p_p_l_e_p_e_n.liga;
sub a p p l e by a_p_p_l_e.liga;
sub p e n P i n e a p p l e A p p l e P e n by p_e_n_P_i_n_e_a_p_p_l_e_A_p_p_l_e_P_e_n.;
sub p e n P i n e a p p l e A p p l e p e n by p_e_n_P_i_n_e_a_p_p_l_e_A_p_p_l_e_p_e_n.;
sub p e n P i n e a p p l e a p p l e P e n by p_e_n_P_i_n_e_a_p_p_l_e_a_p_p_l_e_P_e_n.;
sub p e n P i n e a p p l e a p p l e p e n by p_e_n_P_i_n_e_a_p_p_l_e_a_p_p_l_e_p_e_n.;
sub p e n p i n e a p p l e A p p l e P e n by p_e_n_p_i_n_e_a_p_p_l_e_A_p_p_l_e_P_e_n.;
sub p e n p i n e a p p l e A p p l e p e n by p_e_n_p_i_n_e_a_p_p_l_e_A_p_p_l_e_p_e_n.;
sub p e n p i n e a p p l e a p p l e p e n by p_e_n_p_i_n_e_a_p_p_l_e_a_p_p_l_e_p_e_n.;
sub p i n e a p p l e P e n by p_i_n_e_a_p_p_l_e_P_e_n.liga;
sub p i n e a p p l e p e n by p_i_n_e_a_p_p_l_e_p_e_n.liga;
sub p i n e a p p l e by p_i_n_e_a_p_p_l_e.liga;
sub p e n by p_e_n.liga;

……何やら懐かしい文字列が並んでいることが認識できたかと思います。

コーディングに携わったことがある方はそれ以上のことまで読み取れたかもしれませんが、ここで簡単にligaフィーチャの構文をご説明します。

sub [letter1] [letter2] … by [ligature];

[letterN]:リガチャにする前のグリフ名(2つ以上を並べて指定する)
[ligature]:リガチャ用のグリフ名

例として、sub P E N by P_E_N.liga;を見てみましょう。これが何を意味しているかというと、このフォントでは、「P」「E」「N」が連続した時、つまり「PEN」という文字列が現れたとき、それぞれのグリフの代わりに、「P_E_N.liga」という1つのグリフを表示するような設定を意味します。

p_e_n.liga

同様に、sub A P P L E P E N by A_P_P_L_E_P_E_N.liga;は、「APPLEPEN」が出た時に「A_P_P_L_E_P_E_N.liga」というグリフを表示することを意味します。

a_p_p_l_e_p_e_n.liga

この「DTAP」というフォントは、以下のページで試し打ちが用意されているので、sub p e n p i n e a p p l e a p p l e p e n by p_e_n_p_i_n_e_a_p_p_l_e_a_p_p_l_e_p_e_n.;の結果をみなさん自身で試してみてください。

大日本タイポ組合 DTAP試し打ちページ:https://dainippon.type.org/DTAP/

試しに作ってみる

さて、ligaフィーチャの構造がわかったところで、実際に簡単なものを作ってみます。ここからは、ドイツ製のフォント作成ソフト「Glyphs」と、Adobeのデザインソフト「Adobe Illustrator」を使っていきます。(余談ですが、IllustratorはもともとAdobe社内でフォントを作るために作られ利用されていたフォントらしいです。)

アドベントカレンダーの記事ということで、「Xmas」という文字が並んだらクリスマスツリーが表示されるようにでもしましょう。

ベースには日本情報処理機構(IPA)の公開していた「IPAex明朝」というフォントを使います。この中から最低限のアルファベットのグリフを抜き出して新しいフォントに読み込みます。

新規フォントの作成

続けて、ligature用のクリスマスツリーのグリフをIllustratorで作っていきます。

これをGlyphsにコピペで読み込んで、グリフの名前を「X_m_a_s.liga」としておきます。

新しいグリフをGlyphsに読み込む

最後にligaフィーチャで次のようにプログラミングします。

sub X m a s by X_m_a_s.liga;

フィーチャの設定

試し打ちでフィーチャを有効にして「Xmas」と入力すると、X_m_a_s.ligaのクリスマスツリーが表示されることが確認できました。

XmasFont

このフォントは以下のフィールドで試し打ちができます。「Xma」まで入力してあるので、「s」を入力してみてください。

今回の成果物はこちらのリポジトリにて配布しております。

ligaが活用されたフォント

最後に、ligaが利用されている実用的なフォントを2つご紹介します。

Font awesome 5 Brands

FontAwesome5Brands

Web業界にいる方なら誰しも使ったことのある「Font awesome」というアイコンフォントサービスですが、これも「Twitter」や「Facebook」などの文字列が出た時にligaを使ってサービスのアイコンのグラフにする機能を有しています。Web上で使うイメージが強いかもしれませんが、ローカルにインストールしておけば、PowerPointで自己紹介ページにTwitterのIDを載せる時なんかに便利ですね。

Fira code

Fira Code

エンジニア向けのコーディング用フォントです。!===->>など、複数の文字からなる演算子を、視覚的にわかりやすく表示してくれます。私はターミナルのデフォルトフォントをこれに設定しています。

おわりに

コンピュータにとって、「文字を人間にわかるように表示する」ことのハードルの高さはご理解いだけましたでしょうか。

まだ日本にはOpenTypeや文字組みに関する関心の高いユーザが少ないようで、なかなか日本語による文献や、「日本語」という特殊な言語特有の問題などに関する議論がなされる場が決して多くはありません。特にWeb上での日本語組版には、未だ非常に厳しい制約がかかっているのが現状です。

コンピュータでの文字表現は、誰しもが普段から恩恵を受けている領域ですので、私も一層「コンピュータと文字」についての知見を深め、また広めていきたい所存でございます。

それでは皆様、良いクリスマスを。

*おまけ*

下のフィールドの「Jasmin」に続いて「e」と入力してみてください!

%d人のブロガーが「いいね」をつけました。