More recent versions of the Adafruit GFX library offer the ability to use alternate fonts besides the one standard fixed-size and -spaced face thatâs built in. Several alternate fonts are included, plus thereâs the ability to add new ones.
The included fonts are derived from the GNU FreeFont project. There are three faces: âSerifâ (reminiscent of Times New Roman), âSansâ (reminiscent of Helvetica or Arial) and âMonoâ (reminiscent of Courier). Each is available in a few styles (bold, italic, etc.) and sizes. The included fonts are in a bitmap format, not scalable vectors, as it needs to work within the limitations of a small microcontroller.
Located inside the âFontsâ folder inside Adafruit_GFX, the included files (as of this writing) are:
FreeMono12pt7b.h FreeSansBoldOblique12pt7b.h FreeMono18pt7b.h FreeSansBoldOblique18pt7b.h FreeMono24pt7b.h FreeSansBoldOblique24pt7b.h FreeMono9pt7b.h FreeSansBoldOblique9pt7b.h FreeMonoBold12pt7b.h FreeSansOblique12pt7b.h FreeMonoBold18pt7b.h FreeSansOblique18pt7b.h FreeMonoBold24pt7b.h FreeSansOblique24pt7b.h FreeMonoBold9pt7b.h FreeSansOblique9pt7b.h FreeMonoBoldOblique12pt7b.h FreeSerif12pt7b.h FreeMonoBoldOblique18pt7b.h FreeSerif18pt7b.h FreeMonoBoldOblique24pt7b.h FreeSerif24pt7b.h FreeMonoBoldOblique9pt7b.h FreeSerif9pt7b.h FreeMonoOblique12pt7b.h FreeSerifBold12pt7b.h FreeMonoOblique18pt7b.h FreeSerifBold18pt7b.h FreeMonoOblique24pt7b.h FreeSerifBold24pt7b.h FreeMonoOblique9pt7b.h FreeSerifBold9pt7b.h FreeSans12pt7b.h FreeSerifBoldItalic12pt7b.h FreeSans18pt7b.h FreeSerifBoldItalic18pt7b.h FreeSans24pt7b.h FreeSerifBoldItalic24pt7b.h FreeSans9pt7b.h FreeSerifBoldItalic9pt7b.h FreeSansBold12pt7b.h FreeSerifItalic12pt7b.h FreeSansBold18pt7b.h FreeSerifItalic18pt7b.h FreeSansBold24pt7b.h FreeSerifItalic24pt7b.h FreeSansBold9pt7b.h FreeSerifItalic9pt7b.h
Each filename starts with the face name (âFreeMonoâ, âFreeSerifâ, etc.) followed by the style (âBoldâ, âObliqueâ, none, etc.), font size in points (currently 9, 12, 18 and 24 point sizes are provided) and â7bâ to indicate that these contain 7-bit characters (ASCII codes â â through â~â); 8-bit fonts (supporting symbols and/or international characters) are not yet provided but may come later.
Using GFX Fonts in Arduino Sketches
After #including the Adafruit_GFX and display-specific libraries, include the font file(s) you plan to use in your sketch. For example:
#include <Adafruit_GFX.h> // Core graphics library #include <Adafruit_TFTLCD.h> // Hardware-specific library #include <Fonts/FreeMonoBoldOblique12pt7b.h> #include <Fonts/FreeSerif9pt7b.h>
Each font takes up a bit of program space; larger fonts typically require more room. This is a finite resource (about 32K max on an Arduino Uno for font data and all of your sketch code), so choose carefully. Too big and the code will refuse to compile (or in some edge cases, may compile but then wonât upload to the board). If this happens, use fewer or smaller fonts, or use the standard built-in font.
Inside these .h files are several data structures, including one main font structure which will usually have the same name as the font file (minus the .h). To select a font for subsequent graphics operations, use the setFont() function, passing the address of this structure, such as:
tft.setFont(&FreeMonoBoldOblique12pt7b);
Subsequent calls to tft.print() will now use this font. Most other attributes that previously worked with the built-in font (color, size, etc.) work similarly here.
To return to the standard fixed-size font, call setFont(), passing either NULL or no arguments:
tft.setFont();
You can see a complete example of custom fonts in action in the MagTag Quotes Example source code. Itâs really just a few extra lines compared to a ânormalâ GFX text program.
Some text attributes behave a little differently with these new fonts. Not wanting to break compatibility with existing code, the âclassicâ font continues to behave as before.
For example, whereas the cursor position when printing with the classic font identified the top-left corner of the character cell, with new fonts the cursor position indicates the baseline â the bottom-most row â of subsequent text. Characters may vary in size and width, and donât necessarily begin at the exact cursor column (as in below, this character starts one pixel left of the cursor, but others may be on or to the right of it).
When switching between built-in and custom fonts, the library will automatically shift the cursor position up or down 6 pixels as needed to continue along the same baseline.
One âgotchaâ to be aware of with new fonts: there is no âbackgroundâ color optionâŚyou can set this value but it will be ignored.
This is on purpose and by design.
The background color feature is sometimes used with the âclassicâ font to overwrite old screen contents with new data. This only works because those characters are a uniform size; that wonât work with proportionally-spaced fonts, where the bounds of a string can vary, and an indeterminate number of characters may overlap the same region.
To replace previously-drawn text when using a custom font, either:
- Use getTextBounds() to determine the smallest rectangle encompassing a string, erase the area using fillRect(), then draw new text:
int16_t x1, y1; uint16_t w, h; tft.getTextBounds(string, x, y, &x1, &y1, &w, &h);
getTextBounds expects a string, a starting cursor X&Y position (the current cursor position will not be altered), and addresses of two signed and two unsigned 16-bit integers. These last four values will then contain the upper-left corner and the width & height of the area covered by this text â these can then be passed directly as arguments to fillRect().
This will unfortunately âblinkâ the text when erasing and redrawing, but is unavoidable. The old scheme of drawing background pixels in the same pass only creates a new set of problems.
or:
- Create a GFXcanvas1 object (an offscreen bitmap) for a fixed-size area, draw custom text in there and copy to the screen using drawBitmap().
// In global declarations: GFXcanvas1 canvas(128, 32); // 128x32 pixel canvas // In code later: canvas.println("I like cake"); tft.drawBitmap(x, y, canvas.getBuffer(), 128, 32, foreground, background); // Copy to screen
This is illustrative of syntax, not a complete program â change x
, y
, foreground
and background
to the desired coordinates and color values suited to the display. Some displays also require an explicit display() or show() call to refresh the screen contents.
This will be flicker-free but requires more RAM (about 512 bytes for the 128x32 pixel canvas shown above), so itâs not always practical on AVR boards with only 2K. Arduino Mega or any 32-bit board should manage fine.
See the âMinimizing Redraw Flickerâ page for more info on using canvases.
Adding New Fonts
If you want to create new font sizes not included with the library, or adapt entirely new fonts, we have a command-line tool (in the âfontconvertâ folder) for this. It should work on many Linux- or UNIX-like systems (Raspberry Pi, Mac OS X, maybe Cygwin for Windows, among others).
Building this tool requires the gcc compiler and FreeType library. Most Linux distributions include both by default. For others, you may need to install developer tools and download and build FreeType from the source. Then edit the Makefile to match your setup before invoking âmakeâ.
fontconvert expects at least two arguments: a font filename (such as a scalable TrueType vector font) and a size, in points (72 points = 1 inch; the code presumes a screen resolution similar to the Adafruit 2.8" TFT displays). The output should be redirected to a .h fileâŚyou can call this whatever you like but I try to be somewhat descriptive:
./fontconvert myfont.ttf 12 > myfont12pt7b.h
The GNU FreeFont files are not included in the library repository but are easily downloaded. Or you can convert most any font you like.
The name assigned to the font structure within this file is based on the input filename and font size, not the output. This is why I recommend using descriptive filenames incorporating the font base name, size, and "7b". Then the .h filename and font structure name can match.
The resulting .h file can be copied to the Adafruit_GFX/Fonts folder, or you can import the file as a new tab in your Arduino sketch using the SketchâAdd File⌠command.
If in the Fonts folder, use this syntax when #including the file:
#include <Fonts/myfont12pt7b.h>
If a tab within your sketch, use this syntax:
#include "myfont12pt7b.h"
Text editor powered by tinymce.