點陣字型檔結構以及點陣字顯示的實現原理

2021-05-11 07:27:08 字數 3892 閱讀 1614

點陣字型檔結構以及點陣字顯示的實現原理

2008-10-08 14:32

在 dos 下作遊戲要實現漢字或英文的輸出,一般都是使用的點陣字型檔技術。這樣可以使程式有更好的相容性。那麼我們如何在程式中使用點陣字型檔呢,這片文件將會講解這個。

先講講什麼是點陣字型檔,我首先需要理解的是點陣字型檔是乙個資料檔案,在這個資料檔案裡面儲存了所有文字的點陣資料。至於什麼是點陣,我想我不講大家都知道 的,使用過「文曲星」之類的電子辭典吧,那個的液晶顯示器上面顯示的漢子就能夠明顯的看出「點陣」的痕跡。在 pc 機上也是如此,文字也是由點陣來組成了,不同的是,pc機顯示器的顯示解析度更高,高到了我們肉眼無法區分的地步,因此「點陣」的痕跡也就不那麼明顯了。

點陣、矩陣、點陣圖這三個概念在本質上是有聯絡的,從某種程度上來講,這三個就是同義詞。點陣從本質上講就是單色位圖,他使用乙個位元來表示乙個點,如果這 個位元為0,表示某個位置沒有點,如果為1表示某個位置有點。矩陣和點陣圖有著密不可分的聯絡,矩陣其實是點陣圖的數學抽象,是乙個二維的陣列。位圖就是這種 二維的陣列,這個陣列中的 (x,y) 位置上的資料代表的就是對原始圖形進行取樣量化後的顏色值。但是,另一方面,我們要面對的問題是,計算機中資料的存放都是一維的,線性的。因此,我們需要 將二維的資料線性化到一維裡面去。通常的做法就是將二維資料按行順序的存放,這樣就線性化到了一維。

那麼點陣字的資料存放細節到底是怎麼樣的呢。其實也十分的簡單,舉個例子最能說明問題。比如說 16*16 的點陣,也就是說每一行有16個點,由於乙個點使用乙個位元來表示,如果這個位元的值為1,則表示這個位置有點,如果這個位元的值為0,則表示這個位置沒 有點,那麼一行也就需要16個位元,而8個位元就是乙個位元組,也就是說,這個點陣中,一行的資料需要兩個位元組來存放。第一行的前八個點的資料存放在點陣數 據的第乙個位元組裡面,第一行的後面八個點的資料存放在點陣資料的第二個位元組裡面,第二行的前八個點的資料存放在點陣資料的第三個位元組裡面,...,然後後 面的就以此類推了。這樣我們可以計算出存放乙個點陣總共需要32個位元組。看看下面這個圖形化的例子:

| |1| | | | | | | | | | |1| | | |

| | |1|1| |1|1|1|1|1|1|1|1|1| | |

| | | |1| | | | | | | | |1| | | |

|1| | | | | |1| | | | | |1| | | |

| |1|1| | | |1| | | | | |1| | | |

| | |1| | | |1| | | | |1| | | | |

| | | | |1| | |1| | | |1| | | | |

| | | |1| | | |1| | |1| | | | | |

| | |1| | | | | |1| |1| | | | | |

|1|1|1| | | | | | |1| | | | | | |

| | |1| | | | | |1| |1| | | | | |

| | |1| | | | |1| | | |1| | | | |

| | |1| | | |1| | | | | |1| | | |

| | |1| | |1| | | | | | |1|1|1| |

| | | | |1| | | | | | | | |1| | |

| | | | | | | | | | | | | | | | |

可以看出這是乙個「漢」字的點陣,當然文字的方式效果不是很好。根據上面的原則,我們可以寫出這個點陣的點陣數 據:0x40,0x08,0x37,0xfc,0x10,0x08,..., 當然寫這個確實很麻煩所以我不再繼續下去。我這樣做,也只是為了向你說明,在點陣字型檔中,每乙個點陣的資料就是按照這種方式存放的。

當然也存在著不規則的點陣,這裡說的不規則,指的是點陣的寬度不是8的倍數,比如 12*12 的點陣,那麼這樣的點陣資料又是如何存放的呢?其實也很簡單,每一行的前面8個點存放在乙個位元組裡面,每一行的剩下的4點就使用乙個位元組來存放,也就是說 剩下的4個點將占用乙個位元組的高4位,而這個位元組的低4位沒有使用,全部都預設的為零。這樣做當然顯得有點浪費,不過卻能夠便於我們進行存放和定址。對於 其他不規則的點陣,也是按照這個原則進行處理的。這樣我們可以得出乙個 m*n 的點陣所占用的位元組數為 (m+7)/8*n。

在明白了以上所講的以後,我們可以寫出乙個顯示乙個任意大小的點陣字模的函式,這個函式的功能是輸出乙個寬度為w,高度為h的字模到螢幕的 (x,y) 座標出,文字的顏色為 color,文字的點陣資料為 pdata 所指:

