フォント・DB 管理コマンド

「フォントを入れたのに LaTeX が見つけてくれない」——このページはその一行に答えるためにあります。厄介なのは、エンジンによってフォントの探し方がまるで違うことです。pdflatex はそもそもシステムのフォントを一切見ず、updmap が作ったフォントマップだけを信じます。XeTeX は OS のフォント機構に問い合わせ、LuaTeX は luaotfload が作った自前の Lua データベースを引きます。だから「fc-list に出るのに使えない」は矛盾ではなく、三つの仕組みのうち別のものを覗いているだけです。以下では fc-listfc-cacheupdmapkanji-config-updmapluaotfload-toolfmtutil を、どの層のどの故障を直す道具なのかという順で並べます。

エンジンはどうやってフォントを見つけるのか——三つの別々の仕組み

この三分割は、エンジンの生まれた年代の差がそのまま残ったものです。pdfTeX の血筋は 1980 年代の TeX で、当時はシステムに「フォントの一覧」という概念すらありませんでした。だから TeX 側の論理名(ptmr8r のような文字列)と実ファイルの対応を フォントマップという表 に書き、updmap がそれを組み立てます。XeTeX(2004 年〜)は OS のフォント機構に直接ぶら下がる設計で、macOS 向けにビルドされた TeX Live 2024 の xetexotool -L で覗くと CoreText がリンクされています。LuaTeX は Lua で自前の名前解決を行い、luaotfload が作るデータベースを引きます。同じ \setmainfont{...} を書いても、その一行が問い合わせにいく先は三つとも別なのです。

エンジンフォントの探し方直すコマンド
pdftexシステムのフォントを見ない。.tfm の論理名をフォントマップで実ファイルに解決するupdmap-sys
xetexOS のフォント機構に問い合わせる。macOS 版は CoreText がリンクされているOS 側のフォント管理
luatexLua で名前解決する。luaotfload が作る名前データベースを引くluaotfload-tool --update
dvipdfmx組版ではなく 埋め込み の担当。どのフォントを PDF に入れるかはマップが決めるupdmap-sys / kanji-config-updmap-sys

fc-listfc-cache は TeX Live のコマンドではない

まずここを外すと、以降の判断がすべて狂います。fc-listfc-cachefc-match も fontconfig という別プロジェクトのコマンドで、TeX Live には含まれていません。 TeX Live 2024 の bin ディレクトリを端から端まで探しても fc- で始まる実行ファイルは一つもなく、この Mac にあるのは Homebrew が入れた fontconfig 2.18.2 です。それでもこれらが役に立つのは、システムにどんなフォントがあり、そのファイルがどこにあるかを一覧できるからです。fc-list : family はファミリ名だけを、fc-list -f は書式を指定して file・family・style を並べます。この環境では 2,799 件が返りました。

terminal
fc-list : family | sort -u | wc -l         # how many families the system offers
fc-list -f '%{file}\n' :family=Menlo        # where the file actually is
fc-cache -fv ~/Library/Fonts               # rebuild the fontconfig cache

fc-match "NoSuchFontXYZ"
# Verdana.ttf: "Verdana" "Regular"          <- a substitute, not an error

ここに、一度は引っかかる罠があります。fc-match は「見つからない」と言いません。 存在しない名前を渡しても、fontconfig は必ず何かを返します。手元で fc-match "NoSuchFontXYZ" と打つと Verdana.ttf: "Verdana" "Regular" が返りました——これは代替であって、確認ではありません。「入っているか」を調べるつもりで fc-match を使うと、いつも「入っている」と答えられてしまいます。判定したいなら返ってきたファミリ名が期待どおりかを見るか、fc-list で名指しして絞り込みます。もう一つ、macOS ではさらに注意が要ります。前節のとおり xetex は CoreText を見ているので、fc-list に出ているかどうかは XeTeX が使えるかどうかの保証になりません。 逆に Linux の TeX Live のように XeTeX が fontconfig 経由で探すビルドでは、ユーザのフォントディレクトリに置いたあと fc-cache を走らせる意味があります。

updmap — フォントマップの一行は何を言っているのか

フォントマップは、TeX の論理名と実ファイルを結ぶ一行ずつのテキストです。updmap はマップの中身を書くのではなく、updmap.cfg に列挙された .map ファイルを一つに連結して dvips 用の psfonts.map と、pdftex および dvipdfmx 用の pdftex.map を書き出します。この環境で updmap-sys --listmaps を数えると宣言は 389 行あり、内訳は Map が 332、MixedMap が 46、KanjiMap が 11。連結後の psfonts.map は 45,672 行、5.5 MB 近い一枚のテキストです。中身の一行は次のように読みます——TeX 側の名前、PostScript のフォント名、エンコーディングの再割り当て、そして実ファイル。

terminal
# one real line out of psfonts.map on this machine
ptmr8r NimbusRomNo9L-Regu " TeXBase1Encoding ReEncodeFont " <8r.enc <utmr8a.pfb

updmap-sys --listmaps            # every declared map, and which cfg declared it
sudo updmap-sys --enable Map myfont.map
sudo updmap-sys                  # rebuild psfonts.map and pdftex.map

