Getting the most out of the texttopdf filter used with CUPS on Debian 9 (stretch) and later.
Font Selection and fontconfig
Printing a text file requires at least one suitable font to be available on the system. Supported font formats are TrueType (TTF), OpenType (OTF) and TrueType Collection (TTC). The font should be monospaced.
Font selection is taken care of within the fontconfig framework, documented in fonts-conf, in conjunction with pdf.utf-8, which is found in /usr/share/cups/charsets and installed by the cups-filters package. By default, pdf.utf-8 is symlinked to pdf.utf-8.simple, whose essential content is
charset utf8 0000 04FF ltor single monospace monospace:bold monospace:oblique monospace:bold:oblique 0500 05FF rtol single monospace
Note that monospace is a selector that enables fontconfig to choose a monopaced font. fontconfig will search for fonts that are registered in the monospace group and return what it considers to be the best suitable candidate that is available on the system. This could be FreeMono or DejaVuSansMono or any other monospaced font.
Altering the System-wide Default Font for Printing
The cups-filters package hasn't any dependency on a specific font package but it pulls in fontconfig-config (via libfontconfig1) because it depends on it. In its turn fontconfig-config has a dependency beginning
fonts-dejavu-core | ttf-bitstream-vera | fonts-liberation | fonts-freefont...
This will normally lead to the first in the list being installed. fonts-dejavu-core has a monospaced font. Consequently, there will always be one monospaced font on the system.
The preferred way of using a chosen textttopdf_font would be to create /etc/fonts/local.conf with the contents
<?xml version='1.0'?> <!DOCTYPE fontconfig SYSTEM 'fonts.dtd'> <fontconfig> <alias> <family>monospace</family> <prefer> <family>textttopdf_font</family> </prefer> </alias> </fontconfig>
Possibilities for textttopdf_font are Liberation Mono, FreeMono, Moto Mono or Inconsolata.
User Control of the Default Printing Font
Filters such as texttopdf are always run by the printing system as a non-privileged user, typically lp, with no connection to the user's desktop. This implies that printing via cups-filters is not an option and that a user would have to execute texttopdf under user privileges to gain control of font selection.
The conversion of a text file to a PDF is done with with
CHARSET=utf-8 /usr/lib/cups/filter/texttopdf 1 1 1 1 1 < <text_file> > out.pdf
CHARSET=utf-8 tells the filter to consult /usr/share/cups/charsets/pdf.utf-8, where it will find the request for a monospace font.
fontconfig will now be capable of using what a user wants from the monospace selector when the xml snippet above is put into $HOME/.config/fontconfig/fonts.conf. The user's fonts.conf will take precedence over the system's /etc/fonts/local.conf because texttopdf is being run by an ordinary user.
The two-step production of a PDF and sending it to the printing system can be automated with Tea4CUPS
The Case for FreeMono
The choice of a font for printing text files may very well be based on the look of the font. This is a reasonable criterion. However, there are other factors such as the range of glyphs in the font and, by implication, the language(s) used in the text.
GNU FreeMono has veryfont good coverage of glyphs and caters for characters from many Unicode blocks. It can be compared with other monospaced fonts by altering the the system or user-chosen font and producing and viewing a PDF of UTF-8-demo.txt using (respectively) cupsfilter or texttopdf:
- Produce a PDF with
/usr/sbin/cupsfilter UTF-8-demo.txt > out.pdf CHARSET=utf-8 /usr/lib/cups/filter/texttopdf 1 1 1 1 1 UTF-8-demo.txt > out.pdf
- Check the font used with
- View the PDF with
Using texttpdf to Produce PDFs
The primary purpose of cups-filters is to process files (in conjunction with CUPS) to produce an end product of toner or ink being put on a medium such as paper. However, it didn't take long for people to realise the CUPS+cupsfilters combination gave a way of capturing a PDF file without sending it to a printer. This opens up a way of archiving text files and scripting batch production of PDFs from them using something that is probably on the system already.
Either of the two commands given previously may be used to produce a PDF. An issue that may arise is that the PDFs do not have searchable or extractable test. This is a consequence of the design of the texttopdf filter. If it matters, the situation may be rectified with some post-processing.
With the system text font:
/usr/sbin/cupsfilter <input.txt> | pdftocairo -pdf - out.pdf
With a user's text font:
CHARSET=utf-8 /usr/lib/cups/filter/texttopdf 1 1 1 1 1 <input.txt> | pdftocairo -pdf - out.pdf
You may want to look at the Tea4CUPS page for ideas on creating a searchable PDF with chosen embedded fonts as part of the printing system workflow.
texttopdf handles a text file such as /etc/services by producing a PDF portrait page with the text parallel to the short edge. If either landscape or orientation-requested=4 is given as an option to texttopdf, the PDF is a landscape page and the text is placed parallel to the long edge. The second PDF is processed by pdftopdf to print correctly.
lp -d <queue> /etc/services lp -d <queue> -o landscape /etc/services +------------+ +----------------------+ |AAAAAAAAAAAA| |BBBBBBBBBBBBBBBBBBBBBB| | | | | | | | | | | +----------------------+ | | | | +------------+
The texttopdf filter is based on CUPS' texttops filter and written by Tobias Hoffmann <smilingthax SPAMFREE AT googlemail DOT com> under the auspices of the OpenPrinting group. Significant work has been done in bug #662660 and bug #663070 by Fabian Greffrath <fabian SPAMFREE AT debian DOT org> to integrate the use of fontconfig into the filter.