3 - Developing Raster Printer Drivers

This chapter describes how to develop PPD files for the included DDK raster printer drivers.

The DDK Drivers

The DDK includes two general-purpose raster printer drivers that support the HP-PCL and ESC/P languages. Driver information files based upon these drivers can use a driver-specific include file and the DriverType directive.

Both drivers offer color management and dithering capabilities which are described in detail in Chapter 6, Doing Raster Color Management.

The HP-PCL Driver

The HP-PCL driver includes a printer command filter called commandtopclx and a raster printer driver filter called rastertopclx. The command filter supports head cleaning, printing a self-test page, and ink cartridge alignment.

Table 3-1, HP-PCL ModelNumber 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 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 Constants

Table 3-1 shows the constants that are defined in the <pcl.h> include file. These constants are used with the ModelNumber directive to control the behavior of the driver. For example, a typical PCL laser printer would use the following ModelNumber specification:

    ModelNumber ($PCL_PAPER_SIZE $PCL_PJL $PCL_PJL_RESOLUTION)

The parenthesis around the PCL constants tell the PPD compiler to compute the bitwise OR of each of the values. The HP-PCL driver will then use this information to tailor the output of the driver for the printer, in this case to use Printer Job Language ("PJL") commands to setup the job, including the PJL resolution command, and to use the PCL 3 paper size command. Table 3-2 shows the constants to use for several common types of HP printers.

Writing a Basic HP LaserJet Driver

Now that we have covered the HP-PCL driver definitions, we will create a driver for the HP LaserJet 2100, 2200, and 2300 series printers which supports all of the features that are available via PCL 5. While these printers also support PostScript, the interpreters have several known problems with TrueType fonts which can only be bypassed by using the PCL 5 printing path.

All three models support printing at 300 and 600 DPI through PCL 5 graphics; the 1200 DPI resolution is only available through PostScript and PCL 6. Each printer has an optional high-capacity paper tray and the 2200 and 2300 series printers also offer an optional duplexing unit. Listing 3-1 shows the driver information file for a basic HP LaserJet driver which supports the three models.

The file starts with the usual #include directives and then sets the driver type and model number so that we use the HP-PCL driver with the output tailored to a HP LaserJet printer:

    // Specify that this driver uses the HP-PCL driver...
    DriverType pcl

    // Specify the driver options via the model number...
    ModelNumber ($PCL_PAPER_SIZE $PCL_PJL $PCL_PJL_RESOLUTION)
Table 3-2, ModelNumber values for common HP printers
Printer Model ModelNumber Value
HP Color LaserJet Series ($PCL_PAPER_SIZE $PCL_RASTER_END_COLOR $PCL_RASTER_CID $PCL_RASTER_SIMPLE $PCL_RASTER_RGB24 $PCL_PJL $PCL_PJL_RESOLUTION)
HP DesignJet, Desktop ($PCL_PAPER_SIZE $PCL_RASTER_END_COLOR $PCL_RASTER_CRD $PCL_PJL $PCL_PJL_PCL3GUI)
HP DesignJet, High-End ($PCL_PAPER_SIZE $PCL_RASTER_END_COLOR $PCL_RASTER_CID $PCL_RASTER_SIMPLE $PCL_RASTER_RGB24 $PCL_PJL $PCL_PJL_PAPERWIDTH $PCL_PJL_HPGL2 $PCL_PJL_RESOLUTION)
HP DesignJet, Mid-Range ($PCL_PAPER_SIZE $PCL_RASTER_END_COLOR $PCL_RASTER_CRD $PCL_RASTER_SIMPLE $PCL_RASTER_RGB24 $PCL_PJL $PCL_PJL_PAPERWIDTH $PCL_PJL_PCL3GUI $PCL_PJL_RESOLUTION)
HP DeskJet Series ($PCL_PAPER_SIZE $PCL_RASTER_END_COLOR $PCL_RASTER_CRD $PCL_PJL $PCL_PJL_PCL3GUI)
HP LaserJet Series ($PCL_PAPER_SIZE $PCL_PJL $PCL_PJL_RESOLUTION)
HP OfficeJet Series ($PCL_PAPER_SIZE $PCL_RASTER_END_COLOR $PCL_RASTER_CRD $PCL_PJL $PCL_PJL_PCL3GUI)
HP Photosmart Series ($PCL_PAPER_SIZE $PCL_RASTER_END_COLOR $PCL_RASTER_CRD $PCL_PJL $PCL_PJL_PCL3GUI)