運用でつまずくのは、たいていコマンドではなく どちらの設定を触っているか です。TeX Live 2024 の updmap は、素の updmap を拒否します——updmap [ERROR]: Either -sys or -user mode is required.updmap [ERROR]: In nearly all cases you should use updmap -sys. が返るだけです。これは親切な設計で、その先に本当の落とし穴があるからです。updmap --help 自身がこう書いています。「updmap-user を一度でも実行すると、その後は updmap-sys を走らせても効果がなくなる」。 個人用の設定ファイルが作られ、以後はそちらが優先されるためです。共有マシンや CI では updmap-sys に統一し、updmap-user は「システム設定を意図的に上書きしたい」と自覚しているときだけ使ってください。なお sudo が要るのは、/usr/local/texlive/2024 以下を root が所有しているからです。

kanji-config-updmap — PDF に埋め込む和文フォントを選ぶ

和文フォントの選択が独立したコマンドになっているのには理由があります。pLaTeX・upLaTeX の経路では、どの和文フォントを PDF に埋め込むかは組版時ではなく dvipdfmx の段で決まる からです。原稿を書き換えなくても、埋め込みフォントだけを後から差し替えられる——その切り替えスイッチが kanji-config-updmap(texjporg)で、内部では updmapjaEmbed オプション(以前の名前は kanjiEmbed)を設定しています。まず status で現状を確認してください。この環境では CURRENT family for ja: haranoaji (variant: -04) と返り、続けて ipaipaex などが待機中のファミリとして並びました。切り替えたいときはファミリ名をそのまま渡します。updmap と同じく -sys-user の区別があり、共有環境では kanji-config-updmap-sys に統一するのが安全です。

terminal
kanji-config-updmap-sys status
# CURRENT family for ja: haranoaji (variant: -04)
# Standby family : ipa
# Standby family : ipaex

sudo kanji-config-updmap-sys ipaex   # embed the IPAex family instead
sudo kanji-config-updmap-sys auto    # let it pick from what is installed

luaotfload-tool — LuaTeX の最初の一回が遅い理由

LuaLaTeX を初めて動かした人がまず驚くのは、待ち時間です。原因は luaotfload名前データベース で、システム中のフォントファイルを走査して名前とファイルの対応表を作っています。この環境では TEXMFVAR/luatex-cache/generic/names/luaotfload-names.luc.gz に約 390 KB で保存されていました。おもしろいのは、フォントが見つからないと自動で作り直しが始まることです。存在しない名前を \setmainfont に渡してみると、ログにはこう出ました——luaotfload | db : Reload initiated (formats: otf,ttf,ttc); reason: Font "NoSuchFontXYZ" not found. そのうえで ! Package fontspec Error: The font "NoSuchFontXYZ" cannot be found. で止まります。つまり「入れたばかりのフォントが見つからない」ときは、たいてい一度走らせれば直ります。明示的にやるなら luaotfload-tool --update で、データベースが無ければ Font names database not found, generating new one.This can take several minutes; please be patient. を表示して作り直します。

terminal
luaotfload-tool --update              # rebuild the LuaTeX names database
luaotfload-tool --diagnose=environment # what luaotfload thinks its world looks like
ls "$(kpsewhich --var-value=TEXMFVAR)/luatex-cache/generic/names/"

fmtutil — エンジンが起動時に読み込む .fmt を作り直す

pdflatex を叩くと、エンジンは latex.fmt のような フォーマットファイル を読み込んでから仕事を始めます。これは「LaTeX を全部読み終えた直後のエンジンの内部状態」を丸ごと保存したスナップショットで、毎回何千行ものマクロを読み直さずに起動するための仕掛けです。fmtutil はこの .fmt を作り直します。出番は多くありません——フォーマットに関わる更新をしたときか、.fmt が壊れてエンジンが起動前に止まったときだけです。パッケージを一つ入れるたびに走らせるものではありません。 一つだけなら fmtutil-sys --byfmt pdflatex、全部なら fmtutil-sys --all ですが、後者は数分かかります。-sys-user の使い分けは updmap と同じで、共有環境では -sys に統一します。

terminal
sudo fmtutil-sys --byfmt pdflatex   # rebuild one format
sudo fmtutil-sys --all              # rebuild every format (several minutes)
kpsewhich --var-value=TEXMFVAR      # where the .fmt files end up

症状からコマンドを引く

コマンドこういうときに打つ
fc-list : familyシステムにそのフォントが本当にあるのか、名前は何なのかを先に確かめたい
luaotfload-tool --updateLuaLaTeX だけがフォントを見つけられない。もう一度走らせても直らない
updmap-sys --enable Map欧文フォントのパッケージを手で入れたのに、PDF の字が置き換わらない
kanji-config-updmap-sys statusPDF の和文だけが意図と違う。まず現在の jaEmbed を確認する
fmtutil-sys --byfmtエンジンが組版に入る前、フォーマットが読めずに止まる
mktexlsrTEXMFLOCAL にファイルを置いたのに見つからない。詳しくはビルドツールのページへ

最後に、この地図の余白にある小さな道具を一つ。TeX Live には albatross というコマンドが入っていて、man ページによれば「与えられた Unicode 文字を含むフォントを探す」ツールです。しかも中では fontconfig を使っています——TeX の世界の道具が fontconfig を呼ぶ、という関係がここにも現れます。ただし手元で走らせると Unable to locate a Java Runtime. で止まりました。Java 実行環境が要るので、使いたければ別途用意してください。mktexlsrtexhashkpsewhich はビルドツールのページに詳しくまとめてあります。