Wandering Thoughts archives

2012-05-20

The XFT font naming issue

One of the subtle problems with XFT fonts is that they don't have canonical, broadly supported textual names. To explain this, I need to go back to old server side XLFD fonts to show what I mean and the difference between XLFD fonts and XFT fonts here.

Fundamentally XLFD fonts are specified by their name, right from the relatively low level library APIs on up. You get a handle to the font by asking for it by name, and the name you use is its standard canonical format XLFD name. This means that everything that deals with XLFD fonts fundamentally uses a standard textual identifier for them, and in turn this means that everything accepts the same name to specify a particular XLFD font.

(Now, there are aspects of this that are less than ideal. For instance, a program that starts with one font and wants to derive a bunch of closely related ones (eg the same font in different sizes or the same font in bold or italic) is going to be parsing the XLFD name for the font into its component parts, changing some of them, and then reconstituting this into new font names.)

XFT fonts do not work like this. While XFT fonts sort of have a standard format name due to FontConfig (cf the font names section), these names are not actually a fundamental part of how XFT fonts are used and specified; instead, XFT fonts are usually specified as a collection of attributes and properties. Your code does not ask for a font with the name 'Monospace-14', it asks for a font with family Monospace and point size 14 (and so on). How you go from a text name for a font to this collection of attributes is to a certain extent up to your program in a way that it was not for XLFD font names.

(This is of course convenient for programs that want to deal with a cluster of fonts; now they can just directly vary the attributes they care about, like the point size.)

What this has created is a situation where different programs can each have a different way of naming the same XFT font. Since it's to a large extent up to each program to turn a font name string into the collection of XFT font attributes that it will actually use with the API, each program can and often does do it differently. There's no guarantee that two different programs will accept the same XFT font name and there's no guarantee that a particular program will accept all of the theoretical features of XFT font name specifications that you'll find outlined in the Font Names section of the FontConfig user documentation. Programs are in fact free to be quite limited in what they accept (the practical minimum is family and point size, but even then the format can and does vary). You have to check the documentation for each program to see how it handles XFT font names, what format they're in, and what you can and can't put in a name. And the answers vary, a lot.

What this means pragmatically is that XFT fonts are more annoying to deal with than XLFD fonts if you're primarily specifying them by (text) name. In the XLFD era, you had a single name for a font and everything accepted it. With XFT fonts, you have multiple names for the same font and you have to work out how to format the name of the font so that today's program will accept it (if it will at all; if you need to specify advanced options, it may not). Also, some programs may require you to specify the font in multiple bits (they may have a separate argument or setting for the family and the font size, for example, instead of letting you put it in one name).

XFTNameProblem written at 00:38:49; Add Comment

2012-05-19

A semi-brief history and overview of X fonts and font rendering technology

Because I've just been mucking around in this swamp, I feel like writing all of this down.

In the very beginning, X had some simple bitmap fonts in the server with equally simple names that were basically labels; ie, the X server attached no particular meaning to the font names, which were created by people mostly to be short and sometimes to be vaguely meaningful. Some of these font names linger on in X today; the most well known one is fixed, the name for the default monospace font (and font size), but there are others like 6x10 and 6x13bold. The X clients just asked the server to display some text in the named font, and the server handled all of the rendering and drawing.

(Today these font names are implemented as aliases for other fonts.)

As the X server evolved, it grew more bitmap fonts. Fonts from different vendors, fonts in more sizes, proportional fonts as well as monospaced ones, fonts for different resolutions (75dpi versus 100dpi), fonts for different character set encodings, and so on. It was clear that ad-hoc font names weren't going to scale because no one was going to be able to keep fonts straight or find one. So the X people invented a naming convention for their fonts, the X logical font description (XLFD). In theory an XLFD name describes most of the important attributes of a font, things like the point and pixel size, the slant, the style, whether it's proportional or monospaced, and so on. Along with XLFD names and their defined structure, the X people introduced the idea of wildcard matches so that X programs could say 'I don't really care which vendor it comes from, I just want whatever 15 pixel monospaced font you have'.

