ベクター形式の出力時に背景塗りを加える機能
Closed this issue · 25 comments
どうやらWindows版ではベクター形式の出力でも背景塗りをする機能があるようなので,Mac版でも検討しよう。
メリット
PowerPoint や KeyNote に数式画像を貼り込む際,ベクター形式だと背景が透過になる。
だが,スライドの背景色によっては,数式画像の背景が透明だと見づらい場合がある。
「背景を白くしたいがためにビットマップ形式を用いる」というのは馬鹿げている。
ベクター形式でも背景を白塗り(あるいは指定した別の色による塗り)できる機能があると便利だろう。
実装法のアイデア
- Quartz API でPDFの「お絵かき」ができるので,新たに目的サイズを持つPDFを作成し,背景色の塗りを行った後で,目的PDFの内容を「重ね書き」で流し込めばよい。
- EPS出力時は,一度 pdfTeX でクロップ→背景色追加→gs (eps(2)write) という手順を経ればよさそう。
検討課題
- 余白ありのPDF/EPS出力への対応。どの段階で背景色を塗るか。
- 実験してみたところ,この「Quartz API で元のPDFの内容を流し込む」という方法で再描画すると,「テキスト情報を残すPDF」の場合に,和文文字のテキスト情報が壊れる模様。欧文文字はOK。
- UIのあり方はどうするか。「塗る背景色を指定する機能」を設けるとすると,どのような形のUIが望ましいか。
- CUI版はどうするか。オプションの後方互換性の考慮も必要。
どうやらWindows版ではベクター形式の出力でも背景塗りをする機能があるようなので
Win 版は EMF 限定です。元はといえば pdfiumdraw 最初は EMF 白塗りしかできない状態で、透過をサポートするように少し後に改良しただけです。探してみるとここですね。
Ver. 2.1.1 beta 1 を作成しました。
仕様
- GUI上の「背景を透過させる」のファイルフォーマットに,ベクター画像 (EPS / PDF / SVG / EMF) が増えました。
- 塗る背景色を指定するUIを考えるのは将来のバージョンで再度考えることとし,ひとまずこの Ver. 2.1.1 では,背景色は白塗り固定ということにしようと思います。(従来の非透過ビットマップ画像と同様。)これでUI上の変化は最小限で済みます。
- このベータ版では,開発上分かりやすいように,背景塗りを黄色に固定しています。リリース版では白にします。
- 背景塗りONでかつ和文文字を用いた場合,テキスト保持PDFおよびSVG出力において,文字情報が欠落します。今のところ回避策は見つかっておりません。
- 余白あり・なし,マルチページ,白紙ページ対応など,一通り動作チェックはしてあります。
塗る背景色を指定するUIを考えるのは将来のバージョンで再度考えることとし,ひとまずこの Ver. 2.1.1 では,背景色は白塗り固定ということにしようと思います。
なるほど… Quartz 強い。とりあえず簡単な例では“黄色塗り”が成功しているようです。
背景塗りONでかつ和文文字を用いた場合,テキスト保持PDFおよびSVG出力において,文字情報が欠落します。
というのがよくわかっていません。こちら (Lion) では「あいうえお」で黄色塗りの PDF から「あいうえお」の文字列がコピーできました。
ちなみに、Preview.app って縦書き PDF からの文字のコピペが苦手なのですね… 縦書き複数行からコピーすると文字の順序が滅茶苦茶になります。
Ghostscript で似たようなことができないか遊んでみました(あくまで遊び)。かなり変態な方法ですが、なんとなくそれらしいものができたような気がします。ブログに載せてあります。
%!PS-Adobe-3.0
0.4 0.8 1.0 setrgbcolor
clippath fill
showpage
のようにして「一面色塗りの背景用 PostScript ファイル」を用意し、PostScript 命令を走らせて背景の上に目的の EPS ファイルを overlay するというものです。
Ver. 2.1.1 beta 1 では,余白付きEPSを出力したときに,黄色い余白を増やした上にさらにBB編集で透明な余白を増やしてしまうというバグがありましたので,修正して Ver. 2.1.1 beta 2 としました。
変換経路図もアップデート。
ますます複雑になってきました……。
こちら (Lion) では「あいうえお」で黄色塗りの PDF から「あいうえお」の文字列がコピーできました。
実験ありがとうございます。こちらでも追試してみたところ,確かに Yosemite でも大丈夫でした。
ということは,これは El Capitan の Quartz API のバグっぽいですね……。
ちなみに、Preview.app って縦書き PDF からの文字のコピペが苦手なのですね… 縦書き複数行からコピーすると文字の順序が滅茶苦茶になります。
そのあたりは,OSのバージョンアップでどんどん改善されています。
縦書きPDFの選択や検索は,確か 10.9 Mavericks で対応したのではなかったかと思います。
こちらでも追試してみたところ,確かに Yosemite でも大丈夫でした。
ということは,これは El Capitan の Quartz API のバグっぽいですね……。
El Capitan でも,マシンを変えてみたらうまく行きました。
どうやらマシン固有の問題だったようです。お騒がせしました。
その後色々見つかったバグを一通り潰せたので,Ver. 2.1.1 / 1.11.1 としてリリースしておきました。
新機能は以下の通りです。
- 背景色付きベクター画像出力機能
- 背景色選択機能(ベクター・ビットマップ両方に適用)(Ver. 2.11.1 のみ)
- アノテーション付きPDF生成時の安定性の向上
なお,コマンドラインから色を指定するインターフェースを設けるのが面倒ですので,CUIからは 2. の機能にアクセスする手段を用意しておりません。(白に固定になります。)
将来のバージョンで再度検討しましょう。
pdftexで速攻でやってしまうのが実装的に楽ですかね.ぱっと見背景直接描けるのはなさげ?\pdfliteralあたりで直に書けばいいんだろうか……そのうちやってみます.
pdftexで速攻でやってしまうのが実装的に楽ですかね.
ちょうど pdfTeX での実験が終わったところでした!→ブログ
なるほど,やはり pdfTeX は偉大ですね……!
何となくやってみました.
https://onedrive.live.com/redir?resid=4FABCB4EC4FA1E70!16825&authkey=!ANYoMX5Yq7PLXU4&ithint=folder%2cemf
UI作っていないので全てを無視して真っ青固定です.こんな感じのソースを作ってみています.見ればわかる通り余計に塗っていますが……(割り算面倒)
\def\targetpdffilename{input.pdf}\relax
\def\colorrgb{0 0 1}\relax
\pdfoutput=1\relax
\def\space{ }\relax
\newdimen\zero \zero=0pt\relax
\begingroup\catcode`P = 12\relax\catcode`T = 12\relax
\lowercase{\def\x{\def\rempt##1.##2PT{##1\ifnum##2>\zero.##2\fi}}}\relax
\expandafter\endgroup\x
\def\strippt{\expandafter\rempt\the}\relax
\newcount\totalpage\newcount\pagecount
\pdfhorigin=0bp\relax
\pdfvorigin=0bp\relax
\pdfximage{\targetpdffilename}\relax
\totalpage=\pdflastximagepages
\advance\totalpage by 1\relax
\pagecount=1\relax
\loop\ifnum\pagecount<\totalpage
\pdfximage page \pagecount mediabox{\targetpdffilename}\relax
\setbox0=\hbox{\pdfrefximage\pdflastximage}\relax
\setbox1=\hbox{\pdfliteral{q \colorrgb \space rg 0 0 \strippt\wd0 \space \strippt\ht0 \space re f Q}\box0}\relax
\pdfpageheight=\ht0\relax
\pdfpagewidth=\wd0\relax
\shipout\box1\relax
\advance\pagecount by 1\relax
\repeat
\bye
Ver. 2.1.1 / 1.11.1 としてリリースしておきました。
ありがとうございます。UI もわかりやすいですし、意図どおりに塗れているようです。
見ればわかる通り余計に塗っていますが
まだ Win 版は動かしていませんが、ソースを見る限り pt 単位になっている分だけ余分という意味でしょうか? たいして気にならなかったのと、足りないよりは安心なのでこのままでよいと思います。
意外と簡単に実現できてしまいましたので,背景色選択機能も搭載しました。
背景色の選択ボタンと「透過かどうか」のチェックボックス,近い方が良いかなぁと思うのですがどうですか?
ああ,忘れていました.フォルダのは1.6.7にはついていないです.実は自分でデバッグ用にほしかった(一時ファイルをTMPから探し出すのが辛いので)のですが,一般的にあってもよいかなとつけてみました.一瞬/workingdir=currentを実装したのでbool形式ではないスイッチになっています.(特にGUIの場合「カレントフォルダ」の認識は辛いのでやめました.)
一瞬/workingdir=currentを実装したのでbool形式ではないスイッチになっています.(特にGUIの場合「カレントフォルダ」の認識は辛いのでやめました.)
普通に current もあってよいのではないでしょうか? GUI 版にはカレントという概念が存在しないので「tmp/file」でよいですが、CUI では tmp/file/current が独立な気がします。GUI と CUI で選択肢が同じである必要はないというつもりです(実際 kanji=no も GUI と CUI で違いますし)。対応付けは「CUI の tmp ⇔ GUI の tmp」「CUI の file ⇔ GUI の file」「CUI の current ⇒ GUI の file」で良いと思います。
ではつけておきましょう.
GUI 版にはカレントという概念が存在しない
カレントディレクトリは存在するので,そっちで処理した方が一貫性はとれますね.ショートカットだと指定できたりもするので,それを活用する,という使い方もあるかもしれません.
しかしそうなると「exeのあるフォルダ」とか「フォルダが指定できる」とかいろいろとあり得てしまいますね……まぁ増やしても仕方ないか.
将来的に CUI で背景色塗りを指定できるようにする場合(Mac 版は計画がありそうな気がするので)のことをちょっと考えてみました。たとえば背景色指定を
--background-color <r g b>
などで実装した場合、--[no-]transparent
との兼ね合い(順序も含めて)がどうあるべきかというところが論点になると思います。
--transparent
単独なら?--background-color <r g b>
単独なら?--transparent --background-color <r g b>
なら?--background-color <r g b> --transparent
なら?
ということも意見が分かれると思います。#62 でも挙がっていますが、CUI とあまりにもかけ離れないように GUI 検討の段階で UI 整理の方向性を決めたほうがよいのかもしれませんね。
いまの Windows 版の「可能なら」だと、可能でなかった場合の背景色は何なのかわかりにくい気もしてきたので、ボタンをグレーアウトさせないほうがよかったのかもしれないです。
可能でなかった場合の背景色は何なのかわかりにくい
Win 版ですが、「色ボタンを無効化しない」のほかに「可能なら;不可能な場合は白」と書いてしまうのもアリですね。