« 雑誌付録の32ビットプロセッサー | トップページ | 8ドット漢字電光ニュース »

2008年9月 6日 (土)

美咲フォントの高速アクセス

任意の漢字フォントの表示に成功(6/21/08)
 SDカードに入っている美咲フォントのBDFフォントファイルは、ANK(半角1バイトコード)は20Kバイトそこそこだが、2バイトコードの漢字フォントファイルは400Kを越す。このフォントの実用性を確認するには、色々な漢字フォントを表示させて調べたいのだが、シーケンシャルに読んでいるだけでは効率が悪い。コードを入力するかターミナルから任意の漢字を送って表示させたい。

 しかしFatFSはMega168を継承しているので、TinyFatFSがベースであり、速度が遅く、ブロックで読むときは結構早いが、ちまちまと読んでいると、20Kを読むのに5 秒近くかかり、400Kだと2分近くかかってしまう。ただ、上位のFatFSでどれだけ速くなるかわからないので、更新をする気にはならない。

 はじめ、コンソールからPCが使っているシフトJIS漢字を直接送って表示させようとしたが、BDFファイルの漢字コードはJISで、シフトJISからJIS漢字への変換は、そう簡単でないことを知る。フォントを調べるのが目的なので、最初は開発しやすいコード入力で表示させることにする。

 これが結構面倒なのである。1バイトコードの方は、入力文字からコードを生成してサーチしており、2バイトコードと入力ルーチンを同じにしたので、その区別が難しい。C言語の文字列と配列の取り扱いが微妙に違い、関数によっては、文字列の最後にNULLだけでなく改行コードが入っていたりする。しかも16進のキャラクタ表示は、aとAではコードが違うので逆変換のときは気を使う。BDFファイルが小文字で全部書かれていることを信じて開発を進める。Ws000000

 数時間かけてやっと、コンソールからJISコードを入力すれば漢字が表示されるようになった。しかし、頭から読んでいるので、後半の第二水準の漢字ひとつをだすのにやはり1分以上かかることがわかる。こうなると意地でも何とかしてやろうと、こだわってしまうのが悪い癖だ。電光掲示板に漢字を表示させるのが目的なのだが、全然別の方向にエネルギーを使ってしまう。まあこれが楽しみでやっているようなものだから、暫く時間を費ってみた。

 思いついたロジックは、昔で言う、インデックスシーケンシャル方式(ISAM)である。頭から読むのでなく、コード番号とファイルのポインタのテーブルを作り、ファイルを途中から読んで目的のフォントに辿りつこうというものである。構造体を定義して、早速テーブルを作る。昔取った杵柄(きねづか)である。参考書は20年前のPCのC言語の参考書。

 くどいけれど、プログラムは考えたようには動いてくれない。構造体のテーブルの中の定数宣言も、昔のことで自信がない。こんな感じだったかなと手探りでコーディングする。恐る恐るコンパイルしてみた。これが不思議なことに一発で通る。調子に乗って動かしてみた。

 おお、想定どおり動いている。ファイルポインタの数もちゃんと関数に入っているようだ。用心してテストステートメントを詳しく入れてあったのでデバッグはすぐ済んで、第二水準の漢字まで、5秒以内に表示されるようになった。素晴らしい。成功の余韻にひたる。

 うむ、腕は落ちていないようだな。でも出来上がったものは、単にコードをキャラクタで入力すれば、その漢字が表示されるだけで、次のステップに進めるものではない。冒険物語はこれからが勝負だ。