Then we list all of the media sizes that are supported by the printers along with the margins that should be used:

    HWMargins 18 12 18 12
    *MediaSize Letter
    MediaSize Legal
    MediaSize Executive
    MediaSize Monarch
    MediaSize Statement
    MediaSize FanFoldGermanLegal

    HWMargins 18 12.72 18 12.72
    MediaSize Env10

    HWMargins 9.72 12 9.72 12
    MediaSize A4
    MediaSize A5
    MediaSize B5
    MediaSize EnvC5
    MediaSize EnvDL
    MediaSize EnvISOB5
    MediaSize Postcard
    MediaSize DoublePostcard

Next we use the ColorModel directive to specify that our driver only prints grayscale output using the black colorspace and PCL mode 3 raster compression:

    ColorModel Gray k chunky 3

These printers support printing at 300 and 600 DPI through HP-PCL 5, so we list those resolutions using the Resolution directive. We use 1 bit per color for 300 DPI to provide fast printing and 8 bits per color for 600 DPI to provide the highest quality:

    Resolution - 1 0 0 0 "300dpi/300 DPI"
    *Resolution - 8 0 0 0 "600dpi/600 DPI"

All of the models provide two standard paper trays and one optional tray. The first tray is used as both the multi-purpose and manual feed tray and gets listed twice. We also provide an "auto" tray which tells the printer to grab media from the first available location:

    *InputSlot 7 "Auto/Automatic Selection"
    InputSlot 2 "Manual/Tray 1 - Manual Feed"
    InputSlot 4 "Upper/Tray 1"
    InputSlot 1 "Lower/Tray 2"
    InputSlot 5 "LargeCapacity/Tray 3"
Listing 3-1, "examples/laserjet-basic.drv"
// Include standard font and media definitions
#include <font.defs>
#include <media.defs>

// Include HP-PCL driver definitions
#include <pcl.h>

// Specify that this driver uses the HP-PCL driver...
DriverType pcl

// Specify the driver options via the model number...
ModelNumber ($PCL_PAPER_SIZE $PCL_PJL $PCL_PJL_RESOLUTION)

// List the fonts that are supported, in this case all
// standard fonts...
Font *

// Manufacturer and driver version
Manufacturer "HP"
Version 1.0

// Supported page sizes and their margins
HWMargins 18 12 18 12
*MediaSize Letter
MediaSize Legal
MediaSize Executive
MediaSize Monarch
MediaSize Statement
MediaSize FanFoldGermanLegal

HWMargins 18 12.72 18 12.72
MediaSize Env10

HWMargins 9.72 12 9.72 12
MediaSize A4
MediaSize A5
MediaSize B5
MediaSize EnvC5
MediaSize EnvDL
MediaSize EnvISOB5
MediaSize Postcard
MediaSize DoublePostcard

// Only black-and-white output with mode 3 compression...
ColorModel Gray k chunky 3

// Supported input slots
*InputSlot 7 "Auto/Automatic Selection"
InputSlot 2 "Manual/Tray 1 - Manual Feed"
InputSlot 4 "Upper/Tray 1"
InputSlot 1 "Lower/Tray 2"
InputSlot 5 "LargeCapacity/Tray 3"
Listing 3-1, "examples/laserjet-basic.drv", continued...
// Supported resolutions
Resolution - 1 0 0 0 "300dpi/300 DPI"
*Resolution - 8 0 0 0 "600dpi/600 DPI"

// Tray 3 is an option...
Installable "OptionLargeCapacity/Tray 3 Installed"
UIConstraints "*OptionLargeCapacity False
               *InputSlot LargeCapacity"

{
  // HP LaserJet 2100 Series
  Throughput 10
  ModelName "LaserJet 2100 Series"
  PCFileName "hpljt211.ppd"
}

{
  // LaserJet 2200 and 2300 series have duplexer option...
  Duplex normal
  Installable "OptionDuplex/Duplexer Installed"
  UIConstraints "*OptionDuplex False *Duplex"

  {
    // HP LaserJet 2200 Series
    Throughput 19
    ModelName "LaserJet 2200 Series"
    PCFileName "hpljt221.ppd"
  }

  {
    // HP LaserJet 2300 Series
    Throughput 25
    ModelName "LaserJet 2300 Series"
    PCFileName "hpljt231.ppd"
  }
}

The numbers we used for the input slots are the PCL values associated with each tray; consult the HP-PCL Language Reference Manual for a complete list of possible values on all printers.

