M5Paperに日本語フォントを入れる話
せっかく電子ペーパーなんだし、M5Paperに日本語フォントいれたいよねー。(´・ω・)(・ω・`)ネー。と、以前試したときはなんでかうまくいかなかったので、今度は真剣に。とやってみたけれどなんだか結局いろいろ遠回りしてしまった話です><
はじめに
まず最初に、”M5Paper 日本語” で検索するとでてくる、
↑こちらを参考にすすめよう、としたのですがががw
これ、M5Paperのファクトリーテストで表示させるためにフォントいれますよ。という記事で、いまいち(ファクトリーテストのソースを読めばいいんですけどねw)使いやすくないかんじなのでした。
※ファクトリーテストのソースはこちら(参考)
横着者としてはそのままつかえるのがいいなー、なんて、いろいろ探してみて、その次に参考資料として見つけたのがこれ。
こちらは、SPIFFSというファイルシステムにTTF(フォント)ファイルを置く話です。SPIFFSってのはESP32系に入っているフラッシュメモリで、M5Paperにもばっちり入っていて、SDカードみたいに取り出すことはできないけれど、内蔵のファイルシステムとして利用できるのです。
そこにフォント情報をいれて利用しよう。ってやつですね。
じゃ、さっそくこれやってみます!
やること
まず、IPAexフォントのダウンロード
から、フォントをダウンロード。今回は小さめのやつが欲しい(7M以下)なので
↑の ipaexg.ttf (ゴシック)を font.ttf にリネームして、SDカードへコピーしておきます。
次に、ひさびさのArduinoIDEを用意w
Arudino IDE の設定
参考ページには、ボード設定を「M5Stack-FIRE」にするとかかれてますが、もうPaper用の設定が公開されているので、ボード情報のアップデートをおこなうと、
M5Stack-Paper が出てくるので、そちらをセット。
次に、Partition Schema を
Large SPIFFS (7 MB) にセットします。
※こうしておかないと、SPIFFSにフォントを書きこめません><
プログラムソース
参考サイトを参考に(?)して少し変更したソースがこちら
#include <M5EPD.h>
#include <FS.h>
M5EPD_Canvas canvas(&M5.EPD);
// SDカードがセットされていれば、SPIFFSを初期化後font.ttfをコピーする
bool tryCopySDFile() {
const char *path = "/font.ttf";
if (!SD.begin(4) || !SD.exists(path)) {
return SPIFFS.begin(false) && SPIFFS.exists(path);
}
canvas.drawString("Copying font ...", 270, 664);
canvas.pushCanvas(0,0,UPDATE_MODE_DU4);
Serial.println("Formatting SPIFFS ...");
if (!SPIFFS.format()) {
Serial.println("SPIFFS format Failed");
return false;
}
if (!SPIFFS.begin()) {
Serial.println("SPIFFS Mount Failed");
return false;
}
Serial.println("Copying font ...");
File file = SD.open(path);
SPIFFS.remove(path);
File dest = SPIFFS.open(path, FILE_WRITE);
if (!file || !dest) {
Serial.println("failed.");
return false;
}
uint8_t *buf = new uint8_t[4096];
if (!buf) {
Serial.println("failed.");
return false;
}
size_t len, size, ret;
size = len = file.size();
while (len) {
size_t s = len;
if (s > 4096)
s = 4096;
file.read(buf, s);
if ((ret = dest.write(buf, s)) < s) {
Serial.print("write failed: ");
Serial.print(ret);
Serial.print(" - ");
Serial.println(s);
return false;
}
len -= s;
Serial.print(size - len);
Serial.print(" / ");
Serial.println(size);
}
delete[] buf;
file.close();
dest.close();
if (!SPIFFS.exists(path)) {
Serial.println("no file");
return false;
}
dest = SPIFFS.open(path);
len = dest.size();
dest.close();
if (len != size) {
Serial.print("size not match : ");
Serial.println(dest.size());
return false;
}
Serial.println("Done.");
return true;
}
void setup() {
M5.begin();
M5.TP.SetRotation(90);
M5.EPD.SetRotation(90);
M5.EPD.Clear(true);
//M5.RTC.begin();
canvas.createCanvas(540, 960);
canvas.setTextDatum(TC_DATUM);
canvas.setTextSize(3);
canvas.drawString("... Initializing ...", 270, 640);
canvas.pushCanvas(0,0,UPDATE_MODE_DU4);
if (!tryCopySDFile()) {
canvas.drawString("data copy failed !", 270, 254);
canvas.pushCanvas(0,0,UPDATE_MODE_DU4);
for (;;);
}
// SPIFFSからフォントを読み込む
canvas.drawString("Loading font ...", 270, 230);
canvas.pushCanvas(0,0,UPDATE_MODE_DU4);
Serial.println("Loading font from SPIFFS.");
canvas.loadFont("/font.ttf", SPIFFS);
Serial.println("Loading done.");
canvas.createRender(96, 256);
canvas.createRender(32, 256);
canvas.drawString("OK!", 270, 254);
canvas.pushCanvas(0,0,UPDATE_MODE_DU4);
M5.EPD.Clear(true);
}
void loop() {
String buf;
canvas.setTextDatum(TL_DATUM);
canvas.fillCanvas(0);
buf = "あいうえお";
canvas.setTextSize(32);
canvas.drawString(buf, 12, 16);
buf = "漢字だよ!";
canvas.setTextSize(96);
canvas.drawString(buf, 12, 64);
canvas.pushCanvas(0,0,UPDATE_MODE_DU4);
delay(50000);
}
とくに時間は要らないのでRTCは省きましたw
実行
実行すると、fontファイルの入ったSDカードが突っ込まれていると、最初にSPIFFSへFontデータをコピーします(ちょっと時間かかる)
:
↑こんなかんじで(左端で時間わかりますね)大体2分ぐらいかかります。一度やっておくと、次回からは(SDカードを抜いとくことをわすれずにw)2~3秒でロードは終わります。
そして、どん!
でましたー!☆
1行目の「あいうえお」は32ポイントで、2行目の「漢字だよ!」は96ポイントの文字になってます。
それぞれ、
canvas.createRender(96, 256);
canvas.createRender(32, 256);
という風に事前にレンダー情報を確保しておくことが必要な様子。
※これ知らなくて出しかたわかんなかった><
で、あれ? もしかして?
createRender入れたらSDからでもいけるんじゃね?
と気が付いてさらに書き直したもっと簡易版ソースがこちら
#include <M5EPD.h>
#include <FS.h>
M5EPD_Canvas canvas(&M5.EPD);
void setup() {
M5.begin();
M5.TP.SetRotation(90);
M5.EPD.SetRotation(90);
M5.EPD.Clear(true);
canvas.createCanvas(540, 960);
canvas.setTextDatum(TC_DATUM);
canvas.setTextSize(3);
canvas.drawString("... Initializing ...", 270, 640);
canvas.pushCanvas(0,0,UPDATE_MODE_DU4);
// SDからフォントを読み込む
canvas.drawString("Loading font ...", 270, 230);
canvas.pushCanvas(0,0,UPDATE_MODE_DU4);
Serial.println("Loading font from SD.");
canvas.loadFont("/font.ttf", SD);
Serial.println("Loading done.");
canvas.createRender(96, 256);
canvas.createRender(32, 256);
canvas.drawString("OK!", 270, 254);
canvas.pushCanvas(0,0,UPDATE_MODE_DU4);
M5.EPD.Clear(true);
}
void loop() {
String buf;
canvas.setTextDatum(TL_DATUM);
canvas.fillCanvas(0);
buf = "あいうえおfromSD";
canvas.setTextSize(32);
canvas.drawString(buf, 12, 16);
buf = "漢字だよ!";
canvas.setTextSize(96);
canvas.drawString(buf, 12, 64);
canvas.pushCanvas(0,0,UPDATE_MODE_DU4);
delay(50000);
}
実行
ちょっとー、なによもー、さくっとうごくじゃーん!><
フォントの読み込み時間も
一瞬。1秒かかってません。
SDカードいれっぱにしないとダメですけど、この方がぜんぜん速いし楽ですね><
ちょっとけっこうかなり遠回りしてしまった感がありますが、SPIFFSの使い方もわかったし、まあうごくようになったんでよかったよかった。ということでw
※SPIFFSの設定もPratformIOでできれば早かったのだけれど、やり方分からずArduinoIDEでやってます><
※( ゚д゚)ハッ! SPIFFSに入れるために7MB以下のフォントを用意しましたけど、SDから直接なら明朝でももっときれいな奴でも行ける気が! 明朝体で電子書籍リーダーとか作れると嬉しそうな気がとってもしますねー☆
―――