[備忘]FontForgeで合字(リガチャ：Ligature)の作り方

# はじめに
　フォント作成フリーソフトの「FontForge」内の「合字」の作成方法をネットで調べたので備忘メモします。
　最も役に立った情報源は以下です。欧米の少年がYouTubeで英語でしゃべってます。
　英語は全然わかりませんが、画面操作を撮影しているのでわかりやすかったです。


https://www.youtube.com/watch?v=UUUeogQAjv0

　下はTwitterでの記載です。短くまとまっていてわかりやすかったです。

https://twitter.com/o_tamon/status/1063467444583297024

　ネットで調べたといっても、YouTubeとTwitterが一番の情報源でした。
　時代を感じます。
　Qiitaも役立つ情報があったのですが、直感的でなく、あんまり私の頭に入ってきませんでした。
　私が答えだけを求めたからかな。
　
# 「合字」の定義
「合字」は<b>「2字以上で表記する文字を、1字で表記する文字」</b>です。 英語はリガチャ：Ligatureです。「ガチャ」と聞くと100円入れて玩具が入ってるプラスチックカプセルを出す「ガチャガチャ」が浮かびますが、違う意味です。
- 例(1)「А」と「Е」の合字「Ӕ」
- 例(2)「a」と「e」の合字「ӕ」
- 例(3)「よ」と「り」の合字「ゟ（より）」
- 例(4)「麻」と「呂」の合字「麿」← 和製漢字

# 「合字」と似ている「結合文字」と？
- 濁点「゛」や半濁点「゜」は「合字」ではなく「結合文字」です。
- 通常、結合文字は単独では使いません。他と一緒になって使います。
- 「か」+「゛」=「が」
- 「か」は「基底文字」となります。「が」は「合字」ではなく「結合文字列」となります。
- 英語はCombining character

「結合文字」は「合字」に字は似ているが、意味は異なります。まとめると以下
- 「基底文字」＋「基底文字」＝「<b>合字</b>」
- 「基底文字」＋「<b>結合文字</b>」＝「結合文字列」


#  Unicode上の「合字」や「結合文字」の扱い
- 「A」「E」「a」「e」「よ」「り」「麻」「呂」「か」は１文字毎にUnicode上で１文字の文字コードが割り振られている。
- 「Ӕ」「ӕ」「ゟ」「麿」「゛」も１文字毎にUnicode上で１文字の文字コードが割り振られている。
- したがって、パソコン上では「A」も「E」も「Ӕ」も１文字として扱う。

## 「合字」への理解をややこしくしている要因（愚痴）
- 「合字」と「結合文字」の意味がとらえにくい。
- 「結合文字」と「結合文字列」の違いが分かりにくい。
- 「゛」を「結合文字」、「が」を「結合文字列」、「麿」を「合字」と言われても、直感的に理解しにくい。
- 「゛」は「結合文字」というより「付随文字」と言ったほうが良いと思う。
- 「Ӕ」「ӕ」「ゟ」は、「合字」というより、見た目から「結合文字」と言ったほうがすっきりすると思う。
- 「Ӕ」「ӕ」「ゟ」は「合成済み文字」と呼ぶ場合がある。

## 「合字」への理解を更にややこしくしている要因（愚痴２）
- Shift-JISとかの昔の文字コードでは「Ӕ」「ӕ」が扱えなかった。
- 一方で「Ӕ」「ӕ」「ゟ」は、Unicode上では他の文字と同様に一文字で扱う為、「合字」というより「元合字」
- フォント用語の「結合文字」とプログラミング用語の「結合文字」が、意味は異なる。
- UTF-16のサロゲートペアが話を更にややこしくさせている。
- JavaやJavaScript、C#はUTF-16を扱っている。


# フォントに関する用語
　FontForgeの表記は英語由来のカタカナ語が多いです。
　カタカナ語のままだと意味がとらえ難いので、別に私は中国人ではないですが、中国漢字を含めた和英中で用語の対比表を作成しました。

