Exemple #1
0
void wxMacCarbonPrinterDC::StartPage( wxPrinterDC* dc )
{
    if ( m_err )
        return ;

    wxMacCarbonPrintData *native = (wxMacCarbonPrintData*) dc->GetPrintData().GetNativeData() ;

    m_err = PMSessionBeginPage(native->m_macPrintSession,
                 native->m_macPageFormat,
                 nil);

#if wxMAC_USE_CORE_GRAPHICS
    CGContextRef pageContext;
#endif
    if ( m_err == noErr )
    {
#if wxMAC_USE_CORE_GRAPHICS
        m_err = PMSessionGetGraphicsContext(native->m_macPrintSession,
                                            kPMGraphicsContextCoreGraphics,
                                            (void**) &pageContext );
        dc->MacSetCGContext(pageContext) ;
#else
        m_err = PMSessionGetGraphicsContext(native->m_macPrintSession,
                                            kPMGraphicsContextQuickdraw,
                                            (void**) &dc->m_macPort );
#endif
    }

    if ( m_err != noErr )
    {
        PMSessionEndPage(native->m_macPrintSession);
        PMSessionEndDocument(native->m_macPrintSession);
    }
    else
    {
        PMRect rPage;

        m_err = PMGetAdjustedPageRect(native->m_macPageFormat, &rPage);
        if ( !m_err )
        {
#if wxMAC_USE_CORE_GRAPHICS
            PMRect paperRect ;
            PMGetAdjustedPaperRect( native->m_macPageFormat , &paperRect ) ;
            CGContextTranslateCTM( pageContext , -paperRect.left , -paperRect.top + ( rPage.bottom - rPage.top ) ) ;
            CGContextScaleCTM( pageContext , 1 , -1 ) ;
            CGContextSaveGState( pageContext ) ;
#else
            dc->m_macLocalOrigin.x = (int) rPage.left;
            dc->m_macLocalOrigin.y = (int) rPage.top;
#endif
        }
        // since this is a non-critical error, we set the flag back
        m_err = noErr ;
    }
}
Exemple #2
0
bool QPrinter::newPage()
{
  if (state != PST_ACTIVE)
    return FALSE;
  if (PMSessionEndPage(psession) != noErr)  { //end the last page
    state = PST_ERROR;
    return FALSE;
  }

  if (PMSessionBeginPage(psession, pformat, 0) != noErr)  { //start a new one
    state = PST_ERROR;
    return FALSE;
  }
  if (PMSessionGetGraphicsContext(psession, kPMGraphicsContextQuickdraw, &hd) != noErr) {
    state = PST_ERROR;
    return FALSE;
  }

  if (fullPage()) {
    uint top, left, bottom, right;
    qt_get_margins(pformat, &top, &left, &bottom, &right);
    QMacSavedPortInfo mp(this);
    SetOrigin(top, left);
  } else {
    QMacSavedPortInfo mp(this);
    SetOrigin(0, 0);
  }
  return TRUE;
}
Exemple #3
0
void Printer_nextPage (void) {
	#if defined (macintosh)
		if (thePrinter. postScript) closePostScript ();
		PMSessionEndPage (theMacPrintSession);
		PMSessionBeginPage (theMacPrintSession, theMacPageFormat, NULL);
		PMSessionGetGraphicsContext (theMacPrintSession, kPMGraphicsContextQuickdraw, (void **) & theMacPort);
		SetPort (theMacPort);
		if (! thePrinter. postScript) SetOrigin (- paperSize. left, - paperSize. top);
		if (thePrinter. postScript) openPostScript ();
	#elif defined (_WIN32)
		if (thePrinter. postScript) {
			exitPostScriptPage ();
			EndPage (theWinDC);
			StartPage (theWinDC);
			initPostScriptPage ();
		} else {
			if (EndPage (theWinDC) < 0) ;   /* BUG: should give the opportunity of cancellation. */
			StartPage (theWinDC);
			/*
			 * Since StartPage has reset the DC, restore some of our non-default settings.
			 */
			SetBkMode (theWinDC, TRANSPARENT);
			SetTextAlign (theWinDC, TA_LEFT | TA_BASELINE | TA_NOUPDATECP);
		}
	#endif
}
bool QMacPrintEnginePrivate::newPage_helper()
{
    Q_Q(QMacPrintEngine);
    Q_ASSERT(state == QPrinter::Active);

    if (PMSessionError(session) != noErr) {
        q->abort();
        return false;
    }

    OSStatus status = shouldSuppressStatus() ? PMSessionBeginPageNoDialog(session, format, 0)
                                             : PMSessionBeginPage(session, format, 0);
    if(status != noErr) {
        state = QPrinter::Error;
        return false;
    }

    QRect page = q->property(QPrintEngine::PPK_PageRect).toRect();
    QRect paper = q->property(QPrintEngine::PPK_PaperRect).toRect();

    CGContextRef cgContext;
    OSStatus err = noErr;
#if (MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_4)
    if (QSysInfo::MacintoshVersion >= QSysInfo::MV_10_4) {
        err = PMSessionGetCGGraphicsContext(session, &cgContext);
    } else
#endif
    {
#ifndef Q_OS_MAC64
        err = PMSessionGetGraphicsContext(session, kPMGraphicsContextCoreGraphics,
                                          reinterpret_cast<void **>(&cgContext));
#endif
    }
    if(err != noErr) {
        qWarning("QMacPrintEngine::newPage: Cannot retrieve CoreGraphics context: %ld", long(err));
        state = QPrinter::Error;
        return false;
    }
    QCoreGraphicsPaintEngine *cgEngine = static_cast<QCoreGraphicsPaintEngine*>(paintEngine);
    cgEngine->d_func()->hd = cgContext;

    // Set the resolution as a scaling ration of 72 (the default).
    CGContextScaleCTM(cgContext, 72 / resolution.hRes, 72 / resolution.vRes);

    CGContextScaleCTM(cgContext, 1, -1);
    CGContextTranslateCTM(cgContext, 0, -paper.height());
    if (!fullPage)
        CGContextTranslateCTM(cgContext, page.x() - paper.x(), page.y() - paper.y());
    cgEngine->d_func()->orig_xform = CGContextGetCTM(cgContext);
    cgEngine->d_func()->setClip(0);
    cgEngine->state->dirtyFlags = QPaintEngine::AllDirty;
    cgEngine->syncState();
    return true;
}
Exemple #5
0
bool QPrinter::cmd(int c, QPainter *, QPDevCmdParam *)
{
  if (!psession && PMCreateSession(&psession) != noErr)
    return FALSE;

  if (c ==  PdcBegin) {                     // begin; start printing
    if (state != PST_IDLE) {
      qDebug("Qt: internal: printer: two PdcBegin(s).");
      return FALSE;
    }

    //just to be sure they've been setup
    prepare(&pformat);
    prepare(&psettings);

    //validate the settings
    if (PMSessionValidatePrintSettings(psession, psettings, kPMDontWantBoolean) != noErr)
      return FALSE;
    if (PMSessionValidatePageFormat(psession, pformat, kPMDontWantBoolean) != noErr)
      return FALSE;

    if (PMSessionBeginDocument(psession, psettings, pformat) != noErr) //begin the document
      return FALSE;


    if (PMSessionBeginPage(psession, pformat, 0) != noErr) //begin the page
      return FALSE;
    if (PMSessionGetGraphicsContext(psession, kPMGraphicsContextQuickdraw,
                                    &hd) != noErr) //get the gworld
      return FALSE;
    state = PST_ACTIVE;
    if (fullPage()) {
      uint top, left, bottom, right;
      qt_get_margins(pformat, &top, &left, &bottom, &right);
      QMacSavedPortInfo mp(this);
      SetOrigin(top, left);
    } else {
      QMacSavedPortInfo mp(this);
      SetOrigin(0, 0);
    }
  } else if (c == PdcEnd) {
    if (hd && state != PST_IDLE) {
      PMSessionEndPage(psession);
      PMSessionEndDocument(psession);
      hd = NULL;
    }
    state  = PST_IDLE;
  } else {                                    // all other commands...
    if (state == PST_ABORTED || ((state == PST_ACTIVE || state == PST_ERROR) && PMSessionError(psession) != noErr))
      return FALSE;
  }
  return TRUE;
}
Exemple #6
0
/*------------------------------------------------------------------------------
	Function:
		DoPrintLoop
	
	Parameters:
	
	Description:
		DoPrintLoop calculates which pages to print and executes the print
		loop, calling DrawPage for each page.
				
------------------------------------------------------------------------------*/
OSStatus DoPrintLoop(PrintingLogicPtr printJob)
{
    OSStatus	status = noErr, tempErr;
    CGContextRef  printingContext;
                 
	
    //	Note, we don't have to worry about the number of copies.  The printing
    //	manager handles this.  So we just iterate through the document from the
    //	first page to be printed, to the last.

    //	Note, we don't have to deal with the classic Printing Manager's
    //	128-page boundary limit.
                    
    //	Set up a page for printing.  Under the classic Printing Manager, applications
    //	could provide a page rect different from the one in the print record to achieve
    //	scaling. This is no longer recommended and on Mac OS X, the PageRect argument
    //	is ignored.
    

        
 	//    Now you are ready to request the printing context
	status = PMSessionGetGraphicsContext (printJob->printSession,
		kPMGraphicsContextCoreGraphics, (void **) &printingContext);

    if (status == noErr) {
       //	Draw the page.
        status = DrawPage(printJob,printingContext);
    }
            
    //	Only report a printing error once we have completed the print loop. This
    //	ensures that every PMBeginXXX call that returns no error is followed by
    //	a matching PMEndXXX call, so the Printing Manager can release all temporary 
    //	memory and close properly.
    tempErr = PMSessionError(printJob->printSession);
    if(status == noErr)
        status = tempErr;

    if (status == kPMCancel) 
        status = noErr;
            
    return status;
}	//	DoPrintLoop
Exemple #7
0
void wxMacCarbonPrinterDC::StartPage( wxPrinterDC* dc )
{
    if ( m_err )
        return ;

    wxMacCarbonPrintData *native = (wxMacCarbonPrintData*) dc->GetPrintData().m_nativePrintData ;

    m_err = PMSessionBeginPage(native->m_macPrintSession,
                 native->m_macPageFormat,
                 nil);

    if ( m_err == noErr )
    {
        m_err = PMSessionGetGraphicsContext(native->m_macPrintSession,
                                            nil,
                                            (void**) &dc->m_macPort );
    }

    if ( m_err != noErr )
    {
        PMSessionEndPage(native->m_macPrintSession);
        PMSessionEndDocument(native->m_macPrintSession);
    }
    else
    {
        PMRect rPage;

        m_err = PMGetAdjustedPageRect(native->m_macPageFormat, &rPage);
        if ( !m_err )
        {
            dc->m_macLocalOrigin.x = (int) rPage.left;
            dc->m_macLocalOrigin.y = (int) rPage.top;
        }
        // since this is a non-critical error, we set the flag back
        m_err = noErr ;
    }
}
Exemple #8
0
boolean shellprint (WindowPtr w, boolean fldialog) {

	/*
	9/5/90 dmb:  open and close print resources each time we're called.  also, 
	make sure we close each page opened, even when errors occur
	
	9/28/91 dmb: for exit of edit mode before printing
	
	4/24/92 dmb: make sure bJDocLoop is bSpoolLoop before calling PrPicFile, as 
	per IM II-155.  otherwise, we can get bogus PrErrors
	*/

	OSStatus 		theErr;
	boolean			accepted;

	//remember that this is a grafport, TPPrPort isn't
	//but this should work because all the code that
	//messes with printing uses a grafport. 

	// CGrafPtr			printport;
	UInt32
		minPage = 1,
		maxPage = 9999;

	SInt32	firstPage = 1;
	SInt32	lastPage = 9999;

	short i;
	boolean fl = false;
	
	if (w == nil) /*defensive driving*/
		return (false);

	if (!carbonValidSession())
	{
		carbonStdSetup();
	}
	
	fl = false; /*until sucessfull print, this is return value*/
	
	/*fills in fields of printinfo record*/
	(*shellglobals.setprintinfoproutine) ();

	//this only counts the number of pages.
	maxPage = shellprintinfo.ctpages;
	
	//set the page range
	theErr = PMSetPageRange(shellprintinfo.printsettings, minPage, maxPage);
	if(theErr != noErr){
		goto exit;
	}

	//finally display the dialog
	if (fldialog)
	{
		theErr = PMSessionPrintDialog(
							 shellprintinfo.printhandle,
							 shellprintinfo.printsettings,
							 shellprintinfo.pageformat,
							&accepted);

		//either the user canceled or their was some other error.
		//don't print
		if (!accepted || (theErr != noErr)){
			goto exit;
		}
	}

	setcursortype (cursoriswatch);

	shellupdateallnow (); /*update all windows that were dirtied by the print dialog*/

	shellpushglobals (w);

	(*shellglobals.settextmoderoutine) (false); /*make sure editing changes are accepted*/

	pushport (nil); /*save current port on stack*/

	//Code change by Timothy Paustian Friday, June 16, 2000 4:19:04 PM
	//Changed to Opaque call for Carbon
	//I will have to watch out for this,
	//to save the port I need to use..
	//PMSessionGetGraphicsContext (
	//This does not return the printport, but TPrPort gPort field
	//I think I can get away with this because the only function that uses
	//it is pgInitDevice and that assumes you are passing a port.
	//It is OK in the old code because the first item in the struct is a port

	//we have to call this first before we can get the graphics context
	theErr = PMSessionBeginDocument(
							shellprintinfo.printhandle,
							shellprintinfo.printsettings,
							shellprintinfo.pageformat);

	if(theErr != noErr)
		goto exit;

	/*prepares for printing*/
	(*shellglobals.beginprintroutine) ();

	/*fills in fields of printinfo record*/
	// (*shellglobals.setprintinfoproutine) ();
	//this only counts the number of pages.
	
	//limit this to the number of pages the user asked for. 

	theErr = PMGetFirstPage(shellprintinfo.printsettings, (UInt32 *) (&firstPage));
	if (theErr == noErr)
	{
		theErr = PMGetLastPage(shellprintinfo.printsettings, (UInt32 *) (&lastPage));
	}

	//sanity checks
	if(theErr != noErr)
		goto exit;

	if(lastPage > shellprintinfo.ctpages)
		lastPage = shellprintinfo.ctpages;

	for (i = 1; i <= lastPage; i++) { /*print one page*/

		theErr = PMSessionBeginPage(
							 shellprintinfo.printhandle,
							 shellprintinfo.pageformat,
							&shellprintinfo.pagerect);

		if (theErr != noErr)
			break;
		
		//now set the graphics context.
		//in carbon we have to set up the port each time
		//to make sure it is in the printer port. Since other things can be going on
		//during the printing, the port may have changed.
		{
			GrafPtr thePort, oldPort;

			GetPort(&oldPort);

			//the second parameter is currently ignored.
			theErr = PMSessionGetGraphicsContext(
									shellprintinfo.printhandle,
									kPMGraphicsContextQuickdraw,
									(void **) &thePort);

			shellprintinfo.printport = thePort;

			SetPort(thePort);

			// Draw the page
			SetFractEnable (true);

			fl = (*shellglobals.printroutine) (i);

			//reset back to the old port.
			SetPort(oldPort);
		}

		theErr = PMSessionEndPage(shellprintinfo.printhandle);

		if (!fl)
			break;

		if (keyboardescape ())
		{
			theErr = PMSessionSetError(shellprintinfo.printhandle, iPrAbort);
		}
	} /*for*/

	theErr = PMSessionEndDocument(shellprintinfo.printhandle);

	if(theErr !=  noErr)
		goto exit;

	//everything worked and printing is done. so set fl to true.
	fl = true;

	//the PrPicFile is not supported in carbon.

	popport ();

	(*shellglobals.endprintroutine) ();

	shellpopglobals ();

exit:

	carbonKillPrintVars();
//	PMRelease(shellprintinfo.printhandle);
//	PMRelease(pageformat);
//	PMRelease(printsettings);

	currentprintport = NULL;

	return (fl);

	} /*shellprint*/
