グラフィックLCDにFONTX2 読み込み

2016年9月22日

FONTX2のフォントリーダーを作りました。参考にしたのは以下のHP。
FONTX構造体解説
FONTX2形式のファイルをマイコンで利用する。
メモリ上のフォントを検索して、そのトップアドレスを取るのですが、組み込みでは全然全くメモリが足りません。SD-CARDにフォントを入れて、そこから表示するように変更しました。
fopen とかの関数は、他のシステムでも同様なはずです。bit列の並びとか大変苦労しました。出来るだけ原型のプログラムを残しつつとか。関係ないバグが出ないようにです。とりあえず動いてから考えるということです。
追記:も少し処理を早くしたいですねぇ。ちょっと変えればすぐに早くなる気がします。

// ----------------------------------------------------------------------------
//
// ----------------------------------------------------------------------------
BOOL fsread(UINT8 *dest, FSFILE *fp, size_t size, size_t n, long offset)
{
if(FSfseek(fp, offset, SEEK_SET) != 0) { return FALSE; }
if(!FSfread(dest, size, n, fp)) { return FALSE; }
return TRUE;
}
UINT8 m_font_buff[(32 / 8) * 32];
// ----------------------------------------------------------------------------
// 例として下のリストに、メモリ上に置かれたFONTXファイルから指定された文字コードのフォントを得る関数を示します。
// 引数にはFONTXデータと文字コードを指定し、指定された文字コードに対応するフォントイメージを指すポインタを返します。
// 文字コードが無効なときは0を返します。
// ----------------------------------------------------------------------------
int get_font (   /* Returns pointer to the font image (NULL:invalid code) */
FSFILE *fp,
UINT16 code           /* Character code */
)
{
INT32 nc, bc, sb, eb, fsz, cb, wf, hf, of, ret;
UINT8 *cblk = m_font_buff;
UINT8 *font = m_font_buff;
if(!fsread(font, fp, 19, 1, 0)) {
return 0;
}
wf = m_font_buff[14];
hf = m_font_buff[15];
fsz = (font[14] + 7) / 8 * font[15];  /* Get font size */
if (font[16] == 0) {  /* Single byte code font */
if (code < 0x100)
return 17 + code * fsz;
}
else {              /* Double byte code font */
cb = font[17];
bc = font[17];
nc = 0; of = 18; /* Code block table */
while (bc--) {
if(!fsread(cblk, fp, 4, 1, of)) { return 0; }
sb = cblk[0] + ((UINT32)cblk[1] << 8);  /* Get range of the code block */
eb = cblk[2] + ((UINT32)cblk[3] << 8);
if (code >= sb && code <= eb) {  /* Check if in the code block */
nc += code - sb;             /* Number of codes from top of the block */
ret = 18 + 4 * cb + nc * fsz;
if(!fsread(font, fp, fsz, 1, ret)) { return 0; }
return ret;
}
nc += eb - sb + 1;     /* Number of codes in the previous blocks */
of += 4;
}
}
return 0;   /* Invalid code */
}
// ----------------------------------------------------------------------------
//
// ----------------------------------------------------------------------------
BOOL LCD_print_string_fontx(const char *font_name, int pos_x, int pos_y, const UINT16 *str,
unsigned short fcoler, unsigned short bcoler)
{
FSFILE *fp;
int x, y, i;
int wf, hf;
UINT16 code;
UINT8 line;
if(!FSInit()) {
return FALSE;
}
fp = FSfopen(font_name, READ);
if(fp == NULL) {
return FALSE;
}
if(!fsread(m_font_buff, fp, 1, 18, 0)) {
FSfclose(fp);
return FALSE;
}
code = m_font_buff[16];       // 1:Shift-JIS
if(code != 1) {
FSfclose(fp);
return FALSE;
}
wf = m_font_buff[14];
hf = m_font_buff[15];
if(wf > 32 || hf > 32) {
FSfclose(fp);
return FALSE;
}
while(TRUE) {
if(*str == 0x0000) { break; }       // Shift-JIS code struct
// get shift jis code font top
if(!get_font(fp, *str++)) {
FSfclose(fp);
return FALSE;
}
DIR_ADRESS_BUS_OUT();
LCD_CS = 0;
i = 0;
for(y = 0; y < hf; y++) {
for(x = 0; x < wf; x++, i++) {
if(i % 8 == 0) {
line = m_font_buff[i / 8];
}
if((line >> (7 - (i % 8))) & 0x01) {
LCD_write_pixel(pos_x + x, pos_y + y, fcoler);
}
else {
if(bcoler != CLEAR) {   // 背景なし?
LCD_write_pixel(pos_x + x, pos_y + y, bcoler);
}
}
}
}
pos_x += wf;
LCD_CS = 1;
DIR_ADRESS_BUS_IN();
}
FSfclose(fp);
return TRUE;
}