|日本語|英語|中国漢字(簡体)|台湾漢字(繁体)|
|:-----------|:------------:|:------------:|:------------:|
|フォント|Font|字体|字體|
|書体|Typeface|字体|字體|
|書式|Format|格式|格式|
|合字|Ligature|结扎|結紮|
|結合文字|Combining character|组合字符|組合字符|
|結合文字列|Concatenation string|串联字符串|串聯字符串|
|グリフ|Glyph|字形|字形|
|文字コード|Character code|字符代码|字符代碼|
|ユニコード|Unicode|统一码|統一碼|
|エンコード|encode|编码|編碼|
|デコード|decode|解码|解碼|
|サロゲートペア|Surrogate pair|代理对|代理對|
|ルックアップ|Lookups|查找|查找|
|カーン|kern|字距|字距|
|字詰め|Kerning|字距调整|字距調整|
|フォント・メトリック|font metrics|字体度量|字體度量|
|B-スプライン曲線|B-spline curve|B样条曲线|B樣條曲線|
|ベジェ曲線|Bezier curve|贝塞尔曲线|貝塞爾曲線|


# フォントの内部構造
　フォントのフォーマット（OpenType）の内部構造は複雑です。
　わかっている範囲では以下です。
　特に、FontForgeの設定では、ASCIIの４文字のテーブル名で使われており理解が必要です。

- フォントの内部データは、「テーブル」と呼ばれるグループ毎に分かれている。
- 各「テーブル」の名称は、ASCII文字の４文字で固定される。例「GSUB」
- ASCII文字とは、半角英数字、空白、記号の128文字
- この「テーブル」を頭（ヘッダ）として区別されている。

# 代表的なテーブル名と格納データ

|テーブル名<br>4文字|語源|格納|説明|
|:-----------|:------------:|:------------:|:------------:|
|GSUB|Glyph|単一または複数のグリフを、<br>別のグリフに置き換える為のデータ||
|GPOS|Glyph<br>Position<br>|グリフの位置を調整するデータ
|OS/2||Windowsプラットフォームの<br>重要な設定値
|cmap||Unicode等の文字コードと<br>字形データのインデックス値を<br>一致(マッピング)させるデータ
|glyf|Glyph|字形データ
|EBDT|Embedded<br>Bitmap<br>|埋込ビットマップ<br>データ|マイクロソフトの書式
|EBLC|Embedded<br>Bitmap<br>Location<br>|埋込ビットマップ<br>位置データ|マイクロソフトの書式
|EBSC|Embedded<br>Bitmap<br>Scaling|埋込ビットマップ<br>スケーリング・データ|マイクロソフトの書式
|COLR|Color|COLRは、CPALの色情報が<br>どのグリフで<br>どのように使用されるかを定義する|
|CPAL|Color<br>Palette|色情報が羅列|Segoe UI Emojiなどで<br>使われている色仕様
|hhea|horizontal<br>head|水平レイアウト (横書き) の<br>ヘッダ情報
|hmtx|horizontal<br>matrix|水平レイアウト (横書き) の<br>各グリフの<br>「advance width」と「left side bearing」|
|vhea|vertical<br>head|垂直レイアウト (縦書き) の<br>ヘッダ情報
|vmtx|vertical<br>matrix|垂直レイアウト (縦書き) の<br>各グリフの<br>「advance width」と「left side bearing」|

# FontForgeの主なメニューの和英対応

