はじめに
Railsでサービスを作っていると印刷を前提とした帳票を作ることがあります。
そんな時には、便利なGemを使えば簡単に実装することができます。
しかし、一部の文字がPDFで表示されない問題に遭遇しました。
今回はその時の解決方法を書きたいと思います。
今回の環境
Rails (4.2.7.1)
wkhtmltopdf-binary-11 (0.1.0)
wicked_pdf (1.1.0)
PDFで表示されなかった文字は?
それは、「𠮷」という文字です。
「つちよし」と呼ばれたりするようです。
「吉(きち)」ではなく、上が「土」になっています。
この「𠮷」という文字が厄介なのがWeb画面で見たときには正しく表示されます。
しかし、PDFで表示すると文字がまるごと消えてしまいます。
「𠮷」という文字について
調べてわかったのが、「𠮷」はサロゲートペアという文字のようです。
サロゲートペアについては下記の記事に詳しく書かれているので読んでみてください。
Unicode のサロゲートペアとは何か - ひだまりソケットは壊れない
http://vividcode.hatenablog.com/entry/unicode/surrogate-pair
サロゲートペアが今回の直接的な原因では無いかもしれませんが「すこし特別な文字」ということのようです。
解決方法はNoto Fontsを指定する
いきなり解決策に行くとNoto Fontsを入れてCSSでfont-familyを指定してあげると正しく表示されるようになりました。
Noto FontsはGoogleが提供するフォントファミリーです。
このフォントファミリーには日本語も提供されています。
Noto Sans CJK JP
https://www.google.com/get/noto/#sans-jpan
上記のフォントをダウンロードします。
注意すべき点としてはローカルの開発環境とHerokuではフォントの保存先が異なります。
ローカルの開発環境は「~/Library/Fonts」配下にダウンロードしたフォントを入れます。
~/Library/Fonts
├── NotoSansCJKjp-Black.otf
├── NotoSansCJKjp-Bold.otf
├── NotoSansCJKjp-DemiLight.otf
├── NotoSansCJKjp-Light.otf
├── NotoSansCJKjp-Medium.otf
├── NotoSansCJKjp-Regular.otf
├── NotoSansCJKjp-Thin.otf
├── NotoSansMonoCJKjp-Bold.otf
├── NotoSansMonoCJKjp-Regular.otf
Herokuでは「RAILS.root/.fonts」配下にダウンロードしたフォントを入れます。
.fonts
├── NotoSansCJKjp-Black.otf
├── NotoSansCJKjp-Bold.otf
├── NotoSansCJKjp-DemiLight.otf
├── NotoSansCJKjp-Light.otf
├── NotoSansCJKjp-Medium.otf
├── NotoSansCJKjp-Regular.otf
├── NotoSansCJKjp-Thin.otf
├── NotoSansMonoCJKjp-Bold.otf
├── NotoSansMonoCJKjp-Regular.otf
└── ipaexg.ttf
Herokuではfontconfigに対応しているのでデフォルトのフォントディレクトリが.fontsになるようです。
herokuで日本語フォントを奇麗に使うには? - Qiita
http://qiita.com/ssuzuki@github/items/58be855f909f29c05ae6
CSSでNoto Fontsを指定
あとはPDFに適用するCSSでNoto Fontを指定してあげると「𠮷」が正しく表示されます。
@font-face
font-family: 'Noto Sans JP'
font-style: normal
font-weight: 400
src: local('Noto Sans CJK JP')
html
font-family: 'Noto Sans JP', sans-serif
text-rendering: optimizeLegibility
おまけ
今回のNoto Fontsの指定をWebフォントとして読み込もうと試みたんですが、結果としてはローカル開発環境では表示できたが、Herokuでは「𠮷」が表示されませんでした。
CSSを見る限りはNoto Fontsが適用されてはいたのですが原因が特定できず断念しました。https or http周りが怪しい気はしていますが、何かご存知の方がいればコメントで教えてください。