フォト
2022年9月
        1 2 3
4 5 6 7 8 9 10
11 12 13 14 15 16 17
18 19 20 21 22 23 24
25 26 27 28 29 30  
無料ブログはココログ

« MSX用ゲームカートリッジの中身 | トップページ | OLED(SSD1306)で美咲フォントを使った漢字表示 »

2019年1月30日 (水)

Arduino用フォントライブラリを更新しました

Arduino用フォントライブラリを更新しました。

  更新ライブラリ
    ・Arduino用 美咲フォントライブラリ 教育漢字・内部フラッシュメモリ乗せ版
      https://github.com/Tamakichi/Arduino-misakiUTF16

     変更点
       ・Utf8ToUtf16()の戻り値の型をbyteからint16_tに変更
       ・未使用変数の削除
       ・非AVR対応
       ・マクロ定数 FONT_TOFU (=0x25a1,豆腐"□"コード)の追加
       ・API関数の説明に少々追記

フォントライブラリはいくつか作成していますが、
今回更新したライブラリは1,710文字(教育漢字1,006字+α)に絞ってフラシュメモリに乗せたバージョンです。

文字列にUTF16/UTF8を使用しているので、Arduino IDE環境で
日本語を含む文字列をそのままプログラムソース上に記述出来ます。

収録フォント

   Photo

  フォントは8x8ドットの美咲フォントを利用しています。
  フォントデータは次のような感じでメモリ上に格納します。

    Fontformat

インストール方法

ライブラリ公開先のリンクをクリックし、ページ右上の「Clone or download」を
クリックして、さらに「Dounload ZIP」をクリックするとダウンロードできます。

20190130

ダウンロード後、ファイルを解凍し、フォルダ内のmisakiUTF16 フォルダを
各自のライブラリ配置場所(\libraries)に入れます。


簡単な記述例1(1文字分のフォント取得)

#include <misakiUTF16.h>

void setup() {
  Serial.begin(115200);

  char font[8];              // フォント格納バッファ
  getFontData(font, "あ");   // "あ"のフォントを取得
  
  // 取得フォントの確認
  for (uint8_t row=0; row<8; row++) {
    for (uint8_t col=0; col<8; col++) {
       Serial.write( (0x80>>col) & font[row] ? '#':' ');
    }
    Serial.write('\n');
  }
}

void loop() {

}

実行結果

Test1

フォントデータの取得処理は、getFontData(font,"あ") のみで完了です。
後半のネストしているfor文は取得したフォントの確認用です。


簡単な記述例2(文字列分のフォントを繰り返し取得)

#include <misakiUTF16.h>

void setup() {
  Serial.begin(115200);

  char font[8];                       // フォント格納バッファ
  char *str="Abcあいうえお、埼玉";    // 文字列

  char *ptr = str;
  while(*ptr) {  // 文字列分ループ
     ptr = getFontData(font, ptr);   // 1文字分のフォント取得
     if (!ptr)
        break;                       // エラーの場合は終了
       
    // 取得フォントの確認
    for (uint8_t row=0; row<8; row++) {
      for (uint8_t col=0; col<8; col++) {
         Serial.write( (0x80>>col) & font[row] ? '#':' ');
      }
      Serial.write('\n');
    }
  }
}

void loop() {

}

実行結果

Test2

文字列に対しても、getFontData()関数で処理できます。
UTF8文字コードは可変バイト長なのですが、getFontData()関数は
次の文字へのポインタを返すので簡単に逐次取得処理を実装出来ます。

ちなみに、getFontData()関数の省略している第3引数にtrueを指定すると
半角文字は全角文字に変換してフォントデータを取得します。

こんな感じで、取得したフォントデータを使って、
LEDマトリックスグラフィック液晶への表示が出来ると思います。

« MSX用ゲームカートリッジの中身 | トップページ | OLED(SSD1306)で美咲フォントを使った漢字表示 »

日記・コラム・つぶやき」カテゴリの記事

arduino」カテゴリの記事

コメント

初めまして、ESP32にて+Adafruit 15x7 LEDにて、ありがたく日本語表示に使わせていただいています。

・質問
Fontに入っていない文字を追加する方法があれば、教えていただければ幸いです。
・背景
子供が自分で考えた文章を楽しそうに表示していたのですが、自分の知っている県や市を表示させようとしたところ、「沖縄の沖」や「仙台の仙」「浦和の浦」などが異なる漢字が表示されて、ガッカリしていました。そこで一部の漢字を追加したいのですが、そのような部分修正などはできますでしょうか?

※Adafruit 15x7 CharliePlex FeatherWing
https://learn.adafruit.com/adafruit-15x7-7x15-charlieplex-led-matrix-charliewing-featherwing/overview

Aoya-Utaさん、はじめまして

Arduino-misakiUTF16ライブラリへのフォント追加は少々面倒な作業となります。

