Fontconfig (8日目) - ヒンティング ================================= .. post:: Dec 08, 2022 :tags: fontconfig 文字をまともに描画するには何ピクセルぐらい必要でしょうか? 「書」という字は横に8本線があります。 線の間と上に飛び出てる部分含めて最低16px必要ということになります。 もちろん詰めたらであって実際には上下に余白がありますから18〜20pxは欲しいところです。 もっと画数の多い字でしたらもっと必要です。 それで辛うじて字形が表現できるだけですのでフォントの美しさを堪能するには更に倍は欲しいところです。 物理サイズでは同じ10.5ptであっても、印刷物やスマートフォンはDPIで300を超えますから40pxを超えてフォント本来の形が反映されます。 PCのディスプレイでは14pxとなり到底無理な話です。 .. |ZWSP| unicode:: U+200B .. ZERO WIDTH SPACE :trim: グレイスケール化の様子 ---------------------- フォントの形状が各ピクセルをどう占めてグレイスケール化される様子は ``ftgrid`` で確認できます。 (Debian/Ubuntu系であればパッケージfreetype2-demosに含まれています。) .. image:: 2022_12_08_1_grid0.png :alt: ftgridの様子(ヒンティングなし) 字形の線がどこを通るかで1ピクセル幅で濃く表示されるか2ピクセル幅で薄く表示されるかがばらついているのがわかります。 ここでヒンティングを有効にしてみます。 .. image:: 2022_12_08_1_grid1.png :alt: ftgridの様子(ヒンティングあり) 字形の線がピクセル境界に近づいて1ピクセル幅で濃く表示される箇所が増えました。 その代わりに字が下側に1ピクセル分縦長になっています。 ヒンティング ------------ ヒンティングとは、字形をピクセル境界に沿って描画することで低解像度でもなるべくくっきりはっきりした表示にしようという技術です。 当然ながら文字の形状を歪めることになります。 そのため低解像度ではフォント本来の形状よりもヒンティングの質のほうが大事なのです。 TrueTypeフォントとOpenTypeフォントでフォント側が持っているヒント情報は異なり、TrueTypeフォントの方が細かな制御ができますがヒント情報を付ける難易度が高く、OpenTypeフォントは簡単にヒント情報を付けることができますが細かな制御はできずレンダラの裁量に任せることになります。 フォントを作るのでなければ関係ないと思われるかもしれませんが、ヒンティングを設定する際の注意点がTrueTypeとOpenTypeで異なったりもします。 FreeTypeのヒンティング ++++++++++++++++++++++ FreeTypeでは大まかに「ヒンティングなし」「フォントのヒント情報を使う」「light hinting」「auto-hinter」の4つのモードがあります。 auto-hinterはフォントのヒント情報を使わずにFreeTypeが独自にヒンティングしてくれます。 light hintingはFreeTypeのドキュメント `On slight hinting, proper text rendering, stem darkening and LCD filters `_ によりますと、TrueTypeフォントではauto-hinter、OpenTypeフォントでは縦方向のみのヒンティングを行うようです。 Fontconfigのヒンティング設定 ++++++++++++++++++++++++++++ Fontconfigではヒンティングは ``hinting``\ 、 ``hintstyle``\ 、 ``autohint`` の3つの属性で設定します。 だいたいこんな感じです。 .. list-table:: :header-rows: 1 * - hinting - hintstyle - autohint - FreeType * - false - \* - \* - ヒンティングなし * - true - \* - true - auto-hinter * - true - hintnone - false - ヒンティングなし * - true - hintslight - false - light hinting |ZWSP| (TrueTypeはauto-hinter) * - true - hintmedium |ZWSP| /hintfull - false - フォントのヒント情報を使う 6日目にフォント設定画面で「軽く(hintslight)」を避けて「中間(hintmedium)」を選んだのはauto-hinterを避けるためでした。 .. container:: inserted TrueTypeかOpenTypeかは ``fontformat`` 属性で判別できます。 TrueTypeであれば文字列 "TrueType"、OpenTypeであれば文字列 "CFF" になります。 OpenTypeフォントのみhintslightにするにはこんな感じでしょうか。 .. code-block:: xml CFF hintslight 実例 ---- こんな風に言葉でだけ説明してもわからないと思いますのでスクリーンショットを貼っていきます。 画像はぜひ等倍かそれ以上に拡大してご覧ください。 TrueTypeフォント代表としてIPA Pゴシック、OpenTypeフォント代表としてNoto Sans CJK JPをサンプルに用います。 (Debian/Ubuntu系であればパッケージfonts-noto-cjkとfonts-ipafont-gothicに含まれています。) 注意点としましてはKDE neonではNoto Sans CJK JPは `/etc/fonts/conf.d/56-neon-noto.conf `_ で強制的にhintslightにされます。 UbuntuではIPA Pゴシックは `/etc/fonts/conf.d/65-fonts-ipafont-gothic.conf `_ で強制的にhintnoneにされます。 (IPA明朝も同様に `/etc/fonts/conf.d/65-fonts-ipafont-mincho.conf `_ でされます。) ですのでこれらのフォントのヒンティング設定を変えてみたい時は一時的にこれらのファイル、実際にはシンボリックリンクを削除しておく必要があります。 ちなみにDebianではこれらの設定ファイルはありません。 IPA Pゴシック +++++++++++++ hintnone ^^^^^^^^ .. image:: 2022_12_08_1_IPAPGothic_0.png :alt: IPA Pゴシック(hintnone) Ubuntuでは *65-fonts-ipafont-gothic.conf* により常にこの表示になります。 このようにgの下が切れるのはフォントに埋め込まれている行間設定が0になっているフォントにありがちです。 実際のところフォント側の行間設定は狭いほうが使いやすいですし、エディタ側の行間設定で回避できますので見逃してください。 autohint ^^^^^^^^ .. image:: 2022_12_08_1_IPAPGothic_autohint.png :alt: IPA Pゴシック(autohint) 個々の字は綺麗に見えますが全体で見ると上下に暴れてベースラインも揃っていません。 主になるフォントとしてはちょっと使えませんね。 hintslight ^^^^^^^^^^ .. image:: 2022_12_08_1_IPAPGothic_1.png :alt: IPA Pゴシック(hintslight) TrueTypeフォントですので ``autohint`` をtrueにしたのと同じに見えます。 hintmedium ^^^^^^^^^^ .. image:: 2022_12_08_1_IPAPGothic_2.png :alt: IPA Pゴシック(hintmedium) IPA Pゴシックの持つヒント情報を使った本来の状態ですがautohint以上に暴れていて汚く見えます。 Ubuntuがhintnoneを強制しているのも納得です。 hintfull ^^^^^^^^ .. image:: 2022_12_08_1_IPAPGothic_3.png :alt: IPA Pゴシック(hintfull) hintmediumと同じに見えます。 注釈 ^^^^ IPA Pゴシックはヒントの質が悪いフォントの代表として使わせていただいた面もあります。 このようにヒンティングを行わないほうがマシなフォントというのは存在しますし、フォント毎の個別設定をする価値があります。 IPA Pゴシックの名誉のために書いておきますと16pxではヒント情報を使って綺麗に表示できます。 おそらく16px以外でヒント情報を使うことは想定されていないのだと思います。 .. image:: 2022_12_08_1_IPAPGothic-16_2.png :alt: IPA Pゴシック 16px(hintmedium) ですので *65-fonts-ipafont-gothic.conf* を16px以外の時のみhintnoneにするように修正してもよいのではないでしょうか。 こんな感じでしょうか……。 .. code-block:: xml IPA Pゴシック 16 hintnone IPA ゴシック 16 hintnone 注意点としましてこの内容を *~/.config/fontconfig/conf.d/* 以下に置くと *~/.config/fontconfig/fonts.conf* の方が後から実行されますので恐らくDEの設定に上書きされてしまって(また *65-fonts-ipafont-gothic.conf* が存在する場合はそれにも上書きされてしまって)意味がないかもしれません。 フォント毎の設定はなるべく後ろに回す必要があります。 Noto Sans CJK JP ++++++++++++++++ hintnone ^^^^^^^^ .. image:: 2022_12_08_1_NotoSansCJKJP_0.png :alt: Noto Sans CJK JP(hintnone) Notoフォントファミリーに埋め込まれた行間設定はものすごい広いです。 フォールバックフォントとして他のフォントと混ざることも多いNotoですが、縦長故に目立ってしまうのが難点です。 hintslight ^^^^^^^^^^ .. image:: 2022_12_08_1_NotoSansCJKJP_1_1.png :alt: Noto Sans CJK JP(hintslight, rgba) OpenTypeフォントですので縦方向のみのヒンティングが行われています。 元々縦長のNotoが更に全体的に縦長になりましたがラインが揃わなくなることもなくヒント情報の質の良さがうかがえます。 横方向はサブピクセルレンダリングで補えますのでヒンティングは縦方向だけでも充分綺麗ですね。 .. role:: strike KDE neonでは *56-neon-noto.conf* により常に\ :strike:`この表示になります`\ hintslightが強制されるとともに ``rgba`` 属性もnone(5)にされます。 .. container:: inserted KDE neonデフォルトの状態がこちらになります。 .. image:: 2022_12_08_1_NotoSansCJKJP_1_5.png :alt: Noto Sans CJK JP(hintslight, none) よくよく見ますとサブピクセルレンダリングされてませんよね? :: $ fc-match -v 'Noto Sans CJK JP' | grep rgba rgba: 5(i)(w) $ fc-match -v 'IPA Pゴシック' | grep rgba rgba: 1(i)(w) $ fc-match -v 'Ubuntu' | grep rgba rgba: 1(i)(w) こんなコメントがありますが、さて……。 .. code-block:: xml :caption: 56-neon-noto.conf より抜粋 `Noto開発者のお勧め設定 `_\ はhintfullかつグレイスケール(サブピクセルレンダリングなし)のようですので、これを変に部分的に適用してしまった疑いが……。 hintslightであればサブピクセルレンダリングはしたほうが良いと思います。 .. container:: gray-and_small KDE neonを使っていた時は *56-neon-noto.conf* を消していたのですけれども更新の度に復活するのがうざくて、KDE neonをやめた理由のひとつでした。 hintmedium ^^^^^^^^^^ .. image:: 2022_12_08_1_NotoSansCJKJP_2.png :alt: Noto Sans CJK JP(hintmedium) 縦横共にヒンティングが行われた結果、横幅が変化する文字が確認できます。 hintslightの画像とこの画像をそれぞれ別のタブに等倍で表示して切り替えるとわかりやすいと思います。 .. container:: inserted .. container:: gray-and_small このように文字の横幅はレンダリングの裁量で変化し得ます。 hintfull ^^^^^^^^ .. image:: 2022_12_08_1_NotoSansCJKJP_3.png :alt: Noto Sans CJK JP(hintfull) hintmediumと同じに見えます。 autohint ^^^^^^^^ .. image:: 2022_12_08_1_NotoSansCJKJP_autohint.png :alt: Noto Sans CJK JP(autohint) 幸いアルファベットは上下に暴れてはいませんが「漢」「零」あたりはちょっと怪しいですね。 IPA Pゴシックもそうでしたが、FreeTypeのauto-hinterは上下に暴れる傾向があります。 文字単位で処理されていてフォント全体の整合性は気にされていない気がします。 ですので主になるフォントにauto-hinterは適用し辛いです。 フォールバックフォントとしていくつかの文字だけ使用するフォントに適用するならありなのですが。 .. container:: inserted .. container:: gray-and_small macOSのフォントレンダリングがフォントの持つヒント情報を使用しないのは有名ですが、それでアンチエイリアスだけのぼやけたレンダリングであると思われているようです。 実際には(Retinaではない環境では)ごく軽いヒンティングは行われている……と私は思ってます。 小サイズで複数のフォントを並べてみますと高さが若干異なるはずのフォントであっても横の線が同一線上に並びどちらかが2ピクセルにまたがるようなことはないのが確認できるはずです。 この「macOSのヒンティング」は点や線を1ピクセル以上派手に移動させるようなことはないので文字が上下に暴れることもありません。 FreeTypeのauto-hinterもこれぐらい弱いほうが良いのですけどね……。 という雑談でした。 あと薄く表示されている気がします?