15.picoでAdafruit_GFX fontデモ Arduino


15.picoでAdafruit_GFX fontデモ Arduino

前回、アルファベットで一番大きな font4 は固定幅でないので、数値により文末の文字位置が移動して使いづらいです。固定幅の英数フォントを探していました。今回は、Adafruit_GFXライブラリで使用されているフォントを画面表示します。このライブラリではGFX Free Fonts (GFXFF)と呼ばれています。

使用ハード

・pico
・モニタ : Pico-ResTouch-LCD-3.5 (480x320)

スケッチ例

Arduino-IDE > ファイル > スケッチ例 > (カスタムライブラリのスケッチ例) TFT_eSPI > 460x320 > Free_Font_Demo.ino
のスケッチを使用します。

注意

...\Arduino\libraries\TFT_eSPI\User_Setup.h

#define LOAD_GFXFF
が書かれていること。

スケッチの解説

固定幅のFreeMonoを中心に表示しました。

フリーフォントはベースラインを基準としてるので、1行改行後に表示させます。

FreeMono フォントにて print では、
tft.fillScreen(TFT_NAVY);
tft.setTextColor(TFT_YELLOW, TFT_BLACK);
tft.print("font");
としても、文字の地は濃紺のままです。printで指定してもテキストの地が描画されず、前の字が消えずに残ってしまいます。Adafruit_GFXライブラリとの互換性のためだそうです。1画面目

対策として、drawFloat や drawString を使用します。2と3画面目

tft.setTextPadding(width);
背景ブランキング/オーバーライトの幅を設定(px)

tft.drawFloat(floatNumber,小数点以下の桁数,x,y,font);
表示 setTextDatum,setTextPaddingも使用

フォントサイズ

前回で、H=10-65pxのフォント組合わせは、
H16 = font2 x size1 (比1)
H26 = font4 x size1 (比1.6)
H32 = font2 x size2 (比2)
H48 = font2 x size3 (比3)
H52 = font4 x size2 (比3.3)
H64 = font2 x size4 (比4)
です。

・LOAD_GLCD Font1.Adafruit8x6(中味7x5)ピクセル 1820byte
・LOAD_FONT2 H16ピクセル 3534btye 96文字
・LOAD_FONT4 H26ピクセル 5848byte 96文字
・LOAD_FONT6 H48ピクセル 2666byte "1234567890:-apm"
・LOAD_FONT7 7セグメントH48 2438byte "1234567890:-"
・LOAD_FONT8 H75ピクセル 3256byte "1234567890:-"

Fontホルダ

...\libraries\TFT_eSPI\Fonts
に6ファイルあり、上記ファイルと同じ様です。

・glcdfont : 7x5
・Font16 : FONT2
・Font32rle : FONT4
・Font64rle : FONT6
・Font7srle : FONT7 7セグ
・Font72rle : FONT8 H75x55
・Font72x53rle : FONT8 H75x53

Customホルダ

...\libraries\TFT_eSPI\Fonts\Custom
に5ファイルありますが、装飾性の高い英数記号で読みづらいので略しました。

・Orbitron_Light_{24/32} 角ばっていて読みづらい
・Roboto_Thin_24 : 線が細い
・Satisfy_24 : 手書き風
・Yellowtail_32 : 手書き風

図付解説
https://qiita.com/tomoto335/items/9bb4427d6eb8e993b185

GFXFFホルダ

...\libraries\TFT_eSPI\Fonts\GFXFF
は49(=4x4x3+1)ファイルあり、英数記号です。今回のサンプルで使用します。

・TomThumb : 極小3x5
・FreeMono{-/Bold}{-/Oblique}{9/12/18/24}pt7b : 固定幅
・FreeSans{-/Bold}{-/Oblique}{9/12/18/24}pt7b : ゴシックみたい
・FreeSerif{-/Bold}{-/Italic}{9/12/18/24}pt7b : 始めと終わりに飾り付

