ストロークフォントを使って PlotClock で文字を描く

ペンプロッターで使うようなストロークフォントがあれば、PlotClockで文字が描けるかも!と思って検索してみると、まさにピッタリのフォントデータが公開されてました!

KST32B:極めてコンパクトなJIS第1,2水準漢字他のStrokeFont(KST)
https://www.vector.co.jp/soft/data/writing/se119277.html

フォントデータ一覧はこちらのサイトでまとめてありました。

KST32B JISコード 文字一覧
https://domisan.sakura.ne.jp/article/cadfont/kst32b.html

フォントデータの内容はこういう感じです。

バイナリのフォントデータを、視認可能なS-JISテキスト(半角カナ含む)に変換して保持しています。

先頭「*」はコメント行です。最初の列は JISコード。

実際のデータを確認してみます。0041 (半角「A」)のデータはこういう感じ。

フォントデータの最初のところに、データの読み方説明があります。

00 区切り文字
21~26、28~3F X位置を 0~29に移動
40~5B、5E~5F 現在位置からX位置 0~29に線を引く
60~7D 「次のX位置」を 0~29に移動
7E、A1~BF Y位置を 0~31に移動
C0~DF 現在位置から「次のX位置」、Y位置 0~31に線を引く

さきほどの「A」のデータを読んでみます。20~20の間がフォントデータですね。

21 A3 67 DC 6E C3 24 AC 4B

これを解読すると、

21 X位置を0に
A3 Y位置を3に
67 次のX位置を7に
DC Y位置28 (0,3)-(7,28)に線を引く
6E 次のX位置を14に
C3 Y位置3 (7,28)-(14,3)に線を引く
24 X位置を3に
AC Y位置を11に
4B X位置11 (3,11)-(11,11)に線を引く

このとおりに線を引くとこういう感じです。

逆向きで「A」が出てきました!左下を(0,0)として処理すれば良さそうです。


フォントデータは、S-JISのテキストファイルなので、このままだと Arduino から扱うのが難しいです。
バイナリデータ部分を展開して、Cのヘッダファイル形式に変換するためのスクリプトを Python で作成しました。

変換スクリプトはこちら。

Plotclock / PlotFont / tools /
https://github.com/shikarunochi/Plotclock/tree/main/PlotFont/tools
makeFontData.py

python makeFontData.py KST32B.TXT fontData.h

これでヘッダファイルが生成されます。

ヘッダファイルは「フォントデータ本体」「フォントデータへのポインタ配列」「UTF-16コード変換用配列」で作られています。
全データを変換すると、M5Atom に転送できるサイズを超えてしまったので、JISコード 0x5000 未満のもののみ変換対象としています。


M5Atom側のプログラムは、表示用文字列を順に UTF-16 に変換、対応するフォントデータを取得、フォントデータを展開して線を描画、という流れになっています。

プログラムはこちらです。

Plotclock / PlotFont / PlotFont /
https://github.com/shikarunochi/Plotclock/tree/main/PlotFont/PlotFont

さきほど生成したフォントファイルも含まれています。


最初は「HELLO WORLD」から!

読める…読めますよね!(この時はまだロジック間違ってて「H」が細くなってしまった。)

ちなみに、M5StickC の Cozmo 風な顔表示は、ESP32_Faces です。かわいい!

luisllamasbinaburo / ESP32_Faces
https://github.com/luisllamasbinaburo/ESP32_Faces


漢字にも挑戦!

読めますか…!全集中で読んでください!


まだいろいろ足りないのですが、ひとまずは動作したので満足ですー。

表示テキストデータのUTF-16コード変換の部分は、たなかまさゆきさんの eFontソースを参考にさせていただきました!

tanakamasayuki / efont
https://github.com/tanakamasayuki/efont

“ストロークフォントを使って PlotClock で文字を描く” への2件の返信

  1. 21~26、28~3F
    単純な疑問ですが、なぜ27を飛ばしたのですか?

  2. たしかに、なぜでしょうね。そのあたり特に気にせず、そういうもんなんだな~って思って仕様通り実装してましたw
    0x27 は「’」なので、使用を避けたかった…のかもしれないですね。