JF

こなさんみんばんわ。
ここはフォントについて語るサイトではありません。

という訳で、ここ最近フォントに関する話しか書いてないですが、残念ながら今回もフォントの話です。Noto CJK ファミリーのバリアブルフォント版をローカルにインストールしても、ただ単に CSS の font-family に指定しただけでは普通のフォントとしてしか扱ってくれないので、それを何とかしようとがんばってみた顛末記をお送りします。

ちなみにネタバレというか最初に結論を書いてしまいますと、「無駄な作業だった」です。涙

Noto CJK ファミリーのバリアブルフォント

まずこの記事を読みに来るような方で Noto CJK フォントファミリーやバリアブルフォントが何だか分からないという方はいらっしゃらないと思いますので、その辺の説明は省略します1

その Noto CJK ファミリーのゴシック体フォントである Noto Sans CJK にバリアブルフォント版が加わったのは、元が同じフォントである源ノ角ゴシックをリリースしているアドビの当時のブログ記事にあるように、2021 年 4 月 8 日リリースのバージョン 2.003 からです。

当時はアプリの対応ももう少し先になるだろうからと思って気にも留めてなかったのですが2、普段使ってる Affinity シリーズに v2.5 からそのサポートが入ったことや、ここ最近フォントに関する実験を色々している中で「そういえば CSS で指定するとどうなるんだろう」みたいなことに興味が出てきたので、ちょっと試しに入れてみた次第です。

ダウンロードはどこからするべき?

「Noto Sans ダウンロード」とかで検索すると「Google Fonts からダウンロードしましょう」と書いてある記事がけっこう多くひっかかりますが、ここからは今は地域版サブセットである Noto Sans JP などしかダウンロードできません。CJK 版が必要な場合は GitHub リポジトリReleases から取ることになります。バリアブルフォント版なら All Variable OTF/OTC と書かれたリンクからですね(直接リンクするとダウンロードが始まってしまうのでしません)。

ですが、もしエンジニアの方でしたら一度くらいはリポジトリを全部 git clone して全フォントファイルを確認してみるというのも、色々興味深いものが見られるので個人的にはおすすめしたいところです。ていうか僕はそうしてます…まぁ全部 clone すると 13GB 近いディスク消費量になるので、万人にはおすすめしづらいですが😅

スクリーンショット 1:

git clone してできたフォルダをリスト表示し、一階層だけ展開。Noto Sans / Serif それぞれの各フォントファイルが入ったフォルダの他、google-fontsandroid といったフォルダもある。なお総容量は 12.7GB😱

面白いのは Google Fonts でホストされてるフォントの元ファイル(と思われるもの)や Android OS 用のフォントがリポジトリに含まれているところですね。例えば「Android 用のバリアブルフォントは名前からして 400–900 までのウエイト対応っぽいな、だったら font-weight: 300 とか指定しても無駄かな」というのが分かります。

インストールしてみる → 怒られる(´・_・`)

閑話休題、ダウンロードしたのでインストールしてみます。全部入りの OTC ファイルをダブルクリックすると Font Book が開きますが、僕の Mac mini にはすでに Super OTC 版の Noto Sans CJK がインストール済みだったので「フォントが重複してるよ」という警告がでてしまいました。

スクリーンショット 2

Font Book に出てきた「このフォントのバージョンがすでにインストールされています」という警告。このままインストールできそうなボタンもあるけど、押すのはやめておく。

あとで分かるのですが、どうやらファミリー名などがすべて同じなため同じフォントとして認識され、基本的に両方一緒には入れられないようです。仕方ないので Super OTC 版は一度退避させ、あらためてバリアブルフォント版をインストールしました。

ブラウザで確認 → 以前と何も変わらない(´・_・`)

さて、そんなバリアブルフォント版の Noto Sans CJK ですが、インストール後に Font Book 上で確認してみると、ファミリー名などは全部一緒なんですよね。ウエイトも単にインスタンスとして用意されたものが出てくるだけ。どうやら OS レベルではまだバリアブルフォントだからといって、特別な扱いがされる訳ではないようです3

スクリーンショット 3

