CAPS Universe documentation
1.0.4
All you need to know to be successful
|
In the past the printer descripting files (aka PPD files, aka PostScript Printer Description files) were static files, used to describe the features a printer has and how to control them. This kind of description files is still in use, even if PostScript printers are less popular nowadays than in the past.
And with these static PPD files I always wonder, why I can select a DIN A5 paper format even if my printer has only one paper tray filled with DIN A4 paper. Or why I must select a label format from a list, even if the printer can detect the loaded label size by itself. That is why I wanted dynamic PPD files from the beginning: if my printer has only DIN A4 paper to print on, it should only provide DIN A4 format in the dialogues - and nothing else (makes no sense).
Or if a label printer detects a 6 cm by 3 cm label loaded, it should only provide this format to me in the dialogue. Everything else just confuses every user (including me).
That's why every printer driver must register itself with a descriptive data structure about its features: struct caps_ppd_base.
Here the description how to fill it correctly:
You should support NLS from the beginning. The idea is to not only print messages in the user's native language (which is the mostly use case I guess), also the PPD content should handled accordingly. Due to this, a user can read the printer's feature settings in PPD based printing dialogues in his/her own native language.
In order to support this, you should mark all translateable strings in your printer feature description with the NLS_() macro. Example:
The NLS_() macro expands to the plain string for the compiler. But the gettext tools will extract your sentenses and collect them into pot files for translation into different languages.
To make use of translated sentenses you must define your translation domain name to the libcapsppd via the caps_ppd_base::domain_name member.
Most of the time it is enough to just define this member to the local PACKAGE macro. This macro is defined by the autotools
when the package's configure
script runs. That's all. libcapsppd will make use of your package translations (if available in the requested language), when it creates the PPD on the fly.
Printers shares many features. So they do not need a special description, a simple bit is enough to describe the feature.
The caps_ppd_base::common_features member describes such shared features.
If you have set the LIBCAPS_GA_SINGLE_TRAY bit, the available (e.g. loaded) paper format is expected in the caps_ppd_base::default_paper_name. Here you must use a format name known by libpaper, because it is used to retrieve the width and length of the paper format.
If the LIBCAPS_GA_SINGLE_TRAY bit isn't set, the caps_ppd_base::default_paper_name member is used to define the default paper name in the PPD PageSize
list as the DefaultPageSize
value.
The caps_ppd_base::paper_type member defines if the medium your printer prints on is of continuous form (LIBCAPS_PT_ENDLESS) like labels can be, or individual pages (LIBCAPS_PT_ENDLESS).
The caps_ppd_base::default_leading_edges member is a complicated beast. Refer caps_ppd_paper_leading_edges for a description.
The caps_ppd_base::supported_color_formats member defines the colour space(s) the printer driver supports to print.
If more than one of the LIBCAPS_CT_* enums are or'ed, the PPD will contain a choice to let the user select one of the available colour spaces. Thus, the user can force your printer driver to print a coloured image in greyscale by selecting the LIBCAPS_CT_GRAY PPD choice. Or the user can force a greyscale image to be printed with CMYK colours by selecting the LIBCAPS_CT_CMYK PPD choice instead (if you enable this colour space).
Since PPD files contain a default selection for various features, you must define a default colour space as well. For this, the caps_ppd_base::default_color_format member is used. In this member only one of the LIBCAPS_CT_* enums can be used.
Beside the feature to print in black/white or colours, a second main feature of all printers is their printing resolution. Label printers often can print in one resolution only, while many other printers have the capability to print in more than one (selectable) resolution.
The members caps_ppd_base::resolution_count, caps_ppd_base::default_resolution and caps_ppd_base::resolutions define the printer's resolution capabilities.
The caps_ppd_base::resolutions member points to an array of caps_ppd_resolution entries. Each of it defines one possible resolution capability, separated into the horizontal and vertical direction. Their values are meant in Dots Per Inch (DPI). The entries count in this array must be defined in the caps_ppd_base::resolution_count member. Since the PPD must contain a default resolution, this must be defined in the caps_ppd_base::default_resolution member, as an entry index into the caps_ppd_base::resolutions array.
The example below shows a printer which supports three different resolution settings. The first two are using the same resolution for the horizontal and vertical direction, while the third has a higher resolution only in the horizontal direction. The default resolution selection in the PPD should be the second entry on the array.
const
here and only define them at compile time, but you can set them up at run-time as well (for example based on INI file settings).The caps_ppd_base::media_coverage member defines the printer's print size restrictions, mostly defined by mechanical limitations. For most printers it is somehow defined in their manuals, at least for the manual media feed (if available). While the maximum print size is limited to the largest media format the printer can deal with, the minimum print size is mostly defined for the manual media feed only. The caps_ppd_base::media_coverage member is used to limit the available media format entries in libpaper to the sizes the printer supports. Thus, the user can never select a paper format in the print dialogue the printer cannot handle due to its limitations.
In this example the printer's maximum size is limited by the paper tray size (215.9 mm x 406.4 mm) and the minimum size is limited due to the mechanics to move the medium correctly inside the printer.
The caps_ppd_base::media_margins member defines the printer's printable area and these values are used to define the ImageableArea content in the generated PPD.
Non printable margins are the second mechanical limitation of your printer. You cannot print up to the papers borders precisly on most printers. Thus, you always need some margins at all four paper borders - sometimes four different ones depending on the mechanics.
In this example, the printer has mirrored margin requirements. But the manual defines different margins for portrait versus landscape print. I don't know why and how to deal with it. Currently only one set of margins is supported.
Beside shared features, there are most of the time printer specific features as well.
If you want user selectable printer specific features, you can include them into the PPD as an OpenUI/CloseUI. The printing dialogues will show them and the user can chose a selection. It is a matter of taste if you want to include them into the PPD or not. Some features are more a one time configuration and never changed again.
For example my printer needs to know at what physical hight it is used: below 1000 m or above (aka "Air Pressure"). This kind of setting is (IMHO) more a one time setting, than something you need to select on a print job base.
So my printer driver reads this special setting from the driver's feature INI file and not from the PPD file. But it is up to you where you locate the printer/printer driver specific feature settings.
Two members exist to define additional PPD selections in the printer description: caps_ppd_base::selections is an array and caps_ppd_base::selection_count counts the elements in this array.
Each selection entry is divided into two parts: the base description entry caps_ppd_selection and the selections itself via caps_ppd_selection_entry.
Lets start with the caps_ppd_selection_entry which defines the selections the user can see later in his printing dialogue.
In my example below I add a printer specific feature called EconoMode. It seems changing how the printer deals with its toner somehow. It starts with the selectable entries: this printer can switch this feature off entirely or can use four increments.
The base description for this feature follows and completes the OpenUI/CloseUI definition:
The caps_ppd_selection::option_type member defines the type of this OpenUI/CloseUI PPD entry. I have only seen LIBCAPS_OT_PICKONE yet: the user gets a list of possible selections in his print dialogue and can exactly pick one entry from this list. The also possible LIBCAPS_OT_PICKMANY or LIBCAPS_OT_BOOLEAN are good for…what?
The caps_ppd_selection::option member is the overall name for this choice. It is the key name later on, if you want to retrieve the user's selection.
The caps_ppd_selection::description member defines the description text the user will see in the printing dialogue later on. Due to this you should support Printer Driver National Language Support here.
The remaining three members caps_ppd_selection::entries, caps_ppd_selection::default_entry and caps_ppd_selection::entry_count refer the caps_ppd_selection_entry where you have already defined the possible selections.
Via the members caps_ppd_base::options and caps_ppd_base::options_count more printer specific data can be included into the PPD.
One use for this feature is to define a single paper format type, if the printer has one paper tray only and there is no way for different paper formats and thus, no need to have a selectable paper format OpenUI/CloseUI in the PPD. Other usage can be to insert some printer specific values into the PPD, a generic printer driver can use to parametrize the print later on.