void QPrinter::interpret(PMPageFormat *f)
{
    //get values
    PMOrientation o;
    if(PMGetOrientation(*f, &o) == noErr)
        setOrientation(o == kPMPortrait ? Portrait : Landscape);

    //Finally we update the scale so the resolution is effected by it
    PMSessionValidatePageFormat(psession, *f, kPMDontWantBoolean);
    setPageSize(carbonSize2QPrinterSize(*f));
}
Beispiel #2
0
bool wxMacCarbonPrintData::TransferTo( wxPrintData &data )
{
    OSStatus err = noErr ;
    
    UInt32 copies ;
    err = PMGetCopies( m_macPrintSettings , &copies ) ;
    if ( err == noErr )
        data.SetNoCopies( copies ) ; 
          
    PMOrientation orientation ;
    err = PMGetOrientation(  m_macPageFormat , &orientation ) ;
    if ( err == noErr )
    {
        if ( orientation == kPMPortrait || orientation == kPMReversePortrait )
            data.SetOrientation( wxPORTRAIT  );
        else
            data.SetOrientation( wxLANDSCAPE );
    }

    // collate cannot be set
#if 0
    {
        wxMacCFStringHolder name ;
        PMPrinter printer ;
        PMSessionGetCurrentPrinter( m_macPrintSession ,
            &printer ) ;
        m_printerName = name.AsString() ;
    }
#endif
    
    PMColorMode color ;
    err = PMGetColorMode( m_macPrintSettings, &color ) ;
    if ( err == noErr )
        data.SetColour( !(color == kPMBlackAndWhite) ) ;
        
    // PMDuplexMode not yet accessible via API
    // PMQualityMode not yet accessible via API
    // todo paperSize
	PMRect rPaper;
    err = PMGetUnadjustedPaperRect( m_macPageFormat, &rPaper);
    if ( err == noErr )
    {
        data.SetPaperSize( wxSize (
            (int)(( rPaper.right - rPaper.left ) * pt2mm + 0.5 ) ,
             (int)(( rPaper.bottom - rPaper.top ) * pt2mm + 0.5 ) ) );
    }
    return true ;
}
Beispiel #3
0
void wxOSXPrintData::TransferPaperInfoTo( wxPrintData &data )
{
    PMGetPageFormatPaper(m_macPageFormat, &m_macPaper);

    PMPrinter printer ;
    PMSessionGetCurrentPrinter( m_macPrintSession, &printer );
    OSStatus err = noErr ;
    UInt32 copies ;
    err = PMGetCopies( m_macPrintSettings , &copies ) ;
    if ( err == noErr )
        data.SetNoCopies( copies ) ;

    PMOrientation orientation ;
    err = PMGetOrientation(  m_macPageFormat , &orientation ) ;
    if ( err == noErr )
    {
        if ( orientation == kPMPortrait || orientation == kPMReversePortrait )
        {
            data.SetOrientation( wxPORTRAIT  );
            data.SetOrientationReversed( orientation == kPMReversePortrait );
        }
        else
        {
            data.SetOrientation( wxLANDSCAPE );
            data.SetOrientationReversed( orientation == kPMReverseLandscape );
        }
    }

    Boolean collate;
    if (PMGetCollate(m_macPrintSettings, &collate) == noErr)
        data.SetCollate(collate);


    PMDuplexMode mode = 0 ;
    PMGetDuplex(  m_macPrintSettings, &mode ) ;
    switch( mode )
    {
        case kPMDuplexNoTumble :
            data.SetDuplex(wxDUPLEX_HORIZONTAL);
            break ;
        case kPMDuplexTumble :
            data.SetDuplex(wxDUPLEX_VERTICAL);
            break ;
        case kPMDuplexNone :
        default :
            data.SetDuplex(wxDUPLEX_SIMPLEX);
            break ;
    }

    double height, width;
    PMPaperGetHeight(m_macPaper, &height);
    PMPaperGetWidth(m_macPaper, &width);

    wxSize sz((int)(width * pt2mm + 0.5 ) ,
              (int)(height * pt2mm + 0.5 ));
    data.SetPaperSize(sz);
    wxPaperSize id = wxThePrintPaperDatabase->GetSize(wxSize(sz.x* 10, sz.y * 10));
    if (id != wxPAPER_NONE)
    {
        data.SetPaperId(id);
    }
}
Beispiel #4
0
int QPrinter::metric(int m) const
{
  int val = 1;
  switch (m) {
    case QPaintDeviceMetrics::PdmWidth: {
      bool orientInSync = true;
      PMOrientation o;
      QPrinter::Orientation tmpOrient = orientation();
      if (PMGetOrientation(pformat, &o) == noErr) {
        orientInSync = ((o == kPMPortrait && tmpOrient == Portrait)
                        || o == kPMLandscape && tmpOrient == Landscape);
      }
      PageSize s = pageSize();
      if (s >= QPrinter::Custom) {
        val = tmpOrient == Portrait ? customPaperSize_.width() : customPaperSize_.height();
      } else {
        if (state == PST_ACTIVE || (tmpOrient == Portrait || orientInSync)) {
          val = qt_get_PDMWidth(pformat, fullPage());
        } else {
          val = qt_get_PDMHeight(pformat, fullPage());
        }
      }
      break;
    }
    case QPaintDeviceMetrics::PdmHeight: {
      bool orientInSync = true;
      PMOrientation o;
      QPrinter::Orientation tmpOrient = orientation();
      if (PMGetOrientation(pformat, &o) == noErr) {
        orientInSync = ((o == kPMPortrait && tmpOrient == Portrait)
                        || o == kPMLandscape && tmpOrient == Landscape);
      }
      PageSize s = pageSize();
      if (s >= QPrinter::Custom) {
        val = tmpOrient == Portrait ? customPaperSize_.height() : customPaperSize_.width();
      } else {
        if (state == PST_ACTIVE || (tmpOrient == Portrait || orientInSync)) {
          val = qt_get_PDMHeight(pformat, fullPage());
        } else {
          val = qt_get_PDMWidth(pformat, fullPage());
        }
      }
      break;
    }
    // We don't have to worry about the printer state here as metric() does that for us.
    case QPaintDeviceMetrics::PdmWidthMM:
      val = metric(QPaintDeviceMetrics::PdmWidth);
      val = (val * 254 + 5 * res) / (10 * res);
      break;
    case QPaintDeviceMetrics::PdmHeightMM:
      val = metric(QPaintDeviceMetrics::PdmHeight);
      val = (val * 254 + 5 * res) / (10 * res);
      break;
    case QPaintDeviceMetrics::PdmPhysicalDpiX:
    case QPaintDeviceMetrics::PdmPhysicalDpiY: {
      PMPrinter printer;
      if (PMSessionGetCurrentPrinter(psession, &printer) == noErr) {
        PMResolution resolution;
        PMPrinterGetPrinterResolution(printer, kPMCurrentValue, &resolution);
        val = (int)resolution.vRes;
        break;
      }
      //otherwise fall through
    }
    case QPaintDeviceMetrics::PdmDpiY:
    case QPaintDeviceMetrics::PdmDpiX:
      val = res;
      break;
    case QPaintDeviceMetrics::PdmNumColors:
      val = (1 << metric(QPaintDeviceMetrics::PdmDepth));
      break;
    case QPaintDeviceMetrics::PdmDepth:
      val = 24;
      break;
    default:
      val = 0;
#if defined(QT_CHECK_RANGE)
      qWarning("Qt: QPixmap::metric: Invalid metric command");
#endif
  }
  return val;
}
Beispiel #5
0
bool wxMacCarbonPrintData::TransferTo( wxPrintData &data )
{
    OSStatus err = noErr ;

    UInt32 copies ;
    err = PMGetCopies( m_macPrintSettings , &copies ) ;
    if ( err == noErr )
        data.SetNoCopies( copies ) ;

    PMOrientation orientation ;
    err = PMGetOrientation(  m_macPageFormat , &orientation ) ;
    if ( err == noErr )
    {
        if ( orientation == kPMPortrait || orientation == kPMReversePortrait )
        {
            data.SetOrientation( wxPORTRAIT  );
            data.SetOrientationReversed( orientation == kPMReversePortrait );
        }
        else
        {
            data.SetOrientation( wxLANDSCAPE );
            data.SetOrientationReversed( orientation == kPMReverseLandscape );
        }
    }

    // collate cannot be set
#if 0
    {
        wxMacCFStringHolder name ;
        PMPrinter printer ;
        PMSessionGetCurrentPrinter( m_macPrintSession ,
            &printer ) ;
        m_printerName = name.AsString() ;
    }
#endif

#ifndef __LP64__
    PMColorMode color ;
    err = PMGetColorMode( m_macPrintSettings, &color ) ;
    if ( err == noErr )
        data.SetColour( !(color == kPMBlackAndWhite) ) ;
#endif
#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_4
    if ( &PMGetDuplex!=NULL )
    {
        PMDuplexMode mode = 0 ;
        PMGetDuplex( (PMPrintSettings) m_macPrintSettings, &mode ) ;
        switch( mode )
        {
            case kPMDuplexNoTumble :
                data.SetDuplex(wxDUPLEX_HORIZONTAL);
                break ;
            case kPMDuplexTumble :
                data.SetDuplex(wxDUPLEX_VERTICAL);
                break ;
            case kPMDuplexNone :
            default :
                data.SetDuplex(wxDUPLEX_SIMPLEX);
                break ;
        }
    }
#endif
    // PMQualityMode not yet accessible via API
    
    PMPaper paper ;
    PMGetPageFormatPaper( m_macPageFormat, &paper );
    
    PMRect rPaper;
    err = PMGetUnadjustedPaperRect( m_macPageFormat, &rPaper);
    if ( err == noErr )
    {
        wxSize sz((int)(( rPaper.right - rPaper.left ) * pt2mm + 0.5 ) ,
             (int)(( rPaper.bottom - rPaper.top ) * pt2mm + 0.5 ));
        data.SetPaperSize(sz);
        wxPaperSize id = wxThePrintPaperDatabase->GetSize(wxSize(sz.x* 10, sz.y * 10));
        if (id != wxPAPER_NONE)
        {
            data.SetPaperId(id);
        }
    }
    return true ;
}
Beispiel #6
0
bool wxOSXPrintData::TransferTo( wxPrintData &data )
{
    OSStatus err = noErr ;
#if wxOSX_USE_COCOA
    UpdateToPMState();
#endif
    UInt32 copies ;
    err = PMGetCopies( m_macPrintSettings , &copies ) ;
    if ( err == noErr )
        data.SetNoCopies( copies ) ;

    PMOrientation orientation ;
    err = PMGetOrientation(  m_macPageFormat , &orientation ) ;
    if ( err == noErr )
    {
        if ( orientation == kPMPortrait || orientation == kPMReversePortrait )
        {
            data.SetOrientation( wxPORTRAIT  );
            data.SetOrientationReversed( orientation == kPMReversePortrait );
        }
        else
        {
            data.SetOrientation( wxLANDSCAPE );
            data.SetOrientationReversed( orientation == kPMReverseLandscape );
        }
    }

    Boolean collate;
    if (PMGetCollate(m_macPrintSettings, &collate) == noErr)
        data.SetCollate(collate);
    
    CFStringRef name;
    PMPrinter printer ;
    PMSessionGetCurrentPrinter( m_macPrintSession, &printer );
    if (PMPrinterIsDefault(printer))
        data.SetPrinterName(wxEmptyString);
    else
    {
        name = PMPrinterGetName(printer);
        CFRetain(name);
        data.SetPrinterName(wxCFStringRef(name).AsString());
    }
    
    PMDuplexMode mode = 0 ;
    PMGetDuplex(  m_macPrintSettings, &mode ) ;
    switch( mode )
    {
        case kPMDuplexNoTumble :
            data.SetDuplex(wxDUPLEX_HORIZONTAL);
            break ;
        case kPMDuplexTumble :
            data.SetDuplex(wxDUPLEX_VERTICAL);
            break ;
        case kPMDuplexNone :
        default :
            data.SetDuplex(wxDUPLEX_SIMPLEX);
            break ;
    }
    // PMQualityMode not yet accessible via API
    
    double height, width;
    PMPaperGetHeight(m_macPaper, &height);
    PMPaperGetWidth(m_macPaper, &width);

    wxSize sz((int)(width * pt2mm + 0.5 ) ,
         (int)(height * pt2mm + 0.5 ));
    data.SetPaperSize(sz);
    wxPaperSize id = wxThePrintPaperDatabase->GetSize(wxSize(sz.x* 10, sz.y * 10));
    if (id != wxPAPER_NONE)
    {
        data.SetPaperId(id);
    }
    return true ;
}
QVariant QMacPrintEngine::property(PrintEnginePropertyKey key) const
{
    Q_D(const QMacPrintEngine);
    QVariant ret;

    if (!d->session && d->valueCache.contains(key))
        return *d->valueCache.find(key);

    switch (key) {
    case PPK_CollateCopies:
        ret = false;
        break;
    case PPK_ColorMode:
        ret = QPrinter::Color;
        break;
    case PPK_Creator:
        break;
    case PPK_DocumentName:
        break;
    case PPK_FullPage:
        ret = d->fullPage;
        break;
    case PPK_NumberOfCopies:
        ret = 1;
        break;
    case PPK_Orientation:
        PMOrientation orientation;
        PMGetOrientation(d->format, &orientation);
        ret = orientation == kPMPortrait ? QPrinter::Portrait : QPrinter::Landscape;
        break;
    case PPK_OutputFileName:
        ret = d->outputFilename;
        break;
    case PPK_PageOrder:
        break;
    case PPK_PaperSource:
        break;
    case PPK_PageRect: {
        // PageRect is returned in device pixels
        QRect r;
        PMRect macrect, macpaper;
        qreal hRatio = d->resolution.hRes / 72;
        qreal vRatio = d->resolution.vRes / 72;
        if (d->hasCustomPaperSize) {
            r = QRect(0, 0, qRound(d->customSize.width() * hRatio), qRound(d->customSize.height() * vRatio));
            if (d->hasCustomPageMargins) {
                r.adjust(qRound(d->leftMargin * hRatio), qRound(d->topMargin * vRatio), 
                         -qRound(d->rightMargin * hRatio), -qRound(d->bottomMargin * vRatio));
            } else {
                QList<QVariant> margins = property(QPrintEngine::PPK_PageMargins).toList();
                r.adjust(qRound(margins.at(0).toDouble() * hRatio),
                         qRound(margins.at(1).toDouble() * vRatio),
                         -qRound(margins.at(2).toDouble() * hRatio),
                         -qRound(margins.at(3).toDouble()) * vRatio);
            }
        } else if (PMGetAdjustedPageRect(d->format, &macrect) == noErr
                   && PMGetAdjustedPaperRect(d->format, &macpaper) == noErr)
        {
            if (d->fullPage || d->hasCustomPageMargins) {
                r.setCoords(int(macpaper.left * hRatio), int(macpaper.top * vRatio),
                            int(macpaper.right * hRatio), int(macpaper.bottom * vRatio));
                r.translate(-r.x(), -r.y());
                if (d->hasCustomPageMargins) {
                    r.adjust(qRound(d->leftMargin * hRatio), qRound(d->topMargin * vRatio),
                             -qRound(d->rightMargin * hRatio), -qRound(d->bottomMargin * vRatio));
                }
            } else {
                r.setCoords(int(macrect.left * hRatio), int(macrect.top * vRatio),
                            int(macrect.right * hRatio), int(macrect.bottom * vRatio));
                r.translate(int(-macpaper.left * hRatio), int(-macpaper.top * vRatio));
            } 
        }
        ret = r;
        break; }
    case PPK_PaperSize:
        ret = d->paperSize();
        break;
    case PPK_PaperRect: {
        QRect r;
        PMRect macrect;
        if (d->hasCustomPaperSize) {
            r = QRect(0, 0, qRound(d->customSize.width()), qRound(d->customSize.height()));
        } else if (PMGetAdjustedPaperRect(d->format, &macrect) == noErr) {
            qreal hRatio = d->resolution.hRes / 72;
            qreal vRatio = d->resolution.vRes / 72;
            r.setCoords(int(macrect.left * hRatio), int(macrect.top * vRatio),
                        int(macrect.right * hRatio), int(macrect.bottom * vRatio));
            r.translate(-r.x(), -r.y());
        }
        ret = r;
        break; }
    case PPK_PrinterName: {
        CFIndex currIndex;
        PMPrinter unused;
        QCFType<CFArrayRef> printerList;
        OSStatus status = PMSessionCreatePrinterList(d->session, &printerList, &currIndex, &unused);
        if (status != noErr)
            qWarning("QMacPrintEngine::printerName: Problem getting list of printers: %ld", long(status));
        if (currIndex != -1 && printerList && currIndex < CFArrayGetCount(printerList)) {
            const CFStringRef name = static_cast<CFStringRef>(CFArrayGetValueAtIndex(printerList, currIndex));
            if (name)
                ret = QCFString::toQString(name);
        }
        break; }
    case PPK_Resolution: {
        ret = d->resolution.hRes;
        break;
    }
    case PPK_SupportedResolutions:
        ret = d->supportedResolutions();
        break;
    case PPK_CustomPaperSize:
        ret = d->customSize;
        break;
    case PPK_PageMargins:
    {
        QList<QVariant> margins;
        if (d->hasCustomPageMargins) {
            margins << d->leftMargin << d->topMargin
                    << d->rightMargin << d->bottomMargin;
        } else {
            PMPaperMargins paperMargins;
            PMPaper paper;
            PMGetPageFormatPaper(d->format, &paper);
            PMPaperGetMargins(paper, &paperMargins);
            margins << paperMargins.left << paperMargins.top
                    << paperMargins.right << paperMargins.bottom;
        }
        ret = margins;
        break;
    }
    default:
        break;
    }
    return ret;
}
void QMacPrintEngine::setProperty(PrintEnginePropertyKey key, const QVariant &value)
{
    Q_D(QMacPrintEngine);

    d->valueCache.insert(key, value);
    if (!d->session)
        return;

    switch (key) {
    case PPK_CollateCopies:
        break;
    case PPK_ColorMode:
        break;
    case PPK_Creator:
        break;
    case PPK_DocumentName:
        break;
    case PPK_PageOrder:
        break;
    case PPK_PaperSource:
        break;
    case PPK_SelectionOption:
        break;
    case PPK_Resolution:  {
        PMPrinter printer;
        UInt32 count;
        if (PMSessionGetCurrentPrinter(d->session, &printer) != noErr)
            break;
        if (PMPrinterGetPrinterResolutionCount(printer, &count) != noErr)
            break;
        PMResolution resolution = { 0.0, 0.0 };
        PMResolution bestResolution = { 0.0, 0.0 };
        int dpi = value.toInt();
        int bestDistance = INT_MAX;
        for (UInt32 i = 1; i <= count; ++i) {  // Yes, it starts at 1
            if (PMPrinterGetIndexedPrinterResolution(printer, i, &resolution) == noErr) {
                if (dpi == int(resolution.hRes)) {
                    bestResolution = resolution;
                    break;
                } else {
                    int distance = qAbs(dpi - int(resolution.hRes));
                    if (distance < bestDistance) {
                        bestDistance = distance;
                        bestResolution = resolution;
                    }
                }
            }
        }
        PMSessionValidatePageFormat(d->session, d->format, kPMDontWantBoolean);
        break;
    }

    case PPK_FullPage:
        d->fullPage = value.toBool();
        break;
    case PPK_NumberOfCopies:
        PMSetCopies(d->settings, value.toInt(), false);
        break;
    case PPK_Orientation: {
        if (d->state == QPrinter::Active) {
            qWarning("QMacPrintEngine::setOrientation: Orientation cannot be changed during a print job, ignoring change");
        } else {
            QPrinter::Orientation newOrientation = QPrinter::Orientation(value.toInt());
            if (d->hasCustomPaperSize && (d->orient != newOrientation))
                d->customSize = QSizeF(d->customSize.height(), d->customSize.width());
            d->orient = newOrientation;
            PMOrientation o = d->orient == QPrinter::Portrait ? kPMPortrait : kPMLandscape;
            PMSetOrientation(d->format, o, false);
            PMSessionValidatePageFormat(d->session, d->format, kPMDontWantBoolean);
        }
        break; }
    case PPK_OutputFileName:
        d->outputFilename = value.toString();
        break;
    case PPK_PaperSize:
        d->setPaperSize(QPrinter::PaperSize(value.toInt()));
        break;
    case PPK_PrinterName: {
        OSStatus status = noErr;
        QCFType<CFArrayRef> printerList;
        status = PMServerCreatePrinterList(kPMServerLocal, &printerList);
        if (status == noErr) {
            CFIndex count = CFArrayGetCount(printerList);
            for (CFIndex i=0; i<count; ++i) {
                PMPrinter printer = static_cast<PMPrinter>(const_cast<void *>(CFArrayGetValueAtIndex(printerList, i)));
                QString name = QCFString::toQString(PMPrinterGetName(printer));
                if (name == value.toString()) {
                    status = PMSessionSetCurrentPMPrinter(d->session, printer);
                    break;
                }
            }
        }
        if (status != noErr)
            qWarning("QMacPrintEngine::setPrinterName: Error setting printer: %ld", long(status));
        break; }
    case PPK_SuppressSystemPrintStatus:
        d->suppressStatus = value.toBool();
        break;
    case PPK_CustomPaperSize:
    {
        PMOrientation orientation;
        PMGetOrientation(d->format, &orientation);
        d->hasCustomPaperSize = true;
        d->customSize = value.toSizeF();
        if (orientation != kPMPortrait)
            d->customSize = QSizeF(d->customSize.height(), d->customSize.width());
        break;
    }
    case PPK_PageMargins:
    {
        QList<QVariant> margins(value.toList());
        Q_ASSERT(margins.size() == 4);
        d->leftMargin = margins.at(0).toDouble();
        d->topMargin = margins.at(1).toDouble();
        d->rightMargin = margins.at(2).toDouble();
        d->bottomMargin = margins.at(3).toDouble();
        d->hasCustomPageMargins = true;
        break;
    }

    default:
        break;
    }
}
Beispiel #9
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;
}