M5Stack CoreInkの使い方 その2 日本語フォントや描画拡張

概要

前回は標準ライブラリの使い方を中心に説明をしました。今回は他のライブラリを同時に利用して、より便利に描画をしてみたいと思います。

efontライブラリを利用した日本語(多言語)フォント

  • /efont/(電子書体オープンラボ)

上記のフォントデータを、Arduinoから利用できるようにしたefontライブラリを使って日本語や多言語表示をしてみたいと思います。

ライブラリのインストール

ライブラリマネージャからefontで検索して、インストールしてください。

使い方

#include <M5CoreInk.h>
#include "efontEnableAll.h"
#include "efont.h"
#include "efontM5StackCoreInk.h"

Ink_Sprite inkPageSprite(&M5.M5Ink);

void setup() {
  M5.begin();
  if ( !M5.M5Ink.isInit()) {
    Serial.printf("Ink Init faild");
    while (1) {
      delay(100);
    }
  }
  M5.M5Ink.clear();
  delay(1000);

  //creat ink refresh Sprite
  if ( inkPageSprite.creatSprite(0, 0, 200, 200, true) != 0 ) {
    Serial.printf("Ink Sprite creat faild");
  }

  printEfont(&inkPageSprite, "Hello\n");
  printEfont(&inkPageSprite, "こんにちは\n");
  printEfont(&inkPageSprite, "你好\n");
  printEfont(&inkPageSprite, "안녕하세요\n");
  printEfont(&inkPageSprite, "Доброе утро\n");
  printEfont(&inkPageSprite, "Päivää\n");
  printEfont(&inkPageSprite, "Здравствуйте\n");

  printEfont(&inkPageSprite, "efont\nPrint Test", 0, 130, 2, 1);

  inkPageSprite.pushSprite();
}

void loop() {
}

ちょっと癖がある使い方なのですが、最初に読み込むフォントの範囲を指定する必要があります。

対象オプション文字数フォントサイズ
ALLefontEnableAll.h21,727738,718
AsciiefontEnableAscii.h1916,494
CJK KanjiefontEnableCJK.h19,379658,886
Simplified ChineseefontEnableCn.h18,077614,618
JapaneseefontEnableJa.h10,835368,390
Mini JapaneseefontEnableJaMini.h4,107139,638
KoreanefontEnableKr.h8,319282,846
Traditional ChineseefontEnableTw.h13,555460,870

スケッチ例ではefontEnableAll.hを読み込んでいるので、すべてのフォントデータを読み込んでいます。通常の日本語であればefontEnableJaMini.hで常用漢字+αなのでたいていは表示できるとは思います。

あとはCoreInkのスプライトの初期化をして、printEfont()関数で文字を表示します。

printEfont(スプライト, 文字, X座標, Y座標, テキスト大きさ, 色);

上記の引数ですが、座標以下は省略可能です。

void printEfont(Ink_Sprite *sprite, char *str, int x = -1, int y = -1, int textsize = 1, int color = 0)

デフォルト値は上記になっており、XとYに-1を渡すと前回のカーソル位置から描画します。テキストサイズは1が16ドットで、2が32ドットになります。色は0の黒がデフォルトですが1を指定することで白になります。

実行結果

こんな感じになりました。efontはフォントデータが主体で、各種表示ロジックはサンプル実装になるので、ちょっと内部実装は遅いと思います。

決め打ちで描画しているところがあるので、気になる人はデータだけ利用して内部ロジックは一から作ったほうがいいと思います。

LovyanGFXのスプライトを利用

LovyanGFXにはCoreInkを直接描画する機能がありますが、次回以降に紹介したいと思います。今回は公式ライブラリ+LovyanGFXのスプライト機能のみ利用してみたいと思います。

efontの利用例

#include "M5CoreInk.h"
#include <efontEnableAll.h>
#include <efontFontData.h>
#include <LovyanGFX.hpp>

Ink_Sprite inkPageSprite(&M5.M5Ink);
static LGFX_Sprite sprite;

void pushSprite(Ink_Sprite *coreinkSprite, LGFX_Sprite *lgfxSprite);

void setup() {
  M5.begin();
  M5.M5Ink.isInit();
  M5.M5Ink.clear();
  inkPageSprite.creatSprite(0, 0, 200, 200, false);

  // スプライト作成
  sprite.setColorDepth(2);
  sprite.createPalette();
  sprite.createSprite(200, 200);
  sprite.clear(TFT_WHITE);
  sprite.setFont(&fonts::efont);
  sprite.setTextColor(TFT_BLACK, TFT_WHITE);

  // 描画テスト
  sprite.print("Hello\n");
  sprite.print("こんにちは\n");
  sprite.print("你好\n");
  sprite.print("안녕하세요\n");
  sprite.print("Доброе утро\n");
  sprite.print("Päivää\n");
  sprite.print("Здравствуйте\n");

  sprite.setCursor(0, 130);
  sprite.setTextSize(2);
  sprite.setTextColor(TFT_WHITE, TFT_BLACK);
  sprite.print("LovyanGFX\nPrint Test");

  pushSprite(&inkPageSprite, &sprite);
}

void loop() {
  delay(1);
}

void pushSprite(Ink_Sprite *coreinkSprite, LGFX_Sprite *lgfxSprite) {
  coreinkSprite->clear();
  for (int y = 0; y < 200; y++) {
    for (int x = 0; x < 200; x++) {
      uint16_t c = lgfxSprite->readPixel(x, y);
      if (c == 0x0000) {
        coreinkSprite->drawPix(x, y, 0);
      }
    }
  }
  coreinkSprite->pushSprite();
}

LovyanGFXからでもefontライブラリを利用しての描画が可能です。こちらのほうが一般的な描画関数が利用できるので移植はしやすいと思います。

肝はpushSprite()で、LovyanGFXのスプライトをCoreInkのスプライトに転記してから、画面更新をしています。

#include <efontEnableAll.h>

上記の部分で読み込む文字を指定しています。標準はすべてですが、どう考えても使わないような多言語の文字が大量にはいっていますので、ものすごく容量をくいます。

  • efontEnableJa.h
  • efontEnableJaMini.h

日本語だけであれば上記のどちらかで構わないと思います。

上記に詳しい文字数と容量が書いてあります。個人的にはLovyanGFXに内蔵されたので、個別ライブラリ版は使わなくてもいいのかなって思っています。

その他の日本語フォント

efontライブラリは多言語フォントですが、サイズが縦16ドットしかありません。IPAフォントであれば日本語のみですが、8から40ドットまでの細かいサイズが揃っています。Pがついているのが英数がプロポーショナルなIPAexになります。

こちらのフォントはLovyanGFXに内蔵されているので、別ライブラリが必要ないので気軽に利用することが可能です。efontと比べると機種依存文字などが含まれていないので、特殊な漢字を表示することはできないので注意してください。

IPA明朝体IPAex明朝体IPAゴシック体IPAexゴシック体
lgfxJapanMincho_8lgfxJapanMinchoP_8lgfxJapanGothic_8lgfxJapanGothicP_8
lgfxJapanMincho_12lgfxJapanMinchoP_12lgfxJapanGothic_12lgfxJapanGothicP_12
lgfxJapanMincho_16lgfxJapanMinchoP_16lgfxJapanGothic_16lgfxJapanGothicP_16
lgfxJapanMincho_20lgfxJapanMinchoP_20lgfxJapanGothic_20lgfxJapanGothicP_20
lgfxJapanMincho_24lgfxJapanMinchoP_24lgfxJapanGothic_24lgfxJapanGothicP_24
lgfxJapanMincho_28lgfxJapanMinchoP_28lgfxJapanGothic_28lgfxJapanGothicP_28
lgfxJapanMincho_32lgfxJapanMinchoP_32lgfxJapanGothic_32lgfxJapanGothicP_32
lgfxJapanMincho_36lgfxJapanMinchoP_36lgfxJapanGothic_36lgfxJapanGothicP_36
lgfxJapanMincho_40lgfxJapanMinchoP_40lgfxJapanGothic_40lgfxJapanGothicP_40

また、現在efontの10ドット、12ドット、14ドット、16ドット、24ドットをLovyanGFX内部に取り込み準備中のようです。efontはビットマップフォントですので、小さいサイズの場合にはefontの方が漢字はきれいに見えるかもしれません。

現在efontも追加されましたので、以下に追記します。

日本語韓国語中国語(簡体字)中国語(繁体字)
efontJA_10efontKR_10efontCN_10efontTW_10
efontJA_10_befontKR_10_befontCN_10_befontTW_10_b
efontJA_10_biefontKR_10_biefontCN_10_biefontTW_10_bi
efontJA_10_iefontKR_10_iefontCN_10_iefontTW_10_i
efontJA_12efontKR_12efontCN_12efontTW_12
efontJA_12_befontKR_12_befontCN_12_befontTW_12_b
efontJA_12_biefontKR_12_biefontCN_12_biefontTW_12_bi
efontJA_12_iefontKR_12_iefontCN_12_iefontTW_12_i
efontJA_14efontKR_14efontCN_14efontTW_14
efontJA_14_befontKR_14_befontCN_14_befontTW_14_b
efontJA_14_biefontKR_14_biefontCN_14_biefontTW_14_bi
efontJA_14_iefontKR_14_iefontCN_14_iefontTW_14_i
efontJA_16efontKR_16efontCN_16efontTW_16
efontJA_16_befontKR_16_befontCN_16_befontTW_16_b
efontJA_16_biefontKR_16_biefontCN_16_biefontTW_16_bi
efontJA_16_iefontKR_16_iefontCN_16_iefontTW_16_i
efontJA_24efontKR_24efontCN_24efontTW_24
efontJA_24_befontKR_24_befontCN_24_befontTW_24_b
efontJA_24_biefontKR_24_biefontCN_24_biefontTW_24_bi
efontJA_24_iefontKR_24_iefontCN_24_iefontTW_24_i

上記が追加されています。iがイタリック、bがボールドになります。

sprite.setFont(&fonts::efontJA_24_bi);

上記が縦24ドットの日本語フォントでイタリックとボールドになっています。指定したフォントのみフラッシュに読み込まれますが、大きさに比例したサイズになります。イタリックやボールドと普通を混在する場合には、別フォントとして容量が必要としますので注意してください。

画像や一般描画関数

LovyanGFXの機能を利用できるので、一般的なline関数やJpeg画像の描画なども可能です。標準ライブラリを使いつつ、使いやすい描画エンジンとしてLovyanGFXが利用可能になります。

まとめ

公式ライブラリを捨てて、LovyanGFXを使えばいいのですがそうするとLovyanGFXがサポートしていないRTCまわりの機能が使えなくなります。そのため公式ライブラリ相当のライブラリを組み合わせる必要があり、いろいろ下準備が必要です。

現状では公式ライブラリのリリース前の最新版+LovyanGFXのスプライトを組み合わせるのが一番安定していると思われます。

自作しているM5Liteライブラリでは内部でRTCもLovyanGFXも含んでいるので、もうちょっと検証してから、CoreInkのサポートを追加したいと思っています。

コメント

  1. TAD より:

    ひさびさにCoreInkを引っ張り出していじっているのですが、
    CoreInkライブラリが現状最新の1.0.0だとefontのプログラムで最下行の文字が表示されません。
    printEfont(&inkPageSprite, “efont\nPrint Test”, 0, 130, 2, 1);
    また、他の文字列でもsizeを2にしたり、描画色を1にするといずれも表示されません。
    CoreInkを0.0.7にしたら表示されました。
    この辺、1.0.0で動作させるための対策などでていますでしょうか。
    情報ありましたら教えていただければと思います。

  2. TAD より:

    いじってみて混乱は深まっているのですが、
    ・そもそもM5CoreInkのライブラリ1.0.0はボードライブラリM5CoreInk(Espressifの?)でないとコンパイルできないっぽい(M5Stack-CoreInkライブラリ:M5Stackの?では駄目) まぁ、それはそれでいいとして…
    ・コメント欄で提示いただいたプログラムはコンパイルでき、動作する。ただし、文字列に日本語文字を入れても表示は出ない。□になる。
    ・この記事の後半「LovyanGFXのスプライトを利用」の方のプログラムについて、コンパイルを通すライブラリバージョン構成/#includeの組み合わせが見つけられない

    M5GFX/LovyanGFXの関係も把握できておらず、なかなか「こうするのが正解」構成がみつかりません。

    • たなかまさゆき より:

      おっと、うまく動きませんでしたか、、、
      コンパイルまでは確認したのですが実機では確認していなかったです

      ボードライブラリはEspressif版とM5Stack版がありまして、Espressif版はバージョン3系で、M5Stack版は少し古い2系になっています。
      そしてCoreInkのライブラリ1.0.0だと2系にしか対応していないM5GFXに変更されているので、Espressif版の3系ボードマネージャーだと動きません。

      あとLovyanGFXの対応ボードをM5系に限定したのがM5GFXで中身はあまり変わっていないのですが、LovyanGFX自体のバージョンアップでいろいろ変更されているのでその影響もあると思います。。。

      日本語がでないのはなんでだろうな

      InkPageSprite.setFont(&fonts::lgfxJapanGothic_12);
      InkPageSprite.setCursor(0, 8);
      InkPageSprite.print(“日本語”);

      上記みたいな指定方法でもう一度試してもらえればと思います
      とはいえ、M5Unifiedを使って複数のボードに対応するのではなく、CoreInkのみを使うのであれば古いバージョンの方がシンプルで使いやすいかもしれません