Since the third tray is an optional accessory, we list an installable option along with a constraint so that users may only select the third tray if it has been installed:

    Installable "OptionLargeCapacity/Tray 3 Installed"
    UIConstraints "*OptionLargeCapacity False *InputSlot LargeCapacity"

By convention, installable options usually begin with the prefix Option. Some vendors number the options, e.g. Option1, Option2, etc., however we have opted to use a more readable name, OptionLargeCapacity. Using a textual name also allows you to add additional installable options without renumbering existing options, and makes it easier to validate constraints.

The HP LaserJet 2200 and 2300 series printers also have an optional duplexer, which is listed using the Duplex directive along with another installable option and constraint:

    Duplex normal
    Installable "OptionDuplex/Duplexer Installed"
    UIConstraints "*OptionDuplex False *Duplex"

Again, we are using the more readable installable option name OptionDuplex instead of Option2.

We finish things up by using grouping to isolate the three printer models and provide unique values for the Throughput, ModelName, and PCFileName directives. Notice how we are able to group the duplex option and then share the definition with the 2200 and 2300 drivers:

    {
      // HP LaserJet 2100 Series
      Throughput 10
      ModelName "LaserJet 2100 Series"
      PCFileName "hpljt211.ppd"
    }

    {
      // LaserJet 2200 and 2300 series have duplexer option...
      Duplex normal
      Installable "OptionDuplex/Duplexer Installed"
      UIConstraints "*OptionDuplex False *Duplex"

      {
	// HP LaserJet 2200 Series
	Throughput 19
	ModelName "LaserJet 2200 Series"
	PCFileName "hpljt221.ppd"
      }

      {
	// HP LaserJet 2300 Series
	Throughput 25
	ModelName "LaserJet 2300 Series"
	PCFileName "hpljt231.ppd"
      }
    }

To test the new drivers, start by running the ppdc program to create the PPD files:

    ppdc laserjet-basic.drv ENTER

Then use the lpadmin(8) command to add the printer with the correct device URI. The following example adds a HP LaserJet 2100 which is connected via a JetDirect interface:

    lpadmin -p lj2100 -E -v socket://lj2100 -i ppd/hpljt211.ppd ENTER

Finally, print a test page to see it work:

    lp -d lj2100 /usr/share/cups/data/testprint.ps ENTER

PJL Attributes

The HP-PCL driver also supports extensive Printer Job Language (PJL) commands through a combination of PPD attributes and options. Table 3-3 lists the PJL attributes that are supported along with the PPD options they map to. PJL attributes are specified using the Attribute directive using the cupsPJL keyword. For example, the following attribute provides the PJL commands to enable or disable the resolution enhancement features of the printer:

    Attribute cupsPJL cupsRET
              "@PJL SET SMOOTHING=%?False:OFF;%?True:ON;%n"

The directive, Attribute, is followed by the attribute keyword, cupsPJL, the attribute name, cupsRET, and the attribute value, in this case a PJL command string. The command string consists of PJL command text and special substitution fields starting with the percent (%) character.

In the example above, the %? substitution conditionally inserts some text if the string matches the option value, typically the name of the choice. In this case, we have two conditional substitutions. The first inserts the text OFF if the cupsRET option is False, and the second inserts the text ON if the option is True. The syntax is as follows:

    %?look for:insert;

Multiple conditional substitutions can be listed up to about 230 characters - the PPD file format imposed a 255 character line length limit, and attribute values cannot span multiple lines.

Aside from conditional substitutions, the HP-PCL driver supports the following additional substitutions. Unknown substitutions are inserted verbatim:

Adding PJL Options to the Basic LaserJet Driver

All three HP LaserJet models support additional options via PJL commands. Listing 3-2 shows a modified version of the driver which adds support the resolution enhancement and toner saving features of the printers.

The new resolution enhancement option consists of a PPD attribute containing the cupsRET command followed by the cupsRET option. Since this option applies to the entire job, the option is placed in the DocumentSetup section:

    Attribute cupsPJL cupsRET
              "@PJL SET SMOOTHING=%?False:OFF;%?True:ON;%n"

    Option "cupsRET/Smoothing" Boolean DocumentSetup 10
      Choice "False/Off" ""
      *Choice "True/On" ""

The toner saving option is added the same way using the cupsTonerSave attribute and option:

    Attribute cupsPJL cupsTonerSave
              "@PJL SET ECONOMODE=%?False:OFF;%?True:ON;%n"

    Option "cupsTonerSave/Save Toner" Boolean DocumentSetup 10
      *Choice "False/No" ""
      Choice "True/Yes" ""

