もらったPDFの文字化けを修正するには?

細田真道氏(以下、細田):文字化けを修正するにはどうすればいいかを説明します。誰かからもらったPDFが文字化けしていたとします。データ分析したいとか、検索したいときに困りますね。一番簡単なのは、正規化しちゃう。これはテキストを抽出してから、問題のブロックの文字を対応する通常の漢字に置き換えるように正規化すれば、データ分析ということならこれでできると思います。

あとはちょっと荒っぽい方法ではありますが、PDF内部の上のToUnicode CMapに問題があるので、これを書き換えてしまえばいい。ということで、そういったツールを使えばPDF Viewerで検索できるようになります。私が作ったものもあります。

PDFを作成する場合の対策

もらったものに関してはこれでいいですが、自分で作る場合はどうすればいいでしょうか、という対策を紹介します。一番簡単なのは、トリガーを引かないフォントだけを使う方法です。もちろんおすすめはしません。古いフォントが必要だし、最近のフォントではダメなものが多いです。

例えばMS明朝、MSゴシックはWindowsの一部なので、Linuxなどのサーバーサイドで作るときには「ちょっと使えないよね」というところもあると思うし、アップデートしたら仕様が変わってしまうかもしれない。解決になっていないと思います。

あとは対策済みのPDF作成ツールを使う。これが一番いいと思っています。最新の日本語のTeXは対策済みです。LuaTeXやpTeXなどいろいろありますが、これはUbuntuにもFedoraにもパッケージがあります。OSSだし、インストールも簡単です。

サーバーサイドでPDF帳票など、報告書みたいなものの自動生成にもたぶん使えると思います。定型フォーマットに文書や数字を流し込んで、PDFを作るのはけっこう得意だし、実はこの資料もTeXで作っています。これぐらいきれいなものは作れるということです。TeXは対策済み、では他のツールはどんな対策が必要? というところをちょっと紹介します。

日本語のTeXとpTeX・XeTeXの対策例

CJK(日中韓)系の複雑な事情を、ちょっと考慮しないとうまくいきません。欧米基準で何も考えないと、文字化けしちゃうということです。やることは、先ほど説明した文字化けの発生メカニズムを潰せばいい、ということです。どれかを潰せばいいということで、一応また日本語のTeXの対策の例を紹介します。

問題のあるOSSがあれば、ぜひみなさんで貢献してもらえればと思います。1つ目はLuaTeXで行われている対策です。これは一番簡単、というか極めて正攻法ですが、先ほどの正変換したときの変換元のUnicodeの符号位置を覚えておいて、それでToUnicode CMapを作る方法を採っています。

ただ残念ながら、もしアーキテクチャ的にもとのUnicodeの符号位置がわからなくなって失われてしまうようなフローの場合、この方法は使えないので、その次の対策がpTeXやXeTeXの例です。

cmapテーブルがN対1になっているので、これを考慮します。康煕部首ブロックの優先順位を下げ、複数のUnicodeの符号位置候補がある場合は、優先順位が高いものを使うことをしています。たいていの場合はこれでOKですが、縦書きなどでグリフの置き換えのようなものがあると、うまくいかないこともあります。

ToUnicode CMapを生成しない対策もおすすめ

もう1個、ToUnicode CMapを生成しないという対策も実はあります。これはAdobe-Japan1という規格のフォントの場合に限りますが、実はデメリットがほとんどない、非常にすばらしい方法です。

このAdobe-Japan1、AJ1と言いますが、これは何かというと、日本語に使われるフォントの規格です。日本語で使う文字にCIDを割り当てたもので、1992年ぐらいに最初の版が制定されています。OpenTypeよりも古い歴史がある。そのため、OpenTypeのcmapテーブルに依存しないで、文字コードからCIDを得るという機構があります。

現代的な機構、新しめのモダンなTeXや普通のWindowsアプリは先ほどのOpenTypeのcmapテーブルでCIDに変換しますが、OpenType登場前のpTeXでは、AJ1であることを前提とした方法を使っています。古いとはいえ、まだまだバリバリ現役で広く使われています。

