--- a/gfx/src/thebes/nsThebesDeviceContext.cpp
+++ b/gfx/src/thebes/nsThebesDeviceContext.cpp
@@ -714,16 +714,19 @@ nsThebesDeviceContext::CalcPrintingSize(
#ifdef XP_OS2
case gfxASurface::SurfaceTypeOS2:
{
inPoints = PR_FALSE;
// we already set the size in the surface constructor we set for
// printing, so just get those values here
size = reinterpret_cast<gfxOS2Surface*>(mPrintingSurface.get())->GetSize();
+ // as they are in pixels we need to scale them to app units
+ size.width = NSFloatPixelsToAppUnits(size.width, AppUnitsPerDevPixel());
+ size.height = NSFloatPixelsToAppUnits(size.height, AppUnitsPerDevPixel());
// still need to get the depth from the device context
HDC dc = GetPrintHDC();
LONG value;
if (DevQueryCaps(dc, CAPS_COLOR_BITCOUNT, 1, &value))
mDepth = value;
else
mDepth = 8; // default to 8bpp, should be enough for printers
break;
--- a/widget/src/os2/nsDeviceContextSpecOS2.cpp
+++ b/widget/src/os2/nsDeviceContextSpecOS2.cpp
@@ -94,17 +94,17 @@ protected:
//---------------
// static members
GlobalPrinters GlobalPrinters::mGlobalPrinters;
nsStringArray* GlobalPrinters::mGlobalPrinterList = nsnull;
ULONG GlobalPrinters::mGlobalNumPrinters = 0;
//---------------
nsDeviceContextSpecOS2::nsDeviceContextSpecOS2()
- : mQueue(nsnull)
+ : mQueue(nsnull), mPrintDC(nsnull), mPrintingStarted(PR_FALSE)
{
}
nsDeviceContextSpecOS2::~nsDeviceContextSpecOS2()
{
if (mQueue)
PrnClosePrinter(mQueue);
}
@@ -386,76 +386,121 @@ NS_IMETHODIMP nsDeviceContextSpecOS2::Ge
int printerDest = 0;
char *filename = nsnull;
GetCopies(numCopies);
GetDestination(printerDest);
if (!printerDest) {
GetPath(&filename);
}
- HDC printdc = PrnOpenDC(mQueue, "Mozilla", numCopies, printerDest, filename);
+ mPrintingStarted = PR_TRUE;
+ mPrintDC = PrnOpenDC(mQueue, "Mozilla", numCopies, printerDest, filename);
double width, height;
mPrintSettings->GetEffectivePageSize(&width, &height);
#ifdef debug_thebes_print
printf("nsDeviceContextSpecOS2::GetSurfaceForPrinter(): %fx%ftwips, copies=%d\n",
width, height, numCopies);
#endif
// we need pixels, so scale from twips to the printer resolution
// and take into account that CAPS_*_RESOLUTION are in px/m, default
// to approx. 100dpi
double hDPI = 3937., vDPI = 3937.;
LONG value;
- if (DevQueryCaps(printdc, CAPS_HORIZONTAL_RESOLUTION, 1, &value))
+ if (DevQueryCaps(mPrintDC, CAPS_HORIZONTAL_RESOLUTION, 1, &value))
hDPI = value * 0.0254;
- if (DevQueryCaps(printdc, CAPS_VERTICAL_RESOLUTION, 1, &value))
+ if (DevQueryCaps(mPrintDC, CAPS_VERTICAL_RESOLUTION, 1, &value))
vDPI = value * 0.0254;
width = width * hDPI / 1440;
height = height * vDPI / 1440;
#ifdef debug_thebes_print
- printf("nsDeviceContextSpecOS2::GetSurfaceForPrinter(): %fx%fpx (res=%fx%f)\n",
- width, height, hDPI, vDPI);
+ printf("nsDeviceContextSpecOS2::GetSurfaceForPrinter(): %fx%fpx (res=%fx%f)\n"
+ " expected size: %7.2f MiB\n",
+ width, height, hDPI, vDPI, width*height*4./1024./1024.);
#endif
// Now pass the created DC into the thebes surface for printing.
// It gets destroyed there.
newSurface = new(std::nothrow)
- gfxOS2Surface(printdc, gfxIntSize(int(ceil(width)), int(ceil(height))));
+ gfxOS2Surface(mPrintDC, gfxIntSize(int(ceil(width)), int(ceil(height))));
}
if (!newSurface) {
*surface = nsnull;
return NS_ERROR_FAILURE;
}
*surface = newSurface;
NS_ADDREF(*surface);
return NS_OK;
}
+// Helper function to convert the string to the native codepage,
+// similar to UnicodeToCodepage() in nsDragService.cpp.
+char *GetACPString(const PRUnichar* aStr)
+{
+ nsString str(aStr);
+ if (str.Length() == 0) {
+ return nsnull;
+ }
+
+ nsAutoCharBuffer buffer;
+ PRInt32 bufLength;
+ WideCharToMultiByte(0, PromiseFlatString(str).get(), str.Length(),
+ buffer, bufLength);
+ return ToNewCString(nsDependentCString(buffer.Elements()));
+}
+
NS_IMETHODIMP nsDeviceContextSpecOS2::BeginDocument(PRUnichar* aTitle,
PRUnichar* aPrintToFileName,
PRInt32 aStartPage,
PRInt32 aEndPage)
{
- return NS_ERROR_NOT_IMPLEMENTED;
+#ifdef debug_thebes_print
+ printf("nsDeviceContextSpecOS2[%#x]::BeginPrinting(%s, %s)\n", (unsigned)this,
+ NS_LossyConvertUTF16toASCII(nsString(aTitle)).get(),
+ NS_LossyConvertUTF16toASCII(nsString(aPrintToFileName)).get());
+#endif
+ char *title = GetACPString(aTitle);
+ const PSZ pszGenericDocName = "Mozilla Document";
+ PSZ pszDocName = title ? title : pszGenericDocName;
+ LONG lResult = DevEscape(mPrintDC, DEVESC_STARTDOC,
+ strlen(pszDocName) + 1, pszDocName,
+ (PLONG)NULL, (PBYTE)NULL);
+ mPrintingStarted = PR_TRUE;
+ if (title) {
+ nsMemory::Free(title);
+ }
+
+ return lResult == DEV_OK ? NS_OK : NS_ERROR_GFX_PRINTER_STARTDOC;
}
NS_IMETHODIMP nsDeviceContextSpecOS2::EndDocument()
{
- return NS_ERROR_NOT_IMPLEMENTED;
+ LONG lOutCount = 2;
+ USHORT usJobID = 0;
+ LONG lResult = DevEscape(mPrintDC, DEVESC_ENDDOC, 0L, (PBYTE)NULL,
+ &lOutCount, (PBYTE)&usJobID);
+ return lResult == DEV_OK ? NS_OK : NS_ERROR_GFX_PRINTER_ENDDOC;
}
NS_IMETHODIMP nsDeviceContextSpecOS2::BeginPage()
{
- return NS_ERROR_NOT_IMPLEMENTED;
+ if (mPrintingStarted) {
+ // we don't want an extra page break at the start of the document
+ mPrintingStarted = PR_FALSE;
+ return NS_OK;
+ }
+ LONG lResult = DevEscape(mPrintDC, DEVESC_NEWFRAME, 0L, (PBYTE)NULL,
+ (PLONG)NULL, (PBYTE)NULL);
+ return lResult == DEV_OK ? NS_OK : NS_ERROR_GFX_PRINTER_STARTPAGE;
}
NS_IMETHODIMP nsDeviceContextSpecOS2::EndPage()
{
- return NS_ERROR_NOT_IMPLEMENTED;
+ return NS_OK;
}
// Printer Enumerator
nsPrinterEnumeratorOS2::nsPrinterEnumeratorOS2()
{
}
NS_IMPL_ISUPPORTS1(nsPrinterEnumeratorOS2, nsIPrinterEnumerator)