Articles · Book · Estimator · CUPS 1.1 · CUPS 1.2 · CUPS 1.3 · CUPS 1.4 · Other CUPS · Search Help CUPS Driver Development Kit Manual![]() CUPS Driver Development Kit ManualCUPS-DDK-1.2.3 Apple Inc. Copyright 2007 Table of ContentsPreface
PrefaceThis software users manual provides a step-by-step guide for using the CUPSTM Driver Development Kit ('DDK'), version 1.2.3. Software OverviewThe 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. Document OverviewThis software users manual is organized into the following sections:
Notation ConventionsVarious font and syntax conventions are used in this guide. Examples and their meanings and uses are explained below:
AbbreviationsThe following abbreviations are used throughout this manual:
Other References
Providing FeedbackFeedback 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
1 - Building and Installing the CUPS DDKThis 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). Before You BeginYou'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. Building the DDKThe DDK is built by first configuring the software and then compiling it. Configuring the SoftwareThe 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
Compiling the SoftwareOnce 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
Installing the DDKOnce 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. Installing Using the MakefileThe 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
Installing Using EPMThe 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
2 - Getting Started with the CUPS DDKThis chapter describes how to use the CUPS DDK and write PPD compiler source files. The BasicsThe 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
Using the PPD CompilerThe 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". Driver Information FilesThe 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.
A Simple ExampleThe 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. Grouping and InheritanceThe 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. Defining ConstantsSometimes 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
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)
...
}
Defining Color SupportFor 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.
Defining Custom Options and Option GroupsThe 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"
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. Defining ConstraintsConstraints 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"
Importing Existing PPD FilesThe 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. 3 - Developing Raster Printer DriversThis chapter describes how to develop PPD files for the included DDK raster printer drivers. The DDK DriversThe 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 DriverThe 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.
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
ModelNumber ConstantsTable 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. Writing a Basic HP LaserJet DriverNow 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)
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"
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
PJL AttributesThe 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:
Adding PJL Options to the Basic LaserJet DriverAll 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.
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
The ESC/P DriverThe 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
ModelNumber ConstantsTable 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. Writing a Basic Epson Stylus Photo R300 DriverNow 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.
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"
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
Epson Remote Mode AttributesMost 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. Adding Remote Mode Commands to the R300 DriverThe 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"
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
4 - Developing PostScript Printer DriversThis chapter describes how to develop PPD files for PostScript printer drivers. Overview of PostScript Driver DevelopmentThe 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
Required AttributesPostScript 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
Query CommandsMost 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. Adding FiltersNormally 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 -
Importing Existing PostScript DriversThe 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
5 - Localizing Printer DriversThis chapter describes how to localize printer drivers for different languages and defaults. Overview of the Localization ProcessThe 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. The Message Catalog File FormatEach 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 Localization UtilityThe 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.
Using a Message Catalog with the PPD CompilerOnce 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
Using Multiple Message CatalogsWhen 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
Merging Existing Single-Language PPD FilesThe 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
6 - Doing Raster Color ManagementThis chapter describes how to use the built-in raster color management functions to produce enhanced color and grayscale output on raster printers. Overview of Raster Color ManagementCUPS 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. RIP-Based Color ProfilesThe 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. Driver-Based Color ProfilesThe 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 Color ProfilesRGB 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"
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 ProfilesCMYK 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.
Dithering TablesOnce 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"
7 - Distributing Printer DriversThis chapter describes how to upload PPD files to the CUPS web site and package your printer drivers for Linux and Mac OS X. Uploading PPD Files to the CUPS Web SiteThe 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 CUPS users to download, click on the "Submit Printer Driver" link to start the registration process. Creating Printer Driver PackagesIf you will be distributing printer drivers from your own web site or on physical media, or if your printer drivers require one or more custom filter, port monitor, or backend programs, create packages containing the drivers so that users can install and remove the drivers as needed.
Printer drivers are typically distributed as RPM packages on Linux or Installer packages on Mac OS X. Each package typically installs PPD files (or driver information files , as described later) and filter/driver programs in the corresponding directories. Table 7-1 lists the directories to use on each operating system. If you will be distributing drivers for the Linux x86_64 platform, please see the section on "Packaging Issues on Linux" later in this chapter as well. Tools for Creating PackagesAside from the rpmbuild(8) and PackageMaker tools that come with Linux and Mac OS X, respectively, we recommend using our (free) ESP Package Manager (EPM) software to create your driver packages:
http://www.easysw.com/epm
EPM creates both RPM and Installer format packages, as well as several other common formats. It can also insulate you from system-specific packaging details that can lead to inconsistent package quality. Creating Driver Packages with EPMEPM works with "list" files. A list file literally lists the files you want to package along with common information such as the version of the package, a human-readable description of the package contents, and so forth. Listing 7-1 provides an example list file for a driver package consisting of one filter program called rastertofoo and three PPD files. The list file starts with the common informations (lines 1-8). Lines 12-14 and 16-18 define the installation directories for Mac OS X and Linux, respectively. Lines 20-25 implement one of the suggested workarounds for supporting Linux on the x86_64 platform. Finally, lines 30-33 list the files we want in the package along with the permissions and ownership. The destination filename is listed first, followed by the source filename relative to the current directory. You can then create the package using the epm(1) command. For example, type the following command to create a driver package called "foo" using the native packaging format on your system:
epm -f native foo foo.list
Packaging Drivers Using Standard CUPS DriversWhen packaging drivers that use the DDK or CUPS sample drivers, we recommend creating packages that depend on the corresponding CUPS or CUPS DDK software rather than bundling your own copies. For the CUPS DDK software, we recommend downloading and redistributing the packages from the CUPS web site (www.cups.org). If you are using EPM to create your driver packages on Linux, add the following lines to your list file:
%system linux
%requires cupsddk-drivers
%system
These will ensure that the CUPS DDK drivers are installed on the system. Packaging Issues on LinuxBecause the CUPS packages provided on the Linux x86_64 platform can use one of two different directories for any filter programs, we recommend installing to /usr/lib/cups/filter and including the following pre-install command to ensure that at symlink is present from /usr/lib/cups to /usr/lib64/cups on systems that use /usr/lib64/cups/filter:
if test -d /usr/lib64/cups -a ! -d /usr/lib/cups; then
ln -s /usr/lib64/cups /usr/lib
fi
Another option is to install your Linux drivers in /opt/ vendor/filter and then reference that directory in the cupsFilter attributes of your PPD files, for example:
// Attribute as it appears in the driver information file...
Attribute cupsFilter "" ""
"application/vnd.cups-raster - /opt/vendor/filter"
*% Attribute as it appears in the PPD file:
*cupsFilter: "application/vnd.cups-raster - /opt/vendor/filter"
Distributing Driver Information Files Instead of PPDsIf you are supplying drivers that will only be used on systems running CUPS 1.2 or higher, and if the CUPS DDK drivers are also installed, you can distribute the driver information and message catalog files you use with the PPD compiler instead of the generated PPD files, often leading to noticeable reductions in package size. Driver information and message catalog files are installed in a /usr/share/cups/drv/vendor subdirectory. The PPD compiler's driver interface to CUPS automatically sees the new files as soon as they are installed. A - Software License AgreementThis appendix provides the software license agreement for the CUPS DDK and included drivers. CUPS Driver Development Kit License AgreementCopyright 2007 by Apple Inc.
IntroductionThe CUPSTM Driver Development Kit ("DDK") is provided under the GNU General Public License ("GPL") version 2. For those not familiar with the GNU GPL, the license basically allows you to:
What this license does not allow you to do is make changes or add features to the CUPS DDK and then sell a binary distribution without source code. You must provide source for any new drivers, changes, or additions to the software, and all code must be provided under the GPL. TrademarksApple Inc. has trademarked the Common UNIX Printing System, CUPS, and CUPS logo. These names and logos may be used freely in any direct port or binary distribution of the CUPS DDK. Please contact Apple Inc. for written permission to use them in derivative products. Our intention is to protect the value of these trademarks and ensure that any derivative product meets the same high-quality standards as the original. GNU GENERAL PUBLIC LICENSEVersion 2, June 1991 Copyright 1989, 1991 Free Software Foundation, Inc. 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. PreambleThe licenses for most software are designed to take away your freedom to share and change it. By contrast, the GNU General Public License is intended to guarantee your freedom to share and change free software--to make sure the software is free for all its users. This General Public License applies to most of the Free Software Foundation's software and to any other program whose authors commit to using it. (Some other Free Software Foundation software is covered by the GNU Library General Public License instead.) You can apply it to your programs, too. When we speak of free software, we are referring to freedom, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for this service if you wish), that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs; and that you know you can do these things. To protect your rights, we need to make restrictions that forbid anyone to deny you these rights or to ask you to surrender the rights. These restrictions translate to certain responsibilities for you if you distribute copies of the software, or if you modify it. For example, if you distribute copies of such a program, whether gratis or for a fee, you must give the recipients all the rights that you have. You must make sure that they, too, receive or can get the source code. And you must show them these terms so they know their rights. We protect your rights with two steps: (1) copyright the software, and (2) offer you this license which gives you legal permission to copy, distribute and/or modify the software. Also, for each author's protection and ours, we want to make certain that everyone understands that there is no warranty for this free software. If the software is modified by someone else and passed on, we want its recipients to know that what they have is not the original, so that any problems introduced by others will not reflect on the original authors' reputations. Finally, any free program is threatened constantly by software patents. We wish to avoid the danger that redistributors of a free program will individually obtain patent licenses, in effect making the program proprietary. To prevent this, we have made it clear that any patent must be licensed for everyone's free use or not licensed at all. The precise terms and conditions for copying, distribution and modification follow. GNU GENERAL PUBLIC LICENSE
| |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Note:
Because of certain API binary compatibility issues, CUPS limits the length of PPD group translation strings (text) to 40 characters, while the PPD specification allows for up to 80 characters. |
Choice, ColorModel, Cutter, Darkness, Duplex, Finishing, InputSlot, Installable, MediaType, Option, Resolution , UIConstraints
HWMargins left bottom right top
HWMargins 18 36 18 36
HWMargins 0.25in 0.5in 0.25in 0.5in
HWMargins 0.6cm 1.2cm 0.6cm 1.2cm
The HWMargins directive specifies the current margins for MediaSize that follow. The left, bottom, right, and top margin values specify the printable margins.
InputSlot position name
InputSlot position "name/text"
InputSlot 0 Auto
InputSlot 1 "Upper/Tray 1"
The InputSlot directive adds a new choice to the InputSlot option. The position argument is a number from 0 to 2 32-1 specifying the value that is placed in the MediaPosition attribute in the PostScript page device dictionary.
The name is any combination of letters, numbers, and the underscore and can be up to 40 characters in length.
If provided, the text can be any string up to 80 characters in length. If no text is provided, the name is used.
Choice, ColorModel, Cutter, Darkness, Duplex, Finishing, Group, Installable, MediaType, Option, Resolution , UIConstraints
Installable name
Installable "name/text"
Installable EnvTray
Installable "Option1/Duplexer Installed"
The Installable directive adds a new boolean option to the InstallableOptions group with a default value of False. The name is any combination of letters, numbers, and the underscore and can be up to 40 characters in length.
If provided, the text can be any string up to 80 characters in length. If no text is provided, the name is used.
ManualCopies boolean-value
ManualCopies no
ManualCopies yes
The ManualCopies directive specifies whether copies need to be produced by the RIP filters. The default is no.
Choice, ColorModel, Cutter, Darkness, Duplex, Finishing, Group, InputSlot, MediaType, Option, Resolution, UIConstraints
Manufacturer "name"
Manufacturer "Foo"
Manufacturer "HP"
The Manufacturer directive specifies the manufacturer name for the current driver. The name argument must conform to the manufacturer name requirements in the Adobe PPD file specification.
ModelName, PCFileName, Version
MaxSize width length
MaxSize 36in 100ft
MaxSize 300cm 30m
The MaxSize directive specifies the maximum width and length that is supported for custom page sizes.
MediaSize name
MediaSize Letter
MediaSize A4
The MediaSize directive adds the named size to the current printer driver using the current margins defined with the HWMargins directive. The name argument must match a media size defined using the #media directive.
MediaType type name
MediaType type "name/text"
MediaType 0 Auto
MediaType 1 "Plain/Plain Paper"
The MediaType directive adds a new choice to the MediaType option. The type argument is a number from 0 to 232 -1 specifying the value that is placed in the cupsMediaType attribute in the PostScript page device dictionary.
The name is any combination of letters, numbers, and the underscore and can be up to 40 characters in length. The name is placed in the MediaType attribute in the PostScript page device dictionary.
If provided, the text can be any string up to 80 characters in length. If no text is provided, the name is used.
Choice, ColorModel, Cutter, Darkness, Duplex, Finishing, Group, InputSlot, Installable, Option, Resolution, UIConstraints
MinSize width length
MinSize 4in 8in
MinSize 10cm 20cm
The MinSize directive specifies the minimum width and length that is supported for custom page sizes.
ModelName "name"
ModelName "Foo Laser Printer 2000"
ModelName "Colorific 123"
The ModelName directive sets the printer name for the ModelName, NickName, and ShortNickName attributes for the printer driver. The name is any string of letters, numbers, spaces, and the characters ".", "/", "-", and "+" and should not begin with the manufacturer name since the PPD compiler will add this automatically for you. The maximum length of the name string is 31 characters to conform to the Adobe limits on the length of ShortNickName.
Manufacturer, PCFileName, Version
ModelNumber number
ModelNumber 123
ModelNumber ($PCL_PAPER_SIZE $PCL_PJL)
The ModelNumber directive sets the cupsModelNumber attribute for the printer driver, which is often used by the printer driver filter to tailor its output for the current device. The number is any integer or bitwise OR of integers and constants that is appropriate for the printer driver filters.
A complete list of printer driver model number constants is available later in this appendix in the section titled, " Printer Driver ModelNumber Constants".
Option name type section order
Option "name/text" type section order
Option Punch Boolean AnySetup 10
Option "fooFinish/Finishing Option" PickOne DocumentSetup 10
The Option directive creates a new option in the current group, by default the General group. The name is any combination of letters, numbers, and the underscore and can be up to 40 characters in length.
If provided, the text can be any string up to 80 characters in length. If no text is provided, the name is used.
The type argument is one of the following keywords:
The section argument is one of the following keywords:
The order argument is a real number greater than or equal to 0.0 and is used to sort the printer commands from many options before sending them to the printer or RIP filter.
Choice, ColorModel, Cutter, Darkness, Duplex, Finishing, Group, InputSlot, Installable, MediaType, Resolution, UIConstraints
PCFileName "filename.ppd"
PCFileName "foljt2k1.ppd"
PCFileName "deskjet.ppd"
The PCFileName attribute specifies the name of the PPD file for the current driver. The filename argument must conform to the Adobe PPD file specification and can be no more than 8 filename characters plus the extension ".ppd".
Manufacturer, ModelName, Version
Resolution colorspace bits-per-color row-count row-feed row-step name
Resolution colorspace bits-per-color row-count row-feed row-step "name/text"
Resolution - 8 0 0 0 300dpi
Resolution k 8 0 0 0 "600x300dpi/600 DPI Grayscale"
The Resolution directive creates a new Resolution option choice which sets the HWResolution, cupsBitsPerColor, cupsRowCount, cupsRowFeed, cupsRowStep, and optionally the cupsColorSpace page device dictionary attributes. The colorspace argument specifies a colorspace to use for the specified resolution and can be the hyphen (-) character to make no change to the selected color model or any keyword listed in the section titled, "Colorspace Keywords", to force the named colorspace.
The bits-per-color argument specifies the number of bits per color to generate when RIP'ing a job. The values 1, 2, 4, and 8 are currently supported by CUPS.
The row-count, row-feed, and row-step argument specify the driver-dependent values for the cupsRowCount, cupsRowFeed , and cupsRowStep attributes, respectively. Most drivers leave these attributes set to 0, but any number from 0 to 232-1 is allowed.
The name argument must conform to the resolution naming conventions in the Adobe PPD file specification, either HHHdpi for symmetric resolutions or HHHxVVVdpi for asymmetric resolutions. The HHH and VVV in the examples represent the horizontal and vertical resolutions which must be positive integer values.
If provided, the text can be any string up to 80 characters in length. If no text is provided, the name is used.
Choice, ColorModel, Cutter, Darkness, Duplex, Finishing, Group, InputSlot, Installable, MediaType, Option, UIConstraints
SimpleColorProfile resolution/mediatype density
yellow-density red-density gamma
red-adjust green-adjust blue-adjust
SimpleColorProfile -/- 100 100 200 1.0 0 0 0
SimpleColorProfile 360dpi/- 100 95 150 1.2 5 10 15
SimpleColorProfile 720dpi/Glossy 100 90 120 1.5 -5 5 10
The SimpleColorProfile directive creates a matrix-based ColorProfile using values chosen with the cupsprofile(1) utility. The resolution and mediatype arguments specify the Resolution and MediaType choices which use the profile; the hyphen (-) is used to specify that any resolution or mediatype can be used with the profile.
The density argument specifies the linear density correction to apply to the color values (P = d * 0.01 * pg) and is an integer greater than 0 and less than or equal to 100. A value 100 of disables density correction while lower values produce proportionately lighter output. The density value adjusts all color channels equally in all color modes.
The yellow-density argument specifies the density of the yellow channel when printing in grayscale or RGB mode and is an integer greater than 0 and less then or equal to 100. A value of 100 disables yellow density correction while lower values produce proportionately lighter output.
The red-density argument specifies the two-color density limit (e.g. C + M, C + Y, M + Y) when printing in grayscale or RGB mode and is an integer greater than 0 and less then or equal to 200. A value of 200 disables two-color density correction while lower values produce proportionately lighter output.
The gamma argument specifies the gamma correction to apply to the color values (P = pg) and is a real number greater than 0. Values larger than 1 cause a general lightening of the print while values smaller than 1 cause a general darkening of the print. A value of 1 disables gamma correction.
The red-adjust, green-adjust, blue-adjust arguments specify the percentage of color to add or remove. Positive red-adjust values add magenta and negative values add yellow. Positive green-adjust values add cyan and negative values add yellow. Positive blue-adjust values add cyan and negative values add magenta. Values of 0 disable color adjustments.
Throughput pages-per-minute
Throughput 1
Throughput 10
The Througput directive sets the Troughput attribute for the current printer driver. The pages-per-minute argument is a positive integer representing the peak number of pages per minute that the printer is capable of producing. Use a value of 1 for printers that produce less than 1 page per minute.
UIConstraints "*Option1 *Option2"
UIConstraints "*Option1 Choice1 *Option2"
UIConstraints "*Option1 *Option2 Choice2"
UIConstraints "*Option1 Choice1 *Option2 Choice2"
UIConstraints "*Finishing *MediaType"
UIConstraints "*Option1 False *Duplex"
UIConstraints "*Duplex *MediaType Transparency"
UIConstraints "*Resolution 600dpi *ColorModel RGB"
The UIConstraints directive adds a constraint between two options. Constraints inform the application when a user has chosen incompatible options. 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.
Choice, ColorModel, Cutter, Darkness, Duplex, Finishing, Group, InputSlot, Installable, MediaType, Option, Resolution
VariablePaperSize boolean-value
VariablePaperSize yes
VariablePaperSize no
The VariablePaperSize directive specifies whether the current printer supports variable (custom) page sizes. When yes is specified, the PPD compiler will include the standard PPD attributes required to support custom page sizes.
Version number
Version 1.0
Version 3.7
The Version directive sets the FileVersion attribute in the PPD file and is also used for the NickName attribute. The number argument is a positive real number.
Manufacturer, ModelName, PCFileName
Table B-1 shows the standard include files which are provided with the DDK.
| Include File | Description |
|---|---|
| <font.defs> | Defines all of the standard fonts which are included with ESP Ghostscript and the Apple PDF RIP. |
| <epson.h> | Defines all of the CUPS ESC/P sample driver constants. |
| <escp.h> | Defines all of the DDK ESC/P driver constants. |
| <hp.h> | Defines all of the CUPS HP-PCL sample driver constants. |
| <label.h> | Defines all of the CUPS label sample driver constants. |
| <media.defs> | Defines all of the standard media sizes listed in Appendix B of the Adobe PostScript Printer Description File Format Specification. |
| <pcl.h> | Defines all of the DDK HP-PCL driver constants. |
| <raster.defs> | Defines all of the CUPS raster format constants. |
The CUPS DDK and sample drivers use the cupsModelNumber attribute in the PPD file to tailor their output to the printer. The following sections describe the constants for each driver.
The epson driver supports Epson and Okidata dot-matrix, Epson Stylus Color, and Epson Stylus Photo printers. Table B-2 lists the constants for the ModelNumber directive. ModelNumber values should be inserted by referencing only one of these constants.
| Constant | Description |
|---|---|
| EPSON_9PIN | Epson and Okidata 9-pin dot-matrix printers |
| EPSON_24PIN | Epson and Okidata 24-pin dot-matrix printers |
| EPSON_COLOR | Older Epson Stylus Color printers that use the ESC . graphics command |
| EPSON_PHOTO | Older Epson Stylus Photo printers that use the ESC . graphics command |
| EPSON_ICOLOR | Newer Epson Stylus Color printers that use the ESC i graphics command |
| EPSON_IPHOTO | Newer Epson Stylus Photo printers that use the ESC i graphics command |
The hp driver supports HP LaserJet and DeskJet printers. Table B-3 lists the constants for the ModelNumber directive. ModelNumber values should be inserted by referencing only one of these constants.
| Constant | Description |
|---|---|
| HP_LASERJET | HP LaserJet printers supporting PCL 3, 4, or 5 |
| HP_DESKJET | HP DeskJet printers supporting PCL 3 and using the simple color graphics command (ESC * r # U) |
| HP_DESKJET2 | HP DeskJet printers supporting PCL3GUI and using the configure raster graphics command (ESC * g # W) |
The label driver supports the Dymo Labelwriter, Zebra CPCL, Zebra EPL, and Zebra ZPL, and Intellitech PCL label printers. Table B-4 lists the constants for the ModelNumber directive. ModelNumber values should be inserted by referencing only one of these constants.
| Constant | Description |
|---|---|
| DYMO_3x0 | Format output for the Dymo Labelwriter 300, 330, or 330 Turbo. |
| INTELLITECH_PCL | Format output for the Intellitech PCL printers. |
| ZEBRA_CPCL | Format output for the Zebra CPCL printers. |
| ZEBRA_EPL_LINE | Format output for the Zebra EPL line mode (EPL 1) printers. |
| ZEBRA_EPL_PAGE | Format output for the Zebra EPL page mode (EPL 2) printers. |
| ZEBRA_ZPL | Format output for the Zebra ZPL printers. |
The escp driver supports all Epson inkjet printers. Table B-6 lists the constants for the ModelNumber directive. ModelNumber values should be specified as the bitwise OR of one or more of these constants.
| 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 |
| ESCP_REMOTE_AC | Use auto-cutter command |
| ESCP_REMOTE_CO | Use cutter-operation command |
| ESCP_REMOTE_EX | Use media-position command |
| ESCP_REMOTE_MS | Use media-size command |
| ESCP_REMOTE_MT | Use media-type command |
| ESCP_REMOTE_PC | Use paper-check command |
| ESCP_REMOTE_PH | Use paper-thickness command |
| ESCP_REMOTE_PP | Use paper-path command |
| ESCP_REMOTE_SN0 | Use feed-sequence-0 command |
| ESCP_REMOTE_SN1 | Use platten-gap command |
| ESCP_REMOTE_SN2 | Use feed-sequence-2 command |
| ESCP_REMOTE_SN6 | Use eject-delay command |
| ESCP_REMOTE_FP | Use print-position command |
The pcl driver supports all HP LaserJet, DeskJet, and DesignJet printers. Table B-5 lists the constants for the ModelNumber directive. ModelNumber values should be specified as the bitwise OR of one or more of these constants.
| 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 PPD compiler defines two types of color keywords: colorspace and color order. The following sections list the supported keywords for each type.
The following colorspace keywords are recognized:
The following color order keywords are recognized:
This appendix provides a reference for the CUPS driver API included with the CUPS DDK.
The CUPS driver API provides a single header file called driver.h. You include it using the following preprocessor command:
#include <cups/driver.h>
The CUPS driver API is provided in a single library called cupsdriver. The driver API also depends upon the CUPS imaging API and CUPS API libraries. A typical link command will look like the following:
cc -o rastertomyprinter rastertomyprinter.o -lcupsdriver \
-lcupsimage -lcups -lm ENTER
Delete a color separation.
void
cupsCMYKDelete(
cups_cmyk_t * cmyk);
| Name | Description |
|---|---|
| cmyk | Color separation |
Nothing.
Do a black separation...
void
cupsCMYKDoBlack(
const cups_cmyk_t * cmyk,
const unsigned char * input,
short * output,
int num_pixels);
| Name | Description |
|---|---|
| cmyk | Color separation |
| input | Input grayscale pixels |
| output | Output Device-N pixels |
| num_pixels | Number of pixels |
Nothing.
Do a CMYK separation...
void
cupsCMYKDoCMYK(
const cups_cmyk_t * cmyk,
const unsigned char * input,
short * output,
int num_pixels);
| Name | Description |
|---|---|
| cmyk | Color separation |
| input | Input grayscale pixels |
| output | Output Device-N pixels |
| num_pixels | Number of pixels |
Nothing.
Do a grayscale separation...
void
cupsCMYKDoGray(
const cups_cmyk_t * cmyk,
const unsigned char * input,
short * output,
int num_pixels);
| Name | Description |
|---|---|
| cmyk | Color separation |
| input | Input grayscale pixels |
| output | Output Device-N pixels |
| num_pixels | Number of pixels |
Nothing.
Do an sRGB separation...
void
cupsCMYKDoRGB(
const cups_cmyk_t * cmyk,
const unsigned char * input,
short * output,
int num_pixels);
| Name | Description |
|---|---|
| cmyk | Color separation |
| input | Input grayscale pixels |
| output | Output Device-N pixels |
| num_pixels | Number of pixels |
Nothing.
Load a CMYK color profile from PPD attributes.
cups_cmyk_t * cupsCMYKLoad( ppd_file_t * ppd, const char * colormodel, const char * media, const char * resolution);
| Name | Description |
|---|---|
| ppd | PPD file |
| colormodel | ColorModel value |
| media | MediaType value |
| resolution | Resolution value |
CMYK color separation
Create a new CMYK color separation.
cups_cmyk_t * cupsCMYKNew( int num_channels);
| Name | Description |
|---|---|
| num_channels | Number of color components |
New CMYK separation or NULL
Set the transition range for CMY to black.
void
cupsCMYKSetBlack(
cups_cmyk_t * cmyk,
float lower,
float upper);
| Name | Description |
|---|---|
| cmyk | CMYK color separation |
| lower | No black ink |
| upper | Only black ink |
Nothing.
Set a color transform curve using points.
void
cupsCMYKSetCurve(
cups_cmyk_t * cmyk,
int channel,
int num_xypoints,
const float * xypoints);
| Name | Description |
|---|---|
| cmyk | CMYK color separation |
| channel | Color channel |
| num_xypoints | Number of X,Y points |
| xypoints | X,Y points |
Nothing.
Set a color transform curve using gamma and density.
void
cupsCMYKSetGamma(
cups_cmyk_t * cmyk,
int channel,
float gamval,
float density);
| Name | Description |
|---|---|
| cmyk | CMYK color separation |
| channel | Ink channel |
| gamval | Gamma correction |
| density | Maximum density |
Nothing.
Set the limit on the amount of ink.
void
cupsCMYKSetInkLimit(
cups_cmyk_t * cmyk,
float limit);
| Name | Description |
|---|---|
| cmyk | CMYK color separation |
| limit | Limit of ink |
Nothing.
Set light/dark ink transforms.
void
cupsCMYKSetLtDk(
cups_cmyk_t * cmyk,
int channel,
float light,
float dark);
| Name | Description |
|---|---|
| cmyk | CMYK color separation |
| channel | Dark ink channel (+1 for light) |
| light | Light ink only level |
| dark | Dark ink only level |
Nothing.
Check to see if all bytes are zero.
int
cupsCheckBytes(
const unsigned char * bytes,
int length);
| Name | Description |
|---|---|
| bytes | Bytes to check |
| length | Number of bytes to check |
1 if they match
Check to see if all bytes match the given value.
int
cupsCheckValue(
const unsigned char * bytes,
int length,
const unsigned char value);
| Name | Description |
|---|---|
| bytes | Bytes to check |
| length | Number of bytes to check |
| value | Value to check |
1 if they match
Free a dithering buffer. Returns 0 on success, -1 on failure.
void
cupsDitherDelete(
cups_dither_t * d);
| Name | Description |
|---|---|
| d | Dithering buffer |
Nothing.
Dither a line of pixels...
void
cupsDitherLine(
cups_dither_t * d,
const cups_lut_t * lut,
const short * data,
int num_channels,
unsigned char * p);
| Name | Description |
|---|---|
| d | Dither data |
| lut | Lookup table |
| data | Separation data |
| num_channels | Number of components |
| p | Pixels |
Nothing.
Create an error-diffusion dithering buffer.
cups_dither_t * cupsDitherNew( int width);
| Name | Description |
|---|---|
| width | Width of output in pixels |
New state array
Find a PPD attribute based on the colormodel, media, and resolution.
ppd_attr_t *
cupsFindAttr(
ppd_file_t * ppd,
const char * name,
const char * colormodel,
const char * media,
const char * resolution,
char * spec,
int specsize);
| Name | Description |
|---|---|
| ppd | PPD file |
| name | Attribute name |
| colormodel | Color model |
| media | Media type |
| resolution | Resolution |
| spec | Final selection string |
| specsize | Size of string buffer |
Matching attribute or NULL
Free the memory used by a lookup table.
void
cupsLutDelete(
cups_lut_t * lut);
| Name | Description |
|---|---|
| lut | Lookup table to free |
Nothing.
Load a LUT from a PPD file.
cups_lut_t * cupsLutLoad( ppd_file_t * ppd, const char * colormodel, const char * media, const char * resolution, const char * ink);
| Name | Description |
|---|---|
| ppd | PPD file |
| colormodel | Color model |
| media | Media type |
| resolution | Resolution |
| ink | Ink name |
New lookup table
Make a lookup table from a list of pixel values. Returns a pointer to the lookup table on success, NULL on failure.
cups_lut_t * cupsLutNew( int num_values, const float * values);
| Name | Description |
|---|---|
| num_values | Number of values |
| values | Lookup table values |
New lookup table
Pack pixels horizontally...
void
cupsPackHorizontal(
const unsigned char * ipixels,
unsigned char * obytes,
int width,
const unsigned char clearto,
const int step);
| Name | Description |
|---|---|
| ipixels | Input pixels |
| obytes | Output bytes |
| width | Number of pixels |
| clearto | Initial value of bytes |
| step | Step value between pixels |
Nothing.
Pack 2-bit pixels horizontally...
void
cupsPackHorizontal2(
const unsigned char * ipixels,
unsigned char * obytes,
int width,
const int step);
| Name | Description |
|---|---|
| ipixels | Input pixels |
| obytes | Output bytes |
| width | Number of pixels |
| step | Stepping value |
Nothing.
Pack pixels horizontally by bit...
void
cupsPackHorizontalBit(
const unsigned char * ipixels,
unsigned char * obytes,
int width,
const unsigned char clearto,
const unsigned char bit);
| Name | Description |
|---|---|
| ipixels | Input pixels |
| obytes | Output bytes |
| width | Number of pixels |
| clearto | Initial value of bytes |
| bit | Bit to check |
Nothing.
Pack pixels vertically...
void
cupsPackVertical(
const unsigned char * ipixels,
unsigned char * obytes,
int width,
const unsigned char bit,
const int step);
| Name | Description |
|---|---|
| ipixels | Input pixels |
| obytes | Output bytes |
| width | Number of input pixels |
| bit | Output bit |
| step | Number of bytes between columns |
Nothing.
Delete a color separation.
void
cupsRGBDelete(
cups_rgb_t * rgbptr);
| Name | Description |
|---|---|
| rgbptr | Color separation |
Nothing.
Do a grayscale separation...
void
cupsRGBDoGray(
cups_rgb_t * rgbptr,
const unsigned char * input,
unsigned char * output,
int num_pixels);
| Name | Description |
|---|---|
| rgbptr | Color separation |
| input | Input grayscale pixels |
| output | Output Device-N pixels |
| num_pixels | Number of pixels |
Nothing.
Do a RGB separation...
void
cupsRGBDoRGB(
cups_rgb_t * rgbptr,
const unsigned char * input,
unsigned char * output,
int num_pixels);
| Name | Description |
|---|---|
| rgbptr | Color separation |
| input | Input RGB pixels |
| output | Output Device-N pixels |
| num_pixels | Number of pixels |
Nothing.
Load a RGB color profile from a PPD file.
cups_rgb_t * cupsRGBLoad( ppd_file_t * ppd, const char * colormodel, const char * media, const char * resolution);
| Name | Description |
|---|---|
| ppd | PPD file |
| colormodel | Color model |
| media | Media type |
| resolution | Resolution |
New color profile
Create a new RGB color separation.
cups_rgb_t * cupsRGBNew( int num_samples, cups_sample_t * samples, int cube_size, int num_channels);
| Name | Description |
|---|---|
| num_samples | Number of samples |
| samples | Samples |
| cube_size | Size of LUT cube |
| num_channels | Number of color components |
New color separation or NULL
Simple CMYK lookup table
struct cups_cmyk_s
{
unsigned char black_lut[256];
short * channels[CUPS_MAX_CHAN];
unsigned char color_lut[256];
int ink_limit;
int num_channels;
};
| Name | Description |
|---|---|
| black_lut[256] | Black generation LUT |
| channels[CUPS_MAX_CHAN] | Lookup tables |
| color_lut[256] | Color removal LUT |
| ink_limit | Ink limit |
| num_channels | Number of components |
Dithering State
struct cups_dither_s
{
int errors[96];
int row;
int width;
};
| Name | Description |
|---|---|
| errors[96] | Error values |
| row | Current row |
| width | Width of buffer |
Lookup Table for Dithering
struct cups_lut_s
{
int error;
short intensity;
short pixel;
};
| Name | Description |
|---|---|
| error | Error from desired value |
| intensity | Adjusted intensity |
| pixel | Output pixel value |
Color separation lookup table
struct cups_rgb_s
{
unsigned char black[CUPS_MAX_RGB];
int cache_init;
unsigned char **** colors;
int cube_index[256];
int cube_mult[256];
int cube_size;
int num_channels;
unsigned char white[CUPS_MAX_RGB];
};
| Name | Description |
|---|---|
| black[CUPS_MAX_RGB] | Cached black (sRGB = 0,0,0) |
| cache_init | Are cached values initialized? |
| colors | 4-D array of sample values |
| cube_index[256] | Index into cube for a given sRGB value |
| cube_mult[256] | Multiplier value for a given sRGB value |
| cube_size | Size of color cube (2-N) on a side |
| num_channels | Number of colors per sample |
| white[CUPS_MAX_RGB] | Cached white (sRGB = 255,255,255) |
Color sample point
struct cups_sample_s
{
unsigned char colors[CUPS_MAX_RGB];
unsigned char rgb[3];
};
| Name | Description |
|---|---|
| colors[CUPS_MAX_RGB] | Color values |
| rgb[3] | sRGB values |
Simple CMYK lookup table
typedef struct cups_cmyk_s cups_cmyk_t;
Dithering State
typedef struct cups_dither_s cups_dither_t;
Lookup Table for Dithering
typedef struct cups_lut_s cups_lut_t;
Color separation lookup table
typedef struct cups_rgb_s cups_rgb_t;
Color sample point
typedef struct cups_sample_s cups_sample_t;
sRGB gamma lookup table (inverted)
extern const unsigned char cups_scmy_lut[256];
sRGB gamma lookup table
extern const unsigned char cups_srgb_lut[256];
This appendix provides copies of all of the man pages included with the CUPS DDK.
The -D option sets the named variable for use in the source file. It is equivalent to using the #define directive in the source file.
The -I option specifies an alternate include directory; multiple -I options can be supplied to add additional directories.
The -c option specifies a single message catalog file in GNU gettext source format (filename.po) to be used for localization.
The -d option specifies the output directory for PPD files. The default output directory is "ppd".
The -l option specifies one or more languages to use when localizing the PPD file(s). The default language is "en" (English). Separate multiple languages with commas, for example "de_DE,en_UK,es_ES,es_MX,es_US,fr_CA,fr_FR,it_IT" will create PPD files with German, UK English, Spanish (Spain, Mexico, and US), French (France and Canada), and Italian languages in each file.
The -v option provides more verbose output, basically a running status of which files are being loaded or written.
The -z option generates compressed PPD files (filename.ppd.gz). The default is to generate uncompressed PPD files.
The --cr, --crlf, and --lf options specify the line ending to use - carriage return, carriage return and line feed, or line feed. The default is to use the line feed character alone.
The -I option specifies an alternate include directory; multiple -I options can be supplied to add additional directories.
The -o option specifies the PPD source file to update. If the source file does not exist, a new source file is created. Otherwise the existing file is merged with the new PPD file(s) on the command-line. If no source file is specified, the filename "ppdi.drv" is used.
The -o option specifies the PPD file to create. If not specified, the merged PPD file is written to the standard output. If the output file already exists, the new
The -I option specifies an alternate include directory; multiple -I options can be supplied to add additional directories.
The -o option specifies the output file.
This appendix provides a description of the changes in each release of the CUPS DDK.