フォント
PDFは文書の中にフォントを埋め込みます。 ブラウザと違って「見る人の環境にあるフォントで表示する」ということができないため、どのフォントを使うかは変換時に決まります*
フォントが決まる順番
- CLIの
--font(および--gothic-font/--serif-font/--mono-font) - CSSの
@font-face font-familyに書かれた名前でのシステムフォント探索- 文書中の文字を描画できるフォントのシステム探索
どれでも1つも見つからなかった場合だけ、システムのsans-serif候補が既定フォントになります。
4番目は、font-familyをどこにも書いていない日本語文書のように、名前が手掛かりにならない場合の網です。
1〜3で集めたフォントで描画できない文字が文書に含まれていれば、その文字を持つシステムフォント(日本語ならNoto Sans CJK JPなど)を探して追加します。
この探索はウェイト・スタイルごとに行うので、太字と通常が混在する文書では両方の面が追加されます(通常の文字が太字の面で描かれてしまうのを防ぐためです)。
それでも描画できない文字が残る場合は、豆腐(□)になる前に警告を出します。
警告: 文字 "ไ" を描画できるフォントがありません(豆腐になります)。
--font/--gothic-font か @font-face でフォントを明示してください
サーバやCIでは
--fontを明示してください。 指定しないと出力が実行環境のフォント構成に依存します。 同じHTMLが開発機と本番で違う見た目になる、という事故はここから起きます。
汎用ファミリー名
serif / sans-serif / monospaceはシステムフォントから解決されます(cursive / fantasyは解決しません)。
日本語では、この解決を環境任せにすると本文の書体が変わってしまうので、CLIから決定的に指定できます。
sghtmltopdf invoice.html \
--gothic-font NotoSansJP-Regular.ttf \ # font-family: sans-serif の実体
--serif-font NotoSerifJP-Regular.ttf \ # font-family: serif の実体
--mono-font NotoSansMono-Regular.ttf # font-family: monospace の実体
TrueType Collection(.ttc)を使う場合は、直前の--font系オプションに対して--font-indexでフェイス番号を指定します。
@font-face
@font-face {
font-family: "MyFont";
src: url("fonts/MyFont-Regular.ttf");
font-weight: 400;
font-style: normal;
}
body { font-family: "MyFont", sans-serif; }
対応するディスクリプタはfont-family / src / unicode-range / font-weight / font-styleです。
srcのlocal()と、format()/tech()付きのurl()も受け付けます。
font-displayなどその他のディスクリプタは無視されます。
フォントファイルはTTF/OTFのみです。WOFF/WOFF2は非対応なので、Webで配信しているwebfontをそのまま指すとエラーになります。 元のTTF/OTFを使ってください。
読み込みの待ち合わせはありません。
headless Chromeで必要だったdocument.fonts.ready待ちのような処理は不要で、フォントが未解決のままPDF化されることはありません。
unicode-range
文字の範囲ごとにフォントを切り替えられます。 英数字は欧文フォント、日本語は和文フォント、という典型的な構成がそのまま書けます。
@font-face {
font-family: "Mixed";
src: url("fonts/Latin.ttf");
unicode-range: U+0-24F, U+1E00-1EFF;
}
@font-face {
font-family: "Mixed";
src: url("fonts/JP.ttf"); /* 上の範囲外はこちら */
}
- 単一コードポイント・範囲・ワイルドカード(
U+4??)・カンマ区切りの複数指定に対応します - 宣言された範囲はハードフィルタとして働きます。範囲外の文字には、そのフォントが実際にグリフを持っていても使いません
unicode-rangeを書かなかったフォント(local()・--font・システム探索を含む)は全域をカバーします- 範囲が重なった場合は、CSSの中で先に宣言されたほうが優先されます
太字と斜体
| 指定 | 挙動 |
|---|---|
font-weight | normal/bold/100〜900。数値は600以上をboldとみなす2値化。太字のフォントが無い場合は、塗りに縁取りを足した疑似ボールドで描画します |
font-style | normal/italic/oblique(obliqueはitalicと同一視)。イタリック字形が無い場合は、テキスト行列のせん断による疑似イタリックになります |
fontショートハンドは非対応です。
font-size・font-familyなどのロングハンドを個別に書いてください。
サブセット化
埋め込まれるのは実際に使ったグリフだけです。 日本語フォントを丸ごと指定しても、PDFのサイズは文書に出てくる文字の分にしかなりません。
ストリーミングモードでの注意
ストリーミングモードでは、文書全体を一度に持たないため
上の3・4のシステムフォント探索が行われません(警告を出して既定フォントで描画します)。
--font系オプションか@font-faceで明示すれば、ストリーミングでも意図どおりのフォントになります。
例外として、フォントを1つも指定しなかった場合だけは、既定フォント(ラテン)に加えてCJKを描画できるフォントを1本先回りで読み込みます。 日本語の文書を何も指定せずストリーミングで変換しても豆腐にならないのはこのためです。 CJK以外のスクリプトは警告の対象になります。