非漢字系統下漢字的打印輸出
發表于:2007-07-14來源:作者:點擊數:
標簽:
[摘要]介紹了在無漢字字庫的打印機上,無需啟動漢字操作系統打印漢字的方法,并給出了非漢字系統下打印輸出含有漢字的文本文件的實用VC++源程序。 [關鍵詞]漢字打印,Zebra系列, VC++語言,24*24點陣字庫,文本文件 電腦用戶中,有相當一部分用戶的打印機不帶漢字
[摘要]介紹了在無漢字字庫的打印機上,無需啟動漢字操作系統打印漢字的方法,并給出了非漢字系統下打印輸出含有漢字的文本文件的實用VC++源程序。 [關鍵詞]漢字打印,Zebra系列, VC++語言,24*24點陣字庫,文本文件
電腦用戶中,有相當一部分用戶的打印機不帶漢字庫,他們打印輸出漢字的一般方法是,首先啟動漢字操作系統,使漢字打印驅動程序駐留內存,再把含有漢字的文本文件送打印機輸出,或特定格式的漢字文件經應用程序打印輸出;這對于只是單一打印漢字文件,還是比較簡單實用的,但有時在我們自編的應用程序中,只是要打印漢字,而不需要屏幕顯示或鍵盤輸入漢字,在漢字系統下運行應用程序時,會帶來一些副作用,如漢字系統占用內存資源、使顯示速度變慢等。若在西文狀態下,使不帶漢字庫的打印機也能打印輸出漢字,即可避免因啟動漢字系統運行應用程序而帶來的麻煩。
筆者針對上述問題,經過分析研究Zebra打印機命令碼,通過VC++語言編程,用矩陣轉置的方法實現了西文狀態下漢字的打印。
一、非漢字系統下漢字打印實現原理
以目前擁有工業用戶較多的Zebra系列打印機為例,說明漢字打印實現原理,漢字打印的字摸數據來源于UCDOS的24*24點陣字庫。
打印機為用戶提供了自定義字符功能,標準字符存在打印機的ROM中,而用戶自定義字符則存在打印機的RAM中或直接對內存進行操作。同時為了避免因文本文件中出現重復漢字或圖形符號造成頻繁讀取字庫而影響文本輸出速度,我們直接對內存進行操作。對圖像而言,由于占用內存較大,影響運行速度,所以放在RAM中。
把漢字庫字模點陣數據作為自定義字符的數據,在打印機的內存中生成自定義字符,再輸出內存中的自定義字符,即可在打印機上打印漢字。
打印機自定義
下載字符命令為:
~DGd,t,w,data 其中~DG為設置打印機為下載圖形模式;
d為儲存圖形的目標設備(內存地址);
t為圖像總的字節數;
w為每行字節數;
data為ASSII為十六進制串圖像定義。因24×24點陣打印一個字需要24×3=72個字節,所以在這里 t=72,w=3。
選擇打印字符集命令為:
^XGd,t,w 其中^XG 為打印字符集命令;
d為儲存圖形的目標設備(內存地址);
t為圖像總的字節數;
w為每行字節數。
由于24*24點陣打印字庫字模數據的存貯序列是按列優先的順序,每列的24點用連續的3個字節存儲,其順序是按字模的上中下排列,且每個字節的最高位在上、最低位在下;而Zebra系列打印機打印輸出序列是按行優先的順序打印的,因此字模數據的存貯序列矩陣需行列轉置變換后才可送打印機打印。
二、漢字文本文件的打印
利用上述原理,可以在自己應用程序中,實現在非漢字系統下,不帶漢字庫的打印機上(或帶漢字庫的打印機設置為英文方式)輸出漢字。
作為應用,用VC++語言編制一打印含有漢字的文本文件的程序。
編程思路如下:置打印機為信函打印
質量方式及每英寸10個字符,以使輸出一個漢字和圖形符號占兩個字符位置,處理文本文件中的字串,當字串中遇到漢字時(連續兩個字符的第一個字符 ASCII 碼大于 175 且第二個字符ASCII碼大于 160),讀取UCDOS的24*24點陣漢字庫HZK24S(宋體)或HZK24F(仿宋體) 或 HZK24K(楷體)或HZK24H(黑體)中該漢字對應的點陣數據,當字串中遇到圖形符號時(連續兩個字符ASCII碼的第一個字符ASCII 碼大于 160 小于176且第二個字符ASCII碼大于 160),讀取UCDOS的 24* 24 點陣圖形符號庫HZK24T中該圖形符號對應的點陣數據,用文本方式或圖形方式輸出該漢字或圖形符號,否則輸出原字符。
根據以上理解,得出如下讀取漢字字模的算法:
如前面所述,漢字以字模的形式儲存于字庫中,每個漢字在字庫中有唯一的區位碼與之對應,根據某一漢字的機內碼可以確定其區位碼及其在字庫中的起始位置,就可以從字庫中取出漢字字模。具體步驟如下:
(1)根據機內碼計算漢字的區位碼
區碼=機內碼高字節-A1H
位碼=機內碼底字節-A1H
(2)根據區位碼計算漢字在字庫中的偏移量
漢字在字庫中的偏移量L=((區碼-m)*94+位碼)*n 其中,m位漢字在字庫中的起始號,n為每個漢字所占的字節數。字庫中:偏移量=((區碼-m)*94+位碼)*(字庫的點陣數^2/8) /*因為一個漢字的每一個點是作為一個位 (bit)處理的,又8位為一個字節*/
三、打印漢字文本文件VC++源程序
打印含有漢字的文本文件源程序的主要函數源代碼如下所示:
//**********************************************
//功能 : 將要打印的部分漢字字庫裝入打印機內存中
//輸入參數: sHz 當前需要初始化的漢字字串
//輸出參數: HZtobyte 漢字點陣字節流
//**********************************************
#define FONTK_NAME "c:\\Cclib\\hzk24k"//標準24點陣楷體漢字字庫
#define FONTT_NAME "c:\\Cclib\\hzk24t"//標準24點陣漢字索引庫
void CHesnprinterDlg::MakeHZHEX(CString &sHZ,CString &HZtobyte)
{
CFile theFile,theFile_t;
CString csFileName=FONTK_NAME,csFileName_t=FONTT_NAME;
BOOL bOpenOK,bOpenOK_t;
HZtobyte="";
// Open the file without the Create flag
bOpenOK = theFile.Open( csFileName,
CFile::modeRead );
bOpenOK_t=theFile_t.Open( csFileName_t,
CFile::modeRead );
if ((bOpenOK==0)||(bOpenOK_t==0))
{
CString Msg="字庫文件不能打開!";
AfxMessageBox(Msg,MB_OK|MB_ICONINFORMATION);
}
theFile.Seek( 0, CFile::begin );
theFile_t.Seek( 0, CFile::begin );
//
CString lbs,hbs,sp;
BOOL HzFlag;
long noffset;
int i,j,hb,lb,k,offset=0;
BYTE bytes[72];
HzFlag=FALSE;
int hh=sHZ.GetLength();
for(i=0;i175)
{
hb=hb-0xb0;// 漢字:hb=hb-0xb0;
lb=lb-0xa1;
noffset=hb*94*72+lb*72;
theFile.Seek( noffset, CFile::begin );
theFile.Read(bytes,72);
}
else if((hb>160)&&(hb<176))
{
hb=hb-0xa1;// 圖形字符:hb=hb-0xa1
lb=lb-0xa1;
noffset=hb*94*72+lb*72;
theFile_t.Seek( noffset, CFile::begin );
theFile_t.Read(bytes,72);
}
//點陣字庫轉置
Exchange(bytes);
//取得漢字的的點陣某位為空,即無化點,則置為0
CString HZtobyte_temp;
for(j=0;j<72;)
{
sp.Format("%02x%02x%02x",(unsigned int)bytes[j]
,(unsigned int )bytes[j+1],(unsigned int)bytes[j+2]);
for(k=0;k0xa0 )
{
HzFlag=TRUE;
continue;
}
else
{
sp1.Format("^FO%d,%d^A0%d,%d^FD%c^FS"
,xx,yy,Font_W,Font_H,signStr.GetAt(i));
sp+=sp1;
xx+=Font_W;
continue;
}
}
}
Command=sp;
}
//**********************************************
//功能 : 點陣字庫轉置
//變換參數: pch 列優先級字庫點陣->行優先級字庫點陣
//**********************************************
void CHesnprinterDlg::Exchange(BYTE * pch)
{
CString str,str_temp;
BYTE iMatrix[72][72];
int i,j;
for(i=0;i<72;i++)
{
str_temp=Byte2Bin(pch[i]);
str+=str_temp;
}
for(i=0;i<24;i++)
for(j=0;j<24;j++)
{
str_temp=str.GetAt(i*24+j);
sscanf(str_temp,"%d",&iMatrix[i][j]);
}
for(i=0;i<24;i++)
for(j=0;j=0;i--)
{
str1.Format("%d",(bt>>i)&1);
str2+=str1;
}
return str2;
}
//位轉換成字節運算
BYTE CHesnprinterDlg::Bin2Byte(CString str)
{
int iBit,iSum=0;
for(int i=7;i>=0;i--)
{
iBit=str.GetAt(7-i)-'0';
iSum+=iBit*(1<
以上是該程序的部分漢字處理函數,只要設置好PC機和打印機器之間的串行通信協議,就可以直接
處理漢字與字母混合的字符串了。
運行本程序需要當前目錄中有UCDOS的24*24點陣打印字庫 ( 圖形符號庫HZK24T和宋體字庫HZK24S、
仿宋體字庫HZK24F、楷體字庫HZK24S、黑體字庫HZK24S其中之一)。程序在586微機、Zebra系列 96XiIII打印機
及WIN98環境下運行通過。
參考文獻
[1] 任鐵良,高級語言直接在打印機上繪圖,《現代計算機》,1995年第8期
[2] Zebra工業用條形碼打印機操作手冊和編程手冊。
原文轉自:http://www.anti-gravitydesign.com