GS-HPDJ(1)

NAME
hpdj - Ghostscript device driver for printers understanding PCL-3

SYNOPSIS
gs [options] [files]
option ::= prn_option | hpdj_option prn_option can be any option defined for ghostscript's prn (printer) device. This includes all device-independent options described in gs(1). You should also look into ghostscript's extended documentation (file Use.htm/use.txt and the section Device parameters in Language.htm/language.txt). hpdj does not support the Duplex parameter and it determines the correct value for BitsPerPixel automatically.
hpdj_option ::= -dBlackLevels=integer | -dCMYLevels=integer | -sColorMode=mode | -sColourMode=mode | -dCompressionMethod=method | -dDryTime=seconds | -dManualFeed[=boolean] | -sMarginFile=pathname | -sMediaType=type | -sModel=model | -sPagecountFile=pathname | -sPrintQuality=quality
mode ::= mono | CMY | CMY+K | CMYK
method ::= 0 | 1 | 2 | 3 | 9
boolean ::= false | true
type ::= plain | bond | Premium | glossy | transparency | photo | integer
model ::= 500 | 500C | 510 | 520 | 540 | 550C | 560C | 850C | 855C | unspec
quality ::= draft | normal | presentation | integer Case is significant. Note that some options must be passed as strings (-s) and others as general tokens (-d). You should also keep in mind that gs silently ignores any option it does not recognize, hence some care in spelling parameter names is necessary. Some options have synonyms for values which are listed only in the detailed description below.

DESCRIPTION

  Scope
The ghostscript device driver hpdj is a ghostscript backend for printers understanding Hewlett-Packard's Printer Command Language, Level 3 (PCL-3). It is intended to support in particular the following printer models:
HP DeskJet 500
HP DeskJet 500C
HP DeskJet 510
HP DeskJet 520
HP DeskJet 540
HP DeskJet 550C
HP DeskJet 560C
HP DeskJet 850C
HP DeskJet 855C
The driver does not support DeskJet printers understanding only HP PPA (Printing Performance Architecture) commands. This applies in particular to the DeskJet 820Cse/820Cxi. Different printer models usually implement model-specific subsets of all PCL-3 commands or arguments to commands. You must therefore tell the driver by means of the Model option for which model the generated PCL code is intended. The model-dependent difference in the generated code is not great. Apart from margin specifications and colour capabilities, one can consider three groups of models which are treated with significant differences:
500,
5xx except 500 and 540,
540 and 8xx.
The third group is the one I refer to as the "new DeskJets" below. If you have a PCL-3 printer not appearing in the list above, the likelihood is still good that it will accept the files generated by hpdj. You can specify one of the supported models in these cases (it is sufficient to try one each from the groups just mentioned), or use the special model name unspec which is treated like a new DeskJet with all model-dependent checks having been turned off. I have received reports that hpdj works with the following printers:
HP DeskJet 340
HP DeskJet 500
HP DeskJet 500C (tested for mono only)
HP DeskJet 520
HP DeskJet 540
HP DeskJet 560C
HP DeskJet 600
HP DeskJet 660C/660Cse
HP DeskJet 670C
HP DeskJet 672C
HP DeskJet 680C
HP DeskJet 690C
HP DeskJet 690C+
HP DeskJet 693C
HP DeskJet 694C
HP DeskJet 850C
HP DeskJet 855C
HP DeskJet 870Cse/870Cxi
HP DeskJet 890C
HP DeskJet 895Cxi
HP DeskJet 1100C
HP DeskJet 1120C
HP OfficeJet 590
HP 2000C Professional Series Color Printer
Lexmark 3000 Color Jetprinter
Usually the people who send me reports do not state to which extent hpdj "works" for their printer model. I should like to extend this section with more specific information. Therefore, if you want to report success for a particular printer model not explicitly supported by hpdj, please mention the following items in your answer:
• printer model
• gs version
• hpdj version
• option combinations successfully tested (specify at least model, resolution, colour mode and, if used, the number of intensity levels)
• printer-specific functionality you could not access
So far I have not heard of a PCL-3 printer which cannot be driven by hpdj. Hence the really interesting part of success reports is the list of working option combinations, but since I included the above request in this manual page in December 1997, no one has sent me such a report. Possibly, users find this information unnecessary.

  Colour Modes
