doraTeX / TeX2img

TeX2img for macOS
https://tex2img.tech
Other
26 stars 2 forks source link

テキスト形式のEPSを出力する機能 #52

Closed doraTeX closed 8 years ago

doraTeX commented 8 years ago

テキスト形式のEPSでなければ問題が起こるケースに対処するために,eps2write デバイスによってEPS出力する場合に,pdftops を用いてテキスト形式のEPSに変換する機能を付けるとよいのでは。

仕様案

EPS出力かつ gs>=9.15 かつこのオプションがONの場合には,次の変換経路で変換する。

TeX (→ DVI ) → PDF →[gs(eps2write)でアウトライン化+クロップ] → EPS →[epstopdf(gs)]→ PDF →[pdftops] → EPS (→[BB情報を編集して余白付与] → EPS)

pdftops のオプション

pdftops -eps in.pdf out.eps
aminophen commented 8 years ago

そういえばそんな調査していました… まだ pdftops が本当にテキスト形式の EPS しか出さないのかどうか自信がありませんので、もう少し検証させてください。

doraTeX commented 8 years ago

少し試してみたところ,gsでビットマップ化されてしまう🍣の例「理」の例もテキスト化されていたので,常にテキスト形式で出力できるものと考えてよさそうです。 そちらでもぜひ色々な例で検証してみてください。

aminophen commented 8 years ago

気になる点を挙げておくと:

たとえば元の eps2write が出した EPS が

%%BoundingBox: 289 104 523 758
%%HiResBoundingBox: 289.983991 104.781997 522.031984 757.903977

の場合、そこから epstopdf と pdftops を経た EPS では

%%BoundingBox: 0 0 233 654
%%HiResBoundingBox: 0 0 232.05 653.12

という値になりました。どうやら epstopdf + pdftops 全体としては「元の EPS の HiRes の値を演算して左下が 0 0 になるように描画しなおし、新しい HiRes を小数点以下2桁まで求め、それを包含するように非 HiRes の値も書き込む」ように見えます。この影響がどの程度生じるのか、まだわかっていません。

doraTeX commented 8 years ago

「テキスト形式の EPS を出力」という表現から「(PDF のように)テキストを保持した EPS だろうか」という誤解が生じないように配慮する必要があります。