* -:無し, Oblique:太字, Italic:安定な斜体, Bold:倒れそうな斜体

つまり、固定幅フォントは以下の16種類あります。
・FreeMono9pt7b
・FreeMono12pt7b
・FreeMono18pt7b
・FreeMono24pt7b
・FreeMonoBold9pt7b
・FreeMonoBold12pt7b
・FreeMonoBold18pt7b
・FreeMonoBold24pt7b
・FreeMonoOblique9pt7b
・FreeMonoOblique12pt7b
・FreeMonoOblique18pt7b
・FreeMonoOblique24pt7b
・FreeMonoBoldOblique9pt7b
・FreeMonoBoldOblique12pt7b
・FreeMonoBoldOblique18pt7b
・FreeMonoBoldOblique24pt7b

Adafruit_GFX_Library\Fontsホルダ

...\libraries\Adafruit_GFX_Library\Fonts
に52(=4x4x3+4)ファイルありました。9px以上のフォントは上記と同じようです。

・Tiny3x3a2pt7b : 3x3
・Picopixel
・Org_01 : H6
・TomThumb : 極小3x5
・FreeMono{-/Bold}{-/Oblique}{9/12/18/24}pt7b : 固定幅
・FreeSans{-/Bold}{-/Oblique}{9/12/18/24}pt7b : ゴシックみたい
・FreeSerif{-/Bold}{-/Italic}{9/12/18/24}pt7b : 始めと終わりに飾り付

* -:無し, Oblique:太字, Italic:安定な斜体, Bold:倒れそうな斜体

文字の基準位置設定

void setTextDatum(datum);

datumは、
・TL_DATUM : 左上 (default)
・TC_DATUM : 中央上
・TR_DATUM : 右上

・ML_DATUM : 左中央
・MC_DATUM : 中央
・MR_DATUM : 右中央

・BL_DATUM : 左下
・BC_DATUM : 中央下
・BR_DATUM : 右下

・L_BASELINE : 左baseline (BLより少し上)
・C_BASELINE : 中央baseline
・R_BASELINE : 右baseline

スケッチ

"Free_Fonts.h"はそのまま使用。

// Adafruit_GFXライブラリで使用されているフォントを画面表示
// ライブラリではGFX Free Fonts (GFXFF)と呼ばれています
// その他のTrue Typeはライブラリ内のfontconvertフォルダにあるユーティリティを使用して変換
// この変換もAdafruit_GFXライブラリからコピー
// LOAD_GFXFFがTFT_eSPIライブラリフォルダ内のUser_Setup.hファイルで定義されていること

#include <TFT_eSPI.h>      // ハードウェア固有のライブラリ
#include <SPI.h>           // SPI通信(モニタ)使用
#include "Free_Fonts.h"    // 添付 fontの略称等設定
TFT_eSPI tft = TFT_eSPI(); // カスタムライブラリを呼出す

void header(const char *string) {          // 1行目表示関数
  tft.setTextSize(1);                      // 文字サイズ倍率(整数)
  tft.setTextColor(TFT_MAGENTA, TFT_BLUE); // 文字(薄紫字色,青地)
  tft.fillRect(0, 0, 480, 30, TFT_BLUE);   // ヘッダー部分を青色に設定
  tft.setTextDatum(TC_DATUM);              // 文字基準点(中央上)
  tft.drawString(string, 239, 2, 4);       // 表示(文字列,x,y,font}
}

void drawDatum(int x, int y) {                 // 中心(x,y)の"+"を表示
  tft.drawLine(x - 5, y, x + 5, y, TFT_GREEN); // 横線
  tft.drawLine(x, y - 5, x, y + 5, TFT_GREEN); // 縦線
}

void setup() {
  tft.begin();          // システムモニタ初期設定
  tft.invertDisplay(1); // なぜか色反転しないとだめ
  tft.setRotation(1);   // 画面回転 0:縦,1:左が下,2:逆さま,3:右が下 (CNを上にして)
}

