doraTeX / TeX2img

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

pdftopsを通す「プレーンテキストのEPS出力」時にアウトラインがとられていない / 半透明が含まれるページ以降を eps(2)write で処理すると汚くなる #70

Closed doraTeX closed 8 years ago

doraTeX commented 8 years ago

変換経路図に反して,pdftopsを通す「プレーンテキストのEPS出力」を行うと,pdfwrite によるアウトライン化を行わずにEPS変換に進んでしまっている。変換の実装が誤っているので修正すべき。

aminophen commented 8 years ago

テキスト形式 EPS 出力でもう一つ問題を見つけました。途中の「複数ページ PDF を pdfTeX でクロップ+余白追加したことで生き残った白紙ページの temp***-trim.pdf を gs9.16 の pdfwrite によるアウトライン化にかける段階」で警告が出ます。

$ /usr/local/bin/gs -dNOPAUSE -dBATCH -sDEVICE=pdfwrite -dNoOutputFonts -r2160 -sOutputFile=temp-pdfwrite.pdf -dFirstPage=1 -dLastPage=1 -dAutoRotatePages=/None -c .setpdfwrite -f temp-trim.pdf 2>&1
Processing pages 1 through 1.
Page 1
   **** Warning:  File has an empty MediaBox. Using the current page size instead.
   **** Warning:  File has an empty MediaBox. Using the current page size instead.

   **** This file had errors that were repaired or ignored.
   **** The file was produced by: 
   **** >>>> pdfTeX-1.40.16 <<<<
   **** Please notify the author of the software that produced this
   **** file that it does not conform to Adobe's published PDF
   **** specification.

この結果、クロップしたはずなのにページが A4 サイズに戻されてしまいます。なぜ「複数ページ PDF の中にある生き残った白紙ページ」だけこの警告を出すのか分かりません…

ソースリポジトリのテストケース35が該当します。

aminophen commented 8 years ago

gs9.16 で試しています。アウトライン化した PDF の場合は

で警告なし。ということは、アウトライン化したテキスト EPS の場合も

でいいのではないでしょうか?

aminophen commented 8 years ago

Ver. 2.1.4 beta 4 で直りました。ありがとうございます。

aminophen commented 8 years ago

gs9.05 で実験したところ、EPS 出力時に余白0で「TeX2img: [警告] 1, 3, 5 ページ目が空白ページであったためスキップしました。」といいながら真っ白な EPS を吐いていることに気づきました…

GUI 版で「ソースファイルと出力先が同じで、かつ作業ディレクトリがファイルと同じ場所」の場合に起きています。「吐いたあとに削除する」という例外処理になっていて、消し忘れ…?

doraTeX commented 8 years ago

手元の gs 9.10 ではそれを再現することができておりません……。 他のパラメータに依存している可能性もあります。 CUI版でも再現するでしょうか。再現できる場合はそのインプットファイルとCUIオプションの状態をお願いいたします。

一カ所,それとは直接の関係はないかもしれませんが,「単一ファイルにまとめる」のチェックボックスの状態のON/OFFが,単一ファイルにまとめられない出力形式の場合の作業ファイルの削除の仕方にも影響を及ぼしている不具合を見つけましたので,そこを修正した Ver. 2.1.4 beta 5 を作りました。 こちらで改めてお試しください。

aminophen commented 8 years ago

単一ファイルにまとめられない出力形式の場合の作業ファイルの削除の仕方

確かにそのバグも先ほど見つけましたが、それとは別でした。カレントに tex2img と "sam ple.tex" を置いた状態で、Ver. 2.1.4 beta 5 でも

./tex2img --workingdir=current --quick --margins 0 --background-color 00CC88 "sam ple.tex" "a b.eps"

で起きます。Quartz の背景色塗りが例外処理できていなくてその先に進むようです。

doraTeX commented 8 years ago

Ver. 2.1.4 beta 6 で対処できたと思います。

aminophen commented 8 years ago

Ver. 2.1.4 beta 6 で対処できたと思います。

直りました。ありがとうございます。

全然テストが終わらない…😱

aminophen commented 8 years ago

gs9.05 でアウトライン化 PDF / EPS を出力すると「ほげほーげ」より後の全てのページが汚くなることを見つけました。gs が苦手な半透明の画像より後のページがすべて汚いことになります。汚くなくていいはずの数式のページも汚くて、原因が全く分かりません…

ちなみに test.sh がそのままだと VMError で落ちるので、この部分が検証できませんでした。

doraTeX commented 8 years ago

ちなみに test.sh がそのままだと VMError で落ちるので、この部分が検証できませんでした

