зеркало из https://github.com/mozilla/gecko-dev.git
Bug 221706 - Use unwritable region when printing on Windows. r=jimm
Read more information from the printing device to setup the unwritable region. Translate the printing context's coordinate system so that the point (0,0) refers to the top-left of the physical paper instead of the top-left of the printable region. MozReview-Commit-ID: 9ei2FgEUDyO --HG-- extra : rebase_source : c2e2715f47499538035101a285152eca2aba3202
This commit is contained in:
Родитель
6499399d3c
Коммит
0cc1c8ec9b
|
@ -204,6 +204,7 @@ nsDeviceContext::nsDeviceContext()
|
|||
mAppUnitsPerDevPixel(-1), mAppUnitsPerDevPixelAtUnitFullZoom(-1),
|
||||
mAppUnitsPerPhysicalInch(-1),
|
||||
mFullZoom(1.0f), mPrintingScale(1.0f),
|
||||
mPrintingTranslate(gfxPoint(0, 0)),
|
||||
mIsCurrentlyPrintingDoc(false)
|
||||
#ifdef DEBUG
|
||||
, mIsInitialized(false)
|
||||
|
@ -276,6 +277,7 @@ nsDeviceContext::SetDPI(double* aScale)
|
|||
if (mDeviceContextSpec) {
|
||||
dpi = mDeviceContextSpec->GetDPI();
|
||||
mPrintingScale = mDeviceContextSpec->GetPrintingScale();
|
||||
mPrintingTranslate = mDeviceContextSpec->GetPrintingTranslate();
|
||||
mAppUnitsPerDevPixelAtUnitFullZoom =
|
||||
NS_lround((AppUnitsPerCSSPixel() * 96) / dpi);
|
||||
} else {
|
||||
|
@ -414,6 +416,7 @@ nsDeviceContext::CreateRenderingContextCommon(bool aWantReferenceContext)
|
|||
MOZ_ASSERT(pContext); // already checked draw target above
|
||||
|
||||
gfxMatrix transform;
|
||||
transform.PreTranslate(mPrintingTranslate);
|
||||
if (mPrintTarget->RotateNeededForLandscape()) {
|
||||
// Rotate page 90 degrees to draw landscape page on portrait paper
|
||||
IntSize size = mPrintTarget->GetSize();
|
||||
|
|
|
@ -305,6 +305,7 @@ private:
|
|||
int32_t mAppUnitsPerPhysicalInch;
|
||||
float mFullZoom;
|
||||
float mPrintingScale;
|
||||
gfxPoint mPrintingTranslate;
|
||||
|
||||
RefPtr<nsFontCache> mFontCache;
|
||||
nsCOMPtr<nsIWidget> mWidget;
|
||||
|
|
|
@ -26,14 +26,16 @@ PrintTargetWindows::PrintTargetWindows(cairo_surface_t* aCairoSurface,
|
|||
/* static */ already_AddRefed<PrintTargetWindows>
|
||||
PrintTargetWindows::CreateOrNull(HDC aDC)
|
||||
{
|
||||
// Figure out the cairo surface size - Windows we need to use the printable
|
||||
// area of the page. Note: we only scale the printing using the LOGPIXELSY,
|
||||
// Figure out the paper size, the actual surface size will be the printable
|
||||
// area which is likely smaller, but the size here is later used to create the
|
||||
// draw target where the full page size is needed.
|
||||
// Note: we only scale the printing using the LOGPIXELSY,
|
||||
// so we use that when calculating the surface width as well as the height.
|
||||
int32_t heightDPI = ::GetDeviceCaps(aDC, LOGPIXELSY);
|
||||
float width =
|
||||
(::GetDeviceCaps(aDC, HORZRES) * POINTS_PER_INCH_FLOAT) / heightDPI;
|
||||
(::GetDeviceCaps(aDC, PHYSICALWIDTH) * POINTS_PER_INCH_FLOAT) / heightDPI;
|
||||
float height =
|
||||
(::GetDeviceCaps(aDC, VERTRES) * POINTS_PER_INCH_FLOAT) / heightDPI;
|
||||
(::GetDeviceCaps(aDC, PHYSICALHEIGHT) * POINTS_PER_INCH_FLOAT) / heightDPI;
|
||||
IntSize size = IntSize::Truncate(width, height);
|
||||
|
||||
if (!Factory::CheckSurfaceSize(size)) {
|
||||
|
|
|
@ -133,6 +133,14 @@ nsDeviceContextSpecProxy::GetPrintingScale()
|
|||
return mRealDeviceContextSpec->GetPrintingScale();
|
||||
}
|
||||
|
||||
gfxPoint
|
||||
nsDeviceContextSpecProxy::GetPrintingTranslate()
|
||||
{
|
||||
MOZ_ASSERT(mRealDeviceContextSpec);
|
||||
|
||||
return mRealDeviceContextSpec->GetPrintingTranslate();
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsDeviceContextSpecProxy::BeginDocument(const nsAString& aTitle,
|
||||
const nsAString& aPrintToFileName,
|
||||
|
|
|
@ -38,6 +38,8 @@ public:
|
|||
|
||||
float GetPrintingScale() final;
|
||||
|
||||
gfxPoint GetPrintingTranslate() final;
|
||||
|
||||
|
||||
NS_IMETHOD BeginDocument(const nsAString& aTitle,
|
||||
const nsAString& aPrintToFileName,
|
||||
|
|
|
@ -69,6 +69,13 @@ public:
|
|||
*/
|
||||
virtual float GetPrintingScale() { return 1.0f; }
|
||||
|
||||
/**
|
||||
* Override to return something other than the default.
|
||||
*
|
||||
* @return the point to translate the context to for printing.
|
||||
*/
|
||||
virtual gfxPoint GetPrintingTranslate() { return gfxPoint(0, 0); }
|
||||
|
||||
NS_IMETHOD BeginDocument(const nsAString& aTitle,
|
||||
const nsAString& aPrintToFileName,
|
||||
int32_t aStartPage,
|
||||
|
|
|
@ -321,6 +321,22 @@ nsDeviceContextSpecWin::GetPrintingScale()
|
|||
return float(resolution) / GetDPI();
|
||||
}
|
||||
|
||||
gfxPoint
|
||||
nsDeviceContextSpecWin::GetPrintingTranslate()
|
||||
{
|
||||
// The underlying surface on windows is the size of the printable region. When
|
||||
// the region is smaller than the actual paper size the (0, 0) coordinate
|
||||
// refers top-left of that unwritable region. To instead have (0, 0) become
|
||||
// the top-left of the actual paper, translate it's coordinate system by the
|
||||
// unprintable region's width.
|
||||
double marginTop, marginLeft;
|
||||
mPrintSettings->GetUnwriteableMarginTop(&marginTop);
|
||||
mPrintSettings->GetUnwriteableMarginLeft(&marginLeft);
|
||||
int32_t resolution;
|
||||
mPrintSettings->GetResolution(&resolution);
|
||||
return gfxPoint(-marginLeft * resolution, -marginTop * resolution);
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------------
|
||||
void nsDeviceContextSpecWin::SetDeviceName(const nsAString& aDeviceName)
|
||||
{
|
||||
|
|
|
@ -38,6 +38,7 @@ public:
|
|||
float GetDPI() final;
|
||||
|
||||
float GetPrintingScale() final;
|
||||
gfxPoint GetPrintingTranslate() final;
|
||||
|
||||
void GetDriverName(nsAString& aDriverName) const { aDriverName = mDriverName; }
|
||||
void GetDeviceName(nsAString& aDeviceName) const { aDeviceName = mDeviceName; }
|
||||
|
|
|
@ -275,6 +275,41 @@ nsPrintSettingsWin::GetEffectivePageSize(double *aWidth, double *aHeight)
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
void
|
||||
nsPrintSettingsWin::InitUnwriteableMargin(HDC aHdc)
|
||||
{
|
||||
int32_t pixelsPerInchY = GetDeviceCaps(aHdc, LOGPIXELSY);
|
||||
int32_t pixelsPerInchX = GetDeviceCaps(aHdc, LOGPIXELSX);
|
||||
|
||||
int32_t marginLeft = GetDeviceCaps(aHdc, PHYSICALOFFSETX);
|
||||
int32_t marginTop = GetDeviceCaps(aHdc, PHYSICALOFFSETY);
|
||||
|
||||
double marginLeftInch = double(marginLeft) / pixelsPerInchX;
|
||||
double marginTopInch = double(marginTop) / pixelsPerInchY;
|
||||
|
||||
int32_t printableAreaWidth = GetDeviceCaps(aHdc, HORZRES);
|
||||
int32_t printableAreaHeight = GetDeviceCaps(aHdc, VERTRES);
|
||||
|
||||
double printableAreaWidthInch = double(printableAreaWidth) / pixelsPerInchX;
|
||||
double printableAreaHeightInch = double(printableAreaHeight) / pixelsPerInchY;
|
||||
|
||||
int32_t physicalWidth = GetDeviceCaps(aHdc, PHYSICALWIDTH);
|
||||
int32_t physicalHeight = GetDeviceCaps(aHdc, PHYSICALHEIGHT);
|
||||
|
||||
double physicalWidthInch = double(physicalWidth) / pixelsPerInchX;
|
||||
double physicalHeightInch = double(physicalHeight) / pixelsPerInchY;
|
||||
|
||||
double marginBottomInch = physicalHeightInch - printableAreaHeightInch - marginTopInch;
|
||||
double marginRightInch = physicalWidthInch - printableAreaWidthInch - marginLeftInch;
|
||||
|
||||
mUnwriteableMargin.SizeTo(
|
||||
NS_INCHES_TO_INT_TWIPS(marginTopInch),
|
||||
NS_INCHES_TO_INT_TWIPS(marginRightInch),
|
||||
NS_INCHES_TO_INT_TWIPS(marginBottomInch),
|
||||
NS_INCHES_TO_INT_TWIPS(marginLeftInch)
|
||||
);
|
||||
}
|
||||
|
||||
void
|
||||
nsPrintSettingsWin::CopyFromNative(HDC aHdc, DEVMODEW* aDevMode)
|
||||
{
|
||||
|
@ -311,6 +346,8 @@ nsPrintSettingsWin::CopyFromNative(HDC aHdc, DEVMODEW* aDevMode)
|
|||
mPaperData = -1;
|
||||
}
|
||||
|
||||
InitUnwriteableMargin(aHdc);
|
||||
|
||||
// The length and width in DEVMODE are always in tenths of a millimeter.
|
||||
double sizeUnitToTenthsOfAmm =
|
||||
10L * (mPaperSizeUnit == kPaperSizeInches ? MM_PER_INCH_FLOAT : 1L);
|
||||
|
@ -326,14 +363,10 @@ nsPrintSettingsWin::CopyFromNative(HDC aHdc, DEVMODEW* aDevMode)
|
|||
mPaperWidth = -1l;
|
||||
}
|
||||
|
||||
// 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.
|
||||
// Note: we only scale the printing using the LOGPIXELSY, so we use that
|
||||
// when calculating the surface width as well as the height.
|
||||
int32_t printableWidthInDots = GetDeviceCaps(aHdc, HORZRES);
|
||||
int32_t printableHeightInDots = GetDeviceCaps(aHdc, VERTRES);
|
||||
int32_t printableWidthInDots = GetDeviceCaps(aHdc, PHYSICALWIDTH);
|
||||
int32_t printableHeightInDots = GetDeviceCaps(aHdc, PHYSICALHEIGHT);
|
||||
int32_t heightDPI = GetDeviceCaps(aHdc, LOGPIXELSY);
|
||||
|
||||
// Keep these values in portrait format, so we can reflect our own changes
|
||||
|
|
|
@ -46,6 +46,7 @@ public:
|
|||
|
||||
protected:
|
||||
void CopyDevMode(DEVMODEW* aInDevMode, DEVMODEW *& aOutDevMode);
|
||||
void InitUnwriteableMargin(HDC aHdc);
|
||||
|
||||
nsString mDeviceName;
|
||||
nsString mDriverName;
|
||||
|
|
Загрузка…
Ссылка в новой задаче