Since we didn't specify a group for these options, they will be put in the General option group.

Table 3-3, PJL attributes and options
Attribute Option Description
COLORSPACE. ColorModel Varies Specifies the colorspace to set at the beginning of the job.
cupsBooklet cupsBooklet Specifies the PJL commands to send for setting the booklet printing mode.
cupsPunch cupsPunch Specifies the PJL commands to send for setting the punch mode.
cupsRET cupsRET Specifies the PJL commands to set the resolution enhancement mode.
cupsStaple cupsStaple Specifies the PJL commands to send for setting the stapler mode.
cupsTonerSave cupsTonerSave Specifies the PJL commands to set the toner saving mode.
Duplex Duplex Specifies the PJL commands to send for setting the duplex mode.
EndJob N/A Specifies the PJL commands to send at the end of a job.
Jog Varies Specifies the PJL commands to send for setting the output jogging.
MediaClass Varies Specifies the PJL commands to send for setting the media class.
MediaColor Varies Specifies the PJL commands to send for setting the media color.
MediaType MediaType Specifies the PJL commands to send for setting the media type.
OutputType Varies Specifies the PJL commands to send for setting the output type.
RENDERINTENT. ColorModel Varies Specifies the rendering intent to set at the beginning of the job.
RENDERMODE. ColorModel Varies Specifies the render mode to set at the beginning of the job.
Table 3-3, PJL attributes and options, continued...
Attribute Option Description
StartJob N/A Specifies the PJL commands to send at the beginning of a job.
Tumble Duplex Specifies the PJL commands to send for setting the duplex tumble mode.

To test the new drivers, start by running the ppdc program to create the PPD files:

    ppdc laserjet-pjl.drv ENTER

Then use the lpadmin(8) command to add the printer with the correct device URI. The following example adds a HP LaserJet 2100 which is connected via a JetDirect interface:

    lpadmin -p lj2100 -E -v socket://lj2100 -i ppd/hpljt212.ppd ENTER

Finally, print a test page to see it work:

    lp -d lj2100 -o cupsTonerSave=True \
       /usr/share/cups/data/testprint.ps ENTER
Listing 3-2, "examples/laserjet-pjl.drv"
// Include standard font and media definitions
#include <font.defs>
#include <media.defs>

// Include HP-PCL driver definitions
#include <pcl.h>

// Specify that this driver uses the HP-PCL driver...
DriverType pcl

// Specify the driver options via the model number...
ModelNumber ($PCL_PAPER_SIZE $PCL_PJL $PCL_PJL_RESOLUTION)

// List the fonts that are supported, in this case all
// standard fonts...
Font *

// Manufacturer and driver version
Manufacturer "HP"
Version 2.0

// Supported page sizes and their margins
HWMargins 18 12 18 12
*MediaSize Letter
MediaSize Legal
MediaSize Executive
MediaSize Monarch
MediaSize Statement
MediaSize FanFoldGermanLegal

HWMargins 18 12.72 18 12.72
MediaSize Env10

HWMargins 9.72 12 9.72 12
MediaSize A4
MediaSize A5
MediaSize B5
MediaSize EnvC5
MediaSize EnvDL
MediaSize EnvISOB5
MediaSize Postcard
MediaSize DoublePostcard

// Only black-and-white output with mode 3 compression...
ColorModel Gray k chunky 3

// Supported input slots
*InputSlot 7 "Auto/Automatic Selection"
InputSlot 2 "Manual/Tray 1 - Manual Feed"
InputSlot 4 "Upper/Tray 1"
InputSlot 1 "Lower/Tray 2"
InputSlot 5 "LargeCapacity/Tray 3"
Listing 3-2, "examples/laserjet-pjl.drv", continued...
// Supported resolutions
Resolution - 1 0 0 0 "300dpi/300 DPI"
*Resolution - 8 0 0 0 "600dpi/600 DPI"

// Tray 3 is an option...
Installable "OptionLargeCapacity/Tray 3 Installed"
UIConstraints "*OptionLargeCapacity False
               *InputSlot LargeCapacity"

// PJL options
Attribute cupsPJL cupsRET
          "@PJL SET SMOOTHING=%?False:OFF;%?True:ON;%n"

Option "cupsRET/Smoothing" Boolean DocumentSetup 10
  Choice "False/Off" ""
  *Choice "True/On" ""

