NS_IMETHODIMP nsDeviceContextOS2 :: GetDeviceContextFor(nsIDeviceContextSpec *aDevice, nsIDeviceContext *&aContext) { PRTQUEUE *pq; aContext = new nsDeviceContextOS2(); if(nsnull != aContext){ NS_ADDREF(aContext); } else { return NS_ERROR_OUT_OF_MEMORY; } ((nsDeviceContextOS2 *)aContext)->mSpec = aDevice; NS_ADDREF(aDevice); int numCopies = 0; int printerDest = 0; char *file = nsnull; ((nsDeviceContextSpecOS2 *)aDevice)->GetPRTQUEUE(pq); ((nsDeviceContextSpecOS2 *)aDevice)->GetCopies(numCopies); ((nsDeviceContextSpecOS2 *)aDevice)->GetDestination(printerDest); if (!printerDest) ((nsDeviceContextSpecOS2 *)aDevice)->GetPath(&file); HDC dc = PrnOpenDC(pq, "Mozilla", numCopies, printerDest, file); if (!dc) { return NS_ERROR_FAILURE; //PMERROR("DevOpenDC"); } /* endif */ return ((nsDeviceContextOS2 *)aContext)->Init((nsNativeDeviceContext)dc, this); }
NS_IMETHODIMP nsDeviceContextSpecOS2::GetSurfaceForPrinter(gfxASurface **surface) { NS_ASSERTION(mQueue, "Queue can't be NULL here"); nsRefPtr<gfxASurface> newSurface; PRInt16 outputFormat; mPrintSettings->GetOutputFormat(&outputFormat); // for now always set the output format to PDF, see bug 415522: printf("print output format is %d but we are setting it to %d (PDF)\n", outputFormat, nsIPrintSettings::kOutputFormatPDF); outputFormat = nsIPrintSettings::kOutputFormatPDF; mPrintSettings->SetOutputFormat(outputFormat); // save PDF format in settings if (outputFormat == nsIPrintSettings::kOutputFormatPDF) { nsXPIDLString filename; mPrintSettings->GetToFileName(getter_Copies(filename)); nsresult rv; if (filename.IsEmpty()) { // print to a file that is visible, like one on the Desktop nsCOMPtr<nsIFile> pdfLocation; rv = NS_GetSpecialDirectory(NS_OS_DESKTOP_DIR, getter_AddRefs(pdfLocation)); NS_ENSURE_SUCCESS(rv, rv); // construct a print output name using the current time, to make it // unique and not overwrite existing files char printName[CCHMAXPATH]; PRExplodedTime time; PR_ExplodeTime(PR_Now(), PR_LocalTimeParameters, &time); snprintf(printName, CCHMAXPATH-1, "%s_%04d%02d%02d_%02d%02d%02d.pdf", MOZ_APP_DISPLAYNAME, time.tm_year, time.tm_month+1, time.tm_mday, time.tm_hour, time.tm_min, time.tm_sec); printName[CCHMAXPATH-1] = '\0'; nsCAutoString printString(printName); rv = pdfLocation->AppendNative(printString); NS_ENSURE_SUCCESS(rv, rv); rv = pdfLocation->GetPath(filename); NS_ENSURE_SUCCESS(rv, rv); } #ifdef debug_thebes_print printf("nsDeviceContextSpecOS2::GetSurfaceForPrinter(): print to filename=%s\n", NS_LossyConvertUTF16toASCII(filename).get()); #endif double width, height; mPrintSettings->GetEffectivePageSize(&width, &height); // convert twips to points width /= TWIPS_PER_POINT_FLOAT; height /= TWIPS_PER_POINT_FLOAT; nsCOMPtr<nsILocalFile> file = do_CreateInstance("@mozilla.org/file/local;1"); rv = file->InitWithPath(filename); if (NS_FAILED(rv)) return rv; nsCOMPtr<nsIFileOutputStream> stream = do_CreateInstance("@mozilla.org/network/file-output-stream;1"); rv = stream->Init(file, -1, -1, 0); if (NS_FAILED(rv)) return rv; newSurface = new(std::nothrow) gfxPDFSurface(stream, gfxSize(width, height)); } else { int numCopies = 0; int printerDest = 0; char *filename = nsnull; GetCopies(numCopies); GetDestination(printerDest); if (!printerDest) { GetPath(&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(mPrintDC, CAPS_HORIZONTAL_RESOLUTION, 1, &value)) hDPI = value * 0.0254; 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" " expected size: %7.2f MiB\n", width, height, hDPI, vDPI, width*height*4./1024./1024.); #endif // perhaps restrict to usable area // (this or scaling down won't help, we will just get more pages and still crash!) if (DevQueryCaps(mPrintDC, CAPS_WIDTH, 1, &value) && width > (double)value) width = (double)value; if (DevQueryCaps(mPrintDC, CAPS_HEIGHT, 1, &value) && height > (double)value) height = (double)value; #ifdef debug_thebes_print printf("nsDeviceContextSpecOS2::GetSurfaceForPrinter(): capped? %fx%fpx (res=%fx%f)\n" " expected size: %7.2f MiB per page\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(mPrintDC, gfxIntSize(int(ceil(width)), int(ceil(height)))); } if (!newSurface) { *surface = nsnull; return NS_ERROR_FAILURE; } *surface = newSurface; NS_ADDREF(*surface); return NS_OK; }