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秒待つ
}



