
This software users manual provides a step-by-step guide for using the CUPSTM Driver Development Kit ('DDK'), version 1.2.3.
The CUPS Driver Development Kit ('DDK') provides a suite of standard drivers, a PPD file compiler, and other utilities that can be used to develop printer drivers for CUPS and other printing environments. CUPS provides a portable printing layer for UNIX®-based operating systems. The CUPS DDK provides the means for mass-producing PPD files and drivers/filters for CUPS-based printer drivers.
The CUPS DDK is licensed under the GNU General Public License version 2. Free support is available by posting messages to the cups.ddk newsgroup at:
http://www.cups.org/newsgroups.php
The cups.ddk newsgroup is monitored by volunteers, so your message may go unanswered for days or weeks. Please be patient.
This software users manual is organized into the following sections:
Various font and syntax conventions are used in this guide. Examples and their meanings and uses are explained below:
| Example | Description | |
|---|---|---|
lpstat
lpstat(1) | The names of commands; the first mention of a command or function in a chapter is followed by a manual page section number. | |
| /var
/usr/share/cups/data/testprint.ps | File and directory names. | |
| Request ID is Printer-123 | Screen output. | |
| lp -d printer filename ENTER | Literal user input; special keys like ENTER are in ALL CAPS. | |
| 12.3 | Numbers in the text are written using the period (.) to indicate the decimal point. |
The following abbreviations are used throughout this manual:
Feedback and bug reports for this manual and the DDK as a whole are welcome. Please use the cups.ddk newsgroup to discuss potential problems and report all confirmed problems and documentation errors using the form at the following URL:
http://www.cups.org/ddk/str.php
This chapter describes how to build and install the CUPS DDK. Unsupported Mac OS X Universal Binary and Linux (i386 + x86_64) packages of the CUPS DDK are available for download from the CUPS web site (www.cups.org).
You'll need ANSI-compliant C and C++ compilers, plus a make program and Bourne (POSIX) shell. The GNU compiler tools work well - we've tested the current DDK code against GCC 3.x with excellent results.
The makefiles used by the DDK should work with most versions of make(1). We use them successfully with GNU make as well as the make programs shipped by SGI and Sun. *BSD, HP-UX, and Tru64 users should use GNU make (gmake(1)).
Finally, you must have the CUPS 1.2 or higher software installed including all header files. If you are using MacOS X 10.4 or earlier, you will need to install CUPS 1.2 on your system. An unsupported Universal Binary package for Mac OS X 10.4.x is available on the CUPS web site (www.cups.org) that you can install for this purpose. Drivers created using the DDK can be used on any system with CUPS 1.1.19 or higher installed.
The DDK is built by first configuring the software and then compiling it.
The DDK uses GNU autoconf, so you will find the usual configure script in the main DDK source directory. Type the following command to configure the DDK for your system using the default options:
./configure ENTER
The default options will put the DDK software under the /usr directory on your system. Use the --prefix option to install the DDK software in another location:
./configure --prefix=/some/directory ENTER
If you will be distributing the DDK drivers to systems with different versions of CUPS installed on them, use the --enable-static option to link the DDK drivers against the static CUPS libraries:
./configure --enable-static ENTER
You can see all of the options supported by the configure script by using the --help option:
./configure --help ENTER
Once you have configured things, just type:
make ENTER
or:
gmake ENTER
to build the software. If you encounter any difficulties, please report them to the cups.ddk newsgroup on the CUPS web site at:
http://www.cups.org/newsgroups.php
Once you have built the software you need to install it before using it. The DDK supports installing via the makefile or using the EPM software.
The install target provides a quick way to install the software on your local system:
make install ENTER
or:
gmake install ENTER
Similarly, the uninstall target removes the DDK from the local system:
make uninstall ENTER
or:
gmake uninstall ENTER
The DDK also includes targets for building installable packages using the ESP Package Manager ("EPM") software, available separately at:
http://www.easysw.com/epm/
The EPM software creates binary packages that can be installed on other machines using the EPM list file "cupsddk.list". The top-level makefile included with the DDK provides targets for creating RPM ( rpm), Debian (deb), and portable packages (epm) for installation:
make deb ENTER
make epm ENTER
make rpm ENTER
After typing any of those commands, the corresponding software package file will be placed in the dist sub-directory. Use the corresponding commands to install the packages:
dpkg -i cupsddk-1.0-linux-2.4-intel.deb ENTER
./cupsddk.install ENTER
rpm -i cupsddk-1.0-linux-2.4-intel.rpm ENTER
This chapter describes how to use the CUPS DDK and write PPD compiler source files.
The DDK provides the basis for creating printer drivers that work within the architecture defined by the Common UNIX Printing System. The DDK includes a PostScript Printer Description ("PPD") file compiler, two general-purpose raster printer drivers for printers that understand the Hewlett-Packard Page Control Language ("HP-PCL") or Epson Standard Code for Printers ("ESC/P") languages, and a raster printer driver library that provides general-purpose dithering and color management/separation functions.
All of the tools in the DDK are currently command-line only, however future releases of the DDK will include an integrated development environment which provides an intuitive GUI for creating and testing printer drivers.
Aside from this manual, the DDK also includes several man pages that can be used as a quick reference when developing your printer drivers. These pages are also available via the CUPS on-line help system and the man(1) command. For example, type the following command to display the man page for the ppdc(1) command:
man ppdc ENTER
The PPD compiler, ppdc, is a simple command-line tool that takes a single driver information file, which by convention uses the extension .drv, and produces one or more PPD files that may be distributed with your printer drivers for use with CUPS. For example, you would run the following command to create the English language PPD files defined by the driver information file mydrivers.drv:
ppdc mydrivers.drv ENTER
The PPD files are placed in a subdirectory called ppd. The -d option is used to put the PPD files in a different location, for example:
ppdc -d myppds mydrivers.drv ENTER
places the PPD files in a subdirectory named myppds. Finally, use the -l option to specify the language localization for the PPD files that are created, for example:
ppdc -d myppds/de -l de mydrivers.drv ENTER
ppdc -d myppds/en -l en mydrivers.drv ENTER
ppdc -d myppds/es -l es mydrivers.drv ENTER
ppdc -d myppds/fr -l fr mydrivers.drv ENTER
ppdc -d myppds/it -l it mydrivers.drv ENTER
creates PPD files in German (de), English (en), Spanish (es), French (fr), and Italian (it) in the corresponding subdirectories. Specify multiple languages (separated by commas) to produce "globalized" PPD files:
ppdc -d myppds -l de,en,es,fr,it mydrivers.drv ENTER
You'll learn more about localization in " Chapter 5, Localizing Printer Drivers".
The driver information files accepted by the PPD compiler are plain text files that define the various attributes and options that are included in the PPD files that are generated. A driver information file can define the information for one or more printers and their corresponding PPD files.
// Include standard font and media definitions #include <font.defs> #include <media.defs> // List the fonts that are supported, in this case all standard // fonts... Font * // Manufacturer, model name, and version Manufacturer "Foo" ModelName "FooJet 2000" Version 1.0 // Each filter provided by the driver... Filter application/vnd.cups-raster 100 rastertofoo // Supported page sizes *MediaSize Letter MediaSize A4 // Supported resolutions *Resolution k 8 0 0 0 "600dpi/600 DPI" // Specify the name of the PPD file we want to generate... PCFileName "foojet2k.ppd" |
The example in Listing 2-1 shows a driver information file which defines the minimum required attributes to provide a valid PPD file.
The first part of the file includes standard definition files for fonts and media sizes:
#include <font.defs>
#include <media.defs>
The #include directive works just like the C/C++ include directive; files included using the angle brackets (<filename> ) are found in any of the standard include directories and files included using quotes ("filename") are found in the same directory as the source or include file. The <font.defs> include file defines the standard fonts which are included with ESP Ghostscript and the Apple PDF RIP. The <media.defs> include file defines the standard media sizes listed in Appendix B of the Adobe PostScript Printer Description File Format Specification.
Other standard include files include:
Next we list all of the fonts that are available in the driver; for CUPS raster drivers, the following line is all that is usually supplied:
Font *
The Font directive specifies the name of a single font or the asterisk to specify all fonts. For example, you would use the following line to define an additional bar code font that you are supplying with your printer driver:
// name encoding version charset status
Font Barcode-Foo Special "(1.0)" Special ROM
The name of the font is Barcode-Foo. Since it is not a standard text font, the encoding and charset name Special is used. The version number is 1.0 and the status (where the font is located) is ROM to indicate that the font does not need to be embedded in documents that use the font for this printer.
Third comes the manufacturer, model name, and version number information strings:
Manufacturer "Foo"
ModelName "FooJet 2000"
Version 1.0
These strings are used when the user (or auto-configuration program) selects the printer driver for a newly connected device.
The list of filters comes after the information strings; for the example in Listing 2-1, we have a single filter that takes CUPS raster data:
Filter application/vnd.cups-raster 100 rastertofoo
Each filter specified in the driver information file is the equivalent of a printer driver for that format; if a user submits a print job in a different format, CUPS figures out the sequence of commands that will produce a supported format for the least relative cost.
Once we have defined the driver information we specify the supported options. For the example driver we support a single resolution of 600 dots per inch and two media sizes, A4 and Letter:
*MediaSize Letter
MediaSize A4
*Resolution k 8 0 0 0 "600dpi/600 DPI"
The asterisk in front of the MediaSize and Resolution directives specify that those option choices are the default. The MediaSize directive is followed by a media size name which is normally defined in the <media.defs> file and corresponds to a standard Adobe media size name. If the default media size is Letter , the PPD compiler will override it to be A4 for non-English localizations for you automatically.
The Resolution directive accepts several values after it as follows:
Finally, the PCFileName directive specifies that the named PPD file should be written for the current driver definitions:
PCFileName "foojet2k.ppd"
The filename follows the directive and must conform to the Adobe filename requirements in the Adobe Postscript Printer Description File Format Specification. Specifically, the filename may not exceed 8 characters followed by the extension .ppd.
The previous example created a single PPD file. Driver information files can also define multiple printers by using the PPD compiler grouping functionality. Directives are grouped using the curly braces ( { and }) and every group that uses the PCFileName directive produces a PPD file with that name. Listing 2-2 shows a variation of the original example that uses two groups to define two printers that share the same printer driver filter but provide two different resolution options.
The second example is essentially the same as the first, except that each printer model is defined inside of a pair of curly braces. For example, the first printer is defined using:
{
// Supported resolutions
*Resolution k 8 0 0 0 "600dpi/600 DPI"
// Specify the model name and filename...
ModelName "FooJet 2000"
PCFileName "foojet2k.ppd"
}
The printer inherits all of the definitions from the parent group (the top part of the file) and adds the additional definitions inside the curly braces for that printer driver. When we define the second group, it also inherits the same definitions from the parent group but none of the definitions from the first driver. Groups can be nested to any number of levels to support variations of similar models without duplication of information.
Sometimes you will want to define constants for your drivers so that you can share values in different groups within the same driver information file, or to share values between different driver information files using the #include directive. The #define directive is used to define constants for use in your printer definitions:
#define NAME value
// Include standard font and media definitions
#include <font.defs>
#include <media.defs>
// List the fonts that are supported, in this case all standard
// fonts...
Font *
// Manufacturer and version
Manufacturer "Foo"
Version 1.0
// Each filter provided by the driver...
Filter application/vnd.cups-raster 100 rastertofoo
// Supported page sizes
*MediaSize Letter
MediaSize A4
{
// Supported resolutions
*Resolution k 8 0 0 0 "600dpi/600 DPI"
// Specify the model name and filename...
ModelName "FooJet 2000"
PCFileName "foojet2k.ppd"
}
{
// Supported resolutions
*Resolution k 8 0 0 0 "1200dpi/1200 DPI"
// Specify the model name and filename...
ModelName "FooJet 2001"
PCFileName "foojt2k1.ppd"
}
|
The NAME is any sequence of letters, numbers, and the underscore. The value is a number or string; if the value contains spaces you must put double quotes around it, for example:
#define FOO "My String Value"
Constants can also be defined on the command-line using the -D option:
ppdc -DNAME="value" filename.drv ENTER
Once defined, you use the notation $NAME to substitute the value of the constant in the file, for example:
#define MANUFACTURER "Foo"
#define FOO_600 0
#define FOO_1200 1
{
Manufacturer "$MANUFACTURER"
ModelNumber $FOO_600
ModelName "FooJet 2000"
...
}
{
Manufacturer "$MANUFACTURER"
ModelNumber $FOO_1200
ModelName "FooJet 2001"
...
}
Numeric constants can be bitwise OR'd together by placing the constants inside parenthesis, for example:
// ModelNumber capability bits
#define DUPLEX 1
#define COLOR 2
...
{
// Define a model number specifying the capabilities of
// the printer...
ModelNumber ($DUPLEX $COLOR)
...
}
For printer drivers that support color printing, the ColorDevice and ColorModel directives must be used to tell the printing system that color output is desired and in what formats. Listing 2-3 shows a variation of the previous example which includes a color printer that supports printing at 300 and 600 DPI.
The key changes are the addition of the ColorDevice directive:
ColorDevice true
which tells the printing system that the printer supports color printing, and the ColorModel directives:
ColorModel Gray/Grayscale w chunky 0
*ColorModel RGB/Color rgb chunky 0
which tell the printing system which colorspaces are supported by the printer driver for color printing. Each of the ColorModel directives is followed by the option name and text (Gray/Grayscale and RGB/Color), the colorspace name (w and rgb ), the color organization (chunky), and the compression mode number (0) to be passed to the driver. The option name can be any of the standard Adobe ColorModel names:
Custom names can be used, however it is recommended that you use your vendor prefix for any custom names, for example "fooName".
The colorspace name can be any of the following universally supported colorspaces:
Additional colorspaces are supported by the standard CUPS image RIP filter and by ESP Ghostscript. The full list can be found in Appendix B, PPD Compiler Source File Reference.
The color organization can be any of the following values:
The compression mode value is passed to the driver in the cupsCompression attribute. It is traditionally used to select an appropriate compression mode for the color model but can be used for any purpose, such as specifying a photo mode vs. standard mode.
// Include standard font and media definitions
#include <font.defs>
#include <media.defs>
// List the fonts that are supported, in this case all standard
// fonts...
Font *
// Manufacturer and version
Manufacturer "Foo"
Version 1.0
// Each filter provided by the driver...
Filter application/vnd.cups-raster 100 rastertofoo
// Supported page sizes
*MediaSize Letter
MediaSize A4
{
// Supported resolutions
*Resolution k 8 0 0 0 "600dpi/600 DPI"
// Specify the model name and filename...
ModelName "FooJet 2000"
PCFileName "foojet2k.ppd"
}
{
// Supports color printing
ColorDevice true
// Supported colorspaces
ColorModel Gray/Grayscale w chunky 0
*ColorModel RGB/Color rgb chunky 0
// Supported resolutions
*Resolution - 8 0 0 0 "300dpi/300 DPI"
Resolution - 8 0 0 0 "600dpi/600 DPI"
// Specify the model name and filename...
ModelName "FooJet Color"
PCFileName "foojetco.ppd"
}
|
The Group, Option, and Choice directives are used to define or select a group, option, or choice. Listing 2-4 shows a variation of the first example that provides two custom options in a group named "Footasm".
The custom group is introduced by the Group directive which is followed by the name and optionally text for the user:
Group "Footasm"
The group name must conform to the PPD specification and cannot exceed 40 characters in length. If you specify user text, it cannot exceed 80 characters in length. The groups General, Extra , and InstallableOptions are predefined by CUPS; the general and extra groups are filled by the UI options defined by the PPD specification. The InstallableOptions group is reserved for options that define whether accessories for the printer (duplexer unit, finisher, stapler, etc.) are installed.
Once the group is specified, the Option directive is used to introduce a new option:
Option "fooEnhance/Resolution Enhancement" Boolean AnySetup 10
The directive is followed by the name of the option and any optional user text, the option type, the PostScript document group, and the sort order number. The option name must conform to the PPD specification and cannot exceed 40 characters in length. If you specify user text, it cannot exceed 80 characters in length.
The option type can be Boolean for true/false selections, PickOne for picking one of many choices, or PickMany for picking zero or more choices. Boolean options can have at most two choices with the names False and True. Pick options can have any number of choices, although for Windows compatibility reasons the number of choices should not exceed 255.
The PostScript document group is typically AnySetup, meaning that the option can be introduced at any point in the PostScript document. Other values include PageSetup to include the option before each page and DocumentSetup to include the option once at the beginning of the document.
The sort order number is used to sort the printer commands associated with each option choice within the PostScript document. This allows you to setup certain options before others as required by the printer. For most CUPS raster printer drivers, the value 10 can be used for all options.
Once the option is specified, each option choice can be listed using the Choice directive:
*Choice True/Yes "<</cupsCompression 1>>setpagedevice"
Choice False/No "<</cupsCompression 0>>setpagedevice"
// Include standard font and media definitions
#include <font.defs>
#include <media.defs>
// List the fonts that are supported, in this case all standard
// fonts...
Font *
// Manufacturer, model name, and version
Manufacturer "Foo"
ModelName "FooJet 2000"
Version 1.0
// Each filter provided by the driver...
Filter application/vnd.cups-raster 100 rastertofoo
// Supported page sizes
*MediaSize Letter
MediaSize A4
// Supported resolutions
*Resolution k 8 0 0 0 "600dpi/600 DPI"
// Option Group
Group "Footasm"
// Boolean option
Option "fooEnhance/Resolution Enhancement" Boolean AnySetup 10
*Choice True/Yes "<</cupsCompression 1>>setpagedevice"
Choice False/No "<</cupsCompression 0>>setpagedevice"
// Multiple choice option
Option "fooOutputType/Output Quality" PickOne AnySetup 10
*Choice "Auto/Automatic Selection"
"<</OutputType(Auto)>>setpagedevice""
Choice "Text/Optimize for Text"
"<</OutputType(Text)>>setpagedevice""
Choice "Graph/Optimize for Graphics"
"<</OutputType(Graph)>>setpagedevice""
Choice "Photo/Optimize for Photos"
"<</OutputType(Photo)>>setpagedevice""
// Specify the name of the PPD file we want to generate...
PCFileName "foojet2k.ppd"
|
The directive is followed by the choice name and optionally user text, and the PostScript commands that should be inserted when printing a file to this printer. The option name must conform to the PPD specification and cannot exceed 40 characters in length. If you specify user text, it cannot exceed 80 characters in length.
The PostScript commands are also interpreted by any RIP filters, so these commands typically must be present for all option choices. Most commands take the form:
<</name value>>setpagedevice
where name is the name of the PostScript page device attribute and value is the numeric or string value for that attribute.
Constraints are strings that are used to specify that one or more option choices are incompatible, for example two-sided printing on transparency media. Constraints are also used to prevent the use of uninstalled features such as the duplexer unit, additional media trays, and so forth.
The UIConstraints directive is used to specify a constraint that is placed in the PPD file. The directive is followed by a string using one of the following formats:
UIConstraints "*Option1 *Option2"
UIConstraints "*Option1 Choice1 *Option2"
UIConstraints "*Option1 *Option2 Choice2"
UIConstraints "*Option1 Choice1 *Option2 Choice2"
Each option name is preceded by the asterisk (*). If no choice is given for an option, then all choices except False and None will conflict with the other option and choice(s). Since the PPD compiler automatically adds reciprocal constraints (option A conflicts with option B, so therefore option B conflicts with option A), you need only specify the constraint once.
Listing 2-5 shows a variation of the first example with an added Duplex option and installable option for the duplexer, OptionDuplex. A constraint is added at the end to specify that any choice of the Duplex option that is not None is incompatible with the "Duplexer Installed" option set to "Not Installed" (False):
UIConstraints "*Duplex *OptionDuplexer False"
// Include standard font and media definitions
#include <font.defs>
#include <media.defs>
// List the fonts that are supported, in this case all standard
// fonts...
Font *
// Manufacturer, model name, and version
Manufacturer "Foo"
ModelName "FooJet 2000"
Version 1.0
// Each filter provided by the driver...
Filter application/vnd.cups-raster 100 rastertofoo
// Supported page sizes
*MediaSize Letter
MediaSize A4
// Supported resolutions
*Resolution k 8 0 0 0 "600dpi/600 DPI"
// Installable Option Group
Group "InstallableOptions/Options Installed"
// Duplexing unit option
Option "OptionDuplexer/Duplexing Unit" Boolean AnySetup 10
Choice True/Installed ""
*Choice "False/Not Installed" ""
// General Option Group
Group General
// Duplexing option
Option "Duplex/Two-Sided Printing" PickOne AnySetup 10
*Choice "None/No" "<</Duplex false>>setpagedevice""
Choice "DuplexNoTumble/Long Edge Binding"
"<</Duplex true/Tumble false>>setpagedevice""
Choice "DuplexTumble/Short Edge Binding"
"<</Duplex true/Tumble true>>setpagedevice""
// Only allow duplexing if the duplexer is installed
UIConstraints "*Duplex *OptionDuplexer False"
// Specify the name of the PPD file we want to generate...
PCFileName "foojet2k.ppd"
|
The DDK includes a utility called ppdi(1) which allows you to import existing PPD files into the driver information file format. Once imported, you can modify, localize, and regenerate the PPD files easily. The PPD files can be for CUPS raster printer drivers or for PostScript printers - the DDK makes no distinction when managing driver information or PPD files.
Type the following command to import the PPD file mydevice.ppd into the driver information file mydevice.drv:
ppdi -o mydevice.drv mydevice.ppd ENTER
If you have a whole directory of PPD files that you would like to import, you can list multiple filenames or use shell wildcards to import more than one PPD file on the command-line:
ppdi -o mydevice.drv mydevice1.ppd mydevice2.ppd ENTER
ppdi -o mydevice.drv *.ppd ENTER
If the driver information file already exists, the new PPD file entries are appended to the end of the file. Each PPD file is placed in its own group of curly braces within the driver information file.
This chapter describes how to develop PPD files for the included DDK raster printer drivers.
The DDK includes two general-purpose raster printer drivers that support the HP-PCL and ESC/P languages. Driver information files based upon these drivers can use a driver-specific include file and the DriverType directive.
Both drivers offer color management and dithering capabilities which are described in detail in Chapter 6, Doing Raster Color Management.
The HP-PCL driver includes a printer command filter called commandtopclx and a raster printer driver filter called rastertopclx. The command filter supports head cleaning, printing a self-test page, and ink cartridge alignment.
| Constant | Description |
|---|---|
| PCL_PAPER_SIZE | Use paper size command (ESC & l # A) |
| PCL_INKJET | Use inkjet commands |
| PCL_RASTER_END_COLOR | Use new end-raster command (ESC * r C) |
| PCL_RASTER_CID | Use configure-image-data command (ESC * v # W) |
| PCL_RASTER_CRD | Use configure-raster-data command (ESC * g # W) |
| PCL_RASTER_SIMPLE | Use simple-raster-color command (ESC * r # U) |
| PCL_RASTER_RGB24 | Use 24-bit RGB mode |
| PCL_PJL | Use PJL commands |
| PCL_PJL_PAPERWIDTH | Use PJL PAPERWIDTH/LENGTH commands |
| PCL_PJL_HPGL2 | Use PJL ENTER HPGL2 command |
| PCL_PJL_PCL3GUI | Use PJL ENTER PCL3GUI command |
| PCL_PJL_RESOLUTION | Use PJL SET RESOLUTION command |
The raster printer driver filter accepts grayscale, RGB, and CMYK raster data for printing to laser and inkjet devices. It supports PJL commands for device-specific features and uses PCL 3/4/5 raster graphics commands for all laser and some older inkjet printers or the various PCL3GUI and HP-RTL variants that are used by most of the inkjet printers sold by HP. The driver does not support native text rendering due to the limitations of font support in most PCL implementations.
The HP-PCL driver also provides an include file, <pcl.h>. Driver information files that use the HP-PCL driver begin with the following:
#include <font.defs>
#include <media.defs>
#include <raster.defs>
#include <pcl.h>
DriverType pcl
Table 3-1 shows the constants that are defined in the <pcl.h> include file. These constants are used with the ModelNumber directive to control the behavior of the driver. For example, a typical PCL laser printer would use the following ModelNumber specification:
ModelNumber ($PCL_PAPER_SIZE $PCL_PJL $PCL_PJL_RESOLUTION)
The parenthesis around the PCL constants tell the PPD compiler to compute the bitwise OR of each of the values. The HP-PCL driver will then use this information to tailor the output of the driver for the printer, in this case to use Printer Job Language ("PJL") commands to setup the job, including the PJL resolution command, and to use the PCL 3 paper size command. Table 3-2 shows the constants to use for several common types of HP printers.
Now that we have covered the HP-PCL driver definitions, we will create a driver for the HP LaserJet 2100, 2200, and 2300 series printers which supports all of the features that are available via PCL 5. While these printers also support PostScript, the interpreters have several known problems with TrueType fonts which can only be bypassed by using the PCL 5 printing path.
All three models support printing at 300 and 600 DPI through PCL 5 graphics; the 1200 DPI resolution is only available through PostScript and PCL 6. Each printer has an optional high-capacity paper tray and the 2200 and 2300 series printers also offer an optional duplexing unit. Listing 3-1 shows the driver information file for a basic HP LaserJet driver which supports the three models.
The file starts with the usual #include directives and then sets the driver type and model number so that we use the HP-PCL driver with the output tailored to a HP LaserJet printer:
// Specify that this driver uses the HP-PCL driver...
DriverType pcl
// Specify the driver options via the model number...
ModelNumber ($PCL_PAPER_SIZE $PCL_PJL $PCL_PJL_RESOLUTION)
| Printer Model | ModelNumber Value |
|---|---|
| HP Color LaserJet Series | ($PCL_PAPER_SIZE $PCL_RASTER_END_COLOR $PCL_RASTER_CID $PCL_RASTER_SIMPLE $PCL_RASTER_RGB24 $PCL_PJL $PCL_PJL_RESOLUTION) |
| HP DesignJet, Desktop | ($PCL_PAPER_SIZE $PCL_RASTER_END_COLOR $PCL_RASTER_CRD $PCL_PJL $PCL_PJL_PCL3GUI) |
| HP DesignJet, High-End | ($PCL_PAPER_SIZE $PCL_RASTER_END_COLOR $PCL_RASTER_CID $PCL_RASTER_SIMPLE $PCL_RASTER_RGB24 $PCL_PJL $PCL_PJL_PAPERWIDTH $PCL_PJL_HPGL2 $PCL_PJL_RESOLUTION) |
| HP DesignJet, Mid-Range | ($PCL_PAPER_SIZE $PCL_RASTER_END_COLOR $PCL_RASTER_CRD $PCL_RASTER_SIMPLE $PCL_RASTER_RGB24 $PCL_PJL $PCL_PJL_PAPERWIDTH $PCL_PJL_PCL3GUI $PCL_PJL_RESOLUTION) |
| HP DeskJet Series | ($PCL_PAPER_SIZE $PCL_RASTER_END_COLOR $PCL_RASTER_CRD $PCL_PJL $PCL_PJL_PCL3GUI) |
| HP LaserJet Series | ($PCL_PAPER_SIZE $PCL_PJL $PCL_PJL_RESOLUTION) |
| HP OfficeJet Series | ($PCL_PAPER_SIZE $PCL_RASTER_END_COLOR $PCL_RASTER_CRD $PCL_PJL $PCL_PJL_PCL3GUI) |
| HP Photosmart Series | ($PCL_PAPER_SIZE $PCL_RASTER_END_COLOR $PCL_RASTER_CRD $PCL_PJL $PCL_PJL_PCL3GUI) |
Then we list all of the media sizes that are supported by the printers along with the margins that should be used:
HWMargins 18 12 18 12
*MediaSize Letter
MediaSize Legal
MediaSize Executive
MediaSize Monarch
MediaSize Statement
MediaSize FanFoldGermanLegal
HWMargins 18 12.72 18 12.72
MediaSize Env10
HWMargins 9.72 12 9.72 12
MediaSize A4
MediaSize A5
MediaSize B5
MediaSize EnvC5
MediaSize EnvDL
MediaSize EnvISOB5
MediaSize Postcard
MediaSize DoublePostcard
Next we use the ColorModel directive to specify that our driver only prints grayscale output using the black colorspace and PCL mode 3 raster compression:
ColorModel Gray k chunky 3
These printers support printing at 300 and 600 DPI through HP-PCL 5, so we list those resolutions using the Resolution directive. We use 1 bit per color for 300 DPI to provide fast printing and 8 bits per color for 600 DPI to provide the highest quality:
Resolution - 1 0 0 0 "300dpi/300 DPI"
*Resolution - 8 0 0 0 "600dpi/600 DPI"
All of the models provide two standard paper trays and one optional tray. The first tray is used as both the multi-purpose and manual feed tray and gets listed twice. We also provide an "auto" tray which tells the printer to grab media from the first available location:
*InputSlot 7 "Auto/Automatic Selection"
InputSlot 2 "Manual/Tray 1 - Manual Feed"
InputSlot 4 "Upper/Tray 1"
InputSlot 1 "Lower/Tray 2"
InputSlot 5 "LargeCapacity/Tray 3"
// Include standard font and media definitions #include <font.defs> #include <media.defs> // Include HP-PCL driver definitions #include <pcl.h> // Specify that this driver uses the HP-PCL driver... DriverType pcl // Specify the driver options via the model number... ModelNumber ($PCL_PAPER_SIZE $PCL_PJL $PCL_PJL_RESOLUTION) // List the fonts that are supported, in this case all // standard fonts... Font * // Manufacturer and driver version Manufacturer "HP" Version 1.0 // Supported page sizes and their margins HWMargins 18 12 18 12 *MediaSize Letter MediaSize Legal MediaSize Executive MediaSize Monarch MediaSize Statement MediaSize FanFoldGermanLegal HWMargins 18 12.72 18 12.72 MediaSize Env10 HWMargins 9.72 12 9.72 12 MediaSize A4 MediaSize A5 MediaSize B5 MediaSize EnvC5 MediaSize EnvDL MediaSize EnvISOB5 MediaSize Postcard MediaSize DoublePostcard // Only black-and-white output with mode 3 compression... ColorModel Gray k chunky 3 // Supported input slots *InputSlot 7 "Auto/Automatic Selection" InputSlot 2 "Manual/Tray 1 - Manual Feed" InputSlot 4 "Upper/Tray 1" InputSlot 1 "Lower/Tray 2" InputSlot 5 "LargeCapacity/Tray 3" |
// Supported resolutions
Resolution - 1 0 0 0 "300dpi/300 DPI"
*Resolution - 8 0 0 0 "600dpi/600 DPI"
// Tray 3 is an option...
Installable "OptionLargeCapacity/Tray 3 Installed"
UIConstraints "*OptionLargeCapacity False
*InputSlot LargeCapacity"
{
// HP LaserJet 2100 Series
Throughput 10
ModelName "LaserJet 2100 Series"
PCFileName "hpljt211.ppd"
}
{
// LaserJet 2200 and 2300 series have duplexer option...
Duplex normal
Installable "OptionDuplex/Duplexer Installed"
UIConstraints "*OptionDuplex False *Duplex"
{
// HP LaserJet 2200 Series
Throughput 19
ModelName "LaserJet 2200 Series"
PCFileName "hpljt221.ppd"
}
{
// HP LaserJet 2300 Series
Throughput 25
ModelName "LaserJet 2300 Series"
PCFileName "hpljt231.ppd"
}
}
|
The numbers we used for the input slots are the PCL values associated with each tray; consult the HP-PCL Language Reference Manual for a complete list of possible values on all printers.
Since the third tray is an optional accessory, we list an installable option along with a constraint so that users may only select the third tray if it has been installed:
Installable "OptionLargeCapacity/Tray 3 Installed"
UIConstraints "*OptionLargeCapacity False *InputSlot LargeCapacity"
By convention, installable options usually begin with the prefix Option. Some vendors number the options, e.g. Option1, Option2, etc., however we have opted to use a more readable name, OptionLargeCapacity. Using a textual name also allows you to add additional installable options without renumbering existing options, and makes it easier to validate constraints.
The HP LaserJet 2200 and 2300 series printers also have an optional duplexer, which is listed using the Duplex directive along with another installable option and constraint:
Duplex normal
Installable "OptionDuplex/Duplexer Installed"
UIConstraints "*OptionDuplex False *Duplex"
Again, we are using the more readable installable option name OptionDuplex instead of Option2.
We finish things up by using grouping to isolate the three printer models and provide unique values for the Throughput, ModelName, and PCFileName directives. Notice how we are able to group the duplex option and then share the definition with the 2200 and 2300 drivers:
{
// HP LaserJet 2100 Series
Throughput 10
ModelName "LaserJet 2100 Series"
PCFileName "hpljt211.ppd"
}
{
// LaserJet 2200 and 2300 series have duplexer option...
Duplex normal
Installable "OptionDuplex/Duplexer Installed"
UIConstraints "*OptionDuplex False *Duplex"
{
// HP LaserJet 2200 Series
Throughput 19
ModelName "LaserJet 2200 Series"
PCFileName "hpljt221.ppd"
}
{
// HP LaserJet 2300 Series
Throughput 25
ModelName "LaserJet 2300 Series"
PCFileName "hpljt231.ppd"
}
}
To test the new drivers, start by running the ppdc program to create the PPD files:
ppdc laserjet-basic.drv ENTER
Then use the lpadmin(8) command to add the printer with the correct device URI. The following example adds a HP LaserJet 2100 which is connected via a JetDirect interface:
lpadmin -p lj2100 -E -v socket://lj2100 -i ppd/hpljt211.ppd ENTER
Finally, print a test page to see it work:
lp -d lj2100 /usr/share/cups/data/testprint.ps ENTER
The HP-PCL driver also supports extensive Printer Job Language (PJL) commands through a combination of PPD attributes and options. Table 3-3 lists the PJL attributes that are supported along with the PPD options they map to. PJL attributes are specified using the Attribute directive using the cupsPJL keyword. For example, the following attribute provides the PJL commands to enable or disable the resolution enhancement features of the printer:
Attribute cupsPJL cupsRET
"@PJL SET SMOOTHING=%?False:OFF;%?True:ON;%n"
The directive, Attribute, is followed by the attribute keyword, cupsPJL, the attribute name, cupsRET, and the attribute value, in this case a PJL command string. The command string consists of PJL command text and special substitution fields starting with the percent (%) character.
In the example above, the %? substitution conditionally inserts some text if the string matches the option value, typically the name of the choice. In this case, we have two conditional substitutions. The first inserts the text OFF if the cupsRET option is False, and the second inserts the text ON if the option is True. The syntax is as follows:
%?look for:insert;
Multiple conditional substitutions can be listed up to about 230 characters - the PPD file format imposed a 255 character line length limit, and attribute values cannot span multiple lines.
Aside from conditional substitutions, the HP-PCL driver supports the following additional substitutions. Unknown substitutions are inserted verbatim:
All three HP LaserJet models support additional options via PJL commands. Listing 3-2 shows a modified version of the driver which adds support the resolution enhancement and toner saving features of the printers.
The new resolution enhancement option consists of a PPD attribute containing the cupsRET command followed by the cupsRET option. Since this option applies to the entire job, the option is placed in the DocumentSetup section:
Attribute cupsPJL cupsRET
"@PJL SET SMOOTHING=%?False:OFF;%?True:ON;%n"
Option "cupsRET/Smoothing" Boolean DocumentSetup 10
Choice "False/Off" ""
*Choice "True/On" ""
The toner saving option is added the same way using the cupsTonerSave attribute and option:
Attribute cupsPJL cupsTonerSave
"@PJL SET ECONOMODE=%?False:OFF;%?True:ON;%n"
Option "cupsTonerSave/Save Toner" Boolean DocumentSetup 10
*Choice "False/No" ""
Choice "True/Yes" ""
Since we didn't specify a group for these options, they will be put in the General option group.
| Attribute | Option | Description |
|---|---|---|
| COLORSPACE. ColorModel | Varies | Specifies the colorspace to set at the beginning of the job. |
| cupsBooklet | cupsBooklet | Specifies the PJL commands to send for setting the booklet printing mode. |
| cupsPunch | cupsPunch | Specifies the PJL commands to send for setting the punch mode. |
| cupsRET | cupsRET | Specifies the PJL commands to set the resolution enhancement mode. |
| cupsStaple | cupsStaple | Specifies the PJL commands to send for setting the stapler mode. |
| cupsTonerSave | cupsTonerSave | Specifies the PJL commands to set the toner saving mode. |
| Duplex | Duplex | Specifies the PJL commands to send for setting the duplex mode. |
| EndJob | N/A | Specifies the PJL commands to send at the end of a job. |
| Jog | Varies | Specifies the PJL commands to send for setting the output jogging. |
| MediaClass | Varies | Specifies the PJL commands to send for setting the media class. |
| MediaColor | Varies | Specifies the PJL commands to send for setting the media color. |
| MediaType | MediaType | Specifies the PJL commands to send for setting the media type. |
| OutputType | Varies | Specifies the PJL commands to send for setting the output type. |
| RENDERINTENT. ColorModel | Varies | Specifies the rendering intent to set at the beginning of the job. |
| RENDERMODE. ColorModel | Varies | Specifies the render mode to set at the beginning of the job. |
| Attribute | Option | Description |
|---|---|---|
| StartJob | N/A | Specifies the PJL commands to send at the beginning of a job. |
| Tumble | Duplex | Specifies the PJL commands to send for setting the duplex tumble mode. |
To test the new drivers, start by running the ppdc program to create the PPD files:
ppdc laserjet-pjl.drv ENTER
Then use the lpadmin(8) command to add the printer with the correct device URI. The following example adds a HP LaserJet 2100 which is connected via a JetDirect interface:
lpadmin -p lj2100 -E -v socket://lj2100 -i ppd/hpljt212.ppd ENTER
Finally, print a test page to see it work:
lp -d lj2100 -o cupsTonerSave=True \
/usr/share/cups/data/testprint.ps ENTER
// Include standard font and media definitions #include <font.defs> #include <media.defs> // Include HP-PCL driver definitions #include <pcl.h> // Specify that this driver uses the HP-PCL driver... DriverType pcl // Specify the driver options via the model number... ModelNumber ($PCL_PAPER_SIZE $PCL_PJL $PCL_PJL_RESOLUTION) // List the fonts that are supported, in this case all // standard fonts... Font * // Manufacturer and driver version Manufacturer "HP" Version 2.0 // Supported page sizes and their margins HWMargins 18 12 18 12 *MediaSize Letter MediaSize Legal MediaSize Executive MediaSize Monarch MediaSize Statement MediaSize FanFoldGermanLegal HWMargins 18 12.72 18 12.72 MediaSize Env10 HWMargins 9.72 12 9.72 12 MediaSize A4 MediaSize A5 MediaSize B5 MediaSize EnvC5 MediaSize EnvDL MediaSize EnvISOB5 MediaSize Postcard MediaSize DoublePostcard // Only black-and-white output with mode 3 compression... ColorModel Gray k chunky 3 // Supported input slots *InputSlot 7 "Auto/Automatic Selection" InputSlot 2 "Manual/Tray 1 - Manual Feed" InputSlot 4 "Upper/Tray 1" InputSlot 1 "Lower/Tray 2" InputSlot 5 "LargeCapacity/Tray 3" |
// Supported resolutions
Resolution - 1 0 0 0 "300dpi/300 DPI"
*Resolution - 8 0 0 0 "600dpi/600 DPI"
// Tray 3 is an option...
Installable "OptionLargeCapacity/Tray 3 Installed"
UIConstraints "*OptionLargeCapacity False
*InputSlot LargeCapacity"
// PJL options
Attribute cupsPJL cupsRET
"@PJL SET SMOOTHING=%?False:OFF;%?True:ON;%n"
Option "cupsRET/Smoothing" Boolean DocumentSetup 10
Choice "False/Off" ""
*Choice "True/On" ""
Attribute cupsPJL cupsTonerSave
"@PJL SET ECONOMODE=%?False:OFF;%?True:ON;%n"
Option "cupsTonerSave/Save Toner" Boolean DocumentSetup 10
*Choice "False/No" ""
Choice "True/Yes" ""
{
// HP LaserJet 2100 Series
Throughput 10
ModelName "LaserJet 2100 Series PJL"
PCFileName "hpljt212.ppd"
}
{
// LaserJet 2200 and 2300 series have duplexer option...
Duplex normal
Installable "OptionDuplex/Duplexer Installed"
UIConstraints "*OptionDuplex False *Duplex"
{
// HP LaserJet 2200 Series
Throughput 19
ModelName "LaserJet 2200 Series PJL"
PCFileName "hpljt222.ppd"
}
{
// HP LaserJet 2300 Series
Throughput 25
ModelName "LaserJet 2300 Series PJL"
PCFileName "hpljt232.ppd"
}
}
|
The ESC/P driver includes a printer command filter called commandtoescpx and a raster printer driver filter called rastertoescpx. The command filter supports head cleaning, printing a self-test page, and ink cartridge alignment.
The raster printer driver filter accepts grayscale, RGB, and CMYK raster data for printing to inkjet devices. It supports EJL commands for device-specific features and uses the appropriate ESC/P2 raster graphics commands for all inkjet printers sold by Epson. The driver does not support native text rendering due to the limitations of text support in most ESC/P implementations.
The ESC/P driver also provides an include file, <escp.h>. Driver information files that use the ESC/P driver begin with the following:
#include <font.defs>
#include <media.defs>
#include <raster.defs>
#include <escp.h>
DriverType escp
Table 3-4 shows the constants that are defined in the <escp.h> include file. These constants are used with the ModelNumber directive to control the behavior of the driver. For example, a typical Epson Stylus Color printer would use the following ModelNumber specification:
ModelNumber ($ESCP_MICROWEAVE $ESCP_USB $ESCP_REMOTE)
The parenthesis around the ESCP constants tell the PPD compiler to compute the bitwise OR of each of the values. The ESC/P driver will then use this information to tailor the output of the driver for the printer, in this case to use the printer's built-in microweaving (a way of printing using multiple passes), send the USB packet mode escape sequence, and to use remote mode commands. Table 3-5 shows the constants to use for several common types of Epson printers.
Now that we have covered the ESC/P driver definitions, we will create a driver for the popular Epson Stylus Photo R300 series printers. These printers offer 6-color, full-bleed printing at up to 5760x1440 DPI and can print on recordable CDs and DVDs as well as standard printer media.
| Constant | Description |
|---|---|
| ESCP_MICROWEAVE | Use microweave command? |
| ESCP_STAGGER | Are color jets staggered? |
| ESCP_ESCK | Use print mode command? |
| ESCP_EXT_UNITS | Use extended unit commands? |
| ESCP_EXT_MARGINS | Use extended margin command? |
| ESCP_USB | Send USB packet mode escape |
| ESCP_PAGE_SIZE | Use page size command |
| ESCP_RASTER_ESCI | Use ESC i graphics command |
| ESCP_REMOTE | Use remote mode commands |
| Printer Model | ModelNumber Value |
|---|---|
| Epson Stylus Color | ($ESCP_MICROWEAVE $ESCP_USB $ESCP_REMOTE) |
| Epson Stylus C-Series | ($ESCP_STAGGER $ESCP_USB $ESCP_REMOTE) |
| Epson Stylus Photo | ($ESCP_MICROWEAVE $ESCP_ESCK $ESCP_USB $ESCP_REMOTE) |
| Epson Stylus Pro | ($ESCP_MICROWEAVE $ESCP_EXT_UNITS $ESCP_EXT_MARGINS $ESCP_PAGE_SIZE $ESCP_REMOTE) |
Our first cut of the driver will support printing at up to 1440 DPI. We'll add the full-bleed printing support in the next section. Listing 3-3 shows the driver information file for a basic Epson Stylus Photo R300 driver.
The file starts with the usual #include directives and then sets the driver type and model number so that we use the ESC/P driver with the output tailored to the R300:
// Specify that this driver uses the ESC/P driver...
DriverType escp
// Specify the driver options via the model number...
ModelNumber ($ESCP_ESCK $ESCP_EXT_UNITS $ESCP_EXT_MARGINS $ESCP_USB
$ESCP_PAGE_SIZE $ESCP_RASTER_ESCI)
Then we list all of the media sizes that are supported by the printers along with the margins that should be used:
HWMargins 8.4 0 8.4 0
*MediaSize Letter
MediaSize Legal
MediaSize Executive
MediaSize Statement
MediaSize A4
MediaSize A5
MediaSize A6
MediaSize B5
MediaSize Env10
MediaSize EnvC5
MediaSize EnvDL
MediaSize EnvISOB5
MediaSize Postcard
MediaSize DoublePostcard
The R300 supports custom page sizes up to 44 inches (1.1m) in length. We use the VariablePaperSize directive to instruct the PPD compiler to include the custom page size attributes, and the MinSize and MaxSize directives to specify the range of sizes that are supported:
VariablePaperSize Yes
MinSize 1in 4in
MaxSize 8.5in 44in
The R300 driver also supports four color modes: Grayscale (colorspace = w), Black (colorspace = k), RGB (colorspace = rgb), and CMYK (colorspace = cmyk). The Grayscale and RGB modes provide color/gamma-corrected output while the Black and CMYK modes offer uncorrected color printing. The ColorModel directive tells the PPD compiler to include each of these modes:
ColorModel Gray/Grayscale w chunky 1
ColorModel Black k chunky 1
*ColorModel RGB/Color rgb chunky 1
ColorModel CMYK cmyk chunky 1
The driver provides printing at 360, 720, and 1440 DPI using the Resolution directives. Each resolution makes use of the bits per color, row count, and row step values:
Resolution - 8 90 0 103 "360dpi/360 DPI"
*Resolution - 8 90 0 206 "720dpi/720 DPI"
Resolution - 8 90 0 412 "1440dpi/1440 DPI"
// Include standard font and media definitions
#include <font.defs>
#include <media.defs>
// Include ESC/P driver definitions
#include <escp.h>
// Specify that this driver uses the ESC/P driver...
DriverType escp
// Specify the driver options via the model number...
ModelNumber ($ESCP_ESCK $ESCP_EXT_UNITS $ESCP_EXT_MARGINS
$ESCP_USB $ESCP_PAGE_SIZE $ESCP_RASTER_ESCI)
// List the fonts that are supported, in this case all
// standard fonts...
Font *
// Manufacturer and driver version
Manufacturer "Epson"
Version 1.0
// Supported page sizes and their margins
HWMargins 8.4 0 8.4 0
*MediaSize Letter
MediaSize Legal
MediaSize Executive
MediaSize Statement
MediaSize A4
MediaSize A5
MediaSize A6
MediaSize B5
MediaSize Env10
MediaSize EnvC5
MediaSize EnvDL
MediaSize EnvISOB5
MediaSize Postcard
MediaSize DoublePostcard
VariablePaperSize Yes
MinSize 1in 4in
MaxSize 8.5in 44in
// Four color modes are supported...
ColorModel Gray/Grayscale w chunky 1
ColorModel Black k chunky 1
*ColorModel RGB/Color rgb chunky 1
ColorModel CMYK cmyk chunky 1
// Supported resolutions
Resolution - 8 90 0 103 "360dpi/360 DPI"
*Resolution - 8 90 0 206 "720dpi/720 DPI"
Resolution - 8 90 0 412 "1440dpi/1440 DPI"
|
// Very basic dithering settings
Attribute cupsInkChannels "" 6
Attribute cupsInkLimit "" 2.0
Attribute cupsCyanLtDk "" "0.5 1.0"
Attribute cupsMagentaLtDk "" "0.5 1.0"
Attribute cupsAllDither 360dpi "0.5 0.75 1.0"
Attribute cupsAllDither 720dpi "0.6 0.9 1.2"
Attribute cupsAllDither 1440dpi "0.9 1.35"
Attribute cupsESCPDotSize 360dpi 16
Attribute cupsESCPDotSize 720dpi 17
Attribute cupsESCPDotSize 1440dpi 18
{
// EPSON Stylus Photo R300 Series
Throughput 1
ModelName "Epson Stylus Photo R300"
PCFileName "epspr301.ppd"
}
|
The R300 has 90 nozzles per color spaced at 120 DPI vertically; the head controller can print 360 DPI horizontally. The row count value is the same as the nozzle count, 90. The row step values require a small amount of calculation; each value is computed using the following formula:
row-step = 100 * x-dpi / 360 + y-dpi / 120
For 360x360 DPI, the row step is therefore:
row-step = 100 * x-dpi / 360 + y-dpi / 120
= 100 * 360 / 360 + 360 / 120
= 100 * 1 + 3
= 100 + 3
= 103
The 720 and 1440 DPI resolutions are computed similarly, and it is possible to support any multiple of the base resolution, 360x120 DPI, up to the physical limit of the printer controller, 5760x1440 DPI.
The R300 driver also needs some additional attributes defined to control the amount and kind of ink that is printed on the page. The first attribute we need to define is cupsInkChannels which tells the driver how many colors are used by the printer. In this case, the R300 is a 6-color printer:
Attribute cupsInkChannels "" 6
Next we want to limit the amount of ink that is put on the page to 200%. The cupsInkLimit attribute specifies this value:
Attribute cupsInkLimit "" 2.0
Since the R300 uses light versions of cyan and magenta, we need to tell the driver when to use the light ink and when to use the dark ink. The simplest attributes for this specify the transition range as two numbers from 0 to 1. We'll transition from 0.5 to 1.0 for both colors:
Attribute cupsCyanLtDk "" "0.5 1.0"
Attribute cupsMagentaLtDk "" "0.5 1.0"
Next, we want to specify the ink density for the dots that the R300 can produce for each resolution using the cupsAllDither attribute. Each number represents a percentage of ink, so a value of 1.0 means 100% coverage for each dot and a value of 2.0 means 200% coverage for each dot. The driver uses this information to reduce the amount of ink that is put on the page for each individual color. Since the R300 supports three different dot sizes, we include three numbers for the 360 and 720 DPI modes, however at 1440 DPI the largest dot size is not needed:
Attribute cupsAllDither 360dpi "0.5 0.75 1.0"
Attribute cupsAllDither 720dpi "0.6 0.9 1.2"
Attribute cupsAllDither 1440dpi "0.9 1.35"
Finally, we tell the driver which dot sizes to use for each resolution using the cupsESCPDotSize attribute. These values are defined in the corresponding developer reference manual from Epson. For the R300, size 16 represents the largest variable size dots and size 18 the smallest:
Attribute cupsESCPDotSize 360dpi 16
Attribute cupsESCPDotSize 720dpi 17
Attribute cupsESCPDotSize 1440dpi 18
To test the new drivers, start by running the ppdc program to create the PPD files:
ppdc r300-basic.drv ENTER
Then use the lpadmin(8) command to add the printer with the correct device URI. The following example adds a R300 which is connected via a USB port:
lpadmin -p r300 -E -v 'usb://EPSON/Stylus%20Photo%20R300' -i \
ppd/epspr301.ppd ENTER
Finally, print a test page to see it work:
lp -d r300 /usr/share/cups/data/testprint.ps ENTER
Most Epson inkjet printers support a special "remote" mode which allows you to control things such as the paper cutter, media type, drying time, and so forth. Remote mode also allows you to query the current ink status from the printer, clean the print heads, etc., and that functionality is supported via the commandtoescpx filter.
Remote mode support is specified using the ESCP_REMOTE model number constant. If remote mode is enabled, the rastertoescpx driver will look for several attributes to determine which remote mode commands to send and with what values. Table 3-6 lists the remote mode attributes and their values.
Typically, each attribute maps from a single, integer value from the page device dictionary to a single integer value which is used for the corresponding remote mode command. The only exception to this rule is the cupsESCPPP attribute which maps the MediaPosition value to two integer values for the "PP" (paper path) remote mode command, for example:
Attribute cupsESCPPP 0 "1 255"
The integer values used for all remote mode commands are documented in the corresponding Epson programming guide for your printer.
The R300 supports several remote mode commands that we can use. We will add support for full-bleed printing and specification of the media source. Listing 3-4 shows the updated driver information file. We'll start by adding the ESCP_REMOTE constant to the model number definition:
ModelNumber ($ESCP_ESCK $ESCP_EXT_UNITS $ESCP_EXT_MARGINS $ESCP_USB
$ESCP_PAGE_SIZE $ESCP_RASTER_ESCI $ESCP_REMOTE)
Next we add the horizontal offset attribute, cupsESCPFP, that is used to offset the page for full-bleed printing:
Attribute cupsESCPFP "" -80
Finally, we add InputSlot definitions for automatic and manual feed printing, and cupsESCPPP attributes for each MediaPosition value:
*InputSlot 0 "Auto/Auto Select"
InputSlot 1 "Manual/Manual Feed"
Attribute cupsESCPPP 0 "1 255"
Attribute cupsESCPPP 1 "2 1"
| Attribute | Description |
|---|---|
| cupsESCPAC | Enables/disables the cutter based upon the CutMedia value |
| cupsESCPCO | Enables/disables the cutter based upon the CutMedia value |
| cupsESCPEX | Sets the media position based upon the MediaPosition value |
| cupsESCPFP | Sets the full-bleed horizontal position offset |
| cupsESCPMS | Sets the media size based upon the MediaPosition and PageSize values |
| cupsESCPMT | Sets the media type based upon the cupsMediaType value |
| cupsESCPPC | Sets paper checking based upon the MediaPosition value |
| cupsESCPPH | Sets the paper thickness based upon the cupsMediaType value |
| cupsESCPPP | Sets the paper path based upon the MediaPosition value |
| cupsESCPSN0 | Sets the feed sequence based upon the cupsMediaType value |
| cupsESCPSN1 | Sets the platten gap based upon the cupsMediaType value |
| cupsESCPSN2 | Sets the paper feed/eject sequence based upon the cupsMediaType value |
| cupsESCPSN6 | Sets the eject delay based upon the cupsMediaType value |
| cupsESCPSN80 | Sets the cutting method based upon the CutMedia value |
| cupsESCPSN81 | Sets the cutting pressure based upon the CutMedia value |
To test the new drivers, start by running the ppdc program to create the PPD files:
ppdc r300-remote.drv ENTER
Then use the lpadmin(8) command to add the printer with the correct device URI. The following example adds a R300 which is connected via a USB port:
lpadmin -p r300 -E -v 'usb://EPSON/Stylus%20Photo%20R300' \
-i ppd/epspr302.ppd ENTER
Finally, print a test page to see it work:
lp -d r300 /usr/share/cups/data/testprint.ps ENTER
// Include standard font and media definitions
#include <font.defs>
#include <media.defs>
// Include ESC/P driver definitions
#include <escp.h>
// Specify that this driver uses the ESC/P driver...
DriverType escp
// Specify the driver options via the model number...
ModelNumber ($ESCP_ESCK $ESCP_EXT_UNITS $ESCP_EXT_MARGINS
$ESCP_USB $ESCP_PAGE_SIZE $ESCP_RASTER_ESCI
$ESCP_REMOTE)
// List the fonts that are supported, in this case all
// standard fonts...
Font *
// Manufacturer and driver version
Manufacturer "Epson"
Version 2.0
// Supported page sizes and their margins
HWMargins 0 0 0 0
*MediaSize Letter
MediaSize Legal
MediaSize Executive
MediaSize Statement
MediaSize A4
MediaSize A5
MediaSize A6
MediaSize B5
MediaSize Env10
MediaSize EnvC5
MediaSize EnvDL
MediaSize EnvISOB5
MediaSize Postcard
MediaSize DoublePostcard
|
VariablePaperSize Yes
MinSize 1in 4in
MaxSize 8.5in 44in
// Borderless printing offset...
Attribute cupsESCPFP "" -80
// Four color modes are supported...
ColorModel Gray/Grayscale w chunky 1
ColorModel Black k chunky 1
*ColorModel RGB/Color rgb chunky 1
ColorModel CMYK cmyk chunky 1
// Supported resolutions
Resolution - 8 90 0 103 "360dpi/360 DPI"
*Resolution - 8 90 0 206 "720dpi/720 DPI"
Resolution - 8 90 0 412 "1440dpi/1440 DPI"
// Paper trays...
*InputSlot 0 "Auto/Auto Select"
InputSlot 1 "Manual/Manual Feed"
Attribute cupsESCPPP 0 "1 255"
Attribute cupsESCPPP 1 "2 1"
// Very basic dithering settings
Attribute cupsInkChannels "" 6
Attribute cupsInkLimit "" 2.0
Attribute cupsCyanLtDk "" "0.5 1.0"
Attribute cupsMagentaLtDk "" "0.5 1.0"
Attribute cupsAllDither 360dpi "0.5 0.75 1.0"
Attribute cupsAllDither 720dpi "0.6 0.9 1.2"
Attribute cupsAllDither 1440dpi "0.9 1.35"
Attribute cupsESCPDotSize 360dpi 16
Attribute cupsESCPDotSize 720dpi 17
Attribute cupsESCPDotSize 1440dpi 18
{
// EPSON Stylus Photo R300 Series
Throughput 1
ModelName "Epson Stylus Photo R300"
PCFileName "epspr302.ppd"
}
|
This chapter describes how to develop PPD files for PostScript printer drivers.
The PPD compiler is capable of producing PPD files for PostScript printers just as easily as for non-PostScript printers. PostScript printer drivers use the ps driver type:
DriverType ps
PostScript drivers require the attributes listed in Table 4-1. If not specified, the defaults for CUPS drivers are used. A typical PostScript driver information file would include the following attributes:
Attribute DefaultColorSpace "" Gray
Attribute LandscapeOrientation "" Minus90
Attribute LanguageLevel "" "3"
Attribute Product "" "(Foo LaserProofer 2000)"
Attribute PSVersion "" "(3010) 0"
Attribute TTRasterizer "" Type42
| Attribute | Description |
|---|---|
| DefaultColorSpace | The default colorspace: Gray, RGB, CMY, or CMYK. If not specified, then RGB is assumed. |
| LandscapeOrientation | The preferred landscape orientation: Plus90, Minus90, or Any. If not specified, Plus90 is assumed. |
| LanguageLevel | The PostScript language level supported by the device: 1, 2, or 3. If not specified, 2 is assumed. |
| Product | The string returned by the PostScript product operator, which must include parenthesis to conform with PostScript syntax rules for strings. Multiple Product attributes may be specified to support multiple products with the same PPD file. If not specified, "(ESP Ghostscript)" and "(GNU Ghostscript)" are assumed. |
| PSVersion | The PostScript interpreter version numbers as returned by the version and revision operators. The required format is "(version) revision". Multiple PSVersion attributes may be specified to support multiple interpreter version numbers. If not specified, "(3010) 705" and "(3010) 707" are assumed. |
| TTRasterizer | The type of TrueType font rasterizer supported by the device, if any. The supported values are None, Accept68k, Type42 , and TrueImage. If not specified, None is assumed. |
Most PostScript printer PPD files include query commands ( ?PageSize, etc.) that allow applications to query the printer for its current settings and configuration. Query commands are included in driver information files as attributes. For example, the query command for the PageSize option might look like the following:
Attribute "?PageSize" "" "
save
currentpagedevice /PageSize get aload pop
2 copy gt {exch} if (Unknown)
23 dict
dup [612 792] (Letter) put
dup [612 1008] (Legal) put
dup [595 842] (A4) put
{exch aload pop 4 index sub abs 5 le exch
5 index sub abs 5 le and
{exch pop exit} {pop} ifelse
} bind forall = flush pop pop
restore"
Query commands can span multiple lines, however no single line may contain more than 255 characters.
Normally a PostScript printer driver will not utilize any additional print filters. For drivers that provide additional filters such as a CUPS command file filter for doing printer maintenance, you must also list the following Filter directive to handle printing PostScript files:
Filter application/vnd.cups-postscript 0 -
The ppdi(1) utility included with the CUPS DDK imports existing PPD files into driver information files. This allows you to make modifications and localize PPD files for other languages with great ease. Use the following command to import a single PPD file called filename.ppd into a driver information file called filename.drv:
ppdi filename.drv filename.ppd ENTER
The driver information file is created if it does not exist. Otherwise the PPD file information is appended to the end of the file. You can use shell wildcards to import whole directories of PPD files:
ppdi filename.drv *.ppd ENTER
Once imported, you can edit the driver information file and use the ppdc program to regenerate the PPD files:
ppdc filename.drv ENTER
This chapter describes how to localize printer drivers for different languages and defaults.
The PPD compiler provides localization of PPD files in different languages through message catalog files in the GNU gettext format. Each user text string and several key PPD attribute values such as LanguageVersion and LanguageEncoding are looked up in the corresponding message catalog and the translated text is substituted in the generated PPD files. One message catalog file can be used by multiple driver information files, and each file contains a single language translation.
The DDK provides a utility program to aid in the localization of drivers called ppdpo(1). In addition, the standard DDK installation includes basic localizations of all standard media sizes and options in English, French, German, Italian, Spanish, and Japanese.
Localizations are created using a few options to the PPD compiler which are covered later in this chapter.
Each message catalog file can be edited with your favorite text editor and consists of one or more messages translated into a single language. Comment lines can be included using the # character, for example:
# This is a comment
Each message is specified using a pair of directives: msgid and msgstr. The msgid string specifies the original (probably English) version of a string which is looked up when localizing a PPD file. The msgstr string contains the translated message. For example, the following message catalog translates the word "Yes" to French:
msgid "Yes"
msgstr "Oui"
Each message catalog will also contain two special entries for the LanguageVersion and LanguageEncoding attribute values. The standard msgid values are "English" and "ISOLatin1", respectively. They should be replaced with the Adobe-defined keywords for the language being localized and the character encoding, respectively. Table 5-1 lists the standard LanguageVersion, LanguageEncoding, and corresponding POSIX language abbreviation values that are supported.
The ppdpo program creates or updates a message catalog file based upon one or more driver information files. New messages are added with the word "TRANSLATE" added to the front of the translation string to make locating new strings for translation easier. The program accepts the message catalog filename and one or more driver information files.
For example, run the following command to create a new German message catalog called de.po for all of the driver information files in the current directory:
ppdpo -o de.po *.drv
If the file de.po already exists, ppdpo will update the contents of the file with any new messages that need to be translated.
| LanguageVersion | LanguageEncoding | POSIX |
|---|---|---|
| English | ISOLatin1 | en |
| Chinese | None | zh |
| Danish | ISOLatin1 | da |
| Dutch | ISOLatin1 | nl |
| Finnish | ISOLatin1 | fi |
| French | ISOLatin1 | fr |
| German | ISOLatin1 | de |
| Italian | ISOLatin1 | it |
| Japanese | JIS83-RKSJ | ja |
| Norwegian | ISOLatin1 | no |
| Portuguese | ISOLatin1 | pt |
| Russian | None | ru |
| Spanish | ISOLatin1 | es |
| Swedish | ISOLatin1 | sv |
| Turkish | None | tr |
| Note:
The LanguageVersion and LanguageEncoding strings are only used when creating single-language PPD files. Globalized PPD files, which contain multiple languages in a single PPD file, always report "English" and "ISOLatin1" for the primary localization and provide the other languages using the UTF-8 encoding. | ||
Once you have created a message catalog, use the -c, -l , and -d options with ppdc to create PPD files in alternate languages. The -c option specifies the message catalog to use, the -l option specifies the standard DDK-supplied message catalog using the POSIX language abbreviation, and the -d option specifies the output directory. For example, use the following command to generate the German PPD files for the drivers listed in mydrivers.drv into the directory ppd/de :
ppdc -l de -c de.po -d ppd/de mydrivers.drv
When you want to generate globalized PPD files containing multiple languages, start by listing any message catalog files in your driver information file using the #po directive:
#po de "de.po" // German
#po es "es.po" // Spanish
#po fr "fr.po" // French
#po it "it.po" // Italian
#po ja "ja.po" // Japanese
Then run the ppdc command, listing each language you want to include after the -l option. Each language name must be separated by a comma. For example, use the following command to generate globalized PPD files in English, German, Spanish, French, Italian, and Japanese for the drivers listed in mydrivers.drv into the directory ppd:
ppdc -l en,de,es,fr,it,ja -d ppd mydrivers.drv
The ppdmerge(1) utility allows you to merge existing single-language PPD files into a single globalized (multiple-language) PPD file. Simply provide the name of the PPD file you want to create or update with the -o option followed by a list of PPD files to merge. If the output file already exists, ppdmerge will load that PPD file first and then add the translations from the other PPD files to it.
For example, run the following command to merge all of the FooJet 2000 PPD files (each in their own language subdirectory and called foojet2k.ppd) into a single globalized PPD file called foojet2k.ppd:
ppdmerge -o foojet2k.ppd */foojet2k.ppd
Similarly, run the following commands to incrementally add the French and Italian translations to the English PPD file:
ppdmerge -o foojet2k.ppd fr/foojet2k.ppd
ppdmerge -o foojet2k.ppd it/foojet2k.ppd
This chapter describes how to use the built-in raster color management functions to produce enhanced color and grayscale output on raster printers.
CUPS provides several ways for CUPS-based raster printer drivers to manage the colors produced by a non-PostScript printer. Figure 6-1 shows the raster processing workflow within CUPS. Starting with the print file, applications can embed ICC and other types of color profiles to alter the printed output.
Once converted to a RIP file format, the standard RIP filters can perform various linear transformations during rasterization, such as gamma correction, density adjustment, and color transforms using a matrix.
Upon arrival at the printer driver filter, the driver can perform any number of linear and non-linear transformations as needed. The DDK drivers and custom driver API offer non-linear 3D lookup tables for transforming grayscale and RGB colors to a K or CMYK representation and non-linear 2D lookup tables for transforming K or CMYK colors to device color values.
![]() |
Once converted to a device color, the color values are then dithered, as necessary, using per-color dithering parameters specific to the target device, rendering mode, resolution, and media.
Color management for PostScript and Ghostscript-based printer drivers is not currently supported by CUPS. Please consult the corresponding vendor documentation for any color management capabilities that are offered for those printers and drivers.
The first type of color profile supported by CUPS is provided by the RIP filters and is defined using the cupsColorProfile attribute in the PPD file or the profile attribute in the job options. Each profile consists of 11 numbers: the density, gamma, and CMY 3x3 color transform matrix. The cupsColorProfile PPD attribute value contains 11 real numbers separated by spaces, while the profile job attribute contains 11 integers separated by commas (,); multiple the PPD attribute numbers by 1000 to compute the job attribute numbers.
The cupsColorProfile attribute is specified using the ColorProfile or SimpleColorProfile directives in a driver information file. Each color profile can apply to a specific combination of resolution and media type or to all resolutions or media types. The RIP filter will use the first matching profile in the PPD file, so it is important to specify the specific profiles first followed by the general ones.
The cupsprofile(1) utility can be used to generate a RIP-based color profile using a series of four test pages. The results are suitable for calibrating basic business-type graphics to a particular combination of resolution and media.
One limitation of RIP-based color profiles is that they do not allow for non-linear color transformations typically required for accurate color reproduction.
The DDK drivers and driver API provide two types of color profiles: non-linear 3D RGB or grayscale color lookup table-based profiles, linear and non-linear 2D device color lookup table-based profiles, and 2D color dithering tables. Driver profiles are available only as attributes in the printer's PPD file.
RGB profiles utilize 3D color lookup tables that map from sRGB color values to CMYK color values. Two PPD attributes, cupsRGBProfile and cupsRGBSample, are used to specify an RGB color profile. The cupsRGBProfile attribute specifies the number of samples on each side of the lookup cube, the number of color channels (1, 3, or 4 for K, CMY, and CMYK devices), and the number of color samples in the profile:
*cupsRGBProfile Glossy.720dpi: "3 4 27"
Currently, the number of color samples must equal the cube of the cube size, that is an RGB color profile with a cube size of 4 must have 4 * 4 * 4 = 64 color samples which map the sRGB colors to CMYK. Also, the RGB samples must be spread evenly over the color cube.
Each color sample is represented using cupsRGBSample attributes. The value of each attribute consists of the sRGB and CMYK color values separated by spaces. Each color value is a real number from 0 to 1. For example, a sample for black which maps to a CMYK color of 0,0,0,1 might look like the following:
*cupsRGBSample Glossy.720dpi: "0 0 0 0 0 0 1"
| Attribute | Description |
|---|---|
| cupsAllGamma | Set default curve using gamma + density |
| cupsAllXY | Set default curve using XY points |
| cupsBlackGamma | Set black curve using gamma + density |
| cupsBlackGeneration | Set black generation |
| cupsBlackLightDark | Set black light/dark transition |
| cupsBlackXY | Set black curve using XY points |
| cupsCyanGamma | Set cyan curve using gamma + density |
| cupsCyanLightDark | Set cyan light/dark transition |
| cupsCyanXY | Set cyan curve using XY points |
| cupsInkChannels | Set number of color channels |
| cupsInkLimit | Set total ink limit |
| cupsLightBlackGamma | Set light black curve using gamma + density |
| cupsLightBlackXY | Set light black curve using XY points |
| cupsLightCyanGamma | Set light cyan curve using gamma + density |
| cupsLightCyanXY | Set light cyan curve using XY points |
| cupsLightMagentaGamma | Set light magenta curve using gamma + density |
| cupsLightMagentaXY | Set light magenta curve using XY points |
| cupsMagentaGamma | Set magenta curve using gamma + density |
| cupsMagentaLightDark | Set magenta light/dark transition |
| cupsMagentaXY | Set magenta curve using XY points |
| cupsYellowGamma | Set yellow curve using gamma + density |
| cupsYellowXY | Set yellow curve using XY points |
Similarly, blue mapping to a CMYK value of 1,0.5,0,0 would look like:
*cupsRGBSample Glossy.720dpi: "0 0 1 1 0.5 0 0"
CMYK color profiles map K, CMY, or CMYK colors to device colors. They are normally used to provide linear CMYK output and to transition between light and dark inks. When combined with application or RGB profiles, CMYK profiles allow for easier profiling using existing 4-color profiling software.
The CMYK color profiles are implemented as 2D lookup tables; the tables can be generated automatically using gamma and density values, or manually using measurements of specific values. For printers that support more than 4 inks, the light ink lookup tables are driven by the main color, e.g. the light cyan output value is based upon the cyan input value.
CMYK color profiles are only available via PPD attributes. Table 6-1 lists the supported attributes. The cupsInkChannels attribute specifies the number of output color channels, typically 1, 3, 4, 6, or 7.
The cupsInkLimit attribute specifies the maximum amount of ink that can be placed on the page. When the total amount of ink exceeds the ink limit, all color channels are scaled linearly to the specified limit.
The cupsBlackGeneration attribute specifies a transition range for representing shades of gray as a combination of CMY or as K. The first number specifies the start of the transition range where K = 0 and the second the end of the transition range where CMY = 0.
The gamma attributes define the gamma and density of the specified color channel. For example, the following attribute sets the default gamma and density at 1440dpi to 2.0 and 0.9, respectively:
Attribute cupsAllGamma 1440dpi "2.0 0.9"
The XY attributes specify a point in a piecewise linear curve from an input color value to a measured output value. For example, the XY values for four measurements at 1440dpi would look like the following:
Attriute cupsAllXY 1440dpi "0.25 0.337"
Attriute cupsAllXY 1440dpi "0.5 0.633"
Attriute cupsAllXY 1440dpi "0.75 0.91"
Attriute cupsAllXY 1440dpi "1.0 1.24"
The LtDk ("light dark") attributes specify a transition area for light to dark inks using the dark ink lookup table. The first value specifies the input color value which maps to 100% of the light color output value and the second value specifies the input color value which maps to 0% of the light color output value. The dark color is mapped to 0 up to the first value and is ramped up to the second value as the light color decreases.
| Attribute | Description |
|---|---|
| cupsAllDither | Sets the default dither values |
| cupsBlackDither | Sets the black dither values |
| cupsCyanDither | Sets the cyan dither values |
| cupsLightBlackDither | Sets the light black dither values |
| cupsLightCyanDither | Sets the light cyan dither values |
| cupsLightMagentaDither | Sets the light magenta dither values |
| cupsMagentaDither | Sets the maenta dither values |
| cupsYellowDither | Sets the yellow dither values |
Once converted to device colors, the dither functions use PPD attributes to define the dot densities for each supported size. Table 6-2 lists the supported attributes. For example, the following attributes might be used to define the default dither values for three resolutions:
Attribute cupsAllDither 360dpi "0.5 0.75 1.0"
Attribute cupsAllDither 720dpi "0.6 0.9 1.2"
Attribute cupsAllDither 1440dpi "0.9 1.35"
This chapter describes how to upload PPD files to the CUPS web site and package your printer drivers for Linux and Mac OS X.
The easiest way to distribute your printer drivers is to upload your PPD files to the printer driver page on the CUPS web site (www.cups.org). This page provides an on-line printer driver database where CUPS users can search for and download PPD files for PostScript and CUPS/CUPS DDK-supported printers.
To upload PPD files for other CU