Modified 2005-02-07 09:01
This section describes how to get your perfectly fine 512 kb Canon LBP4 (LBP-4) printer working under Linux. As usual, the standard disclaimers about broken hardware etc apply here, although I don't think this can really break anything.
A reference for the CAPSL printing language can be found here: capslEscapeCodes.zip (64 kb, in DOS-mode). I can't remember quite where I found this reference, but you can download it here.
I have now made a driver for the 512 Kb LBP4 printer in ghostscript, you can read more about it further down. Even though the lbp4 is a pretty mediocre printer, it has now become lots of fun trying to get it working under Linux. :-)
For the impatient, here is how you get your Canon LBP-4 printer working under Linux. This is based on Daniel Sullivans script, which you can find further down.
--- snip --- #!/bin/bash # Print filter add-on to magicfilter # "echo -e -n '\033'" gives the code for escape (033 octal or 0x1B). # Set escape variable to 033 octal. escape=`echo -e -n '\033'` # Send results of normal print filter through "sed" filter that # replaces ESC[2&z with ESC[0&z. # Any other print filter can replace /etc/magicfilter/lbp8-filter. /etc/magicfilter/lbp8-filter | /bin/sed "s/$escape\[2&z/$escape\[0\\&z/g" --- snip ---
The only caveat here is your distribution might not use magicfilter as debian does. If not, you have to replace /etc/magicfilter/lbp8-filter with the print-filter mandrake uses. It is situated somewhere in the /etc directory.
--- snip --- lp|lbp4|CanonLBP-4:\ :lp=/dev/lp1:sd=/var/spool/lpd/lbp4:\ :sh:pw#80:pl#66:px#1440:mx#0:\ :if=/usr/local/bin/print-filter:\ :af=/var/log/lp-acct:lf=/var/log/lp-errs: --- snip ---
(This calls the LBP-4 filter you just created above).
Now the "no full paint" message should no longer appear when you print.
/etc/magicfilter/lbp8-filter | /bin/sed "s/$escape\[2&z/$escape\[0&z/g" | /bin/sed "s/$escape\[14p/$escape\[30p/g"
The first solution is to use the driver for Canon LBP-8II which is supplied with most distributions of Linux. This barely works, the printer prints, but you have to cancel the error messages that occur on the printer for each page (no full paint). I've used this method, and cursed over it, for quite a while.
The reason the LBP8 driver makes your LBP4 moan each time you print is because the LBP8 printer has more memory than your LBP4. The LBP8 has, in printer terms, a "full paint mode", while the LBP4 only has a "partial paint mode". The LBP4 prints without problems if you print in "partial paint mode". What's causing this is simply a small escape sequence in the beginning of the printout, which you can see if you run:
# gs -sOutputFile=a.outlbp8 -sDEVICE=lbp8 -dNOPAUSE a.ps
This causes gs to output to the file a.outlbp8 instead of printing it to the printer. If you examine the file (with emacs for example), you'd notice something like: "c;[2&z[14p[11h[7 I[63k[0e[2480` ..." in the beginning, which is codes and data sent to the printer. Well. Let's have a look in the CAPSL III reference then (REF.TXT, found in the capslEscapeCodes.zip above):
[...] MEMORY MANAGEMENT: ----------------- Paint Memory Mode: Partial paint...........ESC[0&z = 96 KB Full paint..............ESC[2&z = 992 KB Extended full paint.....ESC[3&z = 1,216 KB [...]
Aha! Found something interesting, eh! "Full paint..............ESC[2&z". Yes. Here's the problem. Well, edit the file in emacs and replace [2&z with [0&z instead (this should occur on each printed page). After that, you can print out the a.outlbp8 file directly, and it will work (at least it works for me). Please use the name "a.outlbp8", since your printer setup's filtering will cause some filenames to be printed in a particular fashion, i.e, dont name it a.ps or something like that.
The second method is using the driver for another printer, the LIPS printer which also uses the CAPSL printing language. Just select the lips3 device for gs, with printtool, magicfilterconfig or whatever it's called on your system.
While the lips3 driver does not complain about the full paint mode as the lbp8-driver does, it is far from perfect. You'll get a page with some garbage before the real printout with the lips3 driver, which renders it pretty useless.
Another method is using the cjet package (Source, 49 kb. Local copy, send a link if this program has a homepage). The trick you have to do here is that you select HP laserjet as your printer (run printtool as root in RH60), and then apply a little trick to /usr/lib/rhs/rhs-printfilters/ps-to-printer.fpi. In this file you should comment out the part using ghostscript, which looks something like:
# We're using ghostscript in traditional manner # eval "$mpage_cmd | sed \"s/[(]%%.*%%[)].*flush//g\" | \ # gs -q -sDEVICE=$GSDEVICE \ # -r$RESOLUTION \ # -sPAPERSIZE=$PAPERSIZE \ # -dNOPAUSE \ # -dSAFER \ # -sOutputFile=- \ # $COLOR \ # $EXTRA_GS_OPTIONS \ # -"and then paste
gs -q -sDEVICE=$GSDEVICE \ -r$RESOLUTION \ -sPAPERSIZE=$PAPERSIZE \ -dNOPAUSE \ -dSAFER \ -sOutputFile=- \ - | /usr/bin/cjet -x -27 -q -to that place. This will pipe the output (HP-PCL) from GS to the cjet-program. The "-x -27 -q" part tells cjet to shift the output 27 dpi to the left on the paper. -q means that cjet will work quietly.
A problem with this way of working is that the LBP4 has quite a small amount of memory (512 kb in my case), which means that it will be unable to print complicated documents, like ps-printing dvi-files for example. I'm looking into a solution to this, and so far I've only come up with a small script that converts the dvi-source to HP-PCL and then parses that with cjet (just like the above, only not incorporated in the normal printing). You can call this file something like dvilpr and place it appropriately. The code goes here:
#!/bin/sh # A small script for printing dvi-files to my Canon LBP4 printer. # First converts the dvi-file to HP-PCL codes, and then parses that # with the cjet-program and prints the output. dvilj $1 -e/tmp/dvilpr.lj cjet -q < /tmp/dvilpr.lj > /tmp/dvilpr.capsl lpr /tmp/dvilpr.capsl if [ -f /tmp/dvilpr.lj ]; then rm -f /tmp/dvilpr.lj fi if [ -f /tmp/dvilpr.capsl ]; then rm -f /tmp/dvilpr.capsl fi
Hopefully, this may be of some help. The trick here is that dvilj uses some of the printers own fonts, at least I think so. When using this script, the printer now outputs dvi-files lightning-fast (well...). It seems there is a problem with outputting graphics in DVIs. I'll check into this one when there's time.
I, as most other unhappy Canon LBP4 owners in the world, would like to have these problems solved once and for all. One solution is of course to buy a new printer, but that is another way of saying "I give up". When the Postscript Color Laser printers costs as little as my LBP4 did when I bought that, I'll buy one of those, but until then ...
The best way to solve this problem, I believe, is of course to provide a driver for GS for the beloved LBP4. I've checked into the sources of GhostScript, and those are not trivial. Not at all. Perhaps I've missed something, but I think it looks hard. Still, it's just the initialising that needs changing, a small, small part. So, if there's a GS-wizard out there, you can probably solve our problems easily!
Another way, which I'm not sure works, is to provide a filter specifically for the LBP4. This would pipe the output of gs and replace [2&z with [0&z, which SHOULD cause it to print without those irritating stops for each page.
Well. I had a look at the gs-sources and decided that they wasn't too hard to understand, after all. So I got round to hack the lbp8 driver to also generate a device for the lbp4-printer (called lbp4). As far as I can tell, it works.
Note that this lbp4 driver is only valid for LBP4-printers with 512 Kb memory, with more they are just as well off with the full paint mode that the lbp8 driver uses. I'll post the patched debian packages, and the source, here as soon as I feel I've tested it enough...
The lbp8-driver should really be configurable to allow for different memory-sizes and paper-sizes. I'm not good enough to do this.
I recieved a mail from Daniel Sullivan, daniels[at]mdo[dot]net, where he described the problems with paper sizes for the LBP-4 and LBP-8. Apparently, the gs-driver always sets the paper-size to A4, so the Letter-people have problems printing with the lbp4. Daniel also provided a solution to this, a small script and a change to the if= of the printcap. First, the script to pipe the output of the filter through goes here:
#!/bin/bash # Print filter add-on to magicfilter # Removes printer code for A4 paper and replaces it with # code for letter size paper. # The /etc/printcap file must be changed to use this filter as # the input filter. # "echo -e -n '\033'" gives the code for escape (033 octal or 0x1B). # Set escape variable to 033 octal. escape=`echo -e -n '\033'` # Send results of normal print filter through "sed" filter that # replaces ESC[14p with ESC[30p. # Any other print filter can replace /etc/magicfilter/lbp8-filter. /etc/magicfilter/lbp8-filter | /bin/sed "s/$escape\[14p/$escape\[30p/g"
ESC[14p means A4, while ESC[30p means Letter. Note that this filter does not fix the memory-problems of the low-mem lbp4s, but that can be achieved in exatly the same way (by replacing ESC[2&z with ESC[0&z). Note too, that his add-on uses magicfilter, but should be possible to use with other filtering solutions too. Now, to install the filter, begin with copying the add-on above to someplace like /usr/local/bin. Then edit /etc/printcap to something like this: (This is Daniels printcap).
# # Copyright (c) 1983 Regents of the University of California. # All rights reserved. # # Redistribution and use in source and binary forms are permitted # provided that this notice is preserved and that due credit is given # to the University of California at Berkeley. The name of the University # may not be used to endorse or promote products derived from this # software without specific prior written permission. This software # is provided ``as is'' without express or implied warranty. # # @(#)etc.printcap 5.2 (Berkeley) 5/5/88 # # This file was generated by /usr/sbin/magicfilterconfig. # # Old lp for magicfilter #lp|lbp4|CanonLBP-4:\ # :lp=/dev/lp1:sd=/var/spool/lpd/lbp4:\ # :sh:pw#80:pl#66:px#1440:mx#0:\ # :if=/etc/magicfilter/lbp8-filter:\ # :af=/var/log/lp-acct:lf=/var/log/lp-errs: # # New lp: uses "print-filter" to remove bad printer codes # lp|lbp4|CanonLBP-4:\ :lp=/dev/lp1:sd=/var/spool/lpd/lbp4:\ :sh:pw#80:pl#66:px#1440:mx#0:\ :if=/usr/local/bin/print-filter:\ :af=/var/log/lp-acct:lf=/var/log/lp-errs:
The if= portion is the important line. It should contain the filter add-on mentioned above (called /usr/local/bin/print-filter in this example). We all thank Daniel Sullivan for this contribution!
You can click here to see some statistics on the page.