GxEPD Adafruit library - where is print() or println() defined/implemented?

Hi all,

I've got a weird issue with some ASCII art not rendering correctly, despite my use of (several, different, specifically converted for this purpose) monospace typefaces.

My guess is that my issue consists of two parts:

  1. fontconverter doesn't convert all possible characters.
  2. when display.print()/display.println() encounters a character that doesn't exist in the given font, it simply skips that character rather than, say, printing a space, which would at least keep my art aligned visually if incorrect.

I'm tackling the second part first.

Therefore, does anyone know where, exactly, the Adafruit display print()/println() are defined or implemented in the GxEPD class hierarchy, please?


class Adafruit_GFX : public Print {
 using Print::write;
#if ARDUINO >= 100
  virtual size_t write(uint8_t);
  virtual void write(uint8_t);
    @brief  Print one byte/character of data, used to support print()
    @param  c  The 8-bit ascii character to write
size_t Adafruit_GFX::write(uint8_t c) {
  if (!gfxFont) { // 'Classic' built-in font

    if (c == '\n') {              // Newline?
      cursor_x = 0;               // Reset x to zero,
      cursor_y += textsize_y * 8; // advance y one line
    } else if (c != '\r') {       // Ignore carriage returns
      if (wrap && ((cursor_x + textsize_x * 6) > _width)) { // Off right?
        cursor_x = 0;                                       // Reset x to zero,
        cursor_y += textsize_y * 8; // advance y one line
      drawChar(cursor_x, cursor_y, c, textcolor, textbgcolor, textsize_x,
      cursor_x += textsize_x * 6; // Advance x one char

  } else { // Custom font

    if (c == '\n') {
      cursor_x = 0;
      cursor_y +=
          (int16_t)textsize_y * (uint8_t)pgm_read_byte(&gfxFont->yAdvance);
    } else if (c != '\r') {
      uint8_t first = pgm_read_byte(&gfxFont->first);
      if ((c >= first) && (c <= (uint8_t)pgm_read_byte(&gfxFont->last))) {
        GFXglyph *glyph = pgm_read_glyph_ptr(gfxFont, c - first);
        uint8_t w = pgm_read_byte(&glyph->width),
                h = pgm_read_byte(&glyph->height);
        if ((w > 0) && (h > 0)) { // Is there an associated bitmap?
          int16_t xo = (int8_t)pgm_read_byte(&glyph->xOffset); // sic
          if (wrap && ((cursor_x + textsize_x * (xo + w)) > _width)) {
            cursor_x = 0;
            cursor_y += (int16_t)textsize_y *
          drawChar(cursor_x, cursor_y, c, textcolor, textbgcolor, textsize_x,
        cursor_x +=
            (uint8_t)pgm_read_byte(&glyph->xAdvance) * (int16_t)textsize_x;
  return 1;

Thanks! Couldn't find it to save my life.

So it does look like missing glyphs are simply skipped, at least from my in-browser read of that code.

I'm debating changing that so that it "prints" a space instead of skipping. I'm also considering swapping to this fork GitHub - joeycastillo/Adafruit-GFX-Library: Multilingual fork of the Adafruit GFX graphics core library, this is the 'core' class that all our other graphics libraries derive from of the GFX library, which supports Unicode. (I'm not printing 16-bit Unicode, but it appears some of my characters are definitely ANSI/UTF-8 vs ASCII.)

Many TFT, OLED, EPD, ... hardware libraries inherit from Adafruit_GFX. They just draw the pixels.

You can override the Adafruit_GFX font handling in the EPD hardware library if you want.
Or edit Adafruit_GFX. In which case all your OLED, TFT, ... applications will behave differently.

Personally I like the U8g2_for_Adafruit_GFX library support. e.g. Chinese, Arabic, Unicode, ...




Oh wow! That library works /much/ better than anything else I was considering! It's beautiful!

Thank you so much for pointing me towards it!