別公開ライブラリ「Arduino用漢字フォントライブラリ SDカード版」使う方法もあります。
https://github.com/Tamakichi/Arduino-KanjiFont-Library-SD
ただし、Arduino-misakiUTF16ほどお手軽には使えないかもです。


といいつつ、簡単ではないですが、フォントの追加について説明いたします。

フォントデータはArduino-misakiUTF16ライブラリのmisakiUTF16FontData.hに定義しています。
フォントを追加する場合は、このファイルへの追記&修正が必要となります。

このファイルではデータの定義として、
1) static const uint8_t fdata[] :フォントデータ(1フォント当たり7バイト)
2)static const uint16_t ftable []:フォントコードテーブル(UTF16コード、コードの小さい順にソート)
となっています。
任意のフォントコードのフォントデータの取得の仕組みとしては、
①フォントコードで、フォントテーブルを検索して該当するフォントコードの格納位置(=インデックス)を調べる
②フォントデータからインデックスに該当するフォントデータ7バイトを取得する
 具体的には、fdata[インデックス*7] のアドレスから7バイトをフォントデータとして取得する
という流れです。

上記のテーブルの用途を理解した上で、フォントの追加につてい説明します。
例えば、"沖"のフォントデータを追加する場合、
①まずはその文字のユニコードを調べます(ユニコード 沖 でググれば調べらます)。
 "沖"のUTF16コードは6c96です。
②このコードをフォントコードテーブル_t ftable []に追加します。
 このテーブルはソートされている必要があるため、既存の0x6c7dと0x6cb3の間に追加します。
③追加した位置のインデックスを調べます
 1095となります。
 求め方としては、
 https://github.com/Tamakichi/Arduino-misakiUTF16/blob/master/misakiUTF16/misakiUTF16FontData.h
 を開いて"0x6c7d”で検索し、ソースコードの行番号 1014を取得。その後に挿入なので1095です。
878行からの定義とすると、1行あたり8バイトの定義のため、
 インデックス = (1014-878)*8+行内位置+1 = 136*8+6= 1094+1 = 1095
となりなす。
また、pythonをお使い可能であれば、
d = [
フォントコードテーブルのデータのコピペ
]
print(d.index(0x6c7d)+1)
で求められます。

③次に"沖"のフォントデータ7バイトを フォントデータ fdata[] に追加します。
 追加位置は、先頭から1095*7バイト目となります。
 7バイトデータは美咲フォントデータ(misaki_gothic.bdf)から抽出します。
 美咲フォントデータは、JISコードで格納されているため、 ユニコード0x6C96に対応するJISコードは322dのデータを取得します。
  0x88,0x3e,0xaa,0x2a,0xbe,0x88,0x88
 が得られます。
 このデータを、先頭から1095*7バイト目に追加します。
 これでいけると思いますが、検証していませんので、あくまでも参考程度の情報となります。

かなり面倒の作業かと思います。

実際の作成には、ツールを作成してフォント一覧から
1) static const uint8_t fdata[] :フォントデータ(1フォント当たり7バイト)
2)static const uint16_t ftable []:フォントコードテーブル(UTF16コード、コードの小さい順にソート)
を自動生成しています。

たま吉さん、
さっそくの回答、ありがとうございます!!!
まずは教えていただいたことを調べる所から始めてみます

たま吉さん、

misakiUTF16FontData.hへフォントの追加方法について、私の理解が合っているか、確認させてください。

◆現状
いただいた説明をもとに、misakiUTF16FontData.hを変更しましたが、まだ”沖”の追加までたどり着いておりません。
現状、”沖”は表示されず、正しく表示されていた文字もずれて別な文字になってしまいました。
※「このデータを、先頭から1095*7バイト目に追加します。」の理解が間違っている気がします。。


◆質問①
> 美咲フォントデータ(misaki_gothic.bdf)から抽出します。
>  美咲フォントデータは、JISコードで格納されているため、ユニコード0x6C96に対応するJISコードは322dのデータを取得します。
>   0x88,0x3e,0xaa,0x2a,0xbe,0x88,0x88
>  が得られます。

・美咲フォントデータ(misaki_gothic.bdf)の理解が間違っていれば、ご指摘ください。

1 .8×8 ドット日本語フォント「美咲フォント」のページより、下記ファイルをDown Load&回答し、中にある「misaki_gothic.bdf」を確認しました。
 X11 BDF 形式:https://littlelimit.net/arc/misaki/misaki_bdf_2021-05-05.zip 