漢字ファイルの高速化(6/29/08)
 先週、シフトJISとJIS漢字の変換ロジックをWebで偶然発見した。 20年近く前、パソコン通信が始まった頃、同じようなプログラムを組んだ記憶があるが当然資料など残っていない。判じ物のようなロジックだったが正直にコーディングしたら見事に変換した。それにしてもWebの情報はありがたい。これで残っているのは、連続した1バイト、2バイトコードが混在したテキストの表示である。これが最終ゴールに近い。

 次の朝、コーヒーを飲みながら構想を固め、コーディングを開始する。文字列とポインタの操作に慣れてきたので、コーディングが早い。かみさんの買い物につきあって帰ってきた午後遅くから夕食までの数時間で完成した。調子の良いときはこういうものである。一発で通る。漢字かな混じりの長文の文章でもフォントが次々に表示される。

 見ていた次女が、薔薇(ばら)、顰蹙(ひんしゅく)などの複雑な漢字のフォントを表示させて大笑いしている。まあ殆ど読めないが、8ビットフォントでこれだけ雰囲気が出てくるのはたいしたものだ。文脈があれば、難しい漢字でなければそこそこ読めることがわかった。これなら電光掲示板にしても大丈夫なようだ。

 これでほぼ予定していた必要な機能が実現した。あとはこれにLEDマトリックスのプログラムを合わせてやれば、任意のテキストを表示する電光掲示板が完成する。

 と、気楽に書いていたのが数日前。 しかし、これがかなり手強いのである。現在のフォントファイルは500Kバイト近いテキストベースの漢字フォントファイルで、インデックスをつけていくら早くなったとしても一字取り出すのに数秒かかる。従って、手順としては、これをフォントデータ(グリフというのだそうだ)だけのバイナリに変換し(元のファイルはグリフもキャラクタ)、漢字コードによるダイレクトアクセスでそのフォントが得られるファイルにしないと実用にならない(やや本気)。

 そのとき同時に、LEDマトリックスのダイナミック表示のために、通常、横方向に入っているフォントデータを、縦方向に変換して収容しておきたい。この行列の転置プロセスが一筋縄ではいかないのである。

 かなり考えた挙句のロジックなのだが思い通りの結果が出ない。仕方がないので、ひとつひとつUARTで途中経過を表示させてみて初めて、大きな勘違いをしていることに気がついた。ロジックに自信を持って疑いもしていなかった自分に恥じ入る。思い込みというものは恐ろしいものである。行から列に変換するのだから、各行のデータはその列のデータを足しこんでいくだけで出来ると考えていた。あとから考えればそんな簡単なことではなく、各列の位置に応じたマスクをかけてひとつひとつ拾って行かないと正しいフォントグリフにならないのだが、これに気づいていなかった。

 8ビットのマスクデータを移動させるロジックを追加しやっと横方向のフォントが縦に見えるようになった。勢いに乗って1バイトコードだけはEEPROMに全部入れてしまう。これはこれまでのロジックを活用して簡単に出来上がった。矢のように表示されるANKコードを見て満足する。

 最後の2バイトの漢字ファイル変換も難関だった。7000字もあるのでとりあえず100文字程度のデータを変換するプログラムを作る。しかし、SDカードの書き込みがうまくいかない。最初、リターンコードを勘違いして(FatFSの1文字書き込み関数は今までの関数と違ってリターンコードに書いた文字データが返ってくる)、悩んでいたがそれを直しても動かない。書く文字は1バイト単位なのに型はint(2バイト)というのが良く分からない。文字列ならどうだと文字列関数を試すがこれも動かない。ソースを良く見てみたら動かないと悩んでいる一文字関数を使っているので全くの無駄であることを知る。

 書き込みは前に動いていることを確認しているので、結局この関数を使うことを諦め、元の原始関数の方でやってみたら、不思議なことに一発で動いてしまった。これで半日はつぶれてしまった。動いた勢いで、表示部を仕上げて、「あいうえお」と入力し、正しくフォントが出てくることを確認した。表示速度も前のキャラクタファイルをちまちま順次読んでいたのに比べ圧倒的な速さでEEPROM並みである。コンソールの前で思わずガッツポーズしてしまう。

 勢い込んで、7000文字の変換に移る。1分少々で全部終了。これで終了と鼻を高くしたが、少し不安になり念のため漢字かな交じり文を表示させてみる。やっぱり、そうは問屋はおろさなかった。目茶目茶なフォントが入っている。途中でおかしくなってくるようだ。がっくり肩が落ちる。

 いちから出直しである。相手は7000字。気の遠くなるような数字である。気持ちを強く持ってバイナリエディタなどを持ち出して少しづつ調べ始める。正しい位置に所定のデータが入っているところもある。ロジックはもう間違ってはいないようだ。そうだとするとファイルの位置を決めるポインターがオーバーフローして上書きしている可能性が高い。

 しかしファイルポインタは4バイトもとってあり、この程度のファイルサイズでは超えるわけはない(32ビットは4ギガ、40億バイト)。他のところもみな2バイト(3万から6万)で問題ないはずだ。

 Ws000001 登録文字数を少しづつ増やして中身を表示させることにした。1500字を越えたところで、ファイルポインタが64540から1104になることを発見する。やった。これが原因だ。しかし、どうして4バイトもあるのにオーバーフローする? すぐ原因がわかった。2バイトデータを上へ8ビットシフトして4バイトに入れているのだが、シフトするときはデータをあらかじめ4バイトに入れておかないといけないようである。

 正しくポインターが増えていき、これで全部正しく入ったと喜んだのも束の間、調べていく間にデータがおかしい文字を発見、再びがっくりする。しかし、バイナリエディタで見るとデータは正しい場所に入っている。今度の容疑者はシフトJISからの変換ロジックである。しかし、見たところ間違っていない。このあたりで本日の根が尽きる。

 まあ、殆どの漢字は正しく表示されるので、じっくりバグをつぶしていこう。あせってデバッグして上手くいった例(ためし)はない。