AJ1の場合、なぜ埋め込む必要がないかといえば、共通のToUnicode CMapが使え、フォントを個別で用意する必要がないからです。Acrobat Readerなど、普通のPDF Viewerは自分で持っています。しかもコピペに最適に調整されている。そのため、どんなPDFでもコピペできるし、ToUnicode CMapが入っていない、作成できないツールであっても問題がないと、いいこと尽くめです。

「ないなら作ろう」でできたのが原ノ味フォント

AJ1フォントは非常に良いフォントですが、残念ながら、実用的なAJ1フォントはフリーなものがありませんでした。ないなら作ろうということで、原ノ味フォントを作りました、というのがここから先。

原ノ味フォントは、明朝・ゴシックそれぞれを7ウェイトの全14フォント。これだけあってグリフもすごくいっぱい搭載して、しかも日本語TeXのデフォルト和文フォントに2020年から採用されているし、原ノ味フォントを全面的に使用した書籍が多数出ています。この資料も原ノ味フォントを使っています。

普通に考えれば、商業出版に耐えうる品質の大量のグリフを個人で作れるわけない。これは“巨人の肩の上に立つ”ということで、実はAdobeの源ノフォントを使っています。源ノフォントはたくさんグリフがあって、太さもいっぱいあってすごく良いフォントです。Adobe-Identity0、AI0フォントということで、OpenType前提のフォントになっています。

あとはオープンソースフォント、ここが一番重要です。一定の条件下で、改変や再配布が可能なので、これをAJ1に組換えようということになる。

生成プログラムを作りました。全自動で生成することにして、GUIで手動調整は一切しない。プログラム化できないことはしない、ということをしています。OSSとして公開しています。派生フォントとしては、ちょっと珍しいんじゃないかなと思っています。OSSにしてよかったことは、位置調整が必要なグリフがあり、平行移動させるためにけっこう難しくて大変でしたが、これはコードを貢献してもらって不格好なグリフがなくなりました。これはいいところの1つです。

もう1つは、縦書き用のグリフで不足しているところがありましたが、90度回転や平行移動ができれば作れそうだったので、もらったその平行移動コードをベースに90度回転するコードを実装して、縦書きグリフも解決。全部グリフが搭載できるようになりました。

あとは、プロポーショナルといって文字の横幅がちょっと違うものです。普通のかなは全角幅ですが、こういったグリフも「こうやれば実装できるんじゃない?」とアイデアをもらって、それを実際に実装しました。その他、縦書き用のプロポーショナルなど、かなのグリフはたくさん種類がありますが、こういったものを応用して実装して、かなグリフが充実したところです。

最後です。どんな文字化けなのか、なぜ文字化けするのか、文字化けを修正するにはどうすればいいか、どうすれば文字化けしないPDFが作れるか。あと、原ノ味フォントの紹介をしました。ソースファイルとか関連資料は公開します。不十分なところや間違いがあれば連絡してもらえればと思います。

より詳しく知りたいのであれば、2019年にやったもののほうがもっと詳しいことが書いてあるので、参照してもらえればいと思います。どうもありがとうございました。

司会者:細田さん、発表ありがとうございました。メチャクチャおもしろかったんですが、ちなみになぜこのPDFの文字化けを調べようと思ったんですか?

細田:もともと調べようと思ったわけじゃなくて、実は副産物なんです。「文字化けするよ」という話を聞いて「なるほど」と。調べてみたらこういうToUnicode CMapがおかしいところがわかった感じです。

司会者:私もPDFがコピペできないものとできるものとで「何だこれは?」と思ったんですけど。今回初めてこういう話を聞いて「そんな仕組みになっていたのか!」と。メチャクチャおもしろかったです。

細田:ありがとうございます。もともとLilyPondやTexinfoなど、PDFを扱うようなOSSをやっていたので、うまくハマったという感じです。

司会者:なるほど。細田さん、発表ありがとうございました。

細田:ありがとうございました。