2 .ファイル内にJISコードは322dのデータの記載が無かったため、ユニコード0x6C96に対応する”uni6C96”のBITMAPデータを確認し、「88,3E,AA,2A,BE,88,88」→「小文字化+先頭0x:0x88,0x3e,0xaa,0x2a,0xbe,0x88,0x88」を得ました。
==ここから:misaki_gothic.bdf(uni6C96抜粋)==
STARTCHAR uni6C96
ENCODING 27798
SWIDTH 1000 0
DWIDTH 8 0
BBX 7 7 0 0
BITMAP
88
3E
AA
2A
BE
88
88
ENDCHAR
==ここまで==


>  このデータを、先頭から1095*7バイト目に追加します。

以下のように理解し、misakiUTF16FontData.hを変更しました。

1. uint8_t fdata[] 先頭から1095*7バイト目 = 1095*7バイト目 = 7765バイト目に、0x88,0x3e,0xaa,0x2a,0xbe,0x88,0x88 を追加する
2. fdataは、1行に7バイト*2= 14バイトの定義があるため、「1095 / 14バイト = 78.2.. → fdataの78行目の7バイトデータの次に、0x88,0x3e,0xaa,0x2a,0xbe,0x88,0x88 を追加する

◆fdataの定義
#ifdef __AVR__
PROGMEM static const uint8_t fdata[] = {
#else // __AVR__
static const uint8_t fdata[] = {
#endif // __AVR__
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x40,0x40,0x40,0x00,0x40,0x00,
- 省略 -
92行目:0x04,0x04,0x68,0x2a,0x4a,0x3c,0x10,0x00,0x00,0x22,0x4a,0x4a,0x5a,0x24,
93行目:0x24,0x7e,0x40,0x7c,0x40,0x40,0x7e,0x88,0x3e,0xaa,0x2a,0xbe,0x88,0x88, ←ここにBITMAP追加
94行目:0x10,0x28,0x28,0x44,0x7c,0x82,0x82,0x7e,0x40,0x40,0x7c,0x42,0x42,0x7c,


◆ftableの定義
#ifdef __AVR__
PROGMEM static const uint16_t ftable [] = {
#else // __AVR__
static const uint16_t ftable [] = {
#endif
0x0020,0x0021,0x0022,0x0023,0x0024,0x0025,0x0026,0x0027,
- 省略 -
1013行目:0x6bcd,0x6bce,0x6bd2,0x6bd4,0x6bdb,0x6c0f,0x6c11,0x6c17,
1014行目:0x6c34,0x6c37,0x6c38,0x6c42,0x6c60,0x6c7a,0x6c7d,0x6c96, ←ここに0x6c96追加
1015行目:0x6cb3,0x6cb9,0x6cbb,0x6cbf,0x6cc9,0x6cd5,0x6ce2,0x6ce3,

たま吉さん、

お騒がせしました、無事に”沖”を追加&表示できました!ありがとうございました!
これで子供にも続けて遊ばせることができそうです :)

◆理解補足
> まずは"沖"のUTF16コードは6c96をフォントコードテーブル_t ftable []に追加します。 このテーブルはソートされている必要があるため、既存の0x6c7dと0x6cb3の間に追加します。
> - 中略 -
> ユニコード0x6C96に対応するJISコードは322dのデータを取得します。
>  0x88,0x3e,0xaa,0x2a,0xbe,0x88,0x88
> このデータを、(フォントデータ fdata[] の)先頭から1095*7バイト目に追加します。


以下のように修正したら、”沖”が表示できるようになりました。

・fdataは、1行に7バイト*2= 14バイトの定義があるため、「1095 ÷ 2文字定義/1行 = 547.5
→ fdataの547行目から548行目あたりにある”0x6c7d(のBITMAP定義:0xa0,0x3e,0xd8,0x3c,0x84,0x84,0x82)”の次に、(沖:0x6c96のBITMAP定義:)0x88,0x3e,0xaa,0x2a,0xbe,0x88,0x88 を追加する

Aoya-Utaさん

ご報告ありがとうございます。
あの情報で、追加出来たとはなかなかの技量ですね~

美咲フォント 最新版 X11 BDF 形式は、unicodeになったんですね。知りませんでした。
このライブラリは作成してから6年は経過しているので、そろそろ見直しが必要かもです。
arduinoの新ライブラリ形式にしたりなど..

たま吉さん、

> このライブラリは作成してから6年は経過しているので、そろそろ見直しが必要かもです。

おお、新しい対応にも期待してます ^o^
デバッグサポートしますよー。私は主にM5Stack系(ESP32)で電子工作してます。

このサイトを参考にさせていただいたおかげで、Tiny LED Clipができました!とっても感謝しております。これからの投稿も楽しみにしております :)
・ちんまりLEDクリップ:Tiny LED clip
https://protopedia.net/prototype/3264

コメントを書く

(ウェブ上には掲載しません)

トラックバック


この記事へのトラックバック一覧です: Arduino用フォントライブラリを更新しました:

« MSX用ゲームカートリッジの中身 | トップページ | OLED(SSD1306)で美咲フォントを使った漢字表示 »