点阵字体的旋转
最近由于工作原因一直在編寫熱敏打印應(yīng)用相關(guān)的代碼,其中就涉及到中文打印。對于中文打印大概涉及三個方面的內(nèi)容:中文輸入、漢字編碼與轉(zhuǎn)碼、點陣字體的處理。對于這三個方面涉及的知識還是挺多的,在此就對點陣字體相關(guān)的內(nèi)容做一個小結(jié)。
一、點陣字體概述
做過單片機(jī)點陣開發(fā)的同學(xué)肯定不會陌生,對于16x16的點陣,當(dāng)某些位點亮某些位熄滅時就可以顯示文字或圖片。對于點陣字體其實就是將這些位的亮滅信息保存在一個數(shù)組里,將所有字的這些信息都這樣存儲起來就形成了一個字庫文件。根據(jù)保存信息的不同形成不同的字庫,如HZK16,HZK24,HZK32。
如下HZK16單個字的存儲:
const unsigned char acFontHZKaiTi_16_b0de[32] = {??
________,_X______,
_____X__,_X______,
____XX__,X_XXX___,
__XXX__X,XX__X___,
____X__X,_XX_X___,
___XXX_X,_X__X___,
XXX_X__X,XXXX____,
___XX___,X_X_____,
__X_XX__,X_XXXXX_,
__X_X_XX,XXX_____,
_X__X___,__X_____,
X___X___,__X_____,
____X___,__X_____,
____X___,__X_____,
________,__X_____,
________,________,
};
二、點陣字體的顯示
點陣字體的顯示比較簡單,只需將每個字節(jié)信息中的每一位按需求顯示或不顯示就行了,直接上代碼(以HZK16為例):
static VOID PrintHzk16Font(UINT8* fontDat)
{
?? ?INT i, j, b;
?? ?UINT8 byte;
?? ?if (fontDat != NULL)
?? ?{
?? ??? ?for (i = 0; i < 16; i++)
?? ??? ?{
?? ??? ??? ?for (j = 0; j < 2; j++)
?? ??? ??? ?{
?? ??? ??? ??? ?byte = fontDat[i*2 + j];
?? ??? ??? ??? ?for (b = 7; b >=0; b--)
?? ??? ??? ??? ?{
?? ??? ??? ??? ??? ?if (byte & (1<<b))
?? ??? ??? ??? ??? ?{
?? ??? ??? ??? ??? ??? ?printf("*"); ?//show
?? ??? ??? ??? ??? ?}
?? ??? ??? ??? ??? ?else
?? ??? ??? ??? ??? ?{
?? ??? ??? ??? ??? ??? ?printf(" "); //hide
?? ??? ??? ??? ??? ?}
?? ??? ??? ??? ?}
?? ??? ??? ?}
?? ??? ??? ?printf("\n");
?? ??? ?}
?? ?}
}
三、點陣字體的旋轉(zhuǎn)
點陣字體的旋轉(zhuǎn)其實就是取出數(shù)組中的某個元素的某一位保存在數(shù)組中的另外某個元素中的某一位中,根據(jù)旋轉(zhuǎn)方式的不同讀取和保存的方式都不一樣。在此以HZK16字體旋轉(zhuǎn)為例:
#define GET_BIT(src, n) ((src) & (0x01 << (n)))
#define SET_BIT(dst, n) ((dst) |= (0x01 << (n)))
/*
第一列 ? ? ?第二列
________, ________,
______XX, XXXXXX__,
XXXXX_XX, XXXXXX__,
XXXXX_XX, _XX_XX__,
__XX__XX, XXXXXX__,
__XX__XX, _XX_XX__,
XXXXX_XX, _XX_XX__,
XXXXX_XX, XXXXXX__,
前八個字節(jié)
__XX__XX, XXXXXX__,
__XX____, _XX_____,
__XX____, _XX_____,
__XXX_XX, XXXXXX__,
XXXXX___, _XX_____,
XX___XXX, XXXXXXX_,
_____XXX, XXXXXXX_,
________,________,
后八個字節(jié)
劃分為四塊,然后一塊一塊的處理
*/
static VOID RotateHzk16Font(UINT8* dst, UINT8* src)
{
?? ?int i, j;
?? ?if (NULL == src || NULL == dst)
?? ?{
?? ??? ?e_WARN("src is null.\n");
?? ??? ?return;
?? ?}
?? ?bzero(dst, FONT16X16_BUF);
?? ?//第一列后8個字節(jié)
?? ?for (i = 0; i < 8; ++i)
?? ?{
?? ??? ?for (j = 0; j < 8; ++j)
?? ??? ?{
?? ??? ??? ?if (GET_BIT(src[16+j*2], 7-i))
?? ??? ??? ?{
?? ??? ??? ??? ?SET_BIT(dst[i*2], j);
?? ??? ??? ?}
?? ??? ?}?? ??? ?
?? ?}
?? ?//第一列前8個字節(jié)
?? ?for (i = 0; i < 8; ++i)
?? ?{
?? ??? ?for (j = 0; j < 8; ++j)
?? ??? ?{
?? ??? ??? ?if (GET_BIT(src[j*2], 7-i))
?? ??? ??? ?{
?? ??? ??? ??? ?SET_BIT(dst[1+i*2], j);
?? ??? ??? ?}
?? ??? ?}?? ??? ?
?? ?}
?? ?//第二列后8個字節(jié)
?? ?for (i = 0; i < 8; ++i)
?? ?{
?? ??? ?for (j = 0; j < 8; ++j)
?? ??? ?{
?? ??? ??? ?if (GET_BIT(src[17+j*2], 7-i))
?? ??? ??? ?{
?? ??? ??? ??? ?SET_BIT(dst[16+i*2], j);
?? ??? ??? ?}
?? ??? ?}?? ??? ?
?? ?}
?? ?//第一列前8個字節(jié)
?? ?for (i = 0; i < 8; ++i)
?? ?{
?? ??? ?for (j = 0; j < 8; ++j)
?? ??? ?{
?? ??? ??? ?if (GET_BIT(src[1+j*2], 7-i))
?? ??? ??? ?{
?? ??? ??? ??? ?SET_BIT(dst[17+i*2], j);
?? ??? ??? ?}
?? ??? ?}?? ??? ?
?? ?}
}
其實對于字體的旋轉(zhuǎn)可以寫一個通用的算法適合任何字體的旋轉(zhuǎn),在此就不具體實現(xiàn)了。大概的思路是:根據(jù)字體的大小確定旋轉(zhuǎn)后的空間大小,注意如果字體的寬高不一樣的話旋轉(zhuǎn)后的空間可能會大于原字體的存儲空間,然后八個字節(jié)八個字節(jié)的批量處理。
總結(jié)
- 上一篇: 保姆级教程—部署SpringBoot项目
- 下一篇: [《命如草贱》偶感小记]2013-2-1