Bug 1372108 - Add support for having Save-as-PDF use Skia PDF on Windows r=jwatt draft
authorFarmer Tseng <fatseng@mozilla.com>
Tue, 20 Jun 2017 11:34:43 +0800
changeset 597103 b43e7f8d0a35f234ba98436284163b4029612fea
parent 593914 2811e8f485ceafa50f30ba9e8c6c009ce41dd884
child 597104 8b7d9374f421e0ea3bc3dab4eb830a6bca65bce9
push id64834
push userbmo:fatseng@mozilla.com
push dateTue, 20 Jun 2017 05:41:07 +0000
reviewersjwatt
bugs1372108
milestone55.0a1
Bug 1372108 - Add support for having Save-as-PDF use Skia PDF on Windows r=jwatt MozReview-Commit-ID: aDbuLj4PyI
widget/windows/moz.build
widget/windows/nsDeviceContextSpecWin.cpp
widget/windows/nsDeviceContextSpecWin.h
--- a/widget/windows/moz.build
+++ b/widget/windows/moz.build
@@ -108,16 +108,22 @@ if CONFIG['NS_ENABLE_TSF']:
     SOURCES += [
         'TSFTextStore.cpp',
     ]
 
 include('/ipc/chromium/chromium-config.mozbuild')
 
 FINAL_LIBRARY = 'xul'
 
+if CONFIG['MOZ_ENABLE_SKIA_PDF']:
+  LOCAL_INCLUDES += [
+    '/gfx/skia/skia/include/config',
+    '/gfx/skia/skia/include/core',
+  ]
+
 LOCAL_INCLUDES += [
     '/layout/generic',
     '/layout/xul',
     '/toolkit/xre',
     '/widget',
     '/xpcom/base',
 ]
 
--- a/widget/windows/nsDeviceContextSpecWin.cpp
+++ b/widget/windows/nsDeviceContextSpecWin.cpp
@@ -31,16 +31,21 @@
 #include "nsIFileStreams.h"
 #include "nsIWindowWatcher.h"
 #include "nsIDOMWindow.h"
 #include "mozilla/Services.h"
 #include "nsWindowsHelpers.h"
 
 #include "mozilla/gfx/Logging.h"
 
+#ifdef MOZ_ENABLE_SKIA_PDF
+#include "mozilla/gfx/PrintTargetSkPDF.h"
+#include "nsIUUIDGenerator.h"
+#endif
+
 static mozilla::LazyLogModule kWidgetPrintingLogMod("printing-widget");
 #define PR_PL(_p1)  MOZ_LOG(kWidgetPrintingLogMod, mozilla::LogLevel::Debug, _p1)
 
 using namespace mozilla;
 using namespace mozilla::gfx;
 
 static const wchar_t kDriverName[] =  L"WINSPOOL";
 
@@ -84,17 +89,19 @@ struct AutoFreeGlobalPrinters
 };
 
 //----------------------------------------------------------------------------------
 nsDeviceContextSpecWin::nsDeviceContextSpecWin()
 {
   mDriverName    = nullptr;
   mDeviceName    = nullptr;
   mDevMode       = nullptr;
-
+#ifdef MOZ_ENABLE_SKIA_PDF
+  mPrintViaSkPDF = false;
+#endif
 }
 
 
 //----------------------------------------------------------------------------------
 
 NS_IMPL_ISUPPORTS(nsDeviceContextSpecWin, nsIDeviceContextSpec)
 
 nsDeviceContextSpecWin::~nsDeviceContextSpecWin()
@@ -128,16 +135,25 @@ static char16_t * GetDefaultPrinterNameF
 NS_IMETHODIMP nsDeviceContextSpecWin::Init(nsIWidget* aWidget,
                                            nsIPrintSettings* aPrintSettings,
                                            bool aIsPrintPreview)
 {
   mPrintSettings = aPrintSettings;
 
   nsresult rv = NS_ERROR_GFX_PRINTER_NO_PRINTER_AVAILABLE;
   if (aPrintSettings) {
+#ifdef MOZ_ENABLE_SKIA_PDF
+    const nsAdoptingString& printViaPdf =
+      mozilla::Preferences::GetString("print.print_via_pdf_encoder");
+
+    if (printViaPdf == NS_LITERAL_STRING("skia-pdf")) {
+      mPrintViaSkPDF = true;
+    }
+#endif
+
     // If we're in the child and printing via the parent or we're printing to
     // PDF we only need information from the print settings.
     mPrintSettings->GetOutputFormat(&mOutputFormat);
     if ((XRE_IsContentProcess() &&
          Preferences::GetBool("print.print_via_parent")) ||
         mOutputFormat == nsIPrintSettings::kOutputFormatPDF) {
       return NS_OK;
     }
@@ -219,16 +235,40 @@ static void CleanAndCopyString(wchar_t*&
     wcscpy(aStr, aNewStr);
   }
 }
 
 already_AddRefed<PrintTarget> nsDeviceContextSpecWin::MakePrintTarget()
 {
   NS_ASSERTION(mDevMode, "DevMode can't be NULL here");
 
+#ifdef MOZ_ENABLE_SKIA_PDF
+  if (mPrintViaSkPDF) {
+    double width, height;
+    mPrintSettings->GetEffectivePageSize(&width, &height);
+    if (width <= 0 || height <= 0) {
+      return nullptr;
+    }
+
+    // convert twips to points
+    width  /= TWIPS_PER_POINT_FLOAT;
+    height /= TWIPS_PER_POINT_FLOAT;
+    IntSize size = IntSize::Truncate(width, height);
+
+    if (mOutputFormat == nsIPrintSettings::kOutputFormatPDF) {
+      nsXPIDLString filename;
+      mPrintSettings->GetToFileName(getter_Copies(filename));
+
+      nsAutoCString printFile(NS_ConvertUTF16toUTF8(filename).get());
+      auto skStream = MakeUnique<SkFILEWStream>(printFile.get());
+      return PrintTargetSkPDF::CreateOrNull(Move(skStream), size);
+    }
+  }
+#endif
+
   if (mOutputFormat == nsIPrintSettings::kOutputFormatPDF) {
     nsXPIDLString filename;
     mPrintSettings->GetToFileName(getter_Copies(filename));
 
     double width, height;
     mPrintSettings->GetEffectivePageSize(&width, &height);
     if (width <= 0 || height <= 0) {
       return nullptr;
--- a/widget/windows/nsDeviceContextSpecWin.h
+++ b/widget/windows/nsDeviceContextSpecWin.h
@@ -60,16 +60,20 @@ protected:
   virtual ~nsDeviceContextSpecWin();
 
   wchar_t*      mDriverName;
   wchar_t*      mDeviceName;
   LPDEVMODEW mDevMode;
 
   nsCOMPtr<nsIPrintSettings> mPrintSettings;
   int16_t mOutputFormat = nsIPrintSettings::kOutputFormatNative;
+
+#ifdef MOZ_ENABLE_SKIA_PDF
+  bool mPrintViaSkPDF;
+#endif
 };
 
 
 //-------------------------------------------------------------------------
 // Printer Enumerator
 //-------------------------------------------------------------------------
 class nsPrinterEnumeratorWin final : public nsIPrinterEnumerator
 {