C語言顯示USDOS漢字型檔

2021-09-05 18:33:52 字數 3290 閱讀 5506

最近重新找了一下c語言的資料,深深的被c語言的底層操作特性迷戀~。在這方面,最經典的一本書莫過於清華大學出版社的《c高階實用程式設計》(王士元),在c語言高階應用領域裡這是我見過的寫的最好的一本書,非常可惜的這本書現在已經絕版了(可能是因為技術發展和更新的太快),在書店裡網上都無法買到了。記得本科時期經常借同學的這本書來讀,愛不釋手,裡面的知識極具魅力,即使今天看起來仍讓我覺得不是過時,而是回味無窮。這裡提到的字型檔檔案和作業系統都已經屬於古董級別了,現在可能也很難找到了。。。。這種應用在現在時代也很少有人研究了,但我想在微控制器等嵌入式系統的點陣式漢字顯示屏中仍然在使用。

在這裡我參考了一些資料中的用c語言顯示漢字字型檔的資料。在計算機發展的早期,為了支援顯示漢字,國內發明了相應的2個位元組表示的漢字國標(gb)碼,根據這個編碼規則,漢字分為94個區,每區94個漢字,漢字在其所在區內的位置用位號表示,兩個位元組分別表示區號和位號,為了區分ascii碼,每個位元組的首位都被置為1。在網路傳輸時還有特定的區分方法,這裡不細述這些細節了。在國際編碼中,中國漢字被分配到第16區(起始區號0x0f)。為了顯示漢字,需要漢字字形檔案(字型檔)的支援。在dos時代,出現了usdos系統,有hzk16(16*16字形),hzk24(24*24字形)等字型檔檔案,本質上乙個漢字字元是乙個二值影象(即bpp=1),所以本質上是一種圖形字型(非向量的),例如hzk16,每個字是16*16畫素,每個畫素佔1位(1/8byte),因此每個漢字在檔案中佔據了16*16/8=32 bytes/漢字。hzk24每個漢字佔據24*24/8=72 bytes/漢字。由於採用了這些約定,所以檔案中沒有任何檔案頭等附加描述資訊,而全部是緊密排列的畫素字形點陣,檔案從第乙個位元組開始第乙個字元一直到最後乙個字元結束,檔案也沒有字尾名。字形在檔案中是緊密排列的,但是需要注意的2點重要問題是:

(1)字形掃瞄順序:

hzk16是按行掃瞄,而hzk24是按列掃瞄。

所以假設乙個字形讀取到乙個byte。則位元組的分布分為按行掃瞄和按列掃瞄。例如在hzk16中是按行一行一行掃瞄,即前byte[0],byte[1]是第一行,接著2個byte是第二行。。。而hzk24為了使使用它的印表機輸出,採用的是按列掃瞄,因為印表機有乙個縱向的24針,每一次可以逐列的列印一行漢字,因此為了配合印表機,hzk24採用了按列掃瞄。如下圖所示:(圖中的數字表示的該位元組在byte中的索引。)

下面這張圖顯示的是24*24畫素的按列掃瞄的漢字字元,是如何用乙個byte陣列來描述的:圖中用彩色填充的方式標示出了byte[0],byte[1],byte[2]:

(2)字形在字型檔檔案中的定位:

請注意的是,在hzk16和hzk24中定位是不同的。這是由於漢字在檔案中的起始區不同。hzk16的漢字起始區在第16個分割槽,而hzk24則直接從第乙個分割槽開始。hzk16的前15個分割槽裡面儲存了一些特殊符號,字母等(見後面的截圖)。因此漢字所在的分割槽是從15號分割槽開始的,而hzk24不包含前面的特殊字元,第乙個區就是漢字區「啊」,從0號分割槽開始。另一點需要注意的是,兩者的【bytes/漢字】數值不同。用offset表示從檔案頭開始計算的檔案偏移位址,code[2]表示漢子碼。