Attribute cupsPJL cupsTonerSave
          "@PJL SET ECONOMODE=%?False:OFF;%?True:ON;%n"

Option "cupsTonerSave/Save Toner" Boolean DocumentSetup 10
  *Choice "False/No" ""
  Choice "True/Yes" ""

{
  // HP LaserJet 2100 Series
  Throughput 10
  ModelName "LaserJet 2100 Series PJL"
  PCFileName "hpljt212.ppd"
}

{
  // LaserJet 2200 and 2300 series have duplexer option...
  Duplex normal
  Installable "OptionDuplex/Duplexer Installed"
  UIConstraints "*OptionDuplex False *Duplex"

  {
    // HP LaserJet 2200 Series
    Throughput 19
    ModelName "LaserJet 2200 Series PJL"
    PCFileName "hpljt222.ppd"
  }

  {
    // HP LaserJet 2300 Series
    Throughput 25
    ModelName "LaserJet 2300 Series PJL"
    PCFileName "hpljt232.ppd"
  }
}

The ESC/P Driver

The ESC/P driver includes a printer command filter called commandtoescpx and a raster printer driver filter called rastertoescpx. The command filter supports head cleaning, printing a self-test page, and ink cartridge alignment.

The raster printer driver filter accepts grayscale, RGB, and CMYK raster data for printing to inkjet devices. It supports EJL commands for device-specific features and uses the appropriate ESC/P2 raster graphics commands for all inkjet printers sold by Epson. The driver does not support native text rendering due to the limitations of text support in most ESC/P implementations.

The ESC/P driver also provides an include file, <escp.h>. Driver information files that use the ESC/P driver begin with the following:

    #include <font.defs>
    #include <media.defs>
    #include <raster.defs>
    #include <escp.h>

    DriverType escp

ModelNumber Constants

Table 3-4 shows the constants that are defined in the <escp.h> include file. These constants are used with the ModelNumber directive to control the behavior of the driver. For example, a typical Epson Stylus Color printer would use the following ModelNumber specification:

    ModelNumber ($ESCP_MICROWEAVE $ESCP_USB $ESCP_REMOTE)

The parenthesis around the ESCP constants tell the PPD compiler to compute the bitwise OR of each of the values. The ESC/P driver will then use this information to tailor the output of the driver for the printer, in this case to use the printer's built-in microweaving (a way of printing using multiple passes), send the USB packet mode escape sequence, and to use remote mode commands. Table 3-5 shows the constants to use for several common types of Epson printers.

Writing a Basic Epson Stylus Photo R300 Driver

Now that we have covered the ESC/P driver definitions, we will create a driver for the popular Epson Stylus Photo R300 series printers. These printers offer 6-color, full-bleed printing at up to 5760x1440 DPI and can print on recordable CDs and DVDs as well as standard printer media.

Table 3-4, ESC/P ModelNumber 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
Table 3-5, ModelNumber values for common Epson printers
Printer Model ModelNumber Value
Epson Stylus Color ($ESCP_MICROWEAVE $ESCP_USB $ESCP_REMOTE)
Epson Stylus C-Series ($ESCP_STAGGER $ESCP_USB $ESCP_REMOTE)
Epson Stylus Photo ($ESCP_MICROWEAVE $ESCP_ESCK $ESCP_USB $ESCP_REMOTE)
Epson Stylus Pro ($ESCP_MICROWEAVE $ESCP_EXT_UNITS $ESCP_EXT_MARGINS $ESCP_PAGE_SIZE $ESCP_REMOTE)

Our first cut of the driver will support printing at up to 1440 DPI. We'll add the full-bleed printing support in the next section. Listing 3-3 shows the driver information file for a basic Epson Stylus Photo R300 driver.

The file starts with the usual #include directives and then sets the driver type and model number so that we use the ESC/P driver with the output tailored to the R300:

    // Specify that this driver uses the ESC/P driver...
    DriverType escp

    // Specify the driver options via the model number...
    ModelNumber ($ESCP_ESCK $ESCP_EXT_UNITS $ESCP_EXT_MARGINS $ESCP_USB
        	 $ESCP_PAGE_SIZE $ESCP_RASTER_ESCI)

Then we list all of the media sizes that are supported by the printers along with the margins that should be used:

    HWMargins 8.4 0 8.4 0
    *MediaSize Letter
    MediaSize Legal
    MediaSize Executive
    MediaSize Statement
    MediaSize A4
    MediaSize A5
    MediaSize A6
    MediaSize B5
    MediaSize Env10
    MediaSize EnvC5
    MediaSize EnvDL
    MediaSize EnvISOB5
    MediaSize Postcard
    MediaSize DoublePostcard

