Gutenprint is a suite of printer drivers that can be used with UNIX and Linux print spooling systems, such as CUPS (Common UNIX Printing System), lpr, LPRng, and others. Gutenprint currently supports over 700 printer models. Gutenprint was recently ported to Haiku, both increasing its printing capabilities, as well as extending its supported printer models. This article describes Gutenprint and the effort to port it to Haiku.
Extending the Haiku printer driver framework
Libprint, the printer driver framework, is used by native printer drivers such as
Canon LIPS 3 and 4, HP PCL5 and PCL6, and Adobe PostScript. Exceptions are the Preview and
the PDF printer driver.
This framework makes it very easy to add a new printer driver to Haiku. It provides the
user interface for the page setup dialog, the print job setup dialog and a preview window.
It performs the rendering of the page as a sequence of bitmap bands. The printer
driver then converts the bitmap bands to a stream of data in a format that is understood
by each printer.
The setup dialogs provide a fixed set of settings whose value ranges are configurable
to match specific printer drivers. For example whether a printer is a color printer and the available
paper sizes (Letter, A4, …).
The page setup dialog in Figure 1 shows the values for paper size and resolution from Gutenprint.
Figure 1: Page Setup Dialog
Gutenprint contains a meta model for the available settings of a printer model. Some of these
settings can be mapped to existing settings provided by libprint. For the missing settings
libprint had to be extended to show them in the job setup dialog and to persist them in the
Now libprint supports the following type of settings: A list of values visualized as
a combo box, a boolean flag visualized as a check box and a value in a range of values
visualized as a slider.
Figure 2 shows the job setup dialog. The settings inside the red rectangle are the missing settings
Gutenprint categorizes settings from basic to advanced. In the printer driver only the basic
settings are enabled. When the advanced settings are enabled there are so many that the
setup dialog would get too large to fit on most screens because of a
in the Layout API. As soon as this bug is fixed the advanced settings can be enabled.
Gutenprint consists at least of the core library, a GTK user interface, and support for CUPS, foomatic,
GIMP and Ghostscript.
For the printer driver, only the core library is required. The Gutenprint core library provides an API to
query the available printer models, to query and modify the printer model specific settings, and to
convert an image on a page into a stream of printer specific data.
Porting Gutenprint to Haiku was relatively easy. The core built without any problems with both GCC2 and GCC4
once the configuration files had been created.
Gutenprint uses the “configure”
script to support building on different platforms and in differnt configurations
but the script does not support Haiku yet.
So building on Haiku did not work at first. Since I did not have the knowledge of how to get the configure
script working on Haiku, and I did not want to waste too much time in getting it to build,
I decided to first try to build Gutenprint on OpenSuSE. There was no problem with that build. The
configure script generated header and make files. In the header files macros are used for the
configuration of the Gutenprint build.
After adapting the header files for Haiku and creating Jamfiles, the port was completed!
At runtime Gutenprint needs some data files that are part of Gutenprint source code repository.
When the Haiku image is created these data files needed to be copied to the image as well.
For example the list of printer models is stored in an XML file
Writing the printer driver
Since I had written native Haiku printer drivers
using libprint in the past I am familiar with the
printer driver framework. The driver was implemented step by step.
After each step the added functionality could be tested. The steps outlined here might not be
in chronological order.
I started with a printer driver skeleton by copying an existing driver
and the removing the printer driver specific source code. The driver could be built soon but
did not generate any output yet.
First the printer model selection dialog was implemented. Thanks
to Ithamar R. Adema who implemented such a dialog for the PostScript driver, the user interface
was already available as depicted in figure 3.
Only the printer manufacturer and model had to be obtained from Gutenprint.
Figure 3: Printer Model Selection Dialog.
Then the settings needed for libprint where obtained from Gutenprint.
At this point in time the other Gutenprint generic settings weren’t supported yet.
These were implemented in the last step.
At this step, the printer still did nothing. The bitmap bands for a page needed to be handed over to
Gutenprint. Figure 4 shows an illustration of an image on a page.
When all bitmap bands for a page are available Gutenprint is requested to
print an image on the page. The position and size of the image are set and then Gutenprint
uses a callback mechanism to request the size of the image in pixels and gets the
pixels for the image to be printed line by line.
The pixels are always encoded in RGB 8 bits per channel. For black and white printing
Gutenprint is responsible for doing the color conversion.
The maximum number of bytes temporarily required for a page in letter size in 300 DPI should be
about 32 MiB and for 600 DPI it should be about 128 MiB. On modern hardware that should not
be a problem.
Figure 4: The page with printable rectangle and an image enclosing the bitmap bands.
The bitmap band to Gutenprint image conversion worked on the second attempt printing a test page.
I had quite some difficulties to get the image positioning and size calculation right,
as the unit is 1/72 Inches and the internal unit is 1/dpi where dpi is the currently
selected resolution and at first I wanted it to be as exact as possible. The position and
size should be a multiple of the greatest common divisor of 72 and dpi.
However that is not always possible without truncation of the output image,
because Gutenprint does not allow to place an image outside the printable rectangle
(there is usually a margin of more or less 10/72 Inch around the paper where printing is not possible).
Now a not so accurate solution is implemented that stays within the paper margin limits,
that seems to work good enough.
During the work on the Gutenprint driver most of the printing related user interfaces were
updated to use the Layout API. This gets rid of font size sensitivity issues.
Also some bugs were fixed in the USB transport add-on and in libprint where the page contents
did not rotate printing in landscape mode.
Lines of Code
The following table shows the lines of codes in revision
39800 of the header files, source files,
their sum and the percentage of the sum to the total number of lines.
The lines of codes includes empty lines and comments.
|Component||.h||.cpp||.h + .cpp||Percentage|
|Haiku printer driver framework (libprint)||3.202||8.418||11.620||17,7%|
|Haiku Gutenprint printer driver (Gutenprint)||689||2.344||3.033||4,6%|
Table 1: Lines of Codes.
For the extension of libprint about 1538 lines were added.
Not all lines were new code because the code style in libprint was changed to conform to the
Haiku coding style.
The total number of lines increased between revision 36173
and 39800 in libprint and
Gutenprint printer driver to 4.571.
Copyright 2010 Michael Pfeiffer (a.k.a. laplace)
Lector: Andrew Hudson
This article will be also hosted at haiku-os.org