mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 1238964 Part 1: Hold new printable page sizes in print nsIPrintSettingsWin. r=jimm
This also holds the resolution in the print settings, so that we can start to remove the access to the native Windows print devices in the child process.
This commit is contained in:
parent
c2659321ad
commit
8fbadb6da5
@ -75,6 +75,8 @@ struct PrintData {
|
||||
/* Windows-specific things */
|
||||
nsString driverName;
|
||||
nsString deviceName;
|
||||
double printableWidthInInches;
|
||||
double printableHeightInInches;
|
||||
bool isFramesetDocument;
|
||||
bool isFramesetFrameSelected;
|
||||
bool isIFrameSelected;
|
||||
|
@ -987,13 +987,15 @@ ShowNativePrintDialog(HWND aHWnd,
|
||||
|
||||
// Transfer the settings from the native data to the PrintSettings
|
||||
LPDEVMODEW devMode = (LPDEVMODEW)::GlobalLock(prntdlg.hDevMode);
|
||||
if (devMode == nullptr) {
|
||||
if (!devMode || !prntdlg.hDC) {
|
||||
::GlobalFree(hGlobalDevMode);
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
psWin->SetDevMode(devMode); // copies DevMode
|
||||
SetPrintSettingsFromDevMode(aPrintSettings, devMode);
|
||||
::GlobalUnlock(prntdlg.hDevMode);
|
||||
psWin->CopyFromNative(prntdlg.hDC);
|
||||
::DeleteDC(prntdlg.hDC);
|
||||
|
||||
#if defined(DEBUG_rods) || defined(DEBUG_dcone)
|
||||
bool printSelection = prntdlg.Flags & PD_SELECTION;
|
||||
|
@ -680,38 +680,13 @@ nsDeviceContext::CalcPrintingSize()
|
||||
return (mWidth > 0 && mHeight > 0);
|
||||
}
|
||||
|
||||
bool inPoints = true;
|
||||
|
||||
gfxSize size(0, 0);
|
||||
switch (mPrintingSurface->GetType()) {
|
||||
#ifdef XP_WIN
|
||||
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:
|
||||
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 {
|
||||
mWidth = NSToIntRound(size.width);
|
||||
mHeight = NSToIntRound(size.height);
|
||||
}
|
||||
gfxSize size = mPrintingSurface->GetSize();
|
||||
// For printing, CSS inches and physical inches are identical
|
||||
// so it doesn't matter which we use here
|
||||
mWidth = NSToCoordRound(size.width * AppUnitsPerPhysicalInch()
|
||||
/ POINTS_PER_INCH_FLOAT);
|
||||
mHeight = NSToCoordRound(size.height * AppUnitsPerPhysicalInch()
|
||||
/ POINTS_PER_INCH_FLOAT);
|
||||
|
||||
return (mWidth > 0 && mHeight > 0);
|
||||
}
|
||||
|
@ -310,6 +310,15 @@ gfxWindowsSurface::EndPage()
|
||||
const mozilla::gfx::IntSize
|
||||
gfxWindowsSurface::GetSize() const
|
||||
{
|
||||
if (mForPrinting) {
|
||||
// On Windows we need to use the printable area of the page.
|
||||
float width = (::GetDeviceCaps(mDC, HORZRES) * POINTS_PER_INCH_FLOAT)
|
||||
/ ::GetDeviceCaps(mDC, LOGPIXELSX);
|
||||
float height = (::GetDeviceCaps(mDC, VERTRES) * POINTS_PER_INCH_FLOAT)
|
||||
/ ::GetDeviceCaps(mDC, LOGPIXELSY);
|
||||
return mozilla::gfx::IntSize(width, height);
|
||||
}
|
||||
|
||||
if (!mSurfaceValid) {
|
||||
NS_WARNING ("GetImageSurface on an invalid (null) surface; who's calling this without checking for surface errors?");
|
||||
return mozilla::gfx::IntSize(-1, -1);
|
||||
|
@ -67,15 +67,8 @@ nsDeviceContextSpecProxy::GetSurfaceForPrinter(gfxASurface** aSurface)
|
||||
MOZ_ASSERT(aSurface);
|
||||
MOZ_ASSERT(mRealDeviceContextSpec);
|
||||
|
||||
// The real device context may need to have created a real printing surface
|
||||
// even though we're not using it directly.
|
||||
nsresult rv = mRealDeviceContextSpec->GetSurfaceForPrinter(aSurface);
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return rv;
|
||||
}
|
||||
|
||||
double width, height;
|
||||
rv = mPrintSettings->GetEffectivePageSize(&width, &height);
|
||||
nsresult rv = mPrintSettings->GetEffectivePageSize(&width, &height);
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return rv;
|
||||
}
|
||||
|
@ -13,11 +13,12 @@
|
||||
* Native types
|
||||
*/
|
||||
[ptr] native nsDevMode(DEVMODEW);
|
||||
native nsHdc(HDC);
|
||||
|
||||
/**
|
||||
* Simplified PrintSettings for Windows interface
|
||||
*/
|
||||
[scriptable, uuid(f13b225d-473e-4372-b11f-b6dff9fe0c5b)]
|
||||
[scriptable, uuid(57c22cc1-311f-44c3-bb49-4d1cf411a3b5)]
|
||||
|
||||
interface nsIPrintSettingsWin : nsISupports
|
||||
{
|
||||
@ -39,4 +40,22 @@ interface nsIPrintSettingsWin : nsISupports
|
||||
|
||||
[noscript] attribute nsDevMode devMode;
|
||||
|
||||
/**
|
||||
* On Windows we use the printable width and height for the printing surface.
|
||||
* We don't want to have to create native print device contexts in the content
|
||||
* process, so we need to store these in the settings.
|
||||
* Storing in Inches is most convenient as they are retrieved from the device
|
||||
* using fields which are in pixels and pixels per inch.
|
||||
* Note these are stored in portrait format to ensure that we can take account
|
||||
* of our own changes to the orientation print setting.
|
||||
*/
|
||||
[noscript] attribute double printableWidthInInches;
|
||||
[noscript] attribute double printableHeightInInches;
|
||||
|
||||
/**
|
||||
* Copy relevant print settings from native Windows device.
|
||||
*
|
||||
* @param hdc HDC to copy from
|
||||
*/
|
||||
[notxpcom] void copyFromNative(in nsHdc hdc);
|
||||
};
|
||||
|
@ -214,6 +214,8 @@ nsPrintOptions::SerializeToPrintData(nsIPrintSettings* aSettings,
|
||||
// assertions).
|
||||
// data->driverName() default-initializes
|
||||
// data->deviceName() default-initializes
|
||||
data->printableWidthInInches() = 0;
|
||||
data->printableHeightInInches() = 0;
|
||||
data->isFramesetDocument() = false;
|
||||
data->isFramesetFrameSelected() = false;
|
||||
data->isIFrameSelected() = false;
|
||||
|
@ -49,6 +49,8 @@ PRLogModuleInfo * kWidgetPrintingLogMod = PR_NewLogModule("printing-widget");
|
||||
|
||||
using namespace mozilla;
|
||||
|
||||
static const wchar_t kDriverName[] = L"WINSPOOL";
|
||||
|
||||
//----------------------------------------------------------------------------------
|
||||
// The printer data is shared between the PrinterEnumerator and the nsDeviceContextSpecWin
|
||||
// The PrinterEnumerator creates the printer info
|
||||
@ -81,6 +83,13 @@ protected:
|
||||
GlobalPrinters GlobalPrinters::mGlobalPrinters;
|
||||
nsTArray<LPWSTR>* GlobalPrinters::mPrinters = nullptr;
|
||||
|
||||
struct AutoFreeGlobalPrinters
|
||||
{
|
||||
~AutoFreeGlobalPrinters() {
|
||||
GlobalPrinters::GetInstance()->FreeGlobalPrinters();
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
//******************************************************
|
||||
// Define native paper sizes
|
||||
@ -321,7 +330,6 @@ NS_IMETHODIMP nsDeviceContextSpecWin::GetSurfaceForPrinter(gfxASurface **surface
|
||||
}
|
||||
}
|
||||
|
||||
mPrintingSurface = newSurface;
|
||||
newSurface.forget(surface);
|
||||
return NS_OK;
|
||||
}
|
||||
@ -329,11 +337,11 @@ NS_IMETHODIMP nsDeviceContextSpecWin::GetSurfaceForPrinter(gfxASurface **surface
|
||||
float
|
||||
nsDeviceContextSpecWin::GetPrintingScale()
|
||||
{
|
||||
MOZ_ASSERT(mPrintingSurface);
|
||||
MOZ_ASSERT(mPrintSettings);
|
||||
|
||||
HDC dc = reinterpret_cast<gfxWindowsSurface*>(mPrintingSurface.get())->GetDC();
|
||||
int32_t OSVal = GetDeviceCaps(dc, LOGPIXELSY);
|
||||
return float(OSVal) / GetDPI();
|
||||
int32_t resolution;
|
||||
mPrintSettings->GetResolution(&resolution);
|
||||
return float(resolution) / GetDPI();
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------------
|
||||
@ -512,7 +520,7 @@ nsDeviceContextSpecWin::GetDataFromPrinter(char16ptr_t aName, nsIPrintSettings*
|
||||
|
||||
SetDeviceName(aName);
|
||||
|
||||
SetDriverName(L"WINSPOOL");
|
||||
SetDriverName(kDriverName);
|
||||
|
||||
::ClosePrinter(hPrinter);
|
||||
rv = NS_OK;
|
||||
@ -657,18 +665,30 @@ nsPrinterEnumeratorWin::InitPrintSettingsFromPrinter(const char16_t *aPrinterNam
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
AutoFreeGlobalPrinters autoFreeGlobalPrinters;
|
||||
|
||||
devSpecWin->GetDataFromPrinter(aPrinterName);
|
||||
|
||||
LPDEVMODEW devmode;
|
||||
devSpecWin->GetDevMode(devmode);
|
||||
NS_ASSERTION(devmode, "DevMode can't be NULL here");
|
||||
if (devmode) {
|
||||
aPrintSettings->SetPrinterName(aPrinterName);
|
||||
nsDeviceContextSpecWin::SetPrintSettingsFromDevMode(aPrintSettings, devmode);
|
||||
if (NS_WARN_IF(!devmode)) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
// Free them, we won't need them for a while
|
||||
GlobalPrinters::GetInstance()->FreeGlobalPrinters();
|
||||
aPrintSettings->SetPrinterName(aPrinterName);
|
||||
nsDeviceContextSpecWin::SetPrintSettingsFromDevMode(aPrintSettings, devmode);
|
||||
|
||||
// We need to get information from the device as well.
|
||||
HDC dc = ::CreateICW(kDriverName, aPrinterName, nullptr, devmode);
|
||||
if (NS_WARN_IF(!dc)) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIPrintSettingsWin> psWin = do_QueryInterface(aPrintSettings);
|
||||
MOZ_ASSERT(psWin);
|
||||
psWin->CopyFromNative(dc);
|
||||
::DeleteDC(dc);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
@ -69,7 +69,6 @@ protected:
|
||||
LPDEVMODEW mDevMode;
|
||||
|
||||
nsCOMPtr<nsIPrintSettings> mPrintSettings;
|
||||
RefPtr<gfxASurface> mPrintingSurface;
|
||||
};
|
||||
|
||||
|
||||
|
@ -67,10 +67,12 @@ nsPrintOptionsWin::SerializeToPrintData(nsIPrintSettings* aSettings,
|
||||
free(deviceName);
|
||||
free(driverName);
|
||||
|
||||
// When creating the print dialog on Windows, the parent creates a DEVMODE
|
||||
// which is used to convey print settings to the Windows printing backend.
|
||||
// We don't, therefore, want or care about DEVMODEs sent up from the child.
|
||||
// When creating the print dialog on Windows, we only need to send certain
|
||||
// print settings information from the parent to the child not vice versa.
|
||||
if (XRE_IsParentProcess()) {
|
||||
psWin->GetPrintableWidthInInches(&data->printableWidthInInches());
|
||||
psWin->GetPrintableHeightInInches(&data->printableHeightInInches());
|
||||
|
||||
// A DEVMODE can actually be of arbitrary size. If it turns out that it'll
|
||||
// make our IPC message larger than the limit, then we'll error out.
|
||||
LPDEVMODEW devModeRaw;
|
||||
@ -118,6 +120,9 @@ nsPrintOptionsWin::DeserializeToPrintSettings(const PrintData& data,
|
||||
psWin->SetDeviceName(data.deviceName().get());
|
||||
psWin->SetDriverName(data.driverName().get());
|
||||
|
||||
psWin->SetPrintableWidthInInches(data.printableWidthInInches());
|
||||
psWin->SetPrintableHeightInInches(data.printableHeightInInches());
|
||||
|
||||
nsXPIDLString printerName;
|
||||
settings->GetPrinterName(getter_Copies(printerName));
|
||||
|
||||
|
@ -111,6 +111,82 @@ NS_IMETHODIMP nsPrintSettingsWin::SetDevMode(DEVMODEW * aDevMode)
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsPrintSettingsWin::GetPrintableWidthInInches(double* aPrintableWidthInInches)
|
||||
{
|
||||
MOZ_ASSERT(aPrintableWidthInInches);
|
||||
*aPrintableWidthInInches = mPrintableWidthInInches;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsPrintSettingsWin::SetPrintableWidthInInches(double aPrintableWidthInInches)
|
||||
{
|
||||
mPrintableWidthInInches = aPrintableWidthInInches;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsPrintSettingsWin::GetPrintableHeightInInches(double* aPrintableHeightInInches)
|
||||
{
|
||||
MOZ_ASSERT(aPrintableHeightInInches);
|
||||
*aPrintableHeightInInches = mPrintableHeightInInches;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsPrintSettingsWin::SetPrintableHeightInInches(double aPrintableHeightInInches)
|
||||
{
|
||||
mPrintableHeightInInches = aPrintableHeightInInches;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsPrintSettingsWin::GetEffectivePageSize(double *aWidth, double *aHeight)
|
||||
{
|
||||
// If printable page size not set, fall back to nsPrintSettings.
|
||||
if (mPrintableWidthInInches == 0l || mPrintableHeightInInches == 0l) {
|
||||
return nsPrintSettings::GetEffectivePageSize(aWidth, aHeight);
|
||||
}
|
||||
|
||||
if (mOrientation == kPortraitOrientation) {
|
||||
*aWidth = NS_INCHES_TO_TWIPS(mPrintableWidthInInches);
|
||||
*aHeight = NS_INCHES_TO_TWIPS(mPrintableHeightInInches);
|
||||
} else {
|
||||
*aHeight = NS_INCHES_TO_TWIPS(mPrintableWidthInInches);
|
||||
*aWidth = NS_INCHES_TO_TWIPS(mPrintableHeightInInches);
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
void
|
||||
nsPrintSettingsWin::CopyFromNative(HDC aHdc)
|
||||
{
|
||||
MOZ_ASSERT(aHdc);
|
||||
|
||||
// On Windows we currently create a surface using the printable area of the
|
||||
// page and don't set the unwriteable [sic] margins. Using the unwriteable
|
||||
// margins doesn't appear to work on Windows, but I am not sure if this is a
|
||||
// bug elsewhere in our code or a Windows quirk.
|
||||
int32_t printableWidthInDots = GetDeviceCaps(aHdc, HORZRES);
|
||||
int32_t printableHeightInDots = GetDeviceCaps(aHdc, VERTRES);
|
||||
int32_t widthDPI = GetDeviceCaps(aHdc, LOGPIXELSX);
|
||||
int32_t heightDPI = GetDeviceCaps(aHdc, LOGPIXELSY);
|
||||
|
||||
// Keep these values in portrait format, so we can reflect our own changes
|
||||
// to mOrientation.
|
||||
if (mOrientation == kPortraitOrientation) {
|
||||
mPrintableWidthInInches = double(printableWidthInDots) / widthDPI;
|
||||
mPrintableHeightInInches = double(printableHeightInDots) / heightDPI;
|
||||
} else {
|
||||
mPrintableHeightInInches = double(printableWidthInDots) / widthDPI;
|
||||
mPrintableWidthInInches = double(printableHeightInDots) / heightDPI;
|
||||
}
|
||||
|
||||
// Using Y to match existing code, X DPI should be the same for printing.
|
||||
mResolution = heightDPI;
|
||||
}
|
||||
|
||||
//-------------------------------------------
|
||||
nsresult
|
||||
nsPrintSettingsWin::_Clone(nsIPrintSettings **_retval)
|
||||
|
@ -42,12 +42,16 @@ public:
|
||||
*/
|
||||
nsPrintSettingsWin& operator=(const nsPrintSettingsWin& rhs);
|
||||
|
||||
NS_IMETHOD GetEffectivePageSize(double *aWidth, double *aHeight) override;
|
||||
|
||||
protected:
|
||||
void CopyDevMode(DEVMODEW* aInDevMode, DEVMODEW *& aOutDevMode);
|
||||
|
||||
wchar_t* mDeviceName;
|
||||
wchar_t* mDriverName;
|
||||
LPDEVMODEW mDevMode;
|
||||
double mPrintableWidthInInches = 0l;
|
||||
double mPrintableHeightInInches = 0l;
|
||||
};
|
||||
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user