The R300 supports custom page sizes up to 44 inches (1.1m) in length. We use the VariablePaperSize directive to instruct the PPD compiler to include the custom page size attributes, and the MinSize and MaxSize directives to specify the range of sizes that are supported:

    VariablePaperSize Yes
    MinSize 1in 4in
    MaxSize 8.5in 44in

The R300 driver also supports four color modes: Grayscale (colorspace = w), Black (colorspace = k), RGB (colorspace = rgb), and CMYK (colorspace = cmyk). The Grayscale and RGB modes provide color/gamma-corrected output while the Black and CMYK modes offer uncorrected color printing. The ColorModel directive tells the PPD compiler to include each of these modes:

    ColorModel Gray/Grayscale w chunky 1
    ColorModel Black k chunky 1
    *ColorModel RGB/Color rgb chunky 1
    ColorModel CMYK cmyk chunky 1

The driver provides printing at 360, 720, and 1440 DPI using the Resolution directives. Each resolution makes use of the bits per color, row count, and row step values:

    Resolution - 8 90 0 103 "360dpi/360 DPI"
    *Resolution - 8 90 0 206 "720dpi/720 DPI"
    Resolution - 8 90 0 412 "1440dpi/1440 DPI"
Listing 3-3, "examples/r300-basic.drv"
// Include standard font and media definitions
#include <font.defs>
#include <media.defs>

// Include ESC/P driver definitions
#include <escp.h>

// Specify that this driver uses the ESC/P driver...
DriverType escp

// Specify the driver options via the model number...
ModelNumber ($ESCP_ESCK $ESCP_EXT_UNITS $ESCP_EXT_MARGINS
             $ESCP_USB $ESCP_PAGE_SIZE $ESCP_RASTER_ESCI)

// List the fonts that are supported, in this case all
// standard fonts...
Font *

// Manufacturer and driver version
Manufacturer "Epson"
Version 1.0

// Supported page sizes and their margins
HWMargins 8.4 0 8.4 0
*MediaSize Letter
MediaSize Legal
MediaSize Executive
MediaSize Statement
MediaSize A4
MediaSize A5
MediaSize A6
MediaSize B5
MediaSize Env10
MediaSize EnvC5
MediaSize EnvDL
MediaSize EnvISOB5
MediaSize Postcard
MediaSize DoublePostcard

VariablePaperSize Yes
MinSize 1in 4in
MaxSize 8.5in 44in

// Four color modes are supported...
ColorModel Gray/Grayscale w chunky 1
ColorModel Black k chunky 1
*ColorModel RGB/Color rgb chunky 1
ColorModel CMYK cmyk chunky 1

// Supported resolutions
Resolution - 8 90 0 103 "360dpi/360 DPI"
*Resolution - 8 90 0 206 "720dpi/720 DPI"
Resolution - 8 90 0 412 "1440dpi/1440 DPI"
Listing 3-3, "examples/r300-basic.drv" continued...
// Very basic dithering settings
Attribute cupsInkChannels "" 6
Attribute cupsInkLimit "" 2.0

Attribute cupsCyanLtDk "" "0.5 1.0"
Attribute cupsMagentaLtDk "" "0.5 1.0"

Attribute cupsAllDither 360dpi "0.5 0.75 1.0"
Attribute cupsAllDither 720dpi "0.6 0.9 1.2"
Attribute cupsAllDither 1440dpi "0.9 1.35"

Attribute cupsESCPDotSize 360dpi 16
Attribute cupsESCPDotSize 720dpi 17
Attribute cupsESCPDotSize 1440dpi 18

{
  // EPSON Stylus Photo R300 Series
  Throughput 1
  ModelName "Epson Stylus Photo R300"
  PCFileName "epspr301.ppd"
}

The R300 has 90 nozzles per color spaced at 120 DPI vertically; the head controller can print 360 DPI horizontally. The row count value is the same as the nozzle count, 90. The row step values require a small amount of calculation; each value is computed using the following formula:

    row-step = 100 * x-dpi / 360 + y-dpi / 120

For 360x360 DPI, the row step is therefore:

    row-step = 100 * x-dpi / 360 + y-dpi / 120
             = 100 * 360 / 360 + 360 / 120
             = 100 * 1 + 3
	     = 100 + 3
	     = 103

