マイコンでフォントを読み込む私的方法をご紹介致します。
こちらから16×16ドットフォントファイルを入手。
このファイルの中身を説明すると例えば”1”という文字はテキストで以下のように表記されています。
STARTCHAR 01-03-17
ENCODING 9009
SWIDTH 1024 0
DWIDTH 16 0
BBX 16 16 0 -2
BITMAP
0000
0100
0300
0500
0900
0100
0100
0100
0100
0100
0100
0100
0100
0100
07c0
0000
ENDCHAR
STARTCHAR 01-03-17というのは
シフトJISの2バイトコード(全角文字)のエリアマップの03区の17点に”1”があるということを示しています。
BITMAPとENDCHARの間の数字群が”1”という文字自体のデータです。
例えば下から2行目の"07c0"は2進数で
"0000 0111 1100 0000"と書けます。
これを一番上の行から順番にやってみると・・・
0000000000000000
0000000100000000
0000001100000000
0000010100000000
0000100100000000
0000000100000000
0000000100000000
0000000100000000
0000000100000000
0000000100000000
0000000100000000
0000000100000000
0000000100000000
0000000100000000
0000011111000000
0000000000000000
みての通り”1”です。
このデータのことをここではイメージデータと呼ぶことにしましょう。
このフォントファイルにはエリアマップの順番通りに文字情報が並んでいます。
そのため任意の文字が一番初めの文字から数えて何番目からあるのかがSJISコードから計算できます。
だからイメージデータ以外はいりませんね^^;
ということで、イメージデータのみを残してそれをバイナリに変換するプログラムを作りました。
それで変換したファイルが
これ(16f.hf)
2011/3/13追記:アシッドさんのご指摘点(下位7eの列が全部NULLになる)を修正いたしました。
バイナリエディタでみるとこんな感じです。
赤で囲った部分が”1”のイメージデータと同じだとわかると思います。
青で囲った部分からこのデータはファイルの先頭から1byte単位で数えて19C0(十進数で6592)番目にあることがわかります。
一文字は32byteなので206番目の文字ですね。
先ほどの
シフトJISの2バイトコード(全角文字)のエリアマップを見てください。
206番目に”1”がありますね。
任意の文字が何番目にあるのかをSJISコードから計算する式は表と数分にらめっこして考えました(笑
id=(chara[0]-0x81)*189+(chara[1]-0x40);//SIFT-JISコードから文字の位置を割り出すchara[0]が文字コードの上位ビット
chara[1]が文字コードの下位ビット
一文字目ならばid=0、100文字目ならばid=99といった具合です。
まあ、なぜこうなるのか気になる方は表とにらめっこしてください。
ちなみに私はにらめっこしてるところを母親に後ろから見られて『意味わからない』といわれましたwww
以上のように16f.hfを入手して何番目になんの文字があるのか計算できれば任意のイメージデータを得ることができます。
余談ですが、拡張子がhfは私の名前にちなんでいます。はい、どうでもいいですね^^
今回、私はSDカードに16f.hfを保存してマイコンから読み取り液晶に表示することに挑戦しました。
プログラムはこんな感じです。(説明は面倒なので投げますwwwごめんなさいw参考までに^^)
int main(void){ f_mount(0, &Fatfs[0]);//SDカードをマウント f_open(&File_f,"16f.hf",FA_READ);//フォントファイルオープン backcolor(0x00);//バックを黒色に arrow(RED,100,0,ABOVE);//上矢印 arrow(RED,199,24,RIGHT);//右矢印 arrow(RED,0,24,LEFT);//左矢印
arrow(RED,100,47,UNDER);//下矢印
printdisp(ORANGE,"上下キーで選択してね♪",7,16);//文字列読み込み while(1){ repaint(1);//液晶に描画 }//while f_close(&File_f);//ファイルクローズ f_mount(0,NULL);//ドライブをアンマウント}//mainvoid printdisp(vu8 rgbs,char *st, s16 x, s16 y){u8 i=0,num=0; while(st[i]){//バイト数カウント i++; } i>>=1;//一文字2バイトだから1/2する for(num=0;num<i;num++){//一文字ずつに分けて読み込む sd_font(rgbs,&st[num<<1],x+num*16,y); }}void sd_font(vu8 rgbs,char *chara,s16 sx,s16 sy){UINT kz;u16 id;u8 x,y,i;u8 font[16][2];
id=(chara[0]-0x81)*189+(chara[1]-0x40);//SIFT-JISコードから文字の位置を割り出す f_lseek(&File_f,32*id);//文字の位置までシーク f_read(&File_f,font,32,&kz);//文字の読み込みfor(y=0;y<16;y++){//画面配列に書き込む for(x=0;x<2;x++){ for(i=0;i<8;i++){ if(font[y][x]&(0x80>>i)){ input_rgb(rgbs,sx+i+8*x,sy+y); } }//for_i }//for_x}//for_y }実行結果(文字表示サイズ2倍)
にょろり~ん。きりがいいのでそーろそろ卒研モードに入りま~す。
といっても両方とも進めることになることになると思いますがwww
もちろん卒研に重みをおくということですよ~
質問や要望があったらお気軽にぞうぞ~
これからこんなことをしたい人がいたら力になりたいです。