showtext: Using System Fonts in R Graphics

This article introduces the showtext package that makes it easy to use system fonts in R graphics. Unlike other methods to embed fonts into graphics, showtext converts text into raster images or polygons, and then adds them to the plot canvas. This method produces platform-independent image files that do not rely on the fonts that create them. It supports a large number of font formats and R graphics devices, and meanwhile provides convenient features such as using web fonts and integrating with knitr. This article provides an elaborate introduction to the showtext package, including its design, usage, and examples.


Introduction
Using fonts in R graphics is neither a new topic nor a difficult task, if only the standard font families such as "sans", "serif" and "mono" are needed. However, problems occur when one wants to select fonts that are installed in the system but not among the standard families inside R, especially for the PDF graphics device. With the evolution of R graphics device as well as related extension packages, there are more and more solutions emerging to solve the font problem. The R News article Murrell and Ripley (2006) systematically describes the working mechanism of PostScript and PDF devices to handle nonstandard fonts, and more recently, the blog post by Winston Chang 1 serves as an tutorial for the extrafont package (Chang, 2014) which makes it easy to use TrueType fonts in PostScript, PDF and Windows bitmap devices.
With the same target, this article introduces the showtext package (Qiu, 2015a) that provides an alternative way to use fonts in R graphics. It has good support for various font formats and most graphics devices in R, and meanwhile provides some extra features such as loading web fonts and integration with knitr (Xie, 2013(Xie, , 2014a. All efforts devoted to the showtext package are trying to seek an easy and elegant way to make use of different fonts in R graphics.
In the remaining part, this article will first review some existing methods of font selection in R, and then give an introduction to the showtext package, including its design, usage, examples and a number of suggestions for use.

Built-in graphics devices in R
It is possible to let R's built-in graphics devices (e.g., PNG and PDF) to use installed fonts in the system. However, the implementation is quite configuration dependent. If Cairo graphics 2 support has been compiled in R such that png(type = "cairo") and cairo_pdf() are available, then it is quite straightforward to use system fonts in the plots. One only needs to specify the family name of font as is used by the system. (Figure 1) + txt2 <-annotate("text", 1, 1, label = "A sample of\nDejaVu Serif Italic", + family = "DejaVu Serif", fontface = "italic", size = 15) + print(bg + txt2) + dev.off() + } A sample of DejaVu Serif Italic However, when Cairo graphics is not available, it will require more effort to customize the font. For PNG graphs, the user needs to first register a font family name in R which is mapped to a font that is installed in the system, and then specify the font family name in plotting functions. Below is an example to show this procedure on Windows. Notice that we use the function windowsFonts() to register font and create name mapping. In other operating systems, there are analogous functions such as X11Fonts() and quartzFonts() to do the similar job.
For PDF graphs, the setup is more complicated. The first step is similar: one should call pdfFonts() to register new family names in R, and then use them in the plot. However, the obstacle here is that pdfFonts() requires the Adobe Font Metrics files (.afm), which may be unavailable for users. On the contrary, TrueType fonts (.ttf) and OpenType fonts (mostly .otf) are most commonly used, but unfortunately, these font formats are not directly supported by pdfFonts(). Additionally, to make the plot have consistent appearance across different PDF viewers, it is usually suggested to embed the font within the file by calling the function embedFonts(), which further invokes an external software Ghostscript 3 . For the details, interested readers are referred to the R News article Murrell and Ripley (2006). Due to this complexity, when creating PDF graphs users are most likely to only select the built-in PDF font families, which can be queried by the command names(pdfFonts()).

A sample of Constantia
A sample of Lucida Console The extrafont package extrafont is an R package mainly used to simplify the use of system fonts in PDF and PostScript graphics. It is able to extract metric files (.afm) from TrueType fonts (.ttf) so that the R PDF device can utilize that information to place text in graphics. This procedure is accomplished by the Rttf2pt1 package (Chang, 2015) that extrafont depends on. Also, for the same reason previously described, extrafont provides the function embed_fonts() to call Ghostscript to embed fonts in PDF files. extrafont requires a first-time configuration, during which it will scan for TrueType fonts installed in the system and generate corresponding metric files along with other necessary configuration files. Afterwards, one needs to call loadfonts() to register the newly created metric fonts in R. These two steps only need to be done once and are not necessary in a new R session.

The new approach: showtext
The previous section describes a number of ways to use system fonts in R graphics. While they could be helpful in many situations when dealing with fonts in R, there is still room for seeking more elegant ways to achieve that target, among which the showtext package is one trying to meet such a goal. The following are a number of highlighted features of showtext: 1. Easy installation. showtext only requires the lightweight FreeType library 5 for installation, and works without dependence on external software such as Ghostscript. This would be helpful when other solutions are not possible, e.g., when the Cairo library is unavailable in the system.

Support for various font formats.
A certain type of font is supported as long as the back-end FreeType library can read it, including but not limited to TrueType fonts, OpenType fonts, Type 1 fonts, etc.
3. Support for various R graphics devices. Technically showtext can work on almost any graphics device, regardless of if it is in PNG, PDF, SVG or JPEG format.
4. The output graph produced by showtext has a platform-independent appearance . There is no need to embed fonts into the graph, and viewers can read the text without installing the fonts that actually produced them.
5. It also features functions to automatically search and download many beautiful, accessible and open source fonts on the web, and users can use these fonts without installing them to the operating system, which means that the system level font library can be kept intact and clean.
The basic idea behind showtext is quite simple: it converts text into raster images (for bitmap and on-screen devices) or polygons (for vector graphics), and then put them in the graphics. This design comes from the fact that handling text is a very complicated task for graphics devices, but polygons and raster images are lower-level operations that are easier to deal with. Therefore, as long as a device understands how to draw polygons or overlay bitmap on its canvas, it will also be able to show text with the help of this package.
More specifically, the showtext package develops a general framework to render text in R graphics. First, it overrides the functions contained in the graphics device that are responsible for drawing text, so that showtext will take over the text rendering procedure. Then, it uses the FreeType library to read the font file and analyze the character string that is going to be displayed in the graph. Finally, the text is transformed into basic graphical components (raster images or polygons) that can be easily rendered by the device. As a result, the created graph does not rely on the original font file, thus being platform-independent.
This procedure can be better explained by the diagram in Figure 5.

Usage of showtext
The usage of showtext is easy and intuitive, consisting of two major steps: registering system fonts into R, and enabling showtext when executing plotting commands. As an additional feature, its integration with knitr is also introduced in this section.

Registering fonts
The purpose of this step is to create a mapping between the font family name used by R and the path of the corresponding font file, so that every time the graphics device requests a font with a given name, showtext can locate and open that font file. The actual work of registering fonts is done by the sysfonts package (Qiu, 2015b), on which showtext depends. sysfonts provides the function font.add() to register font families for showtext, with six arguments in total, of which the first two are mandatory. The first parameter, family, is the family name that the user wants to use in the plotting functions. The second one, regular, should give the path to the font file for a regular font face. Other parameters, such as bold and italic, are similar to regular, but pointing to the files with corresponding font faces. If any of the extra font face parameter is set to NULL, the font file for regular font face will be used.
Below is an example to download and register the xkcd 6 font for showtext.
For most operating systems, fonts are usually installed in some standard locations. To add fonts located in these directories, users can provide the filename rather than the absolute path to save some typing. For example on Windows, sysfonts knows about the standard font directory, so we can use the following code to register the Consolas families to showtext: > if(.Platform$OS.type == "windows") { + font.add("consolas", regular = "consola.ttf", bold = "consolab.ttf", + italic = "consolai.ttf", bolditalic = "consolaz.ttf") + font.families() + } [1] "sans" "serif" "mono" "wqy-microhei" [5] "myxkcd" "consolas" Users can view or set such search paths through function font.paths(), and list available font files in those paths by calling font.files(). While it may take some efforts to figure out the filename of a font with a given family name (and perhaps also font face), the naming convention of font files is usually intuitive and fixed. Also, some font file viewers can help mapping the font name to its real file name in the system.
To make the font adding process easier, sysfonts also makes use of the Google Fonts project 7 to simplify the process of downloading and registering fonts available on the web. Google Fonts hosts more than 600 open source fonts, and is still enriching its collection. Function font.families.google() lists the presently accessible fonts in the repository, and font.add.google() could search for a specific font family, download its font files for all possible faces, and add them to showtext. These two functions require the RCurl (Temple Lang, 2015) and jsonlite (Ooms, 2014) packages. The following code demonstrates this process.

Enabling showtext in plots
After registering the fonts, using them in plotting functions will be straightforward. The simplest way to enable showtext in R graphs is to call the showtext.auto() function, after which users are allowed to use the font families that are listed in font.families() to draw text. When it is no longer needed, users may call showtext.auto(FALSE) to turn showtext off. Figure 6 is an example to demonstrate this usage with ggplot2 (Wickham 2009; credit goes to the answer in Stackoverflow 8 for inserting an image in ggplot2): In this example, "wqy-microhei" is the name for the WenQuanYi Micro Hei 9 font that will be automatically loaded by showtext. WenQuanYi Micro Hei contains a large number of CJK (Chinese, Japanese and Korean) characters, so combined with showtext it can be useful to show text in those languages.
Note that when working with bitmap image formats (e.g. PNG, JPEG, TIFF), users should be careful about the resolution of the image. Since showtext is unable to query the DPI that is used by the graphics device, users should set it manually by the command showtext.opts(dpi = ...).
While showtext.auto() should be enough for most cases in using showtext, users actually have more freedom to control which part of the graph should be rendered by showtext and which not. Generally speaking, users could enclose code that wants to use showtext by a pair of function calls: showtext.begin() and showtext.end(). The code outside of these parts will still use the standard way to draw text. Figure 7 is an example to show this.

Integration with knitr
knitr is an R package and engine to generate dynamic documents with R. It is similar to the built-in Sweave engine inside R, but brings in many extensions and enhancements. Starting from version 1.7, knitr began to support showtext through the option fig.showtext. Code chunks with this option being TRUE will automatically invoke the showtext.begin() function, so there is no need to manually call it from the user. Here is a minimal example of an Rmd file that uses showtext.
We first do some setup work...

Limitations and solutions
The goal of showtext is to provide an elegant way to allow R to use system fonts in graphics. While it should be useful in most situations, there are a few limitations that need to be taken care of. This section lists these limitations of showtext, as well as some hints about how to use it in the best way.
First, showtext looks for fonts according to their filenames rather than the usual "font names" in the system. This design is intentional since font names can be ambiguous. For example, the same font can have multiple names given by different font management software. In contrast, the font file is the entity that actually contains the glyphs of a specific font, hence it helps to avoid such confusion. While this setting may cause some problems for users who are searching for the filename for the first time, it should be quite convenient afterwards, and one possible solution is to use the fonts in Google Fonts through the function font.add.google(), which maintains a standard and stable interface to access fonts.
Second, for vector graphics such as PDF and SVG, since text will be converted into polygons, it is no longer real text that can be searched in a PDF or SVG viewer. Also, the size of the PDF or SVG file created by showtext is usually larger than the one produced in the standard way. For users concerned by these issues, it is advisable touse cairo_pdf() or Cairo to generate PDF graphics, and to use RSvgDevice (Luciani et al., 2014) for SVG output.
In addition, at the time of writing showtext is not working well with the plot window provided by the RStudio IDE 10 . The simple solution is to manually open a graphics device using functions such as windows() and x11(), and then draw plots inside this window, rather than the built-in one offered by RStudio IDE.
Finally, in terms of the overall design, showtext is in some sense intrusive, since when user calls showtext.begin(), it temporarily replaces the device functions by its own ones, and later restores them after showtext.end() is called. An alternative and probably more elegant way to address the font problem is to develop new graphics devices that are based on showtext, so that they can make use of the text handling functionality contained in showtext. This possibility is left to future developers of graphics devices.

Summary
This article introduces the showtext package, which helps to use various types of fonts in R graphics, with both highlighted features and its limitations. We have also discussed a number of alternative ways in R to create graphs using non-standard fonts. While there is hardly a universally best way to use fonts in R, some situations were described in which a certain approach is most appropriate.
• The built-in devices in R without Cairo support have the least dependency on external libraries and software. More effort needs to be taken in this situation compared with others, but this may be the only possible solution, especially when R is compiled in a minimal environment.
• When Cairo graphics is compiled in R, devices such as png(type = "cairo") and cairo_pdf() allow users to select fonts by their family names. This should be the easiest way to use fonts in R graphs without extension packages.
• The Cairo package has similar functionality to png(type = "cairo") and cairo_pdf(), and additionally provides a global font selector, which is useful when choosing a default font for all Cairo devices.
• The extrafont package provides a complete solution for pdf() and postscript() devices with TrueType fonts, as well as support for Windows bitmap output. It introduces an easy way to import system fonts into R, so that users only need to make configuration changes once.
• showtext supports various font formats and most graphics devices. It also offers some convenient features like using web fonts obtained from Google Fonts, and integration with the knitr package. Some suggestions are given in Section "Limitations and solutions" in order to use it in the best way.