PdfMetafileSkia: start supporting more document types.

BUG=599185

Review-Url: https://codereview.chromium.org/2064843002
Cr-Commit-Position: refs/heads/master@{#399936}
diff --git a/chrome/browser/printing/print_view_manager_base.cc b/chrome/browser/printing/print_view_manager_base.cc
index ad9f7f0a..083be534 100644
--- a/chrome/browser/printing/print_view_manager_base.cc
+++ b/chrome/browser/printing/print_view_manager_base.cc
@@ -171,7 +171,8 @@
     }
   }
 
-  std::unique_ptr<PdfMetafileSkia> metafile(new PdfMetafileSkia);
+  std::unique_ptr<PdfMetafileSkia> metafile(
+      new PdfMetafileSkia(PDF_SKIA_DOCUMENT_TYPE));
   if (metafile_must_be_valid) {
     if (!metafile->InitFromData(shared_buf->memory(), params.data_size)) {
       NOTREACHED() << "Invalid metafile header";
diff --git a/components/printing/renderer/print_web_view_helper.cc b/components/printing/renderer/print_web_view_helper.cc
index 1a1fdf0..fa79d1a2 100644
--- a/components/printing/renderer/print_web_view_helper.cc
+++ b/components/printing/renderer/print_web_view_helper.cc
@@ -1249,7 +1249,7 @@
   std::unique_ptr<PdfMetafileSkia> draft_metafile;
   PdfMetafileSkia* initial_render_metafile = print_preview_context_.metafile();
   if (print_preview_context_.IsModifiable() && is_print_ready_metafile_sent_) {
-    draft_metafile.reset(new PdfMetafileSkia);
+    draft_metafile.reset(new PdfMetafileSkia(PDF_SKIA_DOCUMENT_TYPE));
     initial_render_metafile = draft_metafile.get();
   }
 
@@ -1264,7 +1264,8 @@
              print_preview_context_.generate_draft_pages()) {
     DCHECK(!draft_metafile.get());
     draft_metafile =
-        print_preview_context_.metafile()->GetMetafileForCurrentPage();
+        print_preview_context_.metafile()->GetMetafileForCurrentPage(
+            PDF_SKIA_DOCUMENT_TYPE);
   }
   return PreviewPageRendered(page_number, draft_metafile.get());
 }
@@ -2023,7 +2024,7 @@
     return false;
   }
 
-  metafile_.reset(new PdfMetafileSkia);
+  metafile_.reset(new PdfMetafileSkia(PDF_SKIA_DOCUMENT_TYPE));
   CHECK(metafile_->Init());
 
   current_page_index_ = 0;
diff --git a/components/printing/renderer/print_web_view_helper_linux.cc b/components/printing/renderer/print_web_view_helper_linux.cc
index cb2555d..330dd33 100644
--- a/components/printing/renderer/print_web_view_helper_linux.cc
+++ b/components/printing/renderer/print_web_view_helper_linux.cc
@@ -45,7 +45,7 @@
 #if defined(ENABLE_BASIC_PRINTING)
 bool PrintWebViewHelper::PrintPagesNative(blink::WebFrame* frame,
                                           int page_count) {
-  PdfMetafileSkia metafile;
+  PdfMetafileSkia metafile(PDF_SKIA_DOCUMENT_TYPE);
   CHECK(metafile.Init());
 
   const PrintMsg_PrintPages_Params& params = *print_pages_params_;
diff --git a/components/printing/renderer/print_web_view_helper_mac.mm b/components/printing/renderer/print_web_view_helper_mac.mm
index 1d23d5b..d227c5e1 100644
--- a/components/printing/renderer/print_web_view_helper_mac.mm
+++ b/components/printing/renderer/print_web_view_helper_mac.mm
@@ -41,7 +41,7 @@
 void PrintWebViewHelper::PrintPageInternal(
     const PrintMsg_PrintPage_Params& params,
     blink::WebFrame* frame) {
-  PdfMetafileSkia metafile;
+  PdfMetafileSkia metafile(PDF_SKIA_DOCUMENT_TYPE);
   CHECK(metafile.Init());
 
   int page_number = params.page_number;
@@ -80,7 +80,7 @@
                          is_print_ready_metafile_sent_;
 
   if (render_to_draft) {
-    draft_metafile.reset(new PdfMetafileSkia());
+    draft_metafile.reset(new PdfMetafileSkia(PDF_SKIA_DOCUMENT_TYPE));
     CHECK(draft_metafile->Init());
     initial_render_metafile = draft_metafile.get();
   }
@@ -99,7 +99,8 @@
         print_preview_context_.generate_draft_pages()) {
       DCHECK(!draft_metafile.get());
       draft_metafile =
-          print_preview_context_.metafile()->GetMetafileForCurrentPage();
+          print_preview_context_.metafile()->GetMetafileForCurrentPage(
+              PDF_SKIA_DOCUMENT_TYPE);
     }
   }
   return PreviewPageRendered(page_number, draft_metafile.get());
