Xft support

What is XFT

The Xft library provides support for antialiased TrueType fonts, full Unicode, and an un-brain-damaged font selection mechanism for X11.

It relies on fontconfig [L1 ], FreeType [L2 ], and the X Render extension (although it will still work if XRender is not available on the server). Xft 2.0 is included in most recent Linux distributions (circa May 2003). Mozilla, Qt, and GTk have all been updated to use Xft.

How to enable or disable XFT

The Xft renderer was made the default (where Tk's configure script can work out how to get the required pieces) for 8.5, but you can always force it to be the reverse using --disable-xft if you prefer the old way of doing it or require access to the old list of fonts. (The last point is because Xft has a fundamentally different way of dealing with fonts than Xservers provide; this is completely outside of Tk's control, and it just reports what it is told by the underlying APIs.)

To check for Xft support inside a Tcl/Tk script, use:

   if {[catch {::tk::pkgconfig get fontsystem} xft]} {set xft no-xft}

As of tk 8.5, you either have Xft and not being able to use old list of fonts, or not use Xft at all. There is no option to allow both new font and old font.

how to switch between bitmap font and anti-aliased font

Although Xft handles both type of fonts, on modern xorg distributions usually bitmap font is turned off in Xft, thus to use bitmap font for tk 8.5 and above, either to compile a version without xft enabled, or change the fontconfig configuration (for example, instruction on Ubuntu Linux )

In debian squeeze it's much the same, with a tclkit 8.5 that is Xft enabled, you can still get 'old' unix fixed bitmap fonts like so:

  1. copy /etc/fonts/conf.avail/70-force-bitmaps.conf to ~/.fonts.conf and if you already have a ~/.fonts.conf then merge
  2. download miscfixed.zip and unzip in ~/.fonts
  3. reload the font list: fc-cache -f -v

now in Tk you can set a font to {miscfixed 8} and it works.


Discussion

KPV I for one don't particularly like antialiased fonts--I find them fuzzy and hard to read. Joel on Software essay Three Wrong Ideas From Computer Science [L3 ] talks about the fallacy of antialiased fonts.

JE Note that Joel constructed the "evidence" that antialiased fonts look bad by taking a screenshot of text in a bitmapped font and running it through Corel PHOTO-PAINT. This is like using Turner's colorized version of The Maltese Falcon to demonstrate that black and white movies are superior. If the antialiasing is done by the font rasterizer (where it's supposed to be done), the results are much better.

IDG I don't like them either. But then, I don't like syntax-colouring editors, so I'm clearly a weirdo!

