2013-07 << 2013-08 >> 2013-09

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にはそれっぽいのが無いのでアプリ側で持つことに.

pdf0818.png

とりあえず表示はできましたが,

  • 文字のレンダリングはdrawText呼んでるだけなので,文字が重なっている箇所がある
  • 一部の記号が化けている
  • 実装してないので画像は表示されない
  • 実装してないので図形や色も無い

のでまだダメっぽいですね.

あとは,表示できる画像リソースが見つからない時に,テキストのレンダリングを試みているので,表示速度に影響を与えない代わりに,サポートされている画像が入ったページはその画像だけ表示されてしまう.

2013-07 << 2013-08 >> 2013-09