diff --git a/components/printing/renderer/print_web_view_helper_pdf_win.cc b/components/printing/renderer/print_web_view_helper_pdf_win.cc
index 401faf9..1c1c2213 100644
--- a/components/printing/renderer/print_web_view_helper_pdf_win.cc
+++ b/components/printing/renderer/print_web_view_helper_pdf_win.cc
@@ -24,7 +24,7 @@
   std::vector<gfx::Size> page_size_in_dpi(printed_pages.size());
   std::vector<gfx::Rect> content_area_in_dpi(printed_pages.size());
 
-  PdfMetafileSkia metafile;
+  PdfMetafileSkia metafile(PDF_SKIA_DOCUMENT_TYPE);
   CHECK(metafile.Init());
 
   PrintMsg_PrintPage_Params page_params;
diff --git a/components/printing/test/mock_printer.cc b/components/printing/test/mock_printer.cc
index 99bdcb36..4197dc60 100644
--- a/components/printing/test/mock_printer.cc
+++ b/components/printing/test/mock_printer.cc
@@ -204,7 +204,7 @@
 #if defined(OS_MACOSX)
   printing::PdfMetafileCg metafile;
 #else
-  printing::PdfMetafileSkia metafile;
+  printing::PdfMetafileSkia metafile(printing::PDF_SKIA_DOCUMENT_TYPE);
 #endif
   metafile.InitFromData(metafile_data.memory(), params.data_size);
   printing::Image image(metafile);
diff --git a/printing/pdf_metafile_skia.cc b/printing/pdf_metafile_skia.cc
index aebd263..dd182ac 100644
--- a/printing/pdf_metafile_skia.cc
+++ b/printing/pdf_metafile_skia.cc
@@ -10,6 +10,9 @@
 #include "third_party/skia/include/core/SkDocument.h"
 #include "third_party/skia/include/core/SkPictureRecorder.h"
 #include "third_party/skia/include/core/SkStream.h"
+// Note that headers in third_party/skia/src are fragile.  This is
+// an experimental, fragile, and diagnostic-only document type.
+#include "third_party/skia/src/utils/SkMultiPictureDocument.h"
 #include "ui/gfx/geometry/safe_integer_conversions.h"
 #include "ui/gfx/skia_util.h"
 
@@ -92,6 +95,7 @@
   // meaningful for a vector canvas as for a raster canvas.
   float scale_factor_;
   SkSize size_;
+  SkiaDocumentType type_;
 
 #if defined(OS_MACOSX)
   PdfMetafileCg pdf_cg_;
@@ -126,6 +130,7 @@
   float inverse_scale = 1.0 / scale_factor;
   SkCanvas* canvas = data_->recorder_.beginRecording(
       inverse_scale * page_size.width(), inverse_scale * page_size.height());