(For backwards compatibility, the original simple X font names were defined to be acceptable XLFD font names (although you can't use wildcards with them).)

Initially XLFD fonts were still all bitmapped fonts, just better named and more numerous than before. However the X server soon got additional font rendering support that let it handle several scalable font formats of the time. Scalability was implemented in XLFD font names in a straightforward way; if the font name itself had zeros in various resolution related fields, you knew that the X server could and would render it at whatever pixel size you asked for.

At some point, people observed that the precious X server was spending a bunch of time and memory loading, parsing, rendering, and so on all of these fonts, even for fonts that weren't very actively used. So the X people decided to offload a lot of this work to a separate daemon, the X font server (xfs), although in the usual manner of X they left all of the direct server side font rendering code intact too. An X font server could (in theory) be isolated from the X server and if necessary restarted independently; all of the hairy and CPU consuming code for scalable font rendering could be parked in a process in it, and so on. The X font server could handle all font formats that the X server could, and thus could render all XLFD fonts for the server. Although the X server delegated actual font rendering to another process, X font handling was still done in the server; clients still just told the server 'draw text X in font Y'.

(Generally xfs could be pointed to exactly the same font directories as the X server had previously been using directly.)

The next evolutionary step in X font handling was to move it to the client side, which marked (and marks) a stark division in X font handling. This is XFT and 'XFT fonts'. XFT is to a significant degree glue; it uses FontConfig to translate from font names (and attributes) to actual concrete font data files, then FreeType to turn text into picture data and draws the picture data using various X bits.

Technically and theoretically XFT and its pieces still support old X bitmapped fonts. Practically they do not; XFT and XFT-using programs really expect fully scalable fonts, generally ones with a wide glyph selection, and have basically no patience or tolerance for bitmapped fonts that are available in only a few point sizes with only a few glyphs. With heroic work in FontConfig configuration files you can sort of get something limping along, but in practice moving to XFT fonts means no more bitmap fonts.

(Yes, I have tried this experiment. It's especially unsatisfactory for 'frankenfonts', ones where the real font is only available in a few pixel sizes and you were already filling in other pixel sizes with substitutes. The XLFD configuration system is much better for this.)

Generally, the system FontConfig configuration will look for fonts in all of the X server font directories with scalable fonts, or at least all of the directories that are considered to include 'good' fonts. This makes scalable XLFD fonts available to modern XFT-using clients, although under somewhat different names.

(TrueType fonts will generally render the same in XLFD and XFT form because the X server and the X font server long ago were set up to render them with FreeType. Any remaining differences in appearance are due to rendering decisions made differently between FontConfig and the X server environment. I'm not sure how older scalable font formats come out, and generally you don't want to use those fonts anyways.)

So today X has two separate font technologies: XLFD fonts and XFT fonts. XLFD fonts are configured through xset's font path directives (the modern coolness is catalogues) and perhaps your xfs configuration file (if xfs support is still working in your X server, which it probably isn't). XLFD fonts and font directories exist only on the X server machine (or perhaps the xfs machine) and properly set up font directories have fonts.dir, fonts.scale, and/or fonts.alias files that describe their contents. These are the only bitmap fonts still supported and XLFD bitmap fonts usually work well at small pixel sizes.

(This is especially true of monospaced bitmap fonts, many of which were extensively tuned for high readability and high density at relatively small pixel sizes.)

XFT fonts are configured through FontConfig. Magic happens, and it happens differently on different machines. On the good side, you can generally put new font files into $HOME/.fonts and they will automatically be recognized for you. FontConfig has various sorts of support for font aliases, but they hide out in magic places like the XML configuration files in /etc/fonts (if you want to see some of it, look for how many things in /etc/fonts/conf.d want to lay claim to be 'monospace', the default monospaced font). Most XFT fonts are TrueType fonts (at least the modern ones that you want to use) and do not work well at small pixel sizes.

XLFD font support is pervasive in old X programs but scattered and increasingly absent in modern ones. XFT support is the inverse; uncommon in old X programs and old Unixes (such as Solaris), but increasingly common in modern X programs (especially ones that are part of a pervasive environment like Gnome or KDE, where it is ubiquitous), on Linux, and at least partially on other Unix OSes such as FreeBSD. Some programs and frameworks make an effort to support both XLFD fonts and XFT fonts, but many are XFT-only.

(Today's expedition into this swamp was started by Tk 8.5, which can be compiled to support XLFD fonts or XFT fonts but not both at once. You can guess which option modern Linux distributions have picked.)

XFontTypes written at 03:27:39; Add Comment

By day for May 2012: 19 20; before May; after May.

Page tools: See As Normal.
Search:
Login: Password:
Atom Syndication: Recent Pages, Recent Comments.

This dinky wiki is brought to you by the Insane Hackers Guild, Python sub-branch.