The 720 and 1440 DPI resolutions are computed similarly, and it is possible to support any multiple of the base resolution, 360x120 DPI, up to the physical limit of the printer controller, 5760x1440 DPI.

The R300 driver also needs some additional attributes defined to control the amount and kind of ink that is printed on the page. The first attribute we need to define is cupsInkChannels which tells the driver how many colors are used by the printer. In this case, the R300 is a 6-color printer:

    Attribute cupsInkChannels "" 6

Next we want to limit the amount of ink that is put on the page to 200%. The cupsInkLimit attribute specifies this value:

    Attribute cupsInkLimit "" 2.0

Since the R300 uses light versions of cyan and magenta, we need to tell the driver when to use the light ink and when to use the dark ink. The simplest attributes for this specify the transition range as two numbers from 0 to 1. We'll transition from 0.5 to 1.0 for both colors:

    Attribute cupsCyanLtDk "" "0.5 1.0"
    Attribute cupsMagentaLtDk "" "0.5 1.0"

Next, we want to specify the ink density for the dots that the R300 can produce for each resolution using the cupsAllDither attribute. Each number represents a percentage of ink, so a value of 1.0 means 100% coverage for each dot and a value of 2.0 means 200% coverage for each dot. The driver uses this information to reduce the amount of ink that is put on the page for each individual color. Since the R300 supports three different dot sizes, we include three numbers for the 360 and 720 DPI modes, however at 1440 DPI the largest dot size is not needed:

    Attribute cupsAllDither 360dpi "0.5 0.75 1.0"
    Attribute cupsAllDither 720dpi "0.6 0.9 1.2"
    Attribute cupsAllDither 1440dpi "0.9 1.35"

Finally, we tell the driver which dot sizes to use for each resolution using the cupsESCPDotSize attribute. These values are defined in the corresponding developer reference manual from Epson. For the R300, size 16 represents the largest variable size dots and size 18 the smallest:

    Attribute cupsESCPDotSize 360dpi 16
    Attribute cupsESCPDotSize 720dpi 17
    Attribute cupsESCPDotSize 1440dpi 18

To test the new drivers, start by running the ppdc program to create the PPD files:

    ppdc r300-basic.drv ENTER

Then use the lpadmin(8) command to add the printer with the correct device URI. The following example adds a R300 which is connected via a USB port:

    lpadmin -p r300 -E -v 'usb://EPSON/Stylus%20Photo%20R300' -i \
           ppd/epspr301.ppd ENTER

Finally, print a test page to see it work:

    lp -d r300 /usr/share/cups/data/testprint.ps ENTER

Epson Remote Mode Attributes

Most Epson inkjet printers support a special "remote" mode which allows you to control things such as the paper cutter, media type, drying time, and so forth. Remote mode also allows you to query the current ink status from the printer, clean the print heads, etc., and that functionality is supported via the commandtoescpx filter.

Remote mode support is specified using the ESCP_REMOTE model number constant. If remote mode is enabled, the rastertoescpx driver will look for several attributes to determine which remote mode commands to send and with what values. Table 3-6 lists the remote mode attributes and their values.

Typically, each attribute maps from a single, integer value from the page device dictionary to a single integer value which is used for the corresponding remote mode command. The only exception to this rule is the cupsESCPPP attribute which maps the MediaPosition value to two integer values for the "PP" (paper path) remote mode command, for example:

    Attribute cupsESCPPP 0 "1 255"

The integer values used for all remote mode commands are documented in the corresponding Epson programming guide for your printer.

Adding Remote Mode Commands to the R300 Driver

The R300 supports several remote mode commands that we can use. We will add support for full-bleed printing and specification of the media source. Listing 3-4 shows the updated driver information file. We'll start by adding the ESCP_REMOTE constant to the model number definition:

    ModelNumber ($ESCP_ESCK $ESCP_EXT_UNITS $ESCP_EXT_MARGINS $ESCP_USB
                 $ESCP_PAGE_SIZE $ESCP_RASTER_ESCI $ESCP_REMOTE)

Next we add the horizontal offset attribute, cupsESCPFP, that is used to offset the page for full-bleed printing:

    Attribute cupsESCPFP "" -80

Finally, we add InputSlot definitions for automatic and manual feed printing, and cupsESCPPP attributes for each MediaPosition value:

    *InputSlot 0 "Auto/Auto Select"
    InputSlot 1 "Manual/Manual Feed"

    Attribute cupsESCPPP 0 "1 255"
    Attribute cupsESCPPP 1 "2 1"
