2015年12月18日

EMFに振り回されていた.EMFの描画にPDFiumを使っている.EMFはGDIの命令を集めたようなものだが,PDFiumはGDIの命令でPDFを描画してくれる.というわけで丸流しするコードをかけばすぐにできる……はずだが,自明にやると二つの問題が現れる.

  1. 破線がおかしい.
  2. 画面サイズ以上の大きさが描画できない.

一つ目は,おかしいならば消してしまえば良いと言うことで,Ghostscriptの命令.dashpashをPDFにかませる.長々とできていなかったのにきれいに出てきて感動.

二つ目は,clip regionの問題.GDIには「描くべき範囲」を指定するclip regionというものがある.もともと画面用なので,画面外とかは描かなくて良いよね,ということ.ただ,EMFに書いている場合は何故かこれが画面サイズ(使っているコンピュータの画面サイズです)を超えられない.画面に出力するのならば妥当なのだが,EMFを画像と思っていると理不尽きわまりない.

別に外に描画ができないというわけではない.描画命令を実行すれば描画はできる.しかし普通は外は描画しないべきだし,PDFiumはそうなっている(正しい実装だ).しかし今の場合は都合が悪い.というわけで分割して描くことにした.

たとえば縦100横200が描きたいが,縦横100しか描けないとする.まずPDFiumに普通に描画してもらう.これで左半分は完成する.次にメモる上にEMFを作り,-100の位置を起点にしてPDFiumに描いてもらう.今度は左半分がclip regionの範囲外なので描画されず,右半分のみ描画される.最後にこのメモリ上のEMFファイルの内容を読み込んで(GDIの描画命令セットである)座標を右に100ずらしつつ描く.既存のEMFファイルの中身を新しく描くには,いっぺんに描画してくれるPlayEnhMetaFileと一つ一つ描画するPlayEnhMetaFileRecordがあるが,前者はclip regionの影響を受けるので今回は使えない.というわけで後者で描くことにした.これがclip region考慮していたら詰みだなぁとちょっと焦りながらやったらきちんと出力された.これでだいたい問題なく出力を得ることができるのではないかと思う.

中身が横に一本線が引かれている状態だったらどうなるか.このとき線は左半分にあるので,左半分のみの描画の時にきちんと描画をする.このとき途中で止めるということはせず(どうせ命令としては一つだ)まっすぐ最後まで引く.右半分にもあるので,このときも描画をしなければならず,PDFiumはやはり描画をしてくれる.結果として,出力においては二回線が引かれていることになっていると思う.まぁ見た目には問題ないので.パスをばらして云々とかやると(そんなことができるかは知らないが)破綻するかも.

ちなみにこれ以前には,PDFiumのclip regionを調べるところを書き換えて,常にばかでかい値が返るようにしてた.そしたら,描画の際にその値を参照している箇所があって,固まってしまった.(実際にはすげーでかいループなのだが,実質的には固まったと見なしてよいだろう.)具体的にはパターンを描画している場所なんだけど.更にこの部分はビットマップに振り分ける処理があって,パターンの含まれているPDFを変換するとやたら大きな(200Mとか)ファイルができてしまっていた.とりあえず振り分けのifを消してみたけど,うーん大丈夫かなこれ……

0 件のコメント:

コメントを投稿

コメントの追加にはサードパーティーCookieの許可が必要です