fontTools.subset でウェブフォント化して、CSS でサブセットを指定しています。

更新 公開)

# [`fontTools.subset`][fontTools.subset] でウェブフォント

## [`fontTools.subset`][fontTools.subset]
[fontTools.subset]: https://fonttools.readthedocs.io/en/latest/subset
[fontTools.ttLib.ttFont.TTFont]: https://fonttools.readthedocs.io/en/latest/ttLib/ttFont.html#fontTools.ttLib.ttFont.TTFont

[fontTools](https://fonttools.readthedocs.io) には [`pyftsubset`](https://fonttools.readthedocs.io/en/latest/subset) コマンドもありますが、スクリプトを書きました。

```py
from fontTools.subset import Options, load_font, Subsetter, save_font
subset_options = Options(**_subset_options)
font = load_font("path/to/font_file", subset_options)
subsetter = Subsetter(subset_options)
subsetter.subset(font)
save_font(font, "path/to/outfile", subset_options)
```

### [`Options`][fontTools.subset.Options]
[fontTools.subset.Options]: https://fonttools.readthedocs.io/en/latest/subset/#fontTools.subset.Options

サブセットの内容が指定できます。

ここで[グリフも指定できます](https://fonttools.readthedocs.io/en/latest/subset/#initial-glyph-set-specification)が、私は [`Subsetter.populate`][fontTools.subset.Subsetter.populate] を使っています。

```py
subset_options = Options(
    flavor="woff2",
    with_zopfli=True,
    layout_features=["*"],
    hinting=False,
    drop_tables=[],
    name_IDs=[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14],
)
```

#### [`flavor`、`with_zopfli`](https://fonttools.readthedocs.io/en/latest/subset/#output-options)

ウェブフォントの形式や、変換(圧縮)方法が指定できます。

私は [Google Zopfli](https://github.com/google/zopfli) で [WOFF2](https://www.w3.org/TR/WOFF2) に変換しています。

`flavor` を指定しなければ、単にサブセット化します。いわゆるウェブフォント形式(WOFF、WOFF2)には変換されません。

#### [`layout_features`](https://fonttools.readthedocs.io/en/latest/subset/#glyph-set-expansion)

保持する [OpenType Layout features](https://learn.microsoft.com/typography/opentype/spec/featuretags) が指定できます。

私はすべて保持しています。

#### [`hinting`](https://fonttools.readthedocs.io/en/latest/subset/#hinting-options)

[TrueType hinting](https://docs.microsoft.com/typography/truetype/hinting) の保持について指定できます。

私は保持せず、除去しています。

#### [`drop_tables`](https://fonttools.readthedocs.io/en/latest/subset/#font-table-options)

削除する [font Tables](https://learn.microsoft.com/typography/opentype/spec/otff#font-tables) が指定できます。

私は削除せず、すべて保持しています。

#### [`name_IDs`](https://fonttools.readthedocs.io/en/latest/subset/#font-naming-options)

保持する [name IDs](https://docs.microsoft.com/typography/opentype/spec/name#name-ids) が指定できます。

### [`load_font`](https://fonttools.readthedocs.io/en/latest/subset/#fontTools.subset.load_font)
ファイルからフォントを読み込むことができます。フォントは [`fontTools.ttLib.ttFont.TTFont`][fontTools.ttLib.ttFont.TTFont] オブジェクトとして扱われます。

### [`Subsetter`](https://fonttools.readthedocs.io/en/latest/subset/#fontTools.subset.Subsetter)

フォントオブジェクトをサブセット化することができます。

私は [`fontTools.ttLib.ttFont.TTFont.getBestCmap`](https://fonttools.readthedocs.io/en/latest/ttLib/ttFont.html#fontTools.ttLib.ttFont.TTFont.getBestCmap) などですべてのグリフを取得しておいて、約 47 分割しています。

```py
subsetter = Subsetter(subset_options)

codepoints = []
for codepoint in font.getBestCmap().keys():
    codepoints.append(codepoint)
from copy import deepcopy
n = 47
while 0 < len(codepoints):
    subset_unicode = codepoints[0:n]
    codepoints[0:n] = []
    subsetter_copy = deepcopy(subsetter)
    subsetter_copy.populate(unicode=subset_unicode)
    font_copy = deepcopy(font)

    subsetter_copy.subset(font_copy)
```

#### [`populate`][fontTools.subset.Subsetter.populate]
[fontTools.subset.Subsetter.populate]: https://fonttools.readthedocs.io/en/latest/subset/#fontTools.subset.Subsetter.populate

グリフが指定できます。

私は [Unicode](https://home.unicode.org) コードポイントで指定しています。

#### [`subset`](https://fonttools.readthedocs.io/en/latest/subset/#fontTools.subset.Subsetter.subset)
サブセット化できます。

### [`save_font`](https://fonttools.readthedocs.io/en/latest/subset/#fontTools.subset.save_font)
フォントが保存できます。

## [`unicode-range`](https://developer.mozilla.org/docs/Web/CSS/@font-face/unicode-range)
使う文字の範囲が指定できます。これにより、指定した文字が使われるときに(必要なときにだけ)フォントが読み込まれるようになります。

```css
/* ASCII が使われるときにだけ読み込まれるフォント */
@font-face {
    font-family: "My Font";
    font-weight: 100 900;
    src: url(MyFont.1.woff2) format("woff2");
    unicode-range: U+20-7f;
}
/* unicode-range 未指定と大差ないフォント */
@font-face {
    font-family: "My Font";
    font-weight: 100 900;
    src: url(MyFont.2.woff2) format("woff2");
    unicode-range: U+0-1f0000;
}
```

無効なフォームです。ページの再読み込み、又は外部サービスをお試しください。