https://www.chromium.org/developers/design-documents/print-preview
目的
実際にプリントする前にプリンタの出力を知る
背景
ウェブページは必ずしもプリントしやすいようには出来ていない。ブラウザがプリントするときにはページをプリントできるように再フォーマットする必要がある。実際プリントアウトされた紙は画面で見ているものとは異なっていることがある。よってユーザが実際にプリントアウトする前に出力されるものを知っておく必要がある。
2010年10月時点で、すべての主要ブラウザがプリビュー機能を搭載しているがChromeだけが例外である。Chromeはプリントと指示されるとプリントダイアグを表示してプリントするだけである。
概観
計画としてはDOMのUIページをプリビューに使う。左ペインにプリンタ選択を表示し、右ペインにプリビューを表示する。
Mocks: TODO(thestig) [insert pictures here]
プリビューを実際のプリントアウトに近づけるために、Chromeはプリンタに送信するためのPDFを作成しそれをプリビューに使う。PDFを表示するための既存のプラグインを利用する。
ユーザ体感
ユーザは今でもそうなってるようにレンチメニューからまたはレンダラのコンテキストメニューからまたはショートカットキーから印刷し、それがプリビューを表示するようにすべきである。プレビュータブでは、左ペインは上部に利用可能なプリンタを表示する。その下部にはよく使うプリンタオプション(印刷するーページ、部数、縦横)を表示する。「詳細オプション」を表示しそれがクリックされるとオプションを拡張する。
ユーザがオプションを調整すると、オプションに合わせて右側のプリビューが更新される。ネイティブのプリントダイアグを表示するおプヨンも設ける。
関連作業
SkiaのためのPDFバックエンド実装作業もすすめている。このバックエンドにより一貫性がありサイズ効率も良いPDFをウェブページから作成できる。WindowsやLinuxではPDF作成機能がないか貧弱なのでこうする。Mac OS Xはすでに高機能のPDFバックエンドがビルドインされている。
ページサムネイル機能などの追加機能をもったPDFプラグインの改善作業も進んでいる。
実装
プリビュー機能の実装はUIを提供するフロントエンドとPDFを作成しプリンタと会話するバックエンドがある。ディスクへの永続化も考慮する必要がある。
フロントエンド
フロントエンドはプリントコマンドをフックし、chrome://printをロードするタブを作成することから始まる。プリビューのためのTabContentsマネージャが必要で、プリント可能タブは最大でも1つのプリビュータブをもつ。すでにプリビュータブがある状態で印刷をクリックするとそのタブにフォーカスする。ユーザが印刷するかキャンセルするとプリビューは閉じられる。プリビュータブそれ自体はプリント可能ではない。
PrintPreviewManagerはDevToolsManagerと似ている。ブラウザプロセス内に1つのインスタンスが存在しそれが共有される。TabContentsとそれが関連するPrintPreviewUIがマップされる。プリントのイベントハンドラは与えられた現存のタブのためのPrintPreviewUIをPrintPreviewManagerに求める。PrintPreviewManagerは新しくプリビュータブを作成するか、既存のプレビュータブを返す。PrintPreviewManagerはどのタブがプリビュータブかを知っているので、PrintPreviewUIのためのPrintPreviewUIを作成しない。
プレビュータブはDOM UIを使いブラウザプロセスと通信する特権をもったウェブページを構築する。IPCを使ってブラウザプロセスと通信し、プリンタの一覧を取得し、デフォルトのプリンタをセットする。 It also needs to get the html snippet for the options for the selected printer from the browser, and send updates as the user selects options that affects the print output.
フロントエンドはPDFプラグインを組み込んでプリビューを表示する。ブラウザはPDFを作成し特別なURLであるchrome://print/fooを使って利用可能にする。なのでUIは<embed>タグにsrcパラメータを付け足したものを作成すれば良い。フロントエンドはプラグインと通信してサムネイル表示を最新の状態に保たなければならない。DOM UIとプラグインはPepperAPIで通信する。TODO(thestig) PDFプラグインの人たちとプラグインのインターフェースについて話しておくこと
バックエンド
バックエンドコードはフロントエンドからの要求に対して重労働をしなければならない。
最初にブラウザプロセスはプリンタのプラットフォーム固有の方法で一覧とオプションを取得する必要がある。クラウドプリントはすでにPPD/XPSからHTMLオプションを生成するコードを持っているのでそれが使える。ただしXPの場合はXPSをサポートしていないので、プリンタへ共通のオプションを尋ねることが出来なければならない。
仕事の大部分はプレビューをサポートするためのややこしいプリントパイプラインの再構築を含んでいる。現状ではLinuxのプリントパイプラインはWindowsやMacと違っている。すべてのプラットフォームが一列になったら、プリントパイプラインは2つに分割する:PDF作成とプリントに。現在のプリントパイプラインはユーザがプリンタを選択するのを待ってプリント出力を生成(プラットフォーム固有のコードで)し出力をプリンタへ送る。実際のプリント処理はパイプラインを使う:レンダラは一度に一ページのプリントメタデータを生成する。一方でブラウザプロセスのPrintJobWorkerはそれらをプリンタへ送る。
プリビューのために、レンダラは現在のプリンタ設定を取得し、PDFを作成し、それをブラウザへ送らなくてはならない。ブラウザではPDFを表示し、ユーザのプリンタ設定を待ち、それがあれば、レンダラにPDF作成を再要求しなければならない。この作業はユーザがプリビューを終えるまで続きその後ChromeはPDFをプリンタへ送る。これを直接行うかプラグインが行うかは今後決定する。
考慮すべき点は:
- プリントパイプラインは古いモデルと新しいモデル両方サポートすべきか。一方でプリビュー開発はコマンドラインフラグをもとにして進んでいる。
- PDF作成は一定時間内に行うべきか(ユーザ体感の反応を上げるために)
- または別の方法として、1ページ毎にPDFを作成してそれを集めるか。しかしPDFビューアプラグインはPDFが1つにまとまってる必要がある。
- プリントのためにFrame/DOM/Renderのコピーを作成すべきか。http://crbug.com/21555
設定をディスクに保存
ユーザが毎回プリントオプションを設定し直すのは大変なので保存するようにする。
保存は新しいデータベースに行うべきである。設定ファイルに直接保存するよりも良い方法である。ユーザが多くのプリンタを持っている場合、保存する設定も大きくなる。Chromeがスタートアップに読み込む設定ファイルに書くとスタートアップが遅くなる可能性がある。
データベースのテーブルにはグローバルなプリビュー設定(最近使ったプリンタなど)が含まれる。コラムがプリンタ名、設定名、設定値のテーブルももつ。プリンタ名と設定名でユニークキーとする。メモリ上では、cloud_print::PrinterBasicInfoのオプション値で表される。
国際化
TODO / 左ペインは右から左の言語に対応すべき?他の問題は?
機能強化
クラウドプリントと統合
最初のバージョンのプリビューはOSによって公開されているプリンタのみを対象をした。Cloud Printingと統合するには、ChromeはクラウドプリントAPIを使ってクラウドプリンタにも照会しないとならない。プリビューがPPD/XPSのパースにクラウドプリンタサーバと同じコードを使うとすると、Chromeはプリンタ情報(PPDファイル)と利用可能そしてデフォルトの紙サイズを取得する必要がある。これら2つのデータで、Chromeはオプションダイアログとプレビューを自分自身でできる。ユーザが印刷ボタンを押したら、ChromeはPDFをプリンタへ送る代わりにクラウドプリントサーバに送る。
他の機能強化
- ヘッダとフッタの調整
- マージンの調整
- 拡大・縮小の調整
- Google Docsとの統合
- 名前でプリンタを検索する機能。大企業の場合多くのネットワークプリンタがあり一覧から選ぶのは大変。
- 位置情報からのプリンタ選択
- プレビュー設定とネイティブのダイアログの設定の同期
プライバシーとセキュリティ
プレビューとPDFプラグインはどちらもサンドボックス化されたレンダラプロセスで動く。ページはブラウザプロセスと通信するしプリンタ情報を取得したりプリントジョブを送ったりする権限をもっていない。レンダラとブラウザ間のインタフェースが注意深く制御されたとして、プリビューはレンダラプロセスと同等にセキュアであるべき。
Done: 2018/07/17 (火) 17:45:14