Exemple #9
0
// --------------------------------------------------------------------------------------
static OSStatus MyDoPrintLoop(PMPrintSession printSession, PMPageFormat pageFormat, 
				PMPrintSettings printSettings, const void *ourDataP,
                                const PrintingProcs *printingProcsP)
{
    OSStatus err = noErr;
    OSStatus tempErr = noErr;
    UInt32 firstPage, lastPage, totalDocPages = MyGetDocumentNumPagesInDoc(ourDataP);
    
    if(!err)
	err = PMGetFirstPage(printSettings, &firstPage);
	
    if (!err)
        err = PMGetLastPage(printSettings, &lastPage);

    if(!err && lastPage > totalDocPages){
        // don't draw more than the number of pages in our document
        lastPage = totalDocPages;
    }

    if (!err)		// tell the printing system the number of pages we are going to print
        err = PMSetLastPage(printSettings, lastPage, false);

    //	Note: we don't have to worry about the number of copies.  The printing
    //	manager handles this.  So we just iterate through the document from the
    //	first page to be printed, to the last.
    if (!err)
    {
        PageDrawProc *drawProc = GetMyDrawPageProc(ourDataP);
        err = printingProcsP->BeginDocumentProc(printSession, printSettings, pageFormat);
        if (!err){
	    UInt32 pageNumber = firstPage;
	    // need to check errors from our print loop and errors from the session for each
	    // time around our print loop before calling our BeginPageProc
            while(pageNumber <= lastPage && err == noErr && PMSessionError(printSession) == noErr)
            {
                err = printingProcsP->BeginPageProc(printSession, pageFormat, NULL);
                if (!err){
                    GrafPtr oldPort = NULL;
                    void *printingContext = NULL;
                    GetPort(&oldPort);	// preserve the existing port
                
                    err = PMSessionGetGraphicsContext(printSession, kPMGraphicsContextQuickdraw,
                                                    (void **)&printingContext);
                    if(!err){
                        Rect pageRect;
                        SetPort((CGrafPtr)printingContext);
                        GetPortBounds(printingContext, &pageRect);
                        err = drawProc(ourDataP, &pageRect, pageNumber); // image the correct page
                        SetPort(oldPort);	// restore the prior port
                    }
                    // we must call EndPage if BeginPage returned noErr
		    tempErr = printingProcsP->EndPageProc(printSession);
                        
		    if(!err)err = tempErr;
                }
		pageNumber++;
            }	// end while loop
            
            // we must call EndDocument if BeginDocument returned noErr
	    tempErr = printingProcsP->EndDocumentProc(printSession);

	    if(!err)err = tempErr;
	    if(!err)
		err = PMSessionError(printSession);
        }
    }
    return err;
}
// --------------------------------------------------------------------------------------------------------------
static OSStatus MyDoPrintLoop(PMPrintSession printSession, PMPageFormat pageFormat, 
				PMPrintSettings printSettings, const void *ourDataP)
{
    OSStatus err = noErr;
    OSStatus tempErr = noErr;
    UInt32 firstPage, lastPage, totalDocPages = MyGetDocumentNumPagesInDoc(ourDataP);
    PMResolution res;
    float ourAppScaling = 1.;
    
    err = PMGetResolution(pageFormat, &res);
    if(!err){
	ourAppScaling = res.hRes/72.;	// the scale factor we are applying
    }

    if(!err)
	err = PMGetFirstPage(printSettings, &firstPage);
	
    if (!err)
        err = PMGetLastPage(printSettings, &lastPage);

    if(!err && lastPage > totalDocPages){
        // don't draw more than the number of pages in our document
        lastPage = totalDocPages;
    }

    if (!err)		// tell the printing system the number of pages we are going to print
        err = PMSetLastPage(printSettings, lastPage, false);

    if (!err)
    {
        PageDrawProc *drawProc = GetMyDrawPageProc(ourDataP);
        err = PMSessionBeginDocument(printSession, printSettings, pageFormat);
        if (!err){
	    UInt32 pageNumber;
            for(pageNumber = firstPage; 
                err == noErr && (err = PMSessionError(printSession)) == noErr && pageNumber <= lastPage; 
                pageNumber++
            ){
                err = PMSessionBeginPage(printSession, pageFormat, NULL);
                if (!err){
                    GrafPtr oldPort = NULL;
                    void *printingContext = NULL;
                    GetPort(&oldPort);	// preserve the existing port
                
                    err = PMSessionGetGraphicsContext(printSession, kPMGraphicsContextQuickdraw,
                                                    (void **)&printingContext);
                    if(!err){
                        SetPort((CGrafPtr)printingContext);
                        err = drawProc(ourDataP, ourAppScaling);	// supply app drawing resolution
                        SetPort(oldPort);	// restore the prior port
                    }
		    tempErr = PMSessionEndPage(printSession);
		    if(!err)err = tempErr;
                }
            }	// end for loop
	    tempErr = PMSessionEndDocument(printSession);
	    if(!err)err = tempErr;
        }
    }
    return err;
}
Exemple #11
0
void wxMacCarbonPrinterDC::StartPage( wxPrinterDC* dc )
{
    if ( m_err )
        return ;

    wxMacCarbonPrintData *native = (wxMacCarbonPrintData*) dc->GetPrintData().GetNativeData() ;

    m_err = PMSessionBeginPage(native->m_macPrintSession,
                 native->m_macPageFormat,
                 nil);

#if wxMAC_USE_CORE_GRAPHICS
    CGContextRef pageContext;
#endif
    if ( m_err == noErr )
    {
#if wxMAC_USE_CORE_GRAPHICS
#if MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_4
        m_err = PMSessionGetCGGraphicsContext(native->m_macPrintSession,
                                            &pageContext );

#else
        m_err = PMSessionGetGraphicsContext(native->m_macPrintSession,
                                            kPMGraphicsContextCoreGraphics,
                                            (void**) &pageContext );
#endif
#else
        m_err = PMSessionGetGraphicsContext(native->m_macPrintSession,
                                            kPMGraphicsContextQuickdraw,
                                            (void**) &dc->m_macPort );
#endif
    }

    if ( m_err != noErr )
    {
        PMSessionEndPage(native->m_macPrintSession);
        PMSessionEndDocument(native->m_macPrintSession);
    }
    else
    {
        PMRect rPage;

        m_err = PMGetAdjustedPageRect(native->m_macPageFormat, &rPage);
        if ( !m_err )
        {
#if wxMAC_USE_CORE_GRAPHICS
            PMRect paperRect ;
            PMGetAdjustedPaperRect( native->m_macPageFormat , &paperRect ) ;
            // make sure (0,0) is at the upper left of the printable area (wx conventions)
            // Core Graphics initially has the lower left of the paper as 0,0
            CGContextTranslateCTM( pageContext , -paperRect.left , paperRect.bottom ) ;
            CGContextScaleCTM( pageContext , 1 , -1 ) ;
#else
            dc->m_macLocalOrigin.x = (int) rPage.left;
            dc->m_macLocalOrigin.y = (int) rPage.top;
#endif
        }
        // since this is a non-critical error, we set the flag back
        m_err = noErr ;
    }
#if wxMAC_USE_CORE_GRAPHICS
    dc->SetGraphicsContext( wxGraphicsContext::CreateFromNative( pageContext ) );
#endif
}
Exemple #12
0
int Printer_print (void (*draw) (void *boss, Graphics g), void *boss) {
	#if defined (UNIX)
		structMelderFile tempFile = { 0 };
		char tempPath_utf8 [] = "/tmp/picXXXXXX";
		close (mkstemp (tempPath_utf8));
		Melder_pathToFile (Melder_peekUtf8ToWcs (tempPath_utf8), & tempFile);
		thePrinter. graphics = Graphics_create_postscriptjob (& tempFile, thePrinter. resolution,
			thePrinter. spots, thePrinter. paperSize, thePrinter. orientation, thePrinter. magnification);
		if (! thePrinter. graphics) return Melder_error1 (L"Cannot create temporary PostScript file for printing.");
		draw (boss, thePrinter. graphics);
		forget (thePrinter. graphics);
		char command [500];
		sprintf (command, Melder_peekWcsToUtf8 (Site_getPrintCommand ()), tempPath_utf8);
		system (command);
		MelderFile_delete (& tempFile);
	#elif defined (_WIN32)
		int postScriptCode = POSTSCRIPT_PASSTHROUGH;
		DOCINFO docInfo;
		DEVMODE *devMode;
		initPrinter ();
		if (! theWinPrint. hDevMode) {
			memset (& theWinPrint, 0, sizeof (PRINTDLG));
			theWinPrint. lStructSize = sizeof (PRINTDLG);
			theWinPrint. Flags = PD_RETURNDEFAULT;
			if (! PrintDlg (& theWinPrint)) return Melder_error1 (L"Cannot initialize printer.");
		}
		if (Melder_backgrounding) {
			theWinPrint. Flags = PD_RETURNDEFAULT | PD_RETURNDC;
			if (! PrintDlg (& theWinPrint) || theWinPrint. hDC == NULL) {
				return Melder_error1 (L"Cannot print from a script on this computer.");
			}
		} else {
			theWinPrint. Flags &= ~ PD_RETURNDEFAULT;
			theWinPrint. Flags |= PD_RETURNDC;
			if (! PrintDlg (& theWinPrint)) return 1;
		}
		theWinDC = theWinPrint. hDC;
		thePrinter. postScript = thePrinter. allowDirectPostScript &&
			Escape (theWinDC, QUERYESCSUPPORT, sizeof (int), (LPSTR) & postScriptCode, NULL);
		/*
		 * The HP colour inkjet printer returns in dmFields:
		 * 0, 1, 8, 9, 10, 11, 12, 13, 14, 15, 23, 24, 25, 26 = DM_ORIENTATION |
		 *    DM_PAPERSIZE | DM_COPIES | DM_DEFAULTSOURCE | DM_PRINTQUALITY |
		 *    DM_COLOR | DM_DUPLEX | DM_YRESOLUTION | DM_TTOPTION | DM_COLLATE |
		 *    DM_ICMMETHOD | DM_ICMINTENT | DM_MEDIATYPE | DM_DITHERTYPE
		 */
		devMode = * (DEVMODE **) theWinPrint. hDevMode;
		thePrinter. resolution = devMode -> dmFields & DM_YRESOLUTION ? devMode -> dmYResolution :
			devMode -> dmFields & DM_PRINTQUALITY ?
			( devMode -> dmPrintQuality > 0 ? devMode -> dmPrintQuality : 300 ) : 300;
		if (devMode -> dmFields & DM_PAPERWIDTH) {
			thePrinter. paperWidth = devMode -> dmPaperWidth * thePrinter. resolution / 254;
			thePrinter. paperHeight = devMode -> dmPaperLength * thePrinter. resolution / 254;
		} else if (devMode -> dmFields & DM_PAPERSIZE) {
			static struct { float width, height; } sizes [] = { { 0, 0 }, { 8.5, 11 }, { 8.5, 11 }, { 11, 17 },
				{ 17, 11 }, { 8.5, 14 }, { 5.5, 8.5 }, { 7.25, 10.5 }, { 297/25.4, 420/25.4 },
				{ 210/25.4, 297/25.4 }, { 210/25.4, 297/25.4 }, { 148.5/25.4, 210/25.4 },
				{ 250/25.4, 354/25.4 }, { 182/25.4, 257/25.4 }, { 8.5, 13 },
				{ 215/25.4, 275/25.4 }, { 10, 14 }, { 11, 17 }, { 8.5, 11 }, { 3.875, 8.875 },
				{ 4.125, 9.5 }, { 4.5, 10.375 } };
			int paperSize = devMode -> dmPaperSize;
			if (paperSize <= 0 || paperSize > 21) paperSize = 1;
			thePrinter. paperWidth = sizes [paperSize]. width * thePrinter. resolution;
			thePrinter. paperHeight = sizes [paperSize]. height * thePrinter. resolution;
			if (devMode -> dmOrientation == DMORIENT_LANDSCAPE) {
				long dummy = thePrinter. paperWidth;
				thePrinter. paperWidth = thePrinter. paperHeight;
				thePrinter. paperHeight = dummy;
			}
		} else {
			thePrinter. paperWidth = 1000;
			thePrinter. paperHeight = 1000;
		}
		EnableWindow ((HWND) XtWindow (theCurrentPraatApplication -> topShell), FALSE);
		SetAbortProc (theWinDC, AbortFunc);
		memset (& docInfo, 0, sizeof (DOCINFO));
		docInfo. cbSize = sizeof (DOCINFO);
		docInfo. lpszDocName = L"Praatjes";
		docInfo. lpszOutput = NULL;
		if (thePrinter. postScript) {
			StartDoc (theWinDC, & docInfo);
			StartPage (theWinDC);
			initPostScriptPage ();
			thePrinter. graphics = Graphics_create_postscriptprinter ();
			if (! thePrinter. graphics) return Melder_error1 (L"Cannot open printer.");
			draw (boss, thePrinter. graphics);
			forget (thePrinter. graphics);
			exitPostScriptPage ();
			EndPage (theWinDC);
			EndDoc (theWinDC);
		} else {
			StartDoc (theWinDC, & docInfo);
			StartPage (theWinDC);
			thePrinter. graphics = Graphics_create_screenPrinter (NULL, (unsigned long) theWinDC);
			if (! thePrinter. graphics) return Melder_error1 (L"Cannot open printer.");
			draw (boss, thePrinter. graphics);
			forget (thePrinter. graphics);
			if (EndPage (theWinDC) < 0) {
				Melder_error1 (L"Cannot print page.");
			} else {
				EndDoc (theWinDC);
			}
		}
		EnableWindow ((HWND) XtWindow (theCurrentPraatApplication -> topShell), TRUE);
		DeleteDC (theWinDC), theWinDC = NULL;
	#elif defined (macintosh)
		Boolean result;
		initPrinter ();
		if (Melder_backgrounding) {
			PMSessionValidatePageFormat (theMacPrintSession, theMacPageFormat, & result);
			PMSessionValidatePrintSettings (theMacPrintSession, theMacPrintSettings, & result);
		} else {
			Boolean accepted;
			PMSessionPrintDialog (theMacPrintSession, theMacPrintSettings, theMacPageFormat, & accepted);
			if (! accepted) return 1;   /* Normal cancelled return. */
		}
		PMSessionValidatePageFormat (theMacPrintSession, theMacPageFormat, & result);
		PMSessionValidatePrintSettings (theMacPrintSession, theMacPrintSettings, & result);
		PMResolution res;
		PMGetResolution (theMacPageFormat, & res);
		thePrinter. resolution = res. hRes;
		PMGetAdjustedPaperRect (theMacPageFormat, & paperSize);
		thePrinter. paperWidth = paperSize. right - paperSize. left;
		thePrinter. paperHeight = paperSize. bottom - paperSize. top;
		Boolean isPostScriptDriver = FALSE;
		//PMSessionIsDocumentFormatSupported (theMacPrintSession,
		//	kPMDocumentFormatPICTPS, & isPostScriptDriver);
		CFArrayRef supportedFormats;
		PMSessionGetDocumentFormatGeneration (theMacPrintSession, & supportedFormats);
		CFIndex numberOfSupportedFormats = CFArrayGetCount (supportedFormats);
		if (Melder_debug == 21) {
			MelderInfo_open ();
			MelderInfo_writeLine1 (L"Supported document formats:");
		}
		for (CFIndex i = 0; i < numberOfSupportedFormats; i ++) {
			CFStringRef supportedFormat = CFArrayGetValueAtIndex (supportedFormats, i);
			if (CFStringCompare (supportedFormat, kPMDocumentFormatPICTPS, 0) == 0) {
				isPostScriptDriver = TRUE;
			}
			if (Melder_debug == 21) {
				MelderInfo_writeLine3 (Melder_integer (i), L": ",
					Melder_peekUtf8ToWcs (CFStringGetCStringPtr (supportedFormat, kCFStringEncodingUTF8)));
			}
		}
		if (Melder_debug == 21) {
			MelderInfo_close ();
		}
		CFRelease (supportedFormats);
		isPostScriptDriver = FALSE;   // OVERRIDE, because from 10.4 on we have something better: we'll be sending PDF
		thePrinter. postScript = thePrinter. allowDirectPostScript && isPostScriptDriver;
		if (thePrinter. postScript) {
			CFStringRef strings [1];
			strings [0] = kPMGraphicsContextQuickdraw;
			CFArrayRef array = CFArrayCreate (kCFAllocatorDefault, (const void **) strings, 1, & kCFTypeArrayCallBacks);
			OSStatus err = PMSessionSetDocumentFormatGeneration (theMacPrintSession, kPMDocumentFormatPICTPS, array, NULL);
			CFRelease (array);
			if (err != 0) {
				return Melder_error2 (L"PMSessionSetDocumentFormatGeneration: error ", Melder_integer (err));
			}
		}
		PMOrientation orientation;
		PMGetOrientation (theMacPageFormat, & orientation);
		thePrinter. orientation = orientation == kPMLandscape ||
			orientation == kPMReverseLandscape ? kGraphicsPostscript_orientation_LANDSCAPE : kGraphicsPostscript_orientation_PORTRAIT;
		PMSessionBeginDocument (theMacPrintSession, theMacPrintSettings, theMacPageFormat);
		PMSessionBeginPage (theMacPrintSession, theMacPageFormat, NULL);
		PMSessionGetGraphicsContext (theMacPrintSession, kPMGraphicsContextQuickdraw, (void **) & theMacPort);
		/*
		 * On PostScript, the point (0, 0) is the bottom left corner of the paper, which is fine.
		 * On the screen, however, the point (0, 0) is the top left corner of the writable page.
		 * Since we want paper-related margins, not writable-page-related margins,
		 * we require that this point gets the coordinates (250, 258) or so,
		 * so that the top left corner of the paper gets coordinates (0, 0).
		 * The "left" and "top" attributes of rPaper are negative values (e.g. -250 and -258),
		 * so multiply them by -1.
		 *
		 * Under Carbon, the port has to be set inside the page.
		 */
		SetPort (theMacPort);
		if (! thePrinter. postScript) SetOrigin (- paperSize. left, - paperSize. top);
		if (thePrinter. postScript) {
			if (! openPostScript ()) error1 (L"Cannot print PostScript.")
			thePrinter. graphics = Graphics_create_postscriptprinter ();
			if (! thePrinter. graphics) goto end;
			draw (boss, thePrinter. graphics);
			forget (thePrinter. graphics);
			closePostScript ();
		} else {
			thePrinter. graphics = Graphics_create_screenPrinter (NULL, (unsigned long) theMacPort);
			draw (boss, thePrinter. graphics);
			forget (thePrinter. graphics);
		}
	end:
		if (theMacPort) {
			PMSessionEndPage (theMacPrintSession);
			PMSessionEndDocument (theMacPrintSession);
			theMacPort = NULL;
		}
	#endif
	iferror return 0;
	return 1;
}