README - OpenPrinting CUPS Filters v1.0.43 - 2013-12-19 ------------------------------------------------------- Looking for compile instructions? Read the file "INSTALL.txt" instead... INTRODUCTION CUPS is a standards-based, open source printing system developed by Apple Inc. for Mac OS® X and other UNIX®-like operating systems. CUPS uses the Internet Printing Protocol ("IPP") and provides System V and Berkeley command-line interfaces, a web interface, and a C API to manage printers and print jobs. This distribution contains backends, filters, and other software that was once part of the core CUPS distribution but is no longer maintained by Apple Inc. In addition it contains additional filters and software developed independently of Apple, especially filters for the PDF-centric printing workflow introduced by OpenPrinting and a daemon to browse Bonjour broadcasts of remote CUPS printers and makes these printers available locally. From CUPS 1.6.0 on, this package is required for using printer drivers with CUPS under Linux. With CUPS 1.5.x and earlier this package can be used optionally to switch over to PDF-based printing. In that case some filters are provided by both CUPS and this package. Then the filters of this package should be used. For compiling and using this package CUPS, Poppler, libjpeg, libpng, libtiff, libijs, freetype, fontconfig, liblcms (liblcms2 recommended), libavahi-common, and libavahi-client are needed. It is highly recommended, especially if non-PostScript printers are used, to have Ghostscript, foomatic-filters, and foomatic-db installed. CUPS, this package, and Ghostscript contain some rudimentary printer drivers, see http://www.openprinting.org/drivers/ for a more comprehensive set of printer drivers for Linux. See http://www.linuxfoundation.org/collaborate/workgroups/openprinting/pdf_as_standard_print_job_format for information about the PDF-based printing workflow. Report bugs to https://bugs.linuxfoundation.org/ Choose "OpenPrinting" as the product and "cups-filters" as the component. See the "LICENSE.txt" files for legal information. IMAGE PRINTING DEFAULT CHANGED TO "SCALE TO FIT" Compared to the PostScript-based original CUPS filters there is a change of defaults: The imagetopdf and imagetoraster filters print in "scale-to-fit" mode (image is scaled to fill one page but nothing of the image being cut off) by default. This is done to support photo printing via AirPrint. The photo apps on Apple's iOS devices send print jobs as JPEG images and do not allow to set any options like "scaling" or the page size. With "scale-to-fit" mode set by default, the iOS photos come out on one page, as expected. To get back to the old behavior, supply one of the options "nofitplot" "filplot=Off", "nofit-to-page", or "fit-to-page=Off". POSTSCRIPT PRINTING RENDERER AND RESOLUTION SELECTION If you use CUPS with this package and a PostScript printer then the included pdftops filter converts the print job data which is in PDF format into PostScript. By default, the PostScript is generated with Ghostscript's "ps2write" output device, which generates a DSC-conforming PostScript with compressed embedded fonts and compressed page content. This is resource-saving and leads to fast wire transfer of print jobs to the printer. Unfortunately, Ghostscript's PostScript output is not compatible with some printers due to interpreter bugs in the printer and in addition, processing (by Ghostscript or by the printer's interpreter) can get very slow with high printing resolutions when parts of the incoming PDF file are converted to bitmaps if they contain graphical structures which are not supported by PostScript. The bitmap problem especially occurs on input files with transparency, especially also the ones produced by Cairo (evince and many other GNOME/GTK applications) which unnecessarily introduces transparency even if the input PDF has no transparency. Therefore there are two possibilities to configure pdftops at runtime: 1. Selection of the renderer: Ghostscript, Poppler, pdftocairo, or Adobe Reader Ghostscript has better color management and is generally optimized more for printing. Poppler produces a PostScript which is compatible with more buggy built-in PostScript interpreters of printers and it leads to a somewhat quicker workflow when graphical structures of the input PDF has to be turned into bitmaps. Adobe Reader is the PDF renderer from Adobe, the ones who created PDF and PostScript. pdftocairo is a good choice for the PDF output of Cairo (for example when printing from evince). It is less resource-consuming when rasterizing graphical elements which cannot be represented in PostScript (like transparency). Note that pdftocairo only supports PDF input using DeviceRGB, DeviceGray, RGB or sGray and is not capable of generating PostScript level 1. So its support is only experimental and distributions should not choose it as default. The selection is done by the "pdftops-renderer" option, setting it to "gs", "pdftops", "pdftocairo", or "acroread": Per-job: lpr -o pdftops-renderer=pdftops ... Per-queue default: lpadmin -p printer -o pdftops-renderer-default=gs Remove default: lpadmin -p printer -R pdftops-renderer-default By default, pdftops uses Ghostscript if this does not get changed at compile time, for example by the Linux distribution vendor. 2. Limitation of the image rendering resolution If graphical structures of the incoming PDF file have to be converted to bitmaps due to limitations of PostScript, the conversion of the file by pdftops or the rendering by the printer can get too slow if the bitmap resolution is too high or the printout quality can degrade if the bitmap resolution is too low. By default, pdftops tries to find out the actual printing resolution and sets the resolution for bitmap generation to the same value. If it cannot find the printing resolution, it uses 300 dpi. It never goes higher than a limit of 1440 dpi. Note that this default limit can get changed at compile time, for example by the Linux distribution vendor. The resolution limit for bitmaps can be changed to a lower or higher value, or be set to unlimited. This is done by the option "pdftops-max-image-resolution", setting it to the desired value (in dpi) or to zero for unlimited. It can be used per-job or as per-queue default as the "pdftops-renderer" option described above. The "pdftops-max-image-resolution" option is ignored when Adobe Reader is selected as PDF renderer. POSTSCRIPT PRINTING DEBUG MODE Sometimes a PostScript printer's interpreter errors, crashes, or somehow else misbehaves on Ghostscript's output. To find workarounds (currently we have already workarounds for Brother and Kyocera) it is much easier to work with uncompressed PostScript. To get uncompressed PostScript as output, send a job with the "psdebug" option, with commands like the following: lpr -P <printer> -o psdebug <file> lp -d <printer> -o psdebug <file> If you want to send your job out of a desktop application, run lpoptions -p <printer> -o psdebug to make "psdebug" a personal default setting for you. To extract the PostScript output for a developer to analyse it, clone your print queue to a one which prints into a file: cupsctl FileDevice=yes lpadmin -p test -E -v file:/tmp/printout \ -P /etc/cups/ppd/<name of original queue>.ppd and print into this queue as described above. The PostScript output is in /tmp/printout after the job has completed. This option does not change anything if Poppler's pdftops is used as renderer. HELPER DAEMON FOR BROWSING REMOTE CUPS PRINTERS AND IPP NETWORK PRINTERS From version 1.6.0 on in CUPS the CUPS broadcasting/browsing facility was dropped, in favour of Bonjour-based broadcasting of shared printers. This is done as Bonjour broadcasting of shared printers is a standard, established by the PWG (Printing Working Group, http://www.pwg.org/), and most other network services (shared file systems, shared media files/streams, remote desktop services, ...) are also broadcasted via Bonjour. Problem is that CUPS only broadcasts its shared printers but does not browse broadcasts of other CUPS servers to make the shared remote printers available locally without any configuration efforts. This is a regression compared to the old CUPS broadcasting/browsing. The intention of CUPS upstream is that the application's print dialogs browse the Bonjour broadcasts as an AirPrint-capable iPhone does, but it will take its time until all toolkit developers add the needed functionality, and programs using old toolkits or no toolkits at all, or the command line stay uncovered. The solution is cups-browsed, a helper daemon running in parallel to the CUPS daemon which listens to Bonjour broadcasts of shared CUPS printers on remote machines in the local network via Avahi, and can also listen for (and send) CUPS Browsing broadcasts. For each reported remote printer it creates a local raw queue pointing to the remote printer so that the printer appears in local print dialogs and is also available for printing via the command line. As with the former CUPS broadcasting/browsing with this queue the driver on the server is used and the local print dialogs give access to all options of the server-side printer driver. Note that CUPS broadcasting/browsing is available for legacy support, to let the local CUPS daemon work seamlessly together with remote CUPS daemons of version 1.5.x and older which only support CUPS broadcasting/browsing. In networks with only CUPS 1.6.x servers (or Ubuntu or Fedora/Red Hat servers with CUPS 1.5.x) please use the native Bonjour broadcasting of your servers and cups-browsed, configured for Bonjour browsing only on the clients. Also high availability with redundant print servers is supported. If there is more than one server providing a shared print queue with the same name, cups-browsed uses the first queue which appeared and if this queue disappears, cups-browsed seamlessly switches to the queue of another server. Unfortunately, load-balancing (what CUPS did via implicit classes) is not possible with cups-browsed. For maximum security cups-browsed uses IPPS (encrypted IPP) whenever possible. In addition, cups-browsed is also capable of discovering IPP network printers (native printers, not CUPS queues) with known page description languages (PWG Raster, PDF, PostScript, PCL XL, PCL 5c/e) in the local network and auto-create PPD-less print queues for them (using a System V interface script to control the filter chain). Clients have to IPP-poll the capabilities of the printer and send option settings as standard IPP attributes. We do not poll the capabilities by ourselves to not wake up the printer from power-saving mode when creating the queues. Jobs have to be sent in PDF format. Other formats are not accepted. This functionality is primarily for mobile devices running CUPS to not need a printer setup tool nor a collection of printer drivers and PPDs. The configuration file for cups-browsed is /etc/cups/cups-browsed.conf. This file can include limited forms of the original CUPS BrowseRemoteProtocols, BrowseLocalProtocols, BrowsePoll, and BrowseAllow directives. It also can contain the new CreateIPPPrinterQueues to activate discovering of IPP network printers and creating PPD-less queues for them. Note that cups-browsed does not work with remote CUPS servers specified by a client.conf file. It always connects to the local CUPS daemon by setting the CUPS_SERVER environment variable and so overriding client.conf. If your local CUPS daemon uses a non-standard domain socket as only way of access, you need to specify it via the DomainSocket directive in /etc/cups/cups-browsed.conf. The "make install" process installs init scripts which make the daemon automatically started during boot. You can also manually start it with (as root): /usr/sbin/cups-browsed & or in debug mode with /usr/sbin/cups-browsed --debug Shut it down by sending signal 2 (SIGINT) or 15 (SIGTERM) to it. The queues which it has created get removed then (except a queue set as system default, to not loose its system default state). Make sure that cups-browsed gets started after avahi-daemon, so that the Bonjour/DNS-SD browsing works. On systems using systemd use a /usr/lib/systemd/system/cups-browsed.service file like this: [Unit] Description=Make remote CUPS printers available locally After=cups.service avahi-daemon.service Wants=cups.service avahi-daemon.service [Service] ExecStart=/usr/sbin/cups-browsed [Install] WantedBy=multi-user.target On systems using Upstart use an /etc/init/cups-browsed.conf file like this: start on (filesystem and started avahi-daemon and (started cups or runlevel [2345])) stop on runlevel [016] respawn respawn limit 3 240 pre-start script [ -x /usr/sbin/cups-browsed ] end script exec /usr/sbin/cups-browsed These files are included in the source distribution as utils/cups-browsed.service and utils/cups-browsed-upstart.conf. Here is some info on how cups-browsed works internally (first concept of a daemon which does only Bonjour browsing): - Daemon start o Wait for CUPS daemon if it is not running o Read out all CUPS queues created by this daemon (in former sessions) o Mark them unconfirmed and set timeout 10 sec from now - Main loop (use avahi_simple_poll_iterate() to do queue list maintenance regularly) o Event: New printer shows up + Queue for printer is already created by this daemon -> Mark list entry confirmed, if discovered printer is ipps but existing queue ipp, upgrade existing queue by setting URI to ipps. Set status to to-be-created and timeout to now-1 sec to make the CUPS queue be updated. + Queue does not yet exist -> Mark as to-be-created and set timeout to now-1 sec. o Event: A printer disappears + If we have listed a queue for it, mark the entry as disappeared, set timeout to now-1 sec o On any of the above events and every 2 sec + Check through list of our listed queues - If queue is unconfirmed and timeout has passed, mark it as disappeared, set timeout to now-1 sec - If queue is marked disappered and timeout has passed, check whether there are still jobs in it, if yes, set timeout to 10 sec from now, if no, remove the CUPS queue and the queue entry in our list. If removal fails, set timeout to 10 sec. - If queue is to-be-created, create it, if succeeded set to confirmed, if not, set timeout to 10 sec fron now. printer-is-shared must be set to false. - Daemon shutdown o Remove all CUPS queues in our list, as long as they do not have jobs. Do not overwrite existing queues which are not created by us If the simple <remote_printer> name is already taken, try to create a <remote_printer>@<server> name, if this is also taken, ignore the remote printer. Do not retry, to avoid polling CUPS all the time. Do not remove queues which are not created by us. We do this by listing only our queues and remove only listed queues. Queue names: Use the name of the remote queue. If a queue with the same name from another server already exists, mark the new queue as duplicate and when a queue disappears, check whether it has duplicates and change the URI of the disappeared queue to the URI of the first duplicate, mark the queue as to-be-created with timeout now-1 sec (to update the URI of the CUPS queue) and mark the duplicate ddisappeared with timeout now-1 sec. In terms of high availability we replace the old load balancing of the implicit class by a failover solution. Alternatively (not implemented), if queue with same name but from other server appears, create new queue as <original name>@<server name without .local>. When queue with simple name is removed, replace the first of the others by one with simple name (mark old queue disappeared with timeout now-1 sec and create new queue with simple name). Fill description of the created CUPS queue with the Bonjour service name (= original description) and location with the server name without .local. stderr messages only in debug mode (command line options: "--debug" or "-d" or "-v"). Queue identified as from this daemon by doing the equivalent of "lpadmin -p printer -o cups-browsed-default", this generates a "cups-browsed" attribute in printers.conf with value "true". CUPS FILTERS FOR PDF AS STANDARD PRINT JOB FORMAT Here is documentation from the former CUPS add-on tarball with the filters for the PDF-based printing workflow: imagetopdf, texttopdf, pdftopdf, pdftoraster, pdftoopvp, and pdftoijs The original filters are from http://sourceforge.jp/projects/opfc/ NOTE: the texttops and imagetops filters shipping with this package are simple wrapper scripts for backward compatibility with third-party PPD files and custom configurations. There are not referred to in the cupsfilters.convs file and therefore not used by the default configuration. Direct conversion of text or images to PostScript is deprecated in the PDF-based printing workflow. So do not use these filters when creating new PPDs or custom configurations. The parameters for these filters are the same as for texttopdf and imagetopdf (see below) as the ...tops filter calls the ....topdf filter plus Ghostscript's pdf2ps. IMAGETOPDF ========== 1. INTRODUCTION This program is "imagetopdf". "imagetopdf" is a CUPS filter which reads a single image file, converts it into a PDF file and outputs it to stdout. This program accepts the following image file format; gif, png, jpeg, tiff, photocd, portable-anymap, portable-bitmap, portable-graymap, portable-pixmap, sgi-rgb, sun-raster, xbitmap, xpixmap, xwindowdump xbitmap, xpixmap and xwindowdump images are converted into png images by the "convert" command. Other kinds of image file format can be supported if the "convert" command support them. Output PDF file format conforms to PDF version 1.3 specification, and input image is converted and contained in the output PDF file as a binary format non-compression image. "imagetopdf" may outputs multiple pages if the input image exceeds page printable area. 2. LICENSE "imagetopdf.c" is under the CUPS license. See the "LICENSE.txt" file. For other files, see the copyright notice and license of each file. 3. COMMAND LINE "imagetopdf" is a CUPS filter, and the command line arguments, environment variables and configuration files are in accordance with the CUPS filter interface. imagetopdf <job> <user> <title> <num-copies> <options> [<filename>] "imagetopdf" ignores <job> and <user>. <title> is appended into the PDF dictionary as /Title. <num-copies> specifies the number of document copies. <options> is a CUPS option list. <filename> is an input image file name. When omit the <filename>, "imagetopdf" reads an image file from stdin. 4. ENVIRONMENT VARIABLES This program refers the following environment variable; PPD: PPD file name of the printer. 5. COMMAND OPTIONS "imagetopdf" accepts the following CUPS standard options; fitplot mirror PageSize page-left, page-right, page-bottom, page-top OutputOrder Collate sides cupsEvenDuplex position scaling ppi natural-scaling landscape orientation-requested See the CUPS documents for details of these options. 6. KNOWN PROBLEMS Problem: PBM and SUN raster images can not be printed. Solution: Due to the CUPS libcupsimage library's bug. Update the CUPS on your system. 7. INFORMATION FOR DEVELOPERS Following information is for developers, not for driver users. 7.1 Options handled by a printer or "imagetopdf" Following options are handled by a printer or "imagetopdf". Collate, Copies, Duplex, OutputOrder Which handles these options depends on following options and attributes. Collate, Copies, Duplex, OutputOrder, cupsEvenDuplex, cupsManualCopies "imagetopdf" judges whether a printer can handle these options according to the followings option settings in a PPD file. Collate: If Collate is defined, "imagetopdf" judges the printer supports Collate. Copies: If cupsManualCopies is defined as True, "imagetopdf" judges the printer does not support Copies feature. Duplex: If Duplex is defined, "imagetopdf" judges the printer supports Duplex. If cupsEvenDuplex is True, Number of pages must be even. OutputOrder: If OutputOrder is defined, "imagetopdf" judges the printer supports OutputOrder. If the printer cannot handle these options, "imagetopdf" handles it. Following pseudo program describes how "imagetopdf" judges to handle these options. Variables Copies : specified Copies Duplex : specified Duplex Collate : specified Collate OutputOrder : specified OutputOrder EvenDuplex : specified cupsEvenDuplex pages : number of pages number_up : specified number-up device_copies : Copies passed to the printer device_duplex : Duplex passed to the printer device_collate : Collate passed to the printer device_outputorder : OutputOrder passed to the printer soft_copies : copies by imagetopdf device_copies = 1; device_duplex = False; device_collate = False; device_outputorder = False; if (Copies == 1) { /* Collate is not needed. */ Collate = False; } if (!Duplex) { /* EvenDuplex is not needed */ EvenDuplex = False; } if (Copies > 1 && the printer can handle Copies) device_copies = Copies; if (Duplex && the printer can handle Duplex) { device_duplex = True; } else { /* imagetopdf cannot handle Duplex */ } if (Collate && the printer can handle Collate) device_collate = True; if (OutputOrder == Reverse && the printer can handle OutputOrder) device_outputorder = True; if (Collate && !device_collate) { /* The printer cannot handle Collate. So imagetopdf handle Copies */ device_copies = 1; } if (device_copies != Copies /* imagetopdf handle Copies */ && Duplex) /* Make imagetopdf handle Collate, otherwise both paper side may have same page */ Collate = True; device_collate = False; } if (Duplex && Collate && !device_collate) { /* Handle EvenDuplex, otherwise the last page has the next copy's first page in the other side of the paper. */ EvenDuplex = True; } if (Duplex && OutputOrder == Reverse && !device_outputorder) { /* Handle EvenDuplex, otherwise the first page's other side of paper is empty. */ EvenDuplex = True; } soft_copies = device_copies > 1 ? 1 : Copies; 7.2 JCL When you print PDF files to a PostScript(PS) printer, you can specify device options in PS. In this case, you can write PS commands in a PPD file like as follows. *OpenUI *Resolution/Resolution : PickOne *DefaultResolution: 600 *Resolution 300/300 dpi: "<</HWResolution[300 300]>>setpagedevice" *Resolution 600/600 dpi: "<</HWResolution[600 600]>>setpagedevice" *CloseUI: *Resolution However, if options cannot be described in PS file, you can write JCLs as follows; *JCLOpenUI *JCLFrameBufferSize/Frame Buffer Size: PickOne *DefaultJCLFrameBufferSize: Letter *OrderDependency: 20 JCLSetup *JCLFrameBufferSize *JCLFrameBufferSize Off: '@PJL SET PAGEPROTECT = OFF<0A>' *JCLFrameBufferSize Letter: '@PJL SET PAGEPROTECT = LTR<0A>' *JCLFrameBufferSize Legal: '@PJL SET PAGEPROTECT = LGL<0A>' *JCLCloseUI: *JCLFrameBufferSize Because PDF cannot specify device options in a PDF file, you have to define all the device options as JCLs. When a printer does not support PS nor PDF, you can use Ghostscript (GS). In this case, you can specify device options like a PS printer. If you want to use the same printer and same PPD file for both PDF and PS printing, when you print a PS file, you can specify that GS handles it, and when you print a PDF file, you can also specify that PDF filters handle it in the same PPD file. However in this case, previous methods is not appropriate to specify device options. So, "imagetopdf" handles this case as follows; (In following pseudo program, JCL option is an option specified with JCLOpenUI) if (Both JCLBegin and JCLToPSInterpreter are specified in the PPD file) { output JCLs that marked JCL options. } if (pdftopdfJCLBegin attribute is specified in the PPD file) { output it's value } if (Copies option is specified in the PPD file) { mark Number of copies specified } else if (pdftopdfJCLCopies is specified in the PPD file) { output JCL specified with JCLCopies } for (each marked options) { if (pdftopdfJCL<marked option's name> is specified in the PPD file) { output it's value as a JCL } else if (pdftopdfJCLBegin attributes is specified in the PPD file) { output "<option's name>=<marked choice>;" as a JCL } } output NEWLINE Thus, if you want to use both PDF filters and GS by single PPD file, what you should do is to add the following line in the PPD file; *pdftopdfJCLBegin: "pdftoopvp jobInfo:" Note: If you specify JCLBegin, you have to specify JCLToPSInterpreter as well. Note: When you need to specify the value which is different from the choosen value based on the PPD into the jobInfo, you have to specify the values with the key started by "pdftopdfJCL" string. For example, if the page size is defined in a PPD file as following; *OpenUI *PageSize/Page Size: PickOne *DefaultPageSize: A4 *PageSize A4/A4: *PageSize Letter/US Letter: *CloseUI: *PageSize if you choose the page size "Letter", the string "PageSize=Letter;" is added to jobInfo. On the other hand, if the driver requires the different value for the "Letter" size, for instance driver requires "PS=LT;" instead of "PageSize=Letter;" as the jobInfo value, the PPD file has to be defined as following; *OpenUI *PageSize/Page Size: PickOne *DefaultPageSize: A4 *PageSize A4/A4: *pdftopdfJCLPageSize A4/A4: "PS=A4;" *PageSize Letter/US Letter: *pdftopdfJCLPageSize Letter/US Letter: "PS=LT;" *CloseUI: *PageSize 7.3 Temporally files location "imagetopdf" creates temporally files if needed. Temporary files are created in the location specified by TMPDIR environment variable. Default location is "/tmp". PDFTOPDF (OLD) ============== 0. DEPRECATION NOTICE This filter is being replaced by a new implementation that does not depend on poppler. Therefore it has been renamed "pdftopdf.old", but the references in the following sections have not been updated. 1. INTRODUCTION There are two executable programs, "pdftopdf" and "pdf2pdf", in this package. "pdftopdf" is a filter for CUPS. It reads PDF files, changes page layout and output a new PDF file. "pdf2pdf" is a user command version of "pdftopdf". This document describes about only "pdftopdf". See man/pdf2pdf.1 for "pdf2pdf". When a input PDF file which is given to "pdftopdf" does not include some required fonts, and if you set the font embedding option, "pdftopdf" embed fonts in the new PDF file "pdftopdf" finds fonts to embed by fontconfig library. "pdftopdf" now embed only TrueType format fonts. PDF Standard fonts are not embedded. Note: Do not embed fonts that the font licenses inhibit embedding. "pdftopdf" does not support functions that are not related to printing features, including interactive features and document interchange features. Many of these operators and sections are just ignored. Some of these may be output, but those functions are not assured. Encryption feature is not supported. 2. NATIVE PDF PRINTER SUPPORT pdftopdf introduces native PDF printer support to CUPS for the first time. PPD files must have a line *cupsFilter: "application/vnd.cups-pdf 0 -" and use the "*JCLToPDFInterpreter:" keyword, for example: *JCLBegin: "<1B>%-12345X@PJL JOB<0A>" *JCLToPDFInterpreter: "@PJL ENTER LANGUAGE = PDF <0A>" *JCLEnd: "<1B>%-12345X@PJL EOJ <0A><1B>%-12345X" They MUST NOT accept PostScript as input data format and will not work with stock CUPS. They will need cups-filters (which implements the PDF- based printing workflow) to work. Options must not be implemented by specifying PostScript code to inject. They must be injecting JCL code ("*JCLOpenUI: ... ... *JCLCloseUI: ..."). A sample PPD file, HP-Color_LaserJet_CM3530_MFP-PDF.ppd is included. 3. LICENSE Almost all source files are under MIT like license. However, "pdftopdf" links some "poppler" libraries, and these files are under GNU public license. See copyright notice of each file for details. 4. COMMAND LINE "pdftopdf" is a CUPS filter, and the command line arguments, environment variables and configuration files are in accordance with the CUPS filter interface. pdftopdf <job> <user> <title> <num-copies> <options> [<filename>] "pdftopdf" ignores <job> and <user>. <title> is appended into the PDF dictionary as /Title. <num-copies> specifies the number of document copies. <options> is a CUPS option list. <filename> is an input PDF file name. When omit the <filename>, "pdftopdf" reads a PDF file from stdin, and save it as a temporary file. CUPS options defined in <options> are delimited by space. Boolean type CUPS option is defined only by the option key, and other type CUPS option are defined by pairs of key and value, <key>=<value>. 5. COMMAND OPTIONS "pdftopdf" accepts the following CUPS standard options; fitplot mirror PageSize page-left, page-right, page-bottom, page-top number-up number-up-layout page-border OutputOrder page-set page-ranges Collate sides cupsEvenDuplex See the CUPS documents for details of these options. Margin given by the page-left, page-right, page-bottom and page-top is valid when fiplot or number-up option is set. "pdftopdf" accepts the following original options; pdftopdfFontEmbedding Boolean option. Force "pdftopdf" to embed fonts. "pdftopdf" does not embed fonts by default. pdftopdfFontEmbeddingWhole Boolean option. Force "pdftopdf" to embed whole fonts. "pdftopdf" does not embed whole fonts by default. If this option is false, "pdftopdf" embed subset of the fonts. This option is valid only when the pdftopdfFontEmbedding option is true. pdftopdfFontEmbeddingPreLoad Boolean option. Force "pdftopdf" to embed fonts specified as pre-loaded fonts in a PPD file. "pdftopdf" does not embed pre-loaded fonts by default. If this option is false, pdftopdf does not embed pre-loaded fonts. This option is valid only when the pdftopdfFontEmbedding option is true. pdftopdfFontCompress Boolean option. Force "pdftopdf" to compress embed fonts. "pdftopdf" does not compress embed fonts by default. This option is valid only when the pdftopdfFontEmbedding option is true. pdftopdfContentsCompress Boolean option. Force "pdftopdf" to compress page contents. "pdftopdf" does not compress page contents by default. pdftopdfJCLBegin Boolean option. Force "pdftopdf" to create JCL info for the following PDF filter "pdftoopvp". 6. INFORMATION FOR DEVELOPERS Following information is for developers, not for driver users. 6.1 Options handled by a printer or "pdftopdf" Following options are handled by a printer or "pdftopdf". Collate, Copies, Duplex, OutputOrder Which handles these options depends on following options and attributes. Collate, Copies, Duplex, OutputOrder, cupsEvenDuplex, cupsManualCopies "pdftopdf" judges whether a printer can handle these options according to the followings option settings in a PPD file. Collate: If Collate is defined, "pdftopdf" judges the printer supports Collate. Copies: If cupsManualCopies is defined as True, "pdftopdf" judges the printer does not support Copies feature. Duplex: If Duplex is defined, "pdftopdf" judges the printer supports Duplex. If cupsEvenDuplex is True, Number of pages must be even. OutputOrder: If OutputOrder is defined, "pdftopdf" judges the printer supports OutputOrder. If the printer cannot handle these options, "pdftopdf" handles it. Following pseudo program describes how "pdftopdf" judges to handle these options. Variables Copies : specified Copies Duplex : specified Duplex Collate : specified Collate OutputOrder : specified OutputOrder EvenDuplex : specified cupsEvenDuplex pages : number of pages number_up : specified number-up device_copies : Copies passed to the printer device_duplex : Duplex passed to the printer device_collate : Collate passed to the printer device_outputorder : OutputOrder passed to the printer soft_copies : copies by pdftopdf device_copies = 1; device_duplex = False; device_collate = False; device_outputorder = False; if (Copies == 1) { /* Collate is not needed. */ Collate = False; } if (!Duplex) { /* EvenDuplex is not needed */ EvenDuplex = False; } if (Copies > 1 && the printer can handle Copies) device_copies = Copies; if (Duplex && the printer can handle Duplex) { device_duplex = True; } else { /* pdftopdf cannot handle Duplex */ } if (Collate && the printer can handle Collate) device_collate = True; if (OutputOrder == Reverse && the printer can handle OutputOrder) device_outputorder = True; if (Collate && !device_collate) { /* The printer cannot handle Collate. So pdftopdf handle Copies */ device_copies = 1; } if (device_copies != Copies /* pdftopdf handle Copies */ && Duplex) /* Make pdftopdf handle Collate, otherwise both paper side may have same page */ Collate = True; device_collate = False; } if (Duplex && Collate && !device_collate) { /* Handle EvenDuplex, otherwise the last page has the next copy's first page in the other side of the paper. */ EvenDuplex = True; } if (Duplex && OutputOrder == Reverse && !device_outputorder) { /* Handle EvenDuplex, otherwise the first page's other side of paper is empty. */ EvenDuplex = True; } soft_copies = device_copies > 1 ? 1 : Copies; 6.2 JCL When you print PDF files to a PostScript(PS) printer, you can specify device options in PS. In this case, you can write PS commands in a PPD file like as follows. *OpenUI *Resolution/Resolution : PickOne *DefaultResolution: 600 *Resolution 300/300 dpi: "<</HWResolution[300 300]>>setpagedevice" *Resolution 600/600 dpi: "<</HWResolution[600 600]>>setpagedevice" *CloseUI: *Resolution However, if options cannot be described in PS file, you can write JCLs as follows; *JCLOpenUI *JCLFrameBufferSize/Frame Buffer Size: PickOne *DefaultJCLFrameBufferSize: Letter *OrderDependency: 20 JCLSetup *JCLFrameBufferSize *JCLFrameBufferSize Off: '@PJL SET PAGEPROTECT = OFF<0A>' *JCLFrameBufferSize Letter: '@PJL SET PAGEPROTECT = LTR<0A>' *JCLFrameBufferSize Legal: '@PJL SET PAGEPROTECT = LGL<0A>' *JCLCloseUI: *JCLFrameBufferSize For PostScript printers all these options are handled by the pdftops filter which is the PostScript printer driver in the PDF-based printing workflow. If you have a native PDF printer you cannot use options which inject PostScript code into the data stream, you have to define all options with JCL. Only in this case pdftopdf adds the JCL header and trailer to the PDF job. Native PDF PPDs with JCL options are recognized by the "*JCLToPDFInterpreter:" keyword, for example with the following lines: *JCLBegin: "<1B>%-12345X@PJL JOB<0A>" *JCLToPDFInterpreter: "@PJL ENTER LANGUAGE = PDF <0A>" *JCLEnd: "<1B>%-12345X@PJL EOJ <0A><1B>%-12345X" To get the correct CUPS filter chain for them, they need the following line: *cupsFilter: "application/vnd.cups-pdf 0 -" and NO "*cupsFilter:" line which accepts PostScript input. A sample PPD file for a native PDF printer, HP-Color_LaserJet_CM3530_MFP-PDF.ppd is included. When a printer does not support PS nor PDF, you can use Ghostscript (GS). In this case, you can specify device options like a PS printer. If you want to use the same printer and same PPD file for both PDF and PS printing, when you print a PS file, you can specify that GS handles it, and when you print a PDF file, you can also specify that PDF filters handle it in the same PPD file. However in this case, previous methods is not appropriate to specify device options. So, "pdftopdf" handles this case as follows; (In following pseudo program, JCL option is a option specified with JCLOpenUI) if (Both JCLBegin and JCLToPDFInterpreter are specified in the PPD file) { output JCLs that marked JCL options. } if (pdftopdfJCLBegin attribute is specified in the PPD file) { output it's value } if (Copies option is specified in the PPD file) { mark Number of copies specified } else if (pdftopdfJCLCopies is specified in the PPD file) { output JCL specified with JCLCopies } for (each marked options) { if (pdftopdfJCL<marked option's name> is specified in the PPD file) { output it's value as a JCL } else if (pdftopdfJCLBegin attributes is specified in the PPD file) { output "<option's name>=<marked choice>;" as a JCL } } output NEWLINE Thus, if you want to use both PDF filters and GS by single PPD file, what you should do is to add the following line in the PPD file; *pdftopdfJCLBegin: "pdftoopvp jobInfo:" Note: If you specify JCLBegin, you have to specify JCLToPDFInterpreter as well. Note: When you need to specify the value which is different from the choosen value based on the PPD into the jobInfo, you have to specify the values with the key started by "pdftopdfJCL" string. For example, if the page size is defined in a PPD file as following; *OpenUI *PageSize/Page Size: PickOne *DefaultPageSize: A4 *PageSize A4/A4: *PageSize Letter/US Letter: *CloseUI: *PageSize if you choose the page size "Letter", the string "PageSize=Letter;" is added to jobInfo. On the other hand, if the driver requires the different value for the "Letter" size, for instance driver requires "PS=LT;" instead of "PageSize=Letter;" as the jobInfo value, the PPD file has to be defined as following; *OpenUI *PageSize/Page Size: PickOne *DefaultPageSize: A4 *PageSize A4/A4: *pdftopdfJCLPageSize A4/A4: "PS=A4;" *PageSize Letter/US Letter: *pdftopdfJCLPageSize Letter/US Letter: "PS=LT;" *CloseUI: *PageSize 6.3 Special PDF comment "pdftopdf" outputs the following special comments from the 4th line in the created PDF data. %%PDFTOPDFNumCopies : <copies> --- <copies> specified Number of Copies %%PDFTOPDFCollate : <collate> --- <collate> is true or false 6.4 Temporally files location "pdftopdf" creates temporally files if needed. Temporary files are created in the location specified by TMPDIR environment variable. Default location is "/tmp". PDFTOPDF -- new implementation =============================== A new implementation of the pdftopdf filter is available. It depends on libqpdf to read/write pdf files. The aim is to replace and imitate the pstops filter in PDF-based workflows. A similar filter (which can serve as behavior reference) is called "cgpdftopdf" in OS X (not open source). Notable options --------------- booklet=Off/On/Shuffle-Only On also tries to set DuplexTumble (two-sided-short-edge) and forces number-up=2 booklet-signature=(multiple of 4, or default: -1 to use "all pages") Known issues ------------ - Borders, esp. in the "number-up=1 fitplot=false"-case are sometimes drawn at incorrect locations. - more testing needs to be done - documentation largely missing TEXTTOPDF ========= This implements a texttopdf filter, and is derived from cups' texttops. To configure: ------------- - texttopdf uses CUPS_DATADIR/charset/pdf.utf-8 for font configuration (when utf-8 was requested as charset). The font names given there are used as fontconfig selectors; the best matching font, that is both monospaced and in a supported format (TTC, TTF or OTF) will then be used. - As a special exception, all fontnames that start with a '.' or '/' are considered filenames, and fontconfig is skipped; the name is used directly for loading the font file. - Implementation note: TrueType Collections (.TTC) are internally handled by appending '/' and the index of the font inside the collection to the filename (e.g. to use the second font of uming.ttc, the filename uming.ttc/1 must be given to the fontembed-library). By appending the index-field returned from fontconfig, this is completely transparent to the user (but currently not widely tested). - You may look at the two examples: pdf.utf-8.simple and pdf.utf-8.heavy. To use: ------- The filter is called just like any other cups filter. Have a look at test.sh for example. Known Issues ------------ - Text extraction does not work (at least for pdftotext from xpdf) for the resulting pdfs. - OTF(CFF) embedding currently does not subset the fonts. - Text wrapping in pretty-printing mode does not respect double-wide characters (CJK), and thus produce wrong results (wrap too late) for lines where they occur. The fix is not trivial, since all the pretty-printing processing is done without knowledge of / prior to the font configuration (which is where single or double width code-ranges are specified). - The hebrew example in test5.pdf shows one of our limitations: Compose glyphs are not composed with the primary glyph but printed as separate glyphs. Further Infos ------------- Font embedding is handled by libfontembed in the filter/fontembed subdirectory. Please report all bugs to https://bugs.linuxfoundation.org/, product "OpenPrinting", component "cups-filters". PDFTORASTER =========== 1. INTRODUCTION "pdftoraster" is a filter for CUPS. It reads PDF files, convert it and output CUPS raster. "pdftoraster" does not support functions that are not related to printing features, including interactive features and document interchange features. Many of these operators and sections are just ignored. Some of these may be output, but those functions are not assured. Encryption feature is not supported. 2. LICENSE Almost source files are under MIT like license. However, "pdftoraster" links some "poppler" libraries, and these files are under GNU public license. See copyright notice of each file for details. 3. COMMAND LINE "pdftoraster" is a CUPS filter, and the command line arguments, environment variables and configuration files are in accordance with the CUPS filter interface. pdftoraster <job> <user> <title> <num-copies> <options> [<filename>] "pdftoraster" ignores <job> and <user>. <title> is appended into the PDF dictionary as /Title. <num-copies> specifies the number of document copies. <options> is a CUPS option list. <filename> is an input PDF file name. When omit the <filename>, "pdftoraster" reads a PDF file from the stdin, and save it as a temporary file. 4. ENVIRONMENT VARIABLES This program refers the following environment variable; PPD: PPD file name of the printer. 5. COMMAND OPTIONS See CUPS documents for details. 6. INFORMATION FOR DEVELOPERS Following information is for developers, not for driver users. 6.1 Options handled by a printer or "pdftoraster" "pdftopdf" outputs the following special comments from the 4th line in the created PDF data. %%PDFTOPDFNumCopies : <copies> --- <copies> specified Number of Copies %%PDFTOPDFCollate : <collate> --- <collate> is true or false "pdftoraster" overrides the command line options by above two option's values. 6.2 Temporally files location "pdftoraster" creates temporally files if needed. Temporary files are created in the location specified by TMPDIR environment variable. Default location is "/tmp". PDFTOIJS ======== 1. INTRODUCTION "pdftoijs" is a filter for CUPS. It reads PDF files, converts it and sends it to an IJS server. 2. LICENSE Almost source files are under MIT like license. However, "pdftoijs" links some "poppler" libraries, and these files are under GNU public license. See copyright notice of each file for details. 3. COMMAND LINE "pdftoijs" is a CUPS filter, and the command line arguments, environment variables and configuration files are in accordance with the CUPS filter interface. pdftoijs <job> <user> <title> <num-copies> <options> [<filename>] "pdftoijs" ignores <job> and <user>. <title> is appended into the PDF dictionary as /Title. <num-copies> specifies the number of document copies. <options> is a CUPS option list. <filename> is an input PDF file name. When omit the <filename>, "pdftoijs" reads a PDF file from the stdin, and save it as a temporary file. 4. ENVIRONMENT VARIABLES This program refers the following environment variable; PPD: PPD file name of the printer. 5. NEW PPD KEYWORDS *ijsServer : the ijsserver executable *ijsManufacturer, *ijsModel : as used by the ijs server *ijsColorspace : the desired output colorspace, one of 'rgb' 'cmyk' (availability depending on poppler compile-options) 'white1', 'black1': 1-bit normal/inverted 'white8', 'black8': 8-bit greyscale normal/inverted *ijsResolution [option]=[choice]: the desired output resolution e.g. "600 600" *ijsParams [option]=[choice]: custom ijs parameters, separated by ',' (to escape: use \,) 6. COMMAND OPTIONS (See CUPS documents for details.) ijsOutputFile : the destination file, stdout otherwise 7. INFORMATION FOR DEVELOPERS Following information is for developers, not for driver users. 7.1 Temporally files location "pdftoijs" creates temporally files if needed. Temporary files are created in the location specified by TMPDIR environment variable. Default location is "/tmp". PDFTOOPVP ========= 1. INTRODUCTION "pdftoopvp" is a CUPS filter which reads PDF file, renders pages and outputs PDL to a printer driver which is compliant with the OpenPrinting Vector Printer Driver Interface "opvp". 2. CONFIGURATION "pdftoopvp" refers the poppler configuration file. Be aware that poppler uses "fontconfig" for its font configuration. 3. JCL When "pdftoopvp" reads a PDF file from stdin, "pdftoopvp" handles the data prior to PDF header (%PDF ...) as JCL options. JCL options for "pdftoopvp" must begin with "pdftoopvp jobInfo:". "pdftoopvp" passes the option string just after ":" to the driver as the jobInfo option. 4. COMMAND LINE "pdftoopvp" is a CUPS filter, and the command line arguments, environment variables and configuration files are in accordance with the CUPS filter interface. pdftoopvp <job> <user> <title> <num-copies> <options> [<filename>] "pdftoopvp" ignores <job>, <user>, <title> and <num-copies>. <options> is a CUPS option list. When omit the <filename>, "pdftoopvp" reads a PDF file from stdin, and save it as a temporary file. CUPS options defined in <options> are delimited by space. Boolean type CUPS option is defined only by the option key, and other type CUPS option are defined by pairs of key and value, <key>=<value>. 5. COMMAND OPTIONS "pdftoopvp" accepts the following CUPS standard options; Resolution=<int> Specifies a printer resolution in dpi. When this option is omitted, the resolution is treated as 300dpi. Horizontal and vertical resolution are treated as the same resolution. PageSize=<string> Specifies a paper size by name defined in the PPD file. This option is ignored when no PPD file is assigned for the printer queue. "pdftoopvp" accepts the following original options; opvpDriver=<string> Specifies a driver library name. opvpModel=<string> Specifies a printer model name. opvpJobInfo=<string> Specifies "jobInfo" printing options that are passed to the driver. Printing options are overridden by JCL options. opvpDocInfo=<string> Specifies "docInfo" document options that are passed to the driver. opvpPageInfo=<string> Specifies "pageInfo" page options that are passed to the driver. pdftoopvpClipPathNotSaved (Boolean option) Specifies that the driver cannot save clipping path operators in PDF. nopdftoopvpShearImage (Boolean option) Specifies that the driver cannot rotate/shear images by CTM. nopdftoopvpMiterLimit (Boolean option) Specifies that the driver does not support miter limit. If the driver does not prepare the opvpSetMiterLimit function entry, this option setting is ignored, and also miter limit is ignored. pdftoopvpIgnoreMiterLimit (Boolean option) When nopdftoopvpMiterLimit option is set, pdftoopvp automatically replace paths to multiple lines or drawing images. This option specifies to avoid the path replacement even when nopdftoopvpMiterLimit option is set. pdftoopvpMaxClipPathLength=<int> Specifies the maximum number of clipping path points that the driver supports. Default value is 2000 points. pdftoopvpMaxFillPathLength=<int> Specifies the maximum number of fill path points that the driver supports. Default value is 4000 points. nopdftoopvpLineStyle (Boolean option) Specifies that the driver ignores the line style settings in PDF. If the driver does not prepare the SetLineStyle , SetLineDash or SetLineDashOffset function entry, this option setting is ignored, and also line style, line dash and line dash offset are ignored. nopdftoopvpClipPath (Boolean option) Specifies that the driver does not support clipping path. If the driver does not prepare the opvpSetClipPath function entry, this option is ignored, and also clip path setting is ignored. nopdftoopvpBitmapChar (Boolean option) Specifies that the driver does not output characters as images. Default setting is that "pdftoopvp" outputs small characters as images. pdftoopvpBitmapCharThreshold=<int> Specifies the threshold value that "pdftoopvp" outputs characters as images. Threshold value is defined as W x H where character's width is given by W pixels and height is given by H pixels. Default threshold value is 2000 points. nopdftoopvpImageMask (Boolean option) Specifies that the driver does not support image mask. If this option is set, "pdftoopvp" treats as the nopdftoopvpBitmapChar option is given. 6. PPD OPTIONS Following options can be defined in a PPD. Resolution=<int> PageSize=<string> opvpDriver=<string> opvpModel=<string> opvpJobInfo=<string> opvpDocInfo=<string> opvpPageInfo=<string> pdftoopvpClipPathNotSaved=True pdftoopvpShearImage=False pdftoopvpMiterLimit=False pdftoopvpIgnoreMiterLimit=True pdftoopvpMaxClipPathLength=<int> pdftoopvpMaxFillPathLength=<int> pdftoopvpLineStyle=False pdftoopvpClipPath=False pdftoopvpBitmapChar=False pdftoopvpBitmapCharThreshold=<int> pdftoopvpImageMask=False 7. OPTIONS OVERRIDING RULE "jobInfo" printing options in a PPD is used as a initial "jobInfo" printing options. If opvpJobInfo option is given in the command line, precedent "jobInfo" printing options are overridden by the opvpJobInfo options. After the "jobInfo" printing options are overridden by the opvpJobInfo options, if JCL options are given, precedent "jobInfo" printing options are overridden by the options given by JCL options. 8. INFORMATION FOR CUPS 1.1 To use this program under CUPS 1.1, following lines must be defined in the CUPS's "mime.types" file. application/vnd.cups-pdf 9. KNOWN PROBLEMS Problem: When a page is rotated and a character is small, character might not be rotated correctly. This problem is caused by free type library. Solution: Define the nopdftoopvpBitmapChar to inhibit characters output as images. URFTOPDF ======== "urftopdf" is a filter to convert Apple's proprietary URF raster format into PDF. URF raster is generated by some iOS applications when printing via Airprint, so this filter provides a more complete support for AirPrint clients. Note that it is not clear whether nowadays all iOS applications send PDF and not URF any more. Also the filter does not support all variants of URF format so the URF support is most probably incomplete. Apple does not provide any official documentation of the format but there is already some reverse engineering done. A description of the format as far as it got found out and two sample files can be found here: https://github.com/AlanQuatermain/unirast An actual implementation of an urftopdf filter is here: https://github.com/superna9999/urftopdf This original version uses libharu and to avoid an extra dependency the filter coming with this package is converted to use libqpdf instead (the same library as pdftopdf uses). License: GNU General Public License version 3 or any newer version