則code是用程式碼頁示的,如漢字表中的第乙個漢字「啊」的內碼是;從漢字碼的第乙個位元組獲取區號,從第二個位元組獲取位號。將他們減去0xa1就轉換為我們需要的區號和位號。即換算成區號是,表示「啊」字位於第15區,位號是0。

對於hzk16來說:94是每個區的漢字數。

unsigned long offset=(

(code[0]-0xa1)*94 + (code[1]-0xa1) )*32l;    

//32是每個漢字佔據的位元組數

對於hzk24來說:

unsigned long offset=((code[0]-0xa1

-15)*94 + (code[1]-0xa1) )*72l;

//72是每個漢字佔據的位元組數

注意上面的hzk24中,由於第乙個分割槽就是漢字區,所以區號被減去了0x0f。

這樣,我們看顯示乙個字元的**:(以下**來自於《c高階應用程式設計》一書。)

/*在螢幕的x0,y0位置顯示乙個漢字字元

*/void

dishz(

intx0,

inty0,

char

code,

intcolor);/*

遮蔽字模每行各位的陣列

*/int

i,j,x,y,pos;

char

mat[

32];

/*下面這個函式用於在檔案中讀取相應的位元組到mat陣列中*/

get_hz(code,mat);y=

y0;for(i=

0;i<16;

++i)

++y;}}

我們要注意的是,由於每個漢字占用了2個位元組,因此我們必須每次是字串的指標遞增2。例如:

char* s="這是漢字字串";

while(*s)

上面的字模陣列的每個數字的某一位為1,這樣用位與操作可以判斷某個byte中的某一位為1還是0,如果為1表示這裡應該顯示漢字的前景顏色。上面的**是用於hzk16的,即按行掃瞄的順序顯示的。按列顯示的**原理類似,不再列出。

關於載入字模,主要採用上面的檔案定位,讀取一定數量位元組即可,這裡我們也不再列出。

下面的截圖是hzk16字型檔的前面一部分特殊字元(有象棋棋子,製表符,全形的字母數字等等):(每行32個字元,每個字元的左上角被我標記了乙個紅點)。

上面的截圖採用了在《用c語言顯示bmp》一文中的tc截圖**截圖的**(我將截圖**寫到cpyscr.h檔案中放到了include資料夾下,這樣只要用#include "cpyscr.h"就可以直接使用截圖函式了),注意第一行中的數字序號表示的是該字元的序號(注意該序號不是ascii碼!!!),而不是檔案位址!。

下圖是用hzk24f(仿宋體)顯示的漢字,上面是原樣大小輸出(24*24),較大的字是把字形邊長擴大成2倍邊長(48*48)的輸出,由於是點陣圖字型,所以擴大後會有位圖放大的鋸齒感:

宋體漢字型檔:

在漢字型檔中尋找某個漢字的點陣資料

在計算機中英文可以使用 ascii 碼來表示,而漢字使用的是擴充套件 ascii 碼,並且使用兩個擴充套件 ascii 碼來表示乙個漢字。乙個 ascii 碼使用乙個位元組表示,所謂擴充套件 ascii 碼,也就是 ascii 碼的最高位是1的 ascii 碼,簡單的說就是碼值大於等於 128 的 ...

漢字型檔HZK16的簡單介紹

hzk16 字型檔是符合gb2312標準的16 16點陣字型檔,hzk16的gb2312 80支援的漢字有6763個,符號682個。其中一級漢字有3755個,按聲序排列,二級漢字有3008個,按偏旁部首排列。我們在一些應用場合根本用不到這麼多漢字字模,所以在應用時就可以只提取部分字型作 為己用。hz...

點陣字型 ASCII碼 漢字型檔 自我學習 簡單總結

學習各種大小點陣字型顯示,參考網上資料,簡單記錄一下!第一部分 點陣字型資料的存放格式 最常見的是16 16 的點陣,意思是說每1行有16個點,一共有16行。由於1個點使用1個位元位來表示,如果這個位元位的值為1,則表示這個位置有點,如果這個位元位的值為0,則表示這個位置沒有點。從而1行就需要16個...