gs 9.15 未満で実験する際には,sam ple.tex の 「ほげほーげ」のページはコメントアウトして実験していましたので,この問題には気づいていませんでしたが,本当ですね。

不思議なことに,この現象は,事前にPDFを1枚ずつpdfcrop類似処理で砕いておいてもなお発生します。 元々「shadowsがある以降のページ」であったページは,たとえその後バラバラに砕いても,何かその名残が残っているのか,epswrite の結果が汚くなりますね。

これは gs のバグとして放置するということでよいのではないかと思います。

aminophen commented 8 years ago

これは gs のバグとして放置するということでよいのではないかと思います。

そうしましょう。

aminophen commented 8 years ago

gs9.05 の EMF 出力で、白紙ページがそのまま出てくるようです。背景が透過でも塗りでも、余白が0なら起こります。epswrite が次の警告を出しています:

   **** Warning:  File has an empty MediaBox. Using the current page size instead.
   **** Warning:  File has an empty MediaBox. Using the current page size instead.

   **** This file had errors that were repaired or ignored.
   **** The file was produced by: 
   **** >>>> pdfTeX-1.40.16 <<<<
   **** Please notify the author of the software that produced this
   **** file that it does not conform to Adobe's published PDF
   **** specification.
doraTeX commented 8 years ago

2.1.4 beta 7 で修正できたと思います。

aminophen commented 8 years ago

beta 7 は大丈夫でした。ちまちま粗探ししているようでなんだかすみません😥 gs9.14 以下のスキームが複雑すぎて、把握するのに手間取っているもので…

doraTeX commented 8 years ago

いえいえ,きめ細かいチェック,大変助かります m(__)m

aminophen commented 8 years ago

いちばん謎なのが gs9.15 未満の赤い波線の経路です…「非透過アウトライン化 PDF」を経由する画像だけいったん pdfTeX を通す理由がわかっていません… ほかは意図がなんとなく読み取れるのですが。

doraTeX commented 8 years ago

Quartz API で背景塗りをするときは,

  1. ファイルからPDFデータを読み込む
  2. 背景を塗る
  3. データをPDFとして書き込む

という動きをするのですが,3. において,ページごとにMediaBoxの大きさが異なるPDFを書き出すことができないようなのです(もっとちゃんと調べればやり方があるのかもしれませんが)。それゆえ背景塗りを行う前に,PDFをページごとにバラバラに砕いています。

aminophen commented 8 years ago

ありがとうございます。先ほどの「ほげほーげ」以降が全て汚くなる件をもう少し調べると

という挙動を示します。さきほど

たとえその後バラバラに砕いても,何かその名残が残っているのか,epswrite の結果が汚くなりますね。

とおっしゃっていましたが、背景色塗りを入れた EPS だけ綺麗になります。なにか変換経路と関係ありますでしょうか?

doraTeX commented 8 years ago

余白なしなら,

という経路の違いとなります。

透過EPSの場合,epswrite が処理する対象は「pdfTeXによってページごとにばらされたPDF」であるのに対し,非透過EPSの場合,「Quartz API が保存したPDF」になります。

先程の

たとえその後バラバラに砕いても,何かその名残が残っている

という仮説に基づいてさらに推測すると,

「Quartz API でPDFを保存し直すと,その『名残』が消える『PDFロンダリング』が行われる」

という仮説を立てることができます。

doraTeX commented 8 years ago

このロンダリング仮説に基づけば,

./tex2img --quick --background-color 00CC88 "sam ple.tex" abc.pdf は汚い

は,次のように説明できます。 この場合は

という経路になります。 これは epswrite によってロンダリング前のPDFのアウトライン化が行われて「汚さが確定」してしまうため,後から Quartz API 保存してもロンダリングできない,と説明することができます。

aminophen commented 8 years ago

Quartz API でPDFを保存し直すと,その『名残』が消える『PDFロンダリング』が行われる」

それはありえますね。一度試してみる価値はあると思います。(仮にその方法が成功すれば、gs あるいは pdfTeX で何かまたフィルタを見つければ回避できるかも!?)

doraTeX commented 8 years ago

そのためには,透過ベクター画像を出力する場合にも,まずは赤波線の経路を通し,pdfcrop類似処理にかけてPDFをページごとにばらす必要がありますね。

aminophen commented 8 years ago

透過ベクター画像を出力する場合にも,まずは赤波線の経路を通し,pdfcrop類似処理にかけてPDFをページごとにばらす必要がありますね。

確かに。「半透明のページ以降の描画が綺麗になるようにする」というモチベーションは大きいです。まだ gs9.15 未満の経路は最適化の余地があるということですね。

aminophen commented 8 years ago

