Arduino(M5StickC)でefont Unicodeフォント表示 完結編

/efont/さんのUnicode Fontを利用して、Arduino用のフォントライブラリを作ってみました。

いろいろ実験した結果、文字単位で読み込むかを決めて、フォント用のテーブルから探す方式がメモリ効率と速度のバランスが一番良かったです。

※現時点の情報ですので、最新情報はM5StickC非公式日本語リファレンスを確認してください。

利用フォント

Unicode Font from /efont/

上記のf16.bdfとb16.bdfを利用させていただき、16ピクセルフォントを作成しました。

作成物

GitHub - tanakamasayuki/efont: efont Font Data for Arduino
efont Font Data for Arduino. Contribute to tanakamasayuki/efont development by creating an account on GitHub.

フォントサイズ

対象オプション文字数フォント容量
すべてefontEnableAll.h21,727738,718
AsciiefontEnableAscii.h1916,494
CJK漢字efontEnableCJK.h19,379658,886
簡体字中国語efontEnableCn.h18,077614,618
日本語efontEnableJa.h10,835368,390
日本語(常用+α)efontEnableJaMini.h4,107139,638
韓国語efontEnableKr.h8,319282,846
繁体字中国語efontEnableTw.h13,555460,870

/efont/は2万文字強収録されており、256文字単位での読み込みだと使っていないエリアがたくさんあって無駄になっていたので、1文字単位で読み込んでいます。

16ピクセルフォントなので、1文字あたり32Byteの字形データ(PROGMEM領域)と、UTF16の文字コードテーブルで2Byte使うので、1文字あたり34Byteです。

このサイズだったら全部読み込んで、メモリが足りなくなってから使わない文字を減らす運用でも大丈夫かもしれません。

ちなみに0(U+0030)の文字が有効になっていない場合には、フォントの指定をしていないとみなして、efontEnableAll.hを読み込むようにしています。

実行結果

サンプルコード

#include <M5StickC.h>
#include "efontEnableAll.h"
//#include "efontEnableAscii.h"
//#include "efontEnableCJK.h"
//#include "efontEnableJa.h"
#include "efont.h"
#include "efontM5StickC.h"

void setup() {
  M5.begin();
  M5.Lcd.setRotation(0);
  M5.Lcd.setCursor(0, 0);

  printEfont("Hello", 0, 16*0);
  printEfont("こんにちは", 0, 16*1);
  printEfont("你好", 0, 16*2);
  printEfont("안녕하세요", 0, 16*3);
  printEfont("Доброе утро", 0, 16*4);
  printEfont("Päivää", 0, 16*6);
  printEfont("Здравствуйте", 0, 16*7);
}

void loop() {
}

ビルド結果

最大1310720バイトのフラッシュメモリのうち、スケッチが977224バイト(74%)を使っています。
最大327680バイトのRAMのうち、グローバル変数が14652バイト(4%)を使っていて、ローカル変数で313028バイト使うことができます。

ちなみにM5StickCのスケッチ例「HelloWorld」との比較。

スケッチフラッシュRAM
efont977,22414,652
HelloWorld226,74814,532
750,476120

んー、もう少しグローバル変数使っている気がするけれど、調べたらESP32実機だとconstつけたデータは、PROGMEMをつけていなくてもフラッシュ領域になるみたいですね。

まとめ

描画が遅いのはちょっとどうにかしないといけないのですが、描画周りはちょっと後にして他の機能を検証する予定です。

コメント