void loop() {
  // 1面目 print関数例 >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
  tft.fillScreen(TFT_NAVY);                       // 画面クリア(濃紺)
  header("Draw free fonts using print class");    // 1行目表示関数へ
  // Adafruit_GFXライブラリとの互換性のため、printで指定してもテキストの地が描画されない●
  tft.setTextColor(TFT_YELLOW, TFT_BLACK);        // しかし、地は濃紺のまま●
  int xpos =  0, ypos = 40;                       // 2行目表示位置
  tft.setCursor(xpos, ypos);                      // カーソル位置設定
  tft.setTextFont(GLCD);  // (NULL) or (GLCD)でオリジナルのGLCDフォント 小さすぎる
  tft.println(); tft.print("Original GLCD font"); // 表示
  tft.println(); tft.println();                   // 2行改行 改行幅は少ない
  tft.setFreeFont(FMB9); tft.println(); tft.print("Mono Bold 9pt"); // 表示
  // tft.setFreeFont(&FreeSerif9pt7b); の代わり
  // フリーフォントはベースラインを基準としてるので、0,0の位置から一行下に移動●
  tft.setFreeFont(FMB12); tft.println(); tft.print("Mono Bold 12pt"); // 表示
  tft.setFreeFont(FMB18); tft.println(); tft.print("Mono Bold 18pt"); // 表示
  tft.setFreeFont(FMB24); tft.println(); tft.print("Mono Bold 24pt"); // 表示
  delay(4000);                                                        // 4秒待つ

  // 2面目 drawString関数例 >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
  tft.fillScreen(TFT_BLACK);                          // 画面クリア(黒)
  header("Draw with background using drawString()");  // 1行目表示関数へ
  tft.setTextColor(TFT_WHITE, TFT_BLACK);             // 文字(白字,黒地)
  tft.setTextDatum(TC_DATUM);                         // 文字の基準位置(中央上)
  xpos = tft.width() / 2; ypos = 50;                  // 2行目表示位置 x:画面幅中央
  tft.setFreeFont(FM9);                               // フォント設定
  tft.drawString("Free Mono 9pt", xpos, ypos, GFXFF); // 表示
  ypos += tft.fontHeight(GFXFF);                      // フォント高さを取得し下に移動
  tft.setFreeFont(FM12);                              // フォント設定
  tft.drawString("Free Mono 12pt", xpos, ypos, GFXFF);// 表示
  ypos += tft.fontHeight(GFXFF);                      // フォント高さを取得し下に移動
  tft.setFreeFont(FM18);                              // フォント設定
  tft.drawString("Free Mono 18pt", xpos, ypos, GFXFF);// 表示
  ypos += tft.fontHeight(GFXFF);                      // フォント高さを取得し下に移動
  tft.setFreeFont(FM24);                              // フォント設定
  tft.drawString("Free Mono 24pt", xpos, ypos, GFXFF);// 表示
  ypos += tft.fontHeight(GFXFF);                      // フォント高さを取得し下に移動

  tft.setTextPadding(120);           // 背景ブランキング/オーバーライトの幅を設定(px)
  for (int i = 40; i >= 0; i--) {    // i=40-0まで
    tft.drawFloat(i / 10.0, 1, xpos, ypos, GFXFF);
    // 表示 (floatNumber,小数点以下の桁数,x,y,font) setTextDatum,setTextPaddingも使用 
    delay (100);                     // 0.1秒待つ
  }

  // 3面目 drawString関数例 (fontと色変更) >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
  tft.fillScreen(TFT_DARKGREY);                   // 画面クリア(濃い灰色)
  header("Show background filled bounding boxes");
  tft.setTextColor(TFT_YELLOW, TFT_BLACK);        // 文字(黄色字,黒地)
  tft.setTextDatum(TC_DATUM);
  xpos = tft.width() / 2;ypos = 50;
  tft.setFreeFont(FSB9);
  tft.drawString("Serif Bold 9pt", xpos, ypos, GFXFF);
  ypos += tft.fontHeight(GFXFF);
  tft.setFreeFont(FSB12);
  tft.drawString("Serif Bold 12pt", xpos, ypos, GFXFF);
  ypos += tft.fontHeight(GFXFF);
  tft.setFreeFont(FSB18);
  tft.drawString("Serif Bold 18pt", xpos, ypos, GFXFF);
  ypos += tft.fontHeight(GFXFF);
  tft.setFreeFont(FSBI24);
  tft.drawString("Serif Bold Italic 24pt", xpos, ypos, GFXFF);
  ypos += tft.fontHeight(GFXFF);
  tft.setTextPadding(120);
  for (int i = 40; i >= 0; i--) {
    tft.drawFloat(i / 10.0, 1, xpos, ypos, GFXFF);
    delay (100);
  }
  // 4面目 文字位置例 >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
  tft.fillScreen(TFT_BLACK);                // 画面クリア(黒)
  header("Draw text relative to a datum");  // 1行目表示関数へ
  tft.setTextColor(TFT_DARKGREY, TFT_BLACK);// 文字(濃い灰色,黒地)
  tft.setFreeFont(FSS9);                    // フォント設定
  tft.setTextDatum(TL_DATUM);               // 文字の基準位置(左上) default
  tft.drawString("[Top left]}", 20, 60, GFXFF); drawDatum(20, 60);
  tft.setTextDatum(TC_DATUM);               // 文字の基準位置(中央上)
  tft.drawString("[Top centre]", 240, 60, GFXFF); drawDatum(240, 60);
  tft.setTextDatum(TR_DATUM);               // 文字の基準位置(右上)
  tft.drawString("[Top right]", 460, 60, GFXFF); drawDatum(460, 60);
  tft.setTextDatum(ML_DATUM);               // 文字の基準位置(左中央)
  tft.drawString("[Middle left]", 20, 140, GFXFF); drawDatum(20, 140);
  tft.setTextDatum(MC_DATUM);               // 文字の基準位置(中央)
  tft.drawString("[Middle centre]", 240, 140, GFXFF); drawDatum(240, 140);
  tft.setTextDatum(MR_DATUM);               // 文字の基準位置(右中央)
  tft.drawString("[Middle right]", 460, 140, GFXFF); drawDatum(460, 140);
  tft.setTextDatum(BL_DATUM);               // 文字の基準位置(左下)
  tft.drawString("[Bottom Left]", 20, 220, GFXFF); drawDatum(20, 220);
  tft.setTextDatum(BC_DATUM);               // 文字の基準位置(中央下)
  tft.drawString("[Bottom centre]", 240, 220, GFXFF); drawDatum(240, 220);
  tft.setTextDatum(BR_DATUM);               // 文字の基準位置(右下)
  tft.drawString("[Bottom right]", 460, 220, GFXFF); drawDatum(460, 220);
  tft.setTextDatum(L_BASELINE);             // 文字の基準位置(左baseline)
  tft.drawString("[Left baseline]", 20, 300, GFXFF); drawDatum(20, 300);
  tft.setTextDatum(C_BASELINE);             // 文字の基準位置(中央baseline)
  tft.drawString("[Centre baseline]", 240, 300, GFXFF); drawDatum(240, 300);
  tft.setTextDatum(R_BASELINE);             // 文字の基準位置(右baseline)
  tft.drawString("[Right baseline]", 460, 300, GFXFF); drawDatum(460, 300);
  delay(8000);                              // 8秒待つ
}
* フラッシュメモリ(1MByte)を、スケッチが15%使用。RAM(262kByte)を、グローバル変数が3%使用し、ローカル変数で254kByte使用可能。(1000byte=1kByteで計算)