漢字是方塊字,寬高相等的漢字型檔在嵌入式領域有著廣泛的應用,且其解析也相對來說是比較簡單的。
漢字在漢字型檔中的索引一般會遵循GB2312/GBK編碼規則,GB2312/GBK規定漢字編碼由2個位元組組成,其中低位元組區碼,高位元組為位碼。本文以最常見的UCDOS中16x16的宋體字型檔HZK16來示範漢字的顯示方法,HZK16中漢字的存放基於GB2312編碼的順序,每個漢字的點陣資料佔32個位元組,每個位元組表徵8個點的狀態,每行從左至右的點的狀態分別對應位元組從高到低的位值。
下面提供完整的示範程式以供參考,
#include <stdio.h>#define FONT_SIZE(16)/* 字型大小 *//* 擷取漢字在漢字型檔中的索引位置 根據GB2312/GBK編碼規則,漢字的低位元組hz[0]是區碼,高位元組hz[1]是位碼,漢字型檔從區位碼0xa1a1開始存放漢字*/#define HZ_INDEX(hz)((hz[0] - 0xa1) * 94 + (hz[1] - 0xa1))#define DOTS_BYTES(FONT_SIZE * FONT_SIZE / 8)/* 漢字點陣資料所佔的位元組數 */int main(int argc, char* argv[]){FILE* hzk;unsigned char song[2] = "\xcb\xce";/* “宋”字的區位碼為0xcbce */unsigned char dots[DOTS_BYTES];unsigned char b;int i, j, k;/* 開啟漢字型檔hzk16,並從中提取“宋”字的點陣資料 */if((hzk = fopen("hzk16", "rb")) == NULL){return -1;}fseek(hzk, HZ_INDEX(song) * DOTS_BYTES, SEEK_SET);fread(dots, sizeof(unsigned char), DOTS_BYTES, hzk);fclose(hzk);/* 用“*”號根據點陣資料顯示“宋”字 */for(i = 0; i < FONT_SIZE; i++){/* 每行共FONT_SIZE / 8個位元組 */for(j = 0; j < FONT_SIZE / 8; j++){b = dots[i * 2 + j];/* 從左至右的點分別對應位元組從高到低的位值 */for(k = 0; k < 8; k++){if(b & 0x80)printf("%c ", '*');elseprintf(" ");b <<= 1;}}printf("\n");}return 0;}
程式編譯運行後會出現如下的顯示效果,
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *