Excel で自作したカスタムフォントを M5stack に表示してみる

記事公開日:2018年5月13日


スポンサーリンク

自作するフォント形式について

このブログでは、16×16 pixel フリーの日本語漢字フォント、東雲フォントをよく使っています。
これは、テキスト形式の BDF ファイルです。
それについては以下の記事を参照してください。

日本語漢字ビットマップフォント、東雲フォントについて

この形式に合わせてフォントを自作した方が、後々汎用性が高いです。

BDFテキスト形式は、テキストエディタでフォント内容が見られて、そのフォントがどの文字を表しているのか判別し易いという特徴があります。

例えば、以下のサイトで「あ」という文字の JIS コードを検索してみます。

http://ash.jp/code/unitbl21.htm

[pic01]

m5stack_customfnt01.jpg


すると、2422 と分かるので、今度は全角の東雲フォントファイル、

shnmk16.bdf

をテキストエディタで開いて、2422で検索してみます。
※メモ帳ではなく、テキスト専用エディタで開いて下さい
私の場合は、Adobe Brackets を使っています

すると、下図の様に

STARTCHAR 2422

というところが見つかり、そこに実際のBDF形式ビットマップデータがあります。

[pic02]

m5stack_customfnt02.jpg


これの見方は、BDFの16進数2バイトデータを上位2桁16進数(上位1byte)と下位2桁16進数(下位1byte)に分けて、それぞれ2進数にして見た時、1になっているビットをディスプレイに1pixel として表示させれば良いわけです。

[pic05]

m5stack_customfnt05.jpg


「あ」という文字を下図の様にエクセルで表示させてみるとより分かりやすいと思います。

[pic03]

m5stack_customfnt03.jpg


これで見ると一目瞭然ですが、上位のビットマップ、つまり左半分と右半分にビットマップが分割できますね。
これは、日本語の場合、半角と全角に分けやすいという利点があります。

半角の東雲フォント
shnm8x16r.bdf
というファイルをテキストエディタで開いて、「A」という文字のビットマップを調べてみます。
ASCII コードでは、0x41 なので、

STARTCHAR 41

で検索をかけてみると、下図の様に半角の BDFデータが見られます。

[pic06]

m5stack_customfnt06.jpg


これを先ほどと同じように、エクセルでビットマップ表記させてみると、こんな感じになります。

[pic07]

m5stack_customfnt07.jpg


これでは、上位バイトと下位バイトで別れていますが、半角の場合は上位も下位もなく、1バイトです。

このように、BDFデータというのは、全角の場合は半角が2つ合わさったデータで出来ています。
これは、半角をディスプレイ表示させる場合にとても都合が良いのです。

この方式はアマチュアの私としてはとても分かりやすいし、フォントを自作し易いと思いました。
そして、カスタム(自作)フォントを東雲フォントに差し替えやすいと思いました。
本当はバイナリ形式にした方が計算は速いし、メモリも少なくて済みますが、それについては後で述べます。

因みに、これから説明するものは、ページの都合上全角フォントに絞って説明します。
半角の場合は各個人で改良してください。

カスタムフォント作成ファイルの使い方

以下、Windows10 で説明します。

まず、ダウンロードした、
MyFont_ver3.0.xlsx
を開いて下さい。
このファイルは、マクロを一切使っていません。
(※このファイルは動作が重いです。
メモリが非力なパソコンでは辛いかもしれません)

次に、Make_MyFont シートを開きます。

すると、下図の様に表示されます。
見本例として、ある程度私が作ったものを32種類入力しておきました。

肌色の16×16マスの中に1を入力すると、その隣にドットが表示されるので、そこでフォントを作成します。

※編集するところは、肌色の枠内だけです

そして、一番左の肌色のところに個人で考えた適当なフォント名を入力しておきます。
このフォント名は、CSVファイルを出力した時に分かりやすくするためのインデックスで、自分自身が判別できれば何でも良いです。

[pic04]

m5stack_customfnt04.jpg


フォント番号やアドレスなどは、自作(カスタム)フォントをバイナリ形式にした時に使用するものです。
これは後で説明します。

BDF形式の項目のところは、入力した自作フォントを東雲フォントの BDF形式に変換した数値です。
2進数表記の方が見た目は分かりやすいのですが、プログラム中に書くとすると16進数表記の方が短く済みます。

その他のシートは以下のものがあります。

CSV_fileOUTputシート

バイナリ形式フォントを作成するための CSV 出力用シート

ShinonomeBDF_CSVout シート

東雲フォントに埋め込む(差し替え)用の CSV 出力用シート

BDF_Font_Check シート

東雲フォントの BDF 値チェック用シート

これらのシートの使用方法は後で述べます。

この Excel ファイルは数式やセル参照を沢山使っているため、動作が重いので予めご了承ください。
動作を軽くしたい場合は、使っていない計算式が入っているセルを消去してください。

今回、この Excel ファイルと作るにあたって、Excel の新しい使い方を覚えました。
それは、飛び飛びセル参照のオートフィルを使う方法です。
それは、OFFSET 関数なるものを使うのですが、これにより作業効率が大幅にアップしました。

それに数式の前に “#” を付けてオートフィルすると、縦参照から横参照のオートフィルができるということも覚えました。

エクセルってスゲーな!

って思いましたね。
少数のカスタムフォントを作るには意外と最適なアプリかも、って思いました。

でも、計算式や参照が増えると、動作がどうしても重くなるので、その場合は専用アプリを開発した方場良いですね。

ということで、次では自作したビットマップを M5Stack に表示させてみます。

自作フォント BDFデータで、簡易的にM5Stack のディスプレイに表示させてみる

では、Arduino – ESP32 を使って、M5Stack のディスプレイにカスタム(自作)フォントを表示させてみます。