Table 3-6, Epson remote mode attributes
Attribute Description
cupsESCPAC Enables/disables the cutter based upon the CutMedia value
cupsESCPCO Enables/disables the cutter based upon the CutMedia value
cupsESCPEX Sets the media position based upon the MediaPosition value
cupsESCPFP Sets the full-bleed horizontal position offset
cupsESCPMS Sets the media size based upon the MediaPosition and PageSize values
cupsESCPMT Sets the media type based upon the cupsMediaType value
cupsESCPPC Sets paper checking based upon the MediaPosition value
cupsESCPPH Sets the paper thickness based upon the cupsMediaType value
cupsESCPPP Sets the paper path based upon the MediaPosition value
cupsESCPSN0 Sets the feed sequence based upon the cupsMediaType value
cupsESCPSN1 Sets the platten gap based upon the cupsMediaType value
cupsESCPSN2 Sets the paper feed/eject sequence based upon the cupsMediaType value
cupsESCPSN6 Sets the eject delay based upon the cupsMediaType value
cupsESCPSN80 Sets the cutting method based upon the CutMedia value
cupsESCPSN81 Sets the cutting pressure based upon the CutMedia value

To test the new drivers, start by running the ppdc program to create the PPD files:

    ppdc r300-remote.drv ENTER

Then use the lpadmin(8) command to add the printer with the correct device URI. The following example adds a R300 which is connected via a USB port:

    lpadmin -p r300 -E -v 'usb://EPSON/Stylus%20Photo%20R300' \
        -i ppd/epspr302.ppd ENTER

Finally, print a test page to see it work:

    lp -d r300 /usr/share/cups/data/testprint.ps ENTER
Listing 3-4, "examples/r300-remote.drv"
// Include standard font and media definitions
#include <font.defs>
#include <media.defs>

// Include ESC/P driver definitions
#include <escp.h>

// Specify that this driver uses the ESC/P driver...
DriverType escp

// Specify the driver options via the model number...
ModelNumber ($ESCP_ESCK $ESCP_EXT_UNITS $ESCP_EXT_MARGINS
             $ESCP_USB $ESCP_PAGE_SIZE $ESCP_RASTER_ESCI
             $ESCP_REMOTE)

// List the fonts that are supported, in this case all
// standard fonts...
Font *

// Manufacturer and driver version
Manufacturer "Epson"
Version 2.0

// Supported page sizes and their margins
HWMargins 0 0 0 0
*MediaSize Letter
MediaSize Legal
MediaSize Executive
MediaSize Statement
MediaSize A4
MediaSize A5
MediaSize A6
MediaSize B5
MediaSize Env10
MediaSize EnvC5
MediaSize EnvDL
MediaSize EnvISOB5
MediaSize Postcard
MediaSize DoublePostcard
Listing 3-4, "examples/r300-remote.drv" continued...
VariablePaperSize Yes
MinSize 1in 4in
MaxSize 8.5in 44in

// Borderless printing offset...
Attribute cupsESCPFP "" -80

// Four color modes are supported...
ColorModel Gray/Grayscale w chunky 1
ColorModel Black k chunky 1
*ColorModel RGB/Color rgb chunky 1
ColorModel CMYK cmyk chunky 1

// Supported resolutions
Resolution - 8 90 0 103 "360dpi/360 DPI"
*Resolution - 8 90 0 206 "720dpi/720 DPI"
Resolution - 8 90 0 412 "1440dpi/1440 DPI"

// Paper trays...
*InputSlot 0 "Auto/Auto Select"
InputSlot 1 "Manual/Manual Feed"

Attribute cupsESCPPP 0 "1 255"
Attribute cupsESCPPP 1 "2 1"

// Very basic dithering settings
Attribute cupsInkChannels "" 6
Attribute cupsInkLimit "" 2.0

Attribute cupsCyanLtDk "" "0.5 1.0"
Attribute cupsMagentaLtDk "" "0.5 1.0"

Attribute cupsAllDither 360dpi "0.5 0.75 1.0"
Attribute cupsAllDither 720dpi "0.6 0.9 1.2"
Attribute cupsAllDither 1440dpi "0.9 1.35"

Attribute cupsESCPDotSize 360dpi 16
Attribute cupsESCPDotSize 720dpi 17
Attribute cupsESCPDotSize 1440dpi 18

{
  // EPSON Stylus Photo R300 Series
  Throughput 1
  ModelName "Epson Stylus Photo R300"
  PCFileName "epspr302.ppd"
}