まだ gs9.15 未満の経路は最適化の余地があるということですね。

gs9.15 以上の eps2write もやはり同じ問題が発生するようです(pdfwrite でアウトライン化したほうはセーフ)。「gs9.15 以上で EPS 透過」を出力するときも、一律に pdfTeX でばらしてロンダリングしたほうがよさそうです。

doraTeX commented 8 years ago

eps(2)write 実施前にPDFロンダリングを行うようにしてみました。 ここまでに挙がってきた「汚い出力」のパターンはつぶせたように見えますが,いかがでしょうか。 Ver. 2.1.4 beta 8

aminophen commented 8 years ago

beta 8 は明日にでも試します…

Quartz が有効ということは、なにか鍵になるフィルタがあるのだと思います。半透明より後のページを

  1. Quartz を通さずに gs9.10 でアウトライン化した場合
  2. Quartz を通してから gs9.10 でアウトライン化した場合

の EPS か、もしくは Quartz を通す前後の PDF をいただければ、中身を読んで違いを見つけられると思います。解析する価値はあります。

doraTeX commented 8 years ago

テストファイル一式 を用意しました。

Quartz API によるロンダリング仮説がますます実証されてきています……。

aminophen commented 8 years ago

beforeLaundering の PDF には /Group<</S/Transparency/CS/DeviceGray>> が登場していて、 afterlaundering の PDF には登場していないのがチョット怪しいです。original.pdf の4ページ目と6ページ目も同様の PDF / EPS のセットをいただけますか?

doraTeX commented 8 years ago

こちらです

aminophen commented 8 years ago

Quartz 前後の EPS を比べると、page 4 同士はほぼ変化なし・page 6 同士は両方とも“汚さ”が同等ですね。page 7 以降だけが Quartz 前後で EPS に大きな変化が表れているということです。

先ほどの指摘はビンゴでした。PDF の中を見ると

このオペレータの存在がカギになるようなにおいです。さて、Quartz の代替が pdfTeX にできるでしょうか?(仮にできれば「ページをばらしながらロンダリングする」という処理ができ、Win / Mac ともに有用そう)

それから、Quartz を通すと PDF Version が 1.3 に落ちるのも若干においます(が、大事なのはたぶん /Transparency の方)。

aminophen commented 8 years ago

gs の pdfwrite を通すだけで Quartz と同じことができますね。

$ gs -sDEVICE=pdfwrite -dBATCH -dNOPAUSE -sOutputFile=out.pdf -c .setpdfwrite -f in.pdf

これだけで「半透明が実在するページは現状維持(/Transparency を残す)」「半透明が実在しないページは /Transparency を排除」が可能です。こうすると、半透明が実在しないページについて eps(2)write が成功します。ただ、問題点はやっぱり gs が縦書き CJK を苦手とすることです。pdfwrite をテキスト保持 PDF に通してしまうとグリフの位置が乱れてしまい、嬉しくありません。なんとか pdfTeX でやりたいですね…

とりあえず Mac 版は Quartz が有効ですので、いまの beta 8 の方法が妥当だと思います。

まさか Quartz も縦書き PDF が苦手ということはないですよね…?(もし苦手だったら背景塗りから pdfTeX でやり直さないといけないことになってしまう…)

doraTeX commented 8 years ago

なるほど,調査ありがとうございます。 お陰様で,色々合点がいきました。

以前書いたように,Preview.app は半透明PDFの表示を苦手としています。 これと根が同じと思うのですが,Quartz API は,

という仕様のようです(明文化した仕様が見つからないのですが……)。

Page 6 の影の部分が,変換経路によって維持されたり失われたりするのを怪訝に思っていたのですが,途中で Quartz API を経由する経路だった場合に /Transparency が失われる,ということだったのですね。動きが理解できました。

まさか Quartz も縦書き PDF が苦手ということはないですよね…?(もし苦手だったら背景塗りから pdfTeX でやり直さないといけないことになってしまう…)

少なくとも El Capitan なら大丈夫なようです。PDF描画エンジンはOSのバージョンごとに改善されていますから,過去のOSについては要調査です。

aminophen commented 8 years ago

Page 6 の影の部分が,変換経路によって維持されたり失われたりするのを怪訝に思っていたのですが,途中で Quartz API を経由する経路だった場合に /Transparency が失われる,ということだったのですね。動きが理解できました。

「Quartz による背景塗り」、または「塗らないけど Quartz でロンダリングする」という処理によって逆に汚くなる例はないでしょうか? (例えば半透明のページそのものがテキスト保持 PDF で汚くなるとか半透明でなくなるとかだと、一律に Quartz に通すのは躊躇します。)いったん調べておきましょう…