まず、ここではカスタム(自作)フォントを表示させるための考え方を説明するために、micro SD カードを使わずに、プログラム中にフォントデータを書き込む方式でやってみます。

Arduino IDE を起動し、以下のスケッチを入力してみてください。

#include "ESP32_LCD_ILI9341_SPI.h" //beta ver 1.25-

const int8_t sck = 18; // SPI clock pin
const int8_t miso = -1; // MISO(master input slave output) don't using
const int8_t mosi = 23; // MOSI(master output slave input) pin
const int8_t cs = 14; // Chip Select pin
const int8_t dc = 27; // Data/Command pin
const int8_t rst = 33; // Reset pin
const int8_t LCD_LEDpin = 32;

ESP32_LCD_ILI9341_SPI LCD(sck, miso, mosi, cs, dc, rst, LCD_LEDpin);

const uint8_t MAX_FONT_NUM = 4;

const uint8_t font_buf[ MAX_FONT_NUM ][ 16 ] = {
  //東雲フォント「あ」
  {0x02,0x02,0x02,0x1f,0x02,0x02,0x03,0x04,0x0c,0x14,0x24,0x23,0x25,0x18,0x00,0x00},
  {0x00,0x00,0x60,0x80,0x00,0x40,0xf0,0x48,0x44,0x82,0x82,0x02,0x04,0x18,0x60,0x00},
  //自作フォント「ハート」
  {0x00,0x1C,0x3E,0x7F,0x7F,0x7F,0x7F,0x7F,0x3F,0x3F,0x1F,0x0F,0x07,0x03,0x01,0x00},
  {0x00,0x70,0xF8,0xFC,0xFC,0xFC,0xFC,0xFC,0xF8,0xF8,0xF0,0xE0,0xC0,0x80,0x00,0x00}};

void setup() {
  Serial.begin(115200);
  delay(1000);
  LCD.ILI9341_Init(false, 40000000); //SDカードを使う場合、必ず false にする
  LCD.Display_Clear();
  LCD.Brightness(255); //LCD LED Full brightness

  uint16_t X0 = 0, Y0 = 0;
  uint8_t Fnt_Cnt; //font count
  uint8_t bt = 0b10000000;
  uint8_t red = 31, green = 63, blue = 31;
  int i;

  for( Fnt_Cnt = 0; Fnt_Cnt < MAX_FONT_NUM; Fnt_Cnt++ ){
    X0 = Fnt_Cnt * 8;
    for( Y0 = 0; Y0 < 16; Y0++ ){
      for( i = 0; i < 8; i++ ){
        if( ( font_buf[ Fnt_Cnt ][ Y0 ] & (bt >> i) )  > 0 ){
          red = 31, green = 63, blue = 31;
        }else{
          red = 0, green = 0, blue = 0;
        }
        LCD.Draw_Pixel_65k_3Color_sd( X0 + i, Y0, red, green, blue ); //SDカードと併用できる関数
      }
    }
  }
}

void loop() {

}

1行目では、私の自作 LCD表示ライブラリをインクルードしています。
先ほども述べましたが、ライブラリは、beta ver 1.25 を使って下さい。

15-21行目で、フォントデータの初期化をしています。
例として、東雲フォントの「あ」とカスタム(自作)フォントの「ハート」を入力しています。

これは、先にダウンロードした、MyFont_ver3.0.xlsx ファイルを開きます。
東雲フォントの「あ」のデータについては、
BDF_Font_Check シート
を開き、下図の様なところのデータをプログラム中にコピペし、16進数値の前に”0x” を加えたものです。

[pic10]

m5stack_customfnt10.jpg


カスタム(自作)フォントのデータは、
Make_MyFont シート
を開いて、下図の様なところを書き写したものです。

[pic11]

m5stack_customfnt11.jpg


全角フォントデータは、上位バイトと、下位バイトに分けて、配列に収納します。
全角2文字分ですが、半角に換算して4つ分としておきます。
ですから、13行目の MAX_FONT_NUM は 4 として配列を確保しています。

31行目の、Fnt_Cnt という引数は、半角相当1文字分のデータを描画し終えたらカウントアップしていくフォントカウント値です。

32行目の bt というものは、フォントビットが0 か 1 を判別するために使うもので、40行目の式に使われています。
39-46行では、フォントの1byteデータを7bit目から順番に見ていき、0の場合はそのピクセルはブラックで描画し、1ならば白色でピクセルを描画します。
45行目が実際に LCD ILI9341 に 1 pixel を65kカラーで描画しています。
(M5Stack のLCD ILI9341 についてはこちらを参照)
自作ライブラリ beta ver 1.25 から、SDカードと併用できるpixel表示関数を追加しました。
この項では SD カードを使いませんが、今後使うことも有ろうかと思い、これにしました。

では、これをコンパイル書き込み実行させてみてください。
以下のように表示されればOKです。

[pic12]

m5stack_customfnt12.jpg



45行目の関数を M5Stack 標準ライブラリを使って pixel 表示させる関数に置き換えると、同じようなことができると思います。

これさえできれば、あとはこれの応用なので、フォントを micro SD から読み込んで表示させたり、時刻を表示させたりできると思います。

ただ、pixel 関数を毎回呼び出しているので、その分描画速度は遅くなります。
私の自作フォント表示関数では、半角フォント1文字分データを一気に LCD RAMに流し込んでいますが、ここではとても解説が難しいので、もし、その方法を知りたければ、ライブラリプログラムをご自身で読み解いていただければと思います。

次の項では、カスタムフォントを東雲フォントに埋め込んでみます。


スポンサーリンク


コメントを残す

メールアドレスが公開されることはありません。

このサイトはスパムを低減するために Akismet を使っています。コメントデータの処理方法の詳細はこちらをご覧ください