Alan Coopersmith
(The introductory text of this chapter was adapted from the introduction of http://www.x.org/releases/X11R7.7/doc/xorg-docs/fonts/fonts.html)
As described in the chapter "The X Client Ecosystem", X has two font systems, the original core X11 fonts system, and the newer Xft fonts system.
The core X11 fonts system is directly derived from the fonts system included with X11R1 in 1987, which could only use monochrome bitmap fonts. Over the years, it has been more or less happily coerced into dealing with scalable fonts and rotated glyphs.
Xft was designed from the start to provide good support for scalable fonts, and to do so efficiently. Unlike the core fonts system, it supports features such as anti-aliasing and sub-pixel rasterisation. Perhaps more importantly, it gives applications full control over the way glyphs are rendered, making fine typesetting and WYSIWIG display possible. Finally, it allows applications to use fonts that are not installed system-wide for displaying documents with embedded fonts.
Xft is not compatible with the core fonts system: usage of Xft requires fairly extensive changes to toolkits and in some cases, applications. While X.Org continues to maintain the core fonts system, client software authors are encouraged to switch to Xft as soon as possible.
More information about using and configuring the X font systems is in http://www.x.org/releases/X11R7.7/doc/xorg-docs/fonts/fonts.html. That document also includes background material on computer fonts in general and pointers to other reference sites, and reading those portions of it first may be helpful in understanding the following sections.
In the original X11 font mechanism, an X client which wants to render some text in the Times New Roman font at a size of 12 points would first call XLoadFont() to open the font using the XLFD font name "-adobe-times-medium-r-normal--12-120-75-75-p-64-iso8859-1". The server opens that font (using routines in libXfont) and returns an XID associated with the open font, which the application then stores in the relevant GC's for later drawing operations. If that font is not found, the client can request a list of available fonts with XListFonts() - since XLFD's report a separate font name for every point size, style variant (bold, italic, roman, condensed, etc.), and supported encoding (iso8859-* for older text encodings, iso10646-1 for Unicode), most X servers will return a list that is thousands of font entries long, which can take a long time to send over a low bandwidth remote connection.
Before drawing text, many clients will first need to determine how big the string will be when drawn (for instance, to size a button or doing line wrapping of a text area). To do this, the client calls XTextExtents() with the string and font information, and the X server lays out the text in simple side-by-side order and returns the resulting bounding box and size information. If another layout is needed, such as complex layouts for languages such as Thai or Arabic, then the client has to do the layout itself. For fitting text into an area, this may involve many round trips trying different subsets of the string, adding latency to text drawing operations.
Actually drawing the text is done via XDrawString() or XDrawText() calls, which redo the side-by-side layout again. Each XDrawString() call can draw only a single horizontal line of text, though characters along that baseline may be individually rotated. Text is drawn monochrome, with no antialiasing, using the foreground and background colors and font choice from the GC passed to the call. Each call can only draw characters in a single font, with text from a single encoding, so mixing English text in iso8859-1 with Chinese characters in big5-1 requires multiple calls. XDrawText() allows passing multiple strings, each with a different font property set, in a single call.
The calls taking text strings each come in multiple variants, depending on how the text string is encoded, for instance, for XDrawString() there is actually:
XDrawString | Single byte text |
---|---|
XDrawString16 | Double byte text |
XmbDrawString | Multibyte text |
XwcDrawString | Wide character text |
Xutf8DrawString | UTF-8 multibyte text |
If you don't know what all those different text encoding types are, you can learn more about the variety of ways to encode text in:
Fonts & Encodings: From Advanced Typography to Unicode and Everything in Between by Yannis Haralambous Publisher: O'Reilly Media ISBN 10: 0-596-10242-9
A new font system was designed and implemented in the early 2000's, which sits alongside the legacy core font system, allowing old clients and new clients to run together. The new font system moved most of the work to the client side, reducing the number of round trips and lowering the latency required to draw fonts. It also added better support for complex text layouts, took advantage of the alpha blending support in the Render extension to provide anti-aliasing and LCD optimization for text rendering, and allowed clients to use fonts that were available in a document or with an application, without requiring them to be first installed in the X server or having to use the X Font Service (xfs) to provide remote access to them.
The API provided by X.Org for this font system is libXft, but typically it sits in the middle of a stack of text handling & font rendering technologies. Clients use the text interfaces provided by their toolkits, or a general high level rendering API such as Cairo. Those use the Pango or Qt layout engines, possibly with the HarfBuzz engine, to determine how to place glyphs next to each other to form words, and if necessary, reshape them to fit their context. Those API's in turn use the FontConfig library to find available fonts for each character set or glyph required, and the FreeType library to rasterize images from the fonts in various formats, such as OpenType, TrueType, PCF, or Type1. The libXft library then sends the imaged text to the X server, using the Render extension glyph cache to avoid resending common characters with uniform appearances, and the render extension composites the text with the underlying image data to accomplish antialiasing effects via blending with the alpha channels of the edge pixels.
This system allows clients to locally compute layouts, without round trips to the server; to draw text along any base of their choosing, not just a horizontal baseline; and to allow plugging in support for all sorts of different text handling models in the clients, depending on their needs, and without having to modify the X server or running the code in the potentially privileged X server process. FontConfig provides a more usable and human readable font naming scheme, with the above mentioned long XLFD name for 12 point Times New Roman instead being simply "Times New Roman-12".
The new font rendering model is widely adopted in modern applications and toolkits such as Gtk+ and Qt, while the original X11 core font subsystem is maintained for backwards compatibility with legacy X11 applications that have not yet updated.