Translation(s): none


Getting the most out of the texttopdf filter used with CUPS on Jessie and Stretch.

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 on Debian 8.x (Jessie) is

charset utf8
0000 04FF ltor single FreeMono FreeMono:bold FreeMono:oblique FreeMono:bold:oblique
0500 05FF rtol single FreeMono

Note that the font names are not file names but selectors which enable fontconfig to choose a monopaced font. The font used for printing will always be FreeMono if fontconfig finds it on the system but otherwise it will conduct a search based on the generic font group which Freemono belongs to. FreeMono belongs to the monospace group of fonts so fontconfig will search for other fonts that are registered in this group and use the first match it finds.

On Debian 9.x (Stretch) pdf.utf-8.simple has been changed to contain

charset utf8
0000 04FF ltor single monospace monospace:bold monospace:oblique monospace:bold:oblique
0500 05FF rtol single monospace

monospace is still a selector for fontconfig but the hard-coded request for FreeMono is changed to the to the generic monospace alias. fontconfig returns the best suitable monospaced font that is available on the system. This might be FreeMono or DejaVuSansMono or any other monospaced font. The preference for a particular font can be configured on a per-system basis by altering which file pdf.utf-8 links to (Jessie and Stretch) or by means of a fontconfig configuration file (Stretch only).

Altering the System-wide Default Font for Printing

The cups-filters package has no 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 the dependency

fonts-dejavu-core | ttf-bitstream-vera | fonts-liberation | fonts-freefont

All these four packages have a monospaced font. There will consequently always be one monospaced font on the system

As pdf.utf-8.simple is written on Jessie, fontconfig will always select FreeMono if this font is installed. It will only fall back to one of DejaVuSansMono or LiberationMono or VeraMono if FreeMono is not available. To specify exactly what font to use, the file pdf.utf-8.defaultfont can be created to replace pdf.utf-8.simple and linked to pdf.utf-8. With the fonts-linuxlibertine package it would be sufficient to have pdf.utf-8.defaultfont as

charset utf8
0000 04FF ltor single /usr/share/fonts/opentype/linux-libertine/LinLibertine_M.otf

This bypasses fontconfig and also works on Stretch.

Substituting the Stretch pdf.utf-8.simple for the Jessie version is also something to consider.

The preferred way of using a chosen textttopdf_font on Stretch 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>

User Control of the Default Printing Font

Filters are always run as a non-privileged user, typically lp, with no connection to the user's desktop. On Jessie and Stretch a user would have to pre-process the text file to produce a PDF which is then sent to the printing system. The PDF would have the chosen font embedded in it.

Create the directory $HOME/charsets and the file pdf.utf-8 (examples below). Put pdf.utf-8 into $HOME/charsets. Convert the text file to a PDF with

CUPS_DATADIR=$HOME CHARSET=utf-8 /usr/lib/cups/filter/texttopdf 1 1 1 1 1 <text_file> > out.pdf

$CUPS_DATADIR would normally be /usr/share/cups/ but texttopdf will now look for the character set in a charsets directory in the home directory. Here are two example $HOME/charsets/pdf.utf-8 files which will override the hard-coded FreeMono font selection:

charset utf8
0000 04FF ltor single /usr/share/fonts/truetype/noto/NotoMono-Regular.ttf

charset utf8
0000 04FF ltor single LiberationMono LiberationMono:bold LiberationMono:oblique LiberationMono:bold:oblique

Use the xml snippet above in $HOME/.config/fontconfig/fonts.conf. The user's fonts.conf will take precedence over the system's local.conf because texttopdf is being run by an ordinary user. Produce a PDF with

CHARSET=utf-8 /usr/lib/cups/filter/texttopdf 1 1 1 1 1 <text_file> > out.pdf

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 very good coverage of glyphs and caters for characters from many Unicode blocks. It may be compared with other monospaced fonts by altering the system font and producing and viewing a PDF of the UTF-8-demo.txt using cupsfilter:

A Difference Between TrueType and OpenType Fonts When Printing

Install fonts-freefont-ttf and convert a text file to a PDF with cupsfilter. The outputs below were obtained from a Jessie machine with a default install.

/usr/sbin/cupsfilter /etc/services > services.pdf

Find the size of services.pdf and run pdffonts to analyse the fonts it uses:

brian@jessie:~$ ls -l services.pdf
-rw-r--r-- 1 brian brian 239047 Jun  9 16:35 services.pdf

brian@jessie:~$ pdffonts services.pdf
name             type          encoding    emb sub uni object ID
---------------  ------------  ----------  ---------------------
SHXZNP+FreeMono  CID TrueType  Identity-H  yes yes no      41  0

Remove fonts-freefont-ttf, replace it with fonts-freefont-otf and repeat.

brian@jessie:~$ ls -l services.pdf
-rw-r--r-- 1 brian brian 755004 Jun  9 16:23 services.pdf

brian@jessie:~$ pdffonts services.pdf
name                     type         encoding    emb sub uni object ID
-----------------------  -----------  ----------  ---------------------
FreeMonoBold-Identity-H  CID Type 0C  Identity-H  yes no  no      40  0
FreeMono-Identity-H      CID Type 0C  Identity-H  yes no  no      45  0

The second file has the fonts embedded but not subset. In other words, the complete font has been included in the file produced by texttopdf. This results in a much larger file to be sent to the printer and might result in a longer printing time. This is not necessarily a problem but it is as well to be aware that using OTF is not yet equivalent to using TTF for the monospaced font.

Using texttpdf to Produce PDFs

The primary purpose of cups-filters is to process files (often 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 which is probably on the system already.

The command to use has been given earlier. Please look again at both pdffonts outputs in that section and note that uni is no. This means there is no ToUnicode map in the PDF file and this in turn implies the text in the PDF is not searchable or capable of being copied. Should this does not matter to you you have a decent method to produce a PDF from a text file.

If it does matter there is

/usr/lib/cups/filter/texttopdf 1 1 1 1 1 input.txt > out.pdf

out.pdf is searchable and copiable. If you use pdffonts it can be seen there are no fonts embedded in it, so printing it would have to rely on whatever fonts the printer provides. It should be viewable on any machine because the font is courier.

Alternatively, the pdf produced by texttopdf can be post-processed with pdftocairo:

/usr/sbin/cupsfilter input.txt | pdftocairo -pdf - out.pdf

CHARSET=utf-8 /usr/lib/cups/filter/texttopdf 1 1 1 1 1 input.txt | pdftocairo -pdf - out.pdf

You might 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.

Credits

The texttopdf filter is based on CUPS' texttops filter and written by Tobias Hoffman <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.