Ignoring photo cartridges, DeskJet printers can be classified in four categories:

    •   The printer has only a black ink cartridge.

    •   The printer can print with either a black or a cyan/magenta/yellow (CMY) cartridge.

    •   The printer holds a CMY and a black cartridge simultaneously, but the inks are chemically incompatible and should not be overlayed. (Don't worry: the printer is not going to explode if they do. You merely get poorer results because the black ink will spread further than it should.)

    •   The printer holds a CMY and a black cartridge simultaneously and the inks can be mixed.
This leads to four colour modes for the driver:

    mono:
        Print in black.

    CMY:
        Print in cyan, magenta and yellow only. In this mode, "composite black" consisting of all three inks is used to stand in for true black.

    CMY+K:
        Print with all four inks, but never mix black with one of the others.

    CMYK:
        Print with all four inks.
Depending on the category of the model chosen, the driver will accept one or more of these modes. The possibilities are:
    Model | Colour Modes
    500, 510, 520 | mono
    500C, 540 | mono, CMY
    550C, 560C | mono, CMY, CMY+K
    850C, 855C, unspec | all
Note that a printer capable only of CMY might accept CMY+K or CMYK data, remapping them to CMY, and a printer capable of CMY+K might remap CMY data to CMY+K.

  Print Quality Selection for Older DeskJets
With the introduction of the DeskJet 540, HP added two new PCL commands to the language: Media Type and Print Quality. For older DeskJets (500, 500C, 510, 520, 550C and 560C), similar effects can be achieved by specifying some technical aspects of the printing process in detail. The hpdj driver accepts only the new Media Type and Print Quality specifications as options. For printers not understanding the new commands, these specifications are mapped to the older Depletion, Shingling, and Raster Graphics Quality commands based on recommendations from HP.

  Media Sizes and Orientations
Ghostscript looks at several sources to determine the page size for a document:
• the default size set for gs (usually US Letter or ISO A4)
• the value given to -sPAPERSIZE in the invocation
• the size requested by the document, unless you specify -dFIXEDMEDIA (available since gs 3.41)
The last applicable item in this list overrides the others. The driver knows which media sizes are supported by each printer model and will refuse to print if an unsupported one is requested. The model unspec normally accepts all sizes, and it assumes the printer to understand all size commands which can be sent to one of the supported series-800 DeskJets. This can be changed with a margin file specification; see the CONFIGURATION section below for details. Each supported size is available in portrait and landscape orientation. Media should however always be put into the input tray as if the intended orientation were portrait. Ghostscript and hpdj will take care of the rest. I do not have a general statement from Hewlett-Packard on the required orientation of media in the input tray, but in my opinion it should always be "short edge first" with respect to the feeding direction. Note that hpdj has no information about the dimension or orientation of the medium in the input tray: you must ensure yourself that this is appropriate. In setting up the PostScript default user space, hpdj does not treat envelope sizes differently.

  Diagnostic Messages
Error messages issued by hpdj start with "? Device hpdj:", warnings with "?-W Device hpdj:". Both are written on the standard error stream.

OPTIONS
The following options are not specific to the hpdj device but have specific meaning or restrictions:

    -sDEVICE=hpdj
        This option specification selects this driver.

    -rresolution
        This option specifies the resolution in pixels per inch (ppi). The driver checks whether the model selected accepts the given resolution unless the model is unspec. Resolutions supported by at least some of the models in some of the colour modes are 75, 100, 150, 300 and 600 ppi. Only unspec permits unequal horizontal and vertical resolutions. For this case read the subsection on the Configure Raster Data command in the LIMITATIONS section below first. The default resolution for hpdj is set at compile time, usually to 300 ppi.
The following options are specific to hpdj:

    -dBlackLevels=levels and -dCMYLevels=levels
        Warning! These options are not based on HP documentation! Read the subsection on the Configure Raster Data command in the LIMITATIONS section below before using them. These options set the number of intensity levels per pixel and colour component to use when printing with black or CMY inks, respectively, and must be consistent with the colour mode. They permit access to the Colour Resolution Enhancement technology (C-REt) feature available in some series-800 DeskJets. The defaults are 0 or 2, depending on the colour mode chosen. Other values are only accepted for the models 850C, 855C and unspec. I strongly suggest that you apply gamma correction and modify the halftone screens whenever you use non-default values for these options (see the CONFIGURATION section below). unspec accepts any non-negative number of levels except 1 up to 256. The models 850C and 855C accept the levels 0, 2, 3 and 4 with the following restrictions if any of the levels is larger than 2:
        • You can't use this feature with draft quality.
        • You can't use a colour mode of CMY.
        • You must use a resolution of 300 ppi.
        • If you are using more than 2 intensity levels for CMY, you must use 4 levels for black.
        When using the model unspec you should expect the printer to similarly limit the possibilities. Unfortunately, there is a problem here because ghostscript's internal colour model is not prepared for the situation where a device can render different small (< 32) numbers of intensity levels for different colour components. In this situation gs will in general assume that the number of black levels available is equal to that for CMY levels. Depending on which of the numbers is smaller, there will then either be unused black levels or some will be used more than once. Regrettably, best results on a DeskJet 850C seem to me to be achieved with 4 black and 3 CMY levels, at least on plain paper. (4 CMY levels might be right for presentation quality on glossy paper or transparencies.) The CONFIGURATION section below presents a slightly dirty path out of this difficulty.

    -sColorMode=mode  or  -sColourMode=mode
        This selects the colour mode to be used by the driver: mono (or monochrome), CMY, CMY+K or CMYK. The default is mono. Which colour modes are accepted depends on the model, see Colour Modes in the section DESCRIPTION above. A value of CMY for this option also sets BlackLevels to zero, and if CMYLevels is zero when you demand any of CMY, CMY+K or CMYK, it is set to two. For all other situations you must ensure yourself that colour mode and intensity levels are consistent or hpdj will complain. This rule implies that you can ignore the level options unless you want to use a non-default number of levels. The PostScript page device dictionary entry ProcessColorModel will not be correct for a colour mode of CMY or CMY+K.

    -dCompressionMethod=method
        PCL interpreters understand several compression methods for raster graphics data in order to speed up host-printer communication. The possible choices are:
          0 Unencoded, non-compressed
          1 Runlength encoding
          2 Tagged Image File Format (TIFF)
          3 Delta Row Compression
          9 Compressed Replacement Delta Row Encoding The default method is set at compile time, usually to 9. Requesting method 3 actually leads to a combination of methods 2 and 3. The DeskJet 500 does not support method 9. The driver may temporarily choose method 0 if a compressed data sequence would be longer than its uncompressed version. Compression rates can vary drastically, depending on the structure of the input. However, although the absolute values change, the relative order of efficiency between the methods is usually the order of increasing method. In short: use method 9 (3 for the DeskJet 500).

    -dDryTime=delay
        With the exception of the DeskJets 500 and 500C, DeskJet printers can be told to guarantee a minimum drying time of delay seconds before the next page of the same print job is dropped on a newly printed page. (This interval can be terminated by pressing the Load/Eject button.) The printer will choose default values depending on the current print quality, hence it is normally not necessary to specify this option. Permissible values for delay are integers in the range -1 to 1200, where -1 instructs hpdj not to send a corresponding command, 0 establishes default values for the current print quality, and all other values explicitly request the duration in seconds. The default is -1.

    -dManualFeed[=boolean]
        It is possible to request a DeskJet printer to wait before each page of a document until the Load/Eject button is pressed on the printer. This is mostly intended for situations where some special medium is used or the medium has to be inserted into an input slot holding only one sheet at a time. The default setting for this option is false except for series-500 DeskJets printing on envelope sizes when it is true. Note that for current ghostscript versions this setting is independent of the value of the PostScript operator manualfeed in statusdict. If you want to set manual feeding from the PostScript code you must therefore use the ManualFeed entry in the page device dictionary. With gs 3.33, you cannot specify arguments for this option.

    -sMarginFile=pathname
        This option must specify an existing file containing a list of supported media sizes and corresponding margin descriptions for the printer. This will take precedence over the builtin model-specific lists of sizes and margins. The format of the file is described in the CONFIGURATION section below. The default is not to use a margin file but the builtin lists. This option is primarily intended to be used with the model unspec. A margin file path can also be specified at compile time overriding the default behaviour for unspec only. Using the MarginFile option in addition will override the compiled-in margin file path.

    -sMediaType=type
        This option selects (you guessed it) the type of medium you wish to print on. The possible choices are:
            0 plain paper
            1 bond paper
            2 HP Premium paper
            3 glossy paper
            4 transparency film
            5 photo paper The default is plain paper. For type, you can specify the full strings, the one-word strings resulting from dropping "paper", "film", and "HP", or an integer. Out-of-range numerical values generate a warning but are passed through to the printer if it is a model understanding the PCL command "Media Type". If it isn't, the effect is the same as specifying plain paper. The value 5/photo paper is only understood by some recent DeskJets (e.g., the DeskJet 690C) and will be ignored by older ones.

    -sModel=model
        This option identifies the printer model for which the generated file is intended. The following names are accepted for model:
        500, 500C, 510, 520, 540, 550C, 560C, 850C, 855C, unspec.
        The choice of model primarily determines which resolutions, colour modes, intensity levels and media sizes the driver will accept, where the output will appear on the page, and to some extent what PCL code the driver will generate. Some of the models are treated identically. A default model can be set at compile time. If this has not been done, you must specify the Model option in every invocation. unspec is intended to be a stop-gap for DeskJet-compatible printers not presently supported by this driver. For unspec, all model-specific checks (e.g., supported resolutions) are turned off. Supported media sizes and margin settings are assumed to be identical with those for the DeskJets 850C/855C/870C/890C, but you can use the MarginFile option or its compile-time equivalent to override this. The PCL code generated assumes a "new" DeskJet in the sense that it should be at least at the level of a DeskJet 540 supporting the PCL commands Media Type and Print Quality. If you specify unequal horizontal and vertical resolutions or more than two levels of intensity per colour and pixel, the printer must in addition understand the Configure Raster Data command. Read the subsection on that command in the LIMITATIONS section below. If you choose to use unspec it is your responsibility to ensure that hpdj is only called with parameter values the printer can handle. This applies in particular to the resolution and the intensity levels.

    -sPagecountFile=pathname
        The pathname must specify either a non-existent file in a directory with write permission or a writable file with a single line containing a non-negative integer. In the first case, hpdj will create the file and insert the number of pages processed, in the second case the number will be incremented by that amount. Parallel invocations of gs are permitted to use the same file. hpdj will also make the initial page count available in its page device dictionary. Note that in present ghostscript versions the PostScript operator pagecount in statusdict always returns 4711 and is not based on the value of PageCount in the page device dictionary. This option is mainly intended for spooler backends calling hpdj. It can be used to keep track of the total number of pages printed and also for per-job accounting. I recommend using this option for the first purpose and to make a note of the values in the resulting files whenever you insert a new ink cartridge. This will enable you to get an indication of how much a printed page costs and why it is a good idea to use draft quality whenever possible. The driver can be compiled without this option present but on a UNIX system I would not expect this to be done unless gs offers the same functionality in a driver-independent manner which it currently does not. hpdj is distributed with an example if-hpdj of a BSD spooler backend using this option.

    -sPrintQuality=quality
        There are three print quality settings:
        -1 | draft
        0 | normal
        1 | presentation or best
        The default is normal. You may specify the strings or an integer. Out-of-range numerical values will generate a warning but are passed through to the printer if it is a model understanding the PCL command "Print Quality". If it isn't, the effect is the same as specifying normal.

  Looking up Compile-Time Defaults
Some default values for options can be chosen at compile time. If you later want to know these values, run gs on the following PostScript code:
currentpagedevice
dup /Name get (hpdj) eq not
{
  (ERROR: You have not selected the hpdj driver.) =
}
{
  (Model: ) print
  dup /Model get =
  (Resolution: ) print
  dup /HWResolution get ==
  (Compression method: ) print
  dup /CompressionMethod get =
  (Margin file: ) print
  dup /MarginFile get
  dup () eq
  {pop (none)} if
  =
  (PagecountFile is ) print
  dup /PagecountFile known not
  {(not ) print} if
  (supported.) =
} ifelse
pop
quit
Note that this will not necessarily return the compile-time defaults but only the values current at the time of execution. Therefore you should not specify any options except -sDEVICE=hpdj and, if your ghostscript executable has been compiled without a default model for hpdj or if you want to find out whether there is a compiled-in margin file path, -sModel=unspec. You should also make sure that you have not set environment variables modifying ghostscript's behaviour.

CONFIGURATION

  Margin Description File
A margin description file (margin file for short) can be used to override the builtin model-specific lists of supported media sizes and the margins in force for each. This feature is mainly intended to be used in conjunction with -sModel=unspec: if you have a model not directly supported by this driver, look up the supported page sizes and corresponding printable regions in your printer's manual and enter them in a margin file. Note: Entering a page size in the margin file which is not really supported by your printer is not useful: the PCL interpreter will simply ignore the request to set this page size, and printer and driver may have diverging opinions about what the margins will be. If you need to print on a medium of a size not supported by your printer, choose a larger and printer-supported size in PostScript, establish properly-positioned clipping regions within the real size, and print. However, if you have a newer DeskJet supporting custom page sizes, this is not necessary (see below). Margin specifications are important for two reasons: the values for the left and top margins determine how the output is positioned on the page, and sufficiently large values for the right and bottom margins prevent the print head being caught at the paper's edge and printing beyond the sheet, respectively. A line in the margin file can be blank, a comment line (first non-blank character is '#'), or one of the following:
unit unit
code left bottom right top
A unit line specifies in which units margin specifications in the following lines should be interpreted. unit can be either in or mm with in being the default. A unit specification remains in force until overridden by a following unit line. The second kind of line states that the model supports a particular page size, identified by its PCL page size code, and specifies the margins in force for that size when printing in black, in raster graphics mode, and in portrait orientation for the medium (width ≤ height). Be careful with envelopes: older (pre-1997) HP documentation frequently gives their margins in landscape orientation; you can check this by looking for the largest margin value: in portrait orientation it should be at the bottom. The margins have to be specified as floating point numbers in inches or millimetres as announced by the last preceding unit line. The floating point format is that of the "C" locale. Depending on the model, hpdj will either assume that the same margins apply for colour printing (this is the case for unspec) or increase the bottom margin by a model-specific amount in that case. The code must be one of the following PCL page size codes (entries marked with an asterisk are those used by the model unspec if no margin file is employed):
    *1 | US Executive (7.25 × 10.5 in)
    *2 | US Letter (8.5 × 11 in)
    *3 | US Legal (8.5 × 14 in)
    6 | US Tabloid (11 × 17 in, also called "Ledger")
    15 | US Statement (5.5 × 8.5 in)
    16 | Super B (305 × 487 mm)
    *24 | ISO/JIS A6 (105 × 148 mm)
    *25 | ISO/JIS A5 (148 × 210 mm)
    *26 | ISO/JIS A4 (210 × 297 mm)
    27 | ISO/JIS A3 (297 × 420 mm)
    *45 | JIS B5 (182 × 257 mm).
     | This is distinct from ISO B5 (176 × 250 mm).
    46 | JIS B4 (257 x 364 mm).
     | This is distinct from ISO B4 (250 × 353 mm).
    *71 | Hagaki card (100 × 148 mm)
    *74 | US index card 4 × 6 in
    *75 | US index card 5 × 8 in
    *81 | US no. 10 envelope (4.125 × 9.5 in).
    *90 | ISO DL envelope (110 × 220 mm)
    *92 | ISO C6 envelope (114 × 162 mm)
    *101 | custom page size
    109 | US A2 envelope (4.375 × 5.75 in)
The page size code 101 (custom page size) is not understood by older printers and may be used in a margin file only for the models 540, 850C, 855C, and unspec. In these cases you can print, within certain limits, on arbitrarily sized media. The driver knows these limits and refuses to generate a file if you exceed them. For unspec, there are no limits. hpdj will tell the printer to expect a custom page size only if there is no fitting discrete entry. Every margin file must contain at least an entry which fits ghostscript's default page size, usually ISO A4 or US Letter. Only those sizes which are listed will be accepted by hpdj. hpdj is distributed with an example of a margin description file, example.mdf.

  PostScript Configuration File
Sometimes it is desirable to execute additional PostScript commands for a particular file or possibly all files sent to a particular printer or print queue. With ghostscript this is easily possible because gs accepts several files in the invocation and executes them sequentially. This is particularly appropriate for those PostScript operators which affect device-specific features and should therefore not appear in a portable page description. The hpdj distribution contains an example of an input filter if-hpdj for the BSD spooler lpr(1) permitting the use of a print-queue-specific configuration file.

  Correcting Offsets
A margin description file is intended to adapt hpdj to the difference in margin settings between printer models and should usually contain "official" information, preferably taken from the model's manual. A different situation arises if a particular printer's output is not properly positioned on the page even if the margin information is correct for this model. PostScript defines two arrays in the page device dictionary for correcting such misadjustments, both containing two numbers describing a desired shift of the page image with respect to device space coordinate axes but in different units. The values in the `Margins' array are interpreted with respect to a canonical default resolution, the newer `PageOffset' array (supported by ghostscript since probably gs 3.50) is taken to be in units of 1/72 inch ("big points", bp). For hpdj the device coordinate system has an x axis pointing to the right and a y axis pointing downwards in portrait orientation, and the canonical default resolution is the default resolution chosen at compile time (see the OPTIONS section above). As an example, assume your printer shifts its output 1 mm to the right and 0.5 mm upwards and the default resolution of your version of hpdj is 300 ppi. Now create a file containing either the PostScript code
<< /Margins [-11.8 5.9] >> setpagedevice
("shift 11.8 pixels to the left and 5.9 pixels down") or
<< /PageOffset [-2.8 1.4] >> setpagedevice
("shift 2.8 bp to the left and 1.4 bp down") and have it executed by ghostscript before the file to be printed. If you specify both, Margins and PageOffset, the total shift performed by gs will be the sum of the two. The file align.ps in the ghostscript distribution or the margin test files distributed with hpdj can be used to determine the necessary correction. You should be aware that you have to expect fluctuations between individual print jobs, in particular in the horizontal direction.

  Gamma Correction
DeskJets usually produce colour prints which are too dark (too much ink on the page). In this case you should perform gamma correction by modifying what PostScript calls transfer functions. In the simplest case, create a file containing the PostScript command
{number exp} settransfer
where a good value for number is usually in the range 0.3-0.5, and specify this file in ghostscript's command line before the file you wish to print. Now the intensities of all colour components will be rescaled by exponentiation with number. Because PostScript intensity values are in the range zero to one with zero meaning dark and one meaning light (additive interpretation), a value of number < 1 will lead to lighter colours and number > 1 results in darker colours. You can also set independent transfer functions for the four colour components by using the operator setcolortransfer which expects four routines as arguments. Consult a PostScript manual if you want to learn more about transfer functions. For a device with less than 32 intensity levels per colour component, at resolutions below 800 ppi, and unless you explicitly set transfer functions, gs applies a default gamma correction roughly corresponding to a value of 0.8 for number.

  Different Numbers of Black and CMY Intensities
DeskJets supporting C-REt apparently achieve more than two intensities per colour component by putting a variable number of layers of the same ink on top of each other. This happens during several passes of the print head. The number of levels which can be achieved is therefore determined by the number of passes which in turn is influenced by the print quality and the media type (that is apparently the reason why using C-REt in draft quality is useless). It is now likely that if one uses more levels than can be supported by the number of passes, the higher levels will look the same. This is what seems to happen if one prints with 4 intensity levels for CMY on plain paper with a DeskJet 850C: the fourth level is accepted by the printer but to me it looks indistinguishable from the third. In this situation we can compensate for ghostscript not correctly dealing with different numbers of black and CMY intensity levels by using PostScript's transfer functions. The idea is to specify in the invocation the higher number of levels for both, black and CMY, but to map the range for those components where actually only a smaller number of levels is distinguishable to a reduced range which gs will divide into the required (smaller) number of intervals. Although the printer will be told to expect the higher number of intensities, it will never receive them. However, if the assumptions above are correct, the highest level it does receive will anyway look like the highest level possible! For the case of 4 black and 3 intended CMY levels the CMY intensities must be remapped from the range [0, 1] to the range [1/3, 1]. Here's the code, including an equal gamma value number for all four components:
{number exp 2 mul 1 add 3 div}
dup dup
{number exp}
setcolortransfer
In the call to gs you must now specify a value of 4 for both, BlackLevels and CMYLevels.

  Halftoning
Most printers offer only a small number of intensities per colour component and pixel. In order to generate a larger range of colours, one therefore employs halftoning which consists of dividing the pixel array into halftone cells, each of which represents one effective pixel which can now display more shades. This method trades resolution for the number of shades and applies to all structures which have to be painted with a colour which cannot be represented exactly. At 300 ppi and with a bi-level device a typical choice is to use halftone cells of 5×5 pixels leading to an effective resolution of 60 ppi and 26 shades per component. These are also ghostscript's default values at 300 ppi. Which kind of halftoning is appropriate depends not only on the printer but also on the document to be printed. For this reason PostScript offers access to the halftoning parameters. You should use this feature in particular if your printer supports more than two intensity levels because ghostscript does not recognize by itself that it can now obtain a higher effective resolution without a loss in the number of shades. However, should your printer support at least 32 intensity levels you need not bother about this point because in that case hpdj will not cause halftoning to be used. For those not familiar with PostScript, here's some code to redefine ghostscript's default halftoning state for non-monochrome colour modes to use an array of halftone cells with a resolution of frequency cells per inch (hence the resolution divided by frequency is the size of the halftone cells in pixels):
currenthalftone dup /HalftoneType get 2 eq
{
  begin
    /RedFrequency   frequency def
    /GreenFrequency frequency def
    /BlueFrequency  frequency def
    /GrayFrequency  frequency def
    currentdict
  end
  sethalftone
}
{pop}  % Not prepared for this case.
ifelse
For general applications, reasonable values for frequency on a 3- or 4-level device at 300 ppi are 75 and 100. You can use the file colorcir.ps in the ghostscript distribution to gain some impression of the effects on the size of halftone cells and the number of shades you can distinguish. Consult a PostScript manual if you want to learn more about how to specify halftones. If you are using the colour mode CMYK and more than 2 black levels you should not set merely a single halftone screen (setscreen, a type-1 or a type-3 halftone dictionary) because ghostscript's dithering routine can in this case return non-monotonic levels of black for monotonic input intensities. However, if you specify independent halftone information for the colour components, gs uses a slower but more accurate algorithm instead which does not lead to the wrong behaviour. It is not necessary for the halftone information to be different for different components to achieve this. Note that ghostscript installs separate halftone screens for CMYK devices by default if the resolution is at least 150 ppi.

LIMITATIONS

  Ghostscript Version
This manual page contains statements relying on undocumented features of ghostscript. These statements are to my best knowledge and belief correct for at least ghostscript 5.50, and I hope I've not missed significant deviations when testing with older versions. But I can't of course guarantee anything for newer ones.

  The Rendering Algorithm
In ghostscript's internal architecture the ghostscript kernel calls on a device driver for basic drawing operations and to ship out completed pages. For most if not all print devices this process can be separated into rendering in memory and transferring the resulting array of pixels to a file or directly to a printer. Ghostscript has an abstract printer device (prn) which uses a memory or clist device for rendering and transfers the completed page to a printer-specific backend for output. Such a backend must supply several parameters for the rendering process but its main purpose is the conversion from ghostscript's internal pixel data structure to a printer-specific format. hpdj is such a prn-derived backend. This means in particular that hpdj does not have much influence on the rendering but also that a user can influence the rendering process by the usual methods available in PostScript. I do not claim that this leaves nothing to be desired. For example, there is no possibility in this implementation to perform Floyd-Steinberg dithering. Of course, one can implement error diffusion in a ghostscript device driver and a number of people have done so in printer-specific backends. I do not believe, though, that such an implementation belongs there: it should better be implemented in an improved rendering device. In that way, it could be used for other printer-specific backends as well. This is also true for every other kind of modification of the rendering process. I have therefore deliberately restricted hpdj to be a "purely printing" backend: it knows about PCL but not about rendering. Therefore, if you need better visual quality for documents with shades of grey or non-primary (non-CMYK) colours, this cannot be achieved by giving some tricky combination of option values to hpdj. Instead you should experiment with the relevant PostScript operators (see chapter 6 of the PostScript Language Reference Manual), or ultimately extend ghostscript's memory and clist devices.

  The Configure Raster Data Command
There is a new PCL-3 command called "Configure Raster Data" for which I have not been able to obtain documentation. This command is apparently the basis for supporting unequal resolutions in horizontal and vertical directions and for HP's Color Resolution Enhancement technology (C-REt). Some option values supported by hpdj lead to Configure Raster Data being used and must therefore be considered unsafe! At least some of the series-500 DeskJets as well as newer models claim to permit unequal resolutions in horizontal and vertical directions, in particular 600 × 300 ppi. The corresponding implementation in hpdj, available only for the model unspec, is based on Configure Raster Data. It seems to work at least for the DeskJet 690C; it does not work for the DeskJet 870Cxi (see below). I would however strongly advise against using these resolutions for printing on a series-500 DeskJet because, although these models have a 600 dpi addressable horizontal resolution grid they do not permit neighbouring pixels to be activated (and the dots printed still have a diameter of about 1/300 in). The raster data generated by gs does not obey this restriction. Concerning the DeskJet 870Cxi, my impression is that although some HP documents and drivers use expressions like "600x300 dpi C-REt color" for this printer, the model does not really support a resolution of 600 × 300 ppi. First, it does not accept hpdj's output with this resolution, and second, if one redirects the best output of HP's Windows driver for this printer to a file, the result is a file with what I've called a mixed resolution, i.e., 600 ppi for black and 300 ppi for CMY. To me it looks therefore as if Hewlett-Packard has been sloppy in formulating its documentation. C-REt makes it possible to specify more than the two basic intensities, on or off, per colour component and pixel. As far as I know C-REt is only available in series-800 DeskJets with the exception of the DJ 890C which instead offers something called PhotoREt II which might or might not be accessible by Configure Raster Data. The implementation of non-default values for hpdj's options BlackLevels and CMYLevels is based on Configure Raster Data. It does seem to work on the DeskJets 850C and 870Cxi.

  Performance for Larger Numbers of Intensity Levels
This could be improved by replacing some generic routines by more specialized ones for particular parameter values. There does not seem much sense in doing this, though, until I know that the code in question actually works on some printer model.

  Mixed Resolutions
Newer DeskJets are able to print with different resolutions for black and CMY on the same region of a page. For example, the best quality on a DeskJet 850C is achieved with 600 ppi for black and 300 ppi for CMY. This is also due to the new Configure Raster Data command and is not supported. I suspect that implementing this really well in ghostscript is not a simple task and probably requires modifying the ghostscript kernel.

  Photo Cartridges
From what I've heard, DeskJet printers with photo cartridges installed do not use a CMYK palette but instead one with 6 components. I have no official information on this interface.

  Cartridge Alignment
DeskJet printers with more than one ink cartridge present should usually be configured for the proper relative alignment of these cartridges. Apparently, this information is stored in not-immediately-volatile memory in the printer together with some default settings like the default media size which are not relevant for printing with hpdj. As I do not have information on how this is done, you will need to use one of HP's programs for this purpose. On a Linux system, try installing and running HP's DOS DeskJet control panel DJCP in the DOS emulator. I did not get it to work, but you might have more luck (or skill). DJCP should be present on one of the installation media you received with your printer.

FUTURE DIRECTIONS
I believe I've already pushed this driver a bit beyond what is sensible. My reasons are:
• First, I have already included functionality for which I do not have sufficiently reliable documentation. After several unsuccessful attempts to coax more out of HP I have given up trying to improve on this situation, and designing hardware drivers by experimentation is in my opinion simply irresponsible. One of the three main design goals of hpdj was reliability.
• Second, I've also run into limitations in ghostscript. One could circumvent this at least partially by dropping the self-imposed restriction on a "purely printing" device driver and including rendering routines. I do not, however, presently have the knowledge and insight to do this and I do not have the impression that the amount of work needed is at an affordable ratio with respect to results. In short: I don't think it's worth the effort.
Besides, I have not found programming for ghostscript a particularly enjoyable experience, and I should also like to concentrate on newer (and totally different) projects. Therefore I do not expect to release new versions of hpdj with significantly extended functionality. There will, however, be at least one further release in which I am going to change the name of the driver from hpdj to (probably) pcl3. The new name will more accurately reflect what this driver is for.

KNOWN BUGS
There are no known bugs in hpdj proper, but there do exist restrictions or bugs in gs which can lead to faulty behaviour when printing with hpdj. As far as I noticed them they are mentioned in the body of this manual page at the relevant points.

SEE ALSO
gs(1) Adobe Systems
PostScript Language Reference Manual
Second edition, 1990. Hewlett-Packard
Technical Reference Guide for the HP DeskJet 500 Series Printers
First edition, October 1994. Manual Part Number: C2170-90099.
Unfortunately, this guide does not describe all valid commands and there is no newer HP manual on PCL-3 (state of October 1997). I was told by the German firm distributing HP manuals that they had even considered writing one themselves for this reason. A few details on PCL and printer models can be obtained from http://www.hp.com. This is not sufficient for programming, though.

AUTHOR
Copyright © 1996, 1997, 1998 by Martin Lottermoser, Metzgerfeldweg 9, 85737 Ismaning, Germany.
E-mail: Martin.Lottermoser@mch.sni.de. This is open source software, released under the terms of the GNU Library General Public License (LGPL), Version 2. USE IT AT YOUR OWN RISK. hpdj has a home page at ftp://ftp.pdb.sni.de/pub/utilities/misc/hpdj.html. The source code for the driver is available in the same directory, file hpdj-version.tar.gz. You should, however, keep in mind that the name of the driver will change in the future (see FUTURE DIRECTIONS) and this will of course be reflected in the names of files.