デバッグの醍醐味(6/30/08)
 仕事は週2日やることにしていて、今日は出番の日。お客さんが来たり、打ち合わせの準備をしたり、会合の司会をしたりして久しぶりに忙しかった。今日のお客さんは昔勤めていたITベンチャー企業の友人で偶然にもインドの組み込みコンピューター会社の売り込みで話が弾む。私が趣味で組み込み系にはまっていると聞いて彼らは大笑い。ホビーの需要を市場は将来期待していると聞き大いに意を強くする。

 そうなのだ。この面白さは私だけではもったいない。もう少し広がってもおかしくない世界だと思う。これだけ驚異的に進歩した技術の恩恵はアマチュアでも享受すべきだと思うし、それが可能になってきた、などと風呂敷を広げているのは、ほかでもない、昨日あんなに悩んだ問題があっさり片付いたからである。深夜なのでヘッドフォンでお気に入りのクラシックを聞きながら、満足感にひたってこの記録を書いている。

 漢字ファイルをバイナリに変換して表示するプログラムは一応データが全部入ってそれらしい表示が出来るようになったが、依然として一部の漢字が化けて頭を抱えていた。こういうときは基本からひとつひとつ検証して調べていくしかない。気を取り直し、別のプログラムからファイルを読んでみようと、以前コード入力で正常に動いていたプログラムにバイナリファイルのアクセスを追加して調べることにした。

 ところが、元のコードを新しいプログラムへコピー&ペーストをしているときに思いがけないものを発見した。何と何と、データの読み込みのアドレス計算のところはオーバフローの修正がされていない。やれやれ、読み込みのところの修正をすっかり忘れている。これでは折角正しい位置にデータを入れても正しく読めないのは当たり前だ。意気込んでとりかかったけれどあっというまに解決してしまった。

 これを修正して漢字ファイルの高速アクセスは完全に実現した。時間を測ってみる。1字あたり2ms台、キャラクタベースのアクセスの秒レベルとは比較にならない。いや、素晴らしい。デバッグの醍醐味は問題が解決したときである。頂上を極めた登山家や、42キロを完走したマラソンランナーの幸福感と同じである。本当に安い娯楽である。

|

« 雑誌付録の32ビットプロセッサー | トップページ | 8ドット漢字電光ニュース »

電子工作」カテゴリの記事

コメント

コメントを書く



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


コメントは記事投稿者が公開するまで表示されません。



トラックバック


この記事へのトラックバック一覧です: 美咲フォントの高速アクセス:

« 雑誌付録の32ビットプロセッサー | トップページ | 8ドット漢字電光ニュース »