2013-08-18 (日)
*PDFのテキストをレンダリングするための最小限の実装
多少のレイアウトの崩れには目をつぶって,それっぽく,テキストをレンダリングする.
PDFの仕様書のAPPENDIX Aにある「Operator Summary」を見て,重要そうなのから実装していく.
Q BT /CS0 cs 0 0 0 scn /T1_0 1 Tf 9.4 0 0 9.4 51.005 537.89 Tm (8)Tj ET 1.02 w q
こんな文字列がContentsのストリームに入っています.各トークンは空白文字で区切りますが,「(8)Tj」のように明らかに分離できる場合は,スペースを入れなくても構いません(このあたりはPDF全体でそうなってます).
PDFはPostScript由来の後置記法を採用しているので,例えば,Tmの引数はその前にある6個の数値です.
cm,Q,q
グラフィックス系のオペレーターとして書かれているけど,座標変換はテキストにも影響する.
cmで与えられた行列は回転を無視するなら,位置とスケールとして覚えておけば大丈夫.
Q,qでグラフィックスのステートをスタックにpushしたりpopしたりする.
BT,ET
BTでテキスト関係の行列を初期化.ネストしないらしいので,ETは無視しててもとりあえず動きます.
Td,TD,TL,Tf,Tm,T*
このへんはサポートしないとまともに位置が合わない.
話は変わるけど,字句解析から自前でやってたら,T*とかいうオペレータがあったの忘れてて,少し面倒くさかった.
Tj,TJ
Tjは1つの文字列を描画する.TJは文字列の間に位置のオフセット情報が入った配列を受け取り,描画.
ここまでできた
自炊本リーダー(仮)に実装してみて,今まで真っ白に表示されてた普通のPDFを開いてみたところ.CIDのマッピングは,Adobe-Japan1に限定.UnicodeとCIDのマッピングはフォントが持って居そうだけど,AndroidのAPIにはそれっぽいのが無いのでアプリ側で持つことに.
とりあえず表示はできましたが,
- 文字のレンダリングはdrawText呼んでるだけなので,文字が重なっている箇所がある
- 一部の記号が化けている
- 実装してないので画像は表示されない
- 実装してないので図形や色も無い
のでまだダメっぽいですね.
あとは,表示できる画像リソースが見つからない時に,テキストのレンダリングを試みているので,表示速度に影響を与えない代わりに,サポートされている画像が入ったページはその画像だけ表示されてしまう.