Font Book の表示。静的フォント版との違いは特にないように思える(ファイル名くらいか…まぁこれは当然ですね😅

続いて本題である「CSS で指定するとどうなるか」を確認するために、2 月 28 日の記事で使ったテスト用のファイルを Firefox で開いて確認してみました(ファミリー名が同じなので特に何もしなくてもフォント自体は認識されます)。スライダーを動かすと、おお! シームレスにウエイトが変わるぞ…などということはなく😅 前回のテスト結果とまったく同じ位置でウエイトが突然切り替わるだけでした。

という訳で、Web ブラウザでも同様、ただインストールしただけでは別にバリアブルフォントだからといってそのように扱ってくれる訳じゃないのでした。

@font-face を書いてみる → Google Chrome で動かない(´・_・`)

まぁでも、そんなことでハイそうですか残念でした…と引き下がるような俺ではないので😤 ならば Web フォントでやるのと同じように @font-face アットルールを書いてみるとどうだろうか? と思いまして、まずは特に下調べもせず次のような CSS を付け足してみました。

@font-face {
  font-family: Noto Sans CJK JP;
  font-weight: 100 900;
  src: local("Noto Sans CJK JP");
}

変更を加えたテストファイルを Firefox で開くと、今度は(ウエイトが 100 に達すると突然太いウエイトに切り替わってしまうという謎の挙動があるものの)スライダーに応じてシームレスにウエイトが切り替わっていきます。どうやらローカルのフォントも @font-face をちゃんと書けばバリアブルフォントとして扱ってくれるようです。

よしこれで解決したか? と思いきや、残念ながらこれだと Google Chrome で動作しませんでした

PostScript 名による指定を追加する → いけた!

最初は単に Chrome がローカルのバリアブルフォントに対応してないのかもな、ならこれ以上は無理だな…と思い、あきらめて数日放置してたんですが、その後色々と調べてるうちに、@font-face でローカルのフォントを指定する際にはフルネームと PostScript 名の両方を書いておく必要があるというのを知りました。これは後日 2 月 28 日の記事に追記した内容ですね。

という訳で otfinfo を使って PostScript 名を調べます。OTC 形式には対応してないので、リポジトリに残っている OTF ファイルで確認しましょう。念のためにフルネームも確認するため -p オプションではなく -i オプションを使いました。

jforg@local OTF % otfinfo -i NotoSansCJKjp-VF.otf
Family:              Noto Sans CJK JP
Subfamily:           Regular
Full name:           Noto Sans CJK JP
PostScript name:     NotoSansCJKjp-Thin
Preferred subfamily: Thin
(以下省略)

PostScript 名は NotoSansCJKjp-Thin とする必要があるようです。あと、たまたま Firefox で動いたのは単にフルネームが偶然合ってただけのようですね…😭

そんな訳で、先ほどの CSS を次のように変更しましょう。

@font-face {
  font-family: Noto Sans CJK JP;
  font-weight: 100 900;
  src:
    local(NotoSansCJKjp-Thin),
    local("Noto Sans CJK JP");
}

さらに変更を加えたテストファイルで再度確認してみますと、今度は Google Chrome でもちゃんとウエイトがシームレスに変わっていくのが確認できました。あと先ほどの Firefox におけるウエイト 100 の時の謎挙動もなくなりました。やったぜ!!

…と、うまくいった最初はハイになってたのもあってそう思った訳ですが、落ち着いてよく考えてみるとこの方法にはひとつ重大な問題があります。勘のいい方ならもうお分かりだと思いますが…

一見うまくいったように見えるこのコードに潜む重大な問題とは?

ではここで、バリアブルフォントでない方のフォントファイルのひとつである NotoSansCJKjp-Thin.otf の PostScript 名を確認してみましょう。

jforg@local Japanese % otfinfo -p NotoSansCJKjp-Thin.otf
NotoSansCJKjp-Thin

もうひとつ、こちらは NotoSansCJKjp-Regular.otf のフルネーム。

jforg@local Japanese % otfinfo -i NotoSansCJKjp-Regular.otf
Family:              Noto Sans CJK JP
Subfamily:           Regular
Full name:           Noto Sans CJK JP
PostScript name:     NotoSansCJKjp-Regular
(以下省略)

どっちも一緒やないかい!!😫

そうです、Noto CJK フォントは基本的に、静的フォントとバリアブルフォントの間でファミリー名はもちろん、そのフルネームや PostScript 名にも両者を区別するための識別子が入っていません。バリアブルフォントには “Variable” って入ってるとか、そういうのが一切ないのですね。CJK と書きましたが、これは地域版サブセット(Noto Sans JP など)でも同様です。

で、これがどういうことを引き起こすかといいますと、静的フォントしかインストールされていない環境でこの CSS が入った Web ページを閲覧すると、

  1. その PostScript 名から静的フォント版の Noto Sans CJK JP Thin を見つける4
  2. ブラウザは CSS の指定通り、そのフォントをバリアブルフォントとして読み込む
  3. しかしそのフォントは静的フォントなので font-weight をどう変更したところで Thin のまま
  4. 結果、その Web ページは全テキストが極細フォントで表示される

ということになる訳です。なんということでしょう…ちなみにブラウザはバリアブルフォントとして読み込んでいるので font-synthesis も効かず、無理やり太らせる偽ボールドにすらなりません。これではちょっと使い物にならないですね。

そんな訳で、静的フォント版がインストールされている環境とバリアブルフォント版がインストールされている環境の両方で正常に機能する CSS を書くのは Google がフォントの名前識別子を何とかしてくれない限り不可能! というのが現時点での結論です。もう我々の側でできることは何もありません、詰みです。あとは何もせずに静的フォントとして扱う以外にないでしょうね。

はーまじでここまでなんぼ時間を費やしたと思てんねん金返せ!(キレても無理

源ノ角ゴシックではどうなってるか

ちなみに元々が同じフォントである源ノ角ゴシックではその辺どうなってるのかといいますと、こちらは実はちゃんと静的フォントとバリアブルフォントで別になってまして、バリアブルフォントの方にはすべての名前識別子に “VF” という文字列が入ってるんですね。

jforg@local OTF % otfinfo -i SourceHanSans-VF.otf
Family:              Source Han Sans VF
Subfamily:           Regular
Full name:           Source Han Sans VF
PostScript name:     SourceHanSansVF-ExtraLight
Preferred subfamily: ExtraLight
(以下省略)

なので源ノ角ゴシックであれば「バリアブルフォントがインストールされていればバリアブルフォントとして扱う」ということができる訳です。あと別名のフォントなので当然両方をインストールしておくことも可能ですから、データ受け渡しの際に入ってるフォントの違いで表示が…ということも発生しないと思います(ない方をダウンロードすればいいだけ)。

なぜ Noto CJK フォントが同じような仕様になってないのか分かりませんが、それぞれ別のフォントとしてリリースしている訳ですから、その辺はもうアドビにはアドビの事情が、Google には Google の事情があるんでしょうね。知らんけど。

そんな訳で

本日は Noto CJK フォントのバリアブル版をローカルにインストールしても CSS でただ指定しただけではバリアブルフォントとしては扱ってくれないという話から、CSS に @font-face アットルールを書くことで一応うまくいくものの、静的フォントしか入ってない環境で問題が発生するので実用的ではなく、バリアブルフォントとして使うのはあきらめるしかない…といった話をしてみました。

まぁ冒頭では「無駄な作業だった」とか書きましたが、それはあくまでも Noto CJK フォントにおいてはという話であって、実際にはこの作業のおかげで local() 指定の際には PostScript 名も必要なことを理解しましたし、それを確認するために使える otfinfo のことも知りました。そしてこれらは先日の Inter フォントの CSS を書いた時にも役に立ってる訳ですから、すべてがまったくの無駄な作業だった訳ではないんですよね。

やっぱり自分で色々試しながら調べてみるのは重要だと感じました…というのを、ありきたりではございますが本日の〆の言葉とさせていただきます。

あっ〆といえばフォントとは全然関係ないけど 👇 昆布じめ美味しいよね。涙

  1. あとで余裕ができたら追記するかもしれませんが、とりあえず今日のところは。 

  2. ていうか、そんなのが話題になってたかどうかすらあんまり覚えてないです。 

  3. ちなみにスクショは省略しますが、Affinity のアプリではちゃんとバリアブルフォント用の UI が出てきました。 

  4. PostScript 名を認識できない環境でも同様に、そのフルネームから(同じ名前を持つ)静的フォント版の Noto Sans CJK Regular を見つけることでしょう。