DKF: I think he's not quite on the ball over AA fonts. More exactly, non-AA fonts are great if you require a font of exactly the size they provide (often the case for GUIs where font sizes can be controlled fairly well) but are awful if you're after some other size of font and the system has to fall back on its own rasterizer. (Previewing printable documents is one of the cases when you'll probably hit this problem.)

JH Some systems provide controllable lower boundaries for the use of AA fonts, which is the best solution. Small text is crisp while larger text gets AAed. OS X provides this for sure, but perhaps there is a way to allow better control for this on the unix side in Tk?

AKA: You guys are so totally wrong it hurts. Any screen design that uses pixels as a design element is flawed. Pixels are artefacts. Sane screen should try to hide the fact that (todays) screens are pixelized. For paper output, this happened when 300 dpi printers got affordable, ca. 1988. With LCD screens, we're at 150 dpi now and should really forget about pixels RSN.

DKF: FWIW, I'm happy to let the system pick whether to AA a font or not. With higher res screens of at least 24-bits deep, it's no longer a major issue.

JAC: Re: "controllable lower boundaries". Xft takes care of deciding whether or not to AA a font. This can be controlled in the fonts.conf which is found in /etc/fonts/fonts.conf or ~/.fonts.conf on my Debian system.

AFS: people, I can commiserate with you if you don't like AA fonts, but at least we should have the choice. I can assure you that for me it's a real problem to work with tcltk text processing applications (for the rest I don't care).

Jasp Blurry AA is only a problem if you are using a font without good hinting instructions, otherwise, it's no doubt a lot better than un-AA, IMHO. Take this screenshot for example: http://www.lostagain.org/images/offworld/aa-firefox.png (16-bit colour, Ubuntu Dapper). The window titlebar font is Trebuchet MS, interface is Segoe UI, webpage is Bitstream Vera Sans with font size turned right down. Notice the active tab is bold and also blurry?, that's because there isn't a bold version of Segoe available, so the font renderer has generated the bolded effect by horizontally resizing the original, losing it's sharpness. Almost all fonts suitable for interface use come with a bold version, so that usually doesn't happen (as you can see in the titlebar). Also notice that the AA Bitstream Vera still looks good when small, especially the italic text, which while is a bit blurryish, I prefer over blockly un-AA italic.

So anyway, I think it's about time AA support on X has been added to Tk, since the current un-AA rendering on X doesn't even appear to look at hinting instructions, and the result is messy blockly text, on 99% of fonts. (Tk just seems to be playing a game of "catch-up to the other toolkits" these days to me).

LV 2007 June 19: With regards to playing catch-up. What it seems to me to be happening is that Tk has, over the years, been updated by people who have a particular interest or need in something. And that seems to continue to be the method of progress. If the people who were interested in AA fonts had jumped in and started coding, Tk would have had them earlier. The same goes for theming and other Tk features. Once someone wants them, and steps up to the plate and starts working on the features, they come along relatively quickly.


TJE: Who can fix this in the configure script? The current source trees (as of 26 Sep 2005) don't 'configure' properly with --enable-xft, at least on Redhat Enterprise. The Xft library is part of the standard installation, and there's no 'xft-config' executable to be found. I managed to get 8.5a3 to build by adding '-lfreetype -lXft' to the 'wish' link line, as well using the output of 'freetype-config' to add the freetype library to the compile line for tkUnixRFont.c (which must be substituted for tkUnixFont.c in the Makefile). Even if you're in the "I hate anti-aliased fonts" camp, this is still a desirable improvement, as it fixes the shape of the font as well, not just the jaggy edges. (Try comparing a 'T' in Courier at size 150, and you'll see what I mean.)

IDG: I had no trouble with --enable-xft on Suse 9.3, using a July 05 source distribution. You are certainly right about shape. Recent versions of X look worse than older ones, if you don't have xft enabled.

TJE: Hmm. I just configured/compiled with Xft on an Opteron running Redhat Enterprise without a single hitch, so I guess the problem is limited to my 32-bit Intel box's configuration. Odd.

DLR Make sure you have the development version of the libraries installed


The Details

EG What fonts are available? Both font systems can serve bitmap and scalable fonts.

The core font system finds its fonts by means of a font path, as listed in the Files section of the X configuration file (either XF86Config or xorg.conf). Such font path can be modified at run time using the command 'xset fp+ /some/dir/with/fonts'. In order to find and use the fonts, such dir must include at least a cache file named 'fonts.dir'. If the dir contains scalable fonts (TTF or Type1), it must also contain the 'fonts.scale' file. Both files can be (re)created using the command line 'mkfontscale && mkfontdir' in the dir containing the fonts.

Xft font system uses the fontconfig library to search and find its fonts. The configuration file is named fonts.conf, usually located in '/etc/fonts/fonts.conf' . This is an xml file in which the directories to be searched for fonts are listed inside <dir> and </dir> tags. It's worth noting that such dirs will be searched recursively. Finally, to make the fonts available you need to create a cache file(s) using the command 'fc-cache -fv'.

Resuming, these are the steps to add fonts to your Tk app on X11 or make your fonts available through both font systems

X Core Fonts (Tk 8.4 or Tk 8.5+ configured with '--disable-xft'):

  • Create the dir which contains the fonts
  • Copy the fonts there and run 'mkfontscale && mkfontdir'
  • Add the dir to the font path, either editing the X configuration file or, as user, using 'xset fp+ /path/to/dir'
  • In case you have used the xset way, force the server to reload its font path with 'xset fp rehash'

Xft/fontconfig (Tk 8.5+ default build):

  • Create the dir which contains the fonts
  • Copy the fonts there and run 'mkfontscale && mkfontdir'
  • Add the dir to the fontconfig font path, editing either the system wide configuration ('/etc/fonts/fonts.conf') or the user defined one in ~/.fonts.conf
  • Rebuild fontconfig cache with 'fc-cache -fv'

There are a lot of fine points in font handling on X11. One of these is that, while Xft can serve bitmap fonts, they are not scaled, so setting a font like 'helvetica 72 roman' will not produce a font 1 inch tall as you would expect, but probably the bigger helvetica font you have installed.

Other point is in the names. While Tk guarantee on all platforms that Helvetica, Times and Courier are always available, the same "safe" font names in Xft are sans-serif, serif and monospace.

LV I have a case where an application is trying to use Helvetica on a Linux system. We've tried using the name helvetica and sans-serif but do not get Helvetica in either case. We are getting Luxi Sans, Nimbus Roman No9 L and Luxi Mono for the safe font names. When we use the original names of helvetica, times, and courier we get Nimbus Sans L, Nimbus Roman No9 L, and Courier. If anyone knows what extra steps we need to take to actually get helvetica, please add the information here.

EG You need to add the directory containing the fonts to the fontconfig configuration file, and then run (as root) 'fc-cache -fv' to rebuild the font cache. On my Slackware system these directories are '/usr/share/fonts/75dpi' and '/usr/share/fonts/100dpi' which contains a bunch of 'helv*.pcf.gz' font files.

DKF: You can probe what fonts are set up using the Unix command “fc-list”[L4 ], which is the (moral, not literal) equivalent of xlsfonts. For example, to check for Helvetica you might do this (including the colon as an argument on its own):

    fc-list : family | grep -i helvetica