/*輸出字模的函式*/

void _draw_model(char *pdata, int w, int h, int x, int y, int color)

; /* 位遮蔽字 */

w = (w + 7) / 8 * 8; /* 重新計算w */

nc = 0;

for (i=0; i**很簡單,不用怎麼講解就能看懂,**可能不是最優化的,但是應該是最易讀懂的。其中的 putpixel 函式,使用的是tc提供的 graphics 中的畫點函式。使用這個函式就可以完成點陣任意大小的點陣字模的輸出。

接下來的問題就是如何在漢子庫中定址某個漢子的點陣資料了。要解決這個問題,首先需要了解漢字在計算機中是如何表示的。在計算機中英文可以使用 ascii 碼來表示,而漢字使用的是擴充套件 ascii 碼,並且使用兩個擴充套件 ascii 碼來表示乙個漢字。乙個 ascii 碼使用乙個位元組表示,所謂擴充套件 ascii 碼,也就是 ascii 碼的最高位是1的 ascii 碼,簡單的說就是碼值大於等於 128 的 ascii 碼。乙個漢字由兩個擴充套件 ascii 碼組成,第乙個擴充套件 ascii 碼用來存放區碼,第二個擴充套件 ascii 碼用來存放位碼。在 gb2312-80 標準中,將所有的漢字分為94個區,每個區有94個位可以存放94個漢字,形成了人們常說的區位碼,這樣總共就有 94*94=8836 個漢字。在點陣字型檔中,漢字點陣資料就是按照這個區位的順序來存放的,也就是最先存放的是第乙個區的漢字點陣資料,在每乙個區中有是按照位的順序來存放 的。在漢字的內碼中,漢字區位碼的存放實在擴充套件 ascii 基礎上存放的,並且將區碼和位碼都加上了32,然後存放在兩個擴充套件 ascii 碼中。具體的說就是:

第乙個擴充套件ascii碼 = 128+32 + 漢字區碼

第二個擴充套件ascii嗎 = 128+32 + 漢字位碼

如果用char hz[2]來表示乙個漢字,那麼我可以計算出這個漢字的區位碼為:

區碼 = hz[0] - 128 - 32 = hz[0] - 160

位碼 = hz[1] - 128 - 32 = hz[1] - 160。

這樣,我們可以根據區位碼在檔案中進行殉職了,定址公式如下:

漢字點陣資料在字型檔檔案中的偏移 = ((區碼-1) * 94 + 位碼) * 乙個點陣字模占用的位元組數

在定址以後,即可讀取漢字的點陣資料到緩衝區進行顯示了。以下是實現**:

/* 輸出乙個漢字的函式 */

void _draw_hz(char hz[2], file *fp, int x, int y, int w, int h, int color)

以上介紹完了中文點陣字型檔的原理,當然還有英文點陣字型檔了。英文點陣字型檔中單個點陣字模資料的存放方式與中文是一模一樣的,也就是對我們所寫的 _draw_model 函式同樣可以使用到英文字型檔中。唯一不同的是對點陣字型檔的定址上。英文使用的就是 ascii 碼,其碼值是0到127,定址公式為:

英文點陣資料在英文點陣字型檔中的偏移 = 英文的ascii碼 * 乙個英文本模占用的位元組數

可以看到,區分中英文的關鍵就是,乙個字元是 ascii 碼還是擴充套件 ascii 碼,如果是 ascii 碼,其範圍是0到127,這樣是使用的英文字型檔,如果是擴充套件 ascii 碼,則與其後的另乙個擴充套件 ascii 碼組成漢字內碼,使用中文字庫進行顯示。只要正確區分 ascii 碼的型別並進行分別的處理,也就能實現中英文本串的混合輸出了。

rockcarry

2005.8.19

點陣字型檔結構以及點陣字顯示的實現原理

在 dos 下作遊戲要實現漢字或英文的輸出,一般都是使用的點陣字型檔技術。這樣可以使程式有更好的相容性。那麼我們如何在程式中使用點陣字型檔呢,這片文件將會講解這個。先講講什麼是點陣字型檔,我首先需要理解的是點陣字型檔是乙個資料檔案,在這個資料檔案裡面儲存了所有文字的點陣資料。至於什麼是點陣,我想我不...

24x24點陣字型檔的顯示

首先,研究了很久,以為和16x16沒多大區別,後來又發現了很多24x24需要注意的點,如 不要小看這個按列掃瞄,如果是16x16的話,可以直接用三層加判斷列印出來,如下 for i 0 i 16 i printf n 但是24的按列掃瞄,三層迴圈判斷時是判斷的第i行那一列的資訊,如果你直接列印的話,...

ASCII字元點陣字型檔的製作和使用

win7,eclipse,mingw ascii編碼的可列印字元是0x20 0x7e,先用執行下面這段 生成乙個包含全部可列印字元的txt檔案 cpp view plain copy include include int main int argc,char argv for i 0x20 i 0...