FontForgeのメニュー
├ファイル　　　　　　　　　　　　[File]
├編集　　　　　　　　　　　　　　[Edit]
├エレメント　　　　　　　　　　　[Element]
│　├フォント情報　　　　　　　　[Font Info]
│　│　├PS Names　　　　　　　　[PS Names]
│　│　├一般情報　　　　　　　　[General]
│　│　├レイヤー　　　　　　　　[Layers]
│　│　├PS UniqueID 　　　　　　[PS UID]
│　│　├PS Pravete辞書　　　　　[PA Pravete]
│　│　├OS/2　　　　　　　　　　[OS/s]
│　│　├TTF名 　　　　　　　　　[TTF Names]
│　│　├StyleSet Names　　　　　[StyleSet Names]
│　│　├Grid Fitting　　　　　　[Grid Fitting]
│　│　├TεX 　　　　　　　　　　[TεX]
│　│　├サイズ　　　　　　　　　[Size]
│　│　├コメント　　　　　　　　[Comment]
│　│　├FONTLOG 　　　　　　　　[FONTLOG]
│　│　├マーククラス　　　　　　[Mark Classed]
│　│　├Mark Sets 　　　　　　　[Mark Sets]
│　│　├Lookups 　　　　　　　　[Lookups]
│　│　├WOFF　　　　　　　　　　[WoFF]
│　│　├MAC 　　　　　　　　　　[Mac]
│　│　├MACの機能 　　　　　　　[Mac Features]
│　│　├日付　　　　　　　　　　[Dates]
│　│　└Unicode範囲 　　　　　　[Unicode Ranges]
│　│
│　├グリフ情報　　　　　　　　　[Glyph Info]
│　│　├Unicode 　　　　　　　　[Unicode]
│　│　├コメント　　　　　　　　[Comments]
│　│　├位置指定　　　　　　　　[Positionings]
│　│　├ペア単位の位置指定　　　[Parewise Pos]
│　│　├置換　　　　　　　　　　[Subsitutions]
│　│　├選択型の置換　　　　　　[Alt Subs]
│　│　├合字　　　　　　　　　　[Ligatures]
│　│　├Lig.Carets　　　　　　　[Lig.Carests]
│　│　├構成要素　　　　　　　　[Componets]
│　│　├カウンタ　　　　　　　　[Counters]
│　│　├TεX & Math　　　　　　　[TεX & Math]
│　│　├Vert. Variants　　　　　[Vert. Variants]
│　│　└Horiz. Variants 　　　　[Horiz. Variants]
│　│
│　│
│　├その他の情報　　　　　　　　[Other Info]
│　├Validation　　　　　　　　　[Validation]
│　├Bitmap Strikes Avalibale　　[Bitmap Strikes Avalibale]
│　├ビットマップの再生成　　　　[Regenerate Bitmap Glyphs]
│　├ビットマップの除去　　　　　[Remove Bitmap Glyphs]
│　├スタイル　　　　　　　　　　[Style]
│　├変形　　　　　　　　　　　　[Transformations]
│　├輪郭を太らせる　　　　　　　[Expand stroke]
│　├重複処理　　	　　　　　　　[Overlap]
│　├単純化　　　	　　　　　　　[Simplify]
│　├極大点を追加　　　　　　　　[Add Extrema]
│　├座標を丸める　　　　　　　　[Round]
│　├自動トレース　　　　　　　　[Autotrace]
│　├アウトラインの向きを修正　　[Correct Direction]
│　├組み立て　　　　　　　　　　[Build]
│　│　├アクセントつきグリフを構築　[Build Accented Glyph]
│　│　├複合グリフを構築　　　　　　[Build Composite Glyph]
│　│　└複製グリフを作成　　　　　　[Build Duplicate Glyph]
│　│
│　├フォントの統合　　　　　　　[Merge Fonts]
│　├フォントの補間　　　　　　　[Interpolate Fonts]
│　├フォントを比較　　　　　　　[Compare Fonts]
│　└レイヤーを比較　　　　　　　[Compare Layers]
│
├ツール　　　　　　　　　　　　　　[Tools]
├ヒント　　　　　　　　　　　　　　[Hints]
├エンコーディング　　　　　　　　　[Encoding]
│　├エンコーディングの変換　　　　[Reencode]
│　├定義済みのグリフのみ表示　　　[Compact]
│　├エンコーディングを強制　　　　[Force Encoding]
│　├エンコーディングスロットを追加[Add Endoding Slots]
│　├未使用のスロットを削除　　　　[Remove Unused Slots]
│　├グリフの切り離し　　　　　　　[Detach Glyphs]
│　├グリフの切り離し・削除　　　　[Detach & Remove Glyphs]
│　├エンコーディングの名前を追加　[Add Endoding Name]
│　├エンコーディングを読み込み　　[Load Encoding]
│　├フォントから作成　　　　　　　[Make From Font]
│　├エンコーディングを削除　　　　[Remove Encoding]
│　├グループ毎の表示　　　　　　　[Displya By Groups]
│　├グループを定義　　　　　　　　[Difine Groups]
│　├フォントの名前リストを保存　　[Save Namelist of Font]
│　├名前リストを読み込み　　　　　[Load Namelist]
│　├グリフ名を変更　　　　　　　　[Rename Glyphs]
│　└名前を指定してグリフを作成　　[Create Named Glyphs]
│
├表示[View]
├メトリック[Metrics]
│　├メトリックスウィンドウを開く　[New Metrics Window]
│　├幅の中央に　　　　　　　　　　[Center in Width]
│　├両端の空きを１：２に　　　　　[Thirds in Width]
│　├幅を設定　　　　　　　　　　　[Set Width]
│　├左サイドのペアリングを設定　　[Set LBeaing]
│　├右サイドのペアリングを設定　　[Set RBearing]
│　├両サイドのペアリングを設定　　[Set Both Bearings]
│　├縦書き時の送り幅を設定　　　　[Set Vertical Advance]
│　├幅の自動設定　　　　　　　　　[Auto Width]
│　├クラス毎のカーニング　　　　　[Kern By Classes]
│　├カーニングをすべて削除　　　　[Remove All Kern Pairs]
│　├カーニングペアの詳細　　　　　[Kern Pair Closeup]
│　├クラス毎の縦書きカーニング　　[VKern By Classes]
│　├横書きカーニングを縦書きに　　[VKern From HKern]
│　└縦書きカーニングをすべて削除　[Romove All VKern Pairs]
│
├CID 　　　　　　　　　　　　　　　[CID]
├MM　　　　　　　　　　　　　　　　[MM]
├ウィンドウ　　　　　　　　　　　　[Window]
└ヘルプ　　　　　　　　　　　　　　[Help]

