LPR Print Filters - How To Cut out the MiddleMan

A recent Thread 50281 provided excellent documentation of three different ways of print filtering when using FreeBSD's LPR print spooler. What became evident during the course of the thread was that all the various options, in the thread, eventually utilize ghostscript and that many *ppd's are based on gs drivers . As far as the print output, all three in their default configuration produced the same output. This how to assumes familiarity with the lpr section in the FreeBSD handbook (Currently Chapter 11)..

The path of a print job via 1) A simple gs based filter 2) foomatic-rip and 3) Magic Filter is illustrated below.
filters_495px.png

Ghostscript based *.ppd's can be parsed for gs based drivers and gs print options that can be used to customize a simple gs filter. Other printers have Postscript, which is licensed from Adobe, or have an unlicensed "Postscript emulation". If you have Postscript or Postscript-emulation, you do not need a filter - just send the output directly to the printer as described in the handbook.

What follows are some examples where common gs modifications for print filters were parsed out of a ppd and plugged into the gs code line.

These examples are based on a somewhat old H-P 5L Laserjet.

Starting with the basic filter from Chapter 10.5.3.3 in the handbook

Code:
/usr/local/bin/gs -dSAFER -dNOPAUSE -q -dBATCH -sDEVICE=**** -sOutputFile=- -

The -sDEVICE entry is the ghostscript driver and can be pulled from the ppd with
less HP-LaserJet_5L-ljet4.ppd | grep driver
Code:
*% driver option access with all supported printer drivers and printing
*driverName ljet4: "
  Built-in Ghostscript driver for PCL 5e laser printers
*driverType G/Ghostscript built-in: ""
*driverUrl: "http://www.ghostscript.com/"
*driverObsolete: False
*driverSupplier: "GPL Ghostscript"
*driverManufacturerSupplied: False
*driverLicense: "GPL"
*driverFreeSoftware: True
*driverSupportContactVoluntary: "http://forums.openprinting.org/ OpenPrinting forums"
*driverMaxResolution: 600 600
*driverColor: False
*driverTextSupport: 90
*driverLineartSupport: 90
*driverGraphicsSupport: 60
*driverPhotoSupport: 30
*driverRenderingSpeed: 90

You can verify that the driver is available in gs with
gs -h
So the basic filter, using the gs ljet4 and no options becomes
Code:
#!/bin/sh
/usr/local/bin/gs -dSAFER -dNOPAUSE -q -dBATCH  -sDEVICE=ljet4 -sOutputFile=- -

The default options in the ppd:
less HP-LaserJet_5L-ljet4.ppd | grep Default
Code:
*DefaultColorSpace: Gray
*DefaultPageSize: Letter
*DefaultPageRegion: Letter
*DefaultImageableArea: Letter
*DefaultPaperDimension: Letter
*DefaultInputSlot: Default
*InputSlot Default/Printer Default: "%% FoomaticRIPOptionSetting: InputSlot=Default"
*FoomaticRIPOptionSetting InputSlot=Default: " -dMediaPosition=0"
*DefaultManualfeed: Off
*DefaultEconomode: Off
*DefaultCopies: 1
*FoomaticRIPDefaultCopies: 1
*DefaultResolution: 300x300dpi
*DefaultREt: Medium
*DefaultTonerDensity: 3
*DefaultMPTray: First
*DefaultFont: Courier

The default options for print/cups and foomatic-rip users can be specified in the simple gs filter by setting
-sPAPERSIZE=letter and -r=300x300
Code:
#!/bin/sh
/usr/local/bin/gs -dSAFER -dNOPAUSE -q -dBATCH -sPAPERSIZE=letter -r300x300 \
-sDEVICE=ljet4 -sOutputFile=- -

In the next examples we'll look closer at pagesize. In my particular *ppd, the height and width of various papersizes are specified as -dDEVICEWIDTHPOINTS and dDEVICEHEIGHTPOINTS. There are 72 points (pts) per inch so a US, 8 1/2" x 11" letter in portrait orientation is -dDEVICEWIDTHPOINTS=612 and -dDEVICEHEIGHTPOINTS=792. Although you can set your paper size using points, Ghostscript provides a concise specification for common paper sizes listed in this link: Ghostscript 9.07 Use.htm#Paper_size.
Code:
#!/bin/sh
/usr/local/bin/gs -dSAFER -dNOPAUSE -q -dBATCH -sPAPERSIZE=a4 -sDEVICE=ljet4 \
-sOutputFile=- -
A more complex example to print #10 envelopes using the HP ppd tray settings. #10 Business envelopes are specified in the ppd but it is not a gs -sPAPERSIZE option. Envelopes are not a big print job so we will max out the resolution.
There was not a convenient way to pull the #10 Envelope setting from the ppd but the PageSizes are all in one grouping. The one were interested in is:
Code:
*PageSize Env10/Envelope #10: "%% FoomaticRIPOptionSetting: PageSize=Env10"
*FoomaticRIPOptionSetting PageSize=Env10: " -dDEVICEWIDTHPOINTS=297 -d&&
DEVICEHEIGHTPOINTS=684"

