Bug 1156742 Part 7: Refactor nsDeviceContext.cpp to use printing surface for size and nsIDeviceContextSpec for DPI and scale. r=roc
☠☠ backed out by 9bdfae920430 ☠ ☠
authorBob Owen <bobowencode@gmail.com>
Mon, 21 Dec 2015 20:33:13 +0000
changeset 312341 7f8e595885186a88d337da38c800ff0b9950a7e8
parent 312340 b90d302c57f6056d9c9077daf8fcd54cccbcb0e5
child 312342 d748b1354f923791573dd35626b0eb6b0e012a3b
push id5703
push userraliiev@mozilla.com
push dateMon, 07 Mar 2016 14:18:41 +0000
treeherdermozilla-beta@31e373ad5b5f [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersroc
bugs1156742
milestone46.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1156742 Part 7: Refactor nsDeviceContext.cpp to use printing surface for size and nsIDeviceContextSpec for DPI and scale. r=roc These changes are to make using an off screen surface behind our DrawTarget in the child easier. It still creates the real printing surface for some of the calculations, removing this will be required for future tightening of the sandbox.
embedding/components/printingui/ipc/PrintingParent.h
embedding/components/printingui/ipc/nsPrintingProxy.cpp
embedding/components/printingui/ipc/nsPrintingProxy.h
gfx/src/nsDeviceContext.cpp
widget/nsIDeviceContextSpec.h
widget/windows/nsDeviceContextSpecWin.cpp
widget/windows/nsDeviceContextSpecWin.h
--- a/embedding/components/printingui/ipc/PrintingParent.h
+++ b/embedding/components/printingui/ipc/PrintingParent.h
@@ -9,19 +9,21 @@
 
 #include "mozilla/dom/PBrowserParent.h"
 #include "mozilla/embedding/PPrintingParent.h"
 
 class nsIDOMWindow;
 class PPrintProgressDialogParent;
 class PPrintSettingsDialogParent;
 
-typedef mozilla::layout::PRemotePrintJobParent PRemotePrintJobParent;
+namespace mozilla {
+namespace layout {
+class PRemotePrintJobParent;
+}
 
-namespace mozilla {
 namespace embedding {
 
 class PrintingParent final : public PPrintingParent
 {
 public:
     virtual bool
     RecvShowProgress(PBrowserParent* parent,
                      PPrintProgressDialogParent* printProgressDialog,
--- a/embedding/components/printingui/ipc/nsPrintingProxy.cpp
+++ b/embedding/components/printingui/ipc/nsPrintingProxy.cpp
@@ -17,18 +17,17 @@
 #include "nsPIDOMWindow.h"
 #include "nsPrintOptionsImpl.h"
 #include "PrintDataUtils.h"
 #include "PrintProgressDialogChild.h"
 
 using namespace mozilla;
 using namespace mozilla::dom;
 using namespace mozilla::embedding;
-
-typedef mozilla::layout::RemotePrintJobChild RemotePrintJobChild;
+using namespace mozilla::layout;
 
 static StaticRefPtr<nsPrintingProxy> sPrintingProxyInstance;
 
 NS_IMPL_ISUPPORTS(nsPrintingProxy, nsIPrintingPromptService)
 
 nsPrintingProxy::nsPrintingProxy()
 {
 }
--- a/embedding/components/printingui/ipc/nsPrintingProxy.h
+++ b/embedding/components/printingui/ipc/nsPrintingProxy.h
@@ -4,17 +4,21 @@
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #ifndef __nsPrintingProxy_h
 #define __nsPrintingProxy_h
 
 #include "nsIPrintingPromptService.h"
 #include "mozilla/embedding/PPrintingChild.h"
 
-typedef mozilla::layout::PRemotePrintJobChild PRemotePrintJobChild;
+namespace mozilla {
+namespace layout {
+class PRemotePrintJobChild;
+}
+}
 
 class nsPrintingProxy: public nsIPrintingPromptService,
                        public mozilla::embedding::PPrintingChild
 {
     virtual ~nsPrintingProxy();
 
 public:
     nsPrintingProxy();
--- a/gfx/src/nsDeviceContext.cpp
+++ b/gfx/src/nsDeviceContext.cpp
@@ -309,40 +309,20 @@ nsDeviceContext::IsPrinterSurface()
     return mPrintingSurface != nullptr;
 }
 
 void
 nsDeviceContext::SetDPI()
 {
     float dpi = -1.0f;
 
-    // PostScript, PDF and Mac (when printing) all use 72 dpi
-    // Use a printing DC to determine the other dpi values
-    if (mPrintingSurface) {
-        switch (mPrintingSurface->GetType()) {
-        case gfxSurfaceType::PDF:
-        case gfxSurfaceType::PS:
-        case gfxSurfaceType::Quartz:
-            dpi = 72.0f;
-            break;
-#ifdef XP_WIN
-        case gfxSurfaceType::Win32:
-        case gfxSurfaceType::Win32Printing: {
-            HDC dc = reinterpret_cast<gfxWindowsSurface*>(mPrintingSurface.get())->GetDC();
-            int32_t OSVal = GetDeviceCaps(dc, LOGPIXELSY);
-            dpi = 144.0f;
-            mPrintingScale = float(OSVal) / dpi;
-            break;
-        }
-#endif
-        default:
-            NS_NOTREACHED("Unexpected printing surface type");
-            break;
-        }
-
+    // Use the printing DC to determine DPI values, if we have one.
+    if (mDeviceContextSpec) {
+        dpi = mDeviceContextSpec->GetDPI();
+        mPrintingScale = mDeviceContextSpec->GetPrintingScale();
         mAppUnitsPerDevPixelAtUnitFullZoom =
             NS_lround((AppUnitsPerCSSPixel() * 96) / dpi);
     } else {
         // A value of -1 means use the maximum of 96 and the system DPI.
         // A value of 0 means use the system DPI. A positive value is used as the DPI.
         // This sets the physical size of a device pixel and thus controls the
         // interpretation of physical units.
         int32_t prefDPI = Preferences::GetInt("layout.css.dpi", -1);
@@ -693,62 +673,33 @@ nsDeviceContext::CalcPrintingSize()
     if (!mPrintingSurface) {
         return (mWidth > 0 && mHeight > 0);
     }
 
     bool inPoints = true;
 
     gfxSize size(0, 0);
     switch (mPrintingSurface->GetType()) {
-    case gfxSurfaceType::Image:
-        inPoints = false;
-        size = reinterpret_cast<gfxImageSurface*>(mPrintingSurface.get())->GetSize();
-        break;
-
-#if defined(MOZ_PDF_PRINTING)
-    case gfxSurfaceType::PDF:
-        inPoints = true;
-        size = reinterpret_cast<gfxPDFSurface*>(mPrintingSurface.get())->GetSize();
-        break;
-#endif
-
-#ifdef MOZ_WIDGET_GTK
-    case gfxSurfaceType::PS:
-        inPoints = true;
-        size = reinterpret_cast<gfxPSSurface*>(mPrintingSurface.get())->GetSize();
-        break;
-#endif
-
-#ifdef XP_MACOSX
-    case gfxSurfaceType::Quartz:
-        inPoints = true; // this is really only true when we're printing
-        size = reinterpret_cast<gfxQuartzSurface*>(mPrintingSurface.get())->GetSize();
-        break;
-#endif
-
 #ifdef XP_WIN
-    case gfxSurfaceType::Win32:
     case gfxSurfaceType::Win32Printing:
         {
             inPoints = false;
             HDC dc = reinterpret_cast<gfxWindowsSurface*>(mPrintingSurface.get())->GetDC();
             if (!dc)
                 dc = GetDC((HWND)mWidget->GetNativeData(NS_NATIVE_WIDGET));
             size.width = NSFloatPixelsToAppUnits(::GetDeviceCaps(dc, HORZRES)/mPrintingScale, AppUnitsPerDevPixel());
             size.height = NSFloatPixelsToAppUnits(::GetDeviceCaps(dc, VERTRES)/mPrintingScale, AppUnitsPerDevPixel());
             mDepth = (uint32_t)::GetDeviceCaps(dc, BITSPIXEL);
             if (dc != reinterpret_cast<gfxWindowsSurface*>(mPrintingSurface.get())->GetDC())
                 ReleaseDC((HWND)mWidget->GetNativeData(NS_NATIVE_WIDGET), dc);
             break;
         }
 #endif
-
     default:
-        gfxCriticalError() << "Printing to unknown surface type " << (int)mPrintingSurface->GetType();
-        NS_ERROR("trying to print to unknown surface type");
+        size = mPrintingSurface->GetSize();
     }
 
     if (inPoints) {
         // For printing, CSS inches and physical inches are identical
         // so it doesn't matter which we use here
         mWidth = NSToCoordRound(float(size.width) * AppUnitsPerPhysicalInch() / 72);
         mHeight = NSToCoordRound(float(size.height) * AppUnitsPerPhysicalInch() / 72);
     } else {
--- a/widget/nsIDeviceContextSpec.h
+++ b/widget/nsIDeviceContextSpec.h
@@ -8,18 +8,18 @@
 
 #include "nsISupports.h"
 
 class nsIWidget;
 class nsIPrintSettings;
 class gfxASurface;
 
 #define NS_IDEVICE_CONTEXT_SPEC_IID   \
-{ 0xb5548fb1, 0xf43e, 0x4921, \
-  { 0x82, 0x19, 0xc3, 0x82, 0x06, 0xee, 0x74, 0x5c } }
+{ 0xf407cfba, 0xbe28, 0x46c9, \
+  { 0x8a, 0xba, 0x04, 0x2d, 0xae, 0xbb, 0x4f, 0x23 } }
 
 class nsIDeviceContextSpec : public nsISupports
 {
 public:
    NS_DECLARE_STATIC_IID_ACCESSOR(NS_IDEVICE_CONTEXT_SPEC_IID)
 
    /**
     * Initialize the device context spec.
@@ -29,16 +29,30 @@ public:
     * @return NS_OK or a suitable error code.
     */
    NS_IMETHOD Init(nsIWidget *aWidget,
                    nsIPrintSettings* aPrintSettings,
                    bool aIsPrintPreview) = 0;
 
    NS_IMETHOD GetSurfaceForPrinter(gfxASurface **nativeSurface) = 0;
 
+   /**
+    * Override to return something other than the default.
+    *
+    * @return DPI for printing.
+    */
+   virtual float GetDPI() { return 72.0f; }
+
+   /**
+    * Override to return something other than the default.
+    *
+    * @return the printing scale to be applied to the context for printing.
+    */
+   virtual float GetPrintingScale() { return 1.0f;  }
+
    NS_IMETHOD BeginDocument(const nsAString& aTitle,
                             char16_t*       aPrintToFileName,
                             int32_t          aStartPage,
                             int32_t          aEndPage) = 0;
 
    NS_IMETHOD EndDocument() = 0;
    NS_IMETHOD BeginPage() = 0;
    NS_IMETHOD EndPage() = 0;
--- a/widget/windows/nsDeviceContextSpecWin.cpp
+++ b/widget/windows/nsDeviceContextSpecWin.cpp
@@ -265,16 +265,17 @@ static void CleanAndCopyString(wchar_t*&
     wcscpy(aStr, aNewStr);
   }
 }
 
 NS_IMETHODIMP nsDeviceContextSpecWin::GetSurfaceForPrinter(gfxASurface **surface)
 {
   NS_ASSERTION(mDevMode, "DevMode can't be NULL here");
 
+  *surface = nullptr;
   RefPtr<gfxASurface> newSurface;
 
   int16_t outputFormat = 0;
   if (mPrintSettings) {
     mPrintSettings->GetOutputFormat(&outputFormat);
   }
 
   if (outputFormat == nsIPrintSettings::kOutputFormatPDF) {
@@ -310,29 +311,34 @@ NS_IMETHODIMP nsDeviceContextSpecWin::Ge
         gfxCriticalError(gfxCriticalError::DefaultOptions(false)) << "Failed to create device context in GetSurfaceForPrinter";
         return NS_ERROR_GFX_PRINTER_NAME_NOT_FOUND;
       }
 
       // have this surface take over ownership of this DC
       newSurface = new gfxWindowsSurface(dc, gfxWindowsSurface::FLAG_TAKE_DC | gfxWindowsSurface::FLAG_FOR_PRINTING);
       if (newSurface->GetType() == (gfxSurfaceType)-1) {
         gfxCriticalError() << "Invalid windows surface from " << gfx::hexa(dc);
-        newSurface = nullptr;
+        return NS_ERROR_FAILURE;
       }
     }
   }
 
-  if (newSurface) {
-    *surface = newSurface;
-    NS_ADDREF(*surface);
-    return NS_OK;
-  }
+  mPrintingSurface = newSurface;
+  newSurface.forget(surface);
+  return NS_OK;
+}
 
-  *surface = nullptr;
-  return NS_ERROR_FAILURE;
+float
+nsDeviceContextSpecWin::GetPrintingScale()
+{
+  MOZ_ASSERT(mPrintingSurface);
+
+  HDC dc = reinterpret_cast<gfxWindowsSurface*>(mPrintingSurface.get())->GetDC();
+  int32_t OSVal = GetDeviceCaps(dc, LOGPIXELSY);
+  return float(OSVal) / GetDPI();
 }
 
 //----------------------------------------------------------------------------------
 void nsDeviceContextSpecWin::SetDeviceName(char16ptr_t aDeviceName)
 {
   CleanAndCopyString(mDeviceName, aDeviceName);
 }
 
--- a/widget/windows/nsDeviceContextSpecWin.h
+++ b/widget/windows/nsDeviceContextSpecWin.h
@@ -8,16 +8,17 @@
 
 #include "nsCOMPtr.h"
 #include "nsIDeviceContextSpec.h"
 #include "nsIPrintOptions.h" // For nsIPrinterEnumerator
 #include "nsIPrintSettings.h"
 #include "nsISupportsPrimitives.h"
 #include <windows.h>
 #include "mozilla/Attributes.h"
+#include "mozilla/RefPtr.h"
 
 class nsIWidget;
 
 class nsDeviceContextSpecWin : public nsIDeviceContextSpec
 {
 public:
   nsDeviceContextSpecWin();
 
@@ -29,16 +30,20 @@ public:
                            int32_t          aStartPage,
                            int32_t          aEndPage) { return NS_OK; }
   NS_IMETHOD EndDocument() { return NS_OK; }
   NS_IMETHOD BeginPage() { return NS_OK; }
   NS_IMETHOD EndPage() { return NS_OK; }
 
   NS_IMETHOD Init(nsIWidget* aWidget, nsIPrintSettings* aPS, bool aIsPrintPreview);
 
+  float GetDPI() final  { return 144.0f; }
+
+  float GetPrintingScale() final;
+
   void GetDriverName(wchar_t *&aDriverName) const   { aDriverName = mDriverName;     }
   void GetDeviceName(wchar_t *&aDeviceName) const   { aDeviceName = mDeviceName;     }
 
   // The GetDevMode will return a pointer to a DevMode
   // whether it is from the Global memory handle or just the DevMode
   // To get the DevMode from the Global memory Handle it must lock it 
   // So this call must be paired with a call to UnlockGlobalHandle
   void GetDevMode(LPDEVMODEW &aDevMode);
@@ -59,16 +64,17 @@ protected:
 
   virtual ~nsDeviceContextSpecWin();
 
   wchar_t*      mDriverName;
   wchar_t*      mDeviceName;
   LPDEVMODEW mDevMode;
 
   nsCOMPtr<nsIPrintSettings> mPrintSettings;
+  RefPtr<gfxASurface> mPrintingSurface;
 };
 
 
 //-------------------------------------------------------------------------
 // Printer Enumerator
 //-------------------------------------------------------------------------
 class nsPrinterEnumeratorWin final : public nsIPrinterEnumerator
 {