doraTeX commented 8 years ago

現状では,「Quartz によるPDFロンダリング」は,最終出力がEPSの場合にのみ行います。 EPS出力では,epswrite / eps2write / pdftops のいずれも元々半透明は苦手としているので,「ロンダリングによってより汚くなる」ということはないと思います。

「背景塗りを行うことによって結果的にロンダリングされる」場合は,確かに半透明部分がロスすることになります。テキスト保持PDF出力などで,背景塗りを行う場合と行わない場合で,サンプルの6ページ目の影の部分の見た目が変化するという状況は確かに発生していたと思います。

aminophen commented 8 years ago

現状では,「Quartz によるPDFロンダリング」は,最終出力がEPSの場合にのみ行います。EPS出力では,epswrite / eps2write / pdftops のいずれも元々半透明は苦手としているので,「ロンダリングによってより汚くなる」ということはないと思います。

では大丈夫ですね。それなら、仮に Quartz がなかったとしても gs でも全く問題ないことになります。(どうせアウトライン化するなら同じ)

aminophen commented 8 years ago

beta 8 はいい感じになっていますね。ありがとうございます。

まだ経路図をよく理解できていないので、あとでもう少しゆっくりテストしてみます。

doraTeX commented 8 years ago

補足:

現状では,「Quartz によるPDFロンダリング」は,最終出力がEPSの場合にのみ行います。 EPS出力では,epswrite / eps2write / pdftops のいずれも元々半透明は苦手としているので,「ロンダリングによってより汚くなる」ということはないと思います。

この説明は gs 9.15 以上を利用している場合の話です。(最終出力がEPS以外の場合は,eps2write ではなく pdfwrite を使うので,ロンダリングが不要です。)

一方,gs 9.14 以下の場合は,最終出力がEPSの場合でなくても,アウトライン化PDFなどを生成する場合,アウトライン化に epswrite を使用します。その場合同じ問題が生じますので,beta 8 では,最終出力がEPSでなくても途中に epswrite によるアウトライン化を挟む経路の場合は「epswrite にかける直前にPDFロンダリング」を行うようにしています。

aminophen commented 8 years ago

ところで EPS 出力の場合ですが、「白紙ページ」で「ページサイズ維持 ON」にした場合、どういう画像が出てくるのが正解でしたっけ…? 維持したなら白画像が出てくるのかなと思ったのですが、手元では、白紙ページだけ「ページサイズ維持 OFF」の場合と同じになっています。

doraTeX commented 8 years ago

ところで EPS 出力の場合ですが、「白紙ページ」で「ページサイズ維持 ON」にした場合、どういう画像が出てくるのが正解でしたっけ…? 維持したなら白画像が出てくるのかなと思ったのですが、手元では、白紙ページだけ「ページサイズ維持 OFF」の場合と同じになっています。

「維持したなら白画像」となるはずです。こちらの手元ではそうなっているように見えるのですが,問題が生じる場合の各種設定値をお教え頂けますでしょうか。

doraTeX commented 8 years ago

すみません,確かに gs 9.10 で再現しました。 Ver. 2.1.4 beta 9 で修正できたはずです。

aminophen commented 8 years ago

Ver. 2.1.4 beta 9 で修正できたはずです。

直りました。(gs9.16 でも gs9.05 でも白紙ページがサイズ維持されずクロップされていた問題が解消しました:bbox が違っていたようです)

aminophen commented 8 years ago

Mac 版、ベクター画像だけ調べましたがたぶん意図どおりになっていると思います。変換経路図についてですが、pdfTeX をかけているときにそれぞれどういう効果を担っているのかもうすこし知りたいです。

それと「pdfTeX を通す場合・eps(2)write のクロップを信用せずに上書きする場合」に bb が必要になると思いますが、どの段階で取得してその値がどこに使われているのかも知りたいです。

以上の2点がわかれば、目的とする画像がちゃんと出ているかどうかの参考になります。

doraTeX commented 8 years ago

そのあたりの詳細は非常に場合分けが多くてややこしく,正確な実装は Converter.m- (BOOL) compileAndConvert から追いかけていくしかないのですが,簡単に言いますと:

aminophen commented 8 years ago

それだけ情報があれば追いかけられます。ありがとうございます。

doraTeX commented 8 years ago

概ね問題なさそうなので,一旦このあたりで Ver. 2.1.4 としてリリースすることにいたしましょう。

aminophen commented 8 years ago

一旦このあたりで Ver. 2.1.4 としてリリースすることにいたしましょう。

細かい修正、ありがとうございました。リリースよろしくお願いします!