Backed out changeset d42d7505c9cf (bug 1760836) for causing mochitest failures on browser_print_stream.js. CLOSED TREE

This commit is contained in:
Iulian Moraru 2022-03-29 23:32:39 +03:00
parent a14c6be573
commit 7a3ed2ce2a
29 changed files with 305 additions and 525 deletions

View File

@ -1351,8 +1351,7 @@ this.tabs = class extends ExtensionAPI {
printSettings.isInitializedFromPrinter = true;
printSettings.isInitializedFromPrefs = true;
printSettings.outputDestination =
Ci.nsIPrintSettings.kOutputDestinationFile;
printSettings.printToFile = true;
printSettings.toFileName = picker.file.path;
printSettings.printSilent = true;

View File

@ -9,9 +9,8 @@
#include <Carbon/Carbon.h>
#include "PrintTarget.h"
class nsIOutputStream;
namespace mozilla::gfx {
namespace mozilla {
namespace gfx {
/**
* CoreGraphics printing target.
@ -19,9 +18,8 @@ namespace mozilla::gfx {
class PrintTargetCG final : public PrintTarget {
public:
static already_AddRefed<PrintTargetCG> CreateOrNull(
nsIOutputStream* aOutputStream, PMPrintSession aPrintSession,
PMPageFormat aPageFormat, PMPrintSettings aPrintSettings,
const IntSize& aSize);
PMPrintSession aPrintSession, PMPageFormat aPageFormat,
PMPrintSettings aPrintSettings, const IntSize& aSize);
nsresult BeginPrinting(const nsAString& aTitle,
const nsAString& aPrintToFileName, int32_t aStartPage,
@ -34,17 +32,16 @@ class PrintTargetCG final : public PrintTarget {
already_AddRefed<DrawTarget> GetReferenceDrawTarget() final;
private:
PrintTargetCG(CGContextRef aPrintToStreamContext,
PMPrintSession aPrintSession, PMPageFormat aPageFormat,
PrintTargetCG(PMPrintSession aPrintSession, PMPageFormat aPageFormat,
PMPrintSettings aPrintSettings, const IntSize& aSize);
~PrintTargetCG();
CGContextRef mPrintToStreamContext = nullptr;
PMPrintSession mPrintSession;
PMPageFormat mPageFormat;
PMPrintSettings mPrintSettings;
};
} // namespace mozilla::gfx
} // namespace gfx
} // namespace mozilla
#endif /* MOZILLA_GFX_PRINTTARGETCG_H */

View File

@ -10,17 +10,13 @@
#include "mozilla/gfx/HelpersCairo.h"
#include "nsObjCExceptions.h"
#include "nsString.h"
#include "nsIOutputStream.h"
namespace mozilla::gfx {
namespace mozilla {
namespace gfx {
static size_t PutBytesNull(void* info, const void* buffer, size_t count) { return count; }
PrintTargetCG::PrintTargetCG(CGContextRef aPrintToStreamContext, PMPrintSession aPrintSession,
PMPageFormat aPageFormat, PMPrintSettings aPrintSettings,
const IntSize& aSize)
PrintTargetCG::PrintTargetCG(PMPrintSession aPrintSession, PMPageFormat aPageFormat,
PMPrintSettings aPrintSettings, const IntSize& aSize)
: PrintTarget(/* aCairoSurface */ nullptr, aSize),
mPrintToStreamContext(aPrintToStreamContext),
mPrintSession(aPrintSession),
mPageFormat(aPageFormat),
mPrintSettings(aPrintSettings) {
@ -45,80 +41,24 @@ PrintTargetCG::~PrintTargetCG() {
::PMRelease(mPageFormat);
::PMRelease(mPrintSettings);
if (mPrintToStreamContext) {
CGContextRelease(mPrintToStreamContext);
}
NS_OBJC_END_TRY_IGNORE_BLOCK;
}
static size_t WriteStreamBytes(void* aInfo, const void* aBuffer, size_t aCount) {
auto* stream = static_cast<nsIOutputStream*>(aInfo);
auto* data = static_cast<const char*>(aBuffer);
size_t remaining = aCount;
do {
uint32_t wrote = 0;
// Handle potential narrowing from size_t to uint32_t.
uint32_t toWrite = uint32_t(std::min(remaining, size_t(std::numeric_limits<uint32_t>::max())));
if (NS_WARN_IF(NS_FAILED(stream->Write(data, toWrite, &wrote)))) {
break;
}
data += wrote;
remaining -= size_t(wrote);
} while (remaining);
return aCount;
}
static void ReleaseStream(void* aInfo) {
auto* stream = static_cast<nsIOutputStream*>(aInfo);
stream->Close();
NS_RELEASE(stream);
}
static CGContextRef CreatePrintToStreamContext(nsIOutputStream* aOutputStream,
const IntSize& aSize) {
MOZ_ASSERT(aOutputStream);
NS_ADDREF(aOutputStream); // Matched by the NS_RELEASE in ReleaseStream.
CGRect pageBox{{0.0, 0.0}, {CGFloat(aSize.width), CGFloat(aSize.height)}};
CGDataConsumerCallbacks callbacks = {WriteStreamBytes, ReleaseStream};
CGDataConsumerRef consumer = CGDataConsumerCreate(aOutputStream, &callbacks);
// This metadata is added by the CorePrinting APIs in the non-stream case.
NSString* bundleName =
[NSBundle.mainBundle.localizedInfoDictionary objectForKey:(NSString*)kCFBundleNameKey];
CFMutableDictionaryRef auxiliaryInfo = CFDictionaryCreateMutable(
kCFAllocatorDefault, 1, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
CFDictionaryAddValue(auxiliaryInfo, kCGPDFContextCreator, (__bridge CFStringRef)bundleName);
CGContextRef pdfContext = CGPDFContextCreate(consumer, &pageBox, auxiliaryInfo);
CGDataConsumerRelease(consumer);
CFRelease(auxiliaryInfo);
return pdfContext;
}
/* static */ already_AddRefed<PrintTargetCG> PrintTargetCG::CreateOrNull(
nsIOutputStream* aOutputStream, PMPrintSession aPrintSession, PMPageFormat aPageFormat,
PMPrintSettings aPrintSettings, const IntSize& aSize) {
PMPrintSession aPrintSession, PMPageFormat aPageFormat, PMPrintSettings aPrintSettings,
const IntSize& aSize) {
if (!Factory::CheckSurfaceSize(aSize)) {
return nullptr;
}
CGContextRef printToStreamContext = nullptr;
if (aOutputStream) {
printToStreamContext = CreatePrintToStreamContext(aOutputStream, aSize);
if (!printToStreamContext) {
return nullptr;
}
}
RefPtr<PrintTargetCG> target =
new PrintTargetCG(printToStreamContext, aPrintSession, aPageFormat, aPrintSettings, aSize);
new PrintTargetCG(aPrintSession, aPageFormat, aPrintSettings, aSize);
return target.forget();
}
static size_t PutBytesNull(void* info, const void* buffer, size_t count) { return count; }
already_AddRefed<DrawTarget> PrintTargetCG::GetReferenceDrawTarget() {
if (!mRefDT) {
const IntSize size(1, 1);
@ -155,10 +95,6 @@ nsresult PrintTargetCG::BeginPrinting(const nsAString& aTitle, const nsAString&
int32_t aStartPage, int32_t aEndPage) {
NS_OBJC_BEGIN_TRY_BLOCK_RETURN;
if (mPrintToStreamContext) {
return NS_OK;
}
// Print Core of Application Service sent print job with names exceeding
// 255 bytes. This is a workaround until fix it.
// (https://openradar.appspot.com/34428043)
@ -191,12 +127,6 @@ nsresult PrintTargetCG::BeginPrinting(const nsAString& aTitle, const nsAString&
nsresult PrintTargetCG::EndPrinting() {
NS_OBJC_BEGIN_TRY_BLOCK_RETURN;
if (mPrintToStreamContext) {
CGContextFlush(mPrintToStreamContext);
CGPDFContextClose(mPrintToStreamContext);
return NS_OK;
}
::PMSessionEndDocumentNoDialog(mPrintSession);
return NS_OK;
@ -213,24 +143,19 @@ nsresult PrintTargetCG::AbortPrinting() {
nsresult PrintTargetCG::BeginPage() {
NS_OBJC_BEGIN_TRY_BLOCK_RETURN;
PMSessionError(mPrintSession);
OSStatus status = ::PMSessionBeginPageNoDialog(mPrintSession, mPageFormat, NULL);
if (status != noErr) {
return NS_ERROR_ABORT;
}
CGContextRef context;
if (mPrintToStreamContext) {
CGContextBeginPage(mPrintToStreamContext, nullptr);
context = mPrintToStreamContext;
} else {
PMSessionError(mPrintSession);
OSStatus status = ::PMSessionBeginPageNoDialog(mPrintSession, mPageFormat, nullptr);
if (status != noErr) {
return NS_ERROR_ABORT;
}
// This call will fail if it wasn't called between the PMSessionBeginPage/
// PMSessionEndPage calls:
::PMSessionGetCGGraphicsContext(mPrintSession, &context);
// This call will fail if it wasn't called between the PMSessionBeginPage/
// PMSessionEndPage calls:
::PMSessionGetCGGraphicsContext(mPrintSession, &context);
if (!context) {
return NS_ERROR_FAILURE;
}
if (!context) {
return NS_ERROR_FAILURE;
}
unsigned int width = static_cast<unsigned int>(mSize.width);
@ -260,13 +185,9 @@ nsresult PrintTargetCG::EndPage() {
cairo_surface_finish(mCairoSurface);
mCairoSurface = nullptr;
if (mPrintToStreamContext) {
CGContextEndPage(mPrintToStreamContext);
} else {
OSStatus status = ::PMSessionEndPageNoDialog(mPrintSession);
if (status != noErr) {
return NS_ERROR_ABORT;
}
OSStatus status = ::PMSessionEndPageNoDialog(mPrintSession);
if (status != noErr) {
return NS_ERROR_ABORT;
}
return PrintTarget::EndPage();
@ -274,4 +195,5 @@ nsresult PrintTargetCG::EndPage() {
NS_OBJC_END_TRY_BLOCK_RETURN(NS_ERROR_FAILURE);
}
} // namespace mozilla::gfx
} // namespace gfx
} // namespace mozilla

View File

@ -1080,9 +1080,10 @@ nsresult nsPrintJob::SetupToPrintContent() {
nsAutoString fileNameStr;
// check to see if we are printing to a file
if (printData->mPrintSettings->GetOutputDestination() ==
nsIPrintSettings::kOutputDestinationFile) {
// On some platforms the BeginDocument needs to know the name of the file.
bool isPrintToFile = false;
printData->mPrintSettings->GetPrintToFile(&isPrintToFile);
if (isPrintToFile) {
// On some platforms The BeginDocument needs to know the name of the file.
printData->mPrintSettings->GetToFileName(fileNameStr);
}
@ -2331,7 +2332,8 @@ nsresult nsPrintJob::StartPagePrintTimer(const UniquePtr<nsPrintObject>& aPO) {
if (!mPagePrintTimer) {
// Get the delay time in between the printing of each page
// this gives the user more time to press cancel
int32_t printPageDelay = mPrt->mPrintSettings->GetPrintPageDelay();
int32_t printPageDelay = 50;
mPrt->mPrintSettings->GetPrintPageDelay(&printPageDelay);
nsCOMPtr<nsIContentViewer> cv = do_QueryInterface(mDocViewerPrint);
NS_ENSURE_TRUE(cv, NS_ERROR_FAILURE);

View File

@ -1721,7 +1721,7 @@ function RecvStartPrint(isPrintSelection, printRange)
ps.unwriteableMarginRight = 0;
ps.unwriteableMarginLeft = 0;
ps.unwriteableMarginBottom = 0;
ps.outputDestination = Ci.nsIPrintSettings.kOutputDestinationFile;
ps.printToFile = true;
ps.toFileName = file.path;
ps.outputFormat = Ci.nsIPrintSettings.kOutputFormatPDF;
ps.printSelectionOnly = isPrintSelection;

View File

@ -575,8 +575,7 @@ class Page extends Domain {
printSettings.outputFormat = Ci.nsIPrintSettings.kOutputFormatPDF;
printSettings.printerName = "";
printSettings.printSilent = true;
printSettings.outputDestination =
Ci.nsIPrintSettings.kOutputDestinationFile;
printSettings.printToFile = true;
printSettings.toFileName = filePath;
printSettings.paperSizeUnit = Ci.nsIPrintSettings.kPaperSizeInches;

View File

@ -70,7 +70,7 @@ function getPrintSettings(settings, filePath) {
printSettings.outputFormat = Ci.nsIPrintSettings.kOutputFormatPDF;
printSettings.printerName = "marionette";
printSettings.printSilent = true;
printSettings.outputDestination = Ci.nsIPrintSettings.kOutputDestinationFile;
printSettings.printToFile = true;
printSettings.toFileName = filePath;
// Setting the paperSizeUnit to kPaperSizeMillimeters doesn't work on mac

View File

@ -1181,18 +1181,15 @@ var PrintSettingsViewProxy = {
printerInfo.defaultSettings.toFileName = "";
printerInfo.defaultSettings.outputFormat =
Ci.nsIPrintSettings.kOutputFormatPDF;
printerInfo.defaultSettings.outputDestination =
Ci.nsIPrintSettings.kOutputDestinationFile;
printerInfo.defaultSettings.printToFile = true;
printerInfo.paperList = this.fallbackPaperList;
}
printerInfo.settings = printerInfo.defaultSettings.clone();
// Apply any previously persisted user values
// Don't apply kInitSavePrintToFile though, that should only be true for
// the PDF printer.
printerInfo.settings.outputDestination =
printerName == PrintUtils.SAVE_TO_PDF_PRINTER
? Ci.nsIPrintSettings.kOutputDestinationFile
: Ci.nsIPrintSettings.kOutputDestinationPrinter;
printerInfo.settings.printToFile =
printerName == PrintUtils.SAVE_TO_PDF_PRINTER;
let flags =
printerInfo.settings.kInitSaveAll ^
printerInfo.settings.kInitSavePrintToFile;
@ -2618,7 +2615,7 @@ class PageCount extends PrintUIControlMixin(HTMLElement) {
update(settings) {
this.numCopies = settings.numCopies;
this.duplex = settings.duplex;
this.outputDestination = settings.outputDestination;
this.printToFile = settings.printToFile;
this.render();
}
@ -2631,10 +2628,7 @@ class PageCount extends PrintUIControlMixin(HTMLElement) {
// When printing to a printer (not to a file) update
// the sheet count to account for duplex printing.
if (
this.outputDestination == Ci.nsIPrintSettings.kOutputDestinationPrinter &&
this.duplex != Ci.nsIPrintSettings.kDuplexNone
) {
if (!this.printToFile && this.duplex != Ci.nsIPrintSettings.kDuplexNone) {
sheetCount = Math.ceil(sheetCount / 2);
}

View File

@ -270,11 +270,7 @@ var PrintUtils = {
async function makePrintSettingsMaybeEnsuringToFileName() {
let settings = PrintUtils.getPrintSettings();
if (
settings.outputDestination ==
Ci.nsIPrintSettings.kOutputDestinationFile &&
!settings.toFileName
) {
if (settings.printToFile && !settings.toFileName) {
// TODO(bug 1748004): We should consider generating the file name
// from the document's title as we do in print.js's pickFileName
// (including using DownloadPaths.sanitize!).

View File

@ -28,7 +28,6 @@ skip-if = (verify && (os == 'mac')) # bug 1675609
[browser_print_margins.js]
[browser_print_frame.js]
[browser_print_selection.js]
[browser_print_stream.js]
[browser_print_page_range.js]
[browser_print_pdf_on_frame_load.js]
support-files =

View File

@ -22,8 +22,8 @@ add_task(async function testPDFPrinterSettings() {
let { settings } = helper;
ok(
settings.outputDestination == Ci.nsIPrintSettings.kOutputDestinationFile,
"Check the current settings have file destination"
settings.printToFile,
"Check the current settings have a truthy printToFile for the PDF printer"
);
ok(
settings.printInColor,

View File

@ -1,94 +0,0 @@
//creativecommons.org/publicdomain/zero/1.0/ */
"use strict";
const PSSVC = Cc["@mozilla.org/gfx/printsettings-service;1"].getService(
Ci.nsIPrintSettingsService
);
async function printToDestination(aBrowser, aDestination) {
let tmpDir = Services.dirsvc.get("TmpD", Ci.nsIFile);
let fileName = `printDestinationTest-${aDestination}.pdf`;
let filePath = PathUtils.join(tmpDir.path, fileName);
info(`Printing to ${filePath}`);
let settings = PSSVC.newPrintSettings;
settings.outputFormat = Ci.nsIPrintSettings.kOutputFormatPDF;
settings.outputDestination = aDestination;
settings.unwriteableMarginTop = 1; /* Just to ensure settings are respected on both */
let outStream = null;
if (aDestination == Ci.nsIPrintSettings.kOutputDestinationFile) {
settings.toFileName = PathUtils.join(tmpDir.path, fileName);
} else {
is(aDestination, Ci.nsIPrintSettings.kOutputDestinationStream);
outStream = Cc["@mozilla.org/network/file-output-stream;1"].createInstance(
Ci.nsIFileOutputStream
);
let tmpFile = tmpDir.clone();
tmpFile.append(fileName);
outStream.init(tmpFile, -1, 0o666, 0);
settings.outputStream = outStream;
}
await aBrowser.browsingContext.print(settings);
return filePath;
}
// In Cocoa the CGContext adds a hash, plus there are other minor
// non-user-visible differences, so we need to be a bit sloppy here.
const COCOA_MAX_SIZE_DIFFERENCE = 100; // bytes
add_task(async function testPrintToStream() {
await PrintHelper.withTestPage(async helper => {
let filePath = await printToDestination(
helper.sourceBrowser,
Ci.nsIPrintSettings.kOutputDestinationFile
);
let streamPath = await printToDestination(
helper.sourceBrowser,
Ci.nsIPrintSettings.kOutputDestinationStream
);
const isCocoa = AppConstants.platform == "macosx";
// Buffering shenanigans? Wait for sizes to match... There's no great
// IOUtils methods to force a flush without writing anything...
await TestUtils.waitForCondition(async function() {
let fileStat = await IOUtils.stat(filePath);
let streamStat = await IOUtils.stat(streamPath);
ok(fileStat.size > 0, "File file should not be empty: " + fileStat.size);
ok(
streamStat.size > 0,
"Stream file should not be empty: " + streamStat.size
);
if (isCocoa) {
return (
Math.abs(fileStat.size - streamStat.size) < COCOA_MAX_SIZE_DIFFERENCE
);
}
return fileStat.size == streamStat.size;
}, "Sizes should match");
if (!isCocoa) {
let fileData = await IOUtils.read(filePath);
let streamData = await IOUtils.read(streamPath);
ok(!!fileData.length, "File should not be empty");
is(fileData.length, streamData.length, "File size should be equal");
for (let i = 0; i < fileData.length; ++i) {
if (fileData[i] != streamData[i]) {
is(
fileData[i],
streamData[i],
`Files should be equal (byte ${i} different)`
);
}
}
}
await IOUtils.remove(filePath);
await IOUtils.remove(streamPath);
});
});

View File

@ -285,8 +285,7 @@ class PrintHelper {
defaultSettings.printerName = name;
defaultSettings.toFileName = "";
defaultSettings.outputFormat = Ci.nsIPrintSettings.kOutputFormatNative;
defaultSettings.outputDestination =
Ci.nsIPrintSettings.kOutputDestinationPrinter;
defaultSettings.printToFile = false;
defaultSettings.paperSizeUnit = paperSizeUnit;
if (paperId) {
defaultSettings.paperId = paperId;

View File

@ -57,13 +57,10 @@ struct PrintData {
int32_t orientation;
int32_t numCopies;
int32_t numPagesPerSheet;
// TODO: Do we really need to deal with these in child processes?
short outputDestination;
short outputFormat;
nsString printerName;
bool printToFile;
nsString toFileName;
short outputFormat;
int32_t printPageDelay;
int32_t resolution;
int32_t duplex;

View File

@ -11,50 +11,32 @@
#include "nsIFile.h"
#include "nsIFileStreams.h"
#include "nsIPrintSettings.h"
#include "nsIFileStreams.h"
#include "nsDirectoryServiceDefs.h"
#include "nsAnonymousTemporaryFile.h"
using namespace mozilla;
using namespace mozilla::gfx;
NS_IMPL_ISUPPORTS(nsDeviceContextSpecAndroid, nsIDeviceContextSpec)
nsDeviceContextSpecAndroid::~nsDeviceContextSpecAndroid() {
if (mTempFile) {
mTempFile->Remove(false);
}
}
already_AddRefed<PrintTarget> nsDeviceContextSpecAndroid::MakePrintTarget() {
double width, height;
mPrintSettings->GetEffectiveSheetSize(&width, &height);
nsresult rv =
NS_GetSpecialDirectory(NS_OS_TEMP_DIR, getter_AddRefs(mTempFile));
NS_ENSURE_SUCCESS(rv, nullptr);
// convert twips to points
width /= TWIPS_PER_POINT_FLOAT;
height /= TWIPS_PER_POINT_FLOAT;
nsAutoCString filename("tmp-printing.pdf");
mTempFile->AppendNative(filename);
rv = mTempFile->CreateUnique(nsIFile::NORMAL_FILE_TYPE, 0660);
NS_ENSURE_SUCCESS(rv, nullptr);
auto stream = [&]() -> nsCOMPtr<nsIOutputStream> {
if (mPrintSettings->GetOutputDestination() ==
nsIPrintSettings::kOutputDestinationStream) {
nsCOMPtr<nsIOutputStream> out;
mPrintSettings->GetOutputStream(getter_AddRefs(out));
return out;
}
if (NS_FAILED(
NS_OpenAnonymousTemporaryNsIFile(getter_AddRefs(mTempFile)))) {
return nullptr;
}
// Print to printer not supported...
nsCOMPtr<nsIFileOutputStream> s =
do_CreateInstance("@mozilla.org/network/file-output-stream;1");
if (NS_FAILED(s->Init(mTempFile, -1, -1, 0))) {
return nullptr;
}
return s;
}();
nsCOMPtr<nsIFileOutputStream> stream =
do_CreateInstance("@mozilla.org/network/file-output-stream;1");
rv = stream->Init(mTempFile, -1, -1, 0);
NS_ENSURE_SUCCESS(rv, nullptr);
return PrintTargetPDF::CreateOrNull(stream, IntSize::Ceil(width, height));
// XXX: what should we do here for size? screen size?
IntSize size(480, 800);
return PrintTargetPDF::CreateOrNull(stream, size);
}
NS_IMETHODIMP
@ -74,23 +56,24 @@ nsDeviceContextSpecAndroid::BeginDocument(const nsAString& aTitle,
NS_IMETHODIMP
nsDeviceContextSpecAndroid::EndDocument() {
if (mPrintSettings->GetOutputDestination() ==
nsIPrintSettings::kOutputDestinationFile &&
mTempFile) {
nsAutoString targetPath;
mPrintSettings->GetToFileName(targetPath);
nsCOMPtr<nsIFile> destFile;
MOZ_TRY(NS_NewLocalFile(targetPath, false, getter_AddRefs(destFile)));
nsAutoString destLeafName;
MOZ_TRY(destFile->GetLeafName(destLeafName));
nsString targetPath;
nsCOMPtr<nsIFile> destFile;
mPrintSettings->GetToFileName(targetPath);
nsCOMPtr<nsIFile> destDir;
MOZ_TRY(destFile->GetParent(getter_AddRefs(destDir)));
nsresult rv = NS_NewLocalFile(targetPath, false, getter_AddRefs(destFile));
NS_ENSURE_SUCCESS(rv, rv);
MOZ_TRY(mTempFile->MoveTo(destDir, destLeafName));
destFile->SetPermissions(0666);
nsAutoString destLeafName;
rv = destFile->GetLeafName(destLeafName);
NS_ENSURE_SUCCESS(rv, rv);
mTempFile = nullptr;
}
nsCOMPtr<nsIFile> destDir;
rv = destFile->GetParent(getter_AddRefs(destDir));
NS_ENSURE_SUCCESS(rv, rv);
rv = mTempFile->MoveTo(destDir, destLeafName);
NS_ENSURE_SUCCESS(rv, rv);
destFile->SetPermissions(0666);
return NS_OK;
}

View File

@ -10,7 +10,7 @@
class nsDeviceContextSpecAndroid final : public nsIDeviceContextSpec {
private:
virtual ~nsDeviceContextSpecAndroid();
~nsDeviceContextSpecAndroid() {}
public:
NS_DECL_ISUPPORTS

View File

@ -37,14 +37,13 @@ class nsDeviceContextSpecX : public nsIDeviceContextSpec {
virtual ~nsDeviceContextSpecX();
protected:
PMPrintSession mPrintSession = nullptr; // printing context.
PMPageFormat mPageFormat = nullptr; // page format.
PMPrintSettings mPrintSettings = nullptr; // print settings.
nsCOMPtr<nsIOutputStream> mOutputStream; // Output stream from settings.
PMPrintSession mPrintSession; // printing context.
PMPageFormat mPageFormat; // page format.
PMPrintSettings mPrintSettings; // print settings.
#ifdef MOZ_ENABLE_SKIA_PDF
// file "print" output generated if printing via PDF
nsCOMPtr<nsIFile> mTempFile;
bool mPrintViaSkPDF = false;
nsCOMPtr<nsIFile>
mTempFile; // file "print" output is generated to if printing via PDF
bool mPrintViaSkPDF;
#endif
};

View File

@ -24,7 +24,6 @@
#include "nsCUPSShim.h"
#include "nsDirectoryServiceDefs.h"
#include "nsILocalFileMac.h"
#include "nsIOutputStream.h"
#include "nsPaper.h"
#include "nsPrinterListCUPS.h"
#include "nsPrintSettingsX.h"
@ -41,11 +40,23 @@ using mozilla::gfx::PrintTargetCG;
#ifdef MOZ_ENABLE_SKIA_PDF
using mozilla::gfx::PrintTargetSkPDF;
#endif
using mozilla::gfx::SurfaceFormat;
static LazyLogModule sDeviceContextSpecXLog("DeviceContextSpecX");
//----------------------------------------------------------------------
// nsDeviceContentSpecX
nsDeviceContextSpecX::nsDeviceContextSpecX() = default;
nsDeviceContextSpecX::nsDeviceContextSpecX()
: mPrintSession(nullptr),
mPageFormat(nullptr),
mPrintSettings(nullptr)
#ifdef MOZ_ENABLE_SKIA_PDF
,
mPrintViaSkPDF(false)
#endif
{
}
nsDeviceContextSpecX::~nsDeviceContextSpecX() {
NS_OBJC_BEGIN_TRY_IGNORE_BLOCK;
@ -74,16 +85,13 @@ NS_IMETHODIMP nsDeviceContextSpecX::Init(nsIWidget* aWidget, nsIPrintSettings* a
return NS_ERROR_NO_INTERFACE;
}
bool toFile;
settings->GetPrintToFile(&toFile);
NSPrintInfo* printInfo = settings->CreateOrCopyPrintInfo();
if (!printInfo) {
return NS_ERROR_FAILURE;
}
if (aPS->GetOutputDestination() == nsIPrintSettings::kOutputDestinationStream) {
aPS->GetOutputStream(getter_AddRefs(mOutputStream));
if (!mOutputStream) {
return NS_ERROR_FAILURE;
}
}
mPrintSession = static_cast<PMPrintSession>([printInfo PMPrintSession]);
mPageFormat = static_cast<PMPageFormat>([printInfo PMPageFormat]);
mPrintSettings = static_cast<PMPrintSettings>([printInfo PMPrintSettings]);
@ -130,7 +138,8 @@ NS_IMETHODIMP nsDeviceContextSpecX::Init(nsIWidget* aWidget, nsIPrintSettings* a
}
#endif
int16_t outputFormat = aPS->GetOutputFormat();
int16_t outputFormat;
aPS->GetOutputFormat(&outputFormat);
if (outputFormat == nsIPrintSettings::kOutputFormatPDF) {
// We don't actually currently support/use kOutputFormatPDF on mac, but
@ -278,7 +287,6 @@ already_AddRefed<PrintTarget> nsDeviceContextSpecX::MakePrintTarget() {
#ifdef MOZ_ENABLE_SKIA_PDF
if (mPrintViaSkPDF) {
// TODO: Add support for stream printing via SkPDF if we enable that again.
nsresult rv = NS_GetSpecialDirectory(NS_OS_TEMP_DIR, getter_AddRefs(mTempFile));
NS_ENSURE_SUCCESS(rv, nullptr);
nsAutoCString tempPath("tmp-printing.pdf");
@ -291,6 +299,5 @@ already_AddRefed<PrintTarget> nsDeviceContextSpecX::MakePrintTarget() {
}
#endif
return PrintTargetCG::CreateOrNull(mOutputStream, mPrintSession, mPageFormat, mPrintSettings,
size);
return PrintTargetCG::CreateOrNull(mPrintSession, mPageFormat, mPrintSettings, size);
}

View File

@ -180,9 +180,7 @@ NSPrintInfo* nsPrintSettingsX::CreateOrCopyPrintInfo(bool aWithScaling) {
}
if (mDisposition.IsEmpty()) {
// NOTE: It's unclear what to do for kOutputDestinationStream but this is
// only for the native print dialog where that can't happen.
if (mOutputDestination == kOutputDestinationFile) {
if (mPrintToFile) {
[printInfo setJobDisposition:NSPrintSaveJob];
} else {
[printInfo setJobDisposition:NSPrintSpoolJob];
@ -294,12 +292,7 @@ void nsPrintSettingsX::SetFromPrintInfo(NSPrintInfo* aPrintInfo, bool aAdoptPrin
mScaling = round(double([aPrintInfo scalingFactor]) * 100.0) / 100.0;
}
mOutputDestination = [&] {
if ([aPrintInfo jobDisposition] == NSPrintSaveJob) {
return kOutputDestinationFile;
}
return kOutputDestinationPrinter;
}();
mPrintToFile = [aPrintInfo jobDisposition] == NSPrintSaveJob;
NSDictionary* dict = [aPrintInfo dictionary];
const char* filePath = [[dict objectForKey:NSPrintJobSavingURL] fileSystemRepresentation];

View File

@ -74,46 +74,37 @@ already_AddRefed<PrintTarget> nsDeviceContextSpecGTK::MakePrintTarget() {
width /= TWIPS_PER_POINT_FLOAT;
height /= TWIPS_PER_POINT_FLOAT;
nsresult rv;
// We shouldn't be attempting to get a surface if we've already got a spool
// file.
MOZ_ASSERT(!mSpoolFile);
auto stream = [&]() -> nsCOMPtr<nsIOutputStream> {
if (mPrintSettings->GetOutputDestination() ==
nsIPrintSettings::kOutputDestinationStream) {
nsCOMPtr<nsIOutputStream> out;
mPrintSettings->GetOutputStream(getter_AddRefs(out));
return out;
}
// Spool file. Use Glib's temporary file function since we're
// already dependent on the gtk software stack.
gchar* buf;
gint fd = g_file_open_tmp("XXXXXX.tmp", &buf, nullptr);
if (-1 == fd) {
return nullptr;
}
close(fd);
if (NS_FAILED(NS_NewNativeLocalFile(nsDependentCString(buf), false,
getter_AddRefs(mSpoolFile)))) {
unlink(buf);
g_free(buf);
return nullptr;
}
mSpoolName = buf;
g_free(buf);
mSpoolFile->SetPermissions(0600);
nsCOMPtr<nsIFileOutputStream> stream =
do_CreateInstance("@mozilla.org/network/file-output-stream;1");
if (NS_FAILED(stream->Init(mSpoolFile, -1, -1, 0))) {
return nullptr;
}
return stream;
}();
// Spool file. Use Glib's temporary file function since we're
// already dependent on the gtk software stack.
gchar* buf;
gint fd = g_file_open_tmp("XXXXXX.tmp", &buf, nullptr);
if (-1 == fd) return nullptr;
close(fd);
if (!stream) {
rv = NS_NewNativeLocalFile(nsDependentCString(buf), false,
getter_AddRefs(mSpoolFile));
if (NS_FAILED(rv)) {
unlink(buf);
g_free(buf);
return nullptr;
}
mSpoolName = buf;
g_free(buf);
mSpoolFile->SetPermissions(0600);
nsCOMPtr<nsIFileOutputStream> stream =
do_CreateInstance("@mozilla.org/network/file-output-stream;1");
rv = stream->Init(mSpoolFile, -1, -1, 0);
if (NS_FAILED(rv)) return nullptr;
return PrintTargetPDF::CreateOrNull(stream, IntSize::Ceil(width, height));
}
@ -206,6 +197,12 @@ NS_IMETHODIMP nsDeviceContextSpecGTK::Init(nsIWidget* aWidget,
return NS_ERROR_NO_INTERFACE;
}
// This is only set by embedders
bool toFile;
aPS->GetPrintToFile(&toFile);
mToPrinter = !toFile && !aIsPrintPreview;
mGtkPrintSettings = mPrintSettings->GetGtkPrintSettings();
mGtkPageSetup = mPrintSettings->GetGtkPageSetup();
@ -312,65 +309,55 @@ nsDeviceContextSpecGTK::BeginDocument(const nsAString& aTitle,
}
NS_IMETHODIMP nsDeviceContextSpecGTK::EndDocument() {
switch (mPrintSettings->GetOutputDestination()) {
case nsIPrintSettings::kOutputDestinationPrinter: {
// At this point, we might have a GtkPrinter set up in nsPrintSettingsGTK,
// or we might not. In the single-process case, we probably will, as this
// is populated by the print settings dialog, or set to the default
// printer.
// In the multi-process case, we proxy the print settings dialog over to
// the parent process, and only get the name of the printer back on the
// content process side. In that case, we need to enumerate the printers
// on the content side, and find a printer with a matching name.
if (mToPrinter) {
// At this point, we might have a GtkPrinter set up in nsPrintSettingsGTK,
// or we might not. In the single-process case, we probably will, as this
// is populated by the print settings dialog, or set to the default
// printer.
// In the multi-process case, we proxy the print settings dialog over to
// the parent process, and only get the name of the printer back on the
// content process side. In that case, we need to enumerate the printers
// on the content side, and find a printer with a matching name.
if (mPrintSettings->GetGtkPrinter()) {
// We have a printer, so we can print right away.
StartPrintJob();
} else {
// We don't have a printer. We have to enumerate the printers and find
// one with a matching name.
NS_DispatchToCurrentThread(
NewRunnableMethod("nsDeviceContextSpecGTK::EnumeratePrinters", this,
&nsDeviceContextSpecGTK::EnumeratePrinters));
}
break;
if (mPrintSettings->GetGtkPrinter()) {
// We have a printer, so we can print right away.
StartPrintJob();
} else {
// We don't have a printer. We have to enumerate the printers and find
// one with a matching name.
NS_DispatchToCurrentThread(
NewRunnableMethod("nsDeviceContextSpecGTK::EnumeratePrinters", this,
&nsDeviceContextSpecGTK::EnumeratePrinters));
}
case nsIPrintSettings::kOutputDestinationFile: {
// Handle print-to-file ourselves for the benefit of embedders
nsString targetPath;
nsCOMPtr<nsIFile> destFile;
mPrintSettings->GetToFileName(targetPath);
} else {
// Handle print-to-file ourselves for the benefit of embedders
nsString targetPath;
nsCOMPtr<nsIFile> destFile;
mPrintSettings->GetToFileName(targetPath);
nsresult rv =
NS_NewLocalFile(targetPath, false, getter_AddRefs(destFile));
NS_ENSURE_SUCCESS(rv, rv);
nsresult rv = NS_NewLocalFile(targetPath, false, getter_AddRefs(destFile));
NS_ENSURE_SUCCESS(rv, rv);
nsAutoString destLeafName;
rv = destFile->GetLeafName(destLeafName);
NS_ENSURE_SUCCESS(rv, rv);
nsAutoString destLeafName;
rv = destFile->GetLeafName(destLeafName);
NS_ENSURE_SUCCESS(rv, rv);
nsCOMPtr<nsIFile> destDir;
rv = destFile->GetParent(getter_AddRefs(destDir));
NS_ENSURE_SUCCESS(rv, rv);
nsCOMPtr<nsIFile> destDir;
rv = destFile->GetParent(getter_AddRefs(destDir));
NS_ENSURE_SUCCESS(rv, rv);
rv = mSpoolFile->MoveTo(destDir, destLeafName);
NS_ENSURE_SUCCESS(rv, rv);
rv = mSpoolFile->MoveTo(destDir, destLeafName);
NS_ENSURE_SUCCESS(rv, rv);
mSpoolFile = nullptr;
mSpoolFile = nullptr;
// This is the standard way to get the UNIX umask. Ugh.
mode_t mask = umask(0);
umask(mask);
// If you're not familiar with umasks, they contain the bits of what NOT
// to set in the permissions (thats because files and directories have
// different numbers of bits for their permissions)
destFile->SetPermissions(0666 & ~(mask));
break;
}
case nsIPrintSettings::kOutputDestinationStream:
// Nothing to do, handled in MakePrintTarget.
MOZ_ASSERT(!mSpoolFile);
break;
// This is the standard way to get the UNIX umask. Ugh.
mode_t mask = umask(0);
umask(mask);
// If you're not familiar with umasks, they contain the bits of what NOT
// to set in the permissions (thats because files and directories have
// different numbers of bits for their permissions)
destFile->SetPermissions(0666 & ~(mask));
}
return NS_OK;
}

View File

@ -45,6 +45,7 @@ class nsDeviceContextSpecGTK : public nsIDeviceContextSpec {
protected:
virtual ~nsDeviceContextSpecGTK();
nsCOMPtr<nsPrintSettingsGTK> mPrintSettings;
bool mToPrinter : 1; /* If true, print to printer */
GtkPrintSettings* mGtkPrintSettings;
GtkPageSetup* mGtkPageSetup;

View File

@ -409,8 +409,7 @@ nsresult nsPrintDialogWidgetGTK::ExportSettings(nsIPrintSettings* aNSSettings) {
// printing won't occur! (We manually copy the spool file when this flag is
// set, because we love our embedders) Even if it is print-to-file in GTK's
// case, GTK does The Right Thing when we send the job.
aNSSettings->SetOutputDestination(
nsIPrintSettings::kOutputDestinationPrinter);
aNSSettings->SetPrintToFile(false);
aNSSettings->SetShrinkToFit(
gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(shrink_to_fit_toggle)));

View File

@ -612,6 +612,9 @@ nsPrintSettingsGTK::GetPageRanges(nsTArray<int32_t>& aPages) {
NS_IMETHODIMP
nsPrintSettingsGTK::GetResolution(int32_t* aResolution) {
if (!gtk_print_settings_has_key(mPrintSettings,
GTK_PRINT_SETTINGS_RESOLUTION))
return NS_ERROR_FAILURE;
*aResolution = gtk_print_settings_get_resolution(mPrintSettings);
return NS_OK;
}

View File

@ -5,6 +5,7 @@
#include "nsISupports.idl"
%{ C++
#include "nsMargin.h"
#include "nsTArray.h"
@ -21,7 +22,6 @@ native nsNativeIntMargin(nsIntMargin);
[ref] native nsNativeIntMarginRef(nsIntMargin);
interface nsIPrintSession;
interface nsIOutputStream;
/**
* Simplified graphics interface for JS rendering.
@ -78,25 +78,24 @@ interface nsIPrintSettings : nsISupports
const long kJustCenter = 1;
const long kJustRight = 2;
/** Page Size Unit Constants */
/**
* Page Size Unit Constants
*/
const short kPaperSizeInches = 0;
const short kPaperSizeMillimeters = 1;
/** Orientation Constants */
/**
* Orientation Constants
*/
const short kPortraitOrientation = 0;
const short kLandscapeOrientation = 1;
/** Output file format */
/**
* Output file format
*/
const short kOutputFormatNative = 0;
const short kOutputFormatPDF = 2;
/** Output destination */
cenum OutputDestinationType : 8 {
kOutputDestinationPrinter = 0,
kOutputDestinationFile = 1,
kOutputDestinationStream = 2,
};
/**
* Duplex printing options.
*
@ -299,19 +298,17 @@ interface nsIPrintSettings : nsISupports
*/
attribute long numPagesPerSheet;
/** Output device information */
[infallible] attribute nsIPrintSettings_OutputDestinationType outputDestination;
[infallible] attribute short outputFormat;
attribute AString printerName; /* name of destination printer */
attribute AString printerName; /* for kOutputDestinationPrinter */
attribute AString toFileName; /* for kOutputDestinationFile */
attribute nsIOutputStream outputStream; /* for kOutputDestinationPrinter */
attribute boolean printToFile;
attribute AString toFileName;
attribute short outputFormat;
[infallible] attribute long printPageDelay; /* in milliseconds */
attribute long printPageDelay; /* in milliseconds */
[infallible] attribute long resolution; /* print resolution (dpi) */
attribute long resolution; /* print resolution (dpi) */
[infallible] attribute long duplex; /* duplex mode */
attribute long duplex; /* duplex mode */
/* initialize helpers */
/**
@ -319,7 +316,7 @@ interface nsIPrintSettings : nsISupports
* from a printer specified by the "printerName" attr.
* If a different name is set into the "printerName"
* attribute than the one it was initialized with the PS
* will then get initialized from that printer.
* will then get intialized from that printer.
*/
attribute boolean isInitializedFromPrinter;
@ -327,7 +324,7 @@ interface nsIPrintSettings : nsISupports
* This attribute tracks whether the PS has been initialized
* from prefs. If a different name is set into the "printerName"
* attribute than the one it was initialized with the PS
* will then get initialized from prefs again.
* will then get intialized from prefs again.
*/
attribute boolean isInitializedFromPrefs;

View File

@ -20,7 +20,33 @@ using namespace mozilla;
NS_IMPL_ISUPPORTS(nsPrintSettings, nsIPrintSettings)
nsPrintSettings::nsPrintSettings() {
nsPrintSettings::nsPrintSettings()
: mScaling(1.0),
mPrintBGColors(false),
mPrintBGImages(false),
mIsCancelled(false),
mSaveOnCancel(true),
mPrintSilent(false),
mShrinkToFit(true),
mShowMarginGuides(false),
mHonorPageRuleMargins(true),
mIsPrintSelectionRBEnabled(false),
mPrintSelectionOnly(false),
mPrintPageDelay(50),
mPaperWidth(8.5),
mPaperHeight(11.0),
mPaperSizeUnit(kPaperSizeInches),
mPrintReversed(false),
mPrintInColor(true),
mOrientation(kPortraitOrientation),
mResolution(0),
mDuplex(0),
mNumCopies(1),
mNumPagesPerSheet(1),
mPrintToFile(false),
mOutputFormat(kOutputFormatNative),
mIsInitedFromPrinter(false),
mIsInitedFromPrefs(false) {
/* member initializers and constructor code */
int32_t marginWidth = NS_INCHES_TO_INT_TWIPS(DEFAULT_MARGIN_WIDTH);
mMargin.SizeTo(marginWidth, marginWidth, marginWidth, marginWidth);
@ -193,25 +219,13 @@ NS_IMETHODIMP nsPrintSettings::SetNumPagesPerSheet(int32_t aNumPagesPerSheet) {
return NS_OK;
}
NS_IMETHODIMP nsPrintSettings::GetOutputDestination(
OutputDestinationType* aDestination) {
*aDestination = mOutputDestination;
NS_IMETHODIMP nsPrintSettings::GetPrintToFile(bool* aPrintToFile) {
NS_ENSURE_ARG_POINTER(aPrintToFile);
*aPrintToFile = mPrintToFile;
return NS_OK;
}
NS_IMETHODIMP nsPrintSettings::SetOutputDestination(
OutputDestinationType aDestination) {
mOutputDestination = aDestination;
return NS_OK;
}
NS_IMETHODIMP nsPrintSettings::SetOutputStream(nsIOutputStream* aStream) {
mOutputStream = aStream;
return NS_OK;
}
NS_IMETHODIMP nsPrintSettings::GetOutputStream(nsIOutputStream** aStream) {
NS_IF_ADDREF(*aStream = mOutputStream.get());
NS_IMETHODIMP nsPrintSettings::SetPrintToFile(bool aPrintToFile) {
mPrintToFile = aPrintToFile;
return NS_OK;
}
@ -932,8 +946,7 @@ nsPrintSettings& nsPrintSettings::operator=(const nsPrintSettings& rhs) {
mNumCopies = rhs.mNumCopies;
mNumPagesPerSheet = rhs.mNumPagesPerSheet;
mPrinter = rhs.mPrinter;
mOutputDestination = rhs.mOutputDestination;
mOutputStream = rhs.mOutputStream;
mPrintToFile = rhs.mPrintToFile;
mToFileName = rhs.mToFileName;
mOutputFormat = rhs.mOutputFormat;
mIsInitedFromPrinter = rhs.mIsInitedFromPrinter;

View File

@ -83,6 +83,8 @@ class nsPrintSettings : public nsIPrintSettings {
virtual nsresult _Clone(nsIPrintSettings** _retval);
virtual nsresult _Assign(nsIPrintSettings* aPS);
typedef enum { eHeader, eFooter } nsHeaderFooterEnum;
// Members
nsWeakPtr mSession; // Should never be touched by Clone or Assign
@ -93,20 +95,19 @@ class nsPrintSettings : public nsIPrintSettings {
nsTArray<int32_t> mPageRanges;
double mScaling = 1.0;
bool mPrintBGColors = false;
bool mPrintBGImages = false;
double mScaling;
bool mPrintBGColors; // print background colors
bool mPrintBGImages; // print background images
bool mIsCancelled = false;
bool mSaveOnCancel = true;
bool mPrintSilent = false;
bool mShrinkToFit = true;
bool mShowMarginGuides = false;
bool mHonorPageRuleMargins = true;
bool mIsPrintSelectionRBEnabled = false;
bool mPrintSelectionOnly = false;
int32_t mPrintPageDelay = 50; // XXX Do we really want this?
bool mIsCancelled;
bool mSaveOnCancel;
bool mPrintSilent;
bool mShrinkToFit;
bool mShowMarginGuides;
bool mHonorPageRuleMargins;
bool mIsPrintSelectionRBEnabled;
bool mPrintSelectionOnly;
int32_t mPrintPageDelay;
nsString mTitle;
nsString mURL;
@ -114,24 +115,23 @@ class nsPrintSettings : public nsIPrintSettings {
nsString mFooterStrs[NUM_HEAD_FOOT];
nsString mPaperId;
double mPaperWidth = 8.5;
double mPaperHeight = 11.0;
int16_t mPaperSizeUnit = kPaperSizeInches;
double mPaperWidth;
double mPaperHeight;
int16_t mPaperSizeUnit;
bool mPrintReversed = false;
bool mPrintInColor = true;
int32_t mOrientation = kPortraitOrientation;
int32_t mResolution = 0;
int32_t mDuplex = kDuplexNone;
int32_t mNumCopies = 1;
int32_t mNumPagesPerSheet = 1;
int16_t mOutputFormat = kOutputFormatNative;
OutputDestinationType mOutputDestination = kOutputDestinationPrinter;
bool mPrintReversed;
bool mPrintInColor; // a false means grayscale
int32_t mOrientation; // see orientation consts
int32_t mResolution;
int32_t mDuplex;
int32_t mNumCopies;
int32_t mNumPagesPerSheet;
nsString mPrinter;
bool mPrintToFile;
nsString mToFileName;
nsCOMPtr<nsIOutputStream> mOutputStream;
bool mIsInitedFromPrinter = false;
bool mIsInitedFromPrefs = false;
int16_t mOutputFormat;
bool mIsInitedFromPrinter;
bool mIsInitedFromPrefs;
};
#endif /* nsPrintSettings_h__ */

View File

@ -154,15 +154,14 @@ nsPrintSettingsService::SerializeToPrintData(nsIPrintSettings* aSettings,
aSettings->GetPrinterName(data->printerName());
data->outputDestination() = aSettings->GetOutputDestination();
aSettings->GetPrintToFile(&data->printToFile());
aSettings->GetToFileName(data->toFileName());
data->outputFormat() = aSettings->GetOutputFormat();
data->printPageDelay() = aSettings->GetPrintPageDelay();
data->resolution() = aSettings->GetResolution();
data->duplex() = aSettings->GetDuplex();
aSettings->GetOutputFormat(&data->outputFormat());
aSettings->GetPrintPageDelay(&data->printPageDelay());
aSettings->GetResolution(&data->resolution());
aSettings->GetDuplex(&data->duplex());
aSettings->GetIsInitializedFromPrinter(&data->isInitializedFromPrinter());
aSettings->GetIsInitializedFromPrefs(&data->isInitializedFromPrefs());
@ -242,11 +241,11 @@ nsPrintSettingsService::DeserializeToPrintSettings(const PrintData& data,
settings->SetNumCopies(data.numCopies());
settings->SetNumPagesPerSheet(data.numPagesPerSheet());
settings->SetOutputDestination(
nsIPrintSettings::OutputDestinationType(data.outputDestination()));
settings->SetPrinterName(data.printerName());
settings->SetPrintToFile(data.printToFile());
settings->SetToFileName(data.toFileName());
// Output stream intentionally unset, child processes shouldn't care about it.
settings->SetOutputFormat(data.outputFormat());
settings->SetPrintPageDelay(data.printPageDelay());
@ -525,9 +524,7 @@ nsresult nsPrintSettingsService::ReadPrefs(nsIPrintSettings* aPS,
if (aFlags & nsIPrintSettings::kInitSavePrintToFile) {
if (GETBOOLPREF(kPrintToFile, &b)) {
aPS->SetOutputDestination(
b ? nsIPrintSettings::kOutputDestinationFile
: nsIPrintSettings::kOutputDestinationPrinter);
aPS->SetPrintToFile(b);
noValidPrefsFound = false;
}
}
@ -743,9 +740,9 @@ nsresult nsPrintSettingsService::WritePrefs(nsIPrintSettings* aPS,
}
if (aFlags & nsIPrintSettings::kInitSavePrintToFile) {
Preferences::SetBool(GetPrefName(kPrintToFile, aPrinterName),
aPS->GetOutputDestination() ==
nsIPrintSettings::kOutputDestinationFile);
if (NS_SUCCEEDED(aPS->GetPrintToFile(&b))) {
Preferences::SetBool(GetPrefName(kPrintToFile, aPrinterName), b);
}
}
if (aFlags & nsIPrintSettings::kInitSaveToFileName) {

View File

@ -111,7 +111,7 @@ NS_IMETHODIMP nsDeviceContextSpecWin::Init(nsIWidget* aWidget,
// Get the Printer Name to be used and output format.
nsAutoString printerName;
if (mPrintSettings) {
mOutputFormat = mPrintSettings->GetOutputFormat();
mPrintSettings->GetOutputFormat(&mOutputFormat);
mPrintSettings->GetPrinterName(printerName);
}
@ -272,6 +272,9 @@ already_AddRefed<PrintTarget> nsDeviceContextSpecWin::MakePrintTarget() {
#endif
if (mOutputFormat == nsIPrintSettings::kOutputFormatPDF) {
nsString filename;
mPrintSettings->GetToFileName(filename);
double width, height;
mPrintSettings->GetEffectiveSheetSize(&width, &height);
if (width <= 0 || height <= 0) {
@ -282,37 +285,26 @@ already_AddRefed<PrintTarget> nsDeviceContextSpecWin::MakePrintTarget() {
width /= TWIPS_PER_POINT_FLOAT;
height /= TWIPS_PER_POINT_FLOAT;
auto stream = [&]() -> nsCOMPtr<nsIOutputStream> {
if (mPrintSettings->GetOutputDestination() ==
nsIPrintSettings::kOutputDestinationStream) {
nsCOMPtr<nsIOutputStream> out;
mPrintSettings->GetOutputStream(getter_AddRefs(out));
return out;
}
nsAutoString filename;
mPrintSettings->GetToFileName(filename);
nsCOMPtr<nsIFile> file;
nsresult rv;
if (!filename.IsEmpty()) {
file = do_CreateInstance("@mozilla.org/file/local;1");
rv = file->InitWithPath(filename);
} else {
rv = NS_OpenAnonymousTemporaryNsIFile(getter_AddRefs(mTempFile));
file = mTempFile;
}
nsCOMPtr<nsIFile> file;
nsresult rv;
if (!filename.IsEmpty()) {
file = do_CreateInstance("@mozilla.org/file/local;1");
rv = file->InitWithPath(filename);
} else {
rv = NS_OpenAnonymousTemporaryNsIFile(getter_AddRefs(mTempFile));
file = mTempFile;
}
if (NS_WARN_IF(NS_FAILED(rv))) {
return nullptr;
}
if (NS_WARN_IF(NS_FAILED(rv))) {
return nullptr;
}
nsCOMPtr<nsIFileOutputStream> stream =
do_CreateInstance("@mozilla.org/network/file-output-stream;1");
if (NS_FAILED(stream->Init(file, -1, -1, 0))) {
return nullptr;
}
return stream;
}();
nsCOMPtr<nsIFileOutputStream> stream =
do_CreateInstance("@mozilla.org/network/file-output-stream;1");
rv = stream->Init(file, -1, -1, 0);
if (NS_FAILED(rv)) {
return nullptr;
}
return PrintTargetPDF::CreateOrNull(stream, IntSize::Ceil(width, height));
}
@ -614,7 +606,8 @@ nsPrinterListWin::InitPrintSettingsFromPrinter(
}
// When printing to PDF on Windows there is no associated printer driver.
int16_t outputFormat = aPrintSettings->GetOutputFormat();
int16_t outputFormat;
aPrintSettings->GetOutputFormat(&outputFormat);
if (outputFormat == nsIPrintSettings::kOutputFormatPDF) {
return NS_OK;
}

View File

@ -314,13 +314,11 @@ static nsresult ShowNativePrintDialog(HWND aHWnd,
if (prntdlg.Flags & PD_PRINTTOFILE) {
char16ptr_t fileName = &(((wchar_t*)devnames)[devnames->wOutputOffset]);
NS_ASSERTION(wcscmp(fileName, L"FILE:") == 0, "FileName must be `FILE:`");
aPrintSettings->SetOutputDestination(
nsIPrintSettings::kOutputDestinationFile);
aPrintSettings->SetToFileName(nsDependentString(fileName));
aPrintSettings->SetPrintToFile(true);
} else {
// clear "print to file" info
aPrintSettings->SetOutputDestination(
nsIPrintSettings::kOutputDestinationPrinter);
aPrintSettings->SetPrintToFile(false);
aPrintSettings->SetToFileName(u""_ns);
}