# FontForgeで合字作成の基本操作メモ
　全操作の説明は、すみませんが挫折しました。
　以下にポイントをピックアップします。詳細はYouTubeの少年の操作を見てください。

## ①Liga（合字）のLookups（索引集）の定義を決定する
「エレメント」→「フォント情報」→「Lookups」→「Add Subtable」→機能に「liga」を設定→「用字系と言語」に合字にしたい言語を選択
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/157498/acea86b0-ad4b-a77d-3f59-a7a05b33f9d1.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/157498/079d240b-4ccb-9c67-de80-7fb2f6b99bda.png)

## ②合字用のスロット（文字を入れる箱）を追加する
↓　(1)メニューの「エンコーディング」の上から４つ目の「エンコーディングスロットを追加」
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/157498/533c5a0a-a41a-281c-8588-dc8503c83be8.png)
↓　(2)追加したいスロットの数を入力して（図中では１）、「OK」ボタンを押す。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/157498/7020c3bb-23a9-3340-07a2-dc0755a2cd6a.png)
↓　(3)最下段に追加される。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/157498/fa0c929a-47db-442e-e432-ed16bb391654.png)

## ③合字のグリフ名の名づけ方法について
　アンダーバー「_」（英語はアンダースコアと言う）で繋げます。以下ポイントです。複数の場合は、アンダーバーで繋げて𝒊
- 半角アルファベットは「文字_文字」と繋げます。例えば「f_i」
- 半角数字は例えば「one_two」と繋げます。
- 日本語等々は、「グリフ名_グリフ名」となります。

↓　(1)新しく追加したスロットのグリフ情報を選ぶ。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/157498/4880ab43-80cb-cb8a-7cec-1aff5c4a13ed.png)
↓　(2)Glyph Name「グリフ名」を選択
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/157498/5e06a023-b238-9ad3-3010-14d398be60ec.png)
↓　(3)Glyph Name「グリフ名」を変更。重要！★アンダーバー「_」で合字にしたいグリフ名を繋ぐ★
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/157498/4bd73ffb-f458-4671-84b6-ff507bb82ca8.png)

## ④合字の設定について
↓　(1)「Subtable」に①の「Lookups」の「GSUB」で定義したsubtableを選択入力する。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/157498/34dddb8f-26e4-5fac-03e3-2c86109bfe40.png)
↓　(2)重要！★　文字と文字（もしくはグリフ名とグリフ名）の間は半角スペース「 」で区切る（複数可）★
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/157498/5d9722dc-a942-d6e3-dfdf-18abecda93ed.png)


## フォントファイルとして保存する時の注意
↓　(1)「TrueType」にした後、「オプション」ボタンを押す。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/157498/7dca6d74-8b89-72d1-fde5-f8c7c614fdd2.png)

↓　(2)SFNTに於いて4つに✅する。特に「OpenTypeの仕様」に✅しないと合字にならない。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/157498/34e7dd0f-c3a9-b8b3-6fb2-3a01b338513f.png)


# 参考リンク
- [OpenType フォント・フォーマット](https://aznote.jakou.com/prog/opentype/index.html)
- [フォントのしくみ](https://www.iwatafont.co.jp/news/img/about_font.pdf)
- [OpenTypeフォントの中身](https://www.dynacw.co.jp/fontstory/fontstory_detail.aspx?s=86&r=50)
- [CPALの説明](https://docs.microsoft.com/en-us/typography/opentype/spec/cpal)
- [Creating a Micro­soft color font (CPAL/‌COLR)](https://glyphsapp.com/learn/creating-a-microsoft-color-font)
- [結合文字の説明がわかり易い](https://dev.mery.co.jp/744)
- [フォントフォーマットって何？](https://aidco.jp/news-8/)