diff --git a/chrome/renderer/print_web_view_helper.h b/chrome/renderer/print_web_view_helper.h
index 7d0a8ea51925f..1884f9f95e4bd 100644
--- a/chrome/renderer/print_web_view_helper.h
+++ b/chrome/renderer/print_web_view_helper.h
@@ -234,7 +234,8 @@ class PrintWebViewHelper : public RenderViewObserver,
 #elif defined(OS_MACOSX)
   void RenderPage(const gfx::Size& page_size, const gfx::Rect& content_area,
                   const float& scale_factor, int page_number,
-                  WebKit::WebFrame* frame, printing::Metafile* metafile);
+                  WebKit::WebFrame* frame, bool is_preview,
+                  printing::Metafile* metafile);
 #elif defined(OS_POSIX)
   bool RenderPages(const PrintMsg_PrintPages_Params& params,
                    WebKit::WebFrame* frame, const WebKit::WebNode& node,
diff --git a/chrome/renderer/print_web_view_helper_linux.cc b/chrome/renderer/print_web_view_helper_linux.cc
index 7d93a84138447..4d03b35b426e0 100644
--- a/chrome/renderer/print_web_view_helper_linux.cc
+++ b/chrome/renderer/print_web_view_helper_linux.cc
@@ -14,6 +14,7 @@
 #include "printing/metafile_impl.h"
 #include "printing/metafile_skia_wrapper.h"
 #include "printing/page_size_margins.h"
+#include "skia/ext/platform_device.h"
 #include "skia/ext/vector_canvas.h"
 #include "third_party/skia/include/core/SkRefCnt.h"
 #include "third_party/WebKit/Source/WebKit/chromium/public/WebFrame.h"
@@ -208,9 +209,8 @@ void PrintWebViewHelper::PrintPageInternal(
   // can't be a stack object.
   SkRefPtr<skia::VectorCanvas> canvas = new skia::VectorCanvas(device);
   canvas->unref();  // SkRefPtr and new both took a reference.
-  printing::MetafileSkiaWrapper::SetMetafileOnCanvas(canvas.get(), metafile);
-  printing::MetafileSkiaWrapper::SetDraftMode(canvas.get(),
-                                              is_print_ready_metafile_sent_);
+  printing::MetafileSkiaWrapper::SetMetafileOnCanvas(*canvas, metafile);
+  skia::SetIsDraftMode(*canvas, is_print_ready_metafile_sent_);
   frame->printPage(params.page_number, canvas.get());
 
   if (params.params.display_header_footer) {
diff --git a/chrome/renderer/print_web_view_helper_mac.mm b/chrome/renderer/print_web_view_helper_mac.mm
index 0e8c3b24133f3..1700f669af18f 100644
--- a/chrome/renderer/print_web_view_helper_mac.mm
+++ b/chrome/renderer/print_web_view_helper_mac.mm
@@ -17,6 +17,7 @@
 
 #if defined(USE_SKIA)
 #include "printing/metafile_skia_wrapper.h"
+#include "skia/ext/platform_device.h"
 #include "skia/ext/vector_canvas.h"
 #include "third_party/WebKit/Source/WebKit/chromium/public/WebCanvas.h"
 #endif
@@ -37,7 +38,7 @@ void PrintWebViewHelper::PrintPageInternal(
   // Render page for printing.
   gfx::Rect content_area(params.params.printable_size);
   RenderPage(params.params.printable_size, content_area, scale_factor,
-             page_number, frame, &metafile);
+             page_number, frame, false, &metafile);
   metafile.FinishDocument();
 
   PrintHostMsg_DidPrintPage_Params page_params;
@@ -96,7 +97,7 @@ bool PrintWebViewHelper::RenderPreviewPage(int page_number) {
 
   base::TimeTicks begin_time = base::TimeTicks::Now();
   RenderPage(printParams.page_size, content_area, scale_factor, page_number,
-             print_preview_context_.frame(), initial_render_metafile);
+             print_preview_context_.frame(), true, initial_render_metafile);
   print_preview_context_.RenderedPreviewPage(
       base::TimeTicks::Now() - begin_time);
 
@@ -144,7 +145,7 @@ bool PrintWebViewHelper::RenderPreviewPage(int page_number) {
 void PrintWebViewHelper::RenderPage(
     const gfx::Size& page_size, const gfx::Rect& content_area,
     const float& scale_factor, int page_number, WebFrame* frame,
-    printing::Metafile* metafile) {
+    bool is_preview, printing::Metafile* metafile) {
 
   {
 #if defined(USE_SKIA)
@@ -156,9 +157,9 @@ void PrintWebViewHelper::RenderPage(
     SkRefPtr<skia::VectorCanvas> canvas = new skia::VectorCanvas(device);
     canvas->unref();  // SkRefPtr and new both took a reference.
     WebKit::WebCanvas* canvas_ptr = canvas.get();
-    printing::MetafileSkiaWrapper::SetMetafileOnCanvas(canvas.get(), metafile);
-    printing::MetafileSkiaWrapper::SetDraftMode(canvas.get(),
-                                                is_print_ready_metafile_sent_);
+    printing::MetafileSkiaWrapper::SetMetafileOnCanvas(*canvas, metafile);
+    skia::SetIsDraftMode(*canvas, is_print_ready_metafile_sent_);
+    skia::SetIsPreviewMetafile(*canvas, is_preview);
 #else
     bool success = metafile->StartPage(page_size, content_area, scale_factor);
     DCHECK(success);
diff --git a/chrome/renderer/print_web_view_helper_win.cc b/chrome/renderer/print_web_view_helper_win.cc
index 4ceef0bef28b3..fe8e6b6b43ed6 100644
--- a/chrome/renderer/print_web_view_helper_win.cc
+++ b/chrome/renderer/print_web_view_helper_win.cc
@@ -193,9 +193,9 @@ Metafile* PrintWebViewHelper::RenderPage(
   SkRefPtr<skia::VectorCanvas> canvas = new skia::VectorCanvas(device);
   canvas->unref();  // SkRefPtr and new both took a reference.
   if (is_preview) {
-    printing::MetafileSkiaWrapper::SetMetafileOnCanvas(canvas.get(), metafile);
-    printing::MetafileSkiaWrapper::SetDraftMode(canvas.get(),
-                                                is_print_ready_metafile_sent_);
+    printing::MetafileSkiaWrapper::SetMetafileOnCanvas(*canvas, metafile);
+    skia::SetIsDraftMode(*canvas, is_print_ready_metafile_sent_);
+    skia::SetIsPreviewMetafile(*canvas, is_preview);
   }
 
   float webkit_scale_factor = frame->printPage(page_number, canvas.get());
diff --git a/printing/metafile_skia_wrapper.cc b/printing/metafile_skia_wrapper.cc
index cc7fa0880417f..ee24a667dba7b 100644
--- a/printing/metafile_skia_wrapper.cc
+++ b/printing/metafile_skia_wrapper.cc
@@ -2,8 +2,8 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#include "base/logging.h"
 #include "printing/metafile_skia_wrapper.h"
+#include "skia/ext/platform_device.h"
 #include "third_party/skia/include/core/SkCanvas.h"
 #include "third_party/skia/include/core/SkDevice.h"
 #include "third_party/skia/include/core/SkMetaData.h"
@@ -12,34 +12,25 @@ namespace printing {
 
 namespace {
 
-const char* kDraftModeKey = "CrDraftMode";
 const char* kMetafileKey = "CrMetafile";
 
-SkMetaData& getMetaData(SkCanvas* canvas) {
-  DCHECK(canvas != NULL);
-
-  SkDevice* device = canvas->getDevice();
-  DCHECK(device != NULL);
-  return device->getMetaData();
-}
-
 }  // namespace
 
 // static
-void MetafileSkiaWrapper::SetMetafileOnCanvas(SkCanvas* canvas,
+void MetafileSkiaWrapper::SetMetafileOnCanvas(const SkCanvas& canvas,
                                               Metafile* metafile) {
   MetafileSkiaWrapper* wrapper = NULL;
   if (metafile)
     wrapper = new MetafileSkiaWrapper(metafile);
 
-  SkMetaData& meta = getMetaData(canvas);
+  SkMetaData& meta = skia::getMetaData(canvas);
   meta.setRefCnt(kMetafileKey, wrapper);
   SkSafeUnref(wrapper);
 }
 
 // static
-Metafile* MetafileSkiaWrapper::GetMetafileFromCanvas(SkCanvas* canvas) {
-  SkMetaData& meta = getMetaData(canvas);
+Metafile* MetafileSkiaWrapper::GetMetafileFromCanvas(const SkCanvas& canvas) {
+  SkMetaData& meta = skia::getMetaData(canvas);
   SkRefCnt* value;
   if (!meta.findRefCnt(kMetafileKey, &value) || !value)
     return NULL;
@@ -47,21 +38,6 @@ Metafile* MetafileSkiaWrapper::GetMetafileFromCanvas(SkCanvas* canvas) {
   return static_cast<MetafileSkiaWrapper*>(value)->metafile_;
 }
 
-// static
-void MetafileSkiaWrapper::SetDraftMode(SkCanvas* canvas, bool draft_mode) {
-  SkMetaData& meta = getMetaData(canvas);
-  meta.setBool(kDraftModeKey, draft_mode);
-}
-
-// static
-bool MetafileSkiaWrapper::GetDraftMode(SkCanvas* canvas) {
-  SkMetaData& meta = getMetaData(canvas);
-  bool draft_mode;
-  if (!meta.findBool(kDraftModeKey, &draft_mode))
-    draft_mode = false;
-  return draft_mode;
-}
-
 MetafileSkiaWrapper::MetafileSkiaWrapper(Metafile* metafile)
     : metafile_(metafile) {
 }
diff --git a/printing/metafile_skia_wrapper.h b/printing/metafile_skia_wrapper.h
index 40e26e82786d1..901044964ffcc 100644
--- a/printing/metafile_skia_wrapper.h
+++ b/printing/metafile_skia_wrapper.h
@@ -20,13 +20,9 @@ class Metafile;
 // as long as the canvas.
 class PRINTING_EXPORT MetafileSkiaWrapper : public SkRefCnt {
  public:
-  static void SetMetafileOnCanvas(SkCanvas* canvas, Metafile* metafile);
+  static void SetMetafileOnCanvas(const SkCanvas& canvas, Metafile* metafile);
 
-  static Metafile* GetMetafileFromCanvas(SkCanvas* canvas);
-
-  static void SetDraftMode(SkCanvas* canvas, bool draft_mode);
-
-  static bool GetDraftMode(SkCanvas* canvas);
+  static Metafile* GetMetafileFromCanvas(const SkCanvas& canvas);
 
  private:
   explicit MetafileSkiaWrapper(Metafile* metafile);
diff --git a/skia/ext/platform_device.cc b/skia/ext/platform_device.cc
index 9e1dde76667d7..6292273a8b511 100644
--- a/skia/ext/platform_device.cc
+++ b/skia/ext/platform_device.cc
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
+#include "base/logging.h"
 #include "skia/ext/platform_device.h"
 
 #include "third_party/skia/include/core/SkMetaData.h"
@@ -9,9 +10,29 @@
 namespace skia {
 
 namespace {
+
 const char* kDevicePlatformBehaviour = "CrDevicePlatformBehaviour";
+const char* kDraftModeKey = "CrDraftMode";
+
+#if defined(OS_MACOSX) || defined(OS_WIN)
+const char* kIsPreviewMetafileKey = "CrIsPreviewMetafile";
+#endif
+
+void SetBoolMetaData(const SkCanvas& canvas, const char* key,  bool value) {
+  SkMetaData& meta = skia::getMetaData(canvas);
+  meta.setBool(key, value);
 }
 
+bool GetBoolMetaData(const SkCanvas& canvas, const char* key) {
+  bool value;
+  SkMetaData& meta = skia::getMetaData(canvas);
+  if (!meta.findBool(key, &value))
+    value = false;
+  return value;
+}
+
+}  // namespace
+
 void SetPlatformDevice(SkDevice* device, PlatformDevice* platform_behaviour) {
   SkMetaData& meta_data = device->getMetaData();
   meta_data.setPtr(kDevicePlatformBehaviour, platform_behaviour);
@@ -27,6 +48,30 @@ PlatformDevice* GetPlatformDevice(SkDevice* device) {
   return NULL;
 }
 
+SkMetaData& getMetaData(const SkCanvas& canvas) {
+  SkDevice* device = canvas.getDevice();
+  DCHECK(device != NULL);
+  return device->getMetaData();
+}
+
+void SetIsDraftMode(const SkCanvas& canvas, bool draft_mode) {
+  SetBoolMetaData(canvas, kDraftModeKey, draft_mode);
+}
+
+bool IsDraftMode(const SkCanvas& canvas) {
+  return GetBoolMetaData(canvas, kDraftModeKey);
+}
+
+#if defined(OS_MACOSX) || defined(OS_WIN)
+void SetIsPreviewMetafile(const SkCanvas& canvas, bool is_preview) {
+  SetBoolMetaData(canvas, kIsPreviewMetafileKey, is_preview);
+}
+
+bool IsPreviewMetafile(const SkCanvas& canvas) {
+  return GetBoolMetaData(canvas, kIsPreviewMetafileKey);
+}
+#endif
+
 bool PlatformDevice::IsNativeFontRenderingAllowed() {
   return true;
 }
diff --git a/skia/ext/platform_device.h b/skia/ext/platform_device.h
index 179a8e8bfa33f..b2972c22a9f85 100644
--- a/skia/ext/platform_device.h
+++ b/skia/ext/platform_device.h
@@ -18,6 +18,7 @@
 #include "third_party/skia/include/core/SkColor.h"
 
 class SkMatrix;
+class SkMetaData;
 class SkPath;
 class SkRegion;
 
@@ -78,6 +79,17 @@ SK_API void InitializeDC(HDC context);
 SK_API CGContextRef GetBitmapContext(SkDevice* device);
 #endif
 
+// Following routines are used in print preview workflow to mark the draft mode
+// metafile and preview metafile.
+SkMetaData& getMetaData(const SkCanvas& canvas);
+void SetIsDraftMode(const SkCanvas& canvas, bool draft_mode);
+bool IsDraftMode(const SkCanvas& canvas);
+
+#if defined(OS_MACOSX) || defined(OS_WIN)
+void SetIsPreviewMetafile(const SkCanvas& canvas, bool is_preview);
+bool IsPreviewMetafile(const SkCanvas& canvas);
+#endif
+
 // A SkDevice is basically a wrapper around SkBitmap that provides a surface for
 // SkCanvas to draw into. PlatformDevice provides a surface Windows can also
 // write to. It also provides functionality to play well with GDI drawing
diff --git a/webkit/plugins/ppapi/ppapi_plugin_instance.cc b/webkit/plugins/ppapi/ppapi_plugin_instance.cc
index 4ec22da3d447e..cee7108aac415 100644
--- a/webkit/plugins/ppapi/ppapi_plugin_instance.cc
+++ b/webkit/plugins/ppapi/ppapi_plugin_instance.cc
@@ -851,10 +851,10 @@ int PluginInstance::PrintBegin(const gfx::Rect& printable_area,
   if (!num_pages)
     return 0;
   current_print_settings_ = print_settings;
-#if defined(OS_LINUX) || defined(OS_WIN)
+#if defined(USE_SKIA)
   canvas_ = NULL;
   ranges_.clear();
-#endif  // OS_LINUX || OS_WIN
+#endif  // USE_SKIA
   return num_pages;
 }
 
@@ -862,14 +862,19 @@ bool PluginInstance::PrintPage(int page_number, WebKit::WebCanvas* canvas) {
   DCHECK(plugin_print_interface_);
   PP_PrintPageNumberRange_Dev page_range;
   page_range.first_page_number = page_range.last_page_number = page_number;
-#if defined(OS_LINUX) || defined(OS_WIN)
+#if defined(USE_SKIA)
   // The canvas only has a metafile on it for print preview.
-  if (printing::MetafileSkiaWrapper::GetMetafileFromCanvas(canvas)) {
+  bool save_for_later =
+      (printing::MetafileSkiaWrapper::GetMetafileFromCanvas(*canvas) != NULL);
+#if defined(OS_MACOSX) || defined(OS_WIN)
+  save_for_later = save_for_later && skia::IsPreviewMetafile(*canvas);
+#endif
+  if (save_for_later) {
     ranges_.push_back(page_range);
     canvas_ = canvas;
     return true;
   } else
-#endif  // OS_LINUX || OS_WIN
+#endif  // USE_SKIA
   {
     return PrintPageHelper(&page_range, 1, canvas);
   }
@@ -901,12 +906,12 @@ bool PluginInstance::PrintPageHelper(PP_PrintPageNumberRange_Dev* page_ranges,
 void PluginInstance::PrintEnd() {
   // Keep a reference on the stack. See NOTE above.
   scoped_refptr<PluginInstance> ref(this);
-#if defined(OS_LINUX) || defined(OS_WIN)
+#if defined(USE_SKIA)
   if (!ranges_.empty())
     PrintPageHelper(&(ranges_.front()), ranges_.size(), canvas_.get());
   canvas_ = NULL;
   ranges_.clear();
-#endif  // OS_LINUX || OS_WIN
+#endif  // USE_SKIA
 
   DCHECK(plugin_print_interface_);
   if (plugin_print_interface_)
@@ -1061,7 +1066,7 @@ bool PluginInstance::PrintPDFOutput(PP_Resource print_output,
   // (NativeMetafile and PreviewMetafile must have compatible formats,
   // i.e. both PDF for this to work).
   printing::Metafile* metafile =
-      printing::MetafileSkiaWrapper::GetMetafileFromCanvas(canvas);
+      printing::MetafileSkiaWrapper::GetMetafileFromCanvas(*canvas);
   DCHECK(metafile != NULL);
   if (metafile)
     ret = metafile->InitFromData(mapper.data(), mapper.size());
@@ -1086,7 +1091,7 @@ bool PluginInstance::PrintPDFOutput(PP_Resource print_output,
   }
 #elif defined(OS_WIN)
   printing::Metafile* metafile =
-    printing::MetafileSkiaWrapper::GetMetafileFromCanvas(canvas);
+    printing::MetafileSkiaWrapper::GetMetafileFromCanvas(*canvas);
   if (metafile) {
     // We only have a metafile when doing print preview, so we just want to
     // pass the PDF off to preview.
diff --git a/webkit/plugins/ppapi/ppapi_plugin_instance.h b/webkit/plugins/ppapi/ppapi_plugin_instance.h
index f46301b1bcdc8..fdb3dcea7d87d 100644
--- a/webkit/plugins/ppapi/ppapi_plugin_instance.h
+++ b/webkit/plugins/ppapi/ppapi_plugin_instance.h
@@ -466,14 +466,14 @@ class PluginInstance : public base::RefCounted<PluginInstance>,
   // variable to hold on to the pixels.
   scoped_refptr<PPB_ImageData_Impl> last_printed_page_;
 #endif  // defined(OS_MACOSX)
-#if defined(OS_LINUX) || defined(OS_WIN)
-  // When printing to PDF (print preview, Linux) the entire document goes into
-  // one metafile.  However, when users print only a subset of all the pages,
-  // it is impossible to know if a call to PrintPage() is the last call.
-  // Thus in PrintPage(), just store the page number in |ranges_|.
-  // The hack is in PrintEnd(), where a valid |canvas_| is preserved in
-  // PrintWebViewHelper::PrintPages. This makes it possible to generate the
-  // entire PDF given the variables below:
+#if defined(USE_SKIA)
+  // Always when printing to PDF on Linux and when printing for preview on Mac
+  // and Win, the entire document goes into one metafile.  However, when users
+  // print only a subset of all the pages, it is impossible to know if a call
+  // to PrintPage() is the last call. Thus in PrintPage(), just store the page
+  // number in |ranges_|. The hack is in PrintEnd(), where a valid |canvas_|
+  // is preserved in PrintWebViewHelper::PrintPages. This makes it possible
+  // to generate the entire PDF given the variables below:
   //
   // The most recently used WebCanvas, guaranteed to be valid.
   SkRefPtr<WebKit::WebCanvas> canvas_;