mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-10 20:05:49 +00:00
b=377336, win32 printing page results in excessive data spooled to printer, for real this time, r=stuart
This commit is contained in:
parent
81a069aa59
commit
847a977dc2
@ -238,8 +238,8 @@ static cairo_int_status_t
|
||||
_paint_fallback_image (cairo_paginated_surface_t *surface,
|
||||
cairo_box_int_t *box)
|
||||
{
|
||||
double x_scale = surface->base.x_fallback_resolution / surface->base.x_resolution;
|
||||
double y_scale = surface->base.y_fallback_resolution / surface->base.y_resolution;
|
||||
double x_scale = surface->base.x_fallback_resolution / surface->target->x_resolution;
|
||||
double y_scale = surface->base.y_fallback_resolution / surface->target->y_resolution;
|
||||
cairo_matrix_t matrix;
|
||||
int x, y, width, height;
|
||||
cairo_status_t status;
|
||||
|
@ -267,6 +267,12 @@ _cairo_win32_printing_surface_paint_surface_pattern (cairo_win32_surface_t *su
|
||||
int x_tile, y_tile, left, right, top, bottom;
|
||||
RECT clip;
|
||||
|
||||
/* If we can't use StretchDIBits with this surface, we can't do anything
|
||||
* special here.
|
||||
*/
|
||||
if (!(surface->flags & CAIRO_WIN32_SURFACE_CAN_STRETCHDIB))
|
||||
return CAIRO_INT_STATUS_UNSUPPORTED;
|
||||
|
||||
extend = cairo_pattern_get_extend (&pattern->base);
|
||||
status = _cairo_pattern_acquire_surface ((cairo_pattern_t *)pattern,
|
||||
(cairo_surface_t *)surface,
|
||||
@ -284,6 +290,12 @@ _cairo_win32_printing_surface_paint_surface_pattern (cairo_win32_surface_t *su
|
||||
goto FINISH2;
|
||||
}
|
||||
|
||||
if (image->width == 0 || image->height == 0)
|
||||
{
|
||||
status = CAIRO_STATUS_SUCCESS;
|
||||
goto FINISH2;
|
||||
}
|
||||
|
||||
if (image->format != CAIRO_FORMAT_RGB24) {
|
||||
opaque_surface = cairo_image_surface_create (CAIRO_FORMAT_RGB24,
|
||||
image->width,
|
||||
@ -378,7 +390,7 @@ _cairo_win32_printing_surface_paint_surface_pattern (cairo_win32_surface_t *su
|
||||
&bi,
|
||||
DIB_RGB_COLORS,
|
||||
SRCCOPY))
|
||||
return _cairo_win32_print_gdi_error ("_cairo_win32_printing_surface_paint(StretchDIBits)");
|
||||
return _cairo_win32_print_gdi_error ("_cairo_win32_printing_surface_paint_surface_pattern(StretchDIBits)");
|
||||
}
|
||||
}
|
||||
SetStretchBltMode(surface->dc, oldmode);
|
||||
|
@ -69,7 +69,6 @@
|
||||
#include "gfxPSSurface.h"
|
||||
static nsSystemFontsGTK2 *gSystemFonts = nsnull;
|
||||
#elif XP_WIN
|
||||
#include <cairo-win32.h>
|
||||
#include "nsSystemFontsWin.h"
|
||||
#include "gfxWindowsSurface.h"
|
||||
#include "gfxPDFSurface.h"
|
||||
@ -193,7 +192,7 @@ nsThebesDeviceContext::SetDPI()
|
||||
|
||||
#elif defined(XP_OS2)
|
||||
// get a printer DC if available, otherwise create a new (memory) DC
|
||||
HDC dc = GetPrintDC();
|
||||
HDC dc = GetPrintHDC();
|
||||
PRBool doCloseDC = PR_FALSE;
|
||||
if (dc <= 0) { // test for NULLHANDLE/DEV_ERROR or HDC_ERROR
|
||||
// create DC compatible with the screen
|
||||
@ -333,9 +332,6 @@ nsThebesDeviceContext::CreateRenderingContext(nsIRenderingContext *&aContext)
|
||||
}
|
||||
|
||||
return rv;
|
||||
|
||||
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
@ -700,6 +696,7 @@ nsThebesDeviceContext::CalcPrintingSize()
|
||||
|
||||
#ifdef XP_WIN
|
||||
case gfxASurface::SurfaceTypeWin32:
|
||||
case gfxASurface::SurfaceTypeWin32Printing:
|
||||
{
|
||||
inPoints = PR_FALSE;
|
||||
HDC dc = GetPrintHDC();
|
||||
@ -756,3 +753,30 @@ nsThebesDeviceContext::UpdateScaledAppUnits()
|
||||
{
|
||||
mAppUnitsPerDevPixel = PR_MAX(1, PRInt32(float(mAppUnitsPerDevNotScaledPixel) / mPixelScale));
|
||||
}
|
||||
|
||||
#if defined(XP_WIN) || defined(XP_OS2)
|
||||
HDC
|
||||
nsThebesDeviceContext::GetPrintHDC()
|
||||
{
|
||||
if (mPrintingSurface) {
|
||||
switch (mPrintingSurface->GetType()) {
|
||||
#ifdef XP_WIN
|
||||
case gfxASurface::SurfaceTypeWin32:
|
||||
case gfxASurface::SurfaceTypeWin32Printing:
|
||||
return reinterpret_cast<gfxWindowsSurface*>(mPrintingSurface.get())->GetDC();
|
||||
#endif
|
||||
|
||||
#ifdef XP_OS2
|
||||
case gfxASurface::SurfaceTypeOS2:
|
||||
return GpiQueryDevice(reinterpret_cast<gfxOS2Surface*>(mPrintingSurface.get())->GetPS());
|
||||
#endif
|
||||
|
||||
default:
|
||||
NS_ASSERTION(0, "invalid surface type in GetPrintHDC");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return nsnull;
|
||||
}
|
||||
#endif
|
||||
|
@ -119,23 +119,8 @@ public:
|
||||
virtual PRBool SetPixelScale(float aScale);
|
||||
|
||||
nsNativeWidget GetWidget() { return mWidget; }
|
||||
#ifdef XP_WIN
|
||||
HDC GetPrintHDC() {
|
||||
if (mPrintingSurface) {
|
||||
NS_ASSERTION(mPrintingSurface->GetType() == gfxASurface::SurfaceTypeWin32, "invalid surface type");
|
||||
return reinterpret_cast<gfxWindowsSurface*>(mPrintingSurface.get())->GetDC();
|
||||
}
|
||||
return nsnull;
|
||||
}
|
||||
#elif defined(XP_OS2)
|
||||
// get the PS from the current surface and from that query the DC
|
||||
HDC GetPrintDC() {
|
||||
if (mPrintingSurface) {
|
||||
NS_ASSERTION(mPrintingSurface->GetType() == gfxASurface::SurfaceTypeOS2, "invalid surface type");
|
||||
return GpiQueryDevice(reinterpret_cast<gfxOS2Surface*>(mPrintingSurface.get())->GetPS());
|
||||
}
|
||||
return nsnull;
|
||||
}
|
||||
#if defined(XP_WIN) || defined(XP_OS2)
|
||||
HDC GetPrintHDC();
|
||||
#endif
|
||||
|
||||
protected:
|
||||
|
@ -80,7 +80,8 @@ public:
|
||||
SurfaceTypeBeOS,
|
||||
SurfaceTypeDirectFB,
|
||||
SurfaceTypeSVG,
|
||||
SurfaceTypeOS2
|
||||
SurfaceTypeOS2,
|
||||
SurfaceTypeWin32Printing
|
||||
} gfxSurfaceType;
|
||||
|
||||
typedef enum {
|
||||
|
@ -45,8 +45,13 @@
|
||||
|
||||
class THEBES_API gfxWindowsSurface : public gfxASurface {
|
||||
public:
|
||||
enum {
|
||||
FLAG_TAKE_DC = (1 << 0),
|
||||
FLAG_FOR_PRINTING = (1 << 1)
|
||||
};
|
||||
|
||||
gfxWindowsSurface(HWND wnd);
|
||||
gfxWindowsSurface(HDC dc, PRBool deleteDC = PR_FALSE);
|
||||
gfxWindowsSurface(HDC dc, PRUint32 flags = 0);
|
||||
|
||||
// Create a DIB surface
|
||||
gfxWindowsSurface(const gfxIntSize& size,
|
||||
@ -76,7 +81,9 @@ public:
|
||||
nsresult EndPage();
|
||||
|
||||
private:
|
||||
PRBool mOwnsDC;
|
||||
PRPackedBool mOwnsDC;
|
||||
PRPackedBool mForPrinting;
|
||||
|
||||
HDC mDC;
|
||||
HWND mWnd;
|
||||
};
|
||||
|
@ -147,7 +147,8 @@ gfxASurface::Wrap (cairo_surface_t *csurf)
|
||||
result = new gfxImageSurface(csurf);
|
||||
}
|
||||
#ifdef CAIRO_HAS_WIN32_SURFACE
|
||||
else if (stype == CAIRO_SURFACE_TYPE_WIN32) {
|
||||
else if (stype == CAIRO_SURFACE_TYPE_WIN32 ||
|
||||
stype == CAIRO_SURFACE_TYPE_WIN32_PRINTING) {
|
||||
result = new gfxWindowsSurface(csurf);
|
||||
}
|
||||
#endif
|
||||
|
@ -91,9 +91,7 @@ gfxPDFSurface::BeginPage()
|
||||
nsresult
|
||||
gfxPDFSurface::EndPage()
|
||||
{
|
||||
cairo_t *cx = cairo_create(CairoSurface());
|
||||
cairo_show_page(cx);
|
||||
cairo_destroy(cx);
|
||||
cairo_surface_show_page(CairoSurface());
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
@ -91,9 +91,7 @@ gfxPSSurface::BeginPage()
|
||||
nsresult
|
||||
gfxPSSurface::EndPage()
|
||||
{
|
||||
cairo_t *cx = cairo_create(CairoSurface());
|
||||
cairo_show_page(cx);
|
||||
cairo_destroy(cx);
|
||||
cairo_surface_show_page(CairoSurface());
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
@ -81,7 +81,10 @@ struct DCFromContext {
|
||||
dc = NULL;
|
||||
nsRefPtr<gfxASurface> aSurface = aContext->CurrentSurface();
|
||||
NS_ASSERTION(aSurface, "DCFromContext: null surface");
|
||||
if (aSurface && aSurface->GetType() == gfxASurface::SurfaceTypeWin32) {
|
||||
if (aSurface &&
|
||||
(aSurface->GetType() == gfxASurface::SurfaceTypeWin32 ||
|
||||
aSurface->GetType() == gfxASurface::SurfaceTypeWin32Printing))
|
||||
{
|
||||
dc = static_cast<gfxWindowsSurface*>(aSurface.get())->GetDC();
|
||||
needsRelease = PR_FALSE;
|
||||
}
|
||||
|
@ -83,7 +83,8 @@ gfxWindowsNativeDrawing::BeginNativeDrawing()
|
||||
// if this is a native win32 surface, we don't have to
|
||||
// redirect rendering to our own HDC; in some cases,
|
||||
// we may be able to use the HDC from the surface directly.
|
||||
if (surf->GetType() == gfxASurface::SurfaceTypeWin32 &&
|
||||
if ((surf->GetType() == gfxASurface::SurfaceTypeWin32 ||
|
||||
surf->GetType() == gfxASurface::SurfaceTypeWin32Printing) &&
|
||||
(surf->GetContentType() == gfxASurface::CONTENT_COLOR ||
|
||||
(surf->GetContentType() == gfxASurface::CONTENT_COLOR_ALPHA &&
|
||||
(mNativeDrawFlags & CAN_DRAW_TO_COLOR_ALPHA))))
|
||||
|
@ -45,20 +45,28 @@
|
||||
#include "nsString.h"
|
||||
|
||||
gfxWindowsSurface::gfxWindowsSurface(HWND wnd) :
|
||||
mOwnsDC(PR_TRUE), mWnd(wnd)
|
||||
mOwnsDC(PR_TRUE), mForPrinting(PR_FALSE), mWnd(wnd)
|
||||
{
|
||||
mDC = ::GetDC(mWnd);
|
||||
Init(cairo_win32_surface_create(mDC));
|
||||
}
|
||||
|
||||
gfxWindowsSurface::gfxWindowsSurface(HDC dc, PRBool deleteDC) :
|
||||
mOwnsDC(deleteDC), mDC(dc),mWnd(nsnull)
|
||||
gfxWindowsSurface::gfxWindowsSurface(HDC dc, PRUint32 flags) :
|
||||
mOwnsDC(PR_FALSE), mForPrinting(PR_FALSE), mDC(dc), mWnd(nsnull)
|
||||
{
|
||||
Init(cairo_win32_surface_create(mDC));
|
||||
if (flags & FLAG_TAKE_DC)
|
||||
mOwnsDC = PR_TRUE;
|
||||
|
||||
if (flags & FLAG_FOR_PRINTING) {
|
||||
Init(cairo_win32_printing_surface_create(mDC, TRUE));
|
||||
mForPrinting = PR_TRUE;
|
||||
} else {
|
||||
Init(cairo_win32_surface_create(mDC));
|
||||
}
|
||||
}
|
||||
|
||||
gfxWindowsSurface::gfxWindowsSurface(const gfxIntSize& size, gfxImageFormat imageFormat) :
|
||||
mOwnsDC(PR_FALSE), mWnd(nsnull)
|
||||
mOwnsDC(PR_FALSE), mForPrinting(PR_FALSE), mWnd(nsnull)
|
||||
{
|
||||
if (!CheckSurfaceSize(size))
|
||||
return;
|
||||
@ -71,7 +79,7 @@ gfxWindowsSurface::gfxWindowsSurface(const gfxIntSize& size, gfxImageFormat imag
|
||||
}
|
||||
|
||||
gfxWindowsSurface::gfxWindowsSurface(HDC dc, const gfxIntSize& size, gfxImageFormat imageFormat) :
|
||||
mOwnsDC(PR_FALSE), mWnd(nsnull)
|
||||
mOwnsDC(PR_FALSE), mForPrinting(PR_FALSE), mWnd(nsnull)
|
||||
{
|
||||
if (!CheckSurfaceSize(size))
|
||||
return;
|
||||
@ -85,10 +93,13 @@ gfxWindowsSurface::gfxWindowsSurface(HDC dc, const gfxIntSize& size, gfxImageFor
|
||||
|
||||
|
||||
gfxWindowsSurface::gfxWindowsSurface(cairo_surface_t *csurf) :
|
||||
mOwnsDC(PR_FALSE), mWnd(nsnull)
|
||||
mOwnsDC(PR_FALSE), mForPrinting(PR_FALSE), mWnd(nsnull)
|
||||
{
|
||||
mDC = cairo_win32_surface_get_dc(csurf);
|
||||
|
||||
if (cairo_surface_get_type(csurf) == CAIRO_SURFACE_TYPE_WIN32_PRINTING)
|
||||
mForPrinting = PR_TRUE;
|
||||
|
||||
Init(csurf, PR_TRUE);
|
||||
}
|
||||
|
||||
@ -105,6 +116,9 @@ gfxWindowsSurface::~gfxWindowsSurface()
|
||||
already_AddRefed<gfxImageSurface>
|
||||
gfxWindowsSurface::GetImageSurface()
|
||||
{
|
||||
if (mForPrinting)
|
||||
return nsnull;
|
||||
|
||||
cairo_surface_t *isurf = cairo_win32_surface_get_image(CairoSurface());
|
||||
if (!isurf)
|
||||
return nsnull;
|
||||
@ -118,6 +132,9 @@ gfxWindowsSurface::GetImageSurface()
|
||||
already_AddRefed<gfxWindowsSurface>
|
||||
gfxWindowsSurface::OptimizeToDDB(HDC dc, const gfxIntSize& size, gfxImageFormat format)
|
||||
{
|
||||
if (mForPrinting)
|
||||
return nsnull;
|
||||
|
||||
gfxImageFormat realFormat = format;
|
||||
|
||||
if (realFormat != ImageFormatRGB24)
|
||||
@ -204,6 +221,8 @@ nsresult gfxWindowsSurface::BeginPage()
|
||||
|
||||
nsresult gfxWindowsSurface::EndPage()
|
||||
{
|
||||
if (mForPrinting)
|
||||
cairo_surface_show_page(CairoSurface());
|
||||
::EndPage(mDC);
|
||||
return NS_OK;
|
||||
}
|
||||
|
@ -547,7 +547,7 @@ NS_IMETHODIMP nsDeviceContextSpecWin::GetSurfaceForPrinter(gfxASurface **surface
|
||||
HDC dc = ::CreateDC(mDriverName, mDeviceName, NULL, mDevMode);
|
||||
|
||||
// have this surface take over ownership of this DC
|
||||
newSurface = new gfxWindowsSurface(dc, PR_TRUE);
|
||||
newSurface = new gfxWindowsSurface(dc, gfxWindowsSurface::FLAG_TAKE_DC | gfxWindowsSurface::FLAG_FOR_PRINTING);
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user