+  // Recording canvas is owned by the data_->recorder_.  No ref() necessary.
   if (content_area != gfx::Rect(page_size)) {
     canvas->scale(inverse_scale, inverse_scale);
     SkRect sk_content_area = gfx::RectToSkRect(content_area);
@@ -140,7 +145,6 @@
   // canvas->getTotalMatrix() returns a value that ignores the scale
   // factor.  We store the scale factor and re-apply it later.
   // http://crbug.com/469656
-  // Recording canvas is owned by the data_->recorder_.  No ref() necessary.
 }
 
 SkCanvas* PdfMetafileSkia::GetVectorCanvasForNewPage(
@@ -157,9 +161,8 @@
 
   sk_sp<SkPicture> pic = data_->recorder_.finishRecordingAsPicture();
   if (data_->scale_factor_ != 1.0f) {
-    SkCanvas* canvas =
-        data_->recorder_.beginRecording(data_->size_.width(),
-                                        data_->size_.height());
+    SkCanvas* canvas = data_->recorder_.beginRecording(data_->size_.width(),
+                                                       data_->size_.height());
     canvas->scale(data_->scale_factor_, data_->scale_factor_);
     canvas->drawPicture(pic);
     pic = data_->recorder_.finishRecordingAsPicture();
@@ -177,9 +180,15 @@
     FinishPage();
 
   SkDynamicMemoryWStream stream;
-  // TODO(halcanary): support more document types (XPS, a sequence of display
-  // lists).
-  sk_sp<SkDocument> doc = MakePdfDocument(&stream);
+  sk_sp<SkDocument> doc;
+  switch (data_->type_) {
+    case PDF_SKIA_DOCUMENT_TYPE:
+      doc = MakePdfDocument(&stream);
+      break;
+    case MSKP_SKIA_DOCUMENT_TYPE:
+      doc = SkMakeMultiPictureDocument(&stream);
+      break;
+  }
 
   for (const Page& page : data_->pages_) {
     SkCanvas* canvas = doc->beginPage(page.size_.width(), page.size_.height());
@@ -287,13 +296,16 @@
   return true;
 }
 
-PdfMetafileSkia::PdfMetafileSkia() : data_(new PdfMetafileSkiaData) {
+PdfMetafileSkia::PdfMetafileSkia(SkiaDocumentType type)
+    : data_(new PdfMetafileSkiaData) {
+  data_->type_ = type;
 }
 
-std::unique_ptr<PdfMetafileSkia> PdfMetafileSkia::GetMetafileForCurrentPage() {
+std::unique_ptr<PdfMetafileSkia> PdfMetafileSkia::GetMetafileForCurrentPage(
+    SkiaDocumentType type) {
   // If we only ever need the metafile for the last page, should we
   // only keep a handle on one SkPicture?
-  std::unique_ptr<PdfMetafileSkia> metafile(new PdfMetafileSkia);
+  std::unique_ptr<PdfMetafileSkia> metafile(new PdfMetafileSkia(type));
 
   if (data_->pages_.size() == 0)
     return metafile;
diff --git a/printing/pdf_metafile_skia.h b/printing/pdf_metafile_skia.h
index 0b7e826..28bd41f 100644
--- a/printing/pdf_metafile_skia.h
+++ b/printing/pdf_metafile_skia.h
@@ -20,20 +20,20 @@
 
 class SkCanvas;
 
-#if defined(OS_CHROMEOS) || defined(OS_ANDROID)
-namespace base {
-struct FileDescriptor;
-}
-#endif
-
 namespace printing {
 
+enum SkiaDocumentType {
+  PDF_SKIA_DOCUMENT_TYPE,
+  // MSKP is an experimental, fragile, and diagnostic-only document type.
+  MSKP_SKIA_DOCUMENT_TYPE,
+};
+
 struct PdfMetafileSkiaData;
 
 // This class uses Skia graphics library to generate a PDF document.
 class PRINTING_EXPORT PdfMetafileSkia : public Metafile {
  public:
-  PdfMetafileSkia();
+  explicit PdfMetafileSkia(SkiaDocumentType type);
   ~PdfMetafileSkia() override;
 
   // Metafile methods.
@@ -68,7 +68,8 @@
   bool SaveTo(base::File* file) const override;
 
   // Return a new metafile containing just the current page in draft mode.
-  std::unique_ptr<PdfMetafileSkia> GetMetafileForCurrentPage();
+  std::unique_ptr<PdfMetafileSkia> GetMetafileForCurrentPage(
+      SkiaDocumentType type);
 
   // This method calls StartPage and then returns an appropriate
   // PlatformCanvas implementation bound to the context created by