Bug 1303051 - Printing Issue: Page Setup not being respected since upgrade to 48.01 on Mac; r=mconley
Adds serialization of native print settings values so
that correct page size, scaling, orientation are sent
to the child after the print dialog is displayed.
Changes the Mac print dialog code to load native
print settings from the "print.macosx.pagesetup-2"
pref and ignore what is passed in.
Overwrites the scaling percentage specified in
the print dialog when "Ignore Scaling and Shrink to
Fit Page Width" is checked.
Scaling on Nightly (remote printing) needs more work
to be done in a follow up bug.
MozReview-Commit-ID: B12ZeHuiYFJ
--- a/embedding/components/printingui/ipc/PPrintingTypes.ipdlh
+++ b/embedding/components/printingui/ipc/PPrintingTypes.ipdlh
@@ -100,12 +100,25 @@ struct PrintData {
/** TODO: Is there an "unsigned short" primitive? **/
short pagesAcross;
short pagesDown;
double printTime;
bool detailedErrorReporting;
nsString faxNumber;
bool addHeaderAndFooter;
bool fileNameExtensionHidden;
+ /*
+ * Holds the scaling factor from the Print dialog when shrink
+ * to fit is not used. This is needed by the child when it
+ * isn't using remote printing. When shrink to fit is enabled
+ * (default), print dialog code ensures this value is 1.0.
+ */
+ float scalingFactor;
+ /*
+ * Scaling factor for converting from OS X native paper size
+ * units to inches.
+ */
+ float widthScale;
+ float heightScale;
};
} // namespace embedding
} // namespace mozilla
--- a/widget/cocoa/nsPrintDialogX.mm
+++ b/widget/cocoa/nsPrintDialogX.mm
@@ -2,16 +2,17 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "mozilla/ArrayUtils.h"
#include "nsPrintDialogX.h"
#include "nsIPrintSettings.h"
+#include "nsIPrintSettingsService.h"
#include "nsPrintSettingsX.h"
#include "nsCOMPtr.h"
#include "nsQueryObject.h"
#include "nsServiceManagerUtils.h"
#include "nsIWebProgressListener.h"
#include "nsIStringBundle.h"
#include "nsIWebBrowserPrint.h"
#include "nsCRT.h"
@@ -44,16 +45,19 @@ nsPrintDialogServiceX::Show(nsPIDOMWindo
NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NSRESULT;
NS_PRECONDITION(aSettings, "aSettings must not be null");
RefPtr<nsPrintSettingsX> settingsX(do_QueryObject(aSettings));
if (!settingsX)
return NS_ERROR_FAILURE;
+ nsCOMPtr<nsIPrintSettingsService> printSettingsSvc
+ = do_GetService("@mozilla.org/gfx/printsettings-service;1");
+
// Set the print job title
char16_t** docTitles;
uint32_t titleCount;
nsresult rv = aWebBrowserPrint->EnumerateDocumentNames(&titleCount, &docTitles);
if (NS_SUCCEEDED(rv) && titleCount > 0) {
CFStringRef cfTitleString = CFStringCreateWithCharacters(NULL, reinterpret_cast<const UniChar*>(docTitles[0]),
NS_strlen(docTitles[0]));
if (cfTitleString) {
@@ -63,16 +67,19 @@ nsPrintDialogServiceX::Show(nsPIDOMWindo
for (int32_t i = titleCount - 1; i >= 0; i--) {
free(docTitles[i]);
}
free(docTitles);
docTitles = NULL;
titleCount = 0;
}
+ // Read default print settings from prefs
+ printSettingsSvc->InitPrintSettingsFromPrefs(settingsX, true,
+ nsIPrintSettings::kInitSaveNativeData);
NSPrintInfo* printInfo = settingsX->GetCocoaPrintInfo();
// Put the print info into the current print operation, since that's where
// [panel runModal] will look for it. We create the view because otherwise
// we'll get unrelated warnings printed to the console.
NSView* tmpView = [[NSView alloc] init];
NSPrintOperation* printOperation = [NSPrintOperation printOperationWithView:tmpView printInfo:printInfo];
[NSPrintOperation setCurrentOperation:printOperation];
@@ -92,28 +99,60 @@ nsPrintDialogServiceX::Show(nsPIDOMWindo
nsCocoaUtils::PrepareForNativeAppModalDialog();
int button = [panel runModal];
nsCocoaUtils::CleanUpAfterNativeAppModalDialog();
NSPrintInfo* copy = [[[NSPrintOperation currentOperation] printInfo] copy];
if (!copy) {
return NS_ERROR_OUT_OF_MEMORY;
}
- settingsX->SetCocoaPrintInfo(copy);
- [copy release];
[NSPrintOperation setCurrentOperation:nil];
[tmpView release];
if (button != NSFileHandlingPanelOKButton)
return NS_ERROR_ABORT;
+ settingsX->SetCocoaPrintInfo(copy);
+ settingsX->InitUnwriteableMargin();
+
+ // Save settings unless saving is pref'd off
+ if (Preferences::GetBool("print.save_print_settings", false)) {
+ printSettingsSvc->SavePrintSettingsToPrefs(settingsX, true,
+ nsIPrintSettings::kInitSaveNativeData);
+ }
+
+ // Get coordinate space resolution for converting paper size units to inches
+ NSWindow *win = [[NSApplication sharedApplication] mainWindow];
+ if (win) {
+ NSDictionary *devDesc = [win deviceDescription];
+ if (devDesc) {
+ NSSize res = [[devDesc objectForKey: NSDeviceResolution] sizeValue];
+ float scale = [win backingScaleFactor];
+ if (scale > 0) {
+ settingsX->SetInchesScale(res.width / scale, res.height / scale);
+ }
+ }
+ }
+
// Export settings.
[viewController exportSettings];
+ // If "ignore scaling" is checked, overwrite scaling factor with 1.
+ bool isShrinkToFitChecked;
+ settingsX->GetShrinkToFit(&isShrinkToFitChecked);
+ if (isShrinkToFitChecked) {
+ NSMutableDictionary* dict = [copy dictionary];
+ if (dict) {
+ [dict setObject: [NSNumber numberWithFloat: 1]
+ forKey: NSPrintScalingFactor];
+ }
+ }
+ [copy release];
+
int16_t pageRange;
aSettings->GetPrintRange(&pageRange);
if (pageRange != nsIPrintSettings::kRangeSelection) {
PMPrintSettings nativePrintSettings = settingsX->GetPMPrintSettings();
UInt32 firstPage, lastPage;
OSStatus status = ::PMGetFirstPage(nativePrintSettings, &firstPage);
if (status == noErr) {
status = ::PMGetLastPage(nativePrintSettings, &lastPage);
--- a/widget/cocoa/nsPrintOptionsX.h
+++ b/widget/cocoa/nsPrintOptionsX.h
@@ -17,16 +17,23 @@ namespace embedding
} // namespace mozilla
class nsPrintOptionsX : public nsPrintOptions
{
public:
nsPrintOptionsX();
virtual ~nsPrintOptionsX();
+ /*
+ * These serialize and deserialize methods are not symmetrical in that
+ * printSettingsX != deserialize(serialize(printSettingsX)). This is because
+ * the native print settings stored in the nsPrintSettingsX's NSPrintInfo
+ * object are not fully serialized. Only the values needed for successful
+ * printing are.
+ */
NS_IMETHODIMP SerializeToPrintData(nsIPrintSettings* aSettings,
nsIWebBrowserPrint* aWBP,
mozilla::embedding::PrintData* data);
NS_IMETHODIMP DeserializeToPrintSettings(const mozilla::embedding::PrintData& data,
nsIPrintSettings* settings);
protected:
nsresult _CreatePrintSettings(nsIPrintSettings **_retval);
--- a/widget/cocoa/nsPrintOptionsX.mm
+++ b/widget/cocoa/nsPrintOptionsX.mm
@@ -4,16 +4,29 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "nsCOMPtr.h"
#include "nsQueryObject.h"
#include "nsIServiceManager.h"
#include "nsPrintOptionsX.h"
#include "nsPrintSettingsX.h"
+// The constants for paper orientation were renamed in 10.9. __MAC_10_9 is
+// defined on OS X 10.9 and later. Although 10.8 and earlier are not supported
+// at this time, this allows for building on those older OS versions. The
+// values are consistent across OS versions so the rename does not affect
+// runtime, just compilation.
+#ifdef __MAC_10_9
+#define NS_PAPER_ORIENTATION_PORTRAIT (NSPaperOrientationPortrait)
+#define NS_PAPER_ORIENTATION_LANDSCAPE (NSPaperOrientationLandscape)
+#else
+#define NS_PAPER_ORIENTATION_PORTRAIT (NSPortraitOrientation)
+#define NS_PAPER_ORIENTATION_LANDSCAPE (NSLandscapeOrientation)
+#endif
+
using namespace mozilla::embedding;
nsPrintOptionsX::nsPrintOptionsX()
{
}
nsPrintOptionsX::~nsPrintOptionsX()
{
@@ -85,16 +98,48 @@ nsPrintOptionsX::SerializeToPrintData(ns
data->printTime() = timestamp;
}
NSString* disposition = [dict objectForKey: NSPrintJobDisposition];
if (disposition) {
nsCocoaUtils::GetStringForNSString(disposition, data->disposition());
}
+ NSString* paperName = [dict objectForKey: NSPrintPaperName];
+ if (paperName) {
+ nsCocoaUtils::GetStringForNSString(paperName, data->paperName());
+ }
+
+ float scalingFactor = [[dict objectForKey: NSPrintScalingFactor] floatValue];
+ data->scalingFactor() = scalingFactor;
+
+ int32_t orientation;
+ if ([printInfo orientation] == NS_PAPER_ORIENTATION_PORTRAIT) {
+ orientation = nsIPrintSettings::kPortraitOrientation;
+ } else {
+ orientation = nsIPrintSettings::kLandscapeOrientation;
+ }
+ data->orientation() = orientation;
+
+ NSSize paperSize = [printInfo paperSize];
+ float widthScale, heightScale;
+ settingsX->GetInchesScale(&widthScale, &heightScale);
+ if (orientation == nsIPrintSettings::kLandscapeOrientation) {
+ // switch widths and heights
+ data->widthScale() = heightScale;
+ data->heightScale() = widthScale;
+ data->paperWidth() = paperSize.height / heightScale;
+ data->paperHeight() = paperSize.width / widthScale;
+ } else {
+ data->widthScale() = widthScale;
+ data->heightScale() = heightScale;
+ data->paperWidth() = paperSize.width / widthScale;
+ data->paperHeight() = paperSize.height / heightScale;
+ }
+
data->numCopies() = [[dict objectForKey: NSPrintCopies] intValue];
data->printAllPages() = [[dict objectForKey: NSPrintAllPages] boolValue];
data->startPageRange() = [[dict objectForKey: NSPrintFirstPage] intValue];
data->endPageRange() = [[dict objectForKey: NSPrintLastPage] intValue];
data->mustCollate() = [[dict objectForKey: NSPrintMustCollate] boolValue];
data->printReversed() = [[dict objectForKey: NSPrintReversePageOrder] boolValue];
data->pagesAcross() = [[dict objectForKey: NSPrintPagesAcross] unsignedShortValue];
data->pagesDown() = [[dict objectForKey: NSPrintPagesDown] unsignedShortValue];
@@ -163,16 +208,38 @@ nsPrintOptionsX::DeserializeToPrintSetti
[newPrintInfoDict setObject: [NSNumber numberWithBool: data.mustCollate()]
forKey: NSPrintMustCollate];
[newPrintInfoDict setObject: [NSNumber numberWithBool: data.printReversed()]
forKey: NSPrintReversePageOrder];
[newPrintInfoDict setObject: nsCocoaUtils::ToNSString(data.disposition())
forKey: NSPrintJobDisposition];
+ [newPrintInfoDict setObject: nsCocoaUtils::ToNSString(data.paperName())
+ forKey: NSPrintPaperName];
+
+ [newPrintInfoDict setObject: [NSNumber numberWithFloat: data.scalingFactor()]
+ forKey: NSPrintScalingFactor];
+
+ CGFloat width = data.paperWidth() * data.widthScale();
+ CGFloat height = data.paperHeight() * data.heightScale();
+ [newPrintInfoDict setObject: [NSValue valueWithSize:NSMakeSize(width,height)]
+ forKey: NSPrintPaperSize];
+
+ int paperOrientation;
+ if (data.orientation() == nsIPrintSettings::kPortraitOrientation) {
+ paperOrientation = NS_PAPER_ORIENTATION_PORTRAIT;
+ settings->SetOrientation(nsIPrintSettings::kPortraitOrientation);
+ } else {
+ paperOrientation = NS_PAPER_ORIENTATION_LANDSCAPE;
+ settings->SetOrientation(nsIPrintSettings::kLandscapeOrientation);
+ }
+ [newPrintInfoDict setObject: [NSNumber numberWithInt:paperOrientation]
+ forKey: NSPrintOrientation];
+
[newPrintInfoDict setObject: [NSNumber numberWithShort: data.pagesAcross()]
forKey: NSPrintPagesAcross];
[newPrintInfoDict setObject: [NSNumber numberWithShort: data.pagesDown()]
forKey: NSPrintPagesDown];
[newPrintInfoDict setObject: [NSNumber numberWithBool: data.detailedErrorReporting()]
forKey: NSPrintDetailedErrorReporting];
[newPrintInfoDict setObject: nsCocoaUtils::ToNSString(data.faxNumber())
forKey: NSPrintFaxNumber];
--- a/widget/cocoa/nsPrintSettingsX.h
+++ b/widget/cocoa/nsPrintSettingsX.h
@@ -26,31 +26,39 @@ public:
virtual nsresult ReadPageFormatFromPrefs();
virtual nsresult WritePageFormatToPrefs();
PMPrintSettings GetPMPrintSettings();
PMPrintSession GetPMPrintSession();
PMPageFormat GetPMPageFormat();
void SetPMPageFormat(PMPageFormat aPageFormat);
+ // Re-initialize mUnwriteableMargin with values from mPageFormat.
+ // Should be called whenever mPageFormat is initialized or overwritten.
+ nsresult InitUnwriteableMargin();
+
+ void SetInchesScale(float aWidthScale, float aHeightScale);
+ void GetInchesScale(float *aWidthScale, float *aHeightScale);
+
protected:
virtual ~nsPrintSettingsX();
nsPrintSettingsX(const nsPrintSettingsX& src);
nsPrintSettingsX& operator=(const nsPrintSettingsX& rhs);
nsresult _Clone(nsIPrintSettings **_retval) override;
nsresult _Assign(nsIPrintSettings *aPS) override;
- // Re-initialize mUnwriteableMargin with values from mPageFormat.
- // Should be called whenever mPageFormat is initialized or overwritten.
- nsresult InitUnwriteableMargin();
-
// The out param has a ref count of 1 on return so caller needs to PMRelase() when done.
OSStatus CreateDefaultPageFormat(PMPrintSession aSession, PMPageFormat& outFormat);
OSStatus CreateDefaultPrintSettings(PMPrintSession aSession, PMPrintSettings& outSettings);
NSPrintInfo* mPrintInfo;
+
+ // Scaling factors used to convert the NSPrintInfo
+ // paper size units to inches
+ float mWidthScale;
+ float mHeightScale;
};
NS_DEFINE_STATIC_IID_ACCESSOR(nsPrintSettingsX, NS_PRINTSETTINGSX_IID)
#endif // nsPrintSettingsX_h_
--- a/widget/cocoa/nsPrintSettingsX.mm
+++ b/widget/cocoa/nsPrintSettingsX.mm
@@ -11,24 +11,27 @@
#include "nsCocoaUtils.h"
#include "mozilla/Preferences.h"
using namespace mozilla;
#define MAC_OS_X_PAGE_SETUP_PREFNAME "print.macosx.pagesetup-2"
+#define COCOA_PAPER_UNITS_PER_INCH 72.0
NS_IMPL_ISUPPORTS_INHERITED(nsPrintSettingsX, nsPrintSettings, nsPrintSettingsX)
nsPrintSettingsX::nsPrintSettingsX()
{
NS_OBJC_BEGIN_TRY_ABORT_BLOCK;
mPrintInfo = [[NSPrintInfo sharedPrintInfo] copy];
+ mWidthScale = COCOA_PAPER_UNITS_PER_INCH;
+ mHeightScale = COCOA_PAPER_UNITS_PER_INCH;
NS_OBJC_END_TRY_ABORT_BLOCK;
}
nsPrintSettingsX::nsPrintSettingsX(const nsPrintSettingsX& src)
{
*this = src;
}
@@ -195,8 +198,21 @@ nsPrintSettingsX::GetPMPageFormat()
void
nsPrintSettingsX::SetPMPageFormat(PMPageFormat aPageFormat)
{
PMPageFormat oldPageFormat = GetPMPageFormat();
::PMCopyPageFormat(aPageFormat, oldPageFormat);
[mPrintInfo updateFromPMPageFormat];
}
+void
+nsPrintSettingsX::SetInchesScale(float aWidthScale, float aHeightScale)
+{
+ mWidthScale = aWidthScale;
+ mHeightScale = aHeightScale;
+}
+
+void
+nsPrintSettingsX::GetInchesScale(float *aWidthScale, float *aHeightScale)
+{
+ *aWidthScale = mWidthScale;
+ *aHeightScale = mHeightScale;
+}