それはUIの表現次第で何とかなるのではないでしょうか。 「プレーンテキストで出力する (EPS)」(英語版:Output as plain text (EPS) とかはいかがでしょう。

EPS の中身がバイナリかテキストかということを意識しているユーザは少ないはずですので、選択させるメリットはあるのだろうか(一方に固定するか、あるいは高度なオプションとして隠すかでも良いのでは)

  • バイナリEPSに固定すると,テキストEPSが要求されるケースで困る。
  • テキストEPSに固定すると,「GUI版TeXimg も pdftops もインストールされていない状況下ではCUI版TeX2imgでのEPS出力が利用できない」となってしまう。

という問題が生じます。 (後者の場合,自動的にバイナリEPS出力にフォールバックさせるという手もありますが。)

どうやら epstopdf + pdftops 全体としては「元の EPS の HiRes の値を演算して左下が 0 0 になるように描画しなおし、新しい HiRes を小数点以下2桁まで求め、それを包含するように非 HiRes の値も書き込む」ように見えます。

確かにBBの原点の変化はちょっと怖いですね。

37 のような例についても検証が必要です。

余白付与については,pdftops 後に実行するようにしておけば問題ないでしょうね。

aminophen commented 8 years ago

「プレーンテキストで出力する (EPS)」なら伝わりそうです。いずれにせよその意義を FAQ に書いておかないと、Forum の質問のような場合に気づいてもらえない可能性が高いですね。(「○○というソフトで EPS を作ったら貼りつくのに TeX2img で作ったら貼りつかない」というときに、「EPS は PostScript 言語で書かれたテキストだったはずだ」という知識がないと「EPS の中身に違いがあるのでは」のような発想にそもそも至らないので)

BB の変化についてはもう少し慎重に調べる必要がありますね。従来の EPS に epstopdf + pdftops を通すと余白の付き方が微妙に変わってしまうことは確認できました。

EPS の左下が epstopdf + pdftops では常に 0 0 なので、ここに余白を付けると必ず BB がマイナスになる…けれど従来の場合も余白が大きければマイナスになりえたので同じですかね?

doraTeX commented 8 years ago

どうやら epstopdf + pdftops 全体としては「元の EPS の HiRes の値を演算して左下が 0 0 になるように描画しなおし、新しい HiRes を小数点以下2桁まで求め、それを包含するように非 HiRes の値も書き込む」ように見えます。この影響がどの程度生じるのか、まだわかっていません。

これは,epstopdf でPDFに直したときに,PDFのMediaBoxの左下が(0,0)になるようにボックスが再調整されるためにおこるもので,pdftops はそれを引き継いでいるに過ぎないようです。

aminophen commented 8 years ago

これは,epstopdf でPDFに直したときに,PDFのMediaBoxの左下が(0,0)になるようにボックスが再調整されるためにおこるもので,pdftops はそれを引き継いでいるに過ぎないようです。

ということは、BB の値が変わることは問題なさそうですね。

doraTeX commented 8 years ago

余白付与については,pdftops 後に実行するようにしておけば問題ないでしょうね。

余白付与と pdftops の順序を逆にしました。 この方が,余白付与後の epstopdf + pdftops コンボによってBBの原点が (0,0) にリセットされるので,最終生成物に負のBB値が出てこなくて済みます。

それに何より,epstopdf はゼロサイズのEPSに弱いという問題に対する対処という点が挙げられます。 「EPSを epstopdf + pdftops でプレーンテキスト化する」という処理を行うとき,余白付与によって最終的に白紙ページになるはずのゼロサイズのEPSをこの経路にかけるとエラーになってしまいます。事前に余白付与を済ませておけばゼロサイズでなくなるのでこの問題が回避できます。

整理すると,経路は以下の7通りとなります。

gsを通さない経路

  1. 速度優先モードでのビットマップ生成 (PDF →[pdfcrop類似処理でクロップ]→ PDF →[Quartz API でビットマップ化+余白付与]→ JPEG/PNG/GIF/TIFF/BMP)
  2. テキスト情報を残したPDF生成 (PDF →[pdfcrop類似処理でクロップ+余白付与]→ PDF)
  3. テキスト情報を残したSVG生成 (PDF →[pdfcrop類似処理でクロップ+余白付与]→ PDF →[mudraw]→ SVG)

gsを通す経路

  1. 画質優先モードでのビットマップ生成 (PDF →[gs(eps(2)write)でアウトライン化[*1]+クロップ]→ EPS →[epstopdf(gs)]→ PDF →[Quartz API でビットマップ化+余白付与]→ JEPG/PNG/GIF/TIFF/BMP)
  2. アウトライン化PDF生成 (PDF →[gs(eps(2)write)でアウトライン化[*1]+クロップ] → EPS →[epstopdf(gs)]→ PDF →[pdfcrop類似処理で余白付与]→ PDF)
  3. アウトライン化EPS(バイナリ形式)生成 (PDF →[gs(eps(2)write)でアウトライン化[*1]+クロップ] → EPS →[BB情報を編集して余白付与] → EPS)
  4. アウトライン化EPS(テキスト形式)生成 (PDF →[gs(eps(2)write)でアウトライン化[*1]+クロップ] → EPS →[BB情報を編集して余白付与] → EPS →[epstopdf(gs)]→ PDF →[pdftops])

[*1] このgsによるアウトライン化は,画質優先モードの場合は -r20016 固定,速度優先モードの場合は解像度レベル設定に従う

doraTeX commented 8 years ago

Ver. 2.0.6 beta 1 が完成しました。

Ver. 2.0.6 beta 1 での改良点

aminophen commented 8 years ago

Ver. 2.0.6 beta 1 の TeX2img.app が正しく梱包されていない…?

doraTeX commented 8 years ago

確かにアーカイブが壊れていましたので差し替えました

aminophen commented 8 years ago

「gs9.15 以上の eps2write 経由時に、Xpdf の pdftops を使ってテキスト形式の EPS を出力する」は成功しているようです。

「あいうえお」を EPS 化していて気づいたのですが、eps2write は epswrite に比べて書き込む量が膨大に増えていて、それを隠すためにバイナリ化圧縮しているようですね。pdftops でそれをプレーンテキストにするとかなり量が減るので、バイナリより軽くなっています。サイズとしては「gs9.14 以前の epswrite < Xpdf の pdftops < gs9.15 以降の eps2write」になる傾向があります。

aminophen commented 8 years ago

54, #55 のバグも直っていました。いままで全然気づきませんでした…

doraTeX commented 8 years ago

eps2write は epswrite に比べて書き込む量が膨大に増えていて、それを隠すためにバイナリ化圧縮しているようですね。pdftops でそれをプレーンテキストにするとかなり量が減るので、バイナリより軽くなっています。サイズとしては「gs9.14 以前の epswrite < Xpdf の pdftops < gs9.15 以降の eps2write」になる傾向があります。

つくづく,なぜ epswrite を廃止する必要があったのかと残念に思います……。

abenori commented 8 years ago

Ghostscriptで何とかならないかと,なんとなくググってみたら,気になるものを見つけました. http://d.hatena.ne.jp/yshl/20070515/1179199949 全然わからないので使えるかさっぱりですが……

aminophen commented 8 years ago

Ghostscriptで何とかならないかと,なんとなくググってみたら,気になるものを見つけました.

/LZWDecode をデコードできないと書いてあるようで、ちょっと厳しそうです… gs9.05 の epswrite が吐いたプレーンテキストな EPS を食わせると「コメント行以外をそっくりそのまま stdout に吐く」ことはわかったのですが

ようです… まあ 2007 年のスクリプトだから無理はないですが、もっと調べるとスクリプトで Decode する方法があるのかもしれません。

abenori commented 8 years ago

そもそもだめなのはLZWそのものなんですね……

一応全部テキストなepsをWordに食わせても読めないと悩んでいました……

WordはPostScript 3.0(とそれ以前)をサポートしているようですが,LZWが入れられるようになったのはその後,という理解でいいんでしょうか?それとpdftopsがLZWを入れないかどうかはよくわからない(一応なっているみたいだが)ということでOK?

aminophen commented 8 years ago

pdftops が LZW を入れないかどうかはソースを見れば分かるかもしれません😏

Windows の場合は pdftops が TeX Live (win32) でも W32TeX でも入っていると仮定してよいはずですので、直接これを呼べば良いでしょうね。

abenori commented 8 years ago

正直なんかやる気が出ないです.なんか繰り返しもありますが.

aminophen commented 8 years ago

「LZWを入れない」というのと「テキスト出力」とは同値ではない.

まさにおっしゃるとおりです。フォーラムに「LZW バイナリがあるから」と回答したのは“無難な正解”で、LZW が原因なのかバイナリが原因なのか当時よくわかっていなかったのです。今も私は手元で「LZW もバイナリも存在しない EPS」と「LZW もバイナリもともに存在する EPS」しか試していないため、はっきりしたことはわかっていません(数か月前の検証段階で pdftops を結論とするのは短絡的だと思ったのもこれが理由だった気がする)。ただ、pdftops がテキスト形式の読める EPS を出すのは確かなので、Mac 版にとりあえずその機能を付けたのは悪くないと思っています。

まだ分かっていない多い状態ですので、もう少し慎重に調べてみます。

abenori commented 8 years ago

何かわかったらよろしくお願いします……が,いずれにせよインストール作業が必要なものを使うのは気が引けます.

pdftops がテキスト形式の読める EPS を出すのは確か

そういう例しか観測されていない,が正しい?(「説明書」にあるのかという質問です.)

aminophen commented 8 years ago

そういう例しか観測されていない,が正しい?

はい。説明書にその手のコメントがないので例で観測するほかなく、そういうことになっています。

…といったところで、doraTeX さんの実験で登場した sushi.pdf を試したところ、gs9.16 の場合のみバイナリが入っています。これは手元では Word 2010 に貼りつけることに成功していません…訂正:かなり動作が重いだけで、貼り付けはできていました。Windows 版 TeX2img で「アウトライン化 PDF」を出力した後、pdftops で変換するという実験を行うと

とりあえずここに置きます。

gs9.16 のあとに pdftops が吐いた EPS は「LZW はないが、バイナリはある」っぽいです。ということは、LZW があることが Office 貼り付け不能の原因なのかもしれません。

追記:「gs9.16 の eps2write + pdfwrite のあと pdftops を通した EPS」は、Word への貼り付けと表示は成功しましたが、保存時に PDF 形式を指定すると PDF には図が出てきませんでした。

doraTeX commented 8 years ago

「LZW はないが、バイナリはある」

equation-916.eps は,モノとしてはテキストファイルに見えますが。

ちなみに,Mac版Wordでは,epsが貼り付けられると内部的にPDFへ変換してから貼り付けているように見えます。そのため,gs 9.16 の eps2write で出力したEPSも貼り付け可能です。 ですから,今回増設した「プレーンテキストEPS出力」機能は,Mac版では特に目に見えるメリットはありません。EPSがプレーンテキストである方が何かと扱いやすい場面もあるだろうと思って付けました。(テキストエディタで中身を簡単に覗ける安心感とか……)

aminophen commented 8 years ago

equation-916.eps をテキストエディタである Emacs で開いているのですが、一万行目付近にテキストとは思えないものが多発しますが…

equation-916-emacs

doraTeX commented 8 years ago

そのあたりも一応ASCII文字っぽいですよ。

2015-10-20 23 44 58

↑ A → U+0041

doraTeX commented 8 years ago

この部分は,PostScript Language Reference の3.2.2節に規定された ASCII base-85 filterに従ってバイナリをテキストへエンコードした部分で,3.13.3節に規定された ASCII85Decode filter でこれをバイナリにデコードする処理が equation-916.eps の457行目に /ASCII85Decode filter として書かれていますね。

参考:PostScript言語 / ファイルとフィルタ

aminophen commented 8 years ago

この部分は,PostScript Language Reference の3.2.2節に規定された ASCII base-85 filterに従ってバイナリをテキストへエンコードした部分で

ああ、本当ですね。だいぶ上の方に /ASCII85Decode filter とあるのも見落としていました。こういうのだったら Windows の Office でも解釈できるのですね。

aminophen commented 8 years ago

…ということは、gs9.16 の eps2write で「LZW バイナリ」と呼んでいたものは /ASCII85Decode filter /LZWDecode filter とあることを加味すると、正確には「LZW バイナリを ASCII base-85 filter に従ってテキストへエンコードした部分」ということですね(ということは結局これもテキスト…?)。

doraTeX commented 8 years ago

その部分はテキストですが,その後に,/ASCII85Decode filter を伴わない /Filter/LZWDecode が現れ,本物のバイナリが登場し始めます。よって,eps2write を通したものは,EPSファイル全体としてはバイナリファイルとなっています。

2015-10-21 0 12 17

↑sushi.pdf を eps2write で処理した結果のeps

aminophen commented 8 years ago

その後に, /ASCII85Decode filter を伴わない /Filter/LZWDecode が現れ,本物のバイナリが登場し始めます。

ああ、そこはまさに -dCompressPages=false をもってしても decode できなかった部分です。/ASCII85Decode された /LZWDecode の部分は -dCompressPages=false を使えば圧縮されないのですが、その後に来る“本物のバイナリ”を gs のみで Decode する方法をいまだに見いだせていないのです。

abenori commented 8 years ago

そのため,gs 9.16 の eps2write で出力したEPSも貼り付け可能です。

Macずるい…….

テキストにしたいだけならば-dASCII85EncodePages=trueでエンコードしてしまえばよいのですが,Windowsの方はWordに張り込めるのをやはり目的とした方がよいですよね…….

現れた/LZWDecodeをすべてデコードしたものに置き換える,というのはさすがに面倒だろうか.

doraTeX commented 8 years ago

テキストにしたいだけならば-dASCII85EncodePages=trueでエンコードしてしまえばよいのですが,

そんなオプションがありましたか……!

まあ,-dASCII85EncodePages=true で出力したテキストEPSは,「実質全体が ASCII base-85 でエンコードされた意味不明な文字列からなるテキスト」になるのに対し,pdftops で出力したテキストEPSは「読めるテキスト」になるという違いがありますので,Mac版に pdftops を内蔵した意義は一応あったということにしておきましょう。 (sushi.pdf の場合は,埋め込み画像の部分があるので pdftops した後にも ASCII85 の部分が現れますが,普通の文字だけの書類を pdftops にかけた場合,ASCII85 部を含まない「完全に読める」EPSを出力してくれるようです。)

abenori commented 8 years ago

上で出ている-dCompressionPage=falseと組み合わせるとかなりの部分がEncodeされていないファイルにはなるのですが,なんだか長ったらしくてよくわかりません……上でも話になっていましたが,pdftopsで出した方が素直には見えますね.(といってもEPSを読もうとする変態がどのくらいいるかは謎ですが…….)

eps2writeがはき出したファイルはPDFみたいです.

abenori commented 8 years ago

ふとGhostscriptを9.18にあげてみたら,次のtest_gs.epsができました.どうも見たところLZW圧縮はないように見えますが,やはりWordへははりこめません.

https://onedrive.live.com/redir?resid=4FABCB4EC4FA1E70!16825&authkey=!ANYoMX5Yq7PLXU4&ithint=folder%2cexe

aminophen commented 8 years ago

テキストにしたいだけならば-dASCII85EncodePages=trueでエンコードしてしまえばよいのですが

それも昔試した記憶が… でもバイナリをエンコードしたにすぎないので読めないと判断し、やめたと思います。フィルタに関係ありそうなオプションは私なりにいったんは試したような状態です。

ふとGhostscriptを9.18にあげてみたら

私も gs9.19 git prerelease をたまたま数日前に Windows で git clone していたので試したところ、-dCompressPages=false の有無によらず「ほぼ」圧縮なしの EPS になりました(最後の方にちょっとだけ意味不明な文字列がある)。LZW はないようですが、やはり Word へはりこめませんね。

評判が悪くてデフォルトを -dCompressPages=true ではなく false に変更したのだろうか。

abenori commented 8 years ago

ともかく小手先ではWordには対応させられなさそうなので,この件は忘れることにします.ご迷惑をおかけしました.

aminophen commented 8 years ago

そろそろ「TeX2img でどの画像まで対応するか」をはっきりさせたほうがよいということですね。依存ツールを抱え込むのも、mudraw くらいなら軽いですし Win 版の pdfiumdraw は他で難しい EMF のための需要があるのであって欲しいですが、これ以上増やすのはあまり乗り気がしないです。万能神話はあくまで神話ですし、私もそれは求めていません。

pdftops も結局どんな場合でもプレーンテキストを出せる保証がないので、どうなんでしょうかね。「テキスト形式の EPS が必要なら、pdftops をインストールすればできるかもしれません」程度の情報を FAQ に書いておくほうが無理がないのかもしれません。依存ツールが増えないならまだしも、「増やしても完全なテキストになるとは保証できない」だとモチベーションが起きないのもわかります。