Creating your own fonts for Adafruit TFT

Hi there, I needed a font creator and found this thread, I needed a few small fonts and the Adafruit TrueType converter was creating fonts with substandard quality, for small sizes the rendering of TrueType make use of interpolation and anti-aliasing, small fonts transformed to a monochromatic plane suffer from a large deformation.

Also I needed extra attributes on the fonts, like the ability to generate a border or blending with whatever was in the display, GFX fonts don't provide that.

I decided to create my own tool to create my extended fonts which also it creates Adafruit_GFX fonts, this is a graphical interface that is very easy to use.

I created an open source project on BitBucket and uploaded the source and binaries.

I provided two fonts "Dmd8x7Clock.xft, Dmd13x20Clock.xft" as example that I created to display the time from a clock so only numbers and few characters were included, but you can create any font you need.

https://bitbucket.org/castortiu/arduino-font-creator

Hi.

Just starting out with Arduino/fonts, and trying to figure out:

Does anyone have any suggestions for what to do if you just want to see a font from the generated .h file?
(Short of, obviously, writing a sketch that runs through a font on one's 0.96" OLED. Which would not be all that useful.)

All examples/editors seem to assume you have the file that generated the .h file.

(OK, answered my own question: In Excel fonts editor-converter for Adafruit, UTFT, Squix, ILI9341_t3, OLED_I2C - Exhibition / Gallery - Arduino Forum they give link to binFontsTool 0.2.6, which does everything I need.)

You can use WYSIWYG online font generators like this one for small OLEDs and this one for TFT displays.

I tryed Bodmer font generator (truetype2gfx), and when I in the program type in the danish special chars æøå, they was shown correct in the little window.
But there are no æøå in the charset when I show the whole charset om my tft-display.
No special chars is shown at all.
How can I expand the charset to the chars from $80 to $FF?

The FreeFonts that come with the Adafruit_GFX library only provide characters from 0x20 to 0x7E
Adafruit_GFX can print 0x20 - 0xFF but it is difficult to put the extended characters into an ascii string.
You need to use an escape sequence.

Many fonts contain characters from 0x80 to 0xFF. The Online Tools only generate the regular 0x20-0x7E ascii characters.

Note that the "system 5x7" font has a full range of characters but the 0x80-0xFF range is non-standard.

Websites and the Arduino IDE use UTF8 coding for strings. Adafruit_GFX will just show the raw chars that encode the UTF8.

Olikraus has a "U8g2_for_Adafruit_GFX.h" library that you can use with GFX-style libraries like MCUFRIEND_kbv. It can be installed via the IDE Library Manager
This supports UTF8 encoded strings. And supports Oliver's vast collection of Fonts.

David.

I already use 5x7 font, but when x4 they are not pretty, so I go to try to make my own charset with the fontgenerator from castortiu. It give a lot of work, but then I have all the chars I want!

It would bee nice if the program could import a charset of some kind, but I can't see how!

I can generate a full 256 character font if you want. Just say which one.

I am sure that there will be an online website that can produce the full-fat fonts. I can't remember.

If you write sketches that have a lot of special strings, it would be best to use an UTF8 compatible library like #24. It is easier to maintain human readable strings than to have escape sequences.

Note that most TFT libraries are GFX-style. So you can use Olikraus's fonts and library with Adafruit_ILI9341 or any other Adafruit code.

This means you can write Cyrillic, Greek, Arabic, ... strings with your TFT.

David.

I would like to get some charsets, but I don't know which for the moment.

I have tryed to use other charsets, but I can't get it to work.

I use this code:

#include <MCUFRIEND_kbv.h>
MCUFRIEND_kbv tft;
#include <Adafruit_GFX.h>

#include <u8g2_fonts.h>
#include <U8g2_for_Adafruit_GFX.h>
#include <gfxfont.h>
#include <Fonts/FreeSans9pt7b.h>
#include <Fonts/FreeMono9pt7b.h>  
#include <Fonts/FreeSerif10pt7b.h>
#include <Fonts/FreeMonoBoldOblique9pt7b.h>  
#include <FreeDefaultFonts.h> 
#include <Fonts/u8g2_fonts.h>
#include <Fonts2/Dmd13x20Clock.h>
#include <Fonts2/KG13x20_mono.h>

#define BLACK 0x0000
//-------------------------------------------------------------
void setup(void)
{ 
  Serial.begin(250000);
  Serial.println();  Serial.println("Programnavn: Menu_MCU1");  Serial.println();
  uint16_t ID = tft.readID();
  Serial.print("TFT ID = 0x");
  Serial.println(ID, HEX);
  if (ID == 0xD3D3) ID = 0x9486; // write-only shield
  tft.begin(ID);
  tft.setFont(&FreeSerif10pt7b);  //  OK
  tft.setFont(&FreeMono9pt7b);    //  OK
//  tft.setFont(&Dmd13x20Clock);    //  'Dmd13x20Clock' was not declared in this scope
//  tft.setFont(&u8g2_fonts);       //  'u8g2_fonts' was not declared in this scope
  asci(); //  Print Char-table
}
//-------------------------------------------------------------
//-------------------------------------------------------------
void loop(void){}
//-------------------------------------------------------------
/*
Danish font in standard charset
Æ: 146  \x092  æ: 145  \x091
Ø:      \x0    ø:      \
Å: 183  \x08F  å: 134  \x086
Degree: 248
 */
void asci()
{ 
  tft.setRotation(1);            //LANDSCAPE
  tft.fillScreen(BLACK);
  int y, x, c=0;
  tft.setCursor(30,16);
  tft.print("0 1 2 3 4 5 6 7 8 9 A B C D E F  ");
  for( y=0; y < 12; y++)
  {
    tft.setCursor(0, (y*18)+30); 
    if(y > 9) {tft.print(char(y+55));} else { tft.print(y);}
    for( x=0; x < 16; x++)
    {
      tft.setCursor(30+x*15, (y*18)+30); 
      if(c == 10) { tft.print(" ");} else { tft.print(char(c)); }
      c++;
    }
  }
}

The compiler say "'u8g2_fonts' was not declared in this scope", but it accept the link to the charset!

Is there a special method for installing extra charset?

The font KG13x20_mono.h is made with castortiu program, and only contain a few chars.

Here is an example that shows some UTF8 strings vs escapes

#include <MCUFRIEND_kbv.h>
MCUFRIEND_kbv tft;

#include <U8g2_for_Adafruit_GFX.h>
U8G2_FOR_ADAFRUIT_GFX u8g2_for_adafruit_gfx;

void setup()
{
    tft.begin(tft.readID());
    u8g2_for_adafruit_gfx.begin(tft);                 // connect u8g2 procedures to Adafruit GFX
}

void loop()
{
    tft.fillScreen(TFT_BLACK);
//    u8g2_for_adafruit_gfx.setFont(u8g2_font_unifont_t_extended);  // extended font
    u8g2_for_adafruit_gfx.setFont(u8g2_font_helvR14_tf);  // select u8g2 font from here: https://github.com/olikraus/u8g2/wiki/fntlistall
    u8g2_for_adafruit_gfx.setFontMode(1);                 // use u8g2 transparent mode (this is default)
    u8g2_for_adafruit_gfx.setFontDirection(0);            // left to right (this is default)
    u8g2_for_adafruit_gfx.setForegroundColor(TFT_WHITE);  // apply Adafruit GFX color
    u8g2_for_adafruit_gfx.setCursor(0, 20);               // start writing at this position
    u8g2_for_adafruit_gfx.print("Hello World");
    u8g2_for_adafruit_gfx.setCursor(0, 40);               // start writing at this position
    u8g2_for_adafruit_gfx.print("Umlaut ÄÖÜ");            // UTF-8 string with german umlaut chars
    u8g2_for_adafruit_gfx.setCursor(0, 60);
    u8g2_for_adafruit_gfx.print("<μȦǀʘ\xB5\xA3ʁμπ>");
    delay(2000);
}

And the attached ZIP has a sketch that shows:

  1. the full set of 5x7 characters
  2. a typical Free Font with 0x20-0xFF
  3. part of one of Oliver's Unifont sets

Note that you can still use the regular GFX text and graphics methods with the tft object.
And the extended methods with the u8g2_for_adafruit_gfx object.

David.

Font_full.zip (8 KB)

Thanks for the examples, I tryed them all.

But there are a problem using them with Adafruit_GFX_Button.
The charsets referancepoint is lowleft, and with the 'initButton' function the chars is written to high in the button. And the 'initButton' don't know the width af the new chars.
See the attached picture.

So I have to use the standard 5x7 charset or give the 'initButton' an empty string and then write the text in the button later.

I still don't understand why I got the errormessage 'u8g2_fonts' was not declared in this scope' in #27.

Well, the Adafruit_GFX_Button class is intended for the 5x7 font. The code is public. You can update it for other font formats.

I have no idea what all the gobbledygook means. Remember that the GFX "TextSize" is a global value. You need to reset it after you have drawn a Button. Or preferably before you draw your regular non-button text.

Yes, it would be wise for Adafruit_GFX_Button class to reset it automatically.

David.

The 'gobbledygook ' is because I has not changed the fontsize.
I will try to change in the Adafruit_GFX_Button class, but I am new to class.
May I rename the 'Adafruit_GFX_Button' in order to prevent confuse?

I suggest that you develop your App with the regular 5x7 font.
Or do you want Cyrillic labels on your buttons?

The 5x7 has several special characters. You can display them with escape sequences.

How did you get on with the full-fat Free Font or with Olikraus's U8g2 fonts?
#28 has a pasted example.
#28 has an attached example.

When your app is 100% working, attach it. Then I will show you how to write your own class or modify the Adafruit code.

David.

Hi David!
Does your 'mcufriend_kbv' library work with esp8266 (Nodemcu) or what should be added or modified? thank you

MCUFRIEND_kbv works with ESP32. There are not enough pins on a ESP8266 for a parallel 8080-8 interface.

Bodmer's TFT_eSPI library does most things that are possible with SPI displays.
And actually supports a few parallel displays with ESP32 too.

TFT_eSPI implements most Adafruit_GFX methods but independently. Not through inheritance. So Olikraus's U8G2_FOR_ADAFRUIT_GFX class will not be able to work with TFT_eSPI

But as a general rule, regular GFX sketches can be built with Adafruit_ILI9341, TFT_eSPI, MCUFRIEND_kbv, ...
You just change the include and the constructor(). Sometimes the begin() syntax.

David.

I can think of buying ESP32 to try out your library; What is the highest resolution your library supports?
What does it offer? I've never tried it.
I really like figures, (static or animated as gif). Text Scrolls (vertical or hor.), etc. Thanks

I support SSD1963 800x480.

Even if a "regular library" does not provide Hardware Scroll methods, you can extend the class by inheritance.

However, thing like readReg() or readGRAM() need hardware that you can read.
Most 16-bit shield hardware do not support any form of read.

David.

Hi David.
I have a sketch, where the menusystem work OK, but some computed values is not yet OK.
It use a lot of buttoms, whitch can bee reduced, it will be done later!
I will make some komment in the sketch before I attach it.

I asked about your experience with extended fonts and with the special characters in the System 5x7 font.

I have posted programs with multiple pages e.g. selected by buttons / menus.

Maintain separate button "lists" for each page.
Then you simply draw and respond to buttons on a specific page.

Look at the button examples. I pasted a phonecal_new sketch in #2608 of the main MCUFRIEND_kbv thread.

Note that Adafruit graphics, text, buttons, .... work with any Adafruit_GFX style libraries. They are not dependent on MCUFRIEND_kbv.

David.

button_multiple.ino (6.65 KB)

I has used extender font often and also use them in my project.

Maybe the best answer is to send you the program as it is for the moment.
I tryed you program buttom_multible, it compile and show two buttons and no else happen.

Menu_MCU1_GB.zip (11.7 KB)