Printing PDF Files on Mac OS X and Linux

Mac OS X includes built-in support for printing PDF files. Modern versions of Linux (with CUPS) also include PDF printing support. This page provides sample code for printing PDF files on these two systems.

For Windows (which does not have built-in PDF support), we recommend our XpdfPrint software.

Printing PDF files on Mac OS X

The following code uses Core Printing and CGPDFDocument (from Core Graphics) to print PDF files. It uses all of the default settings for the specified printer, and prints all pages of the PDF file.

#include <CoreFoundation/CoreFoundation.h> #include <ApplicationServices/ApplicationServices.h> bool printPDF(const char *pdfFileName, const char *printerName) { CFStringRef s; CFURLRef url; CGPDFDocumentRef pdfDoc; CGPDFPageRef pdfPage; PMPrintSession session; PMPrintSettings printSettings; CFArrayRef printerList; PMPrinter printer; char prtName[512]; PMPageFormat pageFormat; CGContextRef ctx; int nPages, pg, i; //--- load the PDF file s = CFStringCreateWithCString(NULL, pdfFileName, kCFStringEncodingUTF8); url = CFURLCreateWithFileSystemPath(NULL, s, kCFURLPOSIXPathStyle, false); CFRelease(s); pdfDoc = CGPDFDocumentCreateWithURL(url); CFRelease(url); if (!pdfDoc) { return false; } //--- create the Session and PrintSettings if (PMCreateSession(&session)) { CFRelease(pdfDoc); return false; } if (PMCreatePrintSettings(&printSettings)) { PMRelease(session); CFRelease(pdfDoc); return false; } if (PMSessionDefaultPrintSettings(session, printSettings)) { PMRelease(printSettings); PMRelease(session); CFRelease(pdfDoc); return false; } s = CFStringCreateWithCString(NULL, pdfFileName, kCFStringEncodingUTF8); PMPrintSettingsSetJobName(printSettings, s); CFRelease(s); //--- set the printer if (PMServerCreatePrinterList(kPMServerLocal, &printerList)) { PMRelease(printSettings); PMRelease(session); CFRelease(pdfDoc); return false; } printer = NULL; for (i = 0; i < CFArrayGetCount(printerList); ++i) { printer = (PMPrinter)CFArrayGetValueAtIndex(printerList, i); s = PMPrinterGetName(printer); if (CFStringGetCString(s, prtName, sizeof(prtName), kCFStringEncodingUTF8)) { if (!strcmp(prtName, printerName)) { break; } } } if (i >= CFArrayGetCount(printerList)) { CFRelease(printerList); PMRelease(printSettings); PMRelease(session); CFRelease(pdfDoc); return false; } if (PMSessionSetCurrentPMPrinter(session, printer)) { CFRelease(printerList); PMRelease(printSettings); PMRelease(session); CFRelease(pdfDoc); return false; } CFRelease(printerList); //--- get the PageFormat if (PMCreatePageFormat(&pageFormat)) { PMRelease(printSettings); PMRelease(session); CFRelease(pdfDoc); return false; } if (PMSessionDefaultPageFormat(session, pageFormat)) { PMRelease(pageFormat); PMRelease(printSettings); PMRelease(session); CFRelease(pdfDoc); return false; } //--- print nPages = CGPDFDocumentGetNumberOfPages(pdfDoc); if (PMSetPageRange(printSettings, 1, nPages)) { PMRelease(pageFormat); PMRelease(printSettings); PMRelease(session); CFRelease(pdfDoc); return false; } if (PMSessionBeginCGDocumentNoDialog(session, printSettings, pageFormat)) { PMRelease(pageFormat); PMRelease(printSettings); PMRelease(session); CFRelease(pdfDoc); return false; } for (pg = 1; pg <= nPages; ++pg) { if (PMSessionBeginPageNoDialog(session, pageFormat, NULL) || PMSessionGetCGGraphicsContext(session, &ctx) || !(pdfPage = CGPDFDocumentGetPage(pdfDoc, pg))) { PMSessionEndDocumentNoDialog(session); PMRelease(pageFormat); PMRelease(printSettings); PMRelease(session); CFRelease(pdfDoc); return false; } CGContextDrawPDFPage(ctx, pdfPage); if (PMSessionEndPageNoDialog(session)) { PMSessionEndDocumentNoDialog(session); PMRelease(pageFormat); PMRelease(printSettings); PMRelease(session); CFRelease(pdfDoc); return false; } } PMSessionEndDocumentNoDialog(session); PMRelease(pageFormat); PMRelease(printSettings); PMRelease(session); CFRelease(pdfDoc); return true; }

Printing PDF files on Linux

The following code uses the CUPS API to print PDF files. It uses all of the default settings for the specified printer, and prints all pages of the PDF file.

#include <cups/cups.h> bool printPDF(const char *pdfFileName, const char *printerName) { return cupsPrintFile(printerName, pdfFileName, pdfFileName, 0, NULL) != 0; }