less HP-LaserJet_5L-ljet4.ppd | grep InputSlot
Code:
*OpenUI *InputSlot/Media Source: PickOne
*FoomaticRIPOption InputSlot: enum CmdLine A
*OrderDependency: 100 AnySetup *InputSlot
*DefaultInputSlot: Default
*InputSlot Default/Printer Default: "%% FoomaticRIPOptionSetting: InputSlot=Default"
*FoomaticRIPOptionSetting InputSlot=Default: " -dMediaPosition=0"
*InputSlot Upper/Upper Tray: "%% FoomaticRIPOptionSetting: InputSlot=Upper"
*FoomaticRIPOptionSetting InputSlot=Upper: " -dMediaPosition=1"
*InputSlot Middle/Middle Tray: "%% FoomaticRIPOptionSetting: InputSlot=Middle"
*FoomaticRIPOptionSetting InputSlot=Middle: " -dMediaPosition=4"
*InputSlot Lower/Lower Tray: "%% FoomaticRIPOptionSetting: InputSlot=Lower"
*FoomaticRIPOptionSetting InputSlot=Lower: " -dMediaPosition=5"
*InputSlot Multipurpose/Multipurpose Tray: "%% FoomaticRIPOptionSetting: InputSlot=Multipurpose"
*FoomaticRIPOptionSetting InputSlot=Multipurpose: " -dMediaPosition=8"
*InputSlot Automatic/Automatic: "%% FoomaticRIPOptionSetting: InputSlot=Automatic"
*FoomaticRIPOptionSetting InputSlot=Automatic: " -dMediaPosition=7"
*InputSlot Envelope/Envelope Feeder: "%% FoomaticRIPOptionSetting: InputSlot=Envelope"
*FoomaticRIPOptionSetting InputSlot=Envelope: " -dMediaPosition=3"
*InputSlot Manual/Manual Feeder: "%% FoomaticRIPOptionSetting: InputSlot=Manual"
*FoomaticRIPOptionSetting InputSlot=Manual: " -dMediaPosition=2"
*CloseUI: *InputSlot
less HP-LaserJet_5L-ljet4.ppd | grep Resolution
Code:
*driverMaxResolution: 600 600
*OpenUI *Resolution/Resolution: PickOne
*FoomaticRIPOption Resolution: enum CmdLine A
*OrderDependency: 110 AnySetup *Resolution
*DefaultResolution: 300x300dpi
*Resolution 75x75dpi/75x75 DPI: "%% FoomaticRIPOptionSetting: Resolution=75x75dpi"
*FoomaticRIPOptionSetting Resolution=75x75dpi: " -r75x75"
*Resolution 150x150dpi/150x150 DPI: "%% FoomaticRIPOptionSetting: Resolution=150x150dpi"
*FoomaticRIPOptionSetting Resolution=150x150dpi: " -r150x150"
*Resolution 300x300dpi/300x300 DPI: "%% FoomaticRIPOptionSetting: Resolution=300x300dpi"
*FoomaticRIPOptionSetting Resolution=300x300dpi: " -r300x300"
*Resolution 600x600dpi/600x600 DPI: "%% FoomaticRIPOptionSetting: Resolution=600x600dpi"
*FoomaticRIPOptionSetting Resolution=600x600dpi: " -r600x600"
*CloseUI: *Resolution

I'm going to manually feed the envelopes, " -dMediaPosition=2" with #10 envelope dimensions and a 600x600dpi resolution:
Code:
#!/bin/sh
/usr/local/bin/gs -dSAFER -dNOPAUSE -q -dDEVICEWIDTHPOINTS=297 \
-dDEVICEHEIGHTPOINTS=684 -dMediaPosition=2 -dBATCH \
-r600x600 -sDEVICE=ljet4 -sOutputFile=- -

Edit: Added Postscript